File manager - Edit - /home/opticamezl/www/newok/Language.zip
Back
PK у�\ ��ѣ � CachingLanguageFactory.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Caching factory for creating language objects. The requested languages are * cached in memory. * * @since 4.0.0 */ class CachingLanguageFactory extends LanguageFactory { /** * Array of Language objects * * @var Language[] * @since 4.0.0 */ private static $languages = []; /** * Method to get an instance of a language. * * @param string $lang The language to use * @param boolean $debug The debug mode * * @return Language * * @since 4.0.0 */ public function createLanguage($lang, $debug = false): Language { if (!isset(self::$languages[$lang . $debug])) { self::$languages[$lang . $debug] = parent::createLanguage($lang, $debug); } return self::$languages[$lang . $debug]; } } PK у�\�>>5L L LanguageFactory.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Default factory for creating language objects * * @since 4.0.0 */ class LanguageFactory implements LanguageFactoryInterface { /** * Method to get an instance of a language. * * @param string $lang The language to use * @param boolean $debug The debug mode * * @return Language * * @since 4.0.0 */ public function createLanguage($lang, $debug = false): Language { return new Language($lang, $debug); } } PK у�\S�fH� � LanguageAwareTrait.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Defines the trait for a language aware class. * * @since 4.4.0 */ trait LanguageAwareTrait { /** * Language * * @var Language * @since 4.4.0 */ private $language; /** * Get the Language. * * @return Language * * @since 4.4.0 * @throws \UnexpectedValueException May be thrown if the language has not been set. */ protected function getLanguage(): Language { if ($this->language) { return $this->language; } throw new \UnexpectedValueException('Language not set in ' . __CLASS__); } /** * Set the language to use. * * @param Language $language The language to use * * @return void * * @since 4.4.0 */ public function setLanguage(Language $language): void { $this->language = $language; } } PK у�\psg� � Multilanguage.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2012 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; use Joomla\Database\DatabaseInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Utility class for multilang * * @since 2.5.4 */ class Multilanguage { /** * Flag indicating multilanguage functionality is enabled. * * @var boolean * @since 4.0.0 */ public static $enabled = false; /** * Method to determine if the language filter plugin is enabled. * This works for both site and administrator. * * @param ?CMSApplication $app The application * @param ?DatabaseInterface $db The database * * @return boolean True if site is supporting multiple languages; false otherwise. * * @since 2.5.4 */ public static function isEnabled(CMSApplication $app = null, DatabaseInterface $db = null) { // Flag to avoid doing multiple database queries. static $tested = false; // Do not proceed with testing if the flag is true if (static::$enabled) { return true; } // Get application object. $app = $app ?: Factory::getApplication(); // If being called from the frontend, we can avoid the database query. if ($app->isClient('site')) { static::$enabled = $app->getLanguageFilter(); return static::$enabled; } // If already tested, don't test again. if (!$tested) { // Determine status of language filter plugin. $db = $db ?: Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('enabled')) ->from($db->quoteName('#__extensions')) ->where( [ $db->quoteName('type') . ' = ' . $db->quote('plugin'), $db->quoteName('folder') . ' = ' . $db->quote('system'), $db->quoteName('element') . ' = ' . $db->quote('languagefilter'), ] ); $db->setQuery($query); static::$enabled = (bool) $db->loadResult(); $tested = true; } return static::$enabled; } /** * Method to return a list of language home page menu items. * * @param ?DatabaseInterface $db The database * * @return array of menu objects. * * @since 3.5 */ public static function getSiteHomePages(DatabaseInterface $db = null) { // To avoid doing duplicate database queries. static $multilangSiteHomePages = null; if (!isset($multilangSiteHomePages)) { // Check for Home pages languages. $db = $db ?: Factory::getDbo(); $query = $db->getQuery(true) ->select( [ $db->quoteName('language'), $db->quoteName('id'), ] ) ->from($db->quoteName('#__menu')) ->where( [ $db->quoteName('home') . ' = ' . $db->quote('1'), $db->quoteName('published') . ' = 1', $db->quoteName('client_id') . ' = 0', ] ); $db->setQuery($query); $multilangSiteHomePages = $db->loadObjectList('language'); } return $multilangSiteHomePages; } } PK у�\}�)j� � Transliterate.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Class to transliterate strings * * @since 1.7.0 * @note Port of phputf8's utf8_accents_to_ascii() */ class Transliterate { /** * Returns strings transliterated from UTF-8 to Latin * * @param string $string String to transliterate * @param integer $case Optionally specify upper or lower case. Default to null. * * @return string Transliterated string * * @since 1.7.0 */ public static function utf8_latin_to_ascii($string, $case = 0) { static $UTF8_LOWER_ACCENTS = null; static $UTF8_UPPER_ACCENTS = null; if ($case <= 0) { if (\is_null($UTF8_LOWER_ACCENTS)) { $UTF8_LOWER_ACCENTS = [ 'à' => 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o', 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k', 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o', 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o', 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c', 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't', 'ū' => 'u', 'č' => 'c', 'ö' => 'oe', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l', 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z', 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't', 'ŗ' => 'r', 'ä' => 'ae', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'ue', 'ò' => 'o', 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j', 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o', 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g', 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a', 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', 'œ' => 'oe', ]; } $string = str_replace(array_keys($UTF8_LOWER_ACCENTS), array_values($UTF8_LOWER_ACCENTS), $string); } if ($case >= 0) { if (\is_null($UTF8_UPPER_ACCENTS)) { $UTF8_UPPER_ACCENTS = [ 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O', 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O', 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O', 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C', 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T', 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'Oe', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L', 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z', 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T', 'Ŗ' => 'R', 'Ä' => 'Ae', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'Ue', 'Ò' => 'O', 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J', 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O', 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G', 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A', 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', 'Ĕ' => 'E', 'Œ' => 'Oe', ]; } $string = str_replace(array_keys($UTF8_UPPER_ACCENTS), array_values($UTF8_UPPER_ACCENTS), $string); } return $string; } } PK у�\4�b�EV EV LanguageHelper.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; use Joomla\CMS\Cache\CacheControllerFactoryInterface; use Joomla\CMS\Cache\Controller\OutputController; use Joomla\CMS\Factory; use Joomla\CMS\Installer\Installer; use Joomla\CMS\Log\Log; use Joomla\Filesystem\File; use Joomla\Registry\Registry; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Language helper class * * @since 1.5 */ class LanguageHelper { /** * Builds a list of the system languages which can be used in a select option * * @param string $actualLanguage Client key for the area * @param string $basePath Base path to use * @param boolean $caching True if caching is used * @param boolean $installed Get only installed languages * * @return array List of system languages * * @since 1.5 */ public static function createLanguageList($actualLanguage, $basePath = JPATH_BASE, $caching = false, $installed = false) { $list = []; $clientId = $basePath === JPATH_ADMINISTRATOR ? 1 : 0; $languages = $installed ? static::getInstalledLanguages($clientId, true) : self::getKnownLanguages($basePath); foreach ($languages as $languageCode => $language) { $metadata = $installed ? $language->metadata : $language; $list[] = [ 'text' => $metadata['nativeName'] ?? $metadata['name'], 'value' => $languageCode, 'selected' => $languageCode === $actualLanguage ? 'selected="selected"' : null, ]; } return $list; } /** * Tries to detect the language. * * @return string locale or null if not found * * @since 1.5 */ public static function detectLanguage() { if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $browserLangs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $systemLangs = self::getLanguages(); foreach ($browserLangs as $browserLang) { // Slice out the part before ; on first step, the part before - on second, place into array $browserLang = substr($browserLang, 0, strcspn($browserLang, ';')); $primary_browserLang = substr($browserLang, 0, 2); foreach ($systemLangs as $systemLang) { // Take off 3 letters iso code languages as they can't match browsers' languages and default them to en $Jinstall_lang = $systemLang->lang_code; if (\strlen($Jinstall_lang) < 6) { if (strtolower($browserLang) == strtolower(substr($systemLang->lang_code, 0, \strlen($browserLang)))) { return $systemLang->lang_code; } elseif ($primary_browserLang == substr($systemLang->lang_code, 0, 2)) { $primaryDetectedLang = $systemLang->lang_code; } } } if (isset($primaryDetectedLang)) { return $primaryDetectedLang; } } } } /** * Get available languages * * @param string $key Array key * * @return array An array of published languages * * @since 1.6 */ public static function getLanguages($key = 'default') { static $languages = []; if (!count($languages)) { // Installation uses available languages if (Factory::getApplication()->isClient('installation')) { $languages[$key] = []; $knownLangs = self::getKnownLanguages(JPATH_BASE); foreach ($knownLangs as $metadata) { // Take off 3 letters iso code languages as they can't match browsers' languages and default them to en $obj = new \stdClass(); $obj->lang_code = $metadata['tag']; $languages[$key][] = $obj; } } else { /** @var OutputController $cache */ $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class) ->createCacheController('output', ['defaultgroup' => 'com_languages']); if ($cache->contains('languages')) { $languages = $cache->get('languages'); } else { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__languages')) ->where($db->quoteName('published') . ' = 1') ->order($db->quoteName('ordering') . ' ASC'); $db->setQuery($query); $languages['default'] = $db->loadObjectList(); $languages['sef'] = []; $languages['lang_code'] = []; if (isset($languages['default'][0])) { foreach ($languages['default'] as $lang) { $languages['sef'][$lang->sef] = $lang; $languages['lang_code'][$lang->lang_code] = $lang; } } $cache->store($languages, 'languages'); } } } return $languages[$key]; } /** * Get a list of installed languages. * * @param integer $clientId The client app id. * @param boolean $processMetaData Fetch Language metadata. * @param boolean $processManifest Fetch Language manifest. * @param string $pivot The pivot of the returning array. * @param string $orderField Field to order the results. * @param string $orderDirection Direction to order the results. * * @return array Array with the installed languages. * * @since 3.7.0 */ public static function getInstalledLanguages( $clientId = null, $processMetaData = false, $processManifest = false, $pivot = 'element', $orderField = null, $orderDirection = null ) { static $installedLanguages = null; if ($installedLanguages === null) { /** @var OutputController $cache */ $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class) ->createCacheController('output', ['defaultgroup' => 'com_languages']); if ($cache->contains('installedlanguages')) { $installedLanguages = $cache->get('installedlanguages'); } else { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select( [ $db->quoteName('element'), $db->quoteName('name'), $db->quoteName('client_id'), $db->quoteName('extension_id'), ] ) ->from($db->quoteName('#__extensions')) ->where( [ $db->quoteName('type') . ' = ' . $db->quote('language'), $db->quoteName('state') . ' = 0', $db->quoteName('enabled') . ' = 1', ] ); $installedLanguages = $db->setQuery($query)->loadObjectList(); $cache->store($installedLanguages, 'installedlanguages'); } } $clients = $clientId === null ? [0, 1] : [(int) $clientId]; $languages = [ 0 => [], 1 => [], ]; foreach ($installedLanguages as $language) { // If the language client is not needed continue cycle. Drop for performance. if (!\in_array((int) $language->client_id, $clients)) { continue; } $lang = $language; if ($processMetaData || $processManifest) { $clientPath = (int) $language->client_id === 0 ? JPATH_SITE : JPATH_ADMINISTRATOR; $metafile = self::getLanguagePath($clientPath, $language->element) . '/langmetadata.xml'; if (!is_file($metafile)) { $metafile = self::getLanguagePath($clientPath, $language->element) . '/' . $language->element . '.xml'; } // Process the language metadata. if ($processMetaData) { try { $lang->metadata = self::parseXMLLanguageFile($metafile); } catch (\Exception $e) { // Not able to process xml language file. Fail silently. Log::add(Text::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METAFILE', $language->element, $metafile), Log::WARNING, 'language'); continue; } // No metadata found, not a valid language. Fail silently. if (!\is_array($lang->metadata)) { Log::add(Text::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METADATA', $language->element, $metafile), Log::WARNING, 'language'); continue; } } // Process the language manifest. if ($processManifest) { try { $lang->manifest = Installer::parseXMLInstallFile($metafile); } catch (\Exception $e) { // Not able to process xml language file. Fail silently. Log::add(Text::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METAFILE', $language->element, $metafile), Log::WARNING, 'language'); continue; } // No metadata found, not a valid language. Fail silently. if (!\is_array($lang->manifest)) { Log::add(Text::sprintf('JLIB_LANGUAGE_ERROR_CANNOT_LOAD_METADATA', $language->element, $metafile), Log::WARNING, 'language'); continue; } } } $languages[$language->client_id][] = $lang; } // Order the list, if needed. if ($orderField !== null && $orderDirection !== null) { $orderDirection = strtolower($orderDirection) === 'desc' ? -1 : 1; foreach ($languages as $cId => $language) { // If the language client is not needed continue cycle. Drop for performance. if (!\in_array($cId, $clients)) { continue; } $languages[$cId] = ArrayHelper::sortObjects($languages[$cId], $orderField, $orderDirection, true, true); } } // Add the pivot, if needed. if ($pivot !== null) { foreach ($languages as $cId => $language) { // If the language client is not needed continue cycle. Drop for performance. if (!\in_array($cId, $clients)) { continue; } $languages[$cId] = ArrayHelper::pivot($languages[$cId], $pivot); } } return $clientId !== null ? $languages[$clientId] : $languages; } /** * Get a list of content languages. * * @param array $publishedStates Array with the content language published states. Empty array for all. * @param boolean $checkInstalled Check if the content language is installed. * @param string $pivot The pivot of the returning array. * @param string $orderField Field to order the results. * @param string $orderDirection Direction to order the results. * * @return array Array of the content languages. * * @since 3.7.0 */ public static function getContentLanguages( $publishedStates = [1], $checkInstalled = true, $pivot = 'lang_code', $orderField = null, $orderDirection = null ) { static $contentLanguages = null; if ($contentLanguages === null) { /** @var OutputController $cache */ $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class) ->createCacheController('output', ['defaultgroup' => 'com_languages']); if ($cache->contains('contentlanguages')) { $contentLanguages = $cache->get('contentlanguages'); } else { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__languages')); $contentLanguages = $db->setQuery($query)->loadObjectList(); $cache->store($contentLanguages, 'contentlanguages'); } } $languages = $contentLanguages; // B/C layer. Before 3.8.3. if ($publishedStates === true) { $publishedStates = [1]; } elseif ($publishedStates === false) { $publishedStates = []; } // Check the language published state, if needed. if (\count($publishedStates) > 0) { foreach ($languages as $key => $language) { if (!\in_array((int) $language->published, $publishedStates, true)) { unset($languages[$key]); } } } // Check if the language is installed, if needed. if ($checkInstalled) { $languages = array_values(array_intersect_key(ArrayHelper::pivot($languages, 'lang_code'), static::getInstalledLanguages(0))); } // Order the list, if needed. if ($orderField !== null && $orderDirection !== null) { $languages = ArrayHelper::sortObjects($languages, $orderField, strtolower($orderDirection) === 'desc' ? -1 : 1, true, true); } // Add the pivot, if needed. if ($pivot !== null) { $languages = ArrayHelper::pivot($languages, $pivot); } return $languages; } /** * Parse strings from a language file. * * @param string $fileName The language ini file path. * @param boolean $debug If set to true debug language ini file. * * @return array The strings parsed. * * @since 3.9.0 */ public static function parseIniFile($fileName, $debug = false) { // Check if file exists. if (!is_file($fileName)) { return []; } // Capture hidden PHP errors from the parsing. if ($debug === true) { // See https://www.php.net/manual/en/reserved.variables.phperrormsg.php $php_errormsg = null; $trackErrors = ini_get('track_errors'); ini_set('track_errors', true); } // This was required for https://github.com/joomla/joomla-cms/issues/17198 but not sure what server setup // issue it is solving $disabledFunctions = explode(',', ini_get('disable_functions')); $isParseIniFileDisabled = \in_array('parse_ini_file', array_map('trim', $disabledFunctions)); if (!\function_exists('parse_ini_file') || $isParseIniFileDisabled) { $contents = file_get_contents($fileName); $strings = @parse_ini_string($contents, false, INI_SCANNER_RAW); } else { $strings = @parse_ini_file($fileName, false, INI_SCANNER_RAW); } // Ini files are processed in the "RAW" mode of parse_ini_string, leaving escaped quotes untouched - lets postprocess them $strings = str_replace('\"', '"', $strings); // Restore error tracking to what it was before. if ($debug === true) { ini_set('track_errors', $trackErrors); } return \is_array($strings) ? $strings : []; } /** * Save strings to a language file. * * @param string $fileName The language ini file path. * @param array $strings The array of strings. * * @return boolean True if saved, false otherwise. * * @since 3.7.0 */ public static function saveToIniFile($fileName, array $strings) { // Escape double quotes. foreach ($strings as $key => $string) { $strings[$key] = addcslashes($string, '"'); } // Write override.ini file with the strings. $registry = new Registry($strings); return File::write($fileName, $registry->toString('INI')); } /** * Checks if a language exists. * * This is a simple, quick check for the directory that should contain language files for the given user. * * @param string $lang Language to check. * @param string $basePath Optional path to check. * * @return boolean True if the language exists. * * @since 3.7.0 */ public static function exists($lang, $basePath = JPATH_BASE) { static $paths = []; // Return false if no language was specified if (!$lang) { return false; } $path = $basePath . '/language/' . $lang; // Return previous check results if it exists if (isset($paths[$path])) { return $paths[$path]; } // Check if the language exists $paths[$path] = is_dir($path); return $paths[$path]; } /** * Returns an associative array holding the metadata. * * @param string $lang The name of the language. * * @return mixed If $lang exists return key/value pair with the language metadata, otherwise return NULL. * * @since 3.7.0 */ public static function getMetadata($lang) { $file = self::getLanguagePath(JPATH_BASE, $lang) . '/langmetadata.xml'; if (!is_file($file)) { $file = self::getLanguagePath(JPATH_BASE, $lang) . '/' . $lang . '.xml'; } $result = null; if (is_file($file)) { $result = self::parseXMLLanguageFile($file); } if (empty($result)) { return; } return $result; } /** * Returns a list of known languages for an area * * @param string $basePath The basepath to use * * @return array key/value pair with the language file and real name. * * @since 3.7.0 */ public static function getKnownLanguages($basePath = JPATH_BASE) { return self::parseLanguageFiles(self::getLanguagePath($basePath)); } /** * Get the path to a language * * @param string $basePath The basepath to use. * @param string $language The language tag. * * @return string language related path or null. * * @since 3.7.0 */ public static function getLanguagePath($basePath = JPATH_BASE, $language = null) { return $basePath . '/language' . (!empty($language) ? '/' . $language : ''); } /** * Searches for language directories within a certain base dir. * * @param string $dir directory of files. * * @return array Array holding the found languages as filename => real name pairs. * * @since 3.7.0 */ public static function parseLanguageFiles($dir = null) { $languages = []; // Search main language directory for subdirectories foreach (glob($dir . '/*', GLOB_NOSORT | GLOB_ONLYDIR) as $directory) { // But only directories with lang code format if (preg_match('#/[a-z]{2,3}-[A-Z]{2}$#', $directory)) { $dirPathParts = pathinfo($directory); $file = $directory . '/langmetadata.xml'; if (!is_file($file)) { $file = $directory . '/' . $dirPathParts['filename'] . '.xml'; } if (!is_file($file)) { continue; } try { // Get installed language metadata from xml file and merge it with lang array if ($metadata = self::parseXMLLanguageFile($file)) { $languages = array_replace($languages, [$dirPathParts['filename'] => $metadata]); } } catch (\RuntimeException $e) { // Ignore it } } } return $languages; } /** * Parse XML file for language information. * * @param string $path Path to the XML files. * * @return array Array holding the found metadata as a key => value pair. * * @since 3.7.0 * @throws \RuntimeException */ public static function parseXMLLanguageFile($path) { if (!is_readable($path)) { throw new \RuntimeException('File not found or not readable'); } // Try to load the file $xml = simplexml_load_file($path); if (!$xml) { return; } // Check that it's a metadata file if ((string) $xml->getName() !== 'metafile') { return; } $metadata = []; foreach ($xml->metadata->children() as $child) { $metadata[$child->getName()] = (string) $child; } return $metadata; } } PK у�\2�:��5 �5 Text.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Text handling class. * * @since 1.7.0 */ class Text { /** * JavaScript strings * * @var array * @since 1.7.0 */ protected static $strings = []; /** * Translates a string into the current language. * * Examples: * `<script>alert(Joomla.Text._('<?php echo Text::_("JDEFAULT", array("script"=>true)); ?>'));</script>` * will generate an alert message containing 'Default' * `<?php echo Text::_("JDEFAULT"); ?>` will generate a 'Default' string * * @param string $string The string to translate. * @param mixed $jsSafe Boolean: Make the result javascript safe. * @param boolean $interpretBackSlashes To interpret backslashes (\\=\, \n=carriage return, \t=tabulation) * @param boolean $script To indicate that the string will be push in the javascript language store * * @return string The translated string or the key if $script is true * * @since 1.7.0 */ public static function _($string, $jsSafe = false, $interpretBackSlashes = true, $script = false) { if (\is_array($jsSafe)) { if (\array_key_exists('interpretBackSlashes', $jsSafe)) { $interpretBackSlashes = (bool) $jsSafe['interpretBackSlashes']; } if (\array_key_exists('script', $jsSafe)) { $script = (bool) $jsSafe['script']; } $jsSafe = \array_key_exists('jsSafe', $jsSafe) ? (bool) $jsSafe['jsSafe'] : false; } if (self::passSprintf($string, $jsSafe, $interpretBackSlashes, $script)) { return $string; } $lang = Factory::getLanguage(); if ($script) { static::$strings[$string] = $lang->_($string, $jsSafe, $interpretBackSlashes); return $string; } return $lang->_($string, $jsSafe, $interpretBackSlashes); } /** * Checks the string if it should be interpreted as sprintf and runs sprintf over it. * * @param string &$string The string to translate. * @param mixed $jsSafe Boolean: Make the result javascript safe. * @param boolean $interpretBackSlashes To interpret backslashes (\\=\, \n=carriage return, \t=tabulation) * @param boolean $script To indicate that the string will be push in the javascript language store * * @return boolean Whether the string be interpreted as sprintf * * @since 3.4.4 */ private static function passSprintf(&$string, $jsSafe = false, $interpretBackSlashes = true, $script = false) { // Check if string contains a comma if (empty($string) || strpos($string, ',') === false) { return false; } $lang = Factory::getLanguage(); $string_parts = explode(',', $string); // Pass all parts through the Text translator foreach ($string_parts as $i => $str) { $string_parts[$i] = $lang->_($str, $jsSafe, $interpretBackSlashes); } $first_part = array_shift($string_parts); // Replace custom named placeholders with sprintf style placeholders $first_part = preg_replace('/\[\[%([0-9]+):[^\]]*\]\]/', '%\1$s', $first_part); // Check if string contains sprintf placeholders if (!preg_match('/%([0-9]+\$)?s/', $first_part)) { return false; } $final_string = vsprintf($first_part, $string_parts); // Return false if string hasn't changed if ($first_part === $final_string) { return false; } $string = $final_string; if ($script) { foreach ($string_parts as $i => $str) { static::$strings[$str] = $string_parts[$i]; } } return true; } /** * Translates a string into the current language. * * Examples: * `<?php echo Text::alt('JALL', 'language'); ?>` will generate a 'All' string in English but a "Toutes" string in French * `<?php echo Text::alt('JALL', 'module'); ?>` will generate a 'All' string in English but a "Tous" string in French * * @param string $string The string to translate. * @param string $alt The alternate option for global string * @param mixed $jsSafe Boolean: Make the result javascript safe. * @param boolean $interpretBackSlashes To interpret backslashes (\\=\, \n=carriage return, \t=tabulation) * @param boolean $script To indicate that the string will be pushed in the javascript language store * * @return string The translated string or the key if $script is true * * @since 1.7.0 */ public static function alt($string, $alt, $jsSafe = false, $interpretBackSlashes = true, $script = false) { if (Factory::getLanguage()->hasKey($string . '_' . $alt)) { $string .= '_' . $alt; } return static::_($string, $jsSafe, $interpretBackSlashes, $script); } /** * Like Text::sprintf but tries to pluralise the string. * * Note that this method can take a mixed number of arguments as for the sprintf function. * * The last argument can take an array of options: * * array('jsSafe'=>boolean, 'interpretBackSlashes'=>boolean, 'script'=>boolean) * * where: * * jsSafe is a boolean to generate a javascript safe strings. * interpretBackSlashes is a boolean to interpret backslashes \\->\, \n->new line, \t->tabulation. * script is a boolean to indicate that the string will be push in the javascript language store. * * Examples: * `<script>alert(Joomla.Text._('<?php echo Text::plural("COM_PLUGINS_N_ITEMS_UNPUBLISHED", 1, array("script"=>true)); ?>'));</script>` * will generate an alert message containing '1 plugin successfully disabled' * `<?php echo Text::plural('COM_PLUGINS_N_ITEMS_UNPUBLISHED', 1); ?>` will generate a '1 plugin successfully disabled' string * * @param string $string The format string. * @param integer $n The number of items * * @return string The translated strings or the key if 'script' is true in the array of options * * @since 1.7.0 */ public static function plural($string, $n) { $lang = Factory::getLanguage(); $args = \func_get_args(); $count = \count($args); // Try the key from the language plural potential suffixes $found = false; $suffixes = $lang->getPluralSuffixes((int) $n); // Add the count as possible suffix to allow for eg "a dozen" with suffix _12. // Only do that if it is a real plural (more than one) to avoid issues with languages. See https://github.com/joomla/joomla-cms/pull/29029 if ($n != 1) { array_unshift($suffixes, (int) $n); } foreach ($suffixes as $suffix) { $key = $string . '_' . $suffix; if ($lang->hasKey($key)) { $found = true; break; } } // Not found so revert to the original. $key = !$found ? $string : $key; if (\is_array($args[$count - 1])) { $args[0] = $lang->_( $key, \array_key_exists('jsSafe', $args[$count - 1]) ? $args[$count - 1]['jsSafe'] : false, \array_key_exists('interpretBackSlashes', $args[$count - 1]) ? $args[$count - 1]['interpretBackSlashes'] : true ); if (\array_key_exists('script', $args[$count - 1]) && $args[$count - 1]['script']) { static::$strings[$key] = \call_user_func_array('sprintf', $args); return $key; } } else { $args[0] = $lang->_($key); } return \call_user_func_array('sprintf', $args); } /** * Passes a string thru a sprintf. * * Note that this method can take a mixed number of arguments as for the sprintf function. * * The last argument can take an array of options: * * array('jsSafe'=>boolean, 'interpretBackSlashes'=>boolean, 'script'=>boolean) * * where: * * jsSafe is a boolean to generate a javascript safe strings. * interpretBackSlashes is a boolean to interpret backslashes \\->\, \n->new line, \t->tabulation. * script is a boolean to indicate that the string will be push in the javascript language store. * * @param string $string The format string. * * @return string The translated strings or the key if 'script' is true in the array of options. * * @since 1.7.0 */ public static function sprintf($string) { $lang = Factory::getLanguage(); $args = \func_get_args(); $count = \count($args); if (\is_array($args[$count - 1])) { $args[0] = $lang->_( $string, \array_key_exists('jsSafe', $args[$count - 1]) ? $args[$count - 1]['jsSafe'] : false, \array_key_exists('interpretBackSlashes', $args[$count - 1]) ? $args[$count - 1]['interpretBackSlashes'] : true ); if (\array_key_exists('script', $args[$count - 1]) && $args[$count - 1]['script']) { static::$strings[$string] = \call_user_func_array('sprintf', $args); return $string; } } else { $args[0] = $lang->_($string); } // Replace custom named placeholders with sprintf style placeholders $args[0] = preg_replace('/\[\[%([0-9]+):[^\]]*\]\]/', '%\1$s', $args[0]); return \call_user_func_array('sprintf', $args); } /** * Passes a string through a printf. * * Note that this method can take a mixed number of arguments as for the sprintf function. * * @param string $string The format string. * * @return mixed * * @since 1.7.0 */ public static function printf($string) { $lang = Factory::getLanguage(); $args = \func_get_args(); $count = \count($args); if (\is_array($args[$count - 1])) { $args[0] = $lang->_( $string, \array_key_exists('jsSafe', $args[$count - 1]) ? $args[$count - 1]['jsSafe'] : false, \array_key_exists('interpretBackSlashes', $args[$count - 1]) ? $args[$count - 1]['interpretBackSlashes'] : true ); } else { $args[0] = $lang->_($string); } return \call_user_func_array('printf', $args); } /** * Translate a string into the current language and stores it in the JavaScript language store. * * @param string $string The Text key. * @param boolean $jsSafe Legacy parameter to add slashes to the string. * Set it as "false" because the method encodes the string as JSON with json_encode(). * @param boolean $interpretBackSlashes Interpret \t and \n. * * @return array * * @since 1.7.0 */ public static function script($string = null, $jsSafe = false, $interpretBackSlashes = true) { if ($string === null) { @trigger_error( sprintf( 'As of 3.7.0, passing a null value for the first argument of %1$s() is deprecated and will not be supported in 4.0.' . ' Use the %2$s::getScriptStrings() method to get the strings from the JavaScript language store instead.', __METHOD__, __CLASS__ ), E_USER_DEPRECATED ); } if (\is_array($jsSafe)) { if (\array_key_exists('interpretBackSlashes', $jsSafe)) { $interpretBackSlashes = (bool) $jsSafe['interpretBackSlashes']; } if (\array_key_exists('jsSafe', $jsSafe)) { $jsSafe = (bool) $jsSafe['jsSafe']; } else { $jsSafe = false; } } // Add the string to the array if not null. if ($string !== null) { $doc = Factory::getDocument(); // Get previously added strings $strings = $doc->getScriptOptions('joomla.jtext'); // Normalize the key and translate the string. $key = strtoupper($string); $strings[$key] = Factory::getLanguage()->_($string, $jsSafe, $interpretBackSlashes); static::$strings[$key] = $strings[$key]; // Load core.js dependency HTMLHelper::_('behavior.core'); // Update Joomla.Text script options $doc->addScriptOptions('joomla.jtext', $strings, false); } return static::getScriptStrings(); } /** * Get the strings that have been loaded to the JavaScript language store. * * @return array * * @since 3.7.0 */ public static function getScriptStrings() { return static::$strings; } } PK у�\� �� � LanguageAwareInterface.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2023 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface to be implemented by classes depending on a language. * * @since 4.4.0 */ interface LanguageAwareInterface { /** * Set the language to use. * * @param Language $language The language to use * * @return void * * @since 4.4.0 */ public function setLanguage(Language $language): void; } PK у�\��` ` Associations.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; use Joomla\CMS\Factory; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Utility class for associations in multilang * * @since 3.1 */ class Associations { /** * Get the associations. * * @param string $extension The name of the component. * @param string $tablename The name of the table. * @param string $context The context * @param integer $id The primary key value. * @param string $pk The name of the primary key in the given $table. * @param string $aliasField If the table has an alias field set it here. Null to not use it * @param string $catField If the table has a catid field set it here. Null to not use it * @param array $advClause Additional advanced 'where' clause; use c as parent column key, c2 as associations column key * * @return array The associated items * * @since 3.1 * * @throws \Exception */ public static function getAssociations( $extension, $tablename, $context, $id, $pk = 'id', $aliasField = 'alias', $catField = 'catid', $advClause = [] ) { // To avoid doing duplicate database queries. static $multilanguageAssociations = []; // Cast before creating cache key. $id = (int) $id; // Multilanguage association array key. If the key is already in the array we don't need to run the query again, just return it. $queryKey = md5(serialize(array_merge([$extension, $tablename, $context, $id], $advClause))); if (!isset($multilanguageAssociations[$queryKey])) { $multilanguageAssociations[$queryKey] = []; $db = Factory::getDbo(); $query = $db->getQuery(true); $categoriesExtraSql = ''; if ($tablename === '#__categories') { $categoriesExtraSql = ' AND c2.extension = :extension1'; $query->bind(':extension1', $extension); } $query->select($db->quoteName('c2.language')) ->from($db->quoteName($tablename, 'c')) ->join( 'INNER', $db->quoteName('#__associations', 'a'), $db->quoteName('a.id') . ' = ' . $db->quoteName('c.' . $pk) . ' AND ' . $db->quoteName('a.context') . ' = :context' ) ->bind(':context', $context) ->join('INNER', $db->quoteName('#__associations', 'a2'), $db->quoteName('a.key') . ' = ' . $db->quoteName('a2.key')) ->join( 'INNER', $db->quoteName($tablename, 'c2'), $db->quoteName('a2.id') . ' = ' . $db->quoteName('c2.' . $pk) . $categoriesExtraSql ); // Use alias field ? if (!empty($aliasField)) { $query->select( $query->concatenate( [ $db->quoteName('c2.' . $pk), $db->quoteName('c2.' . $aliasField), ], ':' ) . ' AS ' . $db->quoteName($pk) ); } else { $query->select($db->quoteName('c2.' . $pk)); } // Use catid field ? if (!empty($catField)) { $query->join( 'INNER', $db->quoteName('#__categories', 'ca'), $db->quoteName('c2.' . $catField) . ' = ' . $db->quoteName('ca.id') . ' AND ' . $db->quoteName('ca.extension') . ' = :extension2' ) ->bind(':extension2', $extension) ->select( $query->concatenate( [ $db->quoteName('ca.id'), $db->quoteName('ca.alias'), ], ':' ) . ' AS ' . $db->quoteName($catField) ); } $query->where($db->quoteName('c.' . $pk) . ' = :id') ->bind(':id', $id, ParameterType::INTEGER); if ($tablename === '#__categories') { $query->where($db->quoteName('c.extension') . ' = :extension3') ->bind(':extension3', $extension); } // Advanced where clause if (!empty($advClause)) { foreach ($advClause as $clause) { $query->where($clause); } } $db->setQuery($query); try { $items = $db->loadObjectList('language'); } catch (\RuntimeException $e) { throw new \Exception($e->getMessage(), 500, $e); } if ($items) { foreach ($items as $tag => $item) { // Do not return itself as result if ((int) $item->{$pk} !== $id) { $multilanguageAssociations[$queryKey][$tag] = $item; } } } } return $multilanguageAssociations[$queryKey]; } /** * Method to determine if the language filter Associations parameter is enabled. * This works for both site and administrator. * * @return boolean True if the parameter is implemented; false otherwise. * * @since 3.2 */ public static function isEnabled() { // Flag to avoid doing multiple database queries. static $tested = false; // Status of language filter parameter. static $enabled = false; if (Multilanguage::isEnabled()) { // If already tested, don't test again. if (!$tested) { $plugin = PluginHelper::getPlugin('system', 'languagefilter'); if (!empty($plugin)) { $params = new Registry($plugin->params); $enabled = (bool) $params->get('item_associations', true); } $tested = true; } } return $enabled; } } PK у�\wp�u LanguageFactoryInterface.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Interface defining a factory which can create language objects * * @since 4.0.0 */ interface LanguageFactoryInterface { /** * Method to get an instance of a language. * * @param string $lang The language to use * @param boolean $debug The debug mode * * @return Language * * @since 4.0.0 */ public function createLanguage($lang, $debug = false): Language; } PK у�\G���� � Language.phpnu �[��� <?php /** * Joomla! Content Management System * * @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Language; use Joomla\CMS\Factory; use Joomla\String\StringHelper; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; // phpcs:enable PSR1.Files.SideEffects /** * Languages/translation handler class * * @since 1.7.0 */ class Language { /** * Array of Language objects * * @var Language[] * @since 1.7.0 */ protected static $languages = []; /** * Debug language, If true, highlights if string isn't found. * * @var boolean * @since 1.7.0 */ protected $debug = false; /** * The default language, used when a language file in the requested language does not exist. * * @var string * @since 1.7.0 */ protected $default = 'en-GB'; /** * An array of orphaned text. * * @var array * @since 1.7.0 */ protected $orphans = []; /** * Array holding the language metadata. * * @var array * @since 1.7.0 */ protected $metadata = null; /** * Array holding the language locale or boolean null if none. * * @var array|boolean * @since 1.7.0 */ protected $locale = null; /** * The language to load. * * @var string * @since 1.7.0 */ protected $lang = null; /** * A nested array of language files that have been loaded * * @var array * @since 1.7.0 */ protected $paths = []; /** * List of language files that are in error state * * @var array * @since 1.7.0 */ protected $errorfiles = []; /** * Translations * * @var array * @since 1.7.0 */ protected $strings = []; /** * An array of used text, used during debugging. * * @var array * @since 1.7.0 */ protected $used = []; /** * Counter for number of loads. * * @var integer * @since 1.7.0 */ protected $counter = 0; /** * An array used to store overrides. * * @var array * @since 1.7.0 */ protected $override = []; /** * Name of the transliterator function for this language. * * @var callable * @since 1.7.0 */ protected $transliterator = null; /** * Name of the pluralSuffixesCallback function for this language. * * @var callable * @since 1.7.0 */ protected $pluralSuffixesCallback = null; /** * Name of the ignoredSearchWordsCallback function for this language. * * @var callable * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ protected $ignoredSearchWordsCallback = null; /** * Name of the lowerLimitSearchWordCallback function for this language. * * @var callable * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ protected $lowerLimitSearchWordCallback = null; /** * Name of the upperLimitSearchWordCallback function for this language. * * @var callable * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ protected $upperLimitSearchWordCallback = null; /** * Name of the searchDisplayedCharactersNumberCallback function for this language. * * @var callable * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ protected $searchDisplayedCharactersNumberCallback = null; /** * Constructor activating the default information of the language. * * @param string $lang The language * @param boolean $debug Indicates if language debugging is enabled. * * @since 1.7.0 */ public function __construct($lang = null, $debug = false) { $this->strings = []; if ($lang == null) { $lang = $this->default; } $this->lang = $lang; $this->metadata = LanguageHelper::getMetadata($this->lang); $this->setDebug($debug); /* * Let's load the default override once, so we can profit from that, too * But make sure, that we don't enforce it on each language file load. * So don't put it in $this->override */ if (!$this->debug && $lang !== $this->default) { $this->loadLanguage(JPATH_BASE . '/language/overrides/' . $this->default . '.override.ini'); } $this->override = $this->parse(JPATH_BASE . '/language/overrides/' . $lang . '.override.ini'); // Look for a language specific localise class $class = str_replace('-', '_', $lang . 'Localise'); $paths = []; if (\defined('JPATH_SITE')) { // Note: Manual indexing to enforce load order. $paths[0] = JPATH_SITE . "/language/overrides/$lang.localise.php"; $paths[2] = JPATH_SITE . "/language/$lang/localise.php"; $paths[4] = JPATH_SITE . "/language/$lang/$lang.localise.php"; } if (\defined('JPATH_ADMINISTRATOR')) { // Note: Manual indexing to enforce load order. $paths[1] = JPATH_ADMINISTRATOR . "/language/overrides/$lang.localise.php"; $paths[3] = JPATH_ADMINISTRATOR . "/language/$lang/localise.php"; $paths[5] = JPATH_ADMINISTRATOR . "/language/$lang/$lang.localise.php"; } ksort($paths); $path = reset($paths); while (!class_exists($class) && $path) { if (is_file($path)) { require_once $path; } $path = next($paths); } if (class_exists($class)) { /** * Class exists. Try to find * -a transliterate method, * -a getPluralSuffixes method, * -a getIgnoredSearchWords method * -a getLowerLimitSearchWord method * -a getUpperLimitSearchWord method * -a getSearchDisplayCharactersNumber method */ if (method_exists($class, 'transliterate')) { $this->transliterator = [$class, 'transliterate']; } if (method_exists($class, 'getPluralSuffixes')) { $this->pluralSuffixesCallback = [$class, 'getPluralSuffixes']; } if (method_exists($class, 'getIgnoredSearchWords')) { $this->ignoredSearchWordsCallback = [$class, 'getIgnoredSearchWords']; } if (method_exists($class, 'getLowerLimitSearchWord')) { $this->lowerLimitSearchWordCallback = [$class, 'getLowerLimitSearchWord']; } if (method_exists($class, 'getUpperLimitSearchWord')) { $this->upperLimitSearchWordCallback = [$class, 'getUpperLimitSearchWord']; } if (method_exists($class, 'getSearchDisplayedCharactersNumber')) { $this->searchDisplayedCharactersNumberCallback = [$class, 'getSearchDisplayedCharactersNumber']; } } $this->load(); } /** * Returns a language object. * * @param string $lang The language to use. * @param boolean $debug The debug mode. * * @return Language The Language object. * * @since 1.7.0 * * @deprecated 4.3 will be removed in 6.0 * Use the language factory instead * Example: Factory::getContainer()->get(LanguageFactoryInterface::class)->createLanguage($lang, $debug); */ public static function getInstance($lang, $debug = false) { if (!isset(self::$languages[$lang . $debug])) { self::$languages[$lang . $debug] = Factory::getContainer()->get(LanguageFactoryInterface::class)->createLanguage($lang, $debug); } return self::$languages[$lang . $debug]; } /** * Translate function, mimics the php gettext (alias _) function. * * The function checks if $jsSafe is true, then if $interpretBackslashes is true. * * @param string $string The string to translate * @param boolean $jsSafe Parameter to add slashes to the string that will be rendered as JavaScript. * However, set as "false" if the string is going to be encoded by json_encode(). * @param boolean $interpretBackSlashes Interpret \t and \n * * @return string The translation of the string * * @since 1.7.0 */ public function _($string, $jsSafe = false, $interpretBackSlashes = true) { // Detect empty string if ($string == '') { return ''; } $key = strtoupper($string); if (isset($this->strings[$key])) { $string = $this->strings[$key]; // Store debug information if ($this->debug) { $value = Factory::getApplication()->get('debug_lang_const', true) ? $string : $key; $string = '**' . $value . '**'; $caller = $this->getCallerInfo(); if (!\array_key_exists($key, $this->used)) { $this->used[$key] = []; } $this->used[$key][] = $caller; } } else { if ($this->debug) { $info = []; $info['trace'] = $this->getTrace(); $info['key'] = $key; $info['string'] = $string; if (!\array_key_exists($key, $this->orphans)) { $this->orphans[$key] = []; } $this->orphans[$key][] = $info; $string = '??' . $string . '??'; } } if ($jsSafe) { // Javascript filter $string = addslashes($string); } elseif ($interpretBackSlashes) { if (strpos($string, '\\') !== false) { // Interpret \n and \t characters $string = str_replace(['\\\\', '\t', '\n'], ["\\", "\t", "\n"], $string); } } return $string; } /** * Transliterate function * * This method processes a string and replaces all accented UTF-8 characters by unaccented * ASCII-7 "equivalents". * * @param string $string The string to transliterate. * * @return string The transliteration of the string. * * @since 1.7.0 */ public function transliterate($string) { // First check for transliterator provided by translation if ($this->transliterator !== null) { $string = \call_user_func($this->transliterator, $string); // Check if all symbols were transliterated (contains only ASCII), otherwise continue if (!preg_match('/[\\x80-\\xff]/', $string)) { return $string; } } // Run our transliterator for common symbols, // This need to be executed before native php transliterator, because it may not have all required transliterators $string = Transliterate::utf8_latin_to_ascii($string); // Check if all symbols were transliterated (contains only ASCII), // Otherwise try to use native php function if available if (preg_match('/[\\x80-\\xff]/', $string) && function_exists('transliterator_transliterate') && function_exists('iconv')) { return iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $string)); } return StringHelper::strtolower($string); } /** * Getter for transliteration function * * @return callable The transliterator function * * @since 1.7.0 */ public function getTransliterator() { return $this->transliterator; } /** * Set the transliteration function. * * @param callable $function Function name or the actual function. * * @return callable The previous function. * * @since 1.7.0 */ public function setTransliterator(callable $function) { $previous = $this->transliterator; $this->transliterator = $function; return $previous; } /** * Returns an array of suffixes for plural rules. * * @param integer $count The count number the rule is for. * * @return array The array of suffixes. * * @since 1.7.0 */ public function getPluralSuffixes($count) { if ($this->pluralSuffixesCallback !== null) { return \call_user_func($this->pluralSuffixesCallback, $count); } else { return [(string) $count]; } } /** * Getter for pluralSuffixesCallback function. * * @return callable Function name or the actual function. * * @since 1.7.0 */ public function getPluralSuffixesCallback() { return $this->pluralSuffixesCallback; } /** * Set the pluralSuffixes function. * * @param callable $function Function name or actual function. * * @return callable The previous function. * * @since 1.7.0 */ public function setPluralSuffixesCallback(callable $function) { $previous = $this->pluralSuffixesCallback; $this->pluralSuffixesCallback = $function; return $previous; } /** * Returns an array of ignored search words * * @return array The array of ignored search words. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getIgnoredSearchWords() { if ($this->ignoredSearchWordsCallback !== null) { return \call_user_func($this->ignoredSearchWordsCallback); } else { return []; } } /** * Getter for ignoredSearchWordsCallback function. * * @return callable Function name or the actual function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getIgnoredSearchWordsCallback() { return $this->ignoredSearchWordsCallback; } /** * Setter for the ignoredSearchWordsCallback function * * @param callable $function Function name or actual function. * * @return callable The previous function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function setIgnoredSearchWordsCallback(callable $function) { $previous = $this->ignoredSearchWordsCallback; $this->ignoredSearchWordsCallback = $function; return $previous; } /** * Returns a lower limit integer for length of search words * * @return integer The lower limit integer for length of search words (3 if no value was set for a specific language). * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getLowerLimitSearchWord() { if ($this->lowerLimitSearchWordCallback !== null) { return \call_user_func($this->lowerLimitSearchWordCallback); } else { return 3; } } /** * Getter for lowerLimitSearchWordCallback function * * @return callable Function name or the actual function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getLowerLimitSearchWordCallback() { return $this->lowerLimitSearchWordCallback; } /** * Setter for the lowerLimitSearchWordCallback function. * * @param callable $function Function name or actual function. * * @return callable The previous function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function setLowerLimitSearchWordCallback(callable $function) { $previous = $this->lowerLimitSearchWordCallback; $this->lowerLimitSearchWordCallback = $function; return $previous; } /** * Returns an upper limit integer for length of search words * * @return integer The upper limit integer for length of search words (200 if no value was set or if default value is < 200). * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getUpperLimitSearchWord() { if ($this->upperLimitSearchWordCallback !== null && \call_user_func($this->upperLimitSearchWordCallback) > 200) { return \call_user_func($this->upperLimitSearchWordCallback); } return 200; } /** * Getter for upperLimitSearchWordCallback function * * @return callable Function name or the actual function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getUpperLimitSearchWordCallback() { return $this->upperLimitSearchWordCallback; } /** * Setter for the upperLimitSearchWordCallback function * * @param callable $function Function name or the actual function. * * @return callable The previous function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function setUpperLimitSearchWordCallback(callable $function) { $previous = $this->upperLimitSearchWordCallback; $this->upperLimitSearchWordCallback = $function; return $previous; } /** * Returns the number of characters displayed in search results. * * @return integer The number of characters displayed (200 if no value was set for a specific language). * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getSearchDisplayedCharactersNumber() { if ($this->searchDisplayedCharactersNumberCallback !== null) { return \call_user_func($this->searchDisplayedCharactersNumberCallback); } else { return 200; } } /** * Getter for searchDisplayedCharactersNumberCallback function * * @return callable Function name or the actual function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function getSearchDisplayedCharactersNumberCallback() { return $this->searchDisplayedCharactersNumberCallback; } /** * Setter for the searchDisplayedCharactersNumberCallback function. * * @param callable $function Function name or the actual function. * * @return callable The previous function. * * @since 1.7.0 * * @deprecated 4.4 will be removed in 6.0 without replacement */ public function setSearchDisplayedCharactersNumberCallback(callable $function) { $previous = $this->searchDisplayedCharactersNumberCallback; $this->searchDisplayedCharactersNumberCallback = $function; return $previous; } /** * Loads a single language file and appends the results to the existing strings * * @param string $extension The extension for which a language file should be loaded. * @param string $basePath The basepath to use. * @param string $lang The language to load, default null for the current language. * @param boolean $reload Flag that will force a language to be reloaded if set to true. * @param boolean $default Flag that force the default language to be loaded if the current does not exist. * * @return boolean True if the file has successfully loaded. * * @since 1.7.0 */ public function load($extension = 'joomla', $basePath = JPATH_BASE, $lang = null, $reload = false, $default = true) { // If language is null set as the current language. if (!$lang) { $lang = $this->lang; } // Load the default language first if we're not debugging and a non-default language is requested to be loaded // with $default set to true if (!$this->debug && ($lang != $this->default) && $default) { $this->load($extension, $basePath, $this->default, false, true); } $path = LanguageHelper::getLanguagePath($basePath, $lang); $internal = $extension === 'joomla' || $extension == ''; $filenames = []; if ($internal) { $filenames[] = "$path/joomla.ini"; $filenames[] = "$path/$lang.ini"; } else { // Try first without a language-prefixed filename. $filenames[] = "$path/$extension.ini"; $filenames[] = "$path/$lang.$extension.ini"; } foreach ($filenames as $filename) { if (isset($this->paths[$extension][$filename]) && !$reload) { // This file has already been tested for loading. $result = $this->paths[$extension][$filename]; } else { // Load the language file $result = $this->loadLanguage($filename, $extension); } if ($result) { return true; } } return false; } /** * Loads a language file. * * This method will not note the successful loading of a file - use load() instead. * * @param string $fileName The name of the file. * @param string $extension The name of the extension. * * @return boolean True if new strings have been added to the language * * @see Language::load() * @since 1.7.0 */ protected function loadLanguage($fileName, $extension = 'unknown') { $this->counter++; $result = false; $strings = $this->parse($fileName); if ($strings !== []) { $this->strings = array_replace($this->strings, $strings, $this->override); $result = true; } // Record the result of loading the extension's file. if (!isset($this->paths[$extension])) { $this->paths[$extension] = []; } $this->paths[$extension][$fileName] = $result; return $result; } /** * Parses a language file. * * @param string $fileName The name of the file. * * @return array The array of parsed strings. * * @since 1.7.0 */ protected function parse($fileName) { $strings = LanguageHelper::parseIniFile($fileName, $this->debug); // Debug the ini file if needed. if ($this->debug === true && is_file($fileName)) { $this->debugFile($fileName); } return $strings; } /** * Debugs a language file * * @param string $filename Absolute path to the file to debug * * @return integer A count of the number of parsing errors * * @since 3.6.3 * @throws \InvalidArgumentException */ public function debugFile($filename) { // Make sure our file actually exists if (!is_file($filename)) { throw new \InvalidArgumentException( sprintf('Unable to locate file "%s" for debugging', $filename) ); } // Initialise variables for manually parsing the file for common errors. $reservedWord = ['YES', 'NO', 'NULL', 'FALSE', 'ON', 'OFF', 'NONE', 'TRUE']; $debug = $this->getDebug(); $this->debug = false; $errors = []; $php_errormsg = null; // Open the file as a stream. $file = new \SplFileObject($filename); foreach ($file as $lineNumber => $line) { // Avoid BOM error as BOM is OK when using parse_ini. if ($lineNumber == 0) { $line = str_replace("\xEF\xBB\xBF", '', $line); } $line = trim($line); // Ignore comment lines. if (!\strlen($line) || $line['0'] == ';') { continue; } // Ignore grouping tag lines, like: [group] if (preg_match('#^\[[^\]]*\](\s*;.*)?$#', $line)) { continue; } // Remove any escaped double quotes \" from the equation $line = str_replace('\"', '', $line); $realNumber = $lineNumber + 1; // Check for odd number of double quotes. if (substr_count($line, '"') % 2 != 0) { $errors[] = $realNumber; continue; } // Check that the line passes the necessary format. if (!preg_match('#^[A-Z][A-Z0-9_:\*\-\.]*\s*=\s*".*"(\s*;.*)?$#', $line)) { $errors[] = $realNumber; continue; } // Check that the key is not in the reserved constants list. $key = strtoupper(trim(substr($line, 0, strpos($line, '=')))); if (\in_array($key, $reservedWord)) { $errors[] = $realNumber; } } // Check if we encountered any errors. if (\count($errors)) { $this->errorfiles[$filename] = $errors; } elseif ($php_errormsg) { // We didn't find any errors but there's probably a parse notice. $this->errorfiles['PHP' . $filename] = 'PHP parser errors :' . $php_errormsg; } $this->debug = $debug; return \count($errors); } /** * Get a metadata language property. * * @param string $property The name of the property. * @param mixed $default The default value. * * @return mixed The value of the property. * * @since 1.7.0 */ public function get($property, $default = null) { if (isset($this->metadata[$property])) { return $this->metadata[$property]; } return $default; } /** * Get a back trace. * * @return array * * @since 4.0.0 */ protected function getTrace() { return \function_exists('debug_backtrace') ? debug_backtrace() : []; } /** * Determine who called Language or Text. * * @return array Caller information. * * @since 1.7.0 */ protected function getCallerInfo() { // Try to determine the source if none was provided if (!\function_exists('debug_backtrace')) { return; } $backtrace = debug_backtrace(); $info = []; // Search through the backtrace to our caller $continue = true; while ($continue && next($backtrace)) { $step = current($backtrace); $class = @$step['class']; // We're looking for something outside of language.php if ($class != self::class && $class != Text::class) { $info['function'] = @$step['function']; $info['class'] = $class; $info['step'] = prev($backtrace); // Determine the file and name of the file $info['file'] = @$step['file']; $info['line'] = @$step['line']; $continue = false; } } return $info; } /** * Getter for Name. * * @return string Official name element of the language. * * @since 1.7.0 */ public function getName() { return $this->metadata['name']; } /** * Get a list of language files that have been loaded. * * @param string $extension An optional extension name. * * @return array * * @since 1.7.0 */ public function getPaths($extension = null) { if (isset($extension)) { if (isset($this->paths[$extension])) { return $this->paths[$extension]; } return []; } return $this->paths; } /** * Get a list of language files that are in error state. * * @return array * * @since 1.7.0 */ public function getErrorFiles() { return $this->errorfiles; } /** * Getter for the language tag (as defined in RFC 3066) * * @return string The language tag. * * @since 1.7.0 */ public function getTag() { return $this->metadata['tag']; } /** * Getter for the calendar type * * @return string The calendar type. * * @since 3.7.0 */ public function getCalendar() { if (isset($this->metadata['calendar'])) { return $this->metadata['calendar']; } else { return 'gregorian'; } } /** * Get the RTL property. * * @return boolean True is it an RTL language. * * @since 1.7.0 */ public function isRtl() { return (bool) $this->metadata['rtl']; } /** * Set the Debug property. * * @param boolean $debug The debug setting. * * @return boolean Previous value. * * @since 1.7.0 */ public function setDebug($debug) { $previous = $this->debug; $this->debug = (bool) $debug; return $previous; } /** * Get the Debug property. * * @return boolean True is in debug mode. * * @since 1.7.0 */ public function getDebug() { return $this->debug; } /** * Get the default language code. * * @return string Language code. * * @since 1.7.0 */ public function getDefault() { return $this->default; } /** * Set the default language code. * * @param string $lang The language code. * * @return string Previous value. * * @since 1.7.0 */ public function setDefault($lang) { $previous = $this->default; $this->default = $lang; return $previous; } /** * Get the list of orphaned strings if being tracked. * * @return array Orphaned text. * * @since 1.7.0 */ public function getOrphans() { return $this->orphans; } /** * Get the list of used strings. * * Used strings are those strings requested and found either as a string or a constant. * * @return array Used strings. * * @since 1.7.0 */ public function getUsed() { return $this->used; } /** * Determines is a key exists. * * @param string $string The key to check. * * @return boolean True, if the key exists. * * @since 1.7.0 */ public function hasKey($string) { if ($string === null) { return false; } return isset($this->strings[strtoupper($string)]); } /** * Get the language locale based on current language. * * @return array The locale according to the language. * * @since 1.7.0 */ public function getLocale() { if (!isset($this->locale)) { $locale = str_replace(' ', '', $this->metadata['locale'] ?? ''); if ($locale) { $this->locale = explode(',', $locale); } else { $this->locale = false; } } return $this->locale; } /** * Get the first day of the week for this language. * * @return integer The first day of the week according to the language * * @since 1.7.0 */ public function getFirstDay() { return (int) ($this->metadata['firstDay'] ?? 0); } /** * Get the weekends days for this language. * * @return string The weekend days of the week separated by a comma according to the language * * @since 3.2 */ public function getWeekEnd() { return $this->metadata['weekEnd'] ?? '0,6'; } } PK у�\ ��ѣ � CachingLanguageFactory.phpnu �[��� PK у�\�>>5L L � LanguageFactory.phpnu �[��� PK у�\S�fH� � | LanguageAwareTrait.phpnu �[��� PK у�\psg� � � Multilanguage.phpnu �[��� PK у�\}�)j� � � Transliterate.phpnu �[��� PK у�\4�b�EV EV >