vendor and env first commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
use Illuminate\Contracts\Translation\Loader;
|
||||
|
||||
class ArrayLoader implements Loader
|
||||
{
|
||||
/**
|
||||
* All of the translation messages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $messages = [];
|
||||
|
||||
/**
|
||||
* Load the messages for the given locale.
|
||||
*
|
||||
* @param string $locale
|
||||
* @param string $group
|
||||
* @param string|null $namespace
|
||||
* @return array
|
||||
*/
|
||||
public function load($locale, $group, $namespace = null)
|
||||
{
|
||||
$namespace = $namespace ?: '*';
|
||||
|
||||
return $this->messages[$namespace][$locale][$group] ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new namespace to the loader.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $hint
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($namespace, $hint)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new JSON path to the loader.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function addJsonPath($path)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Add messages to the loader.
|
||||
*
|
||||
* @param string $locale
|
||||
* @param string $group
|
||||
* @param array $messages
|
||||
* @param string|null $namespace
|
||||
* @return $this
|
||||
*/
|
||||
public function addMessages($locale, $group, array $messages, $namespace = null)
|
||||
{
|
||||
$namespace = $namespace ?: '*';
|
||||
|
||||
$this->messages[$namespace][$locale][$group] = $messages;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all the registered namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function namespaces()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
trait CreatesPotentiallyTranslatedStrings
|
||||
{
|
||||
/**
|
||||
* Create a pending potentially translated string.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $message
|
||||
* @return \Illuminate\Translation\PotentiallyTranslatedString
|
||||
*/
|
||||
protected function pendingPotentiallyTranslatedString($attribute, $message)
|
||||
{
|
||||
$destructor = $message === null
|
||||
? fn ($message) => $this->messages[] = $message
|
||||
: fn ($message) => $this->messages[$attribute] = $message;
|
||||
|
||||
return new class($message ?? $attribute, $this->validator->getTranslator(), $destructor) extends PotentiallyTranslatedString
|
||||
{
|
||||
/**
|
||||
* The callback to call when the object destructs.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $destructor;
|
||||
|
||||
/**
|
||||
* Create a new pending potentially translated string.
|
||||
*
|
||||
* @param string $message
|
||||
* @param \Illuminate\Contracts\Translation\Translator $translator
|
||||
* @param \Closure $destructor
|
||||
*/
|
||||
public function __construct($message, $translator, $destructor)
|
||||
{
|
||||
parent::__construct($message, $translator);
|
||||
|
||||
$this->destructor = $destructor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the object's destruction.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
($this->destructor)($this->toString());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
use Illuminate\Contracts\Translation\Loader;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use RuntimeException;
|
||||
|
||||
class FileLoader implements Loader
|
||||
{
|
||||
/**
|
||||
* The filesystem instance.
|
||||
*
|
||||
* @var \Illuminate\Filesystem\Filesystem
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
/**
|
||||
* The default paths for the loader.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $paths;
|
||||
|
||||
/**
|
||||
* All of the registered paths to JSON translation files.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $jsonPaths = [];
|
||||
|
||||
/**
|
||||
* All of the namespace hints.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hints = [];
|
||||
|
||||
/**
|
||||
* Create a new file loader instance.
|
||||
*
|
||||
* @param \Illuminate\Filesystem\Filesystem $files
|
||||
* @param array|string $path
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Filesystem $files, array|string $path)
|
||||
{
|
||||
$this->files = $files;
|
||||
|
||||
$this->paths = is_string($path) ? [$path] : $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the messages for the given locale.
|
||||
*
|
||||
* @param string $locale
|
||||
* @param string $group
|
||||
* @param string|null $namespace
|
||||
* @return array
|
||||
*/
|
||||
public function load($locale, $group, $namespace = null)
|
||||
{
|
||||
if ($group === '*' && $namespace === '*') {
|
||||
return $this->loadJsonPaths($locale);
|
||||
}
|
||||
|
||||
if (is_null($namespace) || $namespace === '*') {
|
||||
return $this->loadPaths($this->paths, $locale, $group);
|
||||
}
|
||||
|
||||
return $this->loadNamespaced($locale, $group, $namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a namespaced translation group.
|
||||
*
|
||||
* @param string $locale
|
||||
* @param string $group
|
||||
* @param string $namespace
|
||||
* @return array
|
||||
*/
|
||||
protected function loadNamespaced($locale, $group, $namespace)
|
||||
{
|
||||
if (isset($this->hints[$namespace])) {
|
||||
$lines = $this->loadPaths([$this->hints[$namespace]], $locale, $group);
|
||||
|
||||
return $this->loadNamespaceOverrides($lines, $locale, $group, $namespace);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a local namespaced translation group for overrides.
|
||||
*
|
||||
* @param array $lines
|
||||
* @param string $locale
|
||||
* @param string $group
|
||||
* @param string $namespace
|
||||
* @return array
|
||||
*/
|
||||
protected function loadNamespaceOverrides(array $lines, $locale, $group, $namespace)
|
||||
{
|
||||
return collect($this->paths)
|
||||
->reduce(function ($output, $path) use ($lines, $locale, $group, $namespace) {
|
||||
$file = "{$path}/vendor/{$namespace}/{$locale}/{$group}.php";
|
||||
|
||||
if ($this->files->exists($file)) {
|
||||
$lines = array_replace_recursive($lines, $this->files->getRequire($file));
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a locale from a given path.
|
||||
*
|
||||
* @param array $paths
|
||||
* @param string $locale
|
||||
* @param string $group
|
||||
* @return array
|
||||
*/
|
||||
protected function loadPaths(array $paths, $locale, $group)
|
||||
{
|
||||
return collect($paths)
|
||||
->reduce(function ($output, $path) use ($locale, $group) {
|
||||
if ($this->files->exists($full = "{$path}/{$locale}/{$group}.php")) {
|
||||
$output = array_replace_recursive($output, $this->files->getRequire($full));
|
||||
}
|
||||
|
||||
return $output;
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a locale from the given JSON file path.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
protected function loadJsonPaths($locale)
|
||||
{
|
||||
return collect(array_merge($this->jsonPaths, $this->paths))
|
||||
->reduce(function ($output, $path) use ($locale) {
|
||||
if ($this->files->exists($full = "{$path}/{$locale}.json")) {
|
||||
$decoded = json_decode($this->files->get($full), true);
|
||||
|
||||
if (is_null($decoded) || json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new RuntimeException("Translation file [{$full}] contains an invalid JSON structure.");
|
||||
}
|
||||
|
||||
$output = array_merge($output, $decoded);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new namespace to the loader.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $hint
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($namespace, $hint)
|
||||
{
|
||||
$this->hints[$namespace] = $hint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all the registered namespaces.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function namespaces()
|
||||
{
|
||||
return $this->hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new JSON path to the loader.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function addJsonPath($path)
|
||||
{
|
||||
$this->jsonPaths[] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all the registered paths to JSON translation files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function jsonPaths()
|
||||
{
|
||||
return $this->jsonPaths;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Taylor Otwell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,410 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
class MessageSelector
|
||||
{
|
||||
/**
|
||||
* Select a proper translation string based on the given number.
|
||||
*
|
||||
* @param string $line
|
||||
* @param int $number
|
||||
* @param string $locale
|
||||
* @return mixed
|
||||
*/
|
||||
public function choose($line, $number, $locale)
|
||||
{
|
||||
$segments = explode('|', $line);
|
||||
|
||||
if (($value = $this->extract($segments, $number)) !== null) {
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
$segments = $this->stripConditions($segments);
|
||||
|
||||
$pluralIndex = $this->getPluralIndex($locale, $number);
|
||||
|
||||
if (count($segments) === 1 || ! isset($segments[$pluralIndex])) {
|
||||
return $segments[0];
|
||||
}
|
||||
|
||||
return $segments[$pluralIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a translation string using inline conditions.
|
||||
*
|
||||
* @param array $segments
|
||||
* @param int $number
|
||||
* @return mixed
|
||||
*/
|
||||
private function extract($segments, $number)
|
||||
{
|
||||
foreach ($segments as $part) {
|
||||
if (! is_null($line = $this->extractFromString($part, $number))) {
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation string if the condition matches.
|
||||
*
|
||||
* @param string $part
|
||||
* @param int $number
|
||||
* @return mixed
|
||||
*/
|
||||
private function extractFromString($part, $number)
|
||||
{
|
||||
preg_match('/^[\{\[]([^\[\]\{\}]*)[\}\]](.*)/s', $part, $matches);
|
||||
|
||||
if (count($matches) !== 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$condition = $matches[1];
|
||||
|
||||
$value = $matches[2];
|
||||
|
||||
if (str_contains($condition, ',')) {
|
||||
[$from, $to] = explode(',', $condition, 2);
|
||||
|
||||
if ($to === '*' && $number >= $from) {
|
||||
return $value;
|
||||
} elseif ($from === '*' && $number <= $to) {
|
||||
return $value;
|
||||
} elseif ($number >= $from && $number <= $to) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $condition == $number ? $value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip the inline conditions from each segment, just leaving the text.
|
||||
*
|
||||
* @param array $segments
|
||||
* @return array
|
||||
*/
|
||||
private function stripConditions($segments)
|
||||
{
|
||||
return collect($segments)
|
||||
->map(fn ($part) => preg_replace('/^[\{\[]([^\[\]\{\}]*)[\}\]]/', '', $part))
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index to use for pluralization.
|
||||
*
|
||||
* The plural rules are derived from code of the Zend Framework (2010-09-25), which
|
||||
* is subject to the new BSD license (https://framework.zend.com/license)
|
||||
* Copyright (c) 2005-2010 - Zend Technologies USA Inc. (http://www.zend.com)
|
||||
*
|
||||
* @param string $locale
|
||||
* @param int $number
|
||||
* @return int
|
||||
*/
|
||||
public function getPluralIndex($locale, $number)
|
||||
{
|
||||
switch ($locale) {
|
||||
case 'az':
|
||||
case 'az_AZ':
|
||||
case 'bo':
|
||||
case 'bo_CN':
|
||||
case 'bo_IN':
|
||||
case 'dz':
|
||||
case 'dz_BT':
|
||||
case 'id':
|
||||
case 'id_ID':
|
||||
case 'ja':
|
||||
case 'ja_JP':
|
||||
case 'jv':
|
||||
case 'ka':
|
||||
case 'ka_GE':
|
||||
case 'km':
|
||||
case 'km_KH':
|
||||
case 'kn':
|
||||
case 'kn_IN':
|
||||
case 'ko':
|
||||
case 'ko_KR':
|
||||
case 'ms':
|
||||
case 'ms_MY':
|
||||
case 'th':
|
||||
case 'th_TH':
|
||||
case 'tr':
|
||||
case 'tr_CY':
|
||||
case 'tr_TR':
|
||||
case 'vi':
|
||||
case 'vi_VN':
|
||||
case 'zh':
|
||||
case 'zh_CN':
|
||||
case 'zh_HK':
|
||||
case 'zh_SG':
|
||||
case 'zh_TW':
|
||||
return 0;
|
||||
case 'af':
|
||||
case 'af_ZA':
|
||||
case 'bn':
|
||||
case 'bn_BD':
|
||||
case 'bn_IN':
|
||||
case 'bg':
|
||||
case 'bg_BG':
|
||||
case 'ca':
|
||||
case 'ca_AD':
|
||||
case 'ca_ES':
|
||||
case 'ca_FR':
|
||||
case 'ca_IT':
|
||||
case 'da':
|
||||
case 'da_DK':
|
||||
case 'de':
|
||||
case 'de_AT':
|
||||
case 'de_BE':
|
||||
case 'de_CH':
|
||||
case 'de_DE':
|
||||
case 'de_LI':
|
||||
case 'de_LU':
|
||||
case 'el':
|
||||
case 'el_CY':
|
||||
case 'el_GR':
|
||||
case 'en':
|
||||
case 'en_AG':
|
||||
case 'en_AU':
|
||||
case 'en_BW':
|
||||
case 'en_CA':
|
||||
case 'en_DK':
|
||||
case 'en_GB':
|
||||
case 'en_HK':
|
||||
case 'en_IE':
|
||||
case 'en_IN':
|
||||
case 'en_NG':
|
||||
case 'en_NZ':
|
||||
case 'en_PH':
|
||||
case 'en_SG':
|
||||
case 'en_US':
|
||||
case 'en_ZA':
|
||||
case 'en_ZM':
|
||||
case 'en_ZW':
|
||||
case 'eo':
|
||||
case 'eo_US':
|
||||
case 'es':
|
||||
case 'es_AR':
|
||||
case 'es_BO':
|
||||
case 'es_CL':
|
||||
case 'es_CO':
|
||||
case 'es_CR':
|
||||
case 'es_CU':
|
||||
case 'es_DO':
|
||||
case 'es_EC':
|
||||
case 'es_ES':
|
||||
case 'es_GT':
|
||||
case 'es_HN':
|
||||
case 'es_MX':
|
||||
case 'es_NI':
|
||||
case 'es_PA':
|
||||
case 'es_PE':
|
||||
case 'es_PR':
|
||||
case 'es_PY':
|
||||
case 'es_SV':
|
||||
case 'es_US':
|
||||
case 'es_UY':
|
||||
case 'es_VE':
|
||||
case 'et':
|
||||
case 'et_EE':
|
||||
case 'eu':
|
||||
case 'eu_ES':
|
||||
case 'eu_FR':
|
||||
case 'fa':
|
||||
case 'fa_IR':
|
||||
case 'fi':
|
||||
case 'fi_FI':
|
||||
case 'fo':
|
||||
case 'fo_FO':
|
||||
case 'fur':
|
||||
case 'fur_IT':
|
||||
case 'fy':
|
||||
case 'fy_DE':
|
||||
case 'fy_NL':
|
||||
case 'gl':
|
||||
case 'gl_ES':
|
||||
case 'gu':
|
||||
case 'gu_IN':
|
||||
case 'ha':
|
||||
case 'ha_NG':
|
||||
case 'he':
|
||||
case 'he_IL':
|
||||
case 'hu':
|
||||
case 'hu_HU':
|
||||
case 'is':
|
||||
case 'is_IS':
|
||||
case 'it':
|
||||
case 'it_CH':
|
||||
case 'it_IT':
|
||||
case 'ku':
|
||||
case 'ku_TR':
|
||||
case 'lb':
|
||||
case 'lb_LU':
|
||||
case 'ml':
|
||||
case 'ml_IN':
|
||||
case 'mn':
|
||||
case 'mn_MN':
|
||||
case 'mr':
|
||||
case 'mr_IN':
|
||||
case 'nah':
|
||||
case 'nb':
|
||||
case 'nb_NO':
|
||||
case 'ne':
|
||||
case 'ne_NP':
|
||||
case 'nl':
|
||||
case 'nl_AW':
|
||||
case 'nl_BE':
|
||||
case 'nl_NL':
|
||||
case 'nn':
|
||||
case 'nn_NO':
|
||||
case 'no':
|
||||
case 'om':
|
||||
case 'om_ET':
|
||||
case 'om_KE':
|
||||
case 'or':
|
||||
case 'or_IN':
|
||||
case 'pa':
|
||||
case 'pa_IN':
|
||||
case 'pa_PK':
|
||||
case 'pap':
|
||||
case 'pap_AN':
|
||||
case 'pap_AW':
|
||||
case 'pap_CW':
|
||||
case 'ps':
|
||||
case 'ps_AF':
|
||||
case 'pt':
|
||||
case 'pt_BR':
|
||||
case 'pt_PT':
|
||||
case 'so':
|
||||
case 'so_DJ':
|
||||
case 'so_ET':
|
||||
case 'so_KE':
|
||||
case 'so_SO':
|
||||
case 'sq':
|
||||
case 'sq_AL':
|
||||
case 'sq_MK':
|
||||
case 'sv':
|
||||
case 'sv_FI':
|
||||
case 'sv_SE':
|
||||
case 'sw':
|
||||
case 'sw_KE':
|
||||
case 'sw_TZ':
|
||||
case 'ta':
|
||||
case 'ta_IN':
|
||||
case 'ta_LK':
|
||||
case 'te':
|
||||
case 'te_IN':
|
||||
case 'tk':
|
||||
case 'tk_TM':
|
||||
case 'ur':
|
||||
case 'ur_IN':
|
||||
case 'ur_PK':
|
||||
case 'zu':
|
||||
case 'zu_ZA':
|
||||
return ($number == 1) ? 0 : 1;
|
||||
case 'am':
|
||||
case 'am_ET':
|
||||
case 'bh':
|
||||
case 'fil':
|
||||
case 'fil_PH':
|
||||
case 'fr':
|
||||
case 'fr_BE':
|
||||
case 'fr_CA':
|
||||
case 'fr_CH':
|
||||
case 'fr_FR':
|
||||
case 'fr_LU':
|
||||
case 'gun':
|
||||
case 'hi':
|
||||
case 'hi_IN':
|
||||
case 'hy':
|
||||
case 'hy_AM':
|
||||
case 'ln':
|
||||
case 'ln_CD':
|
||||
case 'mg':
|
||||
case 'mg_MG':
|
||||
case 'nso':
|
||||
case 'nso_ZA':
|
||||
case 'ti':
|
||||
case 'ti_ER':
|
||||
case 'ti_ET':
|
||||
case 'wa':
|
||||
case 'wa_BE':
|
||||
case 'xbr':
|
||||
return (($number == 0) || ($number == 1)) ? 0 : 1;
|
||||
case 'be':
|
||||
case 'be_BY':
|
||||
case 'bs':
|
||||
case 'bs_BA':
|
||||
case 'hr':
|
||||
case 'hr_HR':
|
||||
case 'ru':
|
||||
case 'ru_RU':
|
||||
case 'ru_UA':
|
||||
case 'sr':
|
||||
case 'sr_ME':
|
||||
case 'sr_RS':
|
||||
case 'uk':
|
||||
case 'uk_UA':
|
||||
return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
|
||||
case 'cs':
|
||||
case 'cs_CZ':
|
||||
case 'sk':
|
||||
case 'sk_SK':
|
||||
return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);
|
||||
case 'ga':
|
||||
case 'ga_IE':
|
||||
return ($number == 1) ? 0 : (($number == 2) ? 1 : 2);
|
||||
case 'lt':
|
||||
case 'lt_LT':
|
||||
return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
|
||||
case 'sl':
|
||||
case 'sl_SI':
|
||||
return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3));
|
||||
case 'mk':
|
||||
case 'mk_MK':
|
||||
return ($number % 10 == 1) ? 0 : 1;
|
||||
case 'mt':
|
||||
case 'mt_MT':
|
||||
return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));
|
||||
case 'lv':
|
||||
case 'lv_LV':
|
||||
return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2);
|
||||
case 'pl':
|
||||
case 'pl_PL':
|
||||
return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);
|
||||
case 'cy':
|
||||
case 'cy_GB':
|
||||
return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3));
|
||||
case 'ro':
|
||||
case 'ro_RO':
|
||||
return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);
|
||||
case 'ar':
|
||||
case 'ar_AE':
|
||||
case 'ar_BH':
|
||||
case 'ar_DZ':
|
||||
case 'ar_EG':
|
||||
case 'ar_IN':
|
||||
case 'ar_IQ':
|
||||
case 'ar_JO':
|
||||
case 'ar_KW':
|
||||
case 'ar_LB':
|
||||
case 'ar_LY':
|
||||
case 'ar_MA':
|
||||
case 'ar_OM':
|
||||
case 'ar_QA':
|
||||
case 'ar_SA':
|
||||
case 'ar_SD':
|
||||
case 'ar_SS':
|
||||
case 'ar_SY':
|
||||
case 'ar_TN':
|
||||
case 'ar_YE':
|
||||
return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
use Stringable;
|
||||
|
||||
class PotentiallyTranslatedString implements Stringable
|
||||
{
|
||||
/**
|
||||
* The string that may be translated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $string;
|
||||
|
||||
/**
|
||||
* The translated string.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $translation;
|
||||
|
||||
/**
|
||||
* The validator that may perform the translation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Translation\Translator
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
/**
|
||||
* Create a new potentially translated string.
|
||||
*
|
||||
* @param string $string
|
||||
* @param \Illuminate\Contracts\Translation\Translator $translator
|
||||
*/
|
||||
public function __construct($string, $translator)
|
||||
{
|
||||
$this->string = $string;
|
||||
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the string.
|
||||
*
|
||||
* @param array $replace
|
||||
* @param string|null $locale
|
||||
* @return $this
|
||||
*/
|
||||
public function translate($replace = [], $locale = null)
|
||||
{
|
||||
$this->translation = $this->translator->get($this->string, $replace, $locale);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the string based on a count.
|
||||
*
|
||||
* @param \Countable|int|float|array $number
|
||||
* @param array $replace
|
||||
* @param string|null $locale
|
||||
* @return $this
|
||||
*/
|
||||
public function translateChoice($number, array $replace = [], $locale = null)
|
||||
{
|
||||
$this->translation = $this->translator->choice($this->string, $number, $replace, $locale);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the original string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function original()
|
||||
{
|
||||
return $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the potentially translated string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->translation ?? $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the potentially translated string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString()
|
||||
{
|
||||
return (string) $this;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
use Illuminate\Contracts\Support\DeferrableProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class TranslationServiceProvider extends ServiceProvider implements DeferrableProvider
|
||||
{
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->registerLoader();
|
||||
|
||||
$this->app->singleton('translator', function ($app) {
|
||||
$loader = $app['translation.loader'];
|
||||
|
||||
// When registering the translator component, we'll need to set the default
|
||||
// locale as well as the fallback locale. So, we'll grab the application
|
||||
// configuration so we can easily get both of these values from there.
|
||||
$locale = $app->getLocale();
|
||||
|
||||
$trans = new Translator($loader, $locale);
|
||||
|
||||
$trans->setFallback($app->getFallbackLocale());
|
||||
|
||||
return $trans;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the translation line loader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function registerLoader()
|
||||
{
|
||||
$this->app->singleton('translation.loader', function ($app) {
|
||||
return new FileLoader($app['files'], [__DIR__.'/lang', $app['path.lang']]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return ['translator', 'translation.loader'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,567 @@
|
||||
<?php
|
||||
|
||||
namespace Illuminate\Translation;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Translation\Loader;
|
||||
use Illuminate\Contracts\Translation\Translator as TranslatorContract;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\NamespacedItemResolver;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Illuminate\Support\Traits\ReflectsClosures;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Translator extends NamespacedItemResolver implements TranslatorContract
|
||||
{
|
||||
use Macroable, ReflectsClosures;
|
||||
|
||||
/**
|
||||
* The loader implementation.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Translation\Loader
|
||||
*/
|
||||
protected $loader;
|
||||
|
||||
/**
|
||||
* The default locale being used by the translator.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $locale;
|
||||
|
||||
/**
|
||||
* The fallback locale used by the translator.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $fallback;
|
||||
|
||||
/**
|
||||
* The array of loaded translation groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $loaded = [];
|
||||
|
||||
/**
|
||||
* The message selector.
|
||||
*
|
||||
* @var \Illuminate\Translation\MessageSelector
|
||||
*/
|
||||
protected $selector;
|
||||
|
||||
/**
|
||||
* The callable that should be invoked to determine applicable locales.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $determineLocalesUsing;
|
||||
|
||||
/**
|
||||
* The custom rendering callbacks for stringable objects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $stringableHandlers = [];
|
||||
|
||||
/**
|
||||
* The callback that is responsible for handling missing translation keys.
|
||||
*
|
||||
* @var callable|null
|
||||
*/
|
||||
protected $missingTranslationKeyCallback;
|
||||
|
||||
/**
|
||||
* Indicates whether missing translation keys should be handled.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $handleMissingTranslationKeys = true;
|
||||
|
||||
/**
|
||||
* Create a new translator instance.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Translation\Loader $loader
|
||||
* @param string $locale
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Loader $loader, $locale)
|
||||
{
|
||||
$this->loader = $loader;
|
||||
|
||||
$this->setLocale($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a translation exists for a given locale.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|null $locale
|
||||
* @return bool
|
||||
*/
|
||||
public function hasForLocale($key, $locale = null)
|
||||
{
|
||||
return $this->has($key, $locale, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a translation exists.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|null $locale
|
||||
* @param bool $fallback
|
||||
* @return bool
|
||||
*/
|
||||
public function has($key, $locale = null, $fallback = true)
|
||||
{
|
||||
$locale = $locale ?: $this->locale;
|
||||
|
||||
$line = $this->get($key, [], $locale, $fallback);
|
||||
|
||||
// For JSON translations, the loaded files will contain the correct line.
|
||||
// Otherwise, we must assume we are handling typical translation file
|
||||
// and check if the returned line is not the same as the given key.
|
||||
if (! is_null($this->loaded['*']['*'][$locale][$key] ?? null)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $line !== $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the translation for the given key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $replace
|
||||
* @param string|null $locale
|
||||
* @param bool $fallback
|
||||
* @return string|array
|
||||
*/
|
||||
public function get($key, array $replace = [], $locale = null, $fallback = true)
|
||||
{
|
||||
$locale = $locale ?: $this->locale;
|
||||
|
||||
// For JSON translations, there is only one file per locale, so we will simply load
|
||||
// that file and then we will be ready to check the array for the key. These are
|
||||
// only one level deep so we do not need to do any fancy searching through it.
|
||||
$this->load('*', '*', $locale);
|
||||
|
||||
$line = $this->loaded['*']['*'][$locale][$key] ?? null;
|
||||
|
||||
// If we can't find a translation for the JSON key, we will attempt to translate it
|
||||
// using the typical translation file. This way developers can always just use a
|
||||
// helper such as __ instead of having to pick between trans or __ with views.
|
||||
if (! isset($line)) {
|
||||
[$namespace, $group, $item] = $this->parseKey($key);
|
||||
|
||||
// Here we will get the locale that should be used for the language line. If one
|
||||
// was not passed, we will use the default locales which was given to us when
|
||||
// the translator was instantiated. Then, we can load the lines and return.
|
||||
$locales = $fallback ? $this->localeArray($locale) : [$locale];
|
||||
|
||||
foreach ($locales as $languageLineLocale) {
|
||||
if (! is_null($line = $this->getLine(
|
||||
$namespace, $group, $languageLineLocale, $item, $replace
|
||||
))) {
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
$key = $this->handleMissingTranslationKey(
|
||||
$key, $replace, $locale, $fallback
|
||||
);
|
||||
}
|
||||
|
||||
// If the line doesn't exist, we will return back the key which was requested as
|
||||
// that will be quick to spot in the UI if language keys are wrong or missing
|
||||
// from the application's language files. Otherwise we can return the line.
|
||||
return $this->makeReplacements($line ?: $key, $replace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a translation according to an integer value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param \Countable|int|float|array $number
|
||||
* @param array $replace
|
||||
* @param string|null $locale
|
||||
* @return string
|
||||
*/
|
||||
public function choice($key, $number, array $replace = [], $locale = null)
|
||||
{
|
||||
$line = $this->get(
|
||||
$key, $replace, $locale = $this->localeForChoice($locale)
|
||||
);
|
||||
|
||||
// If the given "number" is actually an array or countable we will simply count the
|
||||
// number of elements in an instance. This allows developers to pass an array of
|
||||
// items without having to count it on their end first which gives bad syntax.
|
||||
if (is_countable($number)) {
|
||||
$number = count($number);
|
||||
}
|
||||
|
||||
$replace['count'] = $number;
|
||||
|
||||
return $this->makeReplacements(
|
||||
$this->getSelector()->choose($line, $number, $locale), $replace
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the proper locale for a choice operation.
|
||||
*
|
||||
* @param string|null $locale
|
||||
* @return string
|
||||
*/
|
||||
protected function localeForChoice($locale)
|
||||
{
|
||||
return $locale ?: $this->locale ?: $this->fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a language line out the loaded array.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $group
|
||||
* @param string $locale
|
||||
* @param string $item
|
||||
* @param array $replace
|
||||
* @return string|array|null
|
||||
*/
|
||||
protected function getLine($namespace, $group, $locale, $item, array $replace)
|
||||
{
|
||||
$this->load($namespace, $group, $locale);
|
||||
|
||||
$line = Arr::get($this->loaded[$namespace][$group][$locale], $item);
|
||||
|
||||
if (is_string($line)) {
|
||||
return $this->makeReplacements($line, $replace);
|
||||
} elseif (is_array($line) && count($line) > 0) {
|
||||
array_walk_recursive($line, function (&$value, $key) use ($replace) {
|
||||
$value = $this->makeReplacements($value, $replace);
|
||||
});
|
||||
|
||||
return $line;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the place-holder replacements on a line.
|
||||
*
|
||||
* @param string $line
|
||||
* @param array $replace
|
||||
* @return string
|
||||
*/
|
||||
protected function makeReplacements($line, array $replace)
|
||||
{
|
||||
if (empty($replace)) {
|
||||
return $line;
|
||||
}
|
||||
|
||||
$shouldReplace = [];
|
||||
|
||||
foreach ($replace as $key => $value) {
|
||||
if ($value instanceof Closure) {
|
||||
$line = preg_replace_callback(
|
||||
'/<'.$key.'>(.*?)<\/'.$key.'>/',
|
||||
fn ($args) => $value($args[1]),
|
||||
$line
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_object($value) && isset($this->stringableHandlers[get_class($value)])) {
|
||||
$value = call_user_func($this->stringableHandlers[get_class($value)], $value);
|
||||
}
|
||||
|
||||
$shouldReplace[':'.Str::ucfirst($key ?? '')] = Str::ucfirst($value ?? '');
|
||||
$shouldReplace[':'.Str::upper($key ?? '')] = Str::upper($value ?? '');
|
||||
$shouldReplace[':'.$key] = $value;
|
||||
}
|
||||
|
||||
return strtr($line, $shouldReplace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add translation lines to the given locale.
|
||||
*
|
||||
* @param array $lines
|
||||
* @param string $locale
|
||||
* @param string $namespace
|
||||
* @return void
|
||||
*/
|
||||
public function addLines(array $lines, $locale, $namespace = '*')
|
||||
{
|
||||
foreach ($lines as $key => $value) {
|
||||
[$group, $item] = explode('.', $key, 2);
|
||||
|
||||
Arr::set($this->loaded, "$namespace.$group.$locale.$item", $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the specified language group.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $group
|
||||
* @param string $locale
|
||||
* @return void
|
||||
*/
|
||||
public function load($namespace, $group, $locale)
|
||||
{
|
||||
if ($this->isLoaded($namespace, $group, $locale)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The loader is responsible for returning the array of language lines for the
|
||||
// given namespace, group, and locale. We'll set the lines in this array of
|
||||
// lines that have already been loaded so that we can easily access them.
|
||||
$lines = $this->loader->load($locale, $group, $namespace);
|
||||
|
||||
$this->loaded[$namespace][$group][$locale] = $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given group has been loaded.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $group
|
||||
* @param string $locale
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLoaded($namespace, $group, $locale)
|
||||
{
|
||||
return isset($this->loaded[$namespace][$group][$locale]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a missing translation key.
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $replace
|
||||
* @param string|null $locale
|
||||
* @param bool $fallback
|
||||
* @return string
|
||||
*/
|
||||
protected function handleMissingTranslationKey($key, $replace, $locale, $fallback)
|
||||
{
|
||||
if (! $this->handleMissingTranslationKeys ||
|
||||
! isset($this->missingTranslationKeyCallback)) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
// Prevent infinite loops...
|
||||
$this->handleMissingTranslationKeys = false;
|
||||
|
||||
$key = call_user_func(
|
||||
$this->missingTranslationKeyCallback,
|
||||
$key, $replace, $locale, $fallback
|
||||
) ?? $key;
|
||||
|
||||
$this->handleMissingTranslationKeys = true;
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback that is responsible for handling missing translation keys.
|
||||
*
|
||||
* @param callable|null $callback
|
||||
* @return static
|
||||
*/
|
||||
public function handleMissingKeysUsing(?callable $callback)
|
||||
{
|
||||
$this->missingTranslationKeyCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new namespace to the loader.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $hint
|
||||
* @return void
|
||||
*/
|
||||
public function addNamespace($namespace, $hint)
|
||||
{
|
||||
$this->loader->addNamespace($namespace, $hint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new JSON path to the loader.
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function addJsonPath($path)
|
||||
{
|
||||
$this->loader->addJsonPath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a key into namespace, group, and item.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array
|
||||
*/
|
||||
public function parseKey($key)
|
||||
{
|
||||
$segments = parent::parseKey($key);
|
||||
|
||||
if (is_null($segments[0])) {
|
||||
$segments[0] = '*';
|
||||
}
|
||||
|
||||
return $segments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the array of locales to be checked.
|
||||
*
|
||||
* @param string|null $locale
|
||||
* @return array
|
||||
*/
|
||||
protected function localeArray($locale)
|
||||
{
|
||||
$locales = array_filter([$locale ?: $this->locale, $this->fallback]);
|
||||
|
||||
return call_user_func($this->determineLocalesUsing ?: fn () => $locales, $locales);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a callback that should be invoked to determined the applicable locale array.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return void
|
||||
*/
|
||||
public function determineLocalesUsing($callback)
|
||||
{
|
||||
$this->determineLocalesUsing = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message selector instance.
|
||||
*
|
||||
* @return \Illuminate\Translation\MessageSelector
|
||||
*/
|
||||
public function getSelector()
|
||||
{
|
||||
if (! isset($this->selector)) {
|
||||
$this->selector = new MessageSelector;
|
||||
}
|
||||
|
||||
return $this->selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the message selector instance.
|
||||
*
|
||||
* @param \Illuminate\Translation\MessageSelector $selector
|
||||
* @return void
|
||||
*/
|
||||
public function setSelector(MessageSelector $selector)
|
||||
{
|
||||
$this->selector = $selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language line loader implementation.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Translation\Loader
|
||||
*/
|
||||
public function getLoader()
|
||||
{
|
||||
return $this->loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default locale being used.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function locale()
|
||||
{
|
||||
return $this->getLocale();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default locale being used.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default locale.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return void
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setLocale($locale)
|
||||
{
|
||||
if (Str::contains($locale, ['/', '\\'])) {
|
||||
throw new InvalidArgumentException('Invalid characters present in locale.');
|
||||
}
|
||||
|
||||
$this->locale = $locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fallback locale being used.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFallback()
|
||||
{
|
||||
return $this->fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fallback locale being used.
|
||||
*
|
||||
* @param string $fallback
|
||||
* @return void
|
||||
*/
|
||||
public function setFallback($fallback)
|
||||
{
|
||||
$this->fallback = $fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the loaded translation groups.
|
||||
*
|
||||
* @param array $loaded
|
||||
* @return void
|
||||
*/
|
||||
public function setLoaded(array $loaded)
|
||||
{
|
||||
$this->loaded = $loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a handler to be executed in order to format a given class to a string during translation replacements.
|
||||
*
|
||||
* @param callable|string $class
|
||||
* @param callable|null $handler
|
||||
* @return void
|
||||
*/
|
||||
public function stringable($class, $handler = null)
|
||||
{
|
||||
if ($class instanceof Closure) {
|
||||
[$class, $handler] = [
|
||||
$this->firstClosureParameterType($class),
|
||||
$class,
|
||||
];
|
||||
}
|
||||
|
||||
$this->stringableHandlers[$class] = $handler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "illuminate/translation",
|
||||
"description": "The Illuminate Translation package.",
|
||||
"license": "MIT",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"illuminate/collections": "^11.0",
|
||||
"illuminate/contracts": "^11.0",
|
||||
"illuminate/macroable": "^11.0",
|
||||
"illuminate/filesystem": "^11.0",
|
||||
"illuminate/support": "^11.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Translation\\": ""
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "11.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'password' => 'The provided password is incorrect.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
|
||||
];
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Previous',
|
||||
'next' => 'Next »',
|
||||
|
||||
];
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| outcome such as failure due to an invalid password / reset token.
|
||||
|
|
||||
*/
|
||||
|
||||
'reset' => 'Your password has been reset.',
|
||||
'sent' => 'We have emailed your password reset link.',
|
||||
'throttled' => 'Please wait before retrying.',
|
||||
'token' => 'This password reset token is invalid.',
|
||||
'user' => "We can't find a user with that email address.",
|
||||
|
||||
];
|
||||
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => 'The :attribute field must be accepted.',
|
||||
'accepted_if' => 'The :attribute field must be accepted when :other is :value.',
|
||||
'active_url' => 'The :attribute field must be a valid URL.',
|
||||
'after' => 'The :attribute field must be a date after :date.',
|
||||
'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',
|
||||
'alpha' => 'The :attribute field must only contain letters.',
|
||||
'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',
|
||||
'alpha_num' => 'The :attribute field must only contain letters and numbers.',
|
||||
'array' => 'The :attribute field must be an array.',
|
||||
'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',
|
||||
'before' => 'The :attribute field must be a date before :date.',
|
||||
'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',
|
||||
'between' => [
|
||||
'array' => 'The :attribute field must have between :min and :max items.',
|
||||
'file' => 'The :attribute field must be between :min and :max kilobytes.',
|
||||
'numeric' => 'The :attribute field must be between :min and :max.',
|
||||
'string' => 'The :attribute field must be between :min and :max characters.',
|
||||
],
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'can' => 'The :attribute field contains an unauthorized value.',
|
||||
'confirmed' => 'The :attribute field confirmation does not match.',
|
||||
'contains' => 'The :attribute field is missing a required value.',
|
||||
'current_password' => 'The password is incorrect.',
|
||||
'date' => 'The :attribute field must be a valid date.',
|
||||
'date_equals' => 'The :attribute field must be a date equal to :date.',
|
||||
'date_format' => 'The :attribute field must match the format :format.',
|
||||
'decimal' => 'The :attribute field must have :decimal decimal places.',
|
||||
'declined' => 'The :attribute field must be declined.',
|
||||
'declined_if' => 'The :attribute field must be declined when :other is :value.',
|
||||
'different' => 'The :attribute field and :other must be different.',
|
||||
'digits' => 'The :attribute field must be :digits digits.',
|
||||
'digits_between' => 'The :attribute field must be between :min and :max digits.',
|
||||
'dimensions' => 'The :attribute field has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.',
|
||||
'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.',
|
||||
'email' => 'The :attribute field must be a valid email address.',
|
||||
'ends_with' => 'The :attribute field must end with one of the following: :values.',
|
||||
'enum' => 'The selected :attribute is invalid.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'extensions' => 'The :attribute field must have one of the following extensions: :values.',
|
||||
'file' => 'The :attribute field must be a file.',
|
||||
'filled' => 'The :attribute field must have a value.',
|
||||
'gt' => [
|
||||
'array' => 'The :attribute field must have more than :value items.',
|
||||
'file' => 'The :attribute field must be greater than :value kilobytes.',
|
||||
'numeric' => 'The :attribute field must be greater than :value.',
|
||||
'string' => 'The :attribute field must be greater than :value characters.',
|
||||
],
|
||||
'gte' => [
|
||||
'array' => 'The :attribute field must have :value items or more.',
|
||||
'file' => 'The :attribute field must be greater than or equal to :value kilobytes.',
|
||||
'numeric' => 'The :attribute field must be greater than or equal to :value.',
|
||||
'string' => 'The :attribute field must be greater than or equal to :value characters.',
|
||||
],
|
||||
'hex_color' => 'The :attribute field must be a valid hexadecimal color.',
|
||||
'image' => 'The :attribute field must be an image.',
|
||||
'in' => 'The selected :attribute is invalid.',
|
||||
'in_array' => 'The :attribute field must exist in :other.',
|
||||
'integer' => 'The :attribute field must be an integer.',
|
||||
'ip' => 'The :attribute field must be a valid IP address.',
|
||||
'ipv4' => 'The :attribute field must be a valid IPv4 address.',
|
||||
'ipv6' => 'The :attribute field must be a valid IPv6 address.',
|
||||
'json' => 'The :attribute field must be a valid JSON string.',
|
||||
'list' => 'The :attribute field must be a list.',
|
||||
'lowercase' => 'The :attribute field must be lowercase.',
|
||||
'lt' => [
|
||||
'array' => 'The :attribute field must have less than :value items.',
|
||||
'file' => 'The :attribute field must be less than :value kilobytes.',
|
||||
'numeric' => 'The :attribute field must be less than :value.',
|
||||
'string' => 'The :attribute field must be less than :value characters.',
|
||||
],
|
||||
'lte' => [
|
||||
'array' => 'The :attribute field must not have more than :value items.',
|
||||
'file' => 'The :attribute field must be less than or equal to :value kilobytes.',
|
||||
'numeric' => 'The :attribute field must be less than or equal to :value.',
|
||||
'string' => 'The :attribute field must be less than or equal to :value characters.',
|
||||
],
|
||||
'mac_address' => 'The :attribute field must be a valid MAC address.',
|
||||
'max' => [
|
||||
'array' => 'The :attribute field must not have more than :max items.',
|
||||
'file' => 'The :attribute field must not be greater than :max kilobytes.',
|
||||
'numeric' => 'The :attribute field must not be greater than :max.',
|
||||
'string' => 'The :attribute field must not be greater than :max characters.',
|
||||
],
|
||||
'max_digits' => 'The :attribute field must not have more than :max digits.',
|
||||
'mimes' => 'The :attribute field must be a file of type: :values.',
|
||||
'mimetypes' => 'The :attribute field must be a file of type: :values.',
|
||||
'min' => [
|
||||
'array' => 'The :attribute field must have at least :min items.',
|
||||
'file' => 'The :attribute field must be at least :min kilobytes.',
|
||||
'numeric' => 'The :attribute field must be at least :min.',
|
||||
'string' => 'The :attribute field must be at least :min characters.',
|
||||
],
|
||||
'min_digits' => 'The :attribute field must have at least :min digits.',
|
||||
'missing' => 'The :attribute field must be missing.',
|
||||
'missing_if' => 'The :attribute field must be missing when :other is :value.',
|
||||
'missing_unless' => 'The :attribute field must be missing unless :other is :value.',
|
||||
'missing_with' => 'The :attribute field must be missing when :values is present.',
|
||||
'missing_with_all' => 'The :attribute field must be missing when :values are present.',
|
||||
'multiple_of' => 'The :attribute field must be a multiple of :value.',
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'not_regex' => 'The :attribute field format is invalid.',
|
||||
'numeric' => 'The :attribute field must be a number.',
|
||||
'password' => [
|
||||
'letters' => 'The :attribute field must contain at least one letter.',
|
||||
'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.',
|
||||
'numbers' => 'The :attribute field must contain at least one number.',
|
||||
'symbols' => 'The :attribute field must contain at least one symbol.',
|
||||
'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
|
||||
],
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'present_if' => 'The :attribute field must be present when :other is :value.',
|
||||
'present_unless' => 'The :attribute field must be present unless :other is :value.',
|
||||
'present_with' => 'The :attribute field must be present when :values is present.',
|
||||
'present_with_all' => 'The :attribute field must be present when :values are present.',
|
||||
'prohibited' => 'The :attribute field is prohibited.',
|
||||
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
|
||||
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
|
||||
'prohibits' => 'The :attribute field prohibits :other from being present.',
|
||||
'regex' => 'The :attribute field format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_array_keys' => 'The :attribute field must contain entries for: :values.',
|
||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||
'required_if_accepted' => 'The :attribute field is required when :other is accepted.',
|
||||
'required_if_declined' => 'The :attribute field is required when :other is declined.',
|
||||
'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 are 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 field must match :other.',
|
||||
'size' => [
|
||||
'array' => 'The :attribute field must contain :size items.',
|
||||
'file' => 'The :attribute field must be :size kilobytes.',
|
||||
'numeric' => 'The :attribute field must be :size.',
|
||||
'string' => 'The :attribute field must be :size characters.',
|
||||
],
|
||||
'starts_with' => 'The :attribute field must start with one of the following: :values.',
|
||||
'string' => 'The :attribute field must be a string.',
|
||||
'timezone' => 'The :attribute field must be a valid timezone.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'uploaded' => 'The :attribute failed to upload.',
|
||||
'uppercase' => 'The :attribute field must be uppercase.',
|
||||
'url' => 'The :attribute field must be a valid URL.',
|
||||
'ulid' => 'The :attribute field must be a valid ULID.',
|
||||
'uuid' => 'The :attribute field must be a valid UUID.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap our attribute placeholder
|
||||
| with something more reader friendly such as "E-Mail Address" instead
|
||||
| of "email". This simply helps us make our message more expressive.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
||||
Reference in New Issue
Block a user