1
0
mirror of https://github.com/freescout-helpdesk/freescout.git synced 2024-11-24 11:22:42 +01:00

Merge branch 'master' of github.com:freescout-helpdesk/freescout

This commit is contained in:
FreeScout 2018-11-27 00:20:47 -08:00
commit 0c413261b4
13 changed files with 399 additions and 397 deletions

View File

@ -60,7 +60,7 @@ class SettingsController extends Controller
$section_vars = $this->getSectionParams($section, 'template_vars');
if ($section_vars && is_array($section_vars)) {
return array_merge($template_vars, $section_vars);
return array_merge($template_vars, $section_vars);
} else {
return $template_vars;
}
@ -71,9 +71,11 @@ class SettingsController extends Controller
*
* If in settings parameter `env` is set, option will be saved into .env file
* instead of DB.
* @param [type] $section [description]
* @param string $param [description]
* @return [type] [description]
*
* @param [type] $section [description]
* @param string $param [description]
*
* @return [type] [description]
*/
public function getSectionParams($section, $param = '')
{
@ -88,7 +90,7 @@ class SettingsController extends Controller
'mail' => __("PHP's mail() function"),
'sendmail' => __('Sendmail'),
'smtp' => 'SMTP',
]
],
],
'validator_rules' => [
'settings.mail_from' => 'required|email',
@ -99,10 +101,10 @@ class SettingsController extends Controller
$params = [
'settings' => [
'locale' => [
'env' => 'APP_LOCALE'
'env' => 'APP_LOCALE',
],
'timezone' => [
'env' => 'APP_TIMEZONE'
'env' => 'APP_TIMEZONE',
],
],
];
@ -116,7 +118,7 @@ class SettingsController extends Controller
if (isset($params[$param])) {
return $params[$param];
} else {
return null;
return;
}
} else {
return $params;

View File

@ -8,6 +8,7 @@ class TranslateController extends BaseController
{
/**
* Send translations to FreeScout team.
*
* @return [type] [description]
*/
public function postSend()
@ -35,17 +36,19 @@ class TranslateController extends BaseController
/**
* Remove all translations which has not been published yet.
*
* @return [type] [description]
*/
public function postRemoveUnpublished()
{
\Barryvdh\TranslationManager\Models\Translation::truncate();
return ['status' => 'ok'];
}
/**
* Download as ZIP.
*
*
* @return [type] [description]
*/
public function postDownload()
@ -54,13 +57,13 @@ class TranslateController extends BaseController
$file_name = 'lang.zip';
// Archive langs folder
$archive_path = \Helper::createZipArchive(base_path().DIRECTORY_SEPARATOR.'resources/lang', $file_name, 'lang');
$public_path = storage_path('app/public/'.$file_name);
$public_path = storage_path('app/public/'.$file_name);
\File::copy($archive_path, $public_path);
$headers = array(
$headers = [
'Content-Type: application/zip',
);
];
return \Response::download($public_path, $file_name, $headers);
}

View File

@ -9,14 +9,15 @@ class Localize
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
// Interface language is set automatically, as locale is stored in .env file.
// Set user language if user logged in.
$user_locale = session('user_locale');
if ($user_locale) {

View File

@ -66,103 +66,104 @@ class Helper
/**
* Locales data.
*
* @var [type]
*/
public static $locales = [
'af' => ['name' => 'Afrikaans',
'af' => ['name' => 'Afrikaans',
'name_en' => 'Afrikaans',
],
'sq' => ['name' => 'Shqip',
'sq' => ['name' => 'Shqip',
'name_en' => 'Albanian',
],
'ar' => ['name' => 'العربية',
'ar' => ['name' => 'العربية',
'name_en' => 'Arabic',
],
'ar_IQ' => ['name' => 'العربية',
'ar_IQ' => ['name' => 'العربية',
'name_en' => 'Arabic (Iraq)',
],
'ar_LY' => ['name' => 'العربية',
'ar_LY' => ['name' => 'العربية',
'name_en' => 'Arabic (Libya)',
],
'ar_MA' => ['name' => 'العربية',
'ar_MA' => ['name' => 'العربية',
'name_en' => 'Arabic (Morocco)',
],
'ar_OM' => ['name' => 'العربية',
'ar_OM' => ['name' => 'العربية',
'name_en' => 'Arabic (Oman)',
],
'ar_SY' => ['name' => 'العربية',
'ar_SY' => ['name' => 'العربية',
'name_en' => 'Arabic (Syria)',
],
'ar_LB' => ['name' => 'العربية',
'ar_LB' => ['name' => 'العربية',
'name_en' => 'Arabic (Lebanon)',
],
'ar_AE' => ['name' => 'العربية',
'ar_AE' => ['name' => 'العربية',
'name_en' => 'Arabic (U.A.E.)',
],
'ar_QA' => ['name' => 'العربية',
'ar_QA' => ['name' => 'العربية',
'name_en' => 'Arabic (Qatar)',
],
'ar_SA' => ['name' => 'العربية',
'ar_SA' => ['name' => 'العربية',
'name_en' => 'Arabic (Saudi Arabia)',
],
'ar_EG' => ['name' => 'العربية',
'ar_EG' => ['name' => 'العربية',
'name_en' => 'Arabic (Egypt)',
],
'ar_DZ' => ['name' => 'العربية',
'ar_DZ' => ['name' => 'العربية',
'name_en' => 'Arabic (Algeria)',
],
'ar_TN' => ['name' => 'العربية',
'ar_TN' => ['name' => 'العربية',
'name_en' => 'Arabic (Tunisia)',
],
'ar_YE' => ['name' => 'العربية',
'ar_YE' => ['name' => 'العربية',
'name_en' => 'Arabic (Yemen)',
],
'ar_JO' => ['name' => 'العربية',
'ar_JO' => ['name' => 'العربية',
'name_en' => 'Arabic (Jordan)',
],
'ar_KW' => ['name' => 'العربية',
'ar_KW' => ['name' => 'العربية',
'name_en' => 'Arabic (Kuwait)',
],
'ar_BH' => ['name' => 'العربية',
'ar_BH' => ['name' => 'العربية',
'name_en' => 'Arabic (Bahrain)',
],
'eu' => ['name' => 'Euskara',
'eu' => ['name' => 'Euskara',
'name_en' => 'Basque',
],
'be' => ['name' => 'Беларуская',
'be' => ['name' => 'Беларуская',
'name_en' => 'Belarusian',
],
'bn' => ['name' => 'বাংলা',
'bn' => ['name' => 'বাংলা',
'name_en' => 'Bengali',
],
'bg' => ['name' => 'Български език',
'bg' => ['name' => 'Български език',
'name_en' => 'Bulgarian',
],
'ca' => ['name' => 'Català',
'ca' => ['name' => 'Català',
'name_en' => 'Catalan',
],
'zh_CN' => ['name' => '简体中文',
'zh_CN' => ['name' => '简体中文',
'name_en' => 'Chinese (Simplified)',
],
'zh_SG' => ['name' => '简体中文',
'zh_SG' => ['name' => '简体中文',
'name_en' => 'Chinese (Singapore)',
],
'zh_TW' => ['name' => '简体中文',
'zh_TW' => ['name' => '简体中文',
'name_en' => 'Chinese (Traditional)',
],
'zh_HK' => ['name' => '简体中文',
'zh_HK' => ['name' => '简体中文',
'name_en' => 'Chinese (Hong Kong SAR)',
],
'hr' => ['name' => 'Hrvatski',
'hr' => ['name' => 'Hrvatski',
'name_en' => 'Croatian',
],
'cs' => ['name' => 'Čeština',
'cs' => ['name' => 'Čeština',
'name_en' => 'Czech',
],
'da' => ['name' => 'Dansk',
'da' => ['name' => 'Dansk',
'name_en' => 'Danish',
],
'nl' => ['name' => 'Nederlands',
'nl' => ['name' => 'Nederlands',
'name_en' => 'Dutch',
],
// 'nl_BE' => ['name' => 'Nederlands',
@ -180,7 +181,7 @@ class Helper
// 'en_ZA' => ['name' => '',
// 'name_en' => 'English (South Africa)',
// ],
'en' => ['name' => 'English',
'en' => ['name' => 'English',
'name_en' => 'English',
],
// 'en_TT' => ['name' => '',
@ -201,19 +202,19 @@ class Helper
// 'en_BZ' => ['name' => '',
// 'name_en' => 'English (Belize)',
// ],
'et' => ['name' => 'Eesti',
'et' => ['name' => 'Eesti',
'name_en' => 'Estonian',
],
'fo' => ['name' => 'Føroyskt',
'fo' => ['name' => 'Føroyskt',
'name_en' => 'Faeroese',
],
'fa' => ['name' => 'فارسی',
'fa' => ['name' => 'فارسی',
'name_en' => 'Farsi',
],
'fi' => ['name' => 'Suomi',
'fi' => ['name' => 'Suomi',
'name_en' => 'Finnish',
],
'fr' => ['name' => 'Français',
'fr' => ['name' => 'Français',
'name_en' => 'French',
],
// 'fr_CA' => ['name' => '',
@ -228,10 +229,10 @@ class Helper
// 'fr_CH' => ['name' => '',
// 'name_en' => 'French (Switzerland)',
// ],
'gd' => ['name' => 'Gàidhlig',
'gd' => ['name' => 'Gàidhlig',
'name_en' => 'Gaelic (Scotland)',
],
'de' => ['name' => 'Deutsch',
'de' => ['name' => 'Deutsch',
'name_en' => 'German',
],
// 'de_CH' => ['name' => '',
@ -246,100 +247,100 @@ class Helper
// 'de_LI' => ['name' => '',
// 'name_en' => 'German (Liechtenstein)',
// ],
'el' => ['name' => 'Ελληνικά',
'el' => ['name' => 'Ελληνικά',
'name_en' => 'Greek',
],
'he' => ['name' => 'עברית',
'he' => ['name' => 'עברית',
'name_en' => 'Hebrew',
],
'hi' => ['name' => 'हिन्दी',
'hi' => ['name' => 'हिन्दी',
'name_en' => 'Hindi',
],
'hu' => ['name' => 'Magyar',
'hu' => ['name' => 'Magyar',
'name_en' => 'Hungarian',
],
'is' => ['name' => 'Íslenska',
'is' => ['name' => 'Íslenska',
'name_en' => 'Icelandic',
],
'id' => ['name' => 'Bahasa Indonesia',
'id' => ['name' => 'Bahasa Indonesia',
'name_en' => 'Indonesian',
],
'ga' => ['name' => 'Gaeilge',
'ga' => ['name' => 'Gaeilge',
'name_en' => 'Irish',
],
'it' => ['name' => 'Italiano',
'it' => ['name' => 'Italiano',
'name_en' => 'Italian',
],
// 'it_CH' => ['name' => 'Italiano',
// 'name_en' => 'Italian (Switzerland)',
// ],
'ja' => ['name' => '日本語',
'ja' => ['name' => '日本語',
'name_en' => 'Japanese',
],
'ko' => ['name' => '한국어 (韓國語)',
'ko' => ['name' => '한국어 (韓國語)',
'name_en' => 'Korean (Johab)',
],
'lv' => ['name' => 'Latviešu valoda',
'lv' => ['name' => 'Latviešu valoda',
'name_en' => 'Latvian',
],
'lt' => ['name' => 'Lietuvių kalba',
'lt' => ['name' => 'Lietuvių kalba',
'name_en' => 'Lithuanian',
],
'mk' => ['name' => 'Македонски јазик',
'mk' => ['name' => 'Македонски јазик',
'name_en' => 'Macedonian (FYROM)',
],
'ms' => ['name' => 'Bahasa Melayu, بهاس ملايو',
'ms' => ['name' => 'Bahasa Melayu, بهاس ملايو',
'name_en' => 'Malay',
],
'mt' => ['name' => 'Malti',
'mt' => ['name' => 'Malti',
'name_en' => 'Maltese',
],
'ne' => ['name' => 'नेपाली',
'ne' => ['name' => 'नेपाली',
'name_en' => 'Nepali',
],
'no' => ['name' => 'Norsk bokmål',
'no' => ['name' => 'Norsk bokmål',
'name_en' => 'Norwegian (Bokmal)',
],
'pl' => ['name' => 'Polski',
'pl' => ['name' => 'Polski',
'name_en' => 'Polish',
],
'pt' => ['name' => 'Português',
'pt' => ['name' => 'Português',
'name_en' => 'Portuguese (Portugal)',
],
'pt_BR' => ['name' => 'Português do Brasil',
'pt_BR' => ['name' => 'Português do Brasil',
'name_en' => 'Portuguese (Brazil)',
],
'ro' => ['name' => 'Română',
'ro' => ['name' => 'Română',
'name_en' => 'Romanian',
],
// 'ro_MO' => ['name' => 'Română',
// 'name_en' => 'Romanian (Republic of Moldova)',
// ],
'rm' => ['name' => 'Rumantsch grischun',
'rm' => ['name' => 'Rumantsch grischun',
'name_en' => 'Romansh',
],
'ru' => ['name' => 'Русский',
'ru' => ['name' => 'Русский',
'name_en' => 'Russian',
],
// 'ru_MO' => ['name' => '',
// 'name_en' => 'Russian (Republic of Moldova)',
// ],
'sz' => ['name' => 'Davvisámegiella',
'sz' => ['name' => 'Davvisámegiella',
'name_en' => 'Sami (Lappish)',
],
'sr' => ['name' => 'Српски језик',
'sr' => ['name' => 'Српски језик',
'name_en' => 'Serbian (Latin)',
],
'sk' => ['name' => 'Slovenčina',
'sk' => ['name' => 'Slovenčina',
'name_en' => 'Slovak',
],
'sl' => ['name' => 'Slovenščina',
'sl' => ['name' => 'Slovenščina',
'name_en' => 'Slovenian',
],
/*'sb' => ['name' => 'Serbsce',
'name_en' => 'Sorbian',
],*/
'es' => ['name' => 'Español',
'es' => ['name' => 'Español',
'name_en' => 'Spanish',
],
// 'es_GT' => ['name' => '',
@ -396,7 +397,7 @@ class Helper
// 'es_NI' => ['name' => '',
// 'name_en' => 'Spanish (Nicaragua)',
// ],
'sv' => ['name' => 'Svenska',
'sv' => ['name' => 'Svenska',
'name_en' => 'Swedish',
],
// unknown
@ -406,37 +407,37 @@ class Helper
// 'sv_FI' => ['name' => '',
// 'name_en' => 'Swedish (Finland)',
// ],
'th' => ['name' => 'ไทย',
'th' => ['name' => 'ไทย',
'name_en' => 'Thai',
],
'ts' => ['name' => 'Xitsonga',
'ts' => ['name' => 'Xitsonga',
'name_en' => 'Tsonga',
],
'tn' => ['name' => 'Setswana',
'tn' => ['name' => 'Setswana',
'name_en' => 'Tswana',
],
'tr' => ['name' => 'Türkçe',
'tr' => ['name' => 'Türkçe',
'name_en' => 'Turkish',
],
'uk' => ['name' => 'українська',
'uk' => ['name' => 'українська',
'name_en' => 'Ukrainian',
],
'ur' => ['name' => 'اردو',
'ur' => ['name' => 'اردو',
'name_en' => 'Urdu',
],
've' => ['name' => 'Tshivenḓa',
've' => ['name' => 'Tshivenḓa',
'name_en' => 'Venda',
],
'vi' => ['name' => 'Tiếng Việt',
'vi' => ['name' => 'Tiếng Việt',
'name_en' => 'Vietnamese',
],
'xh' => ['name' => 'isiXhosa',
'xh' => ['name' => 'isiXhosa',
'name_en' => 'Xhosa',
],
'ji' => ['name' => 'ייִדיש',
'ji' => ['name' => 'ייִדיש',
'name_en' => 'Yiddish',
],
'zu' => ['name' => 'isiZulu',
'zu' => ['name' => 'isiZulu',
'name_en' => 'Zulu',
],
];
@ -763,23 +764,25 @@ class Helper
/**
* Get locale's data.
* @param [type] $locale [description]
* @param string $param [description]
* @return [type] [description]
*
* @param [type] $locale [description]
* @param string $param [description]
*
* @return [type] [description]
*/
public static function getLocaleData($locale, $param = '')
{
if (is_string($locale) && isset(self::$locales[$locale])) {
$data = self::$locales[$locale];
} else {
return null;
return;
}
if ($param) {
if (isset(self::$locales[$locale])) {
return self::$locales[$locale][$param];
} else {
return null;
return;
}
} else {
return $data;
@ -788,6 +791,7 @@ class Helper
/**
* Clear application cache.
*
* @return [type] [description]
*/
public static function clearCache()
@ -820,14 +824,14 @@ class Helper
\File::put($env_path, $contents);
} else {
// Add.
$contents = $contents . "\n{$key}={$value}\n";
$contents = $contents."\n{$key}={$value}\n";
\File::put($env_path, $contents);
}
}
/**
* User may add an extra translation to the app on Translate page.
*
*
* @return [type] [description]
*/
public static function getCustomLocales()

View File

@ -695,7 +695,7 @@ class User extends Authenticatable
/**
* Get user locale.
*
*
* @return [type] [description]
*/
public function getLocale()

View File

@ -91,8 +91,8 @@ return [
| locales: available locales
*/
'locale' => env('APP_LOCALE', 'en'),
'locales' => ['en', 'fr'],
'locale' => env('APP_LOCALE', 'en'),
'locales' => ['en', 'fr'],
'default_locale' => 'en',
/*

View File

@ -49,7 +49,7 @@ return [
'installer_messages',
],
/**
/*
* Regular expression may determine goup incorrectly, for example for 'e.g'
*/
'incorrect_groups' => [

View File

@ -1,8 +1,8 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddLocaleColumnToUsersTable extends Migration
{

View File

@ -28,74 +28,74 @@ class Manager
protected $ignoreFilePath;
public function __construct( Application $app, Filesystem $files, Dispatcher $events )
public function __construct(Application $app, Filesystem $files, Dispatcher $events)
{
$this->app = $app;
$this->files = $files;
$this->events = $events;
$this->config = $app[ 'config' ][ 'translation-manager' ];
$this->ignoreFilePath = storage_path( '.ignore_locales' );
$this->locales = [];
$this->ignoreLocales = $this->getIgnoredLocales();
$this->app = $app;
$this->files = $files;
$this->events = $events;
$this->config = $app['config']['translation-manager'];
$this->ignoreFilePath = storage_path('.ignore_locales');
$this->locales = [];
$this->ignoreLocales = $this->getIgnoredLocales();
}
protected function getIgnoredLocales()
{
if ( !$this->files->exists( $this->ignoreFilePath ) ) {
if (!$this->files->exists($this->ignoreFilePath)) {
return [];
}
$result = json_decode( $this->files->get( $this->ignoreFilePath ) );
$result = json_decode($this->files->get($this->ignoreFilePath));
return ( $result && is_array( $result ) ) ? $result : [];
return ($result && is_array($result)) ? $result : [];
}
public function importTranslations( $replace = false, $base = null )
public function importTranslations($replace = false, $base = null)
{
$counter = 0;
//allows for vendor lang files to be properly recorded through recursion.
$vendor = true;
if ( $base == null ) {
$base = $this->app[ 'path.lang' ];
if ($base == null) {
$base = $this->app['path.lang'];
$vendor = false;
}
foreach ( $this->files->directories( $base ) as $langPath ) {
$locale = basename( $langPath );
foreach ($this->files->directories($base) as $langPath) {
$locale = basename($langPath);
//import langfiles for each vendor
if ( $locale == 'vendor' ) {
foreach ( $this->files->directories( $langPath ) as $vendor ) {
$counter += $this->importTranslations( $replace, $vendor );
if ($locale == 'vendor') {
foreach ($this->files->directories($langPath) as $vendor) {
$counter += $this->importTranslations($replace, $vendor);
}
continue;
}
$vendorName = $this->files->name( $this->files->dirname( $langPath ) );
foreach ( $this->files->allfiles( $langPath ) as $file ) {
$info = pathinfo( $file );
$group = $info[ 'filename' ];
$vendorName = $this->files->name($this->files->dirname($langPath));
foreach ($this->files->allfiles($langPath) as $file) {
$info = pathinfo($file);
$group = $info['filename'];
if ( in_array( $group, $this->config[ 'exclude_groups' ] ) ) {
if (in_array($group, $this->config['exclude_groups'])) {
continue;
}
$subLangPath = str_replace( $langPath . DIRECTORY_SEPARATOR, '', $info[ 'dirname' ] );
$subLangPath = str_replace( DIRECTORY_SEPARATOR, '/', $subLangPath );
$langPath = str_replace( DIRECTORY_SEPARATOR, '/', $langPath );
$subLangPath = str_replace($langPath.DIRECTORY_SEPARATOR, '', $info['dirname']);
$subLangPath = str_replace(DIRECTORY_SEPARATOR, '/', $subLangPath);
$langPath = str_replace(DIRECTORY_SEPARATOR, '/', $langPath);
if ( $subLangPath != $langPath ) {
$group = $subLangPath . '/' . $group;
if ($subLangPath != $langPath) {
$group = $subLangPath.'/'.$group;
}
if ( !$vendor ) {
$translations = \Lang::getLoader()->load( $locale, $group );
if (!$vendor) {
$translations = \Lang::getLoader()->load($locale, $group);
} else {
$translations = include( $file );
$group = "vendor/" . $vendorName;
$translations = include $file;
$group = 'vendor/'.$vendorName;
}
if ( $translations && is_array( $translations ) ) {
foreach ( array_dot( $translations ) as $key => $value ) {
$importedTranslation = $this->importTranslation( $key, $value, $locale, $group, $replace );
$counter += $importedTranslation ? 1 : 0;
if ($translations && is_array($translations)) {
foreach (array_dot($translations) as $key => $value) {
$importedTranslation = $this->importTranslation($key, $value, $locale, $group, $replace);
$counter += $importedTranslation ? 1 : 0;
}
}
}
@ -103,27 +103,27 @@ class Manager
// Import app json translations.
//$loader = new \Illuminate\Translation\FileLoader($this->files, $this->app[ 'path.lang' ]);
foreach ( $this->files->files( $this->app[ 'path.lang' ] ) as $jsonTranslationFile ) {
if ( strpos( $jsonTranslationFile, '.json' ) === false ) {
foreach ($this->files->files($this->app['path.lang']) as $jsonTranslationFile) {
if (strpos($jsonTranslationFile, '.json') === false) {
continue;
}
$locale = basename( $jsonTranslationFile, '.json' );
$locale = basename($jsonTranslationFile, '.json');
// Ignore module translations backup files.
if (!preg_match("/^[a-zA-Z_]+$/", $locale)) {
if (!preg_match('/^[a-zA-Z_]+$/', $locale)) {
continue;
}
$group = self::JSON_GROUP;
$group = self::JSON_GROUP;
// Retrieves JSON entries of the given locale only.
// Modules JSON translations are also loaded.
$translations = \Lang::getLoader()->load( $locale, '*', '*' );
$translations = \Lang::getLoader()->load($locale, '*', '*');
//$translations = $loader->load( $locale, '*', '*' );
if ( $translations && is_array( $translations ) ) {
foreach ( $translations as $key => $value ) {
$importedTranslation = $this->importTranslation( $key, $value, $locale, $group, $replace );
$counter += $importedTranslation ? 1 : 0;
if ($translations && is_array($translations)) {
foreach ($translations as $key => $value) {
$importedTranslation = $this->importTranslation($key, $value, $locale, $group, $replace);
$counter += $importedTranslation ? 1 : 0;
}
}
}
@ -131,32 +131,31 @@ class Manager
// Import modules translations.
$modules = \Module::all();
foreach ($modules as $key => $module) {
$moduleLangPath = $module->getPath().'/Resources/lang/';
if (!$this->files->exists( $moduleLangPath ) || !$this->files->isDirectory( $moduleLangPath )) {
if (!$this->files->exists($moduleLangPath) || !$this->files->isDirectory($moduleLangPath)) {
continue;
}
foreach ( $this->files->files( $moduleLangPath ) as $jsonTranslationFile ) {
if ( strpos( $jsonTranslationFile, '.json' ) === false ) {
foreach ($this->files->files($moduleLangPath) as $jsonTranslationFile) {
if (strpos($jsonTranslationFile, '.json') === false) {
continue;
}
// Miss incorrect locales.
if (!preg_match("/^[a-zA-Z_]+$/", $locale)) {
if (!preg_match('/^[a-zA-Z_]+$/', $locale)) {
continue;
}
$locale = basename( $jsonTranslationFile, '.json' );
$locale = basename($jsonTranslationFile, '.json');
$group = '_'.$module->getAlias();
$group = '_'.$module->getAlias();
$loader = new \Illuminate\Translation\FileLoader($this->files, $moduleLangPath);
$translations = \Lang::getLoader()->load( $locale, '*', '*' );
$translations = \Lang::getLoader()->load($locale, '*', '*');
if ( $translations && is_array( $translations ) ) {
foreach ( $translations as $key => $value ) {
$importedTranslation = $this->importTranslation( $key, $value, $locale, $group, $replace );
$counter += $importedTranslation ? 1 : 0;
if ($translations && is_array($translations)) {
foreach ($translations as $key => $value) {
$importedTranslation = $this->importTranslation($key, $value, $locale, $group, $replace);
$counter += $importedTranslation ? 1 : 0;
}
}
}
@ -173,9 +172,10 @@ class Manager
/**
* Remove translations which do not exist in files.
*
* @param [type] $existingTranslations [description]
* @return [type] [description]
*
* @param [type] $existingTranslations [description]
*
* @return [type] [description]
*/
public function removeNonexisting($existingTranslations)
{
@ -189,7 +189,7 @@ class Manager
// $moduleAliases[] = $matches[1];
// }
// }
$existingGroups = [];
// Get unique groups.
foreach ($existingTranslations as $key) {
@ -225,34 +225,34 @@ class Manager
}
}
public function importTranslation( $key, $value, $locale, $group, $replace = false )
public function importTranslation($key, $value, $locale, $group, $replace = false)
{
// process only string values
if ( is_array( $value ) ) {
if (is_array($value)) {
return false;
}
// Miss modules translations: fr.module.json
if (!preg_match("/^[a-zA-Z_]+$/", $locale)) {
if (!preg_match('/^[a-zA-Z_]+$/', $locale)) {
return false;
}
$value = (string) $value;
$translation = Translation::firstOrNew( [
$value = (string) $value;
$translation = Translation::firstOrNew([
'locale' => $locale,
'group' => $group,
'key' => $key,
] );
]);
// Check if the database is different then the files
$newStatus = $translation->value === $value ? Translation::STATUS_SAVED : Translation::STATUS_CHANGED;
if ( $newStatus !== (int) $translation->status ) {
if ($newStatus !== (int) $translation->status) {
$translation->status = $newStatus;
}
// Only replace when empty, or explicitly told so
if ( $replace || !$translation->value ) {
if ($replace || !$translation->value) {
$translation->value = $value;
}
@ -261,32 +261,32 @@ class Manager
return true;
}
public function findTranslations( $path = null )
public function findTranslations($path = null)
{
$path = $path ?: base_path();
$groupKeys = [];
$path = $path ?: base_path();
$groupKeys = [];
$stringKeys = [];
$functions = $this->config[ 'trans_functions' ];
$functions = $this->config['trans_functions'];
$groupPattern = // See http://regexr.com/392hu
"[^\w|>]" . // Must not have an alphanum or _ or > before real method
'(' . implode( '|', $functions ) . ')' . // Must start with one of the functions
"\(" . // Match opening parenthesis
"[\'\"]" . // Match " or '
'(' . // Start a new group to match:
'[a-zA-Z0-9_-]+' . // Must start with group
"([.|\/](?! )[^\1)]+)+" . // Be followed by one or more items/keys
')' . // Close group
"[\'\"]" . // Closing quote
"[^\w|>]". // Must not have an alphanum or _ or > before real method
'('.implode('|', $functions).')'. // Must start with one of the functions
"\(". // Match opening parenthesis
"[\'\"]". // Match " or '
'('. // Start a new group to match:
'[a-zA-Z0-9_-]+'. // Must start with group
"([.|\/](?! )[^\1)]+)+". // Be followed by one or more items/keys
')'. // Close group
"[\'\"]". // Closing quote
"[\),]"; // Close parentheses or new parameter
$stringPattern =
"[^\w|>]" . // Must not have an alphanum or _ or > before real method
'(' . implode( '|', $functions ) . ')' . // Must start with one of the functions
"\(" . // Match opening parenthesis
"(?P<quote>['\"])" . // Match " or ' and store in {quote}
"(?P<string>(?:\\\k{quote}|(?!\k{quote}).)*)" . // Match any string that can be {quote} escaped
"\k{quote}" . // Match " or ' previously matched
"[^\w|>]". // Must not have an alphanum or _ or > before real method
'('.implode('|', $functions).')'. // Must start with one of the functions
"\(". // Match opening parenthesis
"(?P<quote>['\"])". // Match " or ' and store in {quote}
"(?P<string>(?:\\\k{quote}|(?!\k{quote}).)*)". // Match any string that can be {quote} escaped
"\k{quote}". // Match " or ' previously matched
"[\),]"; // Close parentheses or new parameter
// Find all PHP + Twig files in the app folder, except for storage
@ -295,11 +295,11 @@ class Manager
if (!empty(request()->submit) && request()->submit == 'modules') {
// Find in modules.
$searchInModules = true;
$finder->in( $path.DIRECTORY_SEPARATOR.'Modules' )->exclude('vendor')->name( '*.php' )->name( '*.twig' )->name( '*.vue' )->files();
$finder->in($path.DIRECTORY_SEPARATOR.'Modules')->exclude('vendor')->name('*.php')->name('*.twig')->name('*.vue')->files();
} else {
// Find in core.
$exclude = ['bootstrap', 'config', 'database', 'public', 'routes', 'storage', 'tests', 'tools', 'vendor'];
$finder->in( $path )->exclude( $exclude )->name( '*.php' )->name( '*.twig' )->name( '*.vue' )->files();
$finder->in($path)->exclude($exclude)->name('*.php')->name('*.twig')->name('*.vue')->files();
// foreach ($exclude as $exclude_folder) {
// $finder->exclude($exclude_folder);
// }
@ -307,28 +307,27 @@ class Manager
}
/** @var \Symfony\Component\Finder\SplFileInfo $file */
foreach ( $finder as $file ) {
foreach ($finder as $file) {
// Search the current file for the pattern
if ( preg_match_all( "/$groupPattern/siU", $file->getContents(), $matches ) ) {
if (preg_match_all("/$groupPattern/siU", $file->getContents(), $matches)) {
// Get all matches
foreach ( $matches[ 2 ] as $key ) {
foreach ($matches[2] as $key) {
$group = explode('.', $key)[0];
if (!in_array($group, $this->config[ 'incorrect_groups'])) {
if (!in_array($group, $this->config['incorrect_groups'])) {
$groupKeys[] = $key;
}
}
}
if ( preg_match_all( "/$stringPattern/siU", $file->getContents(), $matches ) ) {
if (preg_match_all("/$stringPattern/siU", $file->getContents(), $matches)) {
$moduleAlias = '';
preg_match("/Modules\/([^\/]+)\//", $file->getPathname(), $m);
if (!empty($m[1])) {
$moduleAlias = strtolower($m[1]);
}
foreach ( $matches[ 'string' ] as $key ) {
if ( preg_match( "/(^[a-zA-Z0-9_-]+([.][^\1)\ ]+)+$)/siU", $key, $groupMatches ) ) {
foreach ($matches['string'] as $key) {
if (preg_match("/(^[a-zA-Z0-9_-]+([.][^\1)\ ]+)+$)/siU", $key, $groupMatches)) {
// group{.group}.key format, already in $groupKeys but also matched here
// do nothing, it has to be treated as a group
continue;
@ -337,15 +336,15 @@ class Manager
//TODO: This can probably be done in the regex, but I couldn't do it.
//skip keys which contain namespacing characters, unless they also contain a
//space, which makes it JSON.
if ( !( str_contains( $key, '::' ) && str_contains( $key, '.' ) )
|| str_contains( $key, ' ' ) ) {
if (!(str_contains($key, '::') && str_contains($key, '.'))
|| str_contains($key, ' ')) {
// Modules
//if ($searchInModules) {
if ($moduleAlias) {
//if ($moduleAlias) {
$groupKeys[] = '_'.$moduleAlias.'.'.$key;
// } else {
$groupKeys[] = '_'.$moduleAlias.'.'.$key;
// } else {
// continue;
// }
} else {
@ -356,21 +355,21 @@ class Manager
}
}
// Remove duplicates
$groupKeys = array_unique( $groupKeys );
$stringKeys = array_unique( $stringKeys );
$groupKeys = array_unique($groupKeys);
$stringKeys = array_unique($stringKeys);
// Add the translations to the database, if not existing.
// Modules translations are added here too.
foreach ( $groupKeys as $key ) {
foreach ($groupKeys as $key) {
// Split the group and item
list( $group, $item ) = explode( '.', $key, 2 );
$this->missingKey( '', $group, $item );
list($group, $item) = explode('.', $key, 2);
$this->missingKey('', $group, $item);
}
foreach ( $stringKeys as $key ) {
foreach ($stringKeys as $key) {
$group = self::JSON_GROUP;
$item = $key;
$this->missingKey( '', $group, $item );
$item = $key;
$this->missingKey('', $group, $item);
}
// Return the number of found translations
@ -378,20 +377,20 @@ class Manager
return $groupKeys + $stringKeys;
}
public function missingKey( $namespace, $group, $key )
public function missingKey($namespace, $group, $key)
{
if ( !in_array( $group, $this->config[ 'exclude_groups' ] ) ) {
Translation::firstOrCreate( [
'locale' => $this->app[ 'config' ][ 'app.locale' ],
if (!in_array($group, $this->config['exclude_groups'])) {
Translation::firstOrCreate([
'locale' => $this->app['config']['app.locale'],
'group' => $group,
'key' => $key,
] );
]);
}
}
public function exportTranslations( $group = null /*, $json = false*/ )
public function exportTranslations($group = null /*, $json = false*/)
{
$basePath = $this->app[ 'path.lang' ];
$basePath = $this->app['path.lang'];
$json = false;
// Detect json groups automatically.
@ -404,63 +403,63 @@ class Manager
$moduleAlias = substr($group, 1);
}
if ( !is_null( $group ) && !$json) {
if ( !in_array( $group, $this->config[ 'exclude_groups' ] ) ) {
if (!is_null($group) && !$json) {
if (!in_array($group, $this->config['exclude_groups'])) {
$vendor = false;
if ( $group == '*' ) {
if ($group == '*') {
return $this->exportAllTranslations();
} else {
if ( starts_with( $group, "vendor" ) ) {
if (starts_with($group, 'vendor')) {
$vendor = true;
}
}
$tree = $this->makeTree( Translation::ofTranslatedGroup( $group )
->orderByGroupKeys( array_get( $this->config, 'sort_keys', false ) )
->get() );
$tree = $this->makeTree(Translation::ofTranslatedGroup($group)
->orderByGroupKeys(array_get($this->config, 'sort_keys', false))
->get());
foreach ( $tree as $locale => $groups ) {
if ( isset( $groups[ $group ] ) ) {
$translations = $groups[ $group ];
$path = $this->app[ 'path.lang' ];
foreach ($tree as $locale => $groups) {
if (isset($groups[$group])) {
$translations = $groups[$group];
$path = $this->app['path.lang'];
$locale_path = $locale . DIRECTORY_SEPARATOR . $group;
if ( $vendor ) {
$path = $basePath . '/' . $group . '/' . $locale;
$locale_path = str_after( $group, "/" );
$locale_path = $locale.DIRECTORY_SEPARATOR.$group;
if ($vendor) {
$path = $basePath.'/'.$group.'/'.$locale;
$locale_path = str_after($group, '/');
}
$subfolders = explode( DIRECTORY_SEPARATOR, $locale_path );
array_pop( $subfolders );
$subfolders = explode(DIRECTORY_SEPARATOR, $locale_path);
array_pop($subfolders);
$subfolder_level = '';
foreach ( $subfolders as $subfolder ) {
$subfolder_level = $subfolder_level . $subfolder . DIRECTORY_SEPARATOR;
foreach ($subfolders as $subfolder) {
$subfolder_level = $subfolder_level.$subfolder.DIRECTORY_SEPARATOR;
$temp_path = rtrim( $path . DIRECTORY_SEPARATOR . $subfolder_level, DIRECTORY_SEPARATOR );
if ( !is_dir( $temp_path ) ) {
mkdir( $temp_path, 0777, true );
$temp_path = rtrim($path.DIRECTORY_SEPARATOR.$subfolder_level, DIRECTORY_SEPARATOR);
if (!is_dir($temp_path)) {
mkdir($temp_path, 0777, true);
}
}
$path = $path . DIRECTORY_SEPARATOR . $locale . DIRECTORY_SEPARATOR . $group . '.php';
$path = $path.DIRECTORY_SEPARATOR.$locale.DIRECTORY_SEPARATOR.$group.'.php';
$output = "<?php\n\nreturn " . var_export( $translations, true ) . ";" . \PHP_EOL;
$this->files->put( $path, $output );
$output = "<?php\n\nreturn ".var_export($translations, true).';'.\PHP_EOL;
$this->files->put($path, $output);
}
}
Translation::ofTranslatedGroup( $group )->update( [ 'status' => Translation::STATUS_SAVED ] );
Translation::ofTranslatedGroup($group)->update(['status' => Translation::STATUS_SAVED]);
}
}
if ( $json ) {
$tree = $this->makeTree( Translation::ofTranslatedGroup( $group )
->orderByGroupKeys( array_get( $this->config, 'sort_keys', false ) )
->get(), true );
if ($json) {
$tree = $this->makeTree(Translation::ofTranslatedGroup($group)
->orderByGroupKeys(array_get($this->config, 'sort_keys', false))
->get(), true);
foreach ( $tree as $locale => $groups ) {
foreach ($tree as $locale => $groups) {
if (!$moduleAlias) {
// _json
$path = $this->app[ 'path.lang' ] . '/' . $locale . '.json';
$path = $this->app['path.lang'].'/'.$locale.'.json';
} else {
// Export module translations into module's folder
$modulePath = \Module::getModulePathByAlias($moduleAlias);
@ -468,17 +467,17 @@ class Manager
if (!$modulePath) {
continue;
}
$path = $modulePath . 'Resources/lang/' . $locale . '.json';
$path = $modulePath.'Resources/lang/'.$locale.'.json';
}
$translations = $groups[ $group ];
$output = json_encode( $translations, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE );
$this->files->put( $path, $output );
$translations = $groups[$group];
$output = json_encode($translations, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE);
$this->files->put($path, $output);
// If it is a module, also export translation into the main langs folder.
if ($moduleAlias && $modulePath) {
$path = $this->app[ 'path.lang' ] . '/module.' . $moduleAlias . '.' . $locale . '.json';
$this->files->put( $path, $output );
$path = $this->app['path.lang'].'/module.'.$moduleAlias.'.'.$locale.'.json';
$this->files->put($path, $output);
}
// if ( isset( $groups[ self::JSON_GROUP ] ) ) {
// $translations = $groups[ self::JSON_GROUP ];
@ -488,18 +487,18 @@ class Manager
// }
}
Translation::ofTranslatedGroup( self::JSON_GROUP )->update( [ 'status' => Translation::STATUS_SAVED ] );
Translation::ofTranslatedGroup(self::JSON_GROUP)->update(['status' => Translation::STATUS_SAVED]);
}
$this->events->dispatch( new TranslationsExportedEvent() );
$this->events->dispatch(new TranslationsExportedEvent());
}
public function exportAllTranslations()
{
$groups = Translation::whereNotNull( 'value' )->selectDistinctGroup()->get( 'group' );
$groups = Translation::whereNotNull('value')->selectDistinctGroup()->get('group');
foreach ( $groups as $group ) {
$this->exportTranslations( $group->group );
foreach ($groups as $group) {
$this->exportTranslations($group->group);
// if ( $group->group == self::JSON_GROUP ) {
// $this->exportTranslations( null, true );
// } else {
@ -507,38 +506,38 @@ class Manager
// }
}
$this->events->dispatch( new TranslationsExportedEvent() );
$this->events->dispatch(new TranslationsExportedEvent());
}
protected function makeTree( $translations, $json = false )
protected function makeTree($translations, $json = false)
{
$array = [];
foreach ( $translations as $translation ) {
if ( $json ) {
$this->jsonSet( $array[ $translation->locale ][ $translation->group ], $translation->key,
$translation->value );
foreach ($translations as $translation) {
if ($json) {
$this->jsonSet($array[$translation->locale][$translation->group], $translation->key,
$translation->value);
} else {
array_set( $array[ $translation->locale ][ $translation->group ], $translation->key,
$translation->value );
array_set($array[$translation->locale][$translation->group], $translation->key,
$translation->value);
}
}
return $array;
}
public function jsonSet( &$array, $key, $value )
public function jsonSet(&$array, $key, $value)
{
if ( is_null( $key ) ) {
if (is_null($key)) {
return $array = $value;
}
$array[ $key ] = $value;
$array[$key] = $value;
return $array;
}
public function cleanTranslations()
{
Translation::whereNull( 'value' )->delete();
Translation::whereNull('value')->delete();
}
public function truncateTranslations()
@ -548,33 +547,32 @@ class Manager
public function getLocales()
{
if ( empty( $this->locales ) ) {
$locales = array_merge( [ config( 'app.locale' ) ],
Translation::groupBy( 'locale' )->pluck( 'locale' )->toArray() );
foreach ( $this->files->directories( $this->app->langPath() ) as $localeDir ) {
if ( ( $name = $this->files->name( $localeDir ) ) != 'vendor' ) {
if (empty($this->locales)) {
$locales = array_merge([config('app.locale')],
Translation::groupBy('locale')->pluck('locale')->toArray());
foreach ($this->files->directories($this->app->langPath()) as $localeDir) {
if (($name = $this->files->name($localeDir)) != 'vendor') {
$locales[] = $name;
}
}
$this->locales = array_unique( $locales );
sort( $this->locales );
$this->locales = array_unique($locales);
sort($this->locales);
}
return array_diff( $this->locales, $this->ignoreLocales );
return array_diff($this->locales, $this->ignoreLocales);
}
public function addLocale( $locale )
public function addLocale($locale)
{
$localeDir = $this->app->langPath() . '/' . $locale;
$localeDir = $this->app->langPath().'/'.$locale;
$this->ignoreLocales = array_diff( $this->ignoreLocales, [ $locale ] );
$this->ignoreLocales = array_diff($this->ignoreLocales, [$locale]);
$this->saveIgnoredLocales();
$this->ignoreLocales = $this->getIgnoredLocales();
if ( !$this->files->exists( $localeDir ) || !$this->files->isDirectory( $localeDir ) ) {
return $this->files->makeDirectory( $localeDir );
if (!$this->files->exists($localeDir) || !$this->files->isDirectory($localeDir)) {
return $this->files->makeDirectory($localeDir);
}
return true;
@ -582,34 +580,34 @@ class Manager
protected function saveIgnoredLocales()
{
return $this->files->put( $this->ignoreFilePath, json_encode( $this->ignoreLocales ) );
return $this->files->put($this->ignoreFilePath, json_encode($this->ignoreLocales));
}
public function removeLocale( $locale )
public function removeLocale($locale)
{
if ( !$locale ) {
if (!$locale) {
return false;
}
$this->ignoreLocales = array_merge( $this->ignoreLocales, [ $locale ] );
$this->ignoreLocales = array_merge($this->ignoreLocales, [$locale]);
// Only delete from DB.
//$this->saveIgnoredLocales();
$this->ignoreLocales = $this->getIgnoredLocales();
Translation::where( 'locale', $locale )->delete();
Translation::where('locale', $locale)->delete();
// Remove folder.
$localeDir = $this->app->langPath() . '/' . $locale;
if ( $this->files->exists( $localeDir )) {
$this->files->deleteDirectory( $localeDir );
$localeDir = $this->app->langPath().'/'.$locale;
if ($this->files->exists($localeDir)) {
$this->files->deleteDirectory($localeDir);
}
}
public function getConfig( $key = null )
public function getConfig($key = null)
{
if ( $key == null ) {
if ($key == null) {
return $this->config;
} else {
return $this->config[ $key ];
return $this->config[$key];
}
}
}

View File

@ -406,7 +406,6 @@ abstract class Repository implements RepositoryInterface, Countable
return $module;
}
}
return null;
}
/**
@ -515,8 +514,9 @@ abstract class Repository implements RepositoryInterface, Countable
try {
$module = $this->findByAlias($module_alias);
if (!$module) {
throw new ModuleNotFoundException("", 1);
throw new ModuleNotFoundException('', 1);
}
return $module->getPath().'/';
} catch (ModuleNotFoundException $e) {
//return $this->getPath().'/'.Str::studly($module).'/';

View File

@ -1,6 +1,6 @@
<?php
return array (
'failed' => 'These credentials do not match our records.',
return [
'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
);
];

View File

@ -1,9 +1,9 @@
<?php
return array (
return [
'password' => 'Passwords must be at least six characters and match the confirmation.',
'reset' => 'Your password has been reset!',
'sent' => 'We have e-mailed your password reset link!',
'token' => 'This password reset token is invalid.',
'user' => 'We can\'t find a user with that e-mail address.',
);
'reset' => 'Your password has been reset!',
'sent' => 'We have e-mailed your password reset link!',
'token' => 'This password reset token is invalid.',
'user' => 'We can\'t find a user with that e-mail address.',
];

View File

@ -1,89 +1,83 @@
<?php
return array (
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
return [
'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.',
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
'alpha' => 'The :attribute may only contain letters.',
'alpha_dash' => 'The :attribute may only contain letters, numbers, and dashes.',
'alpha_num' => 'The :attribute may only contain letters and numbers.',
'array' => 'The :attribute must be an array.',
'before' => 'The :attribute must be a date before :date.',
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
'between' =>
array (
'between' => [
'numeric' => 'The :attribute must be between :min and :max.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
),
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'file' => 'The :attribute must be between :min and :max kilobytes.',
'string' => 'The :attribute must be between :min and :max characters.',
'array' => 'The :attribute must have between :min and :max items.',
],
'boolean' => 'The :attribute field must be true or false.',
'confirmed' => 'The :attribute confirmation does not match.',
'date' => 'The :attribute is not a valid date.',
'date_format' => 'The :attribute does not match the format :format.',
'different' => 'The :attribute and :other must be different.',
'digits' => 'The :attribute must be :digits digits.',
'digits_between' => 'The :attribute must be between :min and :max digits.',
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'max' =>
array (
'dimensions' => 'The :attribute has invalid image dimensions.',
'distinct' => 'The :attribute field has a duplicate value.',
'email' => 'The :attribute must be a valid email address.',
'exists' => 'The selected :attribute is invalid.',
'file' => 'The :attribute must be a file.',
'filled' => 'The :attribute field must have a value.',
'image' => 'The :attribute must be an image.',
'in' => 'The selected :attribute is invalid.',
'in_array' => 'The :attribute field does not exist in :other.',
'integer' => 'The :attribute must be an integer.',
'ip' => 'The :attribute must be a valid IP address.',
'ipv4' => 'The :attribute must be a valid IPv4 address.',
'ipv6' => 'The :attribute must be a valid IPv6 address.',
'json' => 'The :attribute must be a valid JSON string.',
'max' => [
'numeric' => 'The :attribute may not be greater than :max.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
),
'mimes' => 'The :attribute must be a file of type: :values.',
'file' => 'The :attribute may not be greater than :max kilobytes.',
'string' => 'The :attribute may not be greater than :max characters.',
'array' => 'The :attribute may not have more than :max items.',
],
'mimes' => 'The :attribute must be a file of type: :values.',
'mimetypes' => 'The :attribute must be a file of type: :values.',
'min' =>
array (
'min' => [
'numeric' => 'The :attribute must be at least :min.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
),
'not_in' => 'The selected :attribute is invalid.',
'numeric' => 'The :attribute must be a number.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values is present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'file' => 'The :attribute must be at least :min kilobytes.',
'string' => 'The :attribute must be at least :min characters.',
'array' => 'The :attribute must have at least :min items.',
],
'not_in' => 'The selected :attribute is invalid.',
'numeric' => 'The :attribute must be a number.',
'present' => 'The :attribute field must be present.',
'regex' => 'The :attribute format is invalid.',
'required' => 'The :attribute field is required.',
'required_if' => 'The :attribute field is required when :other is :value.',
'required_unless' => 'The :attribute field is required unless :other is in :values.',
'required_with' => 'The :attribute field is required when :values is present.',
'required_with_all' => 'The :attribute field is required when :values is present.',
'required_without' => 'The :attribute field is required when :values is not present.',
'required_without_all' => 'The :attribute field is required when none of :values are present.',
'same' => 'The :attribute and :other must match.',
'size' =>
array (
'same' => 'The :attribute and :other must match.',
'size' => [
'numeric' => 'The :attribute must be :size.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
),
'string' => 'The :attribute must be a string.',
'file' => 'The :attribute must be :size kilobytes.',
'string' => 'The :attribute must be :size characters.',
'array' => 'The :attribute must contain :size items.',
],
'string' => 'The :attribute must be a string.',
'timezone' => 'The :attribute must be a valid zone.',
'unique' => 'The :attribute has already been taken.',
'unique' => 'The :attribute has already been taken.',
'uploaded' => 'The :attribute failed to upload.',
'url' => 'The :attribute format is invalid.',
'custom' =>
array (
'attribute-name' =>
array (
'url' => 'The :attribute format is invalid.',
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
),
),
);
],
],
];