Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

A simple subsite setup in Drupal

Parent Feed: 

namespace Drupal\mymodule;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* Get the active subsite from the request based on URL.
*/
class SubsiteManager implements EventSubscriberInterface, OutboundPathProcessorInterface, InboundPathProcessorInterface {

const SUBSITE_ENTITY_TYPE = 'node';

const SUBSITE_PATH_FIELD = 'field_path';

/**
* The entity type manager.
*
*
@var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* The configuration factory.
*
*
@var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;

/**
* The active subsite.
*
*
@var \Drupal\Core\Entity\EntityInterface
*/
protected $subsite;

/**
* Contruct the SubsiteManager.
*
*
@param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*
@param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The configuration factory.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, ConfigFactoryInterface $configFactory) {
$this->entityTypeManager = $entityTypeManager;
$this->configFactory = $configFactory;
}

/**
* {
@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
// Runs as soon as possible in the request but after
// LanguageRequestSubscriber (priority 255) because we want the language
// prefix to come before the subsite prefix.
KernelEvents::REQUEST => ['onKernelRequestSetSubsite', 254],
];
}

/**
* Get the active subsite from the request.
*
*
@param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The event to process.
*/
public function onKernelRequestSetSubsite(GetResponseEvent $event) {
// Set the default subsite as fallback.
if ($default_subsite = $this->getDefaultSubsite()) {
$this->setCurrentSubsite($default_subsite);
}

$request = $event->getRequest();
$request_path = urldecode(trim($request->getPathInfo(), '/'));

// First strip the language when it's processor is available. This is only
// the case when more than 1 language is installed.
if (\Drupal::hasService('path_processor_language')) {
$request_path = \Drupal::service('path_processor_language')->processInbound($request_path, $request);
}

// Get the first part of the path to check if it matches to a subsite page.
$path_args = array_filter(explode('/', $request_path));
$prefix = array_shift($path_args);

if (!$prefix) {
return;
}

// If the prefix matches to a subsite page, set it in the property.
$subsites = $this->entityTypeManager->getStorage(static::SUBSITE_ENTITY_TYPE)->loadByProperties([
'type' => 'subsite',
static::SUBSITE_PATH_FIELD => $prefix,
]);
$subsite = reset($subsites);
if ($subsite) {
$this->setCurrentSubsite($subsite);
}
}

/**
* {
@inheritdoc}
*/
public function processInbound($path, Request $request) {
// Get the first part of the path to check if it matches to a subsite page.
$path_args = explode('/', trim($path, '/'));
$prefix = array_shift($path_args);

// If we don't have a prefix, or if the prefix is the only thing in the path,
// keep the current path as it is. This is a subsite homepage.
if (!$prefix || $path === '/' . $prefix) {
return $path;
}

// Only when dealing with a subsite page, change the request.
$subsites = $this->entityTypeManager->getStorage(static::SUBSITE_ENTITY_TYPE)->loadByProperties([
'type' => 'subsite',
static::SUBSITE_PATH_FIELD => $prefix,
]);
$subsite = reset($subsites);
if (!$subsite) {
return $path;
}

return '/' . implode('/', $path_args);
}

/**
* {
@inheritdoc}
*/
public function processOutbound($path, &$options = [], Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL) {
if (!empty($options['subsite'])) {
$subsite = $this->entityTypeManager->getStorage(static::SUBSITE_ENTITY_TYPE)->load($options['subsite']);
$options['prefix'] = $this->addPrefix($options['prefix'], $subsite->get(static::SUBSITE_PATH_FIELD)->value);
}
$subsite = $this->getCurrentSubsite();
if ($subsite && empty($options['subsite']) && !$this->isDefaultSubsite() && $path !== '/' . $subsite->get(static::SUBSITE_PATH_FIELD)->value) {
$options['subsite'] = $subsite->id();
$options['prefix'] = $this->addPrefix($options['prefix'], $subsite->get(static::SUBSITE_PATH_FIELD)->value);
}
return $path;
}

/**
* Create the updated path prefix.
*
*
@param string $existing_prefix
* The existing path prefix.
*
@param string $subsite_prefix
* The Subsite path prefix.
*
*
@return string
* The combined path prefix.
*/
protected function addPrefix($existing_prefix, $subsite_prefix) {
$existing_prefix = trim($existing_prefix, '/');
$subsite_prefix = trim($subsite_prefix, '/');
$combined_prefixes = array_filter([$existing_prefix, $subsite_prefix]);
$prefix = implode('/', $combined_prefixes) . '/';
return $prefix !== '/' ? $prefix : '';
}

/**
* Set the current subsite.
*
*
@param \Drupal\Core\Entity\EntityInterface $subsite
* The current subsite.
*/
public function setCurrentSubsite(EntityInterface $subsite) {
$this->subsite = $subsite;
}

/**
* Get the current subsite.
*
*
@return \Drupal\Core\Entity\EntityInterface
* The current subsite.
*/
public function getCurrentSubsite() {
return $this->subsite;
}

/**
* Get the default subsite.
*/
public function getDefaultSubsite() {
// Fetch a default subsite based on a config page.
$default_subsite_id = $this->configFactory->get('mymodule.settings')->get('default');
return $default_subsite_id ? $this->entityTypeManager->getStorage(static::SUBSITE_ENTITY_TYPE)->load($default_subsite_id) : NULL;
}

/**
* Check if the current subsite is the default subsite.
*/
public function isDefaultSubsite() {
return $this->subsite && $this->getDefaultSubsite()->id() === $this->subsite->id();
}

}</span>

Author: 
RSS Tags: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web