Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / web / modules / contrib / redirect / src / Form / RedirectForm.php
1 <?php
2
3 namespace Drupal\redirect\Form;
4
5 use Drupal\Component\Utility\UrlHelper;
6 use Drupal\Core\Entity\ContentEntityForm;
7 use Drupal\Core\Language\Language;
8 use Drupal\Core\Language\LanguageInterface;
9 use Drupal\Core\Routing\MatchingRouteNotFoundException;
10 use Drupal\Core\Url;
11 use Drupal\redirect\Entity\Redirect;
12 use Drupal\Core\Form\FormStateInterface;
13
14 class RedirectForm extends ContentEntityForm {
15
16   /**
17    * {@inheritdoc}
18    */
19   protected function prepareEntity() {
20     /** @var \Drupal\redirect\Entity\Redirect $redirect */
21     $redirect = $this->entity;
22
23     if ($redirect->isNew()) {
24
25       // To pass in the query set parameters into GET as follows:
26       // source_query[key1]=value1&source_query[key2]=value2
27       $source_query = array();
28       if ($this->getRequest()->get('source_query')) {
29         $source_query = $this->getRequest()->get('source_query');
30       }
31
32       $redirect_options = array();
33       $redirect_query = array();
34       if ($this->getRequest()->get('redirect_options')) {
35         $redirect_options = $this->getRequest()->get('redirect_options');
36         if (isset($redirect_options['query'])) {
37           $redirect_query = $redirect_options['query'];
38           unset($redirect_options['query']);
39         }
40       }
41
42       $source_url = urldecode($this->getRequest()->get('source'));
43       if (!empty($source_url)) {
44         $redirect->setSource($source_url, $source_query);
45       }
46
47       $redirect_url = urldecode($this->getRequest()->get('redirect'));
48       if (!empty($redirect_url)) {
49         try {
50           $redirect->setRedirect($redirect_url, $redirect_query, $redirect_options);
51         }
52         catch (MatchingRouteNotFoundException $e) {
53           drupal_set_message(t('Invalid redirect URL %url provided.', array('%url' => $redirect_url)), 'warning');
54         }
55       }
56
57       $redirect->setLanguage($this->getRequest()->get('language') ? $this->getRequest()->get('language') : Language::LANGCODE_NOT_SPECIFIED);
58     }
59   }
60
61   /**
62    * {@inheritdoc}
63    */
64   public function form(array $form, FormStateInterface $form_state) {
65     $form = parent::form($form, $form_state);
66     /** @var \Drupal\redirect\Entity\Redirect $redirect */
67     $redirect = $this->entity;
68
69     // Only add the configured languages and a single key for all languages.
70     if (isset($form['language']['widget'][0]['value']))  {
71       foreach (\Drupal::languageManager()->getLanguages(LanguageInterface::STATE_CONFIGURABLE) as $langcode => $language) {
72         $form['language']['widget'][0]['value']['#options'][$langcode] = $language->getName();
73       }
74       $form['language']['widget'][0]['value']['#options'][LanguageInterface::LANGCODE_NOT_SPECIFIED] = t('- All languages -');
75     }
76
77     $default_code = $redirect->getStatusCode() ? $redirect->getStatusCode() : \Drupal::config('redirect.settings')->get('default_status_code');
78
79     $form['status_code'] = array(
80       '#type' => 'select',
81       '#title' => t('Redirect status'),
82       '#description' => t('You can find more information about HTTP redirect status codes at <a href="@status-codes">@status-codes</a>.', array('@status-codes' => 'http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection')),
83       '#default_value' => $default_code,
84       '#options' => redirect_status_code_options(),
85     );
86
87     return $form;
88   }
89
90   /**
91    * {@inheritdoc}
92    */
93   public function validateForm(array &$form, FormStateInterface $form_state) {
94     parent::validateForm($form, $form_state);
95     $source = $form_state->getValue(array('redirect_source', 0));
96     $redirect = $form_state->getValue(array('redirect_redirect', 0));
97
98     if ($source['path'] == '<front>') {
99       $form_state->setErrorByName('redirect_source', t('It is not allowed to create a redirect from the front page.'));
100     }
101     if (strpos($source['path'], '#') !== FALSE) {
102       $form_state->setErrorByName('redirect_source', t('The anchor fragments are not allowed.'));
103     }
104     if (strpos($source['path'], '/') === 0) {
105       $form_state->setErrorByName('redirect_source', t('The url to redirect from should not start with a forward slash (/).'));
106     }
107
108     try {
109       $source_url = Url::fromUri('internal:/' . $source['path']);
110       $redirect_url = Url::fromUri($redirect['uri']);
111
112       // It is relevant to do this comparison only in case the source path has
113       // a valid route. Otherwise the validation will fail on the redirect path
114       // being an invalid route.
115       if ($source_url->toString() == $redirect_url->toString()) {
116         $form_state->setErrorByName('redirect_redirect', t('You are attempting to redirect the page to itself. This will result in an infinite loop.'));
117       }
118     }
119     catch (\InvalidArgumentException $e) {
120       // Do nothing, we want to only compare the resulting URLs.
121     }
122
123     $parsed_url = UrlHelper::parse(trim($source['path']));
124     $path = isset($parsed_url['path']) ? $parsed_url['path'] : NULL;
125     $query = isset($parsed_url['query']) ? $parsed_url['query'] : NULL;
126     $hash = Redirect::generateHash($path, $query, $form_state->getValue('language')[0]['value']);
127
128     // Search for duplicate.
129     $redirects = \Drupal::entityManager()
130       ->getStorage('redirect')
131       ->loadByProperties(array('hash' => $hash));
132
133     if (!empty($redirects)) {
134       $redirect = array_shift($redirects);
135       if ($this->entity->isNew() || $redirect->id() != $this->entity->id()) {
136         $form_state->setErrorByName('redirect_source', t('The source path %source is already being redirected. Do you want to <a href="@edit-page">edit the existing redirect</a>?',
137           array(
138             '%source' => $source['path'],
139             '@edit-page' => $redirect->url('edit-form'))));
140       }
141     }
142   }
143
144   /**
145    * {@inheritdoc}
146    */
147   public function save(array $form, FormStateInterface $form_state) {
148     $this->entity->save();
149     drupal_set_message(t('The redirect has been saved.'));
150     $form_state->setRedirect('redirect.list');
151   }
152 }