[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/plugins/system/languagefilter/ -> languagefilter.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Plugin
   5   * @subpackage  System.languagefilter
   6   *
   7   * @copyright   (C) 2010 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9  
  10   * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
  11   */
  12  
  13  use Joomla\CMS\Application\ApplicationHelper;
  14  use Joomla\CMS\Application\CMSApplication;
  15  use Joomla\CMS\Application\CMSApplicationInterface;
  16  use Joomla\CMS\Association\AssociationServiceInterface;
  17  use Joomla\CMS\Component\ComponentHelper;
  18  use Joomla\CMS\Factory;
  19  use Joomla\CMS\Filesystem\Folder;
  20  use Joomla\CMS\Language\Associations;
  21  use Joomla\CMS\Language\Language;
  22  use Joomla\CMS\Language\LanguageHelper;
  23  use Joomla\CMS\Language\Multilanguage;
  24  use Joomla\CMS\Language\Text;
  25  use Joomla\CMS\Plugin\CMSPlugin;
  26  use Joomla\CMS\Router\Route;
  27  use Joomla\CMS\Router\Router;
  28  use Joomla\CMS\Router\SiteRouter;
  29  use Joomla\CMS\Uri\Uri;
  30  use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
  31  use Joomla\Registry\Registry;
  32  use Joomla\String\StringHelper;
  33  
  34  // phpcs:disable PSR1.Files.SideEffects
  35  \defined('_JEXEC') or die;
  36  // phpcs:enable PSR1.Files.SideEffects
  37  
  38  /**
  39   * Joomla! Language Filter Plugin.
  40   *
  41   * @since  1.6
  42   */
  43  class PlgSystemLanguageFilter extends CMSPlugin
  44  {
  45      /**
  46       * The routing mode.
  47       *
  48       * @var    boolean
  49       * @since  2.5
  50       */
  51      protected $mode_sef;
  52  
  53      /**
  54       * Available languages by sef.
  55       *
  56       * @var    array
  57       * @since  1.6
  58       */
  59      protected $sefs;
  60  
  61      /**
  62       * Available languages by language codes.
  63       *
  64       * @var    array
  65       * @since  2.5
  66       */
  67      protected $lang_codes;
  68  
  69      /**
  70       * The current language code.
  71       *
  72       * @var    string
  73       * @since  3.4.2
  74       */
  75      protected $current_lang;
  76  
  77      /**
  78       * The default language code.
  79       *
  80       * @var    string
  81       * @since  2.5
  82       */
  83      protected $default_lang;
  84  
  85      /**
  86       * The logged user language code.
  87       *
  88       * @var    string
  89       * @since  3.3.1
  90       */
  91      private $user_lang_code;
  92  
  93      /**
  94       * Application object.
  95       *
  96       * @var    CMSApplicationInterface
  97       * @since  3.3
  98       */
  99      protected $app;
 100  
 101      /**
 102       * Constructor.
 103       *
 104       * @param   object  &$subject  The object to observe
 105       * @param   array   $config    An optional associative array of configuration settings.
 106       *
 107       * @since   1.6
 108       */
 109      public function __construct(&$subject, $config)
 110      {
 111          parent::__construct($subject, $config);
 112  
 113          // Setup language data.
 114          $this->mode_sef     = $this->app->get('sef', 0);
 115          $this->sefs         = LanguageHelper::getLanguages('sef');
 116          $this->lang_codes   = LanguageHelper::getLanguages('lang_code');
 117          $this->default_lang = ComponentHelper::getParams('com_languages')->get('site', 'en-GB');
 118  
 119          // If language filter plugin is executed in a site page.
 120          if ($this->app->isClient('site')) {
 121              $levels = $this->app->getIdentity()->getAuthorisedViewLevels();
 122  
 123              foreach ($this->sefs as $sef => $language) {
 124                  // @todo: In Joomla 2.5.4 and earlier access wasn't set. Non modified Content Languages got 0 as access value
 125                  // we also check if frontend language exists and is enabled
 126                  if (
 127                      ($language->access && !in_array($language->access, $levels))
 128                      || (!array_key_exists($language->lang_code, LanguageHelper::getInstalledLanguages(0)))
 129                  ) {
 130                      unset($this->lang_codes[$language->lang_code], $this->sefs[$language->sef]);
 131                  }
 132              }
 133          } else {
 134              // If language filter plugin is executed in an admin page (ex: Route site).
 135              // Set current language to default site language, fallback to en-GB if there is no content language for the default site language.
 136              $this->current_lang = isset($this->lang_codes[$this->default_lang]) ? $this->default_lang : 'en-GB';
 137  
 138              foreach ($this->sefs as $sef => $language) {
 139                  if (!array_key_exists($language->lang_code, LanguageHelper::getInstalledLanguages(0))) {
 140                      unset($this->lang_codes[$language->lang_code]);
 141                      unset($this->sefs[$language->sef]);
 142                  }
 143              }
 144          }
 145      }
 146  
 147      /**
 148       * After initialise.
 149       *
 150       * @return  void
 151       *
 152       * @since   1.6
 153       */
 154      public function onAfterInitialise()
 155      {
 156          $this->app->item_associations = $this->params->get('item_associations', 0);
 157  
 158          // We need to make sure we are always using the site router, even if the language plugin is executed in admin app.
 159          // Router can be injected when turned into a DI built plugin
 160          $router = Factory::getContainer()->get(SiteRouter::class);
 161  
 162          // Attach build rules for language SEF.
 163          $router->attachBuildRule(array($this, 'preprocessBuildRule'), Router::PROCESS_BEFORE);
 164  
 165          if ($this->mode_sef) {
 166              $router->attachBuildRule(array($this, 'buildRule'), Router::PROCESS_BEFORE);
 167              $router->attachBuildRule(array($this, 'postprocessSEFBuildRule'), Router::PROCESS_AFTER);
 168          } else {
 169              $router->attachBuildRule(array($this, 'postprocessNonSEFBuildRule'), Router::PROCESS_AFTER);
 170          }
 171  
 172          // Attach parse rule.
 173          $router->attachParseRule(array($this, 'parseRule'), Router::PROCESS_BEFORE);
 174      }
 175  
 176      /**
 177       * After route.
 178       *
 179       * @return  void
 180       *
 181       * @since   3.4
 182       */
 183      public function onAfterRoute()
 184      {
 185          // Add custom site name.
 186          if ($this->app->isClient('site') && isset($this->lang_codes[$this->current_lang]) && $this->lang_codes[$this->current_lang]->sitename) {
 187              $this->app->set('sitename', $this->lang_codes[$this->current_lang]->sitename);
 188          }
 189      }
 190  
 191      /**
 192       * Add build preprocess rule to router.
 193       *
 194       * @param   Router  &$router  Router object.
 195       * @param   Uri     &$uri     Uri object.
 196       *
 197       * @return  void
 198       *
 199       * @since   3.4
 200       */
 201      public function preprocessBuildRule(&$router, &$uri)
 202      {
 203          $lang = $uri->getVar('lang', $this->current_lang);
 204  
 205          if (isset($this->sefs[$lang])) {
 206              $lang = $this->sefs[$lang]->lang_code;
 207          }
 208  
 209          $uri->setVar('lang', $lang);
 210      }
 211  
 212      /**
 213       * Add build rule to router.
 214       *
 215       * @param   Router  &$router  Router object.
 216       * @param   Uri     &$uri     Uri object.
 217       *
 218       * @return  void
 219       *
 220       * @since   1.6
 221       */
 222      public function buildRule(&$router, &$uri)
 223      {
 224          $lang = $uri->getVar('lang');
 225  
 226          if (isset($this->lang_codes[$lang])) {
 227              $sef = $this->lang_codes[$lang]->sef;
 228          } else {
 229              $sef = $this->lang_codes[$this->current_lang]->sef;
 230          }
 231  
 232          if (
 233              !$this->params->get('remove_default_prefix', 0)
 234              || $lang !== $this->default_lang
 235              || $lang !== $this->current_lang
 236          ) {
 237              $uri->setPath($uri->getPath() . '/' . $sef . '/');
 238          }
 239      }
 240  
 241      /**
 242       * postprocess build rule for SEF URLs
 243       *
 244       * @param   Router  &$router  Router object.
 245       * @param   Uri     &$uri     Uri object.
 246       *
 247       * @return  void
 248       *
 249       * @since   3.4
 250       */
 251      public function postprocessSEFBuildRule(&$router, &$uri)
 252      {
 253          $uri->delVar('lang');
 254      }
 255  
 256      /**
 257       * postprocess build rule for non-SEF URLs
 258       *
 259       * @param   Router  &$router  Router object.
 260       * @param   Uri     &$uri     Uri object.
 261       *
 262       * @return  void
 263       *
 264       * @since   3.4
 265       */
 266      public function postprocessNonSEFBuildRule(&$router, &$uri)
 267      {
 268          $lang = $uri->getVar('lang');
 269  
 270          if (isset($this->lang_codes[$lang])) {
 271              $uri->setVar('lang', $this->lang_codes[$lang]->sef);
 272          }
 273      }
 274  
 275      /**
 276       * Add parse rule to router.
 277       *
 278       * @param   Router  &$router  Router object.
 279       * @param   Uri     &$uri     Uri object.
 280       *
 281       * @return  void
 282       *
 283       * @since   1.6
 284       */
 285      public function parseRule(&$router, &$uri)
 286      {
 287          // Did we find the current and existing language yet?
 288          $found = false;
 289  
 290          // Are we in SEF mode or not?
 291          if ($this->mode_sef) {
 292              $path = $uri->getPath();
 293              $parts = explode('/', $path);
 294  
 295              $sef = StringHelper::strtolower($parts[0]);
 296  
 297              // Do we have a URL Language Code ?
 298              if (!isset($this->sefs[$sef])) {
 299                  // Check if remove default URL language code is set
 300                  if ($this->params->get('remove_default_prefix', 0)) {
 301                      if ($parts[0]) {
 302                          // We load a default site language page
 303                          $lang_code = $this->default_lang;
 304                      } else {
 305                          // We check for an existing language cookie
 306                          $lang_code = $this->getLanguageCookie();
 307                      }
 308                  } else {
 309                      $lang_code = $this->getLanguageCookie();
 310                  }
 311  
 312                  // No language code. Try using browser settings or default site language
 313                  if (!$lang_code && $this->params->get('detect_browser', 0) == 1) {
 314                      $lang_code = LanguageHelper::detectLanguage();
 315                  }
 316  
 317                  if (!$lang_code) {
 318                      $lang_code = $this->default_lang;
 319                  }
 320  
 321                  if ($lang_code === $this->default_lang && $this->params->get('remove_default_prefix', 0)) {
 322                      $found = true;
 323                  }
 324              } else {
 325                  // We found our language
 326                  $found = true;
 327                  $lang_code = $this->sefs[$sef]->lang_code;
 328  
 329                  // If we found our language, but it's the default language and we don't want a prefix for that, we are on a wrong URL.
 330                  // Or we try to change the language back to the default language. We need a redirect to the proper URL for the default language.
 331                  if ($lang_code === $this->default_lang && $this->params->get('remove_default_prefix', 0)) {
 332                      // Create a cookie.
 333                      $this->setLanguageCookie($lang_code);
 334  
 335                      $found = false;
 336                      array_shift($parts);
 337                      $path = implode('/', $parts);
 338                  }
 339  
 340                  // We have found our language and the first part of our URL is the language prefix
 341                  if ($found) {
 342                      array_shift($parts);
 343  
 344                      // Empty parts array when "index.php" is the only part left.
 345                      if (count($parts) === 1 && $parts[0] === 'index.php') {
 346                          $parts = array();
 347                      }
 348  
 349                      $uri->setPath(implode('/', $parts));
 350                  }
 351              }
 352          } else {
 353              // We are not in SEF mode
 354              $lang_code = $this->getLanguageCookie();
 355  
 356              if (!$lang_code && $this->params->get('detect_browser', 1)) {
 357                  $lang_code = LanguageHelper::detectLanguage();
 358              }
 359  
 360              if (!isset($this->lang_codes[$lang_code])) {
 361                  $lang_code = $this->default_lang;
 362              }
 363          }
 364  
 365          $lang = $uri->getVar('lang', $lang_code);
 366  
 367          if (isset($this->sefs[$lang])) {
 368              // We found our language
 369              $found = true;
 370              $lang_code = $this->sefs[$lang]->lang_code;
 371          }
 372  
 373          // We are called via POST or the nolangfilter url parameter was set. We don't care about the language
 374          // and simply set the default language as our current language.
 375          if (
 376              $this->app->input->getMethod() === 'POST'
 377              || $this->app->input->get('nolangfilter', 0) == 1
 378              || count($this->app->input->post) > 0
 379              || count($this->app->input->files) > 0
 380          ) {
 381              $found = true;
 382  
 383              if (!isset($lang_code)) {
 384                  $lang_code = $this->getLanguageCookie();
 385              }
 386  
 387              if (!$lang_code && $this->params->get('detect_browser', 1)) {
 388                  $lang_code = LanguageHelper::detectLanguage();
 389              }
 390  
 391              if (!isset($this->lang_codes[$lang_code])) {
 392                  $lang_code = $this->default_lang;
 393              }
 394          }
 395  
 396          // We have not found the language and thus need to redirect
 397          if (!$found) {
 398              // Lets find the default language for this user
 399              if (!isset($lang_code) || !isset($this->lang_codes[$lang_code])) {
 400                  $lang_code = false;
 401  
 402                  if ($this->params->get('detect_browser', 1)) {
 403                      $lang_code = LanguageHelper::detectLanguage();
 404  
 405                      if (!isset($this->lang_codes[$lang_code])) {
 406                          $lang_code = false;
 407                      }
 408                  }
 409  
 410                  if (!$lang_code) {
 411                      $lang_code = $this->default_lang;
 412                  }
 413              }
 414  
 415              if ($this->mode_sef) {
 416                  // Use the current language sef or the default one.
 417                  if (
 418                      $lang_code !== $this->default_lang
 419                      || !$this->params->get('remove_default_prefix', 0)
 420                  ) {
 421                      $path = $this->lang_codes[$lang_code]->sef . '/' . $path;
 422                  }
 423  
 424                  $uri->setPath($path);
 425  
 426                  if (!$this->app->get('sef_rewrite')) {
 427                      $uri->setPath('index.php/' . $uri->getPath());
 428                  }
 429  
 430                  $redirectUri = $uri->base() . $uri->toString(array('path', 'query', 'fragment'));
 431              } else {
 432                  $uri->setVar('lang', $this->lang_codes[$lang_code]->sef);
 433                  $redirectUri = $uri->base() . 'index.php?' . $uri->getQuery();
 434              }
 435  
 436              // Set redirect HTTP code to "302 Found".
 437              $redirectHttpCode = 302;
 438  
 439              // If selected language is the default language redirect code is "301 Moved Permanently".
 440              if ($lang_code === $this->default_lang) {
 441                  $redirectHttpCode = 301;
 442  
 443                  // We cannot cache this redirect in browser. 301 is cacheable by default so we need to force to not cache it in browsers.
 444                  $this->app->setHeader('Expires', 'Wed, 17 Aug 2005 00:00:00 GMT', true);
 445                  $this->app->setHeader('Last-Modified', gmdate('D, d M Y H:i:s') . ' GMT', true);
 446                  $this->app->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate', false);
 447                  $this->app->sendHeaders();
 448              }
 449  
 450              // Redirect to language.
 451              $this->app->redirect($redirectUri, $redirectHttpCode);
 452          }
 453  
 454          // We have found our language and now need to set the cookie and the language value in our system
 455          $array = array('lang' => $lang_code);
 456          $this->current_lang = $lang_code;
 457  
 458          // Set the request var.
 459          $this->app->input->set('language', $lang_code);
 460          $this->app->set('language', $lang_code);
 461          $language = $this->app->getLanguage();
 462  
 463          if ($language->getTag() !== $lang_code) {
 464              $language_new = Language::getInstance($lang_code, (bool) $this->app->get('debug_lang'));
 465  
 466              foreach ($language->getPaths() as $extension => $files) {
 467                  if (strpos($extension, 'plg_system') !== false) {
 468                      $extension_name = substr($extension, 11);
 469  
 470                      $language_new->load($extension, JPATH_ADMINISTRATOR)
 471                      || $language_new->load($extension, JPATH_PLUGINS . '/system/' . $extension_name);
 472  
 473                      continue;
 474                  }
 475  
 476                  $language_new->load($extension);
 477              }
 478  
 479              Factory::$language = $language_new;
 480              $this->app->loadLanguage($language_new);
 481          }
 482  
 483          // Create a cookie.
 484          if ($this->getLanguageCookie() !== $lang_code) {
 485              $this->setLanguageCookie($lang_code);
 486          }
 487  
 488          return $array;
 489      }
 490  
 491      /**
 492       * Reports the privacy related capabilities for this plugin to site administrators.
 493       *
 494       * @return  array
 495       *
 496       * @since   3.9.0
 497       */
 498      public function onPrivacyCollectAdminCapabilities()
 499      {
 500          $this->loadLanguage();
 501  
 502          return array(
 503              Text::_('PLG_SYSTEM_LANGUAGEFILTER') => array(
 504                  Text::_('PLG_SYSTEM_LANGUAGEFILTER_PRIVACY_CAPABILITY_LANGUAGE_COOKIE'),
 505              ),
 506          );
 507      }
 508  
 509      /**
 510       * Before store user method.
 511       *
 512       * Method is called before user data is stored in the database.
 513       *
 514       * @param   array    $user   Holds the old user data.
 515       * @param   boolean  $isnew  True if a new user is stored.
 516       * @param   array    $new    Holds the new user data.
 517       *
 518       * @return  void
 519       *
 520       * @since   1.6
 521       */
 522      public function onUserBeforeSave($user, $isnew, $new)
 523      {
 524          if (array_key_exists('params', $user) && $this->params->get('automatic_change', 1) == 1) {
 525              $registry = new Registry($user['params']);
 526              $this->user_lang_code = $registry->get('language');
 527  
 528              if (empty($this->user_lang_code)) {
 529                  $this->user_lang_code = $this->current_lang;
 530              }
 531          }
 532      }
 533  
 534      /**
 535       * After store user method.
 536       *
 537       * Method is called after user data is stored in the database.
 538       *
 539       * @param   array    $user     Holds the new user data.
 540       * @param   boolean  $isnew    True if a new user is stored.
 541       * @param   boolean  $success  True if user was successfully stored in the database.
 542       * @param   string   $msg      Message.
 543       *
 544       * @return  void
 545       *
 546       * @since   1.6
 547       */
 548      public function onUserAfterSave($user, $isnew, $success, $msg): void
 549      {
 550          if ($success && array_key_exists('params', $user) && $this->params->get('automatic_change', 1) == 1) {
 551              $registry = new Registry($user['params']);
 552              $lang_code = $registry->get('language');
 553  
 554              if (empty($lang_code)) {
 555                  $lang_code = $this->current_lang;
 556              }
 557  
 558              if ($lang_code === $this->user_lang_code || !isset($this->lang_codes[$lang_code])) {
 559                  if ($this->app->isClient('site')) {
 560                      $this->app->setUserState('com_users.edit.profile.redirect', null);
 561                  }
 562              } else {
 563                  if ($this->app->isClient('site')) {
 564                      $this->app->setUserState('com_users.edit.profile.redirect', 'index.php?Itemid='
 565                          . $this->app->getMenu()->getDefault($lang_code)->id . '&lang=' . $this->lang_codes[$lang_code]->sef);
 566  
 567                      // Create a cookie.
 568                      $this->setLanguageCookie($lang_code);
 569                  }
 570              }
 571          }
 572      }
 573  
 574      /**
 575       * Method to handle any login logic and report back to the subject.
 576       *
 577       * @param   array  $user     Holds the user data.
 578       * @param   array  $options  Array holding options (remember, autoregister, group).
 579       *
 580       * @return  boolean  True on success.
 581       *
 582       * @since   1.5
 583       */
 584      public function onUserLogin($user, $options = array())
 585      {
 586          if ($this->app->isClient('site')) {
 587              $menu = $this->app->getMenu();
 588  
 589              if ($this->params->get('automatic_change', 1)) {
 590                  $assoc = Associations::isEnabled();
 591                  $lang_code = $user['language'];
 592  
 593                  // If no language is specified for this user, we set it to the site default language
 594                  if (empty($lang_code)) {
 595                      $lang_code = $this->default_lang;
 596                  }
 597  
 598                  // The language has been deleted/disabled or the related content language does not exist/has been unpublished
 599                  // or the related home page does not exist/has been unpublished
 600                  if (
 601                      !array_key_exists($lang_code, $this->lang_codes)
 602                      || !array_key_exists($lang_code, Multilanguage::getSiteHomePages())
 603                      || !Folder::exists(JPATH_SITE . '/language/' . $lang_code)
 604                  ) {
 605                      $lang_code = $this->current_lang;
 606                  }
 607  
 608                  // Try to get association from the current active menu item
 609                  $active = $menu->getActive();
 610  
 611                  $foundAssociation = false;
 612  
 613                  /**
 614                   * Looking for associations.
 615                   * If the login menu item form contains an internal URL redirection,
 616                   * This will override the automatic change to the user preferred site language.
 617                   * In that case we use the redirect as defined in the menu item.
 618                   *  Otherwise we redirect, when available, to the user preferred site language.
 619                   */
 620                  if ($active && !$active->getParams()->get('login_redirect_url')) {
 621                      if ($assoc) {
 622                          $associations = MenusHelper::getAssociations($active->id);
 623                      }
 624  
 625                      // Retrieves the Itemid from a login form.
 626                      $uri = new Uri($this->app->getUserState('users.login.form.return'));
 627  
 628                      if ($uri->getVar('Itemid')) {
 629                          // The login form contains a menu item redirection. Try to get associations from that menu item.
 630                          // If any association set to the user preferred site language, redirect to that page.
 631                          if ($assoc) {
 632                              $associations = MenusHelper::getAssociations($uri->getVar('Itemid'));
 633                          }
 634  
 635                          if (isset($associations[$lang_code]) && $menu->getItem($associations[$lang_code])) {
 636                              $associationItemid = $associations[$lang_code];
 637                              $this->app->setUserState('users.login.form.return', 'index.php?Itemid=' . $associationItemid);
 638                              $foundAssociation = true;
 639                          }
 640                      } elseif (isset($associations[$lang_code]) && $menu->getItem($associations[$lang_code])) {
 641                          /**
 642                           * The login form does not contain a menu item redirection.
 643                           * The active menu item has associations.
 644                           * We redirect to the user preferred site language associated page.
 645                           */
 646                          $associationItemid = $associations[$lang_code];
 647                          $this->app->setUserState('users.login.form.return', 'index.php?Itemid=' . $associationItemid);
 648                          $foundAssociation = true;
 649                      } elseif ($active->home) {
 650                          // We are on a Home page, we redirect to the user preferred site language Home page.
 651                          $item = $menu->getDefault($lang_code);
 652  
 653                          if ($item && $item->language !== $active->language && $item->language !== '*') {
 654                              $this->app->setUserState('users.login.form.return', 'index.php?Itemid=' . $item->id);
 655                              $foundAssociation = true;
 656                          }
 657                      }
 658                  }
 659  
 660                  if ($foundAssociation && $lang_code !== $this->current_lang) {
 661                      // Change language.
 662                      $this->current_lang = $lang_code;
 663  
 664                      // Create a cookie.
 665                      $this->setLanguageCookie($lang_code);
 666  
 667                      // Change the language code.
 668                      Factory::getContainer()->get(\Joomla\CMS\Language\LanguageFactoryInterface::class)->createLanguage($lang_code);
 669                  }
 670              } else {
 671                  if ($this->app->getUserState('users.login.form.return')) {
 672                      $this->app->setUserState('users.login.form.return', Route::_($this->app->getUserState('users.login.form.return'), false));
 673                  }
 674              }
 675          }
 676      }
 677  
 678      /**
 679       * Method to add alternative meta tags for associated menu items.
 680       *
 681       * @return  void
 682       *
 683       * @since   1.7
 684       */
 685      public function onAfterDispatch()
 686      {
 687          $doc = $this->app->getDocument();
 688  
 689          if ($this->app->isClient('site') && $this->params->get('alternate_meta', 1) && $doc->getType() === 'html') {
 690              $languages             = $this->lang_codes;
 691              $homes                 = Multilanguage::getSiteHomePages();
 692              $menu                  = $this->app->getMenu();
 693              $active                = $menu->getActive();
 694              $levels                = $this->app->getIdentity()->getAuthorisedViewLevels();
 695              $remove_default_prefix = $this->params->get('remove_default_prefix', 0);
 696              $server                = Uri::getInstance()->toString(array('scheme', 'host', 'port'));
 697              $is_home               = false;
 698  
 699              // Router can be injected when turned into a DI built plugin
 700              $currentInternalUrl    = 'index.php?' . http_build_query(Factory::getContainer()->get(SiteRouter::class)->getVars());
 701  
 702              if ($active) {
 703                  $active_link  = Route::_($active->link . '&Itemid=' . $active->id);
 704                  $current_link = Route::_($currentInternalUrl);
 705  
 706                  // Load menu associations
 707                  if ($active_link === $current_link) {
 708                      $associations = MenusHelper::getAssociations($active->id);
 709                  }
 710  
 711                  // Check if we are on the home page
 712                  $is_home = ($active->home
 713                      && ($active_link === $current_link || $active_link === $current_link . 'index.php' || $active_link . '/' === $current_link));
 714              }
 715  
 716              // Load component associations.
 717              $option = $this->app->input->get('option');
 718  
 719              $component = $this->app->bootComponent($option);
 720  
 721              if ($component instanceof AssociationServiceInterface) {
 722                  $cassociations = $component->getAssociationsExtension()->getAssociationsForItem();
 723              } else {
 724                  $cName = ucfirst(substr($option, 4)) . 'HelperAssociation';
 725                  JLoader::register($cName, \Joomla\CMS\Filesystem\Path::clean(JPATH_SITE . '/components/' . $option . '/helpers/association.php'));
 726  
 727                  if (class_exists($cName) && is_callable(array($cName, 'getAssociations'))) {
 728                      $cassociations = call_user_func(array($cName, 'getAssociations'));
 729                  }
 730              }
 731  
 732              // For each language...
 733              foreach ($languages as $i => $language) {
 734                  switch (true) {
 735                      // Language without frontend UI || Language without specific home menu || Language without authorized access level
 736                      case !array_key_exists($i, LanguageHelper::getInstalledLanguages(0)):
 737                      case !isset($homes[$i]):
 738                      case isset($language->access) && $language->access && !in_array($language->access, $levels):
 739                          unset($languages[$i]);
 740                          break;
 741  
 742                      // Home page
 743                      case $is_home:
 744                          $language->link = Route::_('index.php?lang=' . $language->sef . '&Itemid=' . $homes[$i]->id);
 745                          break;
 746  
 747                      // Current language link
 748                      case $i === $this->current_lang:
 749                          $language->link = Route::_($currentInternalUrl);
 750                          break;
 751  
 752                      // Component association
 753                      case isset($cassociations[$i]):
 754                          $language->link = Route::_($cassociations[$i]);
 755                          break;
 756  
 757                      // Menu items association
 758                      // Heads up! "$item = $menu" here below is an assignment, *NOT* comparison
 759                      case isset($associations[$i]) && ($item = $menu->getItem($associations[$i])):
 760                          $language->link = Route::_('index.php?Itemid=' . $item->id . '&lang=' . $language->sef);
 761                          break;
 762  
 763                      // Too bad...
 764                      default:
 765                          unset($languages[$i]);
 766                  }
 767              }
 768  
 769              // If there are at least 2 of them, add the rel="alternate" links to the <head>
 770              if (count($languages) > 1) {
 771                  // Remove the sef from the default language if "Remove URL Language Code" is on
 772                  if ($remove_default_prefix && isset($languages[$this->default_lang])) {
 773                      $languages[$this->default_lang]->link
 774                                      = preg_replace('|/' . $languages[$this->default_lang]->sef . '/|', '/', $languages[$this->default_lang]->link, 1);
 775                  }
 776  
 777                  foreach ($languages as $i => $language) {
 778                      $doc->addHeadLink($server . $language->link, 'alternate', 'rel', array('hreflang' => $i));
 779                  }
 780  
 781                  // Add x-default language tag
 782                  if ($this->params->get('xdefault', 1)) {
 783                      $xdefault_language = $this->params->get('xdefault_language', $this->default_lang);
 784                      $xdefault_language = ($xdefault_language === 'default') ? $this->default_lang : $xdefault_language;
 785  
 786                      if (isset($languages[$xdefault_language])) {
 787                          // Use a custom tag because addHeadLink is limited to one URI per tag
 788                          $doc->addCustomTag('<link href="' . $server . $languages[$xdefault_language]->link . '" rel="alternate" hreflang="x-default">');
 789                      }
 790                  }
 791              }
 792          }
 793      }
 794  
 795      /**
 796       * Set the language cookie
 797       *
 798       * @param   string  $languageCode  The language code for which we want to set the cookie
 799       *
 800       * @return  void
 801       *
 802       * @since   3.4.2
 803       */
 804      private function setLanguageCookie($languageCode)
 805      {
 806          // If is set to use language cookie for a year in plugin params, save the user language in a new cookie.
 807          if ((int) $this->params->get('lang_cookie', 0) === 1) {
 808              // Create a cookie with one year lifetime.
 809              $this->app->input->cookie->set(
 810                  ApplicationHelper::getHash('language'),
 811                  $languageCode,
 812                  time() + 365 * 86400,
 813                  $this->app->get('cookie_path', '/'),
 814                  $this->app->get('cookie_domain', ''),
 815                  $this->app->isHttpsForced(),
 816                  true
 817              );
 818          } else {
 819              // If not, set the user language in the session (that is already saved in a cookie).
 820              $this->app->getSession()->set('plg_system_languagefilter.language', $languageCode);
 821          }
 822      }
 823  
 824      /**
 825       * Get the language cookie
 826       *
 827       * @return  string
 828       *
 829       * @since   3.4.2
 830       */
 831      private function getLanguageCookie()
 832      {
 833          // Is is set to use a year language cookie in plugin params, get the user language from the cookie.
 834          if ((int) $this->params->get('lang_cookie', 0) === 1) {
 835              $languageCode = $this->app->input->cookie->get(ApplicationHelper::getHash('language'));
 836          } else {
 837              // Else get the user language from the session.
 838              $languageCode = $this->app->getSession()->get('plg_system_languagefilter.language');
 839          }
 840  
 841          // Let's be sure we got a valid language code. Fallback to null.
 842          if (!array_key_exists($languageCode, $this->lang_codes)) {
 843              $languageCode = null;
 844          }
 845  
 846          return $languageCode;
 847      }
 848  }


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