You are here

public function Search404Controller::search404Page in Search 404 8

Same name and namespace in other branches
  1. 2.x src/Controller/Search404Controller.php \Drupal\search404\Controller\Search404Controller::search404Page()
1 string reference to 'Search404Controller::search404Page'
search404.routing.yml in ./search404.routing.yml
search404.routing.yml

File

src/Controller/Search404Controller.php, line 69

Class

Search404Controller
Route controller for search.

Namespace

Drupal\search404\Controller

Code

public function search404Page(Request $request) {
  $keys = $this
    ->search404GetKeys();

  // If the current path is set as one of the ignore path,
  // then do not get into the complex search functions.
  $paths_to_ignore = \Drupal::config('search404.settings')
    ->get('search404_ignore_paths');
  if (!empty($paths_to_ignore)) {
    $path_array = preg_split('/\\R/', $paths_to_ignore);

    // If OR case enabled.
    if (\Drupal::config('search404.settings')
      ->get('search404_use_or')) {
      $keywords = str_replace(' OR ', '/', $keys);
    }
    else {
      $keywords = str_replace(' ', '/', $keys);
    }
    $keywords = strtolower($keywords);
    $ignore_paths = [];
    foreach ($path_array as $key => $path) {
      $path = preg_replace('[ |-|_]', '/', $path);
      $path = strtolower($path);
      $ignore_paths[$key] = trim($path, '/');
    }

    // If the page matches to any of the listed paths to ignore,
    // then return default drupal 404 page title and text.
    $requested_path = $request
      ->getPathInfo();
    $is_matched = $is_wildcard = FALSE;
    foreach ($path_array as $key => $ignored_path) {

      // Find the correct path ?
      $pattern = '/^\\/?([a-z0-9\\-\\/]*[a-z0-9\\-])+(\\/\\*)?/i';
      $find_ignored_path = preg_match($pattern, $ignored_path, $matches);
      if ($find_ignored_path === 1) {
        $cleaned_ignored_path = '/' . $matches[1];

        // Is it the same path.
        if ($cleaned_ignored_path === $requested_path) {
          $is_matched = TRUE;
        }

        // Is it a pattern whose match the requested path.
        if (array_key_exists(2, $matches) && substr($matches[2], -1) === '*' && strpos($requested_path, $cleaned_ignored_path) === 0) {
          $is_wildcard = TRUE;
        }
      }
    }

    // Ignore this requested page ?
    if ($is_matched || $is_wildcard) {
      $build['#title'] = 'Page not found';
      $build['#markup'] = 'The requested page could not be found.';
      return $build;
    }
  }
  if (\Drupal::moduleHandler()
    ->moduleExists('search') && (\Drupal::currentUser()
    ->hasPermission('search content') || \Drupal::currentUser()
    ->hasPermission('search by page'))) {

    // Get and use the default search engine for the site.
    $search_page_repository = \Drupal::service('search.search_page_repository');
    $default_search_page = $search_page_repository
      ->getDefaultSearchPage();
    $entity = SearchPage::load($default_search_page);
    $plugin = $entity
      ->getPlugin();
    $build = [];
    $results = [];

    // Build the form first, because it may redirect during the submit,
    // and we don't want to build the results based on last time's request.
    $plugin
      ->setSearch($keys, $request->query
      ->all(), $request->attributes
      ->all());
    if ($keys && !\Drupal::config('search404.settings')
      ->get('search404_skip_auto_search')) {

      // If custom search enabled.
      if (\Drupal::moduleHandler()
        ->moduleExists('search_by_page') && \Drupal::config('search404.settings')
        ->get('search404_do_search_by_page')) {
        $this
          ->search404CustomErrorMessage($keys);
        return $this
          ->search404Goto('search_pages/' . $keys);
      }
      else {

        // Build search results, if keywords or other search parameters
        // are in the GET parameters. Note that we need to try the
        // search if 'keys' is in there at all, vs. being empty,
        // due to advanced search.
        if ($plugin
          ->isSearchExecutable()) {

          // Log the search.
          if ($this
            ->config('search.settings')
            ->get('logging')) {
            $this->logger
              ->notice('Searched %type for %keys.', [
              '%keys' => $keys,
              '%type' => $entity
                ->label(),
            ]);
          }

          // Collect the search results.
          $results = $plugin
            ->buildResults();
        }
        if (isset($results)) {

          // Jump to first result if there are results and
          // if there is only one result and if jump to first is selected or
          // if there are more than one results and force jump
          // to first is selected.
          $patterns = \Drupal::config('search404.settings')
            ->get('search404_first_on_paths');
          $path_matches = TRUE;

          // Check if the current path exists in the set paths list.
          if (!empty($patterns)) {
            $path = str_replace(' ', '/', $keys);
            $path_matches = \Drupal::service('path.matcher')
              ->matchPath($path, $patterns);
          }
          if (is_array($results) && (count($results) == 1 && \Drupal::config('search404.settings')
            ->get('search404_jump') || count($results) >= 1 && \Drupal::config('search404.settings')
            ->get('search404_first') && $path_matches)) {
            $this
              ->search404CustomErrorMessage($keys);
            if (isset($results[0]['#result']['link'])) {
              $result_path = $results[0]['#result']['link'];
            }
            return $this
              ->search404Goto($result_path);
          }
          else {
            $this
              ->search404CustomErrorMessage($keys);

            // Redirecting the page for empty search404 result,
            // if redirect url is configured.
            if (!count($results) && \Drupal::config('search404.settings')
              ->get('search404_page_redirect')) {
              $redirect_path = \Drupal::config('search404.settings')
                ->get('search404_page_redirect');
              return $this
                ->search404Goto($redirect_path);
            }
          }
        }
      }
    }
    else {
      $this
        ->search404CustomErrorMessage($keys);
    }

    // Construct the search form.
    $build['search_form'] = $this
      ->formBuilder()
      ->getForm(SearchPageForm::class, $entity);

    // Set the custom page text on the top of the results.
    $search_404_page_text = \Drupal::config('search404.settings')
      ->get('search404_page_text');
    if (!empty($search_404_page_text)) {
      $build['content']['#markup'] = '<div id="search404-page-text">' . $search_404_page_text . '</div>';
      $build['content']['#weight'] = -100;
    }

    // Text for, if search results is empty.
    $no_results = '';
    if (!\Drupal::config('search404.settings')
      ->get('search404_skip_auto_search')) {
      $no_results = t('<ul>
        <li>Check if your spelling is correct.</li>
        <li>Remove quotes around phrases to search for each word individually. <em>bike shed</em> will often show more results than <em>&quot;bike shed&quot;</em>.</li>
        <li>Consider loosening your query with <em>OR</em>. <em>bike OR shed</em> will often show more results than <em>bike shed</em>.</li>
        </ul>');
    }
    $build['search_results'] = [
      '#theme' => [
        'item_list__search_results__' . $plugin
          ->getPluginId(),
        'item_list__search_results',
      ],
      '#items' => $results,
      '#empty' => [
        '#markup' => '<h3>' . $this
          ->t('Your search yielded no results.') . '</h3>' . $no_results,
      ],
      '#list_type' => 'ol',
      '#attributes' => [
        'class' => [
          'search-results',
          $plugin
            ->getPluginId() . '-results',
        ],
      ],
      '#cache' => [
        'tags' => $entity
          ->getCacheTags(),
      ],
    ];
    $build['pager_pager'] = [
      '#type' => 'pager',
    ];
    $build['#attached']['library'][] = 'search/drupal.search.results';
  }
  if (\Drupal::config('search404.settings')
    ->get('search404_do_custom_search') && !\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);
      }
      return $this
        ->search404Goto("/" . $custom_search_path);
    }
  }
  if (empty($build)) {
    $build = [
      '#markup' => 'The page you requested does not exist.',
    ];
  }
  return $build;
}