domain_microsite-1.0.0-alpha4/domain_microsite.module

domain_microsite.module
<?php

/**
 * @file
 * Allows creating microsites at paths using the Domain module/ecosystem.
 */

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\domain\DomainInterface;
use Drupal\domain_microsite\DomainMicrositeConstants;

/**
 * Implements hook_help().
 */
function domain_microsite_help($route_name, RouteMatchInterface $route_match) {
  if ($route_name == 'help.page.domain_microsite') {
    $text = file_get_contents(dirname(__FILE__) . "/README.md");
    $output = nl2br($text);
    return $output;
  }
}

/**
 * Implements hook_domain_request_alter().
 *
 * Sets the requested domain (current/active domain) to a domain microsite if
 * the request path is a subpath of a domain microsite base path.
 */
function domain_microsite_domain_request_alter(DomainInterface &$request_domain) {
  // Stores calculated domain.
  static $_domain;
  if (isset($_domain)) {
    $request_domain = $_domain;
  }
  else {
    global $base_path;
    $current_user = \Drupal::currentUser();
    // Permission should match Drupal\domain\Access\DomainAccessCheck::access().
    $current_user_is_admin = $current_user->hasPermission('administer domains') || $current_user->hasPermission('access inactive domains');
    $request = parse_url($request_domain->getUrl());
    $path = trim(substr($request['path'], strlen($base_path)), '/');
    if ($path == '') {
      return;
    }
    // Get eligible domain microsites on the requested hostname.
    $microsites = [];
    $domains = \Drupal::entityTypeManager()->getStorage('domain')->loadMultiple();
    foreach ($domains as $domain) {
      $parent_id = domain_microsite_parent_id($domain);
      $microsite_path = domain_microsite_base_path($domain);
      if ($microsite_path != '' && $parent_id != '' && isset($domains[$parent_id]) && $request['host'] == $domains[$parent_id]->getHostname()) {
        $microsites[$microsite_path] = $domain->id();
      }
    }
    // Compare request path against eligible domain microsite base paths,
    // starting with the longest path possible, and if a match exists,
    // set that domain microsite as the request domain.
    do {
      if (isset($microsites[$path])) {
        $matched_domain = $domains[$microsites[$path]];
        // If matched domain is inactive, do not switch unless admin.
        if (!$matched_domain->status() && !$current_user_is_admin) {
          break;
        }
        // Matched microsite should use the domain alias configuration of its
        // parent domain (which would be the existing request domain).
        if ($alias = $request_domain->get('alias')) {
          $matched_domain->set('alias', $alias);
        }
        // Set matched microsite as new request domain.
        $request_domain = $matched_domain;
        $request_domain->setMatchType();
        $_domain = $request_domain;
        break;
      }
      // Remove last child of request path and check again.
      $path = substr($path, 0, strrpos($path, '/'));
    } while ($path != '');
  }
}

/**
 * Implements hook_ENTITY_TYPE_load() for domain.
 *
 * Sets domain microsite properties for path and url with working urls.
 */
function domain_microsite_domain_load($domains) {
  global $base_path;
  $original_base_path = $base_path;

  foreach ($domains as $domain) {
    $parent_id = domain_microsite_parent_id($domain);
    $microsite_path = domain_microsite_base_path($domain);
    if ($parent_id != '' && $microsite_path != '') {
      // Must set and re-set hostname and global base path because of how setUrl
      // and setPath work.
      $original_hostname = $domain->getHostname();
      $parent_domain = \Drupal::entityTypeManager()->getStorage('domain')->load($parent_id);
      $domain->setHostname($parent_domain->getHostname());
      $domain->setUrl();
      $base_path = $base_path . $microsite_path . '/';
      $domain->setPath();
      $base_path = $original_base_path;
      $domain->setHostname($original_hostname);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for domain_admin_overview_form.
 *
 * Modify domain admin overview list to make sense with domain microsites.
 */
function domain_microsite_form_domain_admin_overview_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Override hostname header to be more generic.
  $form['domains']['#header']['hostname'] = t('Site URL');

  // Modify row data to include domain microsite values.
  foreach ($form['domains']['#domains'] as $domain) {
    $domain_id = $domain->id();
    // Override hostname column value with site url.
    $url = $domain->getPath();
    $form['domains'][$domain_id]['hostname']['#markup'] = t('<a href=:url>@name</a>', [
      ':url' => $url,
      '@name' => $url,
    ]);
    // Remove make default operation link for microsites.
    if ($domain->getThirdPartySetting('domain_microsite', 'is_domain_microsite')) {
      unset($form['domains'][$domain_id]['operations']['data']['#links']['default']);
    }
  }
}

/**
 * Implements hook_form_FORM_ID_alter() for domain_edit_form.
 *
 * Adds domain microsite fields and functionality to domain edit form.
 */
function domain_microsite_form_domain_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $domain = $form_state->getFormObject()->getEntity();
  $domain_id = $domain->id();
  $is_domain_microsite = $domain->getThirdPartySetting('domain_microsite', 'is_domain_microsite');
  $parent_domain_id = $domain->getThirdPartySetting('domain_microsite', 'parent_domain_id');
  $base_path = $domain->getThirdPartySetting('domain_microsite', 'base_path');

  // Add domain microsite by path fields.
  $form['domain_microsite'] = [
    '#type' => 'fieldset',
    '#title' => t('Domain microsite by path'),
  ];
  $domains = \Drupal::entityTypeManager()->getStorage('domain')->loadMultiple();
  $parent_domains = [''];
  foreach ($domains as $_domain) {
    $_domain_id = $_domain->id();
    if ($_domain->isDefault()) {
      $default_domain_id = $_domain_id;
    }
    if (!($_parent_domain_id = $_domain->getThirdPartySetting('domain_microsite', 'parent_domain_id'))) {
      $parent_domains[$_domain_id] = $_domain->getCanonical();
    }
    if ($_parent_domain_id && $_parent_domain_id == $domain_id) {
      $form['domain_microsite']['text']['#markup'] = t('This domain may not be a domain microsite because other domain microsites have specified it as a parent domain.');
      return;
    }
  }
  asort($parent_domains);
  $form['domain_microsite']['domain_microsite_is_domain_microsite'] = [
    '#type' => 'checkbox',
    '#title' => t('Make domain microsite'),
    '#default_value' => $is_domain_microsite,
    '#description' => t('Use this domain record as a domain microsite by path.<br />Cannot be <em>Default domain</em> and ignores <em>Test server response</em>.<br /><strong>Note:</strong> The required fields <em>Hostname</em> and <em>Machine name</em> will be overwritten with auto-generated identifiers. </strong>'),
  ];
  $form['domain_microsite']['domain_microsite_parent_domain_id'] = [
    '#type' => 'select',
    '#title' => t('Parent domain'),
    '#options' => $parent_domains,
    '#default_value' => ($parent_domain_id) ? ($parent_domains[$parent_domain_id] ? $parent_domain_id : '') : ($default_domain_id ?? ''),
    '#description' => t('The parent domain hostname to use as the canonical hostname of this microsite. The parent domain must not itself be a domain microsite.'),
  ];
  $form['domain_microsite']['domain_microsite_base_path'] = [
    '#type' => 'textfield',
    '#title' => t('Base path'),
    '#size' => 40,
    '#maxlength' => 80,
    '#default_value' => $base_path,
    '#description' => t('The base path for this microsite. Start with a slash. Leave off trailing slash. Example: "/example-microsite".'),
  ];
  $form['is_default']['#states'] = [
    'disabled' => [':input[name="domain_microsite_is_domain_microsite"]' => ['checked' => TRUE]],
  ];
  $form['validate_url']['#states'] = [
    'disabled' => [':input[name="domain_microsite_is_domain_microsite"]' => ['checked' => TRUE]],
  ];
  if ($is_domain_microsite) {
    $form['hostname']['#attributes']['readonly'] = 'readonly';
    $form['hostname']['#description'] = t('Auto-generated by Domain Microsite by Path and can not be changed while this domain is a domain microsite.');
  }

  // Must add custom validation function before ::validateForm.
  array_unshift($form['#validate'], 'domain_microsite_domain_edit_form_validate');
}

/**
 * Alters domain hostname and machine_name to auto-generated values.
 *
 * Also does validation for domain microsite fields.
 *
 * @see domain_microsite_form_domain_edit_form_alter()
 */
function domain_microsite_domain_edit_form_validate($form, FormStateInterface &$form_state) {
  $form_object = $form_state->getFormObject();
  $domain = $form_object->getEntity();
  $is_domain_microsite = $form_state->getValue('domain_microsite_is_domain_microsite');
  $parent_domain_id = $form_state->getValue('domain_microsite_parent_domain_id');
  $base_path = $form_state->getValue('domain_microsite_base_path');

  if ($is_domain_microsite) {
    // Auto generate hostname and machine name for new domain microsites.
    if ($domain->isNew()) {
      $domain->createDomainId();
      $new_domainid = $domain->getDomainId();
      $new_id = sprintf(DomainMicrositeConstants::DOMAIN_MICROSITE_ID_PATTERN, $new_domainid);
      $new_hostname = sprintf(DomainMicrositeConstants::DOMAIN_MICROSITE_HOSTNAME_PATTERN, $new_domainid);
      $domain->set('id', $new_id);
      $domain->set('hostname', $new_hostname);
      // Machine name validation occurred earlier so an existing error must be
      // removed to be able to set a new machine name here.
      $form_errors = $form_state->getErrors();
      unset($form_errors['id']);
      $form_state->clearErrors();
      foreach ($form_errors as $name => $error_message) {
        $form_state->setErrorByName($name, $error_message);
      }
      // Form state values and form object must be updated for later validation.
      $form_object->setEntity($domain);
      $form_state->setValue('domain_id', $new_domainid);
      $form_state->setValue('id', $new_id);
      $form_state->setValue('hostname', $new_hostname);
    }
    $domain->setThirdPartySetting('domain_microsite', 'is_domain_microsite', $is_domain_microsite);
    $domain->setThirdPartySetting('domain_microsite', 'parent_domain_id', $parent_domain_id);
    $domain->setThirdPartySetting('domain_microsite', 'base_path', $base_path);

    $domain_id = $domain->id();
    $domains = \Drupal::entityTypeManager()->getStorage('domain')->loadMultiple();
    if (!isset($domains[$parent_domain_id])) {
      $form_state->setErrorByName('domain_microsite_parent_domain_id', t('Parent domain may not be empty or the selected domain no longer exists.'));
    }
    foreach ($domains as $_domain) {
      $_domain_id = $_domain->id();
      $_parent_domain_id = $_domain->getThirdPartySetting('domain_microsite', 'parent_domain_id');
      $_base_path = $_domain->getThirdPartySetting('domain_microsite', 'base_path');
      if ($_parent_domain_id && $_parent_domain_id == $domain_id) {
        $form_state->setErrorByName('domain_microsite_is_domain_microsite', t('This domain may not be a domain microsite because other domain microsites have specified it as a parent domain.'));
        break;
      }
      if ($domain_id != $_domain_id && $parent_domain_id == $_parent_domain_id && $base_path == $_base_path) {
        $form_state->setErrorByName('domain_microsite_base_path', t('A domain microsite already exists with this parent domain and base path.'));
        break;
      }
    }
    if ($base_path == '/') {
      $form_state->setErrorByName('domain_microsite_base_path', t('The domain microsite base path may not be "/".'));
    }
    if (!preg_match('/^\//i', $base_path)) {
      $form_state->setErrorByName('domain_microsite_base_path', t('The domain microsite base path has to start with a slash.'));
    }
    if (preg_match('/\/$/i', $base_path)) {
      $form_state->setErrorByName('domain_microsite_base_path', t('The domain microsite base path can not end with a slash.'));
    }
    if (!empty($form_state->getValue('is_default'))) {
      $form_state->setErrorByName('is_default', t('Domain microsites cannot be default domain.'));
    }
  }
  else {
    foreach ($domain->getThirdPartySettings('domain_microsite') as $key => $value) {
      $domain->unsetThirdPartySetting('domain_microsite', $key);
    }
  }
}

/**
 * Implements hook_preprocess().
 *
 * Adds domain microsite data to contextual links placeholder id. The id is used
 * as js storage cache key so this prevents bad cached data.
 *
 * This needs to run after contextual_preprocess().
 *
 * @see contextual_preprocess()
 */
function domain_microsite_preprocess(&$variables, $hook, $info) {
  if ($id = $variables['title_suffix']['contextual_links']['#id'] ?? FALSE) {
    $microsite_path = domain_microsite_base_path();
    if ($microsite_path != '') {
      $items = explode('|', $id);
      $new_items = [];
      foreach ($items as $item) {
        $parts = explode(':', $item);
        // part[2] holds route metadata info.
        $parts[2] .= '&domain_microsite_base_path=' . $microsite_path;
        $new_items[] = implode(':', $parts);
      }
      $new_id = implode('|', $new_items);
      $variables['title_suffix']['contextual_links']['#id'] = $new_id;
    }
  }
}

/**
 * Returns domain microsite base path or empty string.
 */
function domain_microsite_base_path($domain = NULL) {
  if ($domain == NULL) {
    $domain = \Drupal::service('domain.negotiator')->getActiveDomain();
  }
  if (!($domain instanceof DomainInterface)) {
    return '';
  }
  $microsite_path = trim($domain->getThirdPartySetting('domain_microsite', 'base_path', ''), '/');
  return $microsite_path;
}

/**
 * Returns domain microsite parent id or empty string.
 */
function domain_microsite_parent_id($domain = NULL) {
  if ($domain == NULL) {
    $domain = \Drupal::service('domain.negotiator')->getActiveDomain();
  }
  if (!($domain instanceof DomainInterface)) {
    return '';
  }
  $parent_id = $domain->getThirdPartySetting('domain_microsite', 'parent_domain_id', '');
  return $parent_id;
}

/**
 * Returns the Drupal base url of a given url.
 */
function domain_microsite_scheme_and_host($url) {
  global $base_path;
  $parsed_url = parse_url($url);
  $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
  $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
  $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
  return $scheme . $host . $port . rtrim($base_path, '/');
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc