DomainForm.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. namespace Drupal\domain;
  3. use Drupal\Core\Entity\EntityForm;
  4. use Drupal\Core\Entity\EntityTypeManagerInterface;
  5. use Drupal\Core\Form\FormStateInterface;
  6. use Drupal\Core\Render\RendererInterface;
  7. use Symfony\Component\DependencyInjection\ContainerInterface;
  8. /**
  9. * Base form for domain edit forms.
  10. */
  11. class DomainForm extends EntityForm {
  12. /**
  13. * The domain entity storage.
  14. *
  15. * @var \Drupal\domain\DomainStorageInterface
  16. */
  17. protected $domainStorage;
  18. /**
  19. * The renderer.
  20. *
  21. * @var \Drupal\Core\Render\RendererInterface
  22. */
  23. protected $renderer;
  24. /**
  25. * The domain validator.
  26. *
  27. * @var \Drupal\domain\DomainValidatorInterface
  28. */
  29. protected $validator;
  30. /**
  31. * The entity type manager.
  32. *
  33. * @var \Drupal\Core\Entity\EntityTypeManagerInterface
  34. */
  35. protected $entityTypeManager;
  36. /**
  37. * Constructs a DomainForm object.
  38. *
  39. * @param \Drupal\domain\DomainStorageInterface $domain_storage
  40. * The domain storage manager.
  41. * @param \Drupal\Core\Render\RendererInterface $renderer
  42. * The renderer.
  43. * @param \Drupal\domain\DomainValidatorInterface $validator
  44. * The domain validator.
  45. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
  46. * The entity type manager.
  47. */
  48. public function __construct(DomainStorageInterface $domain_storage, RendererInterface $renderer, DomainValidatorInterface $validator, EntityTypeManagerInterface $entity_type_manager) {
  49. $this->domainStorage = $domain_storage;
  50. $this->renderer = $renderer;
  51. $this->validator = $validator;
  52. $this->entityTypeManager = $entity_type_manager;
  53. }
  54. /**
  55. * {@inheritdoc}
  56. */
  57. public static function create(ContainerInterface $container) {
  58. return new static(
  59. $container->get('entity_type.manager')->getStorage('domain'),
  60. $container->get('renderer'),
  61. $container->get('domain.validator'),
  62. $container->get('entity_type.manager')
  63. );
  64. }
  65. /**
  66. * {@inheritdoc}
  67. */
  68. public function form(array $form, FormStateInterface $form_state) {
  69. $form = parent::form($form, $form_state);
  70. /** @var \Drupal\domain\Entity\Domain $domain */
  71. $domain = $this->entity;
  72. // Create defaults if this is the first domain.
  73. $count_existing = $this->domainStorage->getQuery()->count()->execute();
  74. if (!$count_existing) {
  75. $domain->addProperty('hostname', $this->domainStorage->createHostname());
  76. $domain->addProperty('name', $this->config('system.site')->get('name'));
  77. }
  78. $form['domain_id'] = [
  79. '#type' => 'value',
  80. '#value' => $domain->getDomainId(),
  81. ];
  82. $form['hostname'] = [
  83. '#type' => 'textfield',
  84. '#title' => $this->t('Hostname'),
  85. '#size' => 40,
  86. '#maxlength' => 80,
  87. '#default_value' => $domain->getCanonical(),
  88. '#description' => $this->t('The canonical hostname, using the full <em>subdomain.example.com</em> format. Leave off the http:// and the trailing slash and do not include any paths.<br />If this domain uses a custom http(s) port, you should specify it here, e.g.: <em>subdomain.example.com:1234</em><br />The hostname may contain only lowercase alphanumeric characters, dots, dashes, and a colon (if using alternative ports).'),
  89. ];
  90. $form['id'] = [
  91. '#type' => 'machine_name',
  92. '#default_value' => !empty($domain->id()) ? $domain->id() : '',
  93. '#disabled' => !empty($domain->id()),
  94. '#machine_name' => [
  95. 'source' => ['hostname'],
  96. 'exists' => [$this->domainStorage, 'load'],
  97. ],
  98. ];
  99. $form['name'] = [
  100. '#type' => 'textfield',
  101. '#title' => $this->t('Name'),
  102. '#size' => 40,
  103. '#maxlength' => 80,
  104. '#default_value' => $domain->label(),
  105. '#description' => $this->t('The human-readable name is shown in domain lists and may be used as the title tag.'),
  106. ];
  107. // Do not use the :// suffix when storing data.
  108. $add_suffix = FALSE;
  109. $form['scheme'] = [
  110. '#type' => 'radios',
  111. '#title' => $this->t('Domain URL scheme'),
  112. '#options' => [
  113. 'http' => 'http://',
  114. 'https' => 'https://',
  115. 'variable' => 'Variable',
  116. ],
  117. '#default_value' => $domain->getRawScheme(),
  118. '#description' => $this->t('This URL scheme will be used when writing links and redirects to this domain and its resources. Selecting <strong>Variable</strong> will inherit the current scheme of the web request.'),
  119. ];
  120. $form['status'] = [
  121. '#type' => 'radios',
  122. '#title' => $this->t('Domain status'),
  123. '#options' => [1 => $this->t('Active'), 0 => $this->t('Inactive')],
  124. '#default_value' => (int) $domain->status(),
  125. '#description' => $this->t('"Inactive" domains are only accessible to user roles with that assigned permission.'),
  126. ];
  127. $form['weight'] = [
  128. '#type' => 'weight',
  129. '#title' => $this->t('Weight'),
  130. '#delta' => $count_existing + 1,
  131. '#default_value' => $domain->getWeight(),
  132. '#description' => $this->t('The sort order for this record. Lower values display first.'),
  133. ];
  134. $form['is_default'] = [
  135. '#type' => 'checkbox',
  136. '#title' => $this->t('Default domain'),
  137. '#default_value' => $domain->isDefault(),
  138. '#description' => $this->t('If a URL request fails to match a domain record, the settings for this domain will be used. Only one domain can be default.'),
  139. ];
  140. $form['validate_url'] = [
  141. '#type' => 'checkbox',
  142. '#title' => $this->t('Test server response'),
  143. '#default_value' => TRUE,
  144. '#description' => $this->t('Validate that url of the host is accessible to Drupal before saving.'),
  145. ];
  146. $required = $this->validator->getRequiredFields();
  147. foreach ($form as $key => $element) {
  148. if (in_array($key, $required)) {
  149. $form[$key]['#required'] = TRUE;
  150. }
  151. }
  152. return $form;
  153. }
  154. /**
  155. * {@inheritdoc}
  156. */
  157. public function validateForm(array &$form, FormStateInterface $form_state) {
  158. /** @var \Drupal\domain\DomainInterface $entity */
  159. $entity = $this->entity;
  160. $hostname = $entity->getHostname();
  161. $errors = $this->validator->validate($hostname);
  162. if (!empty($errors)) {
  163. // Render errors to display as message.
  164. $message = [
  165. '#theme' => 'item_list',
  166. '#items' => $errors,
  167. ];
  168. $message = $this->renderer->renderPlain($message);
  169. $form_state->setErrorByName('hostname', $message);
  170. }
  171. // Validate if the same hostname exists.
  172. // Do not use domain loader because it may change hostname.
  173. $existing = $this->domainStorage->loadByProperties(['hostname' => $hostname]);
  174. $existing = reset($existing);
  175. // If we have already registered a hostname, make sure we don't create a
  176. // duplicate.
  177. // We cannot check id() here, as the machine name is editable.
  178. if ($existing && $existing->getDomainId() != $entity->getDomainId()) {
  179. $form_state->setErrorByName('hostname', $this->t('The hostname is already registered.'));
  180. }
  181. // Check the domain response. First, clear the path value.
  182. $entity->setPath();
  183. // Check the response.
  184. $response = $this->validator->checkResponse($entity);
  185. // If validate_url is set, then we must receive a 200 response.
  186. if ($entity->validate_url && $response != 200) {
  187. if (empty($response)) {
  188. $response = 500;
  189. }
  190. $form_state->setErrorByName('hostname', $this->t('The server request to @url returned a @response response. To proceed, disable the <em>Test server response</em> in the form.', ['@url' => $entity->getPath(), '@response' => $response]));
  191. }
  192. }
  193. /**
  194. * {@inheritdoc}
  195. */
  196. public function save(array $form, FormStateInterface $form_state) {
  197. $status = parent::save($form, $form_state);
  198. if ($status == SAVED_NEW) {
  199. \Drupal::messenger()->addMessage($this->t('Domain record created.'));
  200. }
  201. else {
  202. \Drupal::messenger()->addMessage($this->t('Domain record updated.'));
  203. }
  204. $form_state->setRedirect('domain.admin');
  205. }
  206. }