123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- <?php
- /**
- * @file
- * Maps multiple host requests to a single domain record.
- */
- use Drupal\Core\Entity\EntityInterface;
- use Drupal\domain\DomainInterface;
- use Drupal\domain\DomainNegotiator;
- use Drupal\domain\DomainAccessControlHandler;
- use Drupal\Core\Url;
- use Drupal\Core\Session\AccountInterface;
- /**
- * Implements hook_domain_request_alter().
- *
- * The logic in this function gives us the following matches for a request to
- * foo.example.com.
- *
- * 'foo.*'
- * '*.example.com'
- * 'foo.*.com'
- * 'foo.example.*'
- * '*.foo.example.com'
- * 'foo.example.com.*'
- *
- * These patterns should be sufficient for most conditions.
- */
- function domain_alias_domain_request_alter(DomainInterface &$domain) {
- // If an exact match has loaded, do nothing.
- if ($domain->getMatchType() == DomainNegotiator::DOMAIN_MATCH_EXACT) {
- return;
- }
- // If no exact match, then run the alias load routine.
- $hostname = $domain->getHostname();
- $alias_storage = \Drupal::service('entity_type.manager')->getStorage('domain_alias');
- $domain_storage = \Drupal::service('entity_type.manager')->getStorage('domain');
- /** @var \Drupal\domain_alias\Entity\DomainAlias $alias */
- if ($alias = $alias_storage->loadByHostname($hostname)) {
- /** @var \Drupal\domain\Entity\Domain $domain */
- if ($domain = $domain_storage->load($alias->getDomainId())) {
- $domain->addProperty('alias', $alias);
- $domain->setMatchType(DomainNegotiator::DOMAIN_MATCH_ALIAS);
- $redirect = $alias->getRedirect();
- if (!empty($redirect)) {
- $domain->setRedirect($redirect);
- }
- }
- else {
- // If the domain did not load, report an error.
- \Drupal::logger('domain_alias')->error('Found matching alias %alias for host request %hostname, but failed to load matching domain with id %id.',
- ['%alias' => $alias->getPattern(),
- '%hostname' => $hostname,
- '%id' => $alias->getDomainId(),
- ]);
- }
- }
- }
- /**
- * Implements hook_domain_operations().
- */
- function domain_alias_domain_operations(DomainInterface $domain, AccountInterface $account) {
- $operations = [];
- // Check permissions. The user must be a super-admin or assigned to the domain.
- $is_domain_admin = $domain->access('update', $account);
- if ($account->hasPermission('administer domain aliases') || ($is_domain_admin && $account->hasPermission('view domain aliases'))) {
- // Add aliases to the list of operations.
- $operations['domain_alias'] = array(
- 'title' => t('Aliases'),
- 'url' => Url::fromRoute('domain_alias.admin', array('domain' => $domain->id())),
- 'weight' => 60,
- );
- }
- return $operations;
- }
- /**
- * Implements hook_ENTITY_TYPE_load().
- */
- function domain_alias_domain_load($entities) {
- static $enabled;
- // We can only perform meaningful actions if url.site is a cache context. Otherwise,
- // the render process ignores our changes.
- if (!isset($enabled)) {
- $required_cache_contexts = \Drupal::getContainer()->getParameter('renderer.config')['required_cache_contexts'];
- if (!in_array('url.site', $required_cache_contexts) && !in_array('url', $required_cache_contexts)) {
- $enabled = FALSE;
- return;
- }
- $enabled = TRUE;
- }
- // We cannot run before the negotiator service has fired.
- $negotiator = \Drupal::service('domain.negotiator');
- $active = $negotiator->getActiveDomain();
- // Do nothing if no domain is active.
- if (is_null($active)) {
- return;
- }
- // Load and rewrite environement-specific aliases.
- $alias_storage = \Drupal::service('entity_type.manager')->getStorage('domain_alias');
- if (isset($active->alias) && $active->alias->getEnvironment() != 'default') {
- foreach ($entities as $id => $domain) {
- if ($environment_aliases = $alias_storage->loadByEnvironmentMatch($domain, $active->alias->getEnvironment())) {
- foreach($environment_aliases as $environment_alias) {
- $pattern = $environment_alias->getPattern();
- // Add a canonical property.
- $domain->setCanonical();
- // Override the domain hostname and path. We always prefer a string match.
- if (substr_count($pattern, '*') < 1) {
- $domain->setHostname($pattern);
- $domain->setPath();
- $domain->setUrl();
- break;
- }
- else {
- // Do a wildcard replacement based on the current request.
- $request = $negotiator->negotiateActiveHostname();
- // First, check for a wildcard port.
- if (substr_count($pattern, ':*') > 0) {
- // Do not replace ports unless they are nonstandard. See
- // \Symfony\Component\HttpFoundation\Request\getHttpHost().
- if (substr_count($request, ':') > 0) {
- $search = explode(':', $pattern);
- $replace = explode(':', $request);
- if (!empty($search[1]) && !empty($replace[1])) {
- $pattern = str_replace(':' . $search[1], ':' . $replace[1], $pattern);
- }
- }
- // If no port wildcard, then remove the port entirely.
- else {
- $pattern = str_replace(':*', '', $pattern);
- }
- }
- $replacements = ['.' => '\.', '*' => '(.+?)'];
- $regex = '/^' . strtr($active->alias->getPattern(), $replacements) . '$/';
- if (preg_match($regex, $request, $matches) && isset($matches[1])) {
- $pattern = str_replace('*', $matches[1], $pattern);
- }
- // Do not let the domain loop back on itself.
- if ($pattern != $domain->getCanonical()) {
- $domain->setHostname($pattern);
- $domain->setPath();
- $domain->setUrl();
- }
- }
- }
- }
- }
- }
- }
- /**
- * Implements hook_ENTITY_TYPE_delete().
- */
- function domain_alias_domain_delete(EntityInterface $entity) {
- $alias_storage = \Drupal::service('entity_type.manager')->getStorage('domain_alias');
- $properties = ['domain_id' => $entity->id()];
- foreach ($alias_storage->loadByProperties($properties) as $alias) {
- $alias->delete();
- }
- }
|