primo commit
This commit is contained in:
		| @ -0,0 +1,65 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\BaseController; | ||||
| use Joomla\CMS\Router\Route; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Controller. | ||||
|  * | ||||
|  * @since  1.5 | ||||
|  */ | ||||
| class DisplayController extends BaseController | ||||
| { | ||||
|     /** | ||||
|      * @var     string  The default view. | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected $default_view = 'installed'; | ||||
|  | ||||
|     /** | ||||
|      * Method to display a view. | ||||
|      * | ||||
|      * @param   boolean  $cachable   If true, the view output will be cached. | ||||
|      * @param   array    $urlparams  An array of safe URL parameters and their variable types. | ||||
|      *                   @see        \Joomla\CMS\Filter\InputFilter::clean() for valid values. | ||||
|      * | ||||
|      * @return  static|boolean   This object to support chaining or false on failure. | ||||
|      * | ||||
|      * @since   1.5 | ||||
|      */ | ||||
|     public function display($cachable = false, $urlparams = false) | ||||
|     { | ||||
|         $view   = $this->input->get('view', $this->default_view); | ||||
|         $layout = $this->input->get('layout', 'default'); | ||||
|         $id     = $this->input->getInt('id'); | ||||
|  | ||||
|         // Check for edit form. | ||||
|         if ($view == 'language' && $layout == 'edit' && !$this->checkEditId('com_languages.edit.language', $id)) { | ||||
|             // Somehow the person just went to the form - we don't allow that. | ||||
|             if (!\count($this->app->getMessageQueue())) { | ||||
|                 $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error'); | ||||
|             } | ||||
|  | ||||
|             $this->setRedirect(Route::_('index.php?option=com_languages&view=languages', false)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return parent::display(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,110 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\Language; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Multilanguage; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\BaseController; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Controller. | ||||
|  * | ||||
|  * @since  1.5 | ||||
|  */ | ||||
| class InstalledController extends BaseController | ||||
| { | ||||
|     /** | ||||
|      * Task to set the default language. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function setDefault() | ||||
|     { | ||||
|         // Check for request forgeries. | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         $cid   = (string) $this->input->get('cid', '', 'string'); | ||||
|         $model = $this->getModel('installed'); | ||||
|  | ||||
|         if ($model->publish($cid)) { | ||||
|             // Switching to the new administrator language for the message | ||||
|             if ($model->getState('client_id') == 1) { | ||||
|                 $language          = Factory::getLanguage(); | ||||
|                 $newLang           = Language::getInstance($cid); | ||||
|                 Factory::$language = $newLang; | ||||
|                 $this->app->loadLanguage($language = $newLang); | ||||
|                 $newLang->load('com_languages', JPATH_ADMINISTRATOR); | ||||
|             } | ||||
|  | ||||
|             if (Multilanguage::isEnabled() && $model->getState('client_id') == 0) { | ||||
|                 $msg  = Text::_('COM_LANGUAGES_MSG_DEFAULT_MULTILANG_SAVED'); | ||||
|                 $type = 'message'; | ||||
|             } else { | ||||
|                 $msg  = Text::_('COM_LANGUAGES_MSG_DEFAULT_LANGUAGE_SAVED'); | ||||
|                 $type = 'message'; | ||||
|             } | ||||
|         } else { | ||||
|             $msg  = $model->getError(); | ||||
|             $type = 'error'; | ||||
|         } | ||||
|  | ||||
|         $clientId = $model->getState('client_id'); | ||||
|         $this->setRedirect('index.php?option=com_languages&view=installed&client=' . $clientId, $msg, $type); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Task to switch the administrator language. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function switchAdminLanguage() | ||||
|     { | ||||
|         // Check for request forgeries. | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         $cid   = (string) $this->input->get('cid', '', 'string'); | ||||
|         $model = $this->getModel('installed'); | ||||
|  | ||||
|         // Fetching the language name from the langmetadata.xml or xx-XX.xml respectively. | ||||
|         $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/langmetadata.xml'; | ||||
|  | ||||
|         if (!is_file($file)) { | ||||
|             $file = JPATH_ADMINISTRATOR . '/language/' . $cid . '/' . $cid . '.xml'; | ||||
|         } | ||||
|  | ||||
|         $info = LanguageHelper::parseXMLLanguageFile($file); | ||||
|  | ||||
|         if ($model->switchAdminLanguage($cid)) { | ||||
|             // Switching to the new language for the message | ||||
|             $languageName      = $info['nativeName']; | ||||
|             $language          = Factory::getLanguage(); | ||||
|             $newLang           = Language::getInstance($cid); | ||||
|             Factory::$language = $newLang; | ||||
|             $this->app->loadLanguage($language = $newLang); | ||||
|             $newLang->load('com_languages', JPATH_ADMINISTRATOR); | ||||
|  | ||||
|             $msg  = Text::sprintf('COM_LANGUAGES_MSG_SWITCH_ADMIN_LANGUAGE_SUCCESS', $languageName); | ||||
|             $type = 'message'; | ||||
|         } else { | ||||
|             $msg  = $model->getError(); | ||||
|             $type = 'error'; | ||||
|         } | ||||
|  | ||||
|         $this->setRedirect('index.php?option=com_languages&view=installed', $msg, $type); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,40 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\MVC\Controller\FormController; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages list actions controller. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class LanguageController extends FormController | ||||
| { | ||||
|     /** | ||||
|      * Gets the URL arguments to append to an item redirect. | ||||
|      * | ||||
|      * @param   int     $recordId  The primary key id for the item. | ||||
|      * @param   string  $key       The name of the primary key variable. | ||||
|      * | ||||
|      * @return  string  The arguments to append to the redirect URL. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getRedirectToItemAppend($recordId = null, $key = 'lang_id') | ||||
|     { | ||||
|         return parent::getRedirectToItemAppend($recordId, $key); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,67 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2017 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\AdminController; | ||||
| use Joomla\CMS\Response\JsonResponse; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages controller Class. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class LanguagesController extends AdminController | ||||
| { | ||||
|     /** | ||||
|      * Method to get a model object, loading it if required. | ||||
|      * | ||||
|      * @param   string  $name    The model name. Optional. | ||||
|      * @param   string  $prefix  The class prefix. Optional. | ||||
|      * @param   array   $config  Configuration array for model. Optional. | ||||
|      * | ||||
|      * @return  object  The model. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getModel($name = 'Language', $prefix = 'Administrator', $config = ['ignore_request' => true]) | ||||
|     { | ||||
|         return parent::getModel($name, $prefix, $config); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the number of published languages for quickicons | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   4.3.0 | ||||
|      */ | ||||
|     public function getQuickiconContent() | ||||
|     { | ||||
|         $model = $this->getModel('languages'); | ||||
|  | ||||
|         $model->setState('filter.published', 1); | ||||
|  | ||||
|         $amount = (int) $model->getTotal(); | ||||
|  | ||||
|         $result = []; | ||||
|  | ||||
|         $result['amount'] = $amount; | ||||
|         $result['sronly'] = Text::plural('COM_LANGUAGES_N_QUICKICON_SRONLY', $amount); | ||||
|         $result['name']   = Text::plural('COM_LANGUAGES_N_QUICKICON', $amount); | ||||
|  | ||||
|         echo new JsonResponse($result); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,198 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Application\CMSWebApplicationInterface; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\FormController; | ||||
| use Joomla\CMS\Router\Route; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Override Controller | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class OverrideController extends FormController | ||||
| { | ||||
|     /** | ||||
|      * Method to edit an existing override. | ||||
|      * | ||||
|      * @param   string  $key     The name of the primary key of the URL variable (not used here). | ||||
|      * @param   string  $urlVar  The name of the URL variable if different from the primary key (not used here). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function edit($key = null, $urlVar = null) | ||||
|     { | ||||
|         // Do not cache the response to this, its a redirect | ||||
|         $this->app->allowCache(false); | ||||
|  | ||||
|         $cid     = (array) $this->input->post->get('cid', [], 'string'); | ||||
|         $context = "$this->option.edit.$this->context"; | ||||
|  | ||||
|         // Get the constant name. | ||||
|         $recordId = (\count($cid) ? $cid[0] : $this->input->get('id')); | ||||
|  | ||||
|         // Access check. | ||||
|         if (!$this->allowEdit()) { | ||||
|             $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_EDIT_NOT_PERMITTED'), 'error'); | ||||
|             $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->app->setUserState($context . '.data', null); | ||||
|         $this->setRedirect('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to save an override. | ||||
|      * | ||||
|      * @param   string  $key     The name of the primary key of the URL variable (not used here). | ||||
|      * @param   string  $urlVar  The name of the URL variable if different from the primary key (not used here). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function save($key = null, $urlVar = null) | ||||
|     { | ||||
|         // Check for request forgeries. | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         $app     = $this->app; | ||||
|         $model   = $this->getModel(); | ||||
|         $data    = $this->input->post->get('jform', [], 'array'); | ||||
|         $context = "$this->option.edit.$this->context"; | ||||
|         $task    = $this->getTask(); | ||||
|  | ||||
|         $recordId   = $this->input->get('id'); | ||||
|         $data['id'] = $recordId; | ||||
|  | ||||
|         // Access check. | ||||
|         if (!$this->allowSave($data, 'id')) { | ||||
|             $this->setMessage(Text::_('JLIB_APPLICATION_ERROR_SAVE_NOT_PERMITTED'), 'error'); | ||||
|             $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Validate the posted data. | ||||
|         $form = $model->getForm($data, false); | ||||
|  | ||||
|         if (!$form) { | ||||
|             $app->enqueueMessage($model->getError(), 'error'); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Test whether the data is valid. | ||||
|         $validData = $model->validate($form, $data); | ||||
|  | ||||
|         // Check for validation errors. | ||||
|         if ($validData === false) { | ||||
|             // Get the validation messages. | ||||
|             $errors = $model->getErrors(); | ||||
|  | ||||
|             // Push up to three validation messages out to the user. | ||||
|             for ($i = 0, $n = \count($errors); $i < $n && $i < 3; $i++) { | ||||
|                 if ($errors[$i] instanceof \Exception) { | ||||
|                     $app->enqueueMessage($errors[$i]->getMessage(), CMSWebApplicationInterface::MSG_ERROR); | ||||
|                 } else { | ||||
|                     $app->enqueueMessage($errors[$i], CMSWebApplicationInterface::MSG_ERROR); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Save the data in the session. | ||||
|             $app->setUserState($context . '.data', $data); | ||||
|  | ||||
|             // Redirect back to the edit screen. | ||||
|             $this->setRedirect( | ||||
|                 Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) | ||||
|             ); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Attempt to save the data. | ||||
|         if (!$model->save($validData)) { | ||||
|             // Save the data in the session. | ||||
|             $app->setUserState($context . '.data', $validData); | ||||
|  | ||||
|             // Redirect back to the edit screen. | ||||
|             $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_SAVE_FAILED', $model->getError()), 'error'); | ||||
|             $this->setRedirect( | ||||
|                 Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($recordId, 'id'), false) | ||||
|             ); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Add message of success. | ||||
|         $this->setMessage(Text::_('COM_LANGUAGES_VIEW_OVERRIDE_SAVE_SUCCESS')); | ||||
|  | ||||
|         // Redirect the user and adjust session state based on the chosen task. | ||||
|         switch ($task) { | ||||
|             case 'apply': | ||||
|                 // Set the record data in the session. | ||||
|                 $app->setUserState($context . '.data', null); | ||||
|  | ||||
|                 // Redirect back to the edit screen | ||||
|                 $this->setRedirect( | ||||
|                     Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend($validData['key'], 'id'), false) | ||||
|                 ); | ||||
|                 break; | ||||
|  | ||||
|             case 'save2new': | ||||
|                 // Clear the record id and data from the session. | ||||
|                 $app->setUserState($context . '.data', null); | ||||
|  | ||||
|                 // Redirect back to the edit screen | ||||
|                 $this->setRedirect( | ||||
|                     Route::_('index.php?option=' . $this->option . '&view=' . $this->view_item . $this->getRedirectToItemAppend(null, 'id'), false) | ||||
|                 ); | ||||
|                 break; | ||||
|  | ||||
|             default: | ||||
|                 // Clear the record id and data from the session. | ||||
|                 $app->setUserState($context . '.data', null); | ||||
|  | ||||
|                 // Redirect to the list screen. | ||||
|                 $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to cancel an edit. | ||||
|      * | ||||
|      * @param   string  $key  The name of the primary key of the URL variable (not used here). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function cancel($key = null) | ||||
|     { | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         $context = "$this->option.edit.$this->context"; | ||||
|  | ||||
|         $this->app->setUserState($context . '.data', null); | ||||
|         $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list . $this->getRedirectToListAppend(), false)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,88 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Controller\AdminController; | ||||
| use Joomla\CMS\Router\Route; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Overrides Controller. | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class OverridesController extends AdminController | ||||
| { | ||||
|     /** | ||||
|      * The prefix to use with controller messages. | ||||
|      * | ||||
|      * @var     string | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $text_prefix = 'COM_LANGUAGES_VIEW_OVERRIDES'; | ||||
|  | ||||
|     /** | ||||
|      * Method for deleting one or more overrides. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function delete() | ||||
|     { | ||||
|         // Check for request forgeries. | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         // Get items to delete from the request. | ||||
|         $cid = (array) $this->input->get('cid', [], 'string'); | ||||
|  | ||||
|         // Remove zero values resulting from input filter | ||||
|         $cid = array_filter($cid); | ||||
|  | ||||
|         if (empty($cid)) { | ||||
|             $this->setMessage(Text::_($this->text_prefix . '_NO_ITEM_SELECTED'), 'warning'); | ||||
|         } else { | ||||
|             // Get the model. | ||||
|             $model = $this->getModel('overrides'); | ||||
|  | ||||
|             // Remove the items. | ||||
|             if ($model->delete($cid)) { | ||||
|                 $this->setMessage(Text::plural($this->text_prefix . '_N_ITEMS_DELETED', \count($cid))); | ||||
|             } else { | ||||
|                 $this->setMessage($model->getError(), 'error'); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $this->setRedirect(Route::_('index.php?option=' . $this->option . '&view=' . $this->view_list, false)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to purge the overrider table. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.4.2 | ||||
|      */ | ||||
|     public function purge() | ||||
|     { | ||||
|         // Check for request forgeries. | ||||
|         $this->checkToken(); | ||||
|  | ||||
|         /** @var \Joomla\Component\Languages\Administrator\Model\OverridesModel $model */ | ||||
|         $model = $this->getModel('overrides'); | ||||
|         $model->purge(); | ||||
|         $this->setRedirect(Route::_('index.php?option=com_languages&view=overrides', false)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,50 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Controller; | ||||
|  | ||||
| use Joomla\CMS\MVC\Controller\AdminController; | ||||
| use Joomla\CMS\Response\JsonResponse; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Strings JSON Controller | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class StringsController extends AdminController | ||||
| { | ||||
|     /** | ||||
|      * Method for refreshing the cache in the database with the known language strings | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function refresh() | ||||
|     { | ||||
|         echo new JsonResponse($this->getModel('strings')->refresh()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method for searching language strings | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function search() | ||||
|     { | ||||
|         echo new JsonResponse($this->getModel('strings')->search()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,49 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @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\Component\Languages\Administrator\Extension; | ||||
|  | ||||
| use Joomla\CMS\Extension\BootableExtensionInterface; | ||||
| use Joomla\CMS\Extension\MVCComponent; | ||||
| use Joomla\CMS\HTML\HTMLRegistryAwareTrait; | ||||
| use Joomla\Component\Languages\Administrator\Service\HTML\Languages; | ||||
| use Psr\Container\ContainerInterface; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Component class for com_languages | ||||
|  * | ||||
|  * @since  4.0.0 | ||||
|  */ | ||||
| class LanguagesComponent extends MVCComponent implements BootableExtensionInterface | ||||
| { | ||||
|     use HTMLRegistryAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Booting the extension. This is the function to set up the environment of the extension like | ||||
|      * registering new class loaders, etc. | ||||
|      * | ||||
|      * If required, some initial set up can be done from services of the container, eg. | ||||
|      * registering HTML services. | ||||
|      * | ||||
|      * @param   ContainerInterface  $container  The container | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function boot(ContainerInterface $container) | ||||
|     { | ||||
|         $this->getRegistry()->register('languages', new Languages()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,80 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @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\Component\Languages\Administrator\Field; | ||||
|  | ||||
| use Joomla\CMS\Form\Field\ListField; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Client Language List field. | ||||
|  * | ||||
|  * @since  3.9.0 | ||||
|  */ | ||||
| class LanguageclientField extends ListField | ||||
| { | ||||
|     /** | ||||
|      * The form field type. | ||||
|      * | ||||
|      * @var     string | ||||
|      * @since   3.9.0 | ||||
|      */ | ||||
|     protected $type = 'Languageclient'; | ||||
|  | ||||
|     /** | ||||
|      * Cached form field options. | ||||
|      * | ||||
|      * @var     array | ||||
|      * @since   3.9.0 | ||||
|      */ | ||||
|     protected $cache = []; | ||||
|  | ||||
|     /** | ||||
|      * Method to get the field options. | ||||
|      * | ||||
|      * @return  array  The field option objects. | ||||
|      * | ||||
|      * @since   3.9.0 | ||||
|      */ | ||||
|     protected function getOptions() | ||||
|     { | ||||
|         // Try to load the data from our mini-cache. | ||||
|         if (!empty($this->cache)) { | ||||
|             return $this->cache; | ||||
|         } | ||||
|  | ||||
|         // Get all languages of frontend and backend. | ||||
|         $languages       = []; | ||||
|         $site_languages  = LanguageHelper::getKnownLanguages(JPATH_SITE); | ||||
|         $admin_languages = LanguageHelper::getKnownLanguages(JPATH_ADMINISTRATOR); | ||||
|  | ||||
|         // Create a single array of them. | ||||
|         foreach ($site_languages as $tag => $language) { | ||||
|             $languages[$tag . '0'] = Text::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], Text::_('JSITE')); | ||||
|         } | ||||
|  | ||||
|         foreach ($admin_languages as $tag => $language) { | ||||
|             $languages[$tag . '1'] = Text::sprintf('COM_LANGUAGES_VIEW_OVERRIDES_LANGUAGES_BOX_ITEM', $language['name'], Text::_('JADMINISTRATOR')); | ||||
|         } | ||||
|  | ||||
|         // Sort it by language tag and by client after that. | ||||
|         ksort($languages); | ||||
|  | ||||
|         // Add the languages to the internal cache. | ||||
|         $this->cache = array_merge(parent::getOptions(), $languages); | ||||
|  | ||||
|         return $this->cache; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,59 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Helper; | ||||
|  | ||||
| use Joomla\CMS\Filter\InputFilter; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages component helper. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class LanguagesHelper | ||||
| { | ||||
|     /** | ||||
|      * Filter method for language keys. | ||||
|      * This method will be called by \JForm while filtering the form data. | ||||
|      * | ||||
|      * @param   string  $value  The language key to filter. | ||||
|      * | ||||
|      * @return  string  The filtered language key. | ||||
|      * | ||||
|      * @since       2.5 | ||||
|      */ | ||||
|     public static function filterKey($value) | ||||
|     { | ||||
|         $filter = InputFilter::getInstance([], [], InputFilter::ONLY_BLOCK_DEFINED_TAGS, InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES); | ||||
|  | ||||
|         return strtoupper($filter->clean($value, 'cmd')); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Filter method for language strings. | ||||
|      * This method will be called by \JForm while filtering the form data. | ||||
|      * | ||||
|      * @param   string  $value  The language string to filter. | ||||
|      * | ||||
|      * @return  string  The filtered language string. | ||||
|      * | ||||
|      * @since       2.5 | ||||
|      */ | ||||
|     public static function filterText($value) | ||||
|     { | ||||
|         $filter = InputFilter::getInstance([], [], InputFilter::ONLY_BLOCK_DEFINED_TAGS, InputFilter::ONLY_BLOCK_DEFINED_ATTRIBUTES); | ||||
|  | ||||
|         return $filter->clean($value); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,351 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Helper; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\Log\Log; | ||||
| use Joomla\Registry\Registry; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Multilang status helper. | ||||
|  * | ||||
|  * @since  1.7.1 | ||||
|  */ | ||||
| abstract class MultilangstatusHelper | ||||
| { | ||||
|     /** | ||||
|      * Method to get the number of published home pages. | ||||
|      * | ||||
|      * @return  integer | ||||
|      */ | ||||
|     public static function getHomes() | ||||
|     { | ||||
|         // Check for multiple Home pages. | ||||
|         $db    = Factory::getDbo(); | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select('COUNT(*)') | ||||
|             ->from($db->quoteName('#__menu')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('home') . ' = 1', | ||||
|                     $db->quoteName('published') . ' = 1', | ||||
|                     $db->quoteName('client_id') . ' = 0', | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         return $db->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the number of published language switcher modules. | ||||
|      * | ||||
|      * @return  integer | ||||
|      */ | ||||
|     public static function getLangswitchers() | ||||
|     { | ||||
|         // Check if switcher is published. | ||||
|         $db    = Factory::getDbo(); | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select('COUNT(*)') | ||||
|             ->from($db->quoteName('#__modules')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('module') . ' = ' . $db->quote('mod_languages'), | ||||
|                     $db->quoteName('published') . ' = 1', | ||||
|                     $db->quoteName('client_id') . ' = 0', | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         return $db->loadResult(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to return a list of published content languages. | ||||
|      * | ||||
|      * @return  array of language objects. | ||||
|      */ | ||||
|     public static function getContentlangs() | ||||
|     { | ||||
|         // Check for published Content Languages. | ||||
|         $db    = Factory::getDbo(); | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select( | ||||
|                 [ | ||||
|                     $db->quoteName('lang_code'), | ||||
|                     $db->quoteName('published'), | ||||
|                     $db->quoteName('sef'), | ||||
|                 ] | ||||
|             ) | ||||
|             ->from($db->quoteName('#__languages')); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         return $db->loadObjectList(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to return combined language status. | ||||
|      * | ||||
|      * @return  array of language objects. | ||||
|      */ | ||||
|     public static function getStatus() | ||||
|     { | ||||
|         // Check for combined status. | ||||
|         $db    = Factory::getDbo(); | ||||
|         $query = $db->getQuery(true); | ||||
|  | ||||
|         // Select all fields from the languages table. | ||||
|         $query->select( | ||||
|             [ | ||||
|                 $db->quoteName('a') . '.*', | ||||
|                 $db->quoteName('a.published'), | ||||
|                 $db->quoteName('a.lang_code'), | ||||
|                 $db->quoteName('e.enabled'), | ||||
|                 $db->quoteName('e.element'), | ||||
|                 $db->quoteName('l.home'), | ||||
|                 $db->quoteName('l.published', 'home_published'), | ||||
|             ] | ||||
|         ) | ||||
|             ->from($db->quoteName('#__languages', 'a')) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__menu', 'l'), | ||||
|                 $db->quoteName('l.language') . ' = ' . $db->quoteName('a.lang_code') | ||||
|                     . ' AND ' . $db->quoteName('l.home') . ' = 1  AND ' . $db->quoteName('l.language') . ' <> ' . $db->quote('*') | ||||
|             ) | ||||
|             ->join('LEFT', $db->quoteName('#__extensions', 'e'), $db->quoteName('e.element') . ' = ' . $db->quoteName('a.lang_code')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('e.client_id') . ' = 0', | ||||
|                     $db->quoteName('e.enabled') . ' = 1', | ||||
|                     $db->quoteName('e.state') . ' = 0', | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         return $db->loadObjectList(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to return a list of contact objects. | ||||
|      * | ||||
|      * @return  array of contact objects. | ||||
|      */ | ||||
|     public static function getContacts() | ||||
|     { | ||||
|         $db        = Factory::getDbo(); | ||||
|         $languages = \count(LanguageHelper::getLanguages()); | ||||
|  | ||||
|         // Get the number of contact with all as language | ||||
|         $alang = $db->getQuery(true) | ||||
|             ->select('COUNT(*)') | ||||
|             ->from($db->quoteName('#__contact_details', 'cd')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('cd.user_id') . ' = ' . $db->quoteName('u.id'), | ||||
|                     $db->quoteName('cd.published') . ' = 1', | ||||
|                     $db->quoteName('cd.language') . ' = ' . $db->quote('*'), | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         // Get the number of languages for the contact | ||||
|         $slang = $db->getQuery(true) | ||||
|             ->select('COUNT(DISTINCT ' . $db->quoteName('l.lang_code') . ')') | ||||
|             ->from($db->quoteName('#__languages', 'l')) | ||||
|             ->join('LEFT', $db->quoteName('#__contact_details', 'cd'), $db->quoteName('cd.language') . ' = ' . $db->quoteName('l.lang_code')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('cd.user_id') . ' = ' . $db->quoteName('u.id'), | ||||
|                     $db->quoteName('cd.published') . ' = 1', | ||||
|                     $db->quoteName('l.published') . ' = 1', | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         // Get the number of multiple contact/language | ||||
|         $mlang = $db->getQuery(true) | ||||
|             ->select('COUNT(*)') | ||||
|             ->from($db->quoteName('#__languages', 'l')) | ||||
|             ->join('LEFT', $db->quoteName('#__contact_details', 'cd'), $db->quoteName('cd.language') . ' = ' . $db->quoteName('l.lang_code')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('cd.user_id') . ' = ' . $db->quoteName('u.id'), | ||||
|                     $db->quoteName('cd.published') . ' = 1', | ||||
|                     $db->quoteName('l.published') . ' = 1', | ||||
|                 ] | ||||
|             ) | ||||
|             ->group($db->quoteName('l.lang_code')) | ||||
|             ->having('COUNT(*) > 1'); | ||||
|  | ||||
|         // Get the contacts | ||||
|         $subQuery = $db->getQuery(true) | ||||
|             ->select('1') | ||||
|             ->from($db->quoteName('#__content', 'c')) | ||||
|             ->where($db->quoteName('c.created_by') . ' = ' . $db->quoteName('u.id')); | ||||
|  | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select( | ||||
|                 [ | ||||
|                     $db->quoteName('u.name'), | ||||
|                     '(' . $alang . ') AS ' . $db->quoteName('alang'), | ||||
|                     '(' . $slang . ') AS ' . $db->quoteName('slang'), | ||||
|                     '(' . $mlang . ') AS ' . $db->quoteName('mlang'), | ||||
|                 ] | ||||
|             ) | ||||
|             ->from($db->quoteName('#__users', 'u')) | ||||
|             ->join('LEFT', $db->quoteName('#__contact_details', 'cd'), $db->quoteName('cd.user_id') . ' = ' . $db->quoteName('u.id')) | ||||
|             ->where('EXISTS (' . $subQuery . ')') | ||||
|             ->group( | ||||
|                 [ | ||||
|                     $db->quoteName('u.id'), | ||||
|                     $db->quoteName('u.name'), | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|         $warnings = $db->loadObjectList(); | ||||
|  | ||||
|         foreach ($warnings as $index => $warn) { | ||||
|             if ($warn->alang == 1 && $warn->slang == 0) { | ||||
|                 unset($warnings[$index]); | ||||
|             } | ||||
|  | ||||
|             if ($warn->alang == 0 && $warn->slang == 0 && empty($warn->mlang)) { | ||||
|                 unset($warnings[$index]); | ||||
|             } | ||||
|  | ||||
|             if ($warn->alang == 0 && $warn->slang == $languages && empty($warn->mlang)) { | ||||
|                 unset($warnings[$index]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $warnings; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the status of the module displaying the menutype of the default Home page set to All languages. | ||||
|      * | ||||
|      * @return  boolean True if the module is published, false otherwise. | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     public static function getDefaultHomeModule() | ||||
|     { | ||||
|         // Find Default Home menutype. | ||||
|         $db    = Factory::getDbo(); | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select($db->quoteName('menutype')) | ||||
|             ->from($db->quoteName('#__menu')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('home') . ' = 1', | ||||
|                     $db->quoteName('published') . ' = 1', | ||||
|                     $db->quoteName('client_id') . ' = 0', | ||||
|                     $db->quoteName('language') . ' = ' . $db->quote('*'), | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         $menutype = $db->loadResult(); | ||||
|  | ||||
|         // Get published site menu modules titles. | ||||
|         $query->clear() | ||||
|             ->select($db->quoteName('title')) | ||||
|             ->from($db->quoteName('#__modules')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('module') . ' = ' . $db->quote('mod_menu'), | ||||
|                     $db->quoteName('published') . ' = 1', | ||||
|                     $db->quoteName('client_id') . ' = 0', | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         $menutitles = $db->loadColumn(); | ||||
|  | ||||
|         // Do we have a published menu module displaying the default Home menu item set to all languages? | ||||
|         foreach ($menutitles as $menutitle) { | ||||
|             $module       = self::getModule('mod_menu', $menutitle); | ||||
|             $moduleParams = new Registry($module->params); | ||||
|             $param        = $moduleParams->get('menutype', ''); | ||||
|  | ||||
|             if ($param && $param != $menutype) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get module by name | ||||
|      * | ||||
|      * @param   string  $moduleName     The name of the module | ||||
|      * @param   string  $instanceTitle  The title of the module, optional | ||||
|      * | ||||
|      * @return  \stdClass  The Module object | ||||
|      * | ||||
|      * @since   3.7.0 | ||||
|      */ | ||||
|     public static function getModule($moduleName, $instanceTitle = null) | ||||
|     { | ||||
|         $db = Factory::getDbo(); | ||||
|  | ||||
|         $query = $db->getQuery(true) | ||||
|             ->select( | ||||
|                 [ | ||||
|                     $db->quoteName('id'), | ||||
|                     $db->quoteName('title'), | ||||
|                     $db->quoteName('module'), | ||||
|                     $db->quoteName('position'), | ||||
|                     $db->quoteName('content'), | ||||
|                     $db->quoteName('showtitle'), | ||||
|                     $db->quoteName('params'), | ||||
|                 ] | ||||
|             ) | ||||
|             ->from($db->quoteName('#__modules')) | ||||
|             ->where( | ||||
|                 [ | ||||
|                     $db->quoteName('module') . ' = :module', | ||||
|                     $db->quoteName('published') . ' = 1', | ||||
|                     $db->quoteName('client_id') . ' = 0', | ||||
|                 ] | ||||
|             ) | ||||
|             ->bind(':module', $moduleName); | ||||
|  | ||||
|         if ($instanceTitle) { | ||||
|             $query->where($db->quoteName('title') . ' = :title') | ||||
|                 ->bind(':title', $instanceTitle); | ||||
|         } | ||||
|  | ||||
|         $db->setQuery($query); | ||||
|  | ||||
|         try { | ||||
|             $modules = $db->loadObject(); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             Log::add(Text::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), Log::WARNING, 'jerror'); | ||||
|         } | ||||
|  | ||||
|         return $modules; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,388 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Application\ApplicationHelper; | ||||
| use Joomla\CMS\Component\ComponentHelper; | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Filesystem\Folder; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Factory\MVCFactoryInterface; | ||||
| use Joomla\CMS\MVC\Model\ListModel; | ||||
| use Joomla\CMS\Table\Table; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Component Languages Model | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class InstalledModel extends ListModel | ||||
| { | ||||
|     /** | ||||
|      * @var object user object | ||||
|      */ | ||||
|     protected $user = null; | ||||
|  | ||||
|     /** | ||||
|      * @var string option name | ||||
|      */ | ||||
|     protected $option = null; | ||||
|  | ||||
|     /** | ||||
|      * @var array languages description | ||||
|      */ | ||||
|     protected $data = null; | ||||
|  | ||||
|     /** | ||||
|      * @var integer total number of languages | ||||
|      */ | ||||
|     protected $total = null; | ||||
|  | ||||
|     /** | ||||
|      * @var string language path | ||||
|      */ | ||||
|     protected $path = null; | ||||
|  | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array                 $config   An optional associative array of configuration settings. | ||||
|      * @param   ?MVCFactoryInterface  $factory  The factory. | ||||
|      * | ||||
|      * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel | ||||
|      * @since   3.2 | ||||
|      */ | ||||
|     public function __construct($config = [], ?MVCFactoryInterface $factory = null) | ||||
|     { | ||||
|         if (empty($config['filter_fields'])) { | ||||
|             $config['filter_fields'] = [ | ||||
|                 'name', | ||||
|                 'nativeName', | ||||
|                 'language', | ||||
|                 'author', | ||||
|                 'published', | ||||
|                 'version', | ||||
|                 'creationDate', | ||||
|                 'author', | ||||
|                 'authorEmail', | ||||
|                 'extension_id', | ||||
|                 'client_id', | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         parent::__construct($config, $factory); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to auto-populate the model state. | ||||
|      * | ||||
|      * Note. Calling getState in this method will result in recursion. | ||||
|      * | ||||
|      * @param   string  $ordering   An optional ordering field. | ||||
|      * @param   string  $direction  An optional direction (asc|desc). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function populateState($ordering = 'name', $direction = 'asc') | ||||
|     { | ||||
|         // Special case for client id. | ||||
|         $clientId = (int) $this->getUserStateFromRequest($this->context . '.client_id', 'client_id', 0, 'int'); | ||||
|         $clientId = (!\in_array($clientId, [0, 1])) ? 0 : $clientId; | ||||
|         $this->setState('client_id', $clientId); | ||||
|  | ||||
|         // Load the parameters. | ||||
|         $params = ComponentHelper::getParams('com_languages'); | ||||
|         $this->setState('params', $params); | ||||
|  | ||||
|         // List state information. | ||||
|         parent::populateState($ordering, $direction); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get a store id based on model configuration state. | ||||
|      * | ||||
|      * This is necessary because the model is used by the component and | ||||
|      * different modules that might need different sets of data or different | ||||
|      * ordering requirements. | ||||
|      * | ||||
|      * @param   string  $id  A prefix for the store id. | ||||
|      * | ||||
|      * @return  string  A store id. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getStoreId($id = '') | ||||
|     { | ||||
|         // Compile the store id. | ||||
|         $id .= ':' . $this->getState('client_id'); | ||||
|         $id .= ':' . $this->getState('filter.search'); | ||||
|  | ||||
|         return parent::getStoreId($id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the client object. | ||||
|      * | ||||
|      * @return  object | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getClient() | ||||
|     { | ||||
|         return ApplicationHelper::getClientInfo($this->getState('client_id', 0)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the option. | ||||
|      * | ||||
|      * @return  object | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getOption() | ||||
|     { | ||||
|         $option = $this->getState('option'); | ||||
|  | ||||
|         return $option; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get Languages item data. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getData() | ||||
|     { | ||||
|         // Fetch language data if not fetched yet. | ||||
|         if (\is_null($this->data)) { | ||||
|             $this->data = []; | ||||
|  | ||||
|             $isCurrentLanguageRtl = Factory::getLanguage()->isRtl(); | ||||
|             $params               = ComponentHelper::getParams('com_languages'); | ||||
|             $installedLanguages   = LanguageHelper::getInstalledLanguages(null, true, true, null, null, null); | ||||
|  | ||||
|             // Compute all the languages. | ||||
|             foreach ($installedLanguages as $clientId => $languages) { | ||||
|                 $defaultLanguage = $params->get(ApplicationHelper::getClientInfo($clientId)->name, 'en-GB'); | ||||
|  | ||||
|                 foreach ($languages as $lang) { | ||||
|                     $row               = new \stdClass(); | ||||
|                     $row->language     = $lang->element; | ||||
|                     $row->name         = $lang->metadata['name']; | ||||
|                     $row->nativeName   = $lang->metadata['nativeName'] ?? '-'; | ||||
|                     $row->client_id    = (int) $lang->client_id; | ||||
|                     $row->extension_id = (int) $lang->extension_id; | ||||
|                     $row->author       = $lang->manifest['author']; | ||||
|                     $row->creationDate = $lang->manifest['creationDate']; | ||||
|                     $row->authorEmail  = $lang->manifest['authorEmail']; | ||||
|                     $row->version      = $lang->manifest['version']; | ||||
|                     $row->published    = $defaultLanguage === $row->language ? 1 : 0; | ||||
|                     $row->checked_out  = null; | ||||
|  | ||||
|                     // Fix wrongly set parentheses in RTL languages | ||||
|                     if ($isCurrentLanguageRtl) { | ||||
|                         $row->name       = html_entity_decode($row->name . '‎', ENT_QUOTES, 'UTF-8'); | ||||
|                         $row->nativeName = html_entity_decode($row->nativeName . '‎', ENT_QUOTES, 'UTF-8'); | ||||
|                     } | ||||
|  | ||||
|                     $this->data[] = $row; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $installedLanguages = array_merge($this->data); | ||||
|  | ||||
|         // Process filters. | ||||
|         $clientId = (int) $this->getState('client_id'); | ||||
|         $search   = $this->getState('filter.search'); | ||||
|  | ||||
|         foreach ($installedLanguages as $key => $installedLanguage) { | ||||
|             // Filter by client id. | ||||
|             if (\in_array($clientId, [0, 1])) { | ||||
|                 if ($installedLanguage->client_id !== $clientId) { | ||||
|                     unset($installedLanguages[$key]); | ||||
|                     continue; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Filter by search term. | ||||
|             if (!empty($search)) { | ||||
|                 if ( | ||||
|                     stripos($installedLanguage->name, $search) === false | ||||
|                     && stripos($installedLanguage->nativeName, $search) === false | ||||
|                     && stripos($installedLanguage->language, $search) === false | ||||
|                 ) { | ||||
|                     unset($installedLanguages[$key]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Process ordering. | ||||
|         $listOrder          = $this->getState('list.ordering', 'name'); | ||||
|         $listDirn           = $this->getState('list.direction', 'ASC'); | ||||
|         $installedLanguages = ArrayHelper::sortObjects($installedLanguages, $listOrder, strtolower($listDirn) === 'desc' ? -1 : 1, true, true); | ||||
|  | ||||
|         // Process pagination. | ||||
|         $limit = (int) $this->getState('list.limit', 25); | ||||
|  | ||||
|         // Sets the total for pagination. | ||||
|         $this->total = \count($installedLanguages); | ||||
|  | ||||
|         if ($limit !== 0) { | ||||
|             $start = (int) $this->getState('list.start', 0); | ||||
|  | ||||
|             return \array_slice($installedLanguages, $start, $limit); | ||||
|         } | ||||
|  | ||||
|         return $installedLanguages; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the total number of Languages items. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         if (\is_null($this->total)) { | ||||
|             $this->getData(); | ||||
|         } | ||||
|  | ||||
|         return $this->total; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to set the default language. | ||||
|      * | ||||
|      * @param   integer  $cid  Id of the language to publish. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function publish($cid) | ||||
|     { | ||||
|         if ($cid) { | ||||
|             $client = $this->getClient(); | ||||
|  | ||||
|             $params = ComponentHelper::getParams('com_languages'); | ||||
|             $params->set($client->name, $cid); | ||||
|  | ||||
|             $table = Table::getInstance('extension', 'Joomla\\CMS\\Table\\'); | ||||
|             $id    = $table->find(['element' => 'com_languages']); | ||||
|  | ||||
|             // Load. | ||||
|             if (!$table->load($id)) { | ||||
|                 $this->setError($table->getError()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             $table->params = (string) $params; | ||||
|  | ||||
|             // Pre-save checks. | ||||
|             if (!$table->check()) { | ||||
|                 $this->setError($table->getError()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             // Save the changes. | ||||
|             if (!$table->store()) { | ||||
|                 $this->setError($table->getError()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|         } else { | ||||
|             $this->setError(Text::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Clean the cache of com_languages and component cache. | ||||
|         $this->cleanCache(); | ||||
|         $this->cleanCache('_system'); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the folders. | ||||
|      * | ||||
|      * @return  array  Languages folders. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getFolders() | ||||
|     { | ||||
|         if (\is_null($this->folders)) { | ||||
|             $path          = $this->getPath(); | ||||
|             $this->folders = Folder::folders($path, '.', false, false, ['.svn', 'CVS', '.DS_Store', '__MACOSX', 'pdf_fonts', 'overrides']); | ||||
|         } | ||||
|  | ||||
|         return $this->folders; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the path. | ||||
|      * | ||||
|      * @return  string  The path to the languages folders. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getPath() | ||||
|     { | ||||
|         if (\is_null($this->path)) { | ||||
|             $client     = $this->getClient(); | ||||
|             $this->path = LanguageHelper::getLanguagePath($client->path); | ||||
|         } | ||||
|  | ||||
|         return $this->path; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to switch the administrator language. | ||||
|      * | ||||
|      * @param   string  $cid  The language tag. | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     public function switchAdminLanguage($cid) | ||||
|     { | ||||
|         if ($cid) { | ||||
|             $client = $this->getClient(); | ||||
|  | ||||
|             if ($client->name == 'administrator') { | ||||
|                 Factory::getApplication()->setUserState('application.lang', $cid); | ||||
|             } | ||||
|         } else { | ||||
|             Factory::getApplication()->enqueueMessage(Text::_('COM_LANGUAGES_ERR_NO_LANGUAGE_SELECTED'), 'error'); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,283 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Application\ApplicationHelper; | ||||
| use Joomla\CMS\Component\ComponentHelper; | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Factory\MVCFactoryInterface; | ||||
| use Joomla\CMS\MVC\Model\AdminModel; | ||||
| use Joomla\CMS\Object\CMSObject; | ||||
| use Joomla\CMS\Plugin\PluginHelper; | ||||
| use Joomla\CMS\Table\Table; | ||||
| use Joomla\Utilities\ArrayHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Component Language Model | ||||
|  * | ||||
|  * @since  1.5 | ||||
|  */ | ||||
| class LanguageModel extends AdminModel | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array                 $config   An optional associative array of configuration settings. | ||||
|      * @param   ?MVCFactoryInterface  $factory  The factory. | ||||
|      * | ||||
|      * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel | ||||
|      * @since   3.2 | ||||
|      */ | ||||
|     public function __construct($config = [], ?MVCFactoryInterface $factory = null) | ||||
|     { | ||||
|         $config = array_merge( | ||||
|             [ | ||||
|                 'event_after_save'  => 'onExtensionAfterSave', | ||||
|                 'event_before_save' => 'onExtensionBeforeSave', | ||||
|                 'events_map'        => [ | ||||
|                     'save' => 'extension', | ||||
|                 ], | ||||
|             ], | ||||
|             $config | ||||
|         ); | ||||
|  | ||||
|         parent::__construct($config, $factory); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Override to get the table. | ||||
|      * | ||||
|      * @param   string  $name     Name of the table. | ||||
|      * @param   string  $prefix   Table name prefix. | ||||
|      * @param   array   $options  Array of options. | ||||
|      * | ||||
|      * @return  Table | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getTable($name = '', $prefix = '', $options = []) | ||||
|     { | ||||
|         return Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to auto-populate the model state. | ||||
|      * | ||||
|      * Note. Calling getState in this method will result in recursion. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function populateState() | ||||
|     { | ||||
|         $app    = Factory::getApplication(); | ||||
|         $params = ComponentHelper::getParams('com_languages'); | ||||
|  | ||||
|         // Load the User state. | ||||
|         $langId = $app->getInput()->getInt('lang_id'); | ||||
|         $this->setState('language.id', $langId); | ||||
|  | ||||
|         // Load the parameters. | ||||
|         $this->setState('params', $params); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get a member item. | ||||
|      * | ||||
|      * @param   integer  $langId  The id of the member to get. | ||||
|      * | ||||
|      * @return  mixed  User data object on success, false on failure. | ||||
|      * | ||||
|      * @since   1.0 | ||||
|      */ | ||||
|     public function getItem($langId = null) | ||||
|     { | ||||
|         $langId = (!empty($langId)) ? $langId : (int) $this->getState('language.id'); | ||||
|  | ||||
|         // Get a member row instance. | ||||
|         $table = $this->getTable(); | ||||
|  | ||||
|         // Attempt to load the row. | ||||
|         $return = $table->load($langId); | ||||
|  | ||||
|         // Check for a table object error. | ||||
|         if ($return === false && $table->getError()) { | ||||
|             $this->setError($table->getError()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Set a valid accesslevel in case '0' is stored due to a bug in the installation SQL (was fixed with PR 2714). | ||||
|         if ($table->access == '0') { | ||||
|             $table->access = (int) Factory::getApplication()->get('access'); | ||||
|         } | ||||
|  | ||||
|         $properties = $table->getProperties(1); | ||||
|         $value      = ArrayHelper::toObject($properties, CMSObject::class); | ||||
|  | ||||
|         return $value; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the group form. | ||||
|      * | ||||
|      * @param   array    $data      Data for the form. | ||||
|      * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not. | ||||
|      * | ||||
|      * @return  \Joomla\CMS\Form\Form|bool  A Form object on success, false on failure. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function getForm($data = [], $loadData = true) | ||||
|     { | ||||
|         // Get the form. | ||||
|         $form = $this->loadForm('com_languages.language', 'language', ['control' => 'jform', 'load_data' => $loadData]); | ||||
|  | ||||
|         if (empty($form)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return $form; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the data that should be injected in the form. | ||||
|      * | ||||
|      * @return  mixed  The data for the form. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function loadFormData() | ||||
|     { | ||||
|         // Check the session for previously entered form data. | ||||
|         $data = Factory::getApplication()->getUserState('com_languages.edit.language.data', []); | ||||
|  | ||||
|         if (empty($data)) { | ||||
|             $data = $this->getItem(); | ||||
|         } | ||||
|  | ||||
|         $this->preprocessData('com_languages.language', $data); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to save the form data. | ||||
|      * | ||||
|      * @param   array  $data  The form data. | ||||
|      * | ||||
|      * @return  boolean  True on success. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function save($data) | ||||
|     { | ||||
|         $langId = (!empty($data['lang_id'])) ? $data['lang_id'] : (int) $this->getState('language.id'); | ||||
|         $isNew  = true; | ||||
|  | ||||
|         PluginHelper::importPlugin($this->events_map['save']); | ||||
|  | ||||
|         $table   = $this->getTable(); | ||||
|         $context = $this->option . '.' . $this->name; | ||||
|  | ||||
|         // Load the row if saving an existing item. | ||||
|         if ($langId > 0) { | ||||
|             $table->load($langId); | ||||
|             $isNew = false; | ||||
|         } | ||||
|  | ||||
|         // Prevent white spaces, including East Asian double bytes. | ||||
|         $spaces = ['/\xE3\x80\x80/', ' ']; | ||||
|  | ||||
|         $data['lang_code'] = str_replace($spaces, '', $data['lang_code']); | ||||
|  | ||||
|         // Prevent saving an incorrect language tag | ||||
|         if (!preg_match('#\b([a-z]{2,3})[-]([A-Z]{2})\b#', $data['lang_code'])) { | ||||
|             $this->setError(Text::_('COM_LANGUAGES_ERROR_LANG_TAG')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $data['sef'] = str_replace($spaces, '', $data['sef']); | ||||
|         $data['sef'] = ApplicationHelper::stringURLSafe($data['sef']); | ||||
|  | ||||
|         // Prevent saving an empty url language code | ||||
|         if ($data['sef'] === '') { | ||||
|             $this->setError(Text::_('COM_LANGUAGES_ERROR_SEF')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Bind the data. | ||||
|         if (!$table->bind($data)) { | ||||
|             $this->setError($table->getError()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Check the data. | ||||
|         if (!$table->check()) { | ||||
|             $this->setError($table->getError()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Trigger the before save event. | ||||
|         $result = Factory::getApplication()->triggerEvent($this->event_before_save, [$context, &$table, $isNew]); | ||||
|  | ||||
|         // Check the event responses. | ||||
|         if (\in_array(false, $result, true)) { | ||||
|             $this->setError($table->getError()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Store the data. | ||||
|         if (!$table->store()) { | ||||
|             $this->setError($table->getError()); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Trigger the after save event. | ||||
|         Factory::getApplication()->triggerEvent($this->event_after_save, [$context, &$table, $isNew]); | ||||
|  | ||||
|         $this->setState('language.id', $table->lang_id); | ||||
|  | ||||
|         // Clean the cache. | ||||
|         $this->cleanCache(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Custom clean cache method. | ||||
|      * | ||||
|      * @param   string   $group     Optional cache group name. | ||||
|      * @param   integer  $clientId  No longer used, will be removed without replacement | ||||
|      *                              @deprecated   4.3 will be removed in 6.0 | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function cleanCache($group = null, $clientId = 0) | ||||
|     { | ||||
|         parent::cleanCache('_system'); | ||||
|         parent::cleanCache('com_languages'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,236 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Component\ComponentHelper; | ||||
| use Joomla\CMS\MVC\Factory\MVCFactoryInterface; | ||||
| use Joomla\CMS\MVC\Model\ListModel; | ||||
| use Joomla\CMS\Table\Table; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Database\QueryInterface; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Model Class | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class LanguagesModel extends ListModel | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array                 $config   An optional associative array of configuration settings. | ||||
|      * @param   ?MVCFactoryInterface  $factory  The factory. | ||||
|      * | ||||
|      * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel | ||||
|      * @since   3.2 | ||||
|      */ | ||||
|     public function __construct($config = [], ?MVCFactoryInterface $factory = null) | ||||
|     { | ||||
|         if (empty($config['filter_fields'])) { | ||||
|             $config['filter_fields'] = [ | ||||
|                 'lang_id', 'a.lang_id', | ||||
|                 'lang_code', 'a.lang_code', | ||||
|                 'title', 'a.title', | ||||
|                 'title_native', 'a.title_native', | ||||
|                 'sef', 'a.sef', | ||||
|                 'image', 'a.image', | ||||
|                 'published', 'a.published', | ||||
|                 'ordering', 'a.ordering', | ||||
|                 'access', 'a.access', 'access_level', | ||||
|                 'home', 'l.home', | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         parent::__construct($config, $factory); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to auto-populate the model state. | ||||
|      * | ||||
|      * Note. Calling getState in this method will result in recursion. | ||||
|      * | ||||
|      * @param   string  $ordering   An optional ordering field. | ||||
|      * @param   string  $direction  An optional direction (asc|desc). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function populateState($ordering = 'a.ordering', $direction = 'asc') | ||||
|     { | ||||
|         // Load the parameters. | ||||
|         $params = ComponentHelper::getParams('com_languages'); | ||||
|         $this->setState('params', $params); | ||||
|  | ||||
|         // List state information. | ||||
|         parent::populateState($ordering, $direction); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get a store id based on model configuration state. | ||||
|      * | ||||
|      * This is necessary because the model is used by the component and | ||||
|      * different modules that might need different sets of data or different | ||||
|      * ordering requirements. | ||||
|      * | ||||
|      * @param   string  $id  A prefix for the store id. | ||||
|      * | ||||
|      * @return  string  A store id. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getStoreId($id = '') | ||||
|     { | ||||
|         // Compile the store id. | ||||
|         $id .= ':' . $this->getState('filter.search'); | ||||
|         $id .= ':' . $this->getState('filter.access'); | ||||
|         $id .= ':' . $this->getState('filter.published'); | ||||
|  | ||||
|         return parent::getStoreId($id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to build an SQL query to load the list data. | ||||
|      * | ||||
|      * @return  QueryInterface    An SQL query | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function getListQuery() | ||||
|     { | ||||
|         // Create a new query object. | ||||
|         $db    = $this->getDatabase(); | ||||
|         $query = $db->getQuery(true); | ||||
|  | ||||
|         // Select all fields from the languages table. | ||||
|         $query->select( | ||||
|             $this->getState( | ||||
|                 'list.select', | ||||
|                 [ | ||||
|                     $db->quoteName('a') . '.*', | ||||
|                 ] | ||||
|             ) | ||||
|         ) | ||||
|             ->select( | ||||
|                 [ | ||||
|                     $db->quoteName('l.home'), | ||||
|                     $db->quoteName('ag.title', 'access_level'), | ||||
|                 ] | ||||
|             ) | ||||
|             ->from($db->quoteName('#__languages', 'a')) | ||||
|             ->join('LEFT', $db->quoteName('#__viewlevels', 'ag'), $db->quoteName('ag.id') . ' = ' . $db->quoteName('a.access')) | ||||
|             ->join( | ||||
|                 'LEFT', | ||||
|                 $db->quoteName('#__menu', 'l'), | ||||
|                 $db->quoteName('l.language') . ' = ' . $db->quoteName('a.lang_code') | ||||
|                     . ' AND ' . $db->quoteName('l.home') . ' = 1 AND ' . $db->quoteName('l.language') . ' <> ' . $db->quote('*') | ||||
|             ); | ||||
|  | ||||
|         // Filter on the published state. | ||||
|         $published = (string) $this->getState('filter.published'); | ||||
|  | ||||
|         if (is_numeric($published)) { | ||||
|             $published = (int) $published; | ||||
|             $query->where($db->quoteName('a.published') . ' = :published') | ||||
|                 ->bind(':published', $published, ParameterType::INTEGER); | ||||
|         } elseif ($published === '') { | ||||
|             $query->where($db->quoteName('a.published') . ' IN (0, 1)'); | ||||
|         } | ||||
|  | ||||
|         // Filter by search in title. | ||||
|         if ($search = $this->getState('filter.search')) { | ||||
|             $search = '%' . str_replace(' ', '%', trim($search)) . '%'; | ||||
|             $query->where($db->quoteName('a.title') . ' LIKE :search') | ||||
|                 ->bind(':search', $search); | ||||
|         } | ||||
|  | ||||
|         // Filter by access level. | ||||
|         if ($access = (int) $this->getState('filter.access')) { | ||||
|             $query->where($db->quoteName('a.access') . ' = :access') | ||||
|                 ->bind(':access', $access, ParameterType::INTEGER); | ||||
|         } | ||||
|  | ||||
|         // Add the list ordering clause. | ||||
|         $query->order($db->quoteName($db->escape($this->getState('list.ordering', 'a.ordering'))) | ||||
|             . ' ' . $db->escape($this->getState('list.direction', 'ASC'))); | ||||
|  | ||||
|         return $query; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the published language(s). | ||||
|      * | ||||
|      * @param   array    $cid    An array of language IDs. | ||||
|      * @param   integer  $value  The value of the published state. | ||||
|      * | ||||
|      * @return  boolean  True on success, false otherwise. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function setPublished($cid, $value = 0) | ||||
|     { | ||||
|         return Table::getInstance('Language', 'Joomla\\CMS\\Table\\')->publish($cid, $value); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to delete records. | ||||
|      * | ||||
|      * @param   array  $pks  An array of item primary keys. | ||||
|      * | ||||
|      * @return  boolean  Returns true on success, false on failure. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function delete($pks) | ||||
|     { | ||||
|         // Sanitize the array. | ||||
|         $pks = (array) $pks; | ||||
|  | ||||
|         // Get a row instance. | ||||
|         $table = Table::getInstance('Language', 'Joomla\\CMS\\Table\\'); | ||||
|  | ||||
|         // Iterate the items to delete each one. | ||||
|         foreach ($pks as $itemId) { | ||||
|             if (!$table->delete((int) $itemId)) { | ||||
|                 $this->setError($table->getError()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Clean the cache. | ||||
|         $this->cleanCache(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Custom clean cache method, 2 places for 2 clients. | ||||
|      * | ||||
|      * @param   string   $group     Optional cache group name. | ||||
|      * @param   integer  $clientId  No longer used, will be removed without replacement | ||||
|      *                              @deprecated   4.3 will be removed in 6.0 | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function cleanCache($group = null, $clientId = 0) | ||||
|     { | ||||
|         parent::cleanCache('_system'); | ||||
|         parent::cleanCache('com_languages'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,217 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\Language; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Model\AdminModel; | ||||
| use Joomla\Filesystem\Path; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Override Model | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class OverrideModel extends AdminModel | ||||
| { | ||||
|     /** | ||||
|      * Method to get the record form. | ||||
|      * | ||||
|      * @param   array    $data      Data for the form. | ||||
|      * @param   boolean  $loadData  True if the form is to load its own data (default case), false if not. | ||||
|      * | ||||
|      * @return  \Joomla\CMS\Form\Form|bool  A Form object on success, false on failure. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function getForm($data = [], $loadData = true) | ||||
|     { | ||||
|         // Get the form. | ||||
|         $form = $this->loadForm('com_languages.override', 'override', ['control' => 'jform', 'load_data' => $loadData]); | ||||
|  | ||||
|         if (empty($form)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $client   = $this->getState('filter.client', 'site'); | ||||
|         $language = $this->getState('filter.language', 'en-GB'); | ||||
|         $langName = Language::getInstance($language)->getName(); | ||||
|  | ||||
|         if (!$langName) { | ||||
|             // If a language only exists in frontend, its metadata cannot be | ||||
|             // loaded in backend at the moment, so fall back to the language tag. | ||||
|             $langName = $language; | ||||
|         } | ||||
|  | ||||
|         $form->setValue('client', null, Text::_('COM_LANGUAGES_VIEW_OVERRIDE_CLIENT_' . strtoupper($client))); | ||||
|         $form->setValue('language', null, Text::sprintf('COM_LANGUAGES_VIEW_OVERRIDE_LANGUAGE', $langName, $language)); | ||||
|         $form->setValue('file', null, Path::clean(\constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini')); | ||||
|  | ||||
|         return $form; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the data that should be injected in the form. | ||||
|      * | ||||
|      * @return  mixed The data for the form. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected function loadFormData() | ||||
|     { | ||||
|         // Check the session for previously entered form data. | ||||
|         $data = Factory::getApplication()->getUserState('com_languages.edit.override.data', []); | ||||
|  | ||||
|         if (empty($data)) { | ||||
|             $data = $this->getItem(); | ||||
|         } | ||||
|  | ||||
|         $this->preprocessData('com_languages.override', $data); | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get a single record. | ||||
|      * | ||||
|      * @param   string  $pk  The key name. | ||||
|      * | ||||
|      * @return  mixed   Object on success, false otherwise. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function getItem($pk = null) | ||||
|     { | ||||
|         $input    = Factory::getApplication()->getInput(); | ||||
|         $pk       = !empty($pk) ? $pk : $input->get('id'); | ||||
|         $fileName = \constant('JPATH_' . strtoupper($this->getState('filter.client'))) | ||||
|             . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; | ||||
|         $strings  = LanguageHelper::parseIniFile($fileName); | ||||
|  | ||||
|         $result           = new \stdClass(); | ||||
|         $result->key      = ''; | ||||
|         $result->override = ''; | ||||
|  | ||||
|         if (isset($strings[$pk])) { | ||||
|             $result->key      = $pk; | ||||
|             $result->override = $strings[$pk]; | ||||
|         } | ||||
|  | ||||
|         $oppositeFileName = \constant('JPATH_' . strtoupper($this->getState('filter.client') == 'site' ? 'administrator' : 'site')) | ||||
|             . '/language/overrides/' . $this->getState('filter.language', 'en-GB') . '.override.ini'; | ||||
|         $oppositeStrings  = LanguageHelper::parseIniFile($oppositeFileName); | ||||
|         $result->both     = isset($oppositeStrings[$pk]) && ($oppositeStrings[$pk] == $strings[$pk]); | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to save the form data. | ||||
|      * | ||||
|      * @param   array    $data            The form data. | ||||
|      * @param   boolean  $oppositeClient  Indicates whether the override should not be created for the current client. | ||||
|      * | ||||
|      * @return  boolean  True on success, false otherwise. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function save($data, $oppositeClient = false) | ||||
|     { | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         if ($app->isClient('api')) { | ||||
|             $client   = $this->getState('filter.client'); | ||||
|             $language = $this->getState('filter.language'); | ||||
|         } else { | ||||
|             $client   = $app->getUserState('com_languages.overrides.filter.client', 0); | ||||
|             $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); | ||||
|         } | ||||
|  | ||||
|         // If the override should be created for both. | ||||
|         if ($oppositeClient) { | ||||
|             $client = 1 - $client; | ||||
|         } | ||||
|  | ||||
|         // Return false if the constant is a reserved word, i.e. YES, NO, NULL, FALSE, ON, OFF, NONE, TRUE | ||||
|         $reservedWords = ['YES', 'NO', 'NULL', 'FALSE', 'ON', 'OFF', 'NONE', 'TRUE']; | ||||
|  | ||||
|         if (\in_array($data['key'], $reservedWords)) { | ||||
|             $this->setError(Text::_('COM_LANGUAGES_OVERRIDE_ERROR_RESERVED_WORDS')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $client = $client ? 'administrator' : 'site'; | ||||
|  | ||||
|         // Parse the override.ini file in order to get the keys and strings. | ||||
|         $fileName = \constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $language . '.override.ini'; | ||||
|         $strings  = LanguageHelper::parseIniFile($fileName); | ||||
|  | ||||
|         if (isset($strings[$data['id']])) { | ||||
|             // If an existent string was edited check whether | ||||
|             // the name of the constant is still the same. | ||||
|             if ($data['key'] == $data['id']) { | ||||
|                 // If yes, simply override it. | ||||
|                 $strings[$data['key']] = $data['override']; | ||||
|             } else { | ||||
|                 // If no, delete the old string and prepend the new one. | ||||
|                 unset($strings[$data['id']]); | ||||
|                 $strings = [$data['key'] => $data['override']] + $strings; | ||||
|             } | ||||
|         } else { | ||||
|             // If it is a new override simply prepend it. | ||||
|             $strings = [$data['key'] => $data['override']] + $strings; | ||||
|         } | ||||
|  | ||||
|         // Write override.ini file with the strings. | ||||
|         if (LanguageHelper::saveToIniFile($fileName, $strings) === false) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // If the override should be stored for both clients save | ||||
|         // it also for the other one and prevent endless recursion. | ||||
|         if (isset($data['both']) && $data['both'] && !$oppositeClient) { | ||||
|             return $this->save($data, true); | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to auto-populate the model state. | ||||
|      * | ||||
|      * Note. Calling getState in this method will result in recursion. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected function populateState() | ||||
|     { | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         if ($app->isClient('api')) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $client = $app->getUserStateFromRequest('com_languages.overrides.filter.client', 'filter_client', 0, 'int') ? 'administrator' : 'site'; | ||||
|         $this->setState('filter.client', $client); | ||||
|  | ||||
|         $language = $app->getUserStateFromRequest('com_languages.overrides.filter.language', 'filter_language', 'en-GB', 'cmd'); | ||||
|         $this->setState('filter.language', $language); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,254 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\Factory\MVCFactoryInterface; | ||||
| use Joomla\CMS\MVC\Model\ListModel; | ||||
| use Joomla\Filesystem\File; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Overrides Model | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class OverridesModel extends ListModel | ||||
| { | ||||
|     /** | ||||
|      * Constructor. | ||||
|      * | ||||
|      * @param   array                 $config   An optional associative array of configuration settings. | ||||
|      * @param   ?MVCFactoryInterface  $factory  The factory. | ||||
|      * | ||||
|      * @see     \Joomla\CMS\MVC\Model\BaseDatabaseModel | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function __construct($config = [], ?MVCFactoryInterface $factory = null) | ||||
|     { | ||||
|         if (empty($config['filter_fields'])) { | ||||
|             $config['filter_fields'] = [ | ||||
|                 'key', | ||||
|                 'text', | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         parent::__construct($config, $factory); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Retrieves the overrides data | ||||
|      * | ||||
|      * @param   boolean  $all  True if all overrides shall be returned without considering pagination, defaults to false | ||||
|      * | ||||
|      * @return  array  Array of objects containing the overrides of the override.ini file | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function getOverrides($all = false) | ||||
|     { | ||||
|         // Get a storage key. | ||||
|         $store = $this->getStoreId(); | ||||
|  | ||||
|         // Try to load the data from internal storage. | ||||
|         if (!empty($this->cache[$store])) { | ||||
|             return $this->cache[$store]; | ||||
|         } | ||||
|  | ||||
|         $client = strtoupper($this->getState('filter.client')); | ||||
|  | ||||
|         // Parse the override.ini file in order to get the keys and strings. | ||||
|         $fileName = \constant('JPATH_' . $client) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; | ||||
|         $strings  = LanguageHelper::parseIniFile($fileName); | ||||
|  | ||||
|         // Delete the override.ini file if empty. | ||||
|         if (file_exists($fileName) && $strings === []) { | ||||
|             File::delete($fileName); | ||||
|         } | ||||
|  | ||||
|         // Filter the loaded strings according to the search box. | ||||
|         $search = $this->getState('filter.search'); | ||||
|  | ||||
|         if ($search != '') { | ||||
|             $search    = preg_quote($search, '~'); | ||||
|             $matchvals = preg_grep('~' . $search . '~i', $strings); | ||||
|             $matchkeys = array_intersect_key($strings, array_flip(preg_grep('~' . $search . '~i', array_keys($strings)))); | ||||
|             $strings   = array_merge($matchvals, $matchkeys); | ||||
|         } | ||||
|  | ||||
|         // Consider the ordering | ||||
|         if ($this->getState('list.ordering') == 'text') { | ||||
|             if (strtoupper($this->getState('list.direction')) == 'DESC') { | ||||
|                 arsort($strings); | ||||
|             } else { | ||||
|                 asort($strings); | ||||
|             } | ||||
|         } else { | ||||
|             if (strtoupper($this->getState('list.direction')) == 'DESC') { | ||||
|                 krsort($strings); | ||||
|             } else { | ||||
|                 ksort($strings); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Consider the pagination. | ||||
|         if (!$all && $this->getState('list.limit') && $this->getTotal() > $this->getState('list.limit')) { | ||||
|             $strings = \array_slice($strings, $this->getStart(), $this->getState('list.limit'), true); | ||||
|         } | ||||
|  | ||||
|         // Add the items to the internal cache. | ||||
|         $this->cache[$store] = $strings; | ||||
|  | ||||
|         return $this->cache[$store]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to get the total number of overrides. | ||||
|      * | ||||
|      * @return  integer  The total number of overrides. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function getTotal() | ||||
|     { | ||||
|         // Get a storage key. | ||||
|         $store = $this->getStoreId('getTotal'); | ||||
|  | ||||
|         // Try to load the data from internal storage | ||||
|         if (!empty($this->cache[$store])) { | ||||
|             return $this->cache[$store]; | ||||
|         } | ||||
|  | ||||
|         // Add the total to the internal cache. | ||||
|         $this->cache[$store] = \count($this->getOverrides(true)); | ||||
|  | ||||
|         return $this->cache[$store]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to auto-populate the model state. | ||||
|      * | ||||
|      * Note. Calling getState in this method will result in recursion. | ||||
|      * | ||||
|      * @param   string  $ordering   An optional ordering field. | ||||
|      * @param   string  $direction  An optional direction (asc|desc). | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected function populateState($ordering = 'key', $direction = 'asc') | ||||
|     { | ||||
|         // We call populate state first so that we can then set the filter.client and filter.language properties in afterwards | ||||
|         parent::populateState($ordering, $direction); | ||||
|  | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         if ($app->isClient('api')) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $language_client = $this->getUserStateFromRequest('com_languages.overrides.language_client', 'language_client', '', 'cmd'); | ||||
|         $client          = substr($language_client, -1); | ||||
|         $language        = substr($language_client, 0, -1); | ||||
|  | ||||
|         // Sets the search filter. | ||||
|         $search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search'); | ||||
|         $this->setState('filter.search', $search); | ||||
|  | ||||
|         $this->setState('language_client', $language . $client); | ||||
|         $this->setState('filter.client', $client ? 'administrator' : 'site'); | ||||
|         $this->setState('filter.language', $language); | ||||
|  | ||||
|         // Add the 'language_client' value to the session to display a message if none selected | ||||
|         $app->setUserState('com_languages.overrides.language_client', $language . $client); | ||||
|  | ||||
|         // Add filters to the session because they won't be stored there by 'getUserStateFromRequest' if they aren't in the current request. | ||||
|         $app->setUserState('com_languages.overrides.filter.client', $client); | ||||
|         $app->setUserState('com_languages.overrides.filter.language', $language); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to delete one or more overrides. | ||||
|      * | ||||
|      * @param   array  $cids  Array of keys to delete. | ||||
|      * | ||||
|      * @return  integer  Number of successfully deleted overrides, boolean false if an error occurred. | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function delete($cids) | ||||
|     { | ||||
|         // Check permissions first. | ||||
|         if (!$this->getCurrentUser()->authorise('core.delete', 'com_languages')) { | ||||
|             $this->setError(Text::_('JLIB_APPLICATION_ERROR_DELETE_NOT_PERMITTED')); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         if ($app->isClient('api')) { | ||||
|             $cids   = (array) $cids; | ||||
|             $client = $this->getState('filter.client'); | ||||
|         } else { | ||||
|             $filterclient = Factory::getApplication()->getUserState('com_languages.overrides.filter.client'); | ||||
|             $client       = $filterclient == 0 ? 'site' : 'administrator'; | ||||
|         } | ||||
|  | ||||
|         // Parse the override.ini file in order to get the keys and strings. | ||||
|         $fileName = \constant('JPATH_' . strtoupper($client)) . '/language/overrides/' . $this->getState('filter.language') . '.override.ini'; | ||||
|         $strings  = LanguageHelper::parseIniFile($fileName); | ||||
|  | ||||
|         // Unset strings that shall be deleted | ||||
|         foreach ($cids as $key) { | ||||
|             if (isset($strings[$key])) { | ||||
|                 unset($strings[$key]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Write override.ini file with the strings. | ||||
|         if (LanguageHelper::saveToIniFile($fileName, $strings) === false) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $this->cleanCache(); | ||||
|  | ||||
|         return \count($cids); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Removes all of the cached strings from the table. | ||||
|      * | ||||
|      * @return  void|\RuntimeException | ||||
|      * | ||||
|      * @since   3.4.2 | ||||
|      */ | ||||
|     public function purge() | ||||
|     { | ||||
|         $db = $this->getDatabase(); | ||||
|  | ||||
|         // Note: TRUNCATE is a DDL operation | ||||
|         // This may or may not mean depending on your database | ||||
|         try { | ||||
|             $db->truncateTable('#__overrider'); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             return $e; | ||||
|         } | ||||
|  | ||||
|         Factory::getApplication()->enqueueMessage(Text::_('COM_LANGUAGES_VIEW_OVERRIDES_PURGE_SUCCESS')); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,184 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Model; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Filter\InputFilter; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\MVC\Model\BaseDatabaseModel; | ||||
| use Joomla\Database\ParameterType; | ||||
| use Joomla\Filesystem\Folder; | ||||
| use Joomla\Filesystem\Path; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Languages Strings Model | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class StringsModel extends BaseDatabaseModel | ||||
| { | ||||
|     /** | ||||
|      * Method for refreshing the cache in the database with the known language strings. | ||||
|      * | ||||
|      * @return  boolean|\Exception  True on success, \Exception object otherwise. | ||||
|      * | ||||
|      * @since       2.5 | ||||
|      */ | ||||
|     public function refresh() | ||||
|     { | ||||
|         $app = Factory::getApplication(); | ||||
|         $db  = $this->getDatabase(); | ||||
|  | ||||
|         $app->setUserState('com_languages.overrides.cachedtime', null); | ||||
|  | ||||
|         // Empty the database cache first. | ||||
|         try { | ||||
|             $db->truncateTable('#__overrider'); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             return $e; | ||||
|         } | ||||
|  | ||||
|         // Create the insert query. | ||||
|         $query = $db->getQuery(true) | ||||
|             ->insert($db->quoteName('#__overrider')) | ||||
|             ->columns( | ||||
|                 [ | ||||
|                     $db->quoteName('constant'), | ||||
|                     $db->quoteName('string'), | ||||
|                     $db->quoteName('file'), | ||||
|                 ] | ||||
|             ); | ||||
|  | ||||
|         // Initialize some variables. | ||||
|         $client   = $app->getUserState('com_languages.overrides.filter.client', 'site') ? 'administrator' : 'site'; | ||||
|         $language = $app->getUserState('com_languages.overrides.filter.language', 'en-GB'); | ||||
|  | ||||
|         $base = \constant('JPATH_' . strtoupper($client)); | ||||
|         $path = $base . '/language/' . $language; | ||||
|  | ||||
|         $files = []; | ||||
|  | ||||
|         // Parse common language directory. | ||||
|         if (is_dir($path)) { | ||||
|             $files = Folder::files($path, '.*ini$', false, true); | ||||
|         } | ||||
|  | ||||
|         // Parse language directories of components. | ||||
|         $files = array_merge($files, Folder::files($base . '/components', '.*ini$', 3, true)); | ||||
|  | ||||
|         // Parse language directories of modules. | ||||
|         $files = array_merge($files, Folder::files($base . '/modules', '.*ini$', 3, true)); | ||||
|  | ||||
|         // Parse language directories of templates. | ||||
|         $files = array_merge($files, Folder::files($base . '/templates', '.*ini$', 3, true)); | ||||
|  | ||||
|         // Parse language directories of plugins. | ||||
|         $files = array_merge($files, Folder::files(JPATH_PLUGINS, '.*ini$', 4, true)); | ||||
|  | ||||
|         // Parse all found ini files and add the strings to the database cache. | ||||
|         foreach ($files as $file) { | ||||
|             // Only process if language file is for selected language | ||||
|             if (strpos($file, $language, \strlen($base)) === false) { | ||||
|                 continue; | ||||
|             } | ||||
|  | ||||
|             $strings = LanguageHelper::parseIniFile($file); | ||||
|  | ||||
|             if ($strings) { | ||||
|                 $file = Path::clean($file); | ||||
|  | ||||
|                 $query->clear('values') | ||||
|                     ->clear('bounded'); | ||||
|  | ||||
|                 foreach ($strings as $key => $string) { | ||||
|                     $query->values(implode(',', $query->bindArray([$key, $string, $file], ParameterType::STRING))); | ||||
|                 } | ||||
|  | ||||
|                 try { | ||||
|                     $db->setQuery($query); | ||||
|                     $db->execute(); | ||||
|                 } catch (\RuntimeException $e) { | ||||
|                     return $e; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Update the cached time. | ||||
|         $app->setUserState('com_languages.overrides.cachedtime.' . $client . '.' . $language, time()); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method for searching language strings. | ||||
|      * | ||||
|      * @return  array|\Exception  Array of results on success, \Exception object otherwise. | ||||
|      * | ||||
|      * @since       2.5 | ||||
|      */ | ||||
|     public function search() | ||||
|     { | ||||
|         $results    = []; | ||||
|         $input      = Factory::getApplication()->getInput(); | ||||
|         $filter     = InputFilter::getInstance(); | ||||
|         $db         = $this->getDatabase(); | ||||
|         $searchTerm = $input->getString('searchstring'); | ||||
|  | ||||
|         $limitstart = $input->getInt('more'); | ||||
|  | ||||
|         try { | ||||
|             $searchstring = '%' . $filter->clean($searchTerm, 'TRIM') . '%'; | ||||
|  | ||||
|             // Create the search query. | ||||
|             $query = $db->getQuery(true) | ||||
|                 ->select( | ||||
|                     [ | ||||
|                         $db->quoteName('constant'), | ||||
|                         $db->quoteName('string'), | ||||
|                         $db->quoteName('file'), | ||||
|                     ] | ||||
|                 ) | ||||
|                 ->from($db->quoteName('#__overrider')); | ||||
|  | ||||
|             if ($input->get('searchtype') === 'constant') { | ||||
|                 $query->where($db->quoteName('constant') . ' LIKE :search'); | ||||
|             } else { | ||||
|                 $query->where($db->quoteName('string') . ' LIKE :search'); | ||||
|             } | ||||
|  | ||||
|             $query->bind(':search', $searchstring); | ||||
|  | ||||
|             // Consider the limitstart according to the 'more' parameter and load the results. | ||||
|             $query->setLimit(10, $limitstart); | ||||
|             $db->setQuery($query); | ||||
|             $results['results'] = $db->loadObjectList(); | ||||
|  | ||||
|             // Check whether there are more results than already loaded. | ||||
|             $query->clear('select') | ||||
|                 ->clear('limit') | ||||
|                 ->select('COUNT(' . $db->quoteName('id') . ')'); | ||||
|             $db->setQuery($query); | ||||
|  | ||||
|             if ($db->loadResult() > $limitstart + 10) { | ||||
|                 // If this is set a 'More Results' link will be displayed in the view. | ||||
|                 $results['more'] = $limitstart + 10; | ||||
|             } | ||||
|         } catch (\RuntimeException $e) { | ||||
|             return $e; | ||||
|         } | ||||
|  | ||||
|         return $results; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,94 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\Service\HTML; | ||||
|  | ||||
| use Joomla\CMS\HTML\HTMLHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Utility class working with languages | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class Languages | ||||
| { | ||||
|     /** | ||||
|      * Method to generate an information about the default language. | ||||
|      * | ||||
|      * @param   boolean  $published  True if the language is the default. | ||||
|      * | ||||
|      * @return  string  HTML code. | ||||
|      */ | ||||
|     public function published($published) | ||||
|     { | ||||
|         if (!$published) { | ||||
|             return ' '; | ||||
|         } | ||||
|  | ||||
|         return HTMLHelper::_('image', 'menu/icon-16-default.png', Text::_('COM_LANGUAGES_HEADING_DEFAULT'), null, true); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to generate an input radio button. | ||||
|      * | ||||
|      * @param   integer  $rowNum    The row number. | ||||
|      * @param   string   $language  Language tag. | ||||
|      * | ||||
|      * @return  string  HTML code. | ||||
|      */ | ||||
|     public function id($rowNum, $language) | ||||
|     { | ||||
|         return '<input' | ||||
|             . ' class="form-check-input"' | ||||
|             . ' type="radio"' | ||||
|             . ' id="cb' . $rowNum . '"' | ||||
|             . ' name="cid"' | ||||
|             . ' value="' . htmlspecialchars($language, ENT_COMPAT, 'UTF-8') . '"' | ||||
|             . ' onclick="Joomla.isChecked(this.checked);"' | ||||
|             . '>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to generate an array of clients. | ||||
|      * | ||||
|      * @return  array of client objects. | ||||
|      */ | ||||
|     public function clients() | ||||
|     { | ||||
|         return [ | ||||
|             HTMLHelper::_('select.option', 0, Text::_('JSITE')), | ||||
|             HTMLHelper::_('select.option', 1, Text::_('JADMINISTRATOR')), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns an array of published state filter options. | ||||
|      * | ||||
|      * @return  string      The HTML code for the select tag. | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     public function publishedOptions() | ||||
|     { | ||||
|         // Build the active state filter options. | ||||
|         $options   = []; | ||||
|         $options[] = HTMLHelper::_('select.option', '1', 'JPUBLISHED'); | ||||
|         $options[] = HTMLHelper::_('select.option', '0', 'JUNPUBLISHED'); | ||||
|         $options[] = HTMLHelper::_('select.option', '-2', 'JTRASHED'); | ||||
|         $options[] = HTMLHelper::_('select.option', '*', 'JALL'); | ||||
|  | ||||
|         return $options; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,146 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\View\Installed; | ||||
|  | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\View\GenericDataException; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\CMS\Toolbar\ToolbarHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Displays a list of the installed languages. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class HtmlView extends BaseHtmlView | ||||
| { | ||||
|     /** | ||||
|      * Option (component) name | ||||
|      * | ||||
|      * @var string | ||||
|      */ | ||||
|     protected $option = null; | ||||
|  | ||||
|     /** | ||||
|      * The pagination object | ||||
|      * | ||||
|      * @var  \Joomla\CMS\Pagination\Pagination | ||||
|      */ | ||||
|     protected $pagination; | ||||
|  | ||||
|     /** | ||||
|      * Languages information | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $rows = null; | ||||
|  | ||||
|     /** | ||||
|      * The model state | ||||
|      * | ||||
|      * @var   \Joomla\Registry\Registry | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     protected $state; | ||||
|  | ||||
|     /** | ||||
|      * Form object for search filters | ||||
|      * | ||||
|      * @var    \Joomla\CMS\Form\Form | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     public $filterForm; | ||||
|  | ||||
|     /** | ||||
|      * The active search filters | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     public $activeFilters; | ||||
|  | ||||
|     /** | ||||
|      * Display the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->option        = $this->get('Option'); | ||||
|         $this->pagination    = $this->get('Pagination'); | ||||
|         $this->rows          = $this->get('Data'); | ||||
|         $this->total         = $this->get('Total'); | ||||
|         $this->state         = $this->get('State'); | ||||
|         $this->filterForm    = $this->get('FilterForm'); | ||||
|         $this->activeFilters = $this->get('ActiveFilters'); | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors), 500); | ||||
|         } | ||||
|  | ||||
|         $this->addToolbar(); | ||||
|  | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the page title and toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function addToolbar() | ||||
|     { | ||||
|         $canDo   = ContentHelper::getActions('com_languages'); | ||||
|         $toolbar = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         if ((int) $this->state->get('client_id') === 1) { | ||||
|             ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_INSTALLED_ADMIN_TITLE'), 'comments langmanager'); | ||||
|         } else { | ||||
|             ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_INSTALLED_SITE_TITLE'), 'comments langmanager'); | ||||
|         } | ||||
|  | ||||
|         if ($canDo->get('core.edit.state')) { | ||||
|             $toolbar->makeDefault('installed.setDefault'); | ||||
|             $toolbar->divider(); | ||||
|         } | ||||
|  | ||||
|         if ($canDo->get('core.admin')) { | ||||
|             // Switch administrator language | ||||
|             if ($this->state->get('client_id', 0) == 1) { | ||||
|                 $toolbar->standardButton('switch', 'COM_LANGUAGES_SWITCH_ADMIN', 'installed.switchadminlanguage') | ||||
|                     ->icon('icon-refresh') | ||||
|                     ->listCheck(true); | ||||
|                 $toolbar->divider(); | ||||
|             } | ||||
|  | ||||
|             $toolbar->link('COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages') | ||||
|                 ->icon('icon-upload'); | ||||
|             $toolbar->divider(); | ||||
|  | ||||
|             $toolbar->preferences('com_languages'); | ||||
|             $toolbar->divider(); | ||||
|         } | ||||
|  | ||||
|         $toolbar->help('Languages:_Installed'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,132 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\View\Language; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\View\GenericDataException; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\CMS\Toolbar\Toolbar; | ||||
| use Joomla\CMS\Toolbar\ToolbarHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * HTML View class for the Languages component. | ||||
|  * | ||||
|  * @since  1.5 | ||||
|  */ | ||||
| class HtmlView extends BaseHtmlView | ||||
| { | ||||
|     /** | ||||
|      * The active item | ||||
|      * | ||||
|      * @var  object | ||||
|      */ | ||||
|     public $item; | ||||
|  | ||||
|     /** | ||||
|      * The Form object | ||||
|      * | ||||
|      * @var  \Joomla\CMS\Form\Form | ||||
|      */ | ||||
|     public $form; | ||||
|  | ||||
|     /** | ||||
|      * The model state | ||||
|      * | ||||
|      * @var  \Joomla\Registry\Registry | ||||
|      */ | ||||
|     public $state; | ||||
|  | ||||
|     /** | ||||
|      * The actions the user is authorised to perform | ||||
|      * | ||||
|      * @var    \Joomla\Registry\Registry | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     protected $canDo; | ||||
|  | ||||
|     /** | ||||
|      * Display the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->item  = $this->get('Item'); | ||||
|         $this->form  = $this->get('Form'); | ||||
|         $this->state = $this->get('State'); | ||||
|         $this->canDo = ContentHelper::getActions('com_languages'); | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors), 500); | ||||
|         } | ||||
|  | ||||
|         $this->addToolbar(); | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the page title and toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function addToolbar() | ||||
|     { | ||||
|         Factory::getApplication()->getInput()->set('hidemainmenu', 1); | ||||
|         $isNew   = empty($this->item->lang_id); | ||||
|         $canDo   = $this->canDo; | ||||
|         $toolbar = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         ToolbarHelper::title( | ||||
|             Text::_($isNew ? 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_NEW_TITLE' : 'COM_LANGUAGES_VIEW_LANGUAGE_EDIT_EDIT_TITLE'), | ||||
|             'comments-2 langmanager' | ||||
|         ); | ||||
|  | ||||
|         if (($isNew && $canDo->get('core.create')) || (!$isNew && $canDo->get('core.edit'))) { | ||||
|             $toolbar->apply('language.apply'); | ||||
|         } | ||||
|  | ||||
|         $saveGroup = $toolbar->dropdownButton('save-group'); | ||||
|  | ||||
|         $saveGroup->configure( | ||||
|             function (Toolbar $childBar) use ($canDo, $isNew) { | ||||
|                 if (($isNew && $canDo->get('core.create')) || (!$isNew && $canDo->get('core.edit'))) { | ||||
|                     $childBar->save('language.save'); | ||||
|                 } | ||||
|  | ||||
|                 // If an existing item, can save to a copy only if we have create rights. | ||||
|                 if ($canDo->get('core.create')) { | ||||
|                     $childBar->save2new('language.save2new'); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         if ($isNew) { | ||||
|             $toolbar->cancel('language.cancel', 'JTOOLBAR_CANCEL'); | ||||
|         } else { | ||||
|             $toolbar->cancel('language.cancel'); | ||||
|         } | ||||
|  | ||||
|         $toolbar->divider(); | ||||
|         $toolbar->help('Languages:_Edit_Content_Language'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,150 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\View\Languages; | ||||
|  | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\View\GenericDataException; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\CMS\Toolbar\Button\DropdownButton; | ||||
| use Joomla\CMS\Toolbar\ToolbarHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * HTML Languages View class for the Languages component. | ||||
|  * | ||||
|  * @since  1.6 | ||||
|  */ | ||||
| class HtmlView extends BaseHtmlView | ||||
| { | ||||
|     /** | ||||
|      * An array of items | ||||
|      * | ||||
|      * @var  array | ||||
|      */ | ||||
|     protected $items; | ||||
|  | ||||
|     /** | ||||
|      * The pagination object | ||||
|      * | ||||
|      * @var  \Joomla\CMS\Pagination\Pagination | ||||
|      */ | ||||
|     protected $pagination; | ||||
|  | ||||
|     /** | ||||
|      * The model state | ||||
|      * | ||||
|      * @var   \Joomla\Registry\Registry | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     protected $state; | ||||
|  | ||||
|     /** | ||||
|      * Form object for search filters | ||||
|      * | ||||
|      * @var    \Joomla\CMS\Form\Form | ||||
|      * | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     public $filterForm; | ||||
|  | ||||
|     /** | ||||
|      * The active search filters | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     public $activeFilters; | ||||
|  | ||||
|     /** | ||||
|      * Display the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->items         = $this->get('Items'); | ||||
|         $this->pagination    = $this->get('Pagination'); | ||||
|         $this->state         = $this->get('State'); | ||||
|         $this->filterForm    = $this->get('FilterForm'); | ||||
|         $this->activeFilters = $this->get('ActiveFilters'); | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors), 500); | ||||
|         } | ||||
|  | ||||
|         $this->addToolbar(); | ||||
|  | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the page title and toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   1.6 | ||||
|      */ | ||||
|     protected function addToolbar(): void | ||||
|     { | ||||
|         $canDo   = ContentHelper::getActions('com_languages'); | ||||
|         $toolbar = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_LANGUAGES_TITLE'), 'comments langmanager'); | ||||
|  | ||||
|         if ($canDo->get('core.create')) { | ||||
|             $toolbar->addNew('language.add'); | ||||
|         } | ||||
|  | ||||
|         if ($canDo->get('core.edit.state')) { | ||||
|             /** @var DropdownButton $dropdown */ | ||||
|             $dropdown = $toolbar->dropdownButton('status-group', 'JTOOLBAR_CHANGE_STATUS') | ||||
|                 ->toggleSplit(false) | ||||
|                 ->icon('icon-ellipsis-h') | ||||
|                 ->buttonClass('btn btn-action') | ||||
|                 ->listCheck(true); | ||||
|  | ||||
|             $childBar = $dropdown->getChildToolbar(); | ||||
|  | ||||
|             $childBar->publish('languages.publish')->listCheck(true); | ||||
|             $childBar->unpublish('languages.unpublish')->listCheck(true); | ||||
|  | ||||
|             if ($this->state->get('filter.published') != -2) { | ||||
|                 $childBar->trash('languages.trash')->listCheck(true); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if ($this->state->get('filter.published') == -2 && $canDo->get('core.delete')) { | ||||
|             $toolbar->delete('languages.delete', 'JTOOLBAR_DELETE_FROM_TRASH') | ||||
|                 ->message('JGLOBAL_CONFIRM_DELETE') | ||||
|                 ->listCheck(true); | ||||
|         } | ||||
|  | ||||
|         if ($canDo->get('core.admin')) { | ||||
|             // Add install languages link to the lang installer component. | ||||
|             $toolbar->link('COM_LANGUAGES_INSTALL', 'index.php?option=com_installer&view=languages') | ||||
|                 ->icon('icon-upload'); | ||||
|             $toolbar->divider(); | ||||
|  | ||||
|             $toolbar->preferences('com_languages'); | ||||
|             $toolbar->divider(); | ||||
|         } | ||||
|  | ||||
|         $toolbar->help('Languages:_Content'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,52 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\View\Multilangstatus; | ||||
|  | ||||
| use Joomla\CMS\Component\ComponentHelper; | ||||
| use Joomla\CMS\Language\LanguageHelper; | ||||
| use Joomla\CMS\Language\Multilanguage; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\Component\Languages\Administrator\Helper\MultilangstatusHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Displays the multilang status. | ||||
|  * | ||||
|  * @since  1.7.1 | ||||
|  */ | ||||
| class HtmlView extends BaseHtmlView | ||||
| { | ||||
|     /** | ||||
|      * Display the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse. | ||||
|      * | ||||
|      * @return  void | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->homes           = MultilangstatusHelper::getHomes(); | ||||
|         $this->language_filter = Multilanguage::isEnabled(); | ||||
|         $this->switchers       = MultilangstatusHelper::getLangswitchers(); | ||||
|         $this->listUsersError  = MultilangstatusHelper::getContacts(); | ||||
|         $this->contentlangs    = MultilangstatusHelper::getContentlangs(); | ||||
|         $this->site_langs      = LanguageHelper::getInstalledLanguages(0); | ||||
|         $this->statuses        = MultilangstatusHelper::getStatus(); | ||||
|         $this->homepages       = Multilanguage::getSiteHomePages(); | ||||
|         $this->defaultHome     = MultilangstatusHelper::getDefaultHomeModule(); | ||||
|         $this->default_lang    = ComponentHelper::getParams('com_languages')->get('site', 'en-GB'); | ||||
|  | ||||
|         parent::display($tpl); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,148 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\View\Override; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\View\GenericDataException; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\CMS\Toolbar\Toolbar; | ||||
| use Joomla\CMS\Toolbar\ToolbarHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * View to edit a language override | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class HtmlView extends BaseHtmlView | ||||
| { | ||||
|     /** | ||||
|      * The form to use for the view. | ||||
|      * | ||||
|      * @var     object | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $form; | ||||
|  | ||||
|     /** | ||||
|      * The item to edit. | ||||
|      * | ||||
|      * @var     object | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $item; | ||||
|  | ||||
|     /** | ||||
|      * The model state. | ||||
|      * | ||||
|      * @var     object | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $state; | ||||
|  | ||||
|     /** | ||||
|      * Displays the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->form  = $this->get('Form'); | ||||
|         $this->item  = $this->get('Item'); | ||||
|         $this->state = $this->get('State'); | ||||
|  | ||||
|         $app = Factory::getApplication(); | ||||
|  | ||||
|         $languageClient = $app->getUserStateFromRequest('com_languages.overrides.language_client', 'language_client'); | ||||
|  | ||||
|         if ($languageClient == null) { | ||||
|             $app->enqueueMessage(Text::_('COM_LANGUAGES_OVERRIDE_FIRST_SELECT_MESSAGE'), 'warning'); | ||||
|  | ||||
|             $app->redirect('index.php?option=com_languages&view=overrides'); | ||||
|         } | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors)); | ||||
|         } | ||||
|  | ||||
|         // Check whether the cache has to be refreshed. | ||||
|         $cached_time = Factory::getApplication()->getUserState( | ||||
|             'com_languages.overrides.cachedtime.' . $this->state->get('filter.client') . '.' . $this->state->get('filter.language'), | ||||
|             0 | ||||
|         ); | ||||
|  | ||||
|         if (time() - $cached_time > 60 * 5) { | ||||
|             $this->state->set('cache_expired', true); | ||||
|         } | ||||
|  | ||||
|         // Add strings for translations in \Javascript. | ||||
|         Text::script('COM_LANGUAGES_VIEW_OVERRIDE_NO_RESULTS'); | ||||
|         Text::script('COM_LANGUAGES_VIEW_OVERRIDE_REQUEST_ERROR'); | ||||
|  | ||||
|         $this->addToolbar(); | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds the page title and toolbar. | ||||
|      * | ||||
|      * @return void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected function addToolbar() | ||||
|     { | ||||
|         Factory::getApplication()->getInput()->set('hidemainmenu', true); | ||||
|  | ||||
|         $canDo   = ContentHelper::getActions('com_languages'); | ||||
|         $toolbar = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_OVERRIDE_EDIT_TITLE'), 'comments langmanager'); | ||||
|  | ||||
|         if ($canDo->get('core.edit')) { | ||||
|             $toolbar->apply('override.apply'); | ||||
|         } | ||||
|  | ||||
|         $saveGroup = $toolbar->dropdownButton('save-group'); | ||||
|  | ||||
|         $saveGroup->configure( | ||||
|             function (Toolbar $childBar) use ($canDo) { | ||||
|                 if ($canDo->get('core.edit')) { | ||||
|                     $childBar->save('override.save'); | ||||
|                 } | ||||
|  | ||||
|                 // This component does not support Save as Copy. | ||||
|                 if ($canDo->get('core.edit') && $canDo->get('core.create')) { | ||||
|                     $childBar->save2new('override.save2new'); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|         if (empty($this->item->key)) { | ||||
|             $toolbar->cancel('override.cancel', 'JTOOLBAR_CANCEL'); | ||||
|         } else { | ||||
|             $toolbar->cancel('override.cancel'); | ||||
|         } | ||||
|  | ||||
|         $toolbar->divider(); | ||||
|         $toolbar->help('Languages:_Edit_Override'); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,140 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Administrator | ||||
|  * @subpackage  com_languages | ||||
|  * | ||||
|  * @copyright   (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Component\Languages\Administrator\View\Overrides; | ||||
|  | ||||
| use Joomla\CMS\Helper\ContentHelper; | ||||
| use Joomla\CMS\Language\Text; | ||||
| use Joomla\CMS\MVC\View\GenericDataException; | ||||
| use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView; | ||||
| use Joomla\CMS\Toolbar\ToolbarHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * View for language overrides list. | ||||
|  * | ||||
|  * @since  2.5 | ||||
|  */ | ||||
| class HtmlView extends BaseHtmlView | ||||
| { | ||||
|     /** | ||||
|      * The items to list. | ||||
|      * | ||||
|      * @var     array | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $items; | ||||
|  | ||||
|     /** | ||||
|      * The pagination object. | ||||
|      * | ||||
|      * @var     object | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $pagination; | ||||
|  | ||||
|     /** | ||||
|      * The model state. | ||||
|      * | ||||
|      * @var     object | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected $state; | ||||
|  | ||||
|     /** | ||||
|      * An array containing all frontend and backend languages | ||||
|      * | ||||
|      * @var    array | ||||
|      * @since  4.0.0 | ||||
|      */ | ||||
|     protected $languages; | ||||
|  | ||||
|     /** | ||||
|      * Form object for search filters | ||||
|      * | ||||
|      * @var  \Joomla\CMS\Form\Form | ||||
|      */ | ||||
|     public $filterForm; | ||||
|  | ||||
|     /** | ||||
|      * The active search filters | ||||
|      * | ||||
|      * @var  array | ||||
|      */ | ||||
|     public $activeFilters; | ||||
|  | ||||
|     /** | ||||
|      * Displays the view. | ||||
|      * | ||||
|      * @param   string  $tpl  The name of the template file to parse. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     public function display($tpl = null) | ||||
|     { | ||||
|         $this->state         = $this->get('State'); | ||||
|         $this->items         = $this->get('Overrides'); | ||||
|         $this->languages     = $this->get('Languages'); | ||||
|         $this->pagination    = $this->get('Pagination'); | ||||
|         $this->filterForm    = $this->get('FilterForm'); | ||||
|         $this->activeFilters = $this->get('ActiveFilters'); | ||||
|  | ||||
|         // Check for errors. | ||||
|         if (\count($errors = $this->get('Errors'))) { | ||||
|             throw new GenericDataException(implode("\n", $errors)); | ||||
|         } | ||||
|  | ||||
|         $this->addToolbar(); | ||||
|         parent::display($tpl); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds the page title and toolbar. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   2.5 | ||||
|      */ | ||||
|     protected function addToolbar() | ||||
|     { | ||||
|         // Get the results for each action | ||||
|         $canDo   = ContentHelper::getActions('com_languages'); | ||||
|         $toolbar = $this->getDocument()->getToolbar(); | ||||
|  | ||||
|         ToolbarHelper::title(Text::_('COM_LANGUAGES_VIEW_OVERRIDES_TITLE'), 'comments langmanager'); | ||||
|  | ||||
|         if ($canDo->get('core.create')) { | ||||
|             $toolbar->addNew('override.add'); | ||||
|         } | ||||
|  | ||||
|         if ($canDo->get('core.delete') && $this->pagination->total) { | ||||
|             $toolbar->delete('overrides.delete') | ||||
|                 ->message('JGLOBAL_CONFIRM_DELETE'); | ||||
|         } | ||||
|  | ||||
|         if ($this->getCurrentUser()->authorise('core.admin')) { | ||||
|             $toolbar->standardButton('purge', 'COM_LANGUAGES_VIEW_OVERRIDES_PURGE', 'overrides.purge') | ||||
|                 ->listCheck(false) | ||||
|                 ->icon('icon-refresh'); | ||||
|         } | ||||
|  | ||||
|         if ($canDo->get('core.admin')) { | ||||
|             $toolbar->preferences('com_languages'); | ||||
|         } | ||||
|  | ||||
|         $toolbar->divider(); | ||||
|         $toolbar->help('Languages:_Overrides'); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user