3 namespace Drupal\redirect\Form;
5 use Drupal\Component\Utility\UrlHelper;
6 use Drupal\Core\Entity\ContentEntityForm;
7 use Drupal\Core\Language\Language;
8 use Drupal\Core\Routing\MatchingRouteNotFoundException;
10 use Drupal\redirect\Entity\Redirect;
11 use Drupal\Core\Form\FormStateInterface;
13 class RedirectForm extends ContentEntityForm {
18 protected function prepareEntity() {
19 /** @var \Drupal\redirect\Entity\Redirect $redirect */
20 $redirect = $this->entity;
22 if ($redirect->isNew()) {
24 // To pass in the query set parameters into GET as follows:
25 // source_query[key1]=value1&source_query[key2]=value2
26 $source_query = array();
27 if ($this->getRequest()->get('source_query')) {
28 $source_query = $this->getRequest()->get('source_query');
31 $redirect_options = array();
32 $redirect_query = array();
33 if ($this->getRequest()->get('redirect_options')) {
34 $redirect_options = $this->getRequest()->get('redirect_options');
35 if (isset($redirect_options['query'])) {
36 $redirect_query = $redirect_options['query'];
37 unset($redirect_options['query']);
41 $source_url = urldecode($this->getRequest()->get('source'));
42 if (!empty($source_url)) {
43 $redirect->setSource($source_url, $source_query);
46 $redirect_url = urldecode($this->getRequest()->get('redirect'));
47 if (!empty($redirect_url)) {
49 $redirect->setRedirect($redirect_url, $redirect_query, $redirect_options);
51 catch (MatchingRouteNotFoundException $e) {
52 drupal_set_message(t('Invalid redirect URL %url provided.', array('%url' => $redirect_url)), 'warning');
56 $redirect->setLanguage($this->getRequest()->get('language') ? $this->getRequest()->get('language') : Language::LANGCODE_NOT_SPECIFIED);
63 public function form(array $form, FormStateInterface $form_state) {
64 $form = parent::form($form, $form_state);
65 /** @var \Drupal\redirect\Entity\Redirect $redirect */
66 $redirect = $this->entity;
68 $default_code = $redirect->getStatusCode() ? $redirect->getStatusCode() : \Drupal::config('redirect.settings')->get('default_status_code');
70 $form['status_code'] = array(
72 '#title' => t('Redirect status'),
73 '#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')),
74 '#default_value' => $default_code,
75 '#options' => redirect_status_code_options(),
84 public function validateForm(array &$form, FormStateInterface $form_state) {
85 parent::validateForm($form, $form_state);
86 $source = $form_state->getValue(array('redirect_source', 0));
87 $redirect = $form_state->getValue(array('redirect_redirect', 0));
89 if ($source['path'] == '<front>') {
90 $form_state->setErrorByName('redirect_source', t('It is not allowed to create a redirect from the front page.'));
92 if (strpos($source['path'], '#') !== FALSE) {
93 $form_state->setErrorByName('redirect_source', t('The anchor fragments are not allowed.'));
95 if (strpos($source['path'], '/') === 0) {
96 $form_state->setErrorByName('redirect_source', t('The url to redirect from should not start with a forward slash (/).'));
100 $source_url = Url::fromUri('internal:/' . $source['path']);
101 $redirect_url = Url::fromUri($redirect['uri']);
103 // It is relevant to do this comparison only in case the source path has
104 // a valid route. Otherwise the validation will fail on the redirect path
105 // being an invalid route.
106 if ($source_url->toString() == $redirect_url->toString()) {
107 $form_state->setErrorByName('redirect_redirect', t('You are attempting to redirect the page to itself. This will result in an infinite loop.'));
110 catch (\InvalidArgumentException $e) {
111 // Do nothing, we want to only compare the resulting URLs.
114 $parsed_url = UrlHelper::parse(trim($source['path']));
115 $path = isset($parsed_url['path']) ? $parsed_url['path'] : NULL;
116 $query = isset($parsed_url['query']) ? $parsed_url['query'] : NULL;
117 $hash = Redirect::generateHash($path, $query, $form_state->getValue('language')[0]['value']);
119 // Search for duplicate.
120 $redirects = \Drupal::entityManager()
121 ->getStorage('redirect')
122 ->loadByProperties(array('hash' => $hash));
124 if (!empty($redirects)) {
125 $redirect = array_shift($redirects);
126 if ($this->entity->isNew() || $redirect->id() != $this->entity->id()) {
127 $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>?',
129 '%source' => $source['path'],
130 '@edit-page' => $redirect->url('edit-form'))));
138 public function save(array $form, FormStateInterface $form_state) {
139 $this->entity->save();
140 drupal_set_message(t('The redirect has been saved.'));
141 $form_state->setRedirect('redirect.list');