[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/installation/src/Model/ -> LanguagesModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Installation
   5   * @subpackage  Model
   6   *
   7   * @copyright   (C) 2012 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\CMS\Installation\Model;
  12  
  13  use Joomla\CMS\Application\ApplicationHelper;
  14  use Joomla\CMS\Component\ComponentHelper;
  15  use Joomla\CMS\Factory;
  16  use Joomla\CMS\Form\Form;
  17  use Joomla\CMS\Installer\Installer;
  18  use Joomla\CMS\Installer\InstallerHelper;
  19  use Joomla\CMS\Language\LanguageHelper;
  20  use Joomla\CMS\Language\Text;
  21  use Joomla\CMS\Table\Table;
  22  use Joomla\CMS\Updater\Update;
  23  use Joomla\CMS\Updater\Updater;
  24  use Joomla\Database\DatabaseAwareInterface;
  25  use Joomla\Database\DatabaseAwareTrait;
  26  use Joomla\Registry\Registry;
  27  
  28  // phpcs:disable PSR1.Files.SideEffects
  29  \defined('_JEXEC') or die;
  30  // phpcs:enable PSR1.Files.SideEffects
  31  
  32  /**
  33   * Language Installer model for the Joomla Core Installer.
  34   *
  35   * @since  3.1
  36   */
  37  class LanguagesModel extends BaseInstallationModel implements DatabaseAwareInterface
  38  {
  39      use DatabaseAwareTrait;
  40  
  41      /**
  42       * @var    object  Client object.
  43       * @since  3.1
  44       */
  45      protected $client;
  46  
  47      /**
  48       * @var    array  Languages description.
  49       * @since  3.1
  50       */
  51      protected $data;
  52  
  53      /**
  54       * @var    string  Language path.
  55       * @since  3.1
  56       */
  57      protected $path;
  58  
  59      /**
  60       * @var    integer  Total number of languages installed.
  61       * @since  3.1
  62       */
  63      protected $langlist;
  64  
  65      /**
  66       * @var    integer  Admin Id, author of all generated content.
  67       * @since  3.1
  68       */
  69      protected $adminId;
  70  
  71      /**
  72       * Constructor: Deletes the default installation config file and recreates it with the good config file.
  73       *
  74       * @since  3.1
  75       */
  76      public function __construct()
  77      {
  78          // Overrides application config and set the configuration.php file so tokens and database works.
  79          if (file_exists(JPATH_BASE . '/configuration.php')) {
  80              Factory::getApplication()->setConfiguration(new Registry(new \JConfig()));
  81          }
  82  
  83          parent::__construct();
  84      }
  85  
  86      /**
  87       * Generate a list of language choices to install in the Joomla CMS.
  88       *
  89       * @return  array
  90       *
  91       * @since   3.1
  92       */
  93      public function getItems()
  94      {
  95          // Get the extension_id of the en-GB package.
  96          $db        = $this->getDatabase();
  97          $extQuery  = $db->getQuery(true);
  98  
  99          $extQuery->select($db->quoteName('extension_id'))
 100              ->from($db->quoteName('#__extensions'))
 101              ->where($db->quoteName('type') . ' = ' . $db->quote('package'))
 102              ->where($db->quoteName('element') . ' = ' . $db->quote('pkg_en-GB'))
 103              ->where($db->quoteName('client_id') . ' = 0');
 104  
 105          $db->setQuery($extQuery);
 106  
 107          $extId = (int) $db->loadResult();
 108  
 109          if ($extId) {
 110              $updater = Updater::getInstance();
 111  
 112              /*
 113               * The following function call uses the extension_id of the en-GB package.
 114               * In #__update_sites_extensions you should have this extension_id linked
 115               * to the Accredited Translations Repo.
 116               */
 117              $updater->findUpdates(array($extId), 0);
 118  
 119              $query = $db->getQuery(true);
 120  
 121              // Select the required fields from the updates table.
 122              $query->select($db->quoteName(array('update_id', 'name', 'element', 'version')))
 123                  ->from($db->quoteName('#__updates'))
 124                  ->order($db->quoteName('name'));
 125  
 126              $db->setQuery($query);
 127              $list = $db->loadObjectList();
 128  
 129              if (!$list || $list instanceof \Exception) {
 130                  $list = array();
 131              }
 132          } else {
 133              $list = array();
 134          }
 135  
 136          return $list;
 137      }
 138  
 139      /**
 140       * Method that installs in Joomla! the selected languages in the Languages View of the installer.
 141       *
 142       * @param   array  $lids  List of the update_id value of the languages to install.
 143       *
 144       * @return  boolean  True if successful
 145       */
 146      public function install($lids)
 147      {
 148          $app = Factory::getApplication();
 149          $installerBase = new Installer();
 150          $installerBase->setDatabase($this->getDatabase());
 151  
 152          // Loop through every selected language.
 153          foreach ($lids as $id) {
 154              $installer = clone $installerBase;
 155  
 156              // Loads the update database object that represents the language.
 157              $language = Table::getInstance('update');
 158              $language->load($id);
 159  
 160              // Get the URL to the XML manifest file of the selected language.
 161              $remote_manifest = $this->getLanguageManifest($id);
 162  
 163              if (!$remote_manifest) {
 164                  // Could not find the url, the information in the update server may be corrupt.
 165                  $message = Text::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_INSTALL_LANGUAGE', $language->name);
 166                  $message .= ' ' . Text::_('INSTL_DEFAULTLANGUAGE_TRY_LATER');
 167  
 168                  $app->enqueueMessage($message, 'warning');
 169  
 170                  continue;
 171              }
 172  
 173              // Based on the language XML manifest get the URL of the package to download.
 174              $package_url = $this->getPackageUrl($remote_manifest);
 175  
 176              if (!$package_url) {
 177                  // Could not find the URL, maybe the URL is wrong in the update server, or there is no internet access.
 178                  $message = Text::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_INSTALL_LANGUAGE', $language->name);
 179                  $message .= ' ' . Text::_('INSTL_DEFAULTLANGUAGE_TRY_LATER');
 180  
 181                  $app->enqueueMessage($message, 'warning');
 182  
 183                  continue;
 184              }
 185  
 186              // Download the package to the tmp folder.
 187              $package = $this->downloadPackage($package_url);
 188  
 189              if (!$package) {
 190                  $app->enqueueMessage(Text::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_DOWNLOAD_PACKAGE', $package_url), 'error');
 191  
 192                  continue;
 193              }
 194  
 195              // Install the package.
 196              if (!$installer->install($package['dir'])) {
 197                  // There was an error installing the package.
 198                  $message = Text::sprintf('INSTL_DEFAULTLANGUAGE_COULD_NOT_INSTALL_LANGUAGE', $language->name);
 199                  $message .= ' ' . Text::_('INSTL_DEFAULTLANGUAGE_TRY_LATER');
 200  
 201                  $app->enqueueMessage($message, 'warning');
 202  
 203                  continue;
 204              }
 205  
 206              // Cleanup the install files in tmp folder.
 207              if (!is_file($package['packagefile'])) {
 208                  $package['packagefile'] = $app->get('tmp_path') . '/' . $package['packagefile'];
 209              }
 210  
 211              InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']);
 212  
 213              // Delete the installed language from the list.
 214              $language->delete($id);
 215          }
 216  
 217          return true;
 218      }
 219  
 220      /**
 221       * Gets the manifest file of a selected language from a the language list in an update server.
 222       *
 223       * @param   integer  $uid  The id of the language in the #__updates table.
 224       *
 225       * @return  string
 226       *
 227       * @since   3.1
 228       */
 229      protected function getLanguageManifest($uid)
 230      {
 231          $instance = Table::getInstance('update');
 232          $instance->load($uid);
 233  
 234          return trim($instance->detailsurl);
 235      }
 236  
 237      /**
 238       * Finds the URL of the package to download.
 239       *
 240       * @param   string  $remoteManifest  URL to the manifest XML file of the remote package.
 241       *
 242       * @return  string|boolean
 243       *
 244       * @since   3.1
 245       */
 246      protected function getPackageUrl($remoteManifest)
 247      {
 248          $update = new Update();
 249          $update->loadFromXml($remoteManifest);
 250  
 251          // Get the download url from the remote manifest
 252          $downloadUrl = $update->get('downloadurl', false);
 253  
 254          // Check if the download url exist, otherwise return empty value
 255          if ($downloadUrl === false) {
 256              return '';
 257          }
 258  
 259          return trim($downloadUrl->_data);
 260      }
 261  
 262      /**
 263       * Download a language package from a URL and unpack it in the tmp folder.
 264       *
 265       * @param   string  $url  URL of the package.
 266       *
 267       * @return  array|boolean  Package details or false on failure.
 268       *
 269       * @since   3.1
 270       */
 271      protected function downloadPackage($url)
 272      {
 273          $app = Factory::getApplication();
 274  
 275          // Download the package from the given URL.
 276          $p_file = InstallerHelper::downloadPackage($url);
 277  
 278          // Was the package downloaded?
 279          if (!$p_file) {
 280              $app->enqueueMessage(Text::_('INSTL_ERROR_INVALID_URL'), 'warning');
 281  
 282              return false;
 283          }
 284  
 285          // Unpack the downloaded package file.
 286          return InstallerHelper::unpack($app->get('tmp_path') . '/' . $p_file);
 287      }
 288  
 289      /**
 290       * Get Languages item data for the Administrator.
 291       *
 292       * @return  array
 293       *
 294       * @since   3.1
 295       */
 296      public function getInstalledlangsAdministrator()
 297      {
 298          return $this->getInstalledlangs('administrator');
 299      }
 300  
 301      /**
 302       * Get Languages item data for the Frontend.
 303       *
 304       * @return  array  List of installed languages in the frontend application.
 305       *
 306       * @since   3.1
 307       */
 308      public function getInstalledlangsFrontend()
 309      {
 310          return $this->getInstalledlangs('site');
 311      }
 312  
 313      /**
 314       * Get Languages item data.
 315       *
 316       * @param   string  $clientName  Name of the cms client.
 317       *
 318       * @return  array
 319       *
 320       * @since   3.1
 321       */
 322      protected function getInstalledlangs($clientName = 'administrator')
 323      {
 324          // Get information.
 325          $path     = $this->getPath();
 326          $client   = $this->getClient($clientName);
 327          $langlist = $this->getLanguageList($client->id);
 328  
 329          // Compute all the languages.
 330          $data = array();
 331  
 332          foreach ($langlist as $lang) {
 333              $file = $path . '/' . $lang . '/langmetadata.xml';
 334  
 335              if (!is_file($file)) {
 336                  $file = $path . '/' . $lang . '/' . $lang . '.xml';
 337              }
 338  
 339              $info = Installer::parseXMLInstallFile($file);
 340              $row  = new \stdClass();
 341              $row->language = $lang;
 342  
 343              if (!is_array($info)) {
 344                  continue;
 345              }
 346  
 347              foreach ($info as $key => $value) {
 348                  $row->$key = $value;
 349              }
 350  
 351              // If current then set published.
 352              $params = ComponentHelper::getParams('com_languages');
 353  
 354              if ($params->get($client->name, 'en-GB') == $row->language) {
 355                  $row->published = 1;
 356              } else {
 357                  $row->published = 0;
 358              }
 359  
 360              $row->checked_out = null;
 361              $data[]           = $row;
 362          }
 363  
 364          usort($data, array($this, 'compareLanguages'));
 365  
 366          return $data;
 367      }
 368  
 369      /**
 370       * Get installed languages data.
 371       *
 372       * @param   integer  $clientId  The client ID to retrieve data for.
 373       *
 374       * @return  object  The language data.
 375       *
 376       * @since   3.1
 377       */
 378      protected function getLanguageList($clientId = 1)
 379      {
 380          // Create a new db object.
 381          $db    = $this->getDatabase();
 382          $query = $db->getQuery(true);
 383  
 384          // Select field element from the extensions table.
 385          $query->select($db->quoteName(array('element', 'name')))
 386              ->from($db->quoteName('#__extensions'))
 387              ->where($db->quoteName('type') . ' = ' . $db->quote('language'))
 388              ->where($db->quoteName('state') . ' = 0')
 389              ->where($db->quoteName('enabled') . ' = 1')
 390              ->where($db->quoteName('client_id') . ' = ' . (int) $clientId);
 391  
 392          $db->setQuery($query);
 393  
 394          $this->langlist = $db->loadColumn();
 395  
 396          return $this->langlist;
 397      }
 398  
 399      /**
 400       * Compare two languages in order to sort them.
 401       *
 402       * @param   object  $lang1  The first language.
 403       * @param   object  $lang2  The second language.
 404       *
 405       * @return  integer
 406       *
 407       * @since   3.1
 408       */
 409      protected function compareLanguages($lang1, $lang2)
 410      {
 411          return strcmp($lang1->name, $lang2->name);
 412      }
 413  
 414      /**
 415       * Get the languages folder path.
 416       *
 417       * @return  string  The path to the languages folders.
 418       *
 419       * @since   3.1
 420       */
 421      protected function getPath()
 422      {
 423          if ($this->path === null) {
 424              $client     = $this->getClient();
 425              $this->path = LanguageHelper::getLanguagePath($client->path);
 426          }
 427  
 428          return $this->path;
 429      }
 430  
 431      /**
 432       * Get the client object of Administrator or Frontend.
 433       *
 434       * @param   string  $client  Name of the client object.
 435       *
 436       * @return  object
 437       *
 438       * @since   3.1
 439       */
 440      protected function getClient($client = 'administrator')
 441      {
 442          $this->client = ApplicationHelper::getClientInfo($client, true);
 443  
 444          return $this->client;
 445      }
 446  
 447      /**
 448       * Set the default language.
 449       *
 450       * @param   string  $language    The language to be set as default.
 451       * @param   string  $clientName  The name of the CMS client.
 452       *
 453       * @return  boolean
 454       *
 455       * @since   3.1
 456       */
 457      public function setDefault($language, $clientName = 'administrator')
 458      {
 459          $client = $this->getClient($clientName);
 460  
 461          $params = ComponentHelper::getParams('com_languages');
 462          $params->set($client->name, $language);
 463  
 464          $table = Table::getInstance('extension');
 465          $id    = $table->find(array('element' => 'com_languages'));
 466  
 467          // Load
 468          if (!$table->load($id)) {
 469              Factory::getApplication()->enqueueMessage($table->getError(), 'warning');
 470  
 471              return false;
 472          }
 473  
 474          $table->params = (string) $params;
 475  
 476          // Pre-save checks.
 477          if (!$table->check()) {
 478              Factory::getApplication()->enqueueMessage($table->getError(), 'warning');
 479  
 480              return false;
 481          }
 482  
 483          // Save the changes.
 484          if (!$table->store()) {
 485              Factory::getApplication()->enqueueMessage($table->getError(), 'warning');
 486  
 487              return false;
 488          }
 489  
 490          return true;
 491      }
 492  
 493      /**
 494       * Get the current setup options from the session.
 495       *
 496       * @return  array
 497       *
 498       * @since   3.1
 499       */
 500      public function getOptions()
 501      {
 502          return Factory::getSession()->get('setup.options', array());
 503      }
 504  
 505      /**
 506       * Get the model form.
 507       *
 508       * @param   string|null $view  The view being processed.
 509       *
 510       * @return  mixed  JForm object on success, false on failure.
 511       *
 512       * @since   3.1
 513       */
 514      public function getForm($view = null)
 515      {
 516          if (!$view) {
 517              $view = Factory::getApplication()->input->getWord('view', 'defaultlanguage');
 518          }
 519  
 520          // Get the form.
 521          Form::addFormPath(JPATH_COMPONENT . '/forms');
 522          Form::addFieldPath(JPATH_COMPONENT . '/model/fields');
 523          Form::addRulePath(JPATH_COMPONENT . '/model/rules');
 524  
 525          try {
 526              $form = Form::getInstance('jform', $view, array('control' => 'jform'));
 527          } catch (\Exception $e) {
 528              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 529  
 530              return false;
 531          }
 532  
 533          // Check the session for previously entered form data.
 534          $data = (array) $this->getOptions();
 535  
 536          // Bind the form data if present.
 537          if (!empty($data)) {
 538              $form->bind($data);
 539          }
 540  
 541          return $form;
 542      }
 543  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer