LanguageNegotiationUserAdmin.php

Same filename in other branches
  1. 9 core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
  2. 8.9.x core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
  3. 11.x core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php

Namespace

Drupal\user\Plugin\LanguageNegotiation

File

core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php

View source
<?php

namespace Drupal\user\Plugin\LanguageNegotiation;

use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\PathProcessor\PathProcessorManager;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\AdminContext;
use Drupal\Core\Routing\StackedRouteMatchInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\language\Attribute\LanguageNegotiation;
use Drupal\language\LanguageNegotiationMethodBase;
use Drupal\Core\Routing\RouteObjectInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Routing\Exception\ExceptionInterface;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;

/**
 * Identifies admin language from the user preferences.
 */
class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase implements ContainerFactoryPluginInterface {
    
    /**
     * The language negotiation method id.
     */
    const METHOD_ID = 'language-user-admin';
    
    /**
     * The admin context.
     *
     * @var \Drupal\Core\Routing\AdminContext
     */
    protected $adminContext;
    
    /**
     * The router.
     *
     * This is only used when called from an event subscriber, before the request
     * has been populated with the route info.
     *
     * @var \Symfony\Component\Routing\Matcher\UrlMatcherInterface
     */
    protected $router;
    
    /**
     * The path processor manager.
     *
     * @var \Drupal\Core\PathProcessor\PathProcessorManager
     */
    protected $pathProcessorManager;
    
    /**
     * The stacked route match.
     *
     * @var \Drupal\Core\Routing\StackedRouteMatchInterface
     */
    protected $stackedRouteMatch;
    
    /**
     * Constructs a new LanguageNegotiationUserAdmin instance.
     *
     * @param \Drupal\Core\Routing\AdminContext $admin_context
     *   The admin context.
     * @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $router
     *   The router.
     * @param \Drupal\Core\PathProcessor\PathProcessorManager $path_processor_manager
     *   The path processor manager.
     * @param \Drupal\Core\Routing\StackedRouteMatchInterface $stacked_route_match
     *   The stacked route match.
     */
    public function __construct(AdminContext $admin_context, UrlMatcherInterface $router, PathProcessorManager $path_processor_manager, StackedRouteMatchInterface $stacked_route_match) {
        $this->adminContext = $admin_context;
        $this->router = $router;
        $this->pathProcessorManager = $path_processor_manager;
        $this->stackedRouteMatch = $stacked_route_match;
    }
    
    /**
     * {@inheritdoc}
     */
    public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
        return new static($container->get('router.admin_context'), $container->get('router'), $container->get('path_processor_manager'), $container->get('current_route_match'));
    }
    
    /**
     * {@inheritdoc}
     */
    public function getLangcode(?Request $request = NULL) {
        $langcode = NULL;
        // User preference (only for administrators).
        if (($this->currentUser
            ->hasPermission('access administration pages') || $this->currentUser
            ->hasPermission('view the administration theme')) && ($preferred_admin_langcode = $this->currentUser
            ->getPreferredAdminLangcode(FALSE)) && $this->isAdminPath($request)) {
            $langcode = $preferred_admin_langcode;
        }
        // Not an admin, no admin language preference or not on an admin path.
        return $langcode;
    }
    
    /**
     * Checks whether the given path is an administrative one.
     *
     * @param \Symfony\Component\HttpFoundation\Request $request
     *   The request object.
     *
     * @return bool
     *   TRUE if the path is administrative, FALSE otherwise.
     */
    protected function isAdminPath(Request $request) {
        $result = FALSE;
        if ($request && $this->adminContext) {
            // If called from an event subscriber, the request may not have the route
            // object yet (it is still being built), so use the router to look up
            // based on the path.
            $route_match = $this->stackedRouteMatch
                ->getRouteMatchFromRequest($request);
            if ($route_match && !($route_object = $route_match->getRouteObject())) {
                try {
                    // Some inbound path processors make changes to the request. Make a
                    // copy as we're not actually routing the request so we do not want to
                    // make changes.
                    $cloned_request = clone $request;
                    // Process the path as an inbound path. This will remove any language
                    // prefixes and other path components that inbound processing would
                    // clear out, so we can attempt to load the route clearly.
                    $path = $this->pathProcessorManager
                        ->processInbound(urldecode(rtrim($cloned_request->getPathInfo(), '/')), $cloned_request);
                    $attributes = $this->router
                        ->match($path);
                } catch (ExceptionInterface|HttpException) {
                    return FALSE;
                }
                $route_object = $attributes[RouteObjectInterface::ROUTE_OBJECT];
            }
            $result = $this->adminContext
                ->isAdminRoute($route_object);
        }
        return $result;
    }

}

Classes

Title Deprecated Summary
LanguageNegotiationUserAdmin Identifies admin language from the user preferences.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.