You are here

public function CustomSearchBlockForm::buildForm in Custom Search 8

Form constructor.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Return value

array The form structure.

Overrides FormInterface::buildForm

File

src/Form/CustomSearchBlockForm.php, line 97

Class

CustomSearchBlockForm
Builds the search form for the search block.

Namespace

Drupal\custom_search\Form

Code

public function buildForm(array $form, FormStateInterface $form_state) {
  $config = func_get_arg(2);
  $form['#method'] = 'post';

  // Popup.
  $form['popup'] = [
    '#type' => 'fieldset',
    '#weight' => 1 + $config['search_box']['weight'],
    '#attributes' => [
      'class' => [
        'custom_search-popup',
      ],
    ],
  ];

  // Search box.
  $form['keys'] = [
    '#type' => 'search',
    '#title' => Html::escape($config['search_box']['label']),
    '#title_display' => $config['search_box']['label_visibility'] ? 'before' : 'invisible',
    '#size' => $config['search_box']['size'],
    '#maxlength' => $config['search_box']['max_length'],
    '#default_value' => '',
    '#placeholder' => [
      'title' => Html::escape($config['search_box']['placeholder']),
    ],
    '#attributes' => [
      'title' => Html::escape($config['search_box']['title']),
      'class' => [
        'custom_search-keys',
      ],
    ],
    '#weight' => $config['search_box']['weight'],
  ];

  // Content.
  $toptions = [];
  $types = array_keys(array_filter($config['content']['types']));
  if (count($types)) {
    $names = node_type_get_names();
    if (count($types) > 1 || $config['content']['any']['force']) {
      $toptions['c-all'] = $config['content']['any']['text'];
    }
    foreach ($types as $type) {
      $toptions['c-' . $type] = $names[$type];
    }
  }
  $options = [];

  // Other searches.
  $others = !empty($config['content']['other']) ? array_keys(array_filter($config['content']['other'])) : [];

  // If content types and other searches are combined, make an optgroup.
  if (count($others) && count($toptions) && $config['content']['selector']['type'] == 'select') {
    $search_page = $this->entityTypeManager
      ->getStorage('search_page')
      ->load($config['content']['page']);
    $options[Html::escape($search_page
      ->label())] = $toptions;
  }
  else {
    $options = $toptions;
  }
  if (count($others)) {
    $other_pages = $this->entityTypeManager
      ->getStorage('search_page')
      ->loadMultiple($others);
    foreach ($others as $other) {
      $options['o-' . Html::escape($other_pages[$other]
        ->id())] = Html::escape($other_pages[$other]
        ->label());
    }
  }
  if (count($options)) {
    $selector_type = $config['content']['selector']['type'];
    if ($selector_type == 'selectmultiple') {
      $selector_type = 'select';
      $multiple = TRUE;
    }
    else {
      $multiple = FALSE;
    }
    $form['types'] = [
      '#type' => $selector_type,
      '#multiple' => $multiple,
      '#title' => Html::escape($config['content']['selector']['label']),
      '#title_display' => $config['content']['selector']['label_visibility'] ? 'before' : 'invisible',
      '#options' => $options,
      '#default_value' => $selector_type == 'checkboxes' ? [
        'c-all',
      ] : 'c-all',
      '#attributes' => [
        'class' => [
          'custom-search-selector',
          'custom-search-types',
        ],
      ],
      '#weight' => $config['content']['weight'],
      '#validated' => TRUE,
    ];

    // If there's only one type, hide the selector.
    if (count($others) + count($types) == 1 && !$config['content']['any']['force']) {
      $form['custom_search_types']['#type'] = 'hidden';
      $form['custom_search_types']['#default_value'] = key(array_slice($options, count($options) - 1));
    }
    elseif ($config['content']['region'] == 'popup') {
      $form['popup']['types'] = $form['types'];
      unset($form['types']);
    }
  }

  // Taxonomy.
  $vocabularies = $this->entityTypeManager
    ->getStorage('taxonomy_vocabulary')
    ->loadMultiple();
  if (count($config['taxonomy']) > 0) {
    $taxonomy_term_storage = \Drupal::entityTypeManager()
      ->getStorage('taxonomy_term');
    foreach ($vocabularies as $voc) {
      $vid = $voc
        ->id();
      if (empty($config['taxonomy'][$vid]['type']) || $config['taxonomy'][$vid]['type'] == 'disabled') {
        continue;
      }
      $options = [];
      $options['c-all'] = $config['taxonomy'][$vid]['all_text'];
      $vocabulary_depth = !$config['taxonomy'][$vid]['depth'] ? NULL : $config['taxonomy'][$vid]['depth'];
      $terms = $taxonomy_term_storage
        ->loadTree($vid, 0, $vocabulary_depth, TRUE);
      foreach ($terms as $term) {
        $termName = Html::escape($this->entityRepository
          ->getTranslationFromContext($term)
          ->label());
        $options['c-' . $term
          ->id()] = mb_substr($config['taxonomy'][$vid]['type'], 0, 6) == 'select' ? str_repeat('-', $term->depth) . ' ' . $termName : $termName;
      }
      $selector_type = $config['taxonomy'][$vid]['type'];
      if ($selector_type == 'selectmultiple') {
        $selector_type = 'select';
        $multiple = TRUE;
      }
      else {
        $multiple = FALSE;
      }
      $form['vocabulary_' . $vid] = [
        '#type' => $selector_type,
        '#multiple' => $multiple,
        '#title' => Html::escape($config['taxonomy'][$vid]['label']),
        '#title_display' => $config['taxonomy'][$vid]['label_visibility'] ? 'before' : 'invisible',
        '#options' => $options,
        '#default_value' => $selector_type == 'checkboxes' ? [
          'c-all',
        ] : 'c-all',
        '#attributes' => [
          'class' => [
            'custom-search-selector',
            'custom-search-vocabulary',
          ],
        ],
        '#weight' => $config['taxonomy'][$vid]['weight'],
      ];
      if ($config['taxonomy'][$vid]['region'] == 'popup') {
        $form['popup']['vocabulary_' . $vid] = $form['vocabulary_' . $vid];
        unset($form['vocabulary_' . $vid]);
      }
    }
  }

  // Languages.
  $options = [];
  $languages = array_keys(array_filter($config['languages']['languages']));
  if (count($languages)) {
    if (count($languages) > 1 || $config['languages']['any']['force']) {
      $options['c-all'] = $config['languages']['any']['text'];
    }
    $current_language = \Drupal::languageManager()
      ->getCurrentLanguage();
    $current_language_id = $current_language
      ->getId();
    foreach ($languages as $language) {
      switch ($language) {
        case 'current':
          $options['c-' . $language] = t('- Current language (@current) -', [
            '@current' => $current_language
              ->getName(),
          ]);
          break;
        case Language::LANGCODE_NOT_SPECIFIED:
          $options['c-' . $language] = t('- Not specified -');
          break;
        case Language::LANGCODE_NOT_APPLICABLE:
          $options['c-' . $language] = t('- Not applicable -');
          break;
        default:
          if ($language != $current_language_id || $language != $current_language_id && !array_key_exists('c-' . $language, $options)) {
            $options['c-' . $language] = \Drupal::languageManager()
              ->getLanguageName($language);
          }
      }
    }
  }
  if (count($options)) {
    $selector_type = $config['languages']['selector']['type'];
    if ($selector_type == 'selectmultiple') {
      $selector_type = 'select';
      $multiple = TRUE;
    }
    else {
      $multiple = FALSE;
    }
    $form['languages'] = [
      '#type' => $selector_type,
      '#multiple' => $multiple,
      '#title' => Html::escape($config['languages']['selector']['label']),
      '#title_display' => $config['languages']['selector']['label_visibility'] ? 'before' : 'invisible',
      '#options' => $options,
      '#default_value' => $selector_type == 'checkboxes' ? [
        'c-all',
      ] : 'c-all',
      '#attributes' => [
        'class' => [
          'custom-search-selector',
          'custom-search-language',
        ],
      ],
      '#weight' => $config['languages']['weight'],
      '#validated' => TRUE,
    ];

    // If there's only one type, hide the selector.
    if (count($languages) == 1 && !$config['languages']['any']['force']) {
      $form['languages']['#type'] = 'hidden';
      $form['languages']['#default_value'] = key(array_slice($options, count($options) - 1));
    }
    elseif ($config['languages']['region'] == 'popup') {
      $form['popup']['languages'] = $form['languages'];
      unset($form['languages']);
    }
  }

  // Custom Paths.
  $paths = $config['paths']['list'];
  if ($paths != '') {
    $options = [];
    $lines = explode("\n", $paths);
    foreach ($lines as $line) {
      $temp = explode('|', $line);
      $options[$temp[0]] = count($temp) >= 2 ? t($temp[1]) : '';
    }
    if (count($options) == 1) {
      $form['paths'] = [
        '#type' => 'hidden',
        '#default_value' => key($options),
      ];
    }
    else {
      $form['paths'] = [
        '#type' => $config['paths']['selector']['type'],
        '#title' => Html::escape($config['paths']['selector']['label']),
        '#title_display' => $config['paths']['selector']['label_visibility'] ? 'before' : 'invisible',
        '#options' => $options,
        '#default_value' => key($options),
        '#weight' => $config['paths']['weight'],
      ];
      if ($config['paths']['region'] == 'popup') {
        $form['popup']['paths'] = $form['paths'];
        unset($form['paths']);
      }
    }
  }

  // Criteria.
  $criteria = [
    'or',
    'phrase',
    'negative',
  ];
  foreach ($criteria as $c) {
    if ($config['criteria'][$c]['display']) {
      $form['criteria_' . $c] = [
        '#type' => 'textfield',
        '#title' => Html::escape($config['criteria'][$c]['label']),
        '#size' => 15,
        '#maxlength' => 255,
        '#weight' => $config['criteria'][$c]['weight'],
      ];
      if ($config['criteria'][$c]['region'] == 'popup') {
        $form['popup']['criteria_' . $c] = $form['criteria_' . $c];
        unset($form['criteria_' . $c]);
      }
    }
  }

  // Actions.
  $form['actions'] = [
    '#type' => 'actions',
  ];
  $form['actions']['submit'] = [
    '#type' => 'submit',
    '#value' => Html::escape($config['submit']['text']),
    // Prevent op from showing up in the query string.
    '#name' => '',
    '#weight' => $config['submit']['weight'],
  ];
  if ($config['submit']['image_path'] != '') {
    $form['actions']['submit']['#type'] = 'image_button';
    $form['actions']['submit']['#src'] = $config['submit']['image_path'];
    $form['actions']['submit']['#attributes'] = [
      'alt' => Html::escape($config['submit']['text']),
      'class' => [
        'custom-search-button',
      ],
    ];
    unset($form['actions']['submit']['#value']);
  }
  elseif ($form['actions']['submit']['#value'] == '') {
    $form['actions']['submit']['#attributes'] = [
      'style' => 'display:none;',
    ];
  }

  // If nothing has been added to the popup, don't output any markup.
  if (!count(Element::children($form['popup']))) {
    unset($form['popup']);
  }

  // Add attributes.
  $form['#attributes']['role'] = 'search';

  // Passes the config for later use.
  $form_state
    ->set('config', $config);
  return $form;
}