View source
<?php
namespace Drupal\custom_search\Plugin\Block;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\StreamWrapper\StreamWrapperManager;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
class CustomSearchBlock extends BlockBase implements ContainerFactoryPluginInterface {
protected $moduleHandler;
protected $errorHandler;
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('module_handler'));
}
protected function blockAccess(AccountInterface $account) {
if ($account
->hasPermission('search content')) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
public function defaultConfiguration() {
$defaults = [
'search_box' => [
'label_visibility' => FALSE,
'label' => $this
->t('Search this site'),
'placeholder' => '',
'title' => $this
->t('Enter the terms you wish to search for.'),
'size' => 15,
'max_length' => 128,
'weight' => -9,
'region' => 'block',
],
'submit' => [
'text' => $this
->t('Search'),
'image_path' => '',
'weight' => 9,
'region' => 'block',
],
'content' => [
'types' => [],
'other' => [],
'selector' => [
'type' => 'select',
'label_visibility' => TRUE,
'label' => $this
->t('Search for'),
],
'any' => [
'text' => $this
->t('- Any -'),
'restricts' => FALSE,
'force' => FALSE,
],
'excluded' => [],
'weight' => -8,
'region' => 'block',
],
'criteria' => [
'or' => [
'display' => FALSE,
'label' => $this
->t('Containing any of the words'),
'weight' => 4,
'region' => 'block',
],
'phrase' => [
'display' => FALSE,
'label' => $this
->t('Containing the phrase'),
'weight' => 5,
'region' => 'block',
],
'negative' => [
'display' => FALSE,
'label' => $this
->t('Containing none of the words'),
'weight' => 6,
'region' => 'block',
],
],
'languages' => [
'languages' => [],
'selector' => [
'type' => 'select',
'label_visibility' => TRUE,
'label' => $this
->t('Languages'),
],
'any' => [
'text' => $this
->t('- Any -'),
'restricts' => FALSE,
'force' => FALSE,
],
'weight' => 7,
'region' => 'block',
],
'paths' => [
'list' => '',
'selector' => [
'type' => 'select',
'label_visibility' => TRUE,
'label' => $this
->t('Customize your search'),
],
'separator' => '+',
'weight' => 8,
'region' => 'block',
],
];
$search_pages = \Drupal::entityTypeManager()
->getStorage('search_page')
->loadMultiple();
foreach ($search_pages as $page) {
if ($page
->getPlugin()
->getPluginId() == 'node_search' && $page
->isDefaultSearch()) {
$defaults['content']['page'] = $page
->id();
break;
}
}
$vocabularies = \Drupal::entityTypeManager()
->getStorage('search_page')
->loadMultiple();
$vocWeight = -7;
foreach ($vocabularies as $voc) {
$vocId = $voc
->id();
$defaults['taxonomy'][$vocId]['type'] = 'disabled';
$defaults['taxonomy'][$vocId]['depth'] = 0;
$defaults['taxonomy'][$vocId]['label_visibility'] = TRUE;
$defaults['taxonomy'][$vocId]['label'] = $voc
->label();
$defaults['taxonomy'][$vocId]['all_text'] = t('- Any -');
$defaults['taxonomy'][$vocId]['region'] = 'block';
$defaults['taxonomy'][$vocId]['weight'] = $vocWeight;
$vocWeight++;
}
return $defaults;
}
public function blockForm($form, FormStateInterface $form_state) {
$form['search_box'] = [
'#type' => 'details',
'#title' => $this
->t('Search box'),
'#open' => TRUE,
];
$form['search_box']['label_visibility'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display label'),
'#default_value' => $this->configuration['search_box']['label_visibility'],
];
$form['search_box']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label'),
'#default_value' => $this->configuration['search_box']['label'],
'#description' => $this
->t('Enter the label text for the search box. The default value is "Search this site".'),
'#states' => [
'visible' => [
':input[name="settings[search_box][label_visibility]"]' => [
'checked' => TRUE,
],
],
],
];
$form['search_box']['placeholder'] = [
'#type' => 'textfield',
'#title' => $this
->t('Placeholder text'),
'#default_value' => $this->configuration['search_box']['placeholder'],
'#description' => $this
->t('This will change the default text inside the search form. This is the <a href="http://www.w3schools.com/tags/att_input_placeholder.asp" target="_blank">placeholder</a> attribute for the TextField. Leave blank for no text. This field is blank by default.'),
];
$form['search_box']['title'] = [
'#type' => 'textfield',
'#title' => $this
->t('Hint text'),
'#default_value' => $this->configuration['search_box']['title'],
'#description' => $this
->t('Enter the text that will be displayed when hovering the input field (HTML <em>title</em> attritube).'),
];
$form['search_box']['size'] = [
'#type' => 'textfield',
'#title' => $this
->t('Size'),
'#size' => 3,
'#default_value' => $this->configuration['search_box']['size'],
'#description' => $this
->t('The default value is "@default".', [
'@default' => 15,
]),
];
$form['search_box']['max_length'] = [
'#type' => 'textfield',
'#title' => $this
->t('Maximum length'),
'#size' => 3,
'#default_value' => $this->configuration['search_box']['max_length'],
'#description' => $this
->t('The default value is "@default".', [
'@default' => 128,
]),
'#required' => TRUE,
];
$form['submit'] = [
'#type' => 'details',
'#title' => $this
->t('Submit button'),
'#open' => TRUE,
];
$form['submit']['text'] = [
'#type' => 'textfield',
'#title' => $this
->t('Text'),
'#default_value' => $this->configuration['submit']['text'],
'#description' => $this
->t('Enter the text for the submit button. Leave blank to hide it. The default value is "Search".'),
];
if ($this->moduleHandler
->moduleExists('file')) {
$form['submit']['image_path'] = [
'#type' => 'textfield',
'#title' => $this
->t('Image path'),
'#description' => $this
->t('The path to the file you would like to use as submit button instead of the default text button.'),
'#default_value' => $this->configuration['submit']['image_path'],
];
$friendly_path = NULL;
$default_image = 'search.png';
if (StreamWrapperManager::getScheme($this->configuration['submit']['image_path']) == 'public') {
$friendly_path = StreamWrapperManager::getTarget($this->configuration['submit']['image_path']);
}
if ($this->configuration['submit']['image_path'] && isset($friendly_path)) {
$local_file = strtr($this->configuration['submit']['image_path'], [
'public:/' => PublicStream::basePath(),
]);
}
else {
$local_file = \Drupal::theme()
->getActiveTheme()
->getPath() . '/' . $default_image;
}
$form['submit']['image_path']['#description'] = t('Examples: <code>@implicit-public-file</code> (for a file in the public filesystem), <code>@explicit-file</code>, or <code>@local-file</code>.', [
'@implicit-public-file' => isset($friendly_path) ? $friendly_path : $default_image,
'@explicit-file' => StreamWrapperManager::getScheme($this->configuration['submit']['image_path']) !== FALSE ? $this->configuration['submit']['image_path'] : 'public://' . $default_image,
'@local-file' => $local_file,
]);
$form['submit']['image'] = [
'#type' => 'file',
'#title' => $this
->t('Image'),
'#description' => $this
->t("If you don't have direct file access to the server, use this field to upload your image."),
];
}
$form['content'] = [
'#type' => 'details',
'#title' => $this
->t('Content'),
'#description' => $this
->t("Select the search types to present as search options in the search block. If none is selected, no selector will be displayed. <strong>Note</strong>: if there's only one type checked, the selector won't be displayed BUT only this type will be searched."),
'#open' => count(array_filter($this->configuration['content']['types'])) + count(array_filter($this->configuration['content']['excluded'])),
];
$search_pages = \Drupal::entityTypeManager()
->getStorage('search_page')
->loadMultiple();
$pages_options = [];
foreach ($search_pages as $page) {
if ($page
->getPlugin()
->getPluginId() == 'node_search') {
$pages_options[$page
->id()] = $page
->label();
}
}
if (count($pages_options)) {
$form['content']['page'] = [
'#type' => 'select',
'#title' => $this
->t('Search page'),
'#description' => $this
->t('Select which page to use when searching content with this block. Pages are defined <a href=":link">here</a>.', [
':link' => Url::fromRoute('entity.search_page.collection', [], [
'fragment' => 'edit-search-pages',
])
->toString(),
]),
'#default_value' => $this->configuration['content']['page'],
'#options' => $pages_options,
];
}
$form['content']['types'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Content types'),
'#default_value' => $this->configuration['content']['types'],
'#options' => node_type_get_names(),
];
$other_pages_options = [];
foreach ($search_pages as $page) {
if ($page
->getPlugin()
->getPluginId() != 'node_search') {
$other_pages_options[$page
->id()] = $page
->label();
}
}
if (count($other_pages_options)) {
$form['content']['other'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Other search pages'),
'#default_value' => $this->configuration['content']['other'],
'#options' => $other_pages_options,
];
}
$form['content']['selector']['type'] = [
'#type' => 'select',
'#title' => $this
->t('Selector type'),
'#options' => [
'select' => $this
->t('Drop-down list'),
'selectmultiple' => $this
->t('Drop-down list with multiple choices'),
'radios' => $this
->t('Radio buttons'),
'checkboxes' => $this
->t('Checkboxes'),
],
'#description' => $this
->t('Choose which selector type to use. Note: content types and other searches cannot be combined in a single search.'),
'#default_value' => $this->configuration['content']['selector']['type'],
];
$form['content']['selector']['label_visibility'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display label'),
'#default_value' => $this->configuration['content']['selector']['label_visibility'],
];
$form['content']['selector']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label text'),
'#default_value' => $this->configuration['content']['selector']['label'],
'#description' => $this
->t('Enter the label text for the selector. The default value is "Search for".'),
'#states' => [
'visible' => [
':input[name="settings[content][selector][label_visibility]"]' => [
'checked' => TRUE,
],
],
],
];
$form['content']['any'] = [
'#type' => 'details',
'#title' => $this
->t('- Any -'),
];
$form['content']['any']['text'] = [
'#type' => 'textfield',
'#title' => $this
->t('- Any content type - text'),
'#default_value' => $this->configuration['content']['any']['text'],
'#required' => TRUE,
'#description' => $this
->t('Enter the text for "any content type" choice. The default value is "- Any -".'),
];
$form['content']['any']['restricts'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Choosing - Any - restricts the search to the selected content types.'),
'#default_value' => $this->configuration['content']['any']['restricts'],
'#description' => $this
->t('If not checked, choosing - Any - will search in all content types.'),
];
$form['content']['any']['force'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Force - Any - to be displayed.'),
'#default_value' => $this->configuration['content']['any']['force'],
'#description' => $this
->t('When only one content type is selected, the default behaviour is to hide the selector. If you need the - Any - option to be displayed, check this.'),
];
$form['content']['excluded'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Content exclusion'),
'#description' => $this
->t("Select the content types you don't want to be displayed as results."),
'#default_value' => $this->configuration['content']['excluded'],
'#options' => node_type_get_names(),
];
$vocabularies = \Drupal::entityTypeManager()
->getStorage('taxonomy_vocabulary')
->loadMultiple();
if (count($vocabularies)) {
$open = FALSE;
foreach ($vocabularies as $voc) {
$vocId = $voc
->id();
if ($this->configuration['taxonomy'][$vocId]['type'] != 'disabled') {
$open = TRUE;
break;
}
}
$form['taxonomy'] = [
'#type' => 'details',
'#title' => $this
->t('Taxonomy'),
'#description' => $this
->t('Select the vocabularies to present as search options in the search block. If none is selected, no selector will be displayed.'),
'#open' => $open,
];
foreach ($vocabularies as $voc) {
$vocId = $voc
->id();
$form['taxonomy'][$vocId] = [
'#type' => 'details',
'#title' => $voc
->label(),
'#open' => $this->configuration['taxonomy'][$vocId]['type'] != 'disabled',
];
$form['taxonomy'][$vocId]['type'] = [
'#type' => 'select',
'#title' => $this
->t('Selector type'),
'#options' => [
'disabled' => $this
->t('Disabled'),
'select' => $this
->t('Drop-down list'),
'selectmultiple' => $this
->t('Drop-down list with multiple choices'),
'radios' => $this
->t('Radio buttons'),
'checkboxes' => $this
->t('Checkboxes'),
],
'#description' => $this
->t('Choose which selector type to use.'),
'#default_value' => $this->configuration['taxonomy'][$vocId]['type'],
];
$form['taxonomy'][$vocId]['depth'] = [
'#type' => 'textfield',
'#title' => $this
->t('Depth'),
'#size' => 2,
'#default_value' => $this->configuration['taxonomy'][$vocId]['depth'],
'#description' => $this
->t('Define the maximum depth of terms being displayed. The default value is "0" which disables the limit.'),
];
$form['taxonomy'][$vocId]['label_visibility'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display label'),
'#default_value' => $this->configuration['taxonomy'][$vocId]['label_visibility'],
];
$form['taxonomy'][$vocId]['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label text'),
'#default_value' => $this->configuration['taxonomy'][$vocId]['label'],
'#description' => $this
->t('Enter the label text for the selector. The default value is "@default".', [
'@default' => $voc
->label(),
]),
'#states' => [
'visible' => [
':input[name="settings[taxonomy][' . $vocId . '][label_visibility]"]' => [
'checked' => TRUE,
],
],
],
];
$form['taxonomy'][$vocId]['all_text'] = [
'#type' => 'textfield',
'#title' => $this
->t('-Any- text'),
'#default_value' => $this->configuration['taxonomy'][$vocId]['all_text'],
'#required' => TRUE,
'#description' => $this
->t('Enter the text for "any term" choice. The default value is "- Any -".'),
];
}
}
$form['criteria'] = [
'#type' => 'details',
'#title' => $this
->t('Advanced search criteria'),
'#open' => $this->configuration['criteria']['or']['display'] || $this->configuration['criteria']['phrase']['display'] || $this->configuration['criteria']['negative']['display'],
];
$form['criteria']['or'] = [
'#type' => 'details',
'#title' => $this
->t('Or'),
'#open' => $this->configuration['criteria']['or']['display'],
];
$form['criteria']['or']['display'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display'),
'#default_value' => $this->configuration['criteria']['or']['display'],
];
$form['criteria']['or']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label'),
'#default_value' => $this->configuration['criteria']['or']['label'],
'#description' => $this
->t('Enter the label text for this field. The default value is "Containing any of the words".'),
'#states' => [
'visible' => [
':input[name="settings[criteria][or][display]"]' => [
'checked' => TRUE,
],
],
],
];
$form['criteria']['phrase'] = [
'#type' => 'details',
'#title' => $this
->t('Phrase'),
'#open' => $this->configuration['criteria']['phrase']['display'],
];
$form['criteria']['phrase']['display'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display'),
'#default_value' => $this->configuration['criteria']['phrase']['display'],
];
$form['criteria']['phrase']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label'),
'#default_value' => $this->configuration['criteria']['phrase']['label'],
'#description' => $this
->t('Enter the label text for this field. The default value is "Containing the phrase".'),
'#states' => [
'visible' => [
':input[name="settings[criteria][phrase][display]"]' => [
'checked' => TRUE,
],
],
],
];
$form['criteria']['negative'] = [
'#type' => 'details',
'#title' => $this
->t('Negative'),
'#open' => $this->configuration['criteria']['negative']['display'],
];
$form['criteria']['negative']['display'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display'),
'#default_value' => $this->configuration['criteria']['negative']['display'],
];
$form['criteria']['negative']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label'),
'#default_value' => $this->configuration['criteria']['negative']['label'],
'#description' => $this
->t('Enter the label text for this field. The default value is "Containing none of the words".'),
'#states' => [
'visible' => [
':input[name="settings[criteria][negative][display]"]' => [
'checked' => TRUE,
],
],
],
];
if ($this->moduleHandler
->moduleExists('search_api_page')) {
$search_api_pages = search_api_page_load_multiple();
$options[0] = t('None');
foreach ($search_api_pages as $page) {
$options[$page
->id()] = $page
->label();
}
$form['searchapi'] = [
'#type' => 'details',
'#title' => $this
->t('Search API'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
];
$form['searchapi']['page'] = [
'#type' => 'select',
'#title' => $this
->t('Search API Page to use'),
'#options' => $options,
'#default_value' => $this->configuration['searchapi']['page'],
];
}
$form['languages'] = [
'#type' => 'details',
'#title' => $this
->t('Languages'),
'#description' => $this
->t("Select the languages to present as search options in the search block. If none is selected, no selector will be displayed. <strong>Note</strong>: if there's only one language checked, the selector won't be displayed BUT only this language will be searched."),
'#open' => count(array_filter($this->configuration['languages']['languages'])),
];
$languages = \Drupal::languageManager()
->getLanguages();
$languages_options = [
'current' => $this
->t('- Current language -'),
];
foreach ($languages as $id => $language) {
$languages_options[$id] = $language
->getName();
}
$languages_options[Language::LANGCODE_NOT_SPECIFIED] = $this
->t('- Not specified -');
$languages_options[Language::LANGCODE_NOT_APPLICABLE] = $this
->t('- Not applicable -');
$form['languages']['languages'] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Languages'),
'#description' => $this
->t("Note: if <em>- Current language -</em> is selected, this current language won't be displayed twice."),
'#default_value' => $this->configuration['languages']['languages'],
'#options' => $languages_options,
];
$form['languages']['selector']['type'] = [
'#type' => 'select',
'#title' => $this
->t('Selector type'),
'#options' => [
'select' => $this
->t('Drop-down list'),
'selectmultiple' => $this
->t('Drop-down list with multiple choices'),
'radios' => $this
->t('Radio buttons'),
'checkboxes' => $this
->t('Checkboxes'),
],
'#description' => $this
->t('Choose which selector type to use.'),
'#default_value' => $this->configuration['languages']['selector']['type'],
];
$form['languages']['selector']['label_visibility'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display label'),
'#default_value' => $this->configuration['languages']['selector']['label_visibility'],
];
$form['languages']['selector']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label text'),
'#default_value' => $this->configuration['languages']['selector']['label'],
'#description' => $this
->t('Enter the label text for the selector. The default value is "Languages".'),
'#states' => [
'visible' => [
':input[name="settings[languages][selector][label_visibility]"]' => [
'checked' => TRUE,
],
],
],
];
$form['languages']['any'] = [
'#type' => 'details',
'#title' => $this
->t('- Any -'),
];
$form['languages']['any']['text'] = [
'#type' => 'textfield',
'#title' => $this
->t('- Any language - text'),
'#default_value' => $this->configuration['languages']['any']['text'],
'#required' => TRUE,
'#description' => $this
->t('Enter the text for "any language" choice. The default value is "- Any -".'),
];
$form['languages']['any']['restricts'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Choosing - Any - restricts the search to the selected languages.'),
'#default_value' => $this->configuration['languages']['any']['restricts'],
'#description' => $this
->t('If not checked, choosing - Any - will search in all languages.'),
];
$form['languages']['any']['force'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Force - Any - to be displayed.'),
'#default_value' => $this->configuration['languages']['any']['force'],
'#description' => $this
->t('When only one language is selected, the default behaviour is to hide the selector. If you need the - Any - option to be displayed, check this.'),
];
$form['paths'] = [
'#type' => 'details',
'#title' => $this
->t('Custom search paths'),
'#open' => $this->configuration['paths']['list'] != '',
];
$form['paths']['selector']['type'] = [
'#type' => 'select',
'#title' => $this
->t('Selector type'),
'#options' => [
'select' => $this
->t('Drop-down list'),
'radios' => $this
->t('Radio buttons'),
],
'#description' => $this
->t('Choose which selector type to use.'),
'#default_value' => $this->configuration['paths']['selector']['type'],
];
$form['paths']['selector']['label_visibility'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Display label'),
'#default_value' => $this->configuration['paths']['selector']['label_visibility'],
];
$form['paths']['selector']['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Label text'),
'#default_value' => $this->configuration['paths']['selector']['label'],
'#description' => $this
->t('Enter the label text for the selector. The default value is "Customize your search".'),
'#states' => [
'visible' => [
':input[name="settings[paths][selector][label_visibility]"]' => [
'checked' => TRUE,
],
],
],
];
$form['paths']['list'] = [
'#type' => 'textarea',
'#title' => $this
->t('Paths'),
'#default_value' => $this->configuration['paths']['list'],
'#rows' => 3,
'#description' => $this
->t('If you want to use custom search paths, enter them here in the form <em>path</em>|<em>label</em>, one per line (if only one path is specified, the selector will be hidden). The [key] token will be replaced by what is entered in the search box, the [types] token will be replaced by the selected content types machine name(s) and the [terms] token will be replaced by the selected taxonomy term id(s). Ie: mysearch/[key]|My custom search label. The [current_path] token can also be used to use the current URL path of the page being viewed.'),
];
$form['paths']['separator'] = [
'#type' => 'textfield',
'#title' => $this
->t('Arguments separator'),
'#description' => $this
->t('Enter a separator that will be used when multiple content types or taxonomy terms are selected and [types] and/or [terms] tokens are used.'),
'#default_value' => $this->configuration['paths']['separator'],
'#size' => 2,
];
$form['#attached']['library'][] = 'core/drupal.tableheader';
$form['#attached']['library'][] = 'custom_search/custom_search.ordering';
$form['order'] = [
'#type' => 'details',
'#title' => $this
->t('Elements layout'),
'#description' => $this
->t('Order the form elements as you want them to be displayed. If you put elements in the Popup region, they will only appear when the search field is clicked.'),
'#open' => TRUE,
];
$form['order']['table'] = [
'#type' => 'table',
'#header' => [
$this
->t('Element'),
$this
->t('Region'),
$this
->t('Weight'),
],
'#attributes' => [
'id' => 'elements',
],
];
$elements = [
'search_box' => [
'label' => $this
->t('Search box'),
'config' => $this->configuration['search_box'],
],
'submit' => [
'label' => $this
->t('Submit button'),
'config' => $this->configuration['submit'],
],
'content' => [
'label' => $this
->t('Content types'),
'config' => $this->configuration['content'],
],
'or' => [
'label' => $this
->t('Criteria: Containing any of the words'),
'config' => $this->configuration['criteria']['or'],
],
'phrase' => [
'label' => $this
->t('Criteria: Containing the phrase'),
'config' => $this->configuration['criteria']['phrase'],
],
'negative' => [
'label' => $this
->t('Criteria: Containing none of the words'),
'config' => $this->configuration['criteria']['negative'],
],
'languages' => [
'label' => $this
->t('Languages'),
'config' => $this->configuration['languages'],
],
'paths' => [
'label' => $this
->t('Custom Path'),
'config' => $this->configuration['paths'],
],
];
if (count($vocabularies)) {
foreach ($vocabularies as $voc) {
$vocId = $voc
->id();
$elements['voc-' . $vocId] = [
'label' => $this
->t('Taxonomy: @name', [
'@name' => $voc
->label(),
]),
'config' => $this->configuration['taxonomy'][$vocId],
];
}
}
uasort($elements, [
$this,
'weightsSort',
]);
$regions = [
'block' => $this
->t('Block'),
'popup' => $this
->t('Popup'),
];
foreach ($elements as $id => $element) {
$element_config = $element['config'];
$regionsElements[$element_config['region']][$id] = $element;
}
foreach ($regions as $region => $title) {
$form['order']['table']['#tabledrag'][] = [
'action' => 'match',
'relationship' => 'sibling',
'group' => 'order-region',
'subgroup' => 'order-region-' . $region,
'hidden' => FALSE,
];
$form['order']['table']['#tabledrag'][] = [
'action' => 'order',
'relationship' => 'sibling',
'group' => 'order-weight',
'subgroup' => 'order-weight-' . $region,
];
$form['order']['table'][$region] = [
'#attributes' => [
'class' => [
'region-title',
'region-title-' . $region,
],
'no_striping' => TRUE,
],
];
$form['order']['table'][$region]['title'] = [
'#markup' => $title,
'#wrapper_attributes' => [
'colspan' => 5,
],
];
$form['order']['table'][$region . '-message'] = [
'#attributes' => [
'class' => [
'region-message',
'region-' . $region . '-message',
empty($regionsElements[$region]) ? 'region-empty' : 'region-populated',
],
],
];
$form['order']['table'][$region . '-message']['message'] = [
'#markup' => '<em>' . $this
->t('No elements in this region') . '</em>',
'#wrapper_attributes' => [
'colspan' => 5,
],
];
if (isset($regionsElements[$region])) {
foreach ($regionsElements[$region] as $id => $element) {
$element_config = $element['config'];
$form['order']['table'][$id]['#attributes']['class'][] = 'draggable';
$form['order']['table'][$id]['#weight'] = $element_config['weight'];
$form['order']['table'][$id]['element'] = [
'#markup' => $element['label'],
];
$form['order']['table'][$id]['region'] = [
'#type' => 'select',
'#title' => $this
->t('Region for @title', [
'@title' => $element['label'],
]),
'#title_display' => 'invisible',
'#options' => [
'block' => $this
->t('Block'),
'popup' => $this
->t('Popup'),
],
'#default_value' => $region,
'#attributes' => [
'class' => [
'order-region',
'order-region-' . $region,
],
],
];
$form['order']['table'][$id]['weight'] = [
'#type' => 'weight',
'#title' => $this
->t('Weight for @title', [
'@title' => $element['label'],
]),
'#title_display' => 'invisible',
'#default_value' => $element_config['weight'],
'#attributes' => [
'class' => [
'order-weight',
'order-weight-' . $element_config['region'],
],
],
];
}
}
}
return $form;
}
public function blockValidate($form, FormStateInterface $form_state) {
if ($form_state
->getValue([
'paths',
'list',
]) != '') {
$lines = explode("\n", $form_state
->getValue([
'paths',
'list',
]));
foreach ($lines as $line) {
if (strpos($line, '|') < 1) {
$form_state
->setErrorByName('list', $this
->t('Custom path must be in the form <em>path</em>|<em>label</em>.'));
break;
}
}
}
if ($this->moduleHandler
->moduleExists('file')) {
$validators = [
'file_validate_is_image' => [],
];
$file = file_save_upload('settings', $validators, FALSE, 0);
if (isset($file)) {
if ($file) {
$directory_path = 'public://custom_search';
\Drupal::service('file_system')
->prepareDirectory($directory_path, FileSystemInterface::CREATE_DIRECTORY);
\Drupal::service('file_system')
->copy($file
->getFileUri(), $directory_path);
$form_state
->setValue([
'submit',
'image_path',
], $filename);
}
else {
$form_state
->setErrorByName('image', $this
->t('The submit image could not be uploaded.'));
}
}
if (!$form_state
->isValueEmpty([
'submit',
'image_path',
])) {
$path = $this
->validatePath($form_state
->getValue([
'submit',
'image_path',
]));
if (!$path) {
$form_state
->setErrorByName('image_path', $this
->t('The submit image path is invalid.'));
}
}
}
}
public function blockSubmit($form, FormStateInterface $form_state) {
$this->configuration['search_box'] = [
'label_visibility' => $form_state
->getValue([
'search_box',
'label_visibility',
]),
'label' => $form_state
->getValue([
'search_box',
'label',
]),
'placeholder' => $form_state
->getValue([
'search_box',
'placeholder',
]),
'title' => $form_state
->getValue([
'search_box',
'title',
]),
'size' => $form_state
->getValue([
'search_box',
'size',
]),
'max_length' => $form_state
->getValue([
'search_box',
'max_length',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'search_box',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'search_box',
'region',
]),
];
$this->configuration['submit'] = [
'text' => $form_state
->getValue([
'submit',
'text',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'submit',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'submit',
'region',
]),
];
if ($this->moduleHandler
->moduleExists('file')) {
if (!$form_state
->isValueEmpty([
'submit',
'image_path',
])) {
$this->configuration['submit']['image_path'] = $this
->validatePath($form_state
->getValue([
'submit',
'image_path',
]));
}
}
$this->configuration['content'] = [
'page' => $form_state
->getValue([
'content',
'page',
]),
'types' => $form_state
->getValue([
'content',
'types',
]),
'other' => $form_state
->getValue([
'content',
'other',
]),
'selector' => [
'type' => $form_state
->getValue([
'content',
'selector',
'type',
]),
'label_visibility' => $form_state
->getValue([
'content',
'selector',
'label_visibility',
]),
'label' => $form_state
->getValue([
'content',
'selector',
'label',
]),
],
'any' => [
'text' => $form_state
->getValue([
'content',
'any',
'text',
]),
'restricts' => $form_state
->getValue([
'content',
'any',
'restricts',
]),
'force' => $form_state
->getValue([
'content',
'any',
'force',
]),
],
'excluded' => $form_state
->getValue([
'content',
'excluded',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'content',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'content',
'region',
]),
];
$vocabularies = \Drupal::entityTypeManager()
->getStorage('taxonomy_vocabulary')
->loadMultiple();
if (count($vocabularies)) {
foreach ($vocabularies as $voc) {
$vocId = $voc
->id();
$this->configuration['taxonomy'][$vocId] = [
'type' => $form_state
->getValue([
'taxonomy',
$vocId,
'type',
]),
'depth' => $form_state
->getValue([
'taxonomy',
$vocId,
'depth',
]),
'label_visibility' => $form_state
->getValue([
'taxonomy',
$vocId,
'label_visibility',
]),
'label' => $form_state
->getValue([
'taxonomy',
$vocId,
'label',
]),
'all_text' => $form_state
->getValue([
'taxonomy',
$vocId,
'all_text',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'voc-' . $vocId,
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'voc-' . $vocId,
'region',
]),
];
}
}
$this->configuration['criteria'] = [
'or' => [
'display' => $form_state
->getValue([
'criteria',
'or',
'display',
]),
'label' => $form_state
->getValue([
'criteria',
'or',
'label',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'or',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'or',
'region',
]),
],
'phrase' => [
'display' => $form_state
->getValue([
'criteria',
'phrase',
'display',
]),
'label' => $form_state
->getValue([
'criteria',
'phrase',
'label',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'phrase',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'phrase',
'region',
]),
],
'negative' => [
'display' => $form_state
->getValue([
'criteria',
'negative',
'display',
]),
'label' => $form_state
->getValue([
'criteria',
'negative',
'label',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'negative',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'negative',
'region',
]),
],
];
if ($this->moduleHandler
->moduleExists('search_api_page')) {
$this->configuration['searchapi']['page'] = $form_state
->getValue([
'searchapi',
'page',
]);
}
$this->configuration['languages'] = [
'languages' => $form_state
->getValue([
'languages',
'languages',
]),
'selector' => [
'type' => $form_state
->getValue([
'languages',
'selector',
'type',
]),
'label_visibility' => $form_state
->getValue([
'languages',
'selector',
'label_visibility',
]),
'label' => $form_state
->getValue([
'languages',
'selector',
'label',
]),
],
'any' => [
'text' => $form_state
->getValue([
'languages',
'any',
'text',
]),
'restricts' => $form_state
->getValue([
'languages',
'any',
'restricts',
]),
'force' => $form_state
->getValue([
'languages',
'any',
'force',
]),
],
'weight' => $form_state
->getValue([
'order',
'table',
'languages',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'languages',
'region',
]),
];
$this->configuration['paths'] = [
'list' => $form_state
->getValue([
'paths',
'list',
]),
'selector' => [
'type' => $form_state
->getValue([
'paths',
'selector',
'type',
]),
'label_visibility' => $form_state
->getValue([
'paths',
'selector',
'label_visibility',
]),
'label' => $form_state
->getValue([
'paths',
'selector',
'label',
]),
],
'separator' => $form_state
->getValue([
'paths',
'separator',
]),
'weight' => $form_state
->getValue([
'order',
'table',
'paths',
'weight',
]),
'region' => $form_state
->getValue([
'order',
'table',
'paths',
'region',
]),
];
}
public function build() {
return \Drupal::formBuilder()
->getForm('Drupal\\custom_search\\Form\\CustomSearchBlockForm', $this->configuration);
}
protected function validatePath($path) {
if (\Drupal::service('file_system')
->realpath($path) == $path) {
return FALSE;
}
if (is_file($path)) {
return $path;
}
if (StreamWrapperManager::getScheme($path) === FALSE) {
$path = 'public://' . $path;
}
if (is_file($path)) {
return $path;
}
return FALSE;
}
private static function weightsSort($a, $b) {
$config_a = $a['config'];
$config_b = $b['config'];
if ($config_a['weight'] == $config_b['weight']) {
return 0;
}
return $config_a['weight'] < $config_b['weight'] ? -1 : 1;
}
}