Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 53 additions & 60 deletions domain_alias/src/DomainAliasStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

namespace Drupal\domain_alias;

use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Cache\MemoryCache\MemoryCacheInterface;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\domain\DomainInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
* Alias loader utility class.
Expand All @@ -25,38 +22,42 @@ class DomainAliasStorage extends ConfigEntityStorage implements DomainAliasStora
protected $typedConfig;

/**
* Constructs a DomainAliasStorage object.
* The request stack object.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;


/**
* Sets the TypedConfigManager dependency.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
* The entity type definition.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \Drupal\Component\Uuid\UuidInterface $uuid_service
* The UUID service.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Drupal\Core\Cache\MemoryCache\MemoryCacheInterface $memory_cache
* The memory cache.
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
* The typed config handler.
*/
public function __construct(EntityTypeInterface $entity_type, ConfigFactoryInterface $config_factory, UuidInterface $uuid_service, LanguageManagerInterface $language_manager, MemoryCacheInterface $memory_cache, TypedConfigManagerInterface $typed_config) {
parent::__construct($entity_type, $config_factory, $uuid_service, $language_manager, $memory_cache);
protected function setTypedConfigManager(TypedConfigManagerInterface $typed_config) {
$this->typedConfig = $typed_config;
}

/**
* Sets the request stack object dependency.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack object.
*/
protected function setRequestStack(RequestStack $request_stack) {
$this->requestStack = $request_stack;
}

/**
* {@inheritdoc}
*/
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static(
$entity_type,
$container->get('config.factory'),
$container->get('uuid'),
$container->get('language_manager'),
$container->get('entity.memory_cache'),
$container->get('config.typed')
);
$instance = parent::createInstance($container, $entity_type);
$instance->setTypedConfigManager($container->get('config.typed'));
$instance->setRequestStack($container->get('request_stack'));

return $instance;
}

/**
Expand Down Expand Up @@ -137,23 +138,26 @@ public function sort($a, $b) {
public function getPatterns($hostname) {
$parts = explode('.', $hostname);
$count = count($parts);

// Account for ports.
$port = NULL;
if (substr_count($hostname, ':') > 0) {
// Extract port and save for later.
$ports = explode(':', $parts[$count - 1]);
$parts[$count - 1] = preg_replace('/:(\d+)/', '', $parts[$count - 1]);
$parts[] = $ports[1];
$port = $ports[1];
}

// Build the list of possible matching patterns.
$patterns = $this->buildPatterns($parts);
// Pattern lists are sorted based on the fewest wildcards. That gives us
// more precise matches first.
uasort($patterns, [$this, 'sort']);
array_unshift($patterns, $hostname);
// Re-assemble parts without port
array_unshift($patterns, implode('.', $parts));

// Account for ports.
if (isset($ports)) {
$patterns = $this->buildPortPatterns($patterns, $hostname);
}
$patterns = $this->buildPortPatterns($patterns, $hostname, $port);

// Return unique patters.
return array_unique($patterns);
Expand Down Expand Up @@ -210,42 +214,31 @@ private function buildPatterns(array $parts) {
* An array of eligible matching patterns.
* @param string $hostname
* A hostname string, in the format example.com.
* @param integer $port
* The port of the request.
*
* @return array
* An array of eligible matching patterns, modified by port.
*/
private function buildPortPatterns(array $patterns, $hostname) {
private function buildPortPatterns(array $patterns, $hostname, $port = NULL) {
// Fetch the port if empty.
if (empty($port)) {
$port = $this->requestStack->getCurrentRequest()->getPort();
}

$new_patterns = [];
foreach ($patterns as $index => $pattern) {
// Make a pattern for port wildcards.
if (substr_count($pattern, ':') < 1) {
$new = explode('.', $pattern);
$port = (int) array_pop($new);
$allow = FALSE;
// Do not allow *.* or *:*.
foreach ($new as $item) {
if ($item != '*') {
$allow = TRUE;
}
}
if ($allow) {
// For port 80, allow bare hostname matches.
if ($port == 80) {
// Base hostname with port.
$patterns[] = str_replace(':' . $port, '', $hostname);
// Base hostname is allowed.
$patterns[] = implode('.', $new);
}
// Base hostname with wildcard port.
$patterns[] = str_replace(':' . $port, ':*', $hostname);
// Pattern with exact port.
$patterns[] = implode('.', $new) . ':' . $port;
// Pattern with wildcard port.
$patterns[] = implode('.', $new) . ':*';
}
unset($patterns[$index]);
// If default ports, allow exact no-port alias
$new_patterns[] = $pattern . ':*';
if (empty($port) || $port == 80 || $port == 443) {
$new_patterns[] = $pattern;
}
if (!empty($port)) {
$new_patterns[] = $pattern . ':' . $port;
}
}
return $patterns;

return $new_patterns;
}

}