Commit 6ecf51a8 authored by Juan Martinez's avatar Juan Martinez Committed by Jijo Joseph
Browse files

Issue #3089600 by stefan.korn, jcmartinez, jastraat, smustgrave,...

Issue #3089600 by stefan.korn, jcmartinez, jastraat, smustgrave, jijojoseph_zyxware, hswong3i, Akhildev.cs, jurgenhaas, trebormc: Improve Search with a custom path
parent 7fc25084
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ search404_jump: false
search404_skip_auto_search: false
search404_disable_error_message: false
search404_use_or: false
search404_use_customclue: false
search404_use_search_engine: false
search404_ignore_extensions: 'htm html php'
search404_ignore_query: 'gif jpg jpeg bmp png'
+2 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ search404.settings:
      type: boolean
    search404_use_or:
      type: boolean
    search404_use_customclue:
      type: string
    search404_use_search_engine:
      type: boolean
    search404_ignore_extensions:
+9 −76
Original line number Diff line number Diff line
@@ -251,34 +251,12 @@ class Search404Controller extends ControllerBase {
    !\Drupal::config('search404.settings')->get('search404_skip_auto_search')) {
      $custom_search_path = \Drupal::config('search404.settings')->get('search404_custom_search_path');

      // Remove query parameters before checking whether the search path
      // exists or the user has access rights.
      $custom_search_path_no_query = preg_replace('/\?.*/', '', $custom_search_path);
      $current_path = \Drupal::service('path.current')->getPath();
      $current_path = preg_replace('/[!@#$^&*();\'"+_,]/', '', $current_path);

      // All search keywords with space
      // and slash are replacing with hyphen in url redirect.
      $search_keys = '';
      // If search with OR condition enabled.
      if (\Drupal::config('search404.settings')->get('search404_use_or')) {
        $search_details = $this->search404CustomRedirection(' OR ', $current_path, $keys);
      }
      else {
        $search_details = $this->search404CustomRedirection(' ', $current_path, $keys);
      }
      $current_path = $search_details['path'];
      $search_keys = $search_details['keys'];

      // Redirect to the custom path.
      if ($current_path == "/" . $keys || $current_path == "/" . $search_keys) {
      $this->search404CustomErrorMessage($keys);
        if ($search_keys != '') {
          $custom_search_path = str_replace('@keys', $search_keys, $custom_search_path);
      if ($keys != '') {
        $custom_search_path = str_replace('@keys', $keys, $custom_search_path);
      }
      return $this->search404Goto("/" . $custom_search_path);
    }
    }

    if (empty($build)) {
      $build = ['#markup' => $this->t('The page you requested does not exist.')];
@@ -441,63 +419,18 @@ class Search404Controller extends ControllerBase {
    // When using keywords with OR operator.
    if (\Drupal::config('search404.settings')->get('search404_use_or')) {
      $keys = trim(implode(' OR ', $keys));

      // Removing the custom path string from the keywords.
      if (\Drupal::config('search404.settings')->get('search404_do_custom_search')) {
        $custom_search_path = \Drupal::config('search404.settings')->get('search404_custom_search_path');
        $custom_search = explode('/', $custom_search_path);
        $custom_path = array_diff($custom_search, ["@keys"]);
        $keys = str_replace($custom_path[0], '', $keys);
        $keys = trim(rtrim($keys, ' OR '));
    }
    // Using a custom string to concatenate keywords
    elseif (\Drupal::config('search404.settings')->get('search404_use_customclue')) {
      $keys = trim(implode(\Drupal::config('search404.settings')->get('search404_use_customclue'), $keys));
    }
    // By default using whitespace between keywords
    else {
      $keys = trim(implode(' ', $keys));
      // Removing the custom path string from the keywords.
      if (\Drupal::config('search404.settings')->get('search404_do_custom_search')) {
        $custom_search_path = \Drupal::config('search404.settings')->get('search404_custom_search_path');
        $custom_search = explode('/', $custom_search_path);
        $custom_path = array_diff($custom_search, ["@keys"]);
        $keys = trim(str_replace($custom_path[0], '', $keys));
      }
    }
    return $keys;
  }

  /**
   * Helper function to make a redirection path with custom path.
   *
   * @param string $search_type
   *   Which type of search.
   * @param string $path
   *   Searched url or keyword in the address bar.
   * @param string $keys
   *   Searching keywords.
   *
   * @return array
   *   Custom redirection path and key for comparison.
   */
  public function search404CustomRedirection($search_type, $path, $keys) {
    $search['keys'] = $keys;
    $search['path'] = $path;

    // If search keywords has space or hyphen or slash.
    if (preg_match('/-|%20/', $search['path']) || stripos($search['path'], '/') !== FALSE) {
      $search['keys'] = str_replace($search_type, '-', $search['keys']);
      if (preg_match('/%20/', $search['path'])) {
        $search['path'] = str_replace('%20', '-', $search['path']);
      }
      // If search keywords has slash.
      if (stripos($search['path'], '/') !== FALSE) {
        $search['keys'] = str_replace($search_type, '-', $search['keys']);
        $search['path'] = str_replace('/', '-', $search['path']);
        $search['path'] = substr_replace($search['path'], '/', 0, 1);
        $search['path'] = rtrim($search['path'], "-");
      }
    }
    return $search;
  }

  /**
   * Displays an error message of page not found.
   *
+16 −4
Original line number Diff line number Diff line
@@ -123,6 +123,17 @@ class Search404Settings extends ConfigFormBase {
      '#title' => $this->t('Use OR between keywords when searching'),
      '#default_value' => \Drupal::config('search404.settings')->get('search404_use_or'),
    ];
    $form['advanced']['search404_use_customclue'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Use a custom string between keywords when searching'),
      '#description' => $this->t('using a custom string (for example a hyphen) to concatenate the keywords, has no effect if OR keyword is chosen, leave this empty to concatenate by whitespace'),
      '#default_value' => \Drupal::config('search404.settings')->get('search404_use_customclue'),
      '#states' => [
        'invisible' => [
          ':input[name="search404_use_or"]' => ['checked' => TRUE]
        ]
      ]
    ];
    $form['advanced']['search404_use_search_engine'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Use auto-detection of keywords from search engine referer'),
@@ -229,12 +240,12 @@ class Search404Settings extends ConfigFormBase {
    if (!empty($form_state->getValue('search404_do_custom_search'))) {
      $custom_path = $form_state->getValue('search404_custom_search_path');

      if (empty(preg_match("/\@keys$/", $custom_path))) {
        $form_state->setErrorByName('search404_custom_search_path', $this->t('Custom search path should end with the following text: @keys'));
      if (empty(preg_match("/@keys$/", $custom_path))) {
        $form_state->setErrorByName('search404_custom_search_path', $this->t('Custom search path should end with search key pattern "@keys".'));
      }
      $url_path = explode("@keys", $custom_path);
      if (!empty(preg_match('/[\'^£!`$%*()\{}\:.;,\[\]"@#~><>,|+¬-]/', $url_path[0]))) {
        $form_state->setErrorByName('search404_custom_search_path', t('Custom search path should not contain special characters other than "/", "=", "?" and "&".'));
      if (!empty(preg_match('/[\'^£!`$%&*()\{}\:.;,\[\]"@#~><>,|+¬-]/', $url_path[0]))) {
        $form_state->setErrorByName('search404_custom_search_path', t('Custom search path should not contain special characters other than "/?=_".'));
      }
      if (strpos($custom_path, '/') === 0) {
        $form_state->setErrorByName('search404_custom_search_path', $this->t('Custom search path should not start with a slash.'));
@@ -254,6 +265,7 @@ class Search404Settings extends ConfigFormBase {
      ->set('search404_first_on_paths', $form_state->getValue('search404_first_on_paths'))
      ->set('search404_jump', $form_state->getValue('search404_jump'))
      ->set('search404_use_or', $form_state->getValue('search404_use_or'))
      ->set('search404_use_customclue', $form_state->getValue('search404_use_customclue'))
      ->set('search404_ignore', $form_state->getValue('search404_ignore'))
      ->set('search404_ignore_paths', $form_state->getValue('search404_ignore_paths'))
      ->set('search404_ignore_query', $form_state->getValue('search404_ignore_query'))