Back | Home
الـ Path الحالي: /home/picotech/domains/instantly.picotech.app/public_html/public/./../app/.././../../finland.picotech.app/public_html/storage/../vendor/./phpoption/../laravel/../nikic/../telnyx/../brick/../unicodeveloper/../firebase/../ezyang/../maatwebsite/../nikic/../sebastian/../barryvdh/laravel-translation-manager/src
الملفات الموجودة في هذا الـ Path:
.
..
Console
Controller.php
Events
Manager.php
ManagerServiceProvider.php
Models
TranslationServiceProvider.php
Translator.php
routes.php
مشاهدة ملف: Manager.php
<?php
namespace Barryvdh\TranslationManager;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Symfony\Component\Finder\Finder;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Contracts\Foundation\Application;
use Barryvdh\TranslationManager\Models\Translation;
use Barryvdh\TranslationManager\Events\TranslationsExportedEvent;
class Manager
{
const JSON_GROUP = '_json';
/** @var \Illuminate\Contracts\Foundation\Application */
protected $app;
/** @var \Illuminate\Filesystem\Filesystem */
protected $files;
/** @var \Illuminate\Contracts\Events\Dispatcher */
protected $events;
protected $config;
protected $locales;
protected $ignoreLocales;
protected $ignoreFilePath;
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();
}
protected function getIgnoredLocales()
{
if (! $this->files->exists($this->ignoreFilePath)) {
return [];
}
$result = json_decode($this->files->get($this->ignoreFilePath));
return ($result && is_array($result)) ? $result : [];
}
public function importTranslations($replace = false, $base = null, $import_group = false)
{
$counter = 0;
//allows for vendor lang files to be properly recorded through recursion.
$vendor = true;
if ($base == null) {
$base = $this->app['path.lang'];
$vendor = false;
}
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);
}
continue;
}
$vendorName = $this->files->name($this->files->dirname($langPath));
foreach ($this->files->allfiles($langPath) as $file) {
$info = pathinfo($file);
$group = $info['filename'];
if ($import_group) {
if ($import_group !== $group) {
continue;
}
}
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);
if ($subLangPath != $langPath) {
$group = $subLangPath.'/'.$group;
}
if (! $vendor) {
$translations = \Lang::getLoader()->load($locale, $group);
} else {
$translations = include $file;
$group = 'vendor/'.$vendorName;
}
if ($translations && is_array($translations)) {
foreach (Arr::dot($translations) as $key => $value) {
$importedTranslation = $this->importTranslation($key, $value, $locale, $group, $replace);
$counter += $importedTranslation ? 1 : 0;
}
}
}
}
foreach ($this->files->files($this->app['path.lang']) as $jsonTranslationFile) {
if (strpos($jsonTranslationFile, '.json') === false) {
continue;
}
$locale = basename($jsonTranslationFile, '.json');
$group = self::JSON_GROUP;
$translations =
\Lang::getLoader()->load($locale, '*', '*'); // Retrieves JSON entries of the given locale only
if ($translations && is_array($translations)) {
foreach ($translations as $key => $value) {
$importedTranslation = $this->importTranslation($key, $value, $locale, $group, $replace);
$counter += $importedTranslation ? 1 : 0;
}
}
}
return $counter;
}
public function importTranslation($key, $value, $locale, $group, $replace = false)
{
// process only string values
if (is_array($value)) {
return false;
}
$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) {
$translation->status = $newStatus;
}
// Only replace when empty, or explicitly told so
if ($replace || ! $translation->value) {
$translation->value = $value;
}
$translation->save();
return true;
}
public function findTranslations($path = null)
{
$path = $path ?: base_path();
$groupKeys = [];
$stringKeys = [];
$functions = $this->config['trans_functions'];
$groupPattern = // See https://regex101.com/r/WEJqdL/6
"[^\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 before real method
'('.implode('|', $functions).')'. // Must start with one of the functions
"\(\s*". // 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
"\s*[\),]"; // Close parentheses or new parameter
// Find all PHP + Twig files in the app folder, except for storage
$finder = new Finder();
$finder->in($path)->exclude('storage')->exclude('vendor')->name('*.php')->name('*.twig')->name('*.vue')->files();
/** @var \Symfony\Component\Finder\SplFileInfo $file */
foreach ($finder as $file) {
// Search the current file for the pattern
if (preg_match_all("/$groupPattern/siU", $file->getContents(), $matches)) {
// Get all matches
foreach ($matches[2] as $key) {
$groupKeys[] = $key;
}
}
if (preg_match_all("/$stringPattern/siU", $file->getContents(), $matches)) {
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;
}
//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, ' ')) {
$stringKeys[] = $key;
}
}
}
}
// Remove duplicates
$groupKeys = array_unique($groupKeys);
$stringKeys = array_unique($stringKeys);
// Add the translations to the database, if not existing.
foreach ($groupKeys as $key) {
// Split the group and item
list($group, $item) = explode('.', $key, 2);
$this->missingKey('', $group, $item);
}
foreach ($stringKeys as $key) {
$group = self::JSON_GROUP;
$item = $key;
$this->missingKey('', $group, $item);
}
// Return the number of found translations
return count($groupKeys + $stringKeys);
}
public function missingKey($namespace, $group, $key)
{
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)
{
$group = basename($group);
$basePath = $this->app['path.lang'];
if (! is_null($group) && ! $json) {
if (! in_array($group, $this->config['exclude_groups'])) {
$vendor = false;
if ($group == '*') {
return $this->exportAllTranslations();
} else {
if (Str::startsWith($group, 'vendor')) {
$vendor = true;
}
}
$tree = $this->makeTree(Translation::ofTranslatedGroup($group)
->orderByGroupKeys(Arr::get($this->config, 'sort_keys', false))
->get());
foreach ($tree as $locale => $groups) {
$locale = basename($locale);
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, '/');
}
$subfolders = explode(DIRECTORY_SEPARATOR, $locale_path);
array_pop($subfolders);
$subfolder_level = '';
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);
}
}
if ($vendor) {
$path = $path.DIRECTORY_SEPARATOR.'messages.php';
} else {
$path = $path.DIRECTORY_SEPARATOR.$locale.DIRECTORY_SEPARATOR.$group.'.php';
}
$output = "<?php\n\nreturn ".var_export($translations, true).';'.\PHP_EOL;
$this->files->put($path, $output);
}
}
Translation::ofTranslatedGroup($group)->update(['status' => Translation::STATUS_SAVED]);
}
}
if ($json) {
$tree = $this->makeTree(Translation::ofTranslatedGroup(self::JSON_GROUP)
->orderByGroupKeys(Arr::get($this->config, 'sort_keys', false))
->get(), true);
foreach ($tree as $locale => $groups) {
if (isset($groups[self::JSON_GROUP])) {
$translations = $groups[self::JSON_GROUP];
$path = $this->app['path.lang'].'/'.$locale.'.json';
$output = json_encode($translations, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_UNICODE);
$this->files->put($path, $output);
}
}
Translation::ofTranslatedGroup(self::JSON_GROUP)->update(['status' => Translation::STATUS_SAVED]);
}
$this->events->dispatch(new TranslationsExportedEvent());
}
public function exportAllTranslations()
{
$groups = Translation::whereNotNull('value')->selectDistinctGroup()->get('group');
foreach ($groups as $group) {
if ($group->group == self::JSON_GROUP) {
$this->exportTranslations(null, true);
} else {
$this->exportTranslations($group->group);
}
}
$this->events->dispatch(new TranslationsExportedEvent());
}
protected function makeTree($translations, $json = false)
{
$array = [];
foreach ($translations as $translation) {
// For JSON and sentences, do not use dotted notation
if ($json || Str::contains($translation->key, [' ']) || Str::endsWith($translation->key, ['.'])) {
$this->jsonSet($array[$translation->locale][$translation->group], $translation->key,
$translation->value);
} else {
Arr::set($array[$translation->locale][$translation->group], $translation->key,
$translation->value);
}
}
return $array;
}
public function jsonSet(&$array, $key, $value)
{
if (is_null($key)) {
return $array = $value;
}
$array[$key] = $value;
return $array;
}
public function cleanTranslations()
{
Translation::whereNull('value')->delete();
}
public function truncateTranslations()
{
Translation::truncate();
}
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') {
$locales[] = $name;
}
}
$this->locales = array_unique($locales);
sort($this->locales);
}
return array_diff($this->locales, $this->ignoreLocales);
}
public function addLocale($locale)
{
$localeDir = $this->app->langPath().'/'.basename($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);
}
return true;
}
protected function saveIgnoredLocales()
{
return $this->files->put($this->ignoreFilePath, json_encode($this->ignoreLocales));
}
public function removeLocale($locale)
{
if (! $locale) {
return false;
}
$this->ignoreLocales = array_merge($this->ignoreLocales, [$locale]);
$this->saveIgnoredLocales();
$this->ignoreLocales = $this->getIgnoredLocales();
Translation::where('locale', $locale)->delete();
}
public function getConfig($key = null)
{
if ($key == null) {
return $this->config;
} else {
return $this->config[$key];
}
}
}