class CustomSearchBlock in Custom Search 8
Provides a 'Custom Search form' block.
Plugin annotation
@Block(
id = "custom_search",
category = @Translation("Forms"),
admin_label = @Translation("Custom Search form")
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Component\Plugin\ContextAwarePluginBase implements ContextAwarePluginInterface
- class \Drupal\Core\Plugin\ContextAwarePluginBase implements CacheableDependencyInterface, ContextAwarePluginInterface uses DependencySerializationTrait, StringTranslationTrait, TypedDataTrait
- class \Drupal\Core\Block\BlockBase implements BlockPluginInterface, PluginWithFormsInterface, PreviewFallbackInterface uses BlockPluginTrait, ContextAwarePluginAssignmentTrait
- class \Drupal\custom_search\Plugin\Block\CustomSearchBlock implements ContainerFactoryPluginInterface
- class \Drupal\Core\Block\BlockBase implements BlockPluginInterface, PluginWithFormsInterface, PreviewFallbackInterface uses BlockPluginTrait, ContextAwarePluginAssignmentTrait
- class \Drupal\Core\Plugin\ContextAwarePluginBase implements CacheableDependencyInterface, ContextAwarePluginInterface uses DependencySerializationTrait, StringTranslationTrait, TypedDataTrait
- class \Drupal\Component\Plugin\ContextAwarePluginBase implements ContextAwarePluginInterface
Expanded class hierarchy of CustomSearchBlock
File
- src/
Plugin/ Block/ CustomSearchBlock.php, line 26
Namespace
Drupal\custom_search\Plugin\BlockView source
class CustomSearchBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The form error handler.
*
* @var \Drupal\Core\Form\FormErrorInterface
*/
protected $errorHandler;
/**
* Constructs a new CustomSearchBlock instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The Module handler object.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('module_handler'));
}
/**
* {@inheritdoc}
*/
protected function blockAccess(AccountInterface $account) {
if ($account
->hasPermission('search content')) {
return AccessResult::allowed();
}
return AccessResult::forbidden();
}
/**
* {@inheritdoc}
*/
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;
}
/**
* Overrides \Drupal\block\BlockBase::blockForm().
*/
public function blockForm($form, FormStateInterface $form_state) {
// Labels & default text.
$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,
];
// Submit button.
$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."),
];
}
// Content.
$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(),
];
// Taxonomy.
$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,
];
// Get vocabularies forms.
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 -".'),
];
}
}
// Criteria.
$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,
],
],
],
];
// Search API support.
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'],
];
}
// Languages.
$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.'),
];
// Custom Paths.
$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,
];
// Ordering.
$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;
}
/**
* Overrides \Drupal\block\BlockBase::blockValidate().
*/
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')) {
// Handle file uploads.
$validators = [
'file_validate_is_image' => [],
];
// Check for a new uploaded logo.
$file = file_save_upload('settings', $validators, FALSE, 0);
if (isset($file)) {
// File upload was attempted.
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 {
// File upload failed.
$form_state
->setErrorByName('image', $this
->t('The submit image could not be uploaded.'));
}
}
// If the user provided a path for a logo or favicon file, make sure a
// file exists at that path.
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.'));
}
}
}
}
/**
* Overrides \Drupal\block\BlockBase::blockSubmit().
*/
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 the user uploaded a new submit image, save it to a permanent location.
if ($this->moduleHandler
->moduleExists('file')) {
// If the user entered a path relative to the system files directory for
// the submit image, store a public:// URI so the theme system can handle
// it.
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',
]),
];
}
/**
* {@inheritdoc}
*/
public function build() {
return \Drupal::formBuilder()
->getForm('Drupal\\custom_search\\Form\\CustomSearchBlockForm', $this->configuration);
}
/**
* Helper function for the form.
*
* Attempts to validate normal system paths, paths relative to the public
* files directory, or stream wrapper URIs. If the given path is any of the
* above, returns a valid path or URI that the theme system can display.
*
* @param string $path
* A path relative to the Drupal root or to the public files directory, or
* a stream wrapper URI.
*
* @return mixed
* A valid path that can be displayed through the theme system, or FALSE if
* the path could not be validated.
*/
protected function validatePath($path) {
// Absolute local file paths are invalid.
if (\Drupal::service('file_system')
->realpath($path) == $path) {
return FALSE;
}
// A path relative to the Drupal root or a fully qualified URI is valid.
if (is_file($path)) {
return $path;
}
// Prepend 'public://' for relative file paths within public filesystem.
if (StreamWrapperManager::getScheme($path) === FALSE) {
$path = 'public://' . $path;
}
if (is_file($path)) {
return $path;
}
return FALSE;
}
/**
* Helper function for sorting elements in the ordering table.
*
* @param mixed $a
* The first value to compare.
* @param mixed $b
* The second value to compare.
*
* @return int
* An integer less than, equal to, or greater than zero if the first
* argument is considered to be respectively less than, equal to, or
* greater than the second.
*/
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;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
BlockPluginInterface:: |
constant | Indicates the block label (title) should be displayed to end users. | ||
BlockPluginTrait:: |
protected | property | The transliteration service. | |
BlockPluginTrait:: |
public | function | ||
BlockPluginTrait:: |
protected | function | Returns generic default configuration for block plugins. | |
BlockPluginTrait:: |
public | function | Creates a generic configuration form for all block types. Individual block plugins can add elements to this form by overriding BlockBase::blockForm(). Most block plugins should not override this method unless they need to alter the generic form elements. | 2 |
BlockPluginTrait:: |
public | function | ||
BlockPluginTrait:: |
public | function | 1 | |
BlockPluginTrait:: |
public | function | 1 | |
BlockPluginTrait:: |
public | function | 3 | |
BlockPluginTrait:: |
public | function | ||
BlockPluginTrait:: |
public | function | ||
BlockPluginTrait:: |
public | function | ||
BlockPluginTrait:: |
public | function | Sets the transliteration service. | |
BlockPluginTrait:: |
public | function | Most block plugins should not override this method. To add submission handling for a specific block type, override BlockBase::blockSubmit(). | |
BlockPluginTrait:: |
protected | function | Wraps the transliteration service. | |
BlockPluginTrait:: |
public | function | Most block plugins should not override this method. To add validation for a specific block type, override BlockBase::blockValidate(). | 1 |
ContextAwarePluginAssignmentTrait:: |
protected | function | Builds a form element for assigning a context to a given slot. | |
ContextAwarePluginAssignmentTrait:: |
protected | function | Wraps the context handler. | |
ContextAwarePluginBase:: |
protected | property | The data objects representing the context of this plugin. | |
ContextAwarePluginBase:: |
private | property | Data objects representing the contexts passed in the plugin configuration. | |
ContextAwarePluginBase:: |
protected | function |
Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
The cache contexts associated with this object. Overrides CacheableDependencyInterface:: |
9 |
ContextAwarePluginBase:: |
public | function |
The maximum age for which this object may be cached. Overrides CacheableDependencyInterface:: |
7 |
ContextAwarePluginBase:: |
public | function |
The cache tags associated with this object. Overrides CacheableDependencyInterface:: |
4 |
ContextAwarePluginBase:: |
public | function |
This code is identical to the Component in order to pick up a different
Context class. Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Gets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Gets the defined contexts. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Gets the value for a defined context. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Gets the values for all defined contexts. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Set a context on this plugin. Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Sets a mapping of the expected assignment names to their context names. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function |
Sets the value for a defined context. Overrides ContextAwarePluginBase:: |
|
ContextAwarePluginBase:: |
public | function |
Validates the set values for the defined contexts. Overrides ContextAwarePluginInterface:: |
|
ContextAwarePluginBase:: |
public | function | Implements magic __get() method. | |
CustomSearchBlock:: |
protected | property | The form error handler. | |
CustomSearchBlock:: |
protected | property | The module handler. | |
CustomSearchBlock:: |
protected | function |
Indicates whether the block should be shown. Overrides BlockPluginTrait:: |
|
CustomSearchBlock:: |
public | function |
Overrides \Drupal\block\BlockBase::blockForm(). Overrides BlockPluginTrait:: |
|
CustomSearchBlock:: |
public | function |
Overrides \Drupal\block\BlockBase::blockSubmit(). Overrides BlockPluginTrait:: |
|
CustomSearchBlock:: |
public | function |
Overrides \Drupal\block\BlockBase::blockValidate(). Overrides BlockPluginTrait:: |
|
CustomSearchBlock:: |
public | function |
Builds and returns the renderable array for this block plugin. Overrides BlockPluginInterface:: |
|
CustomSearchBlock:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
CustomSearchBlock:: |
public | function |
Overrides BlockPluginTrait:: |
|
CustomSearchBlock:: |
protected | function | Helper function for the form. | |
CustomSearchBlock:: |
private static | function | Helper function for sorting elements in the ordering table. | |
CustomSearchBlock:: |
public | function |
Constructs a new CustomSearchBlock instance. Overrides BlockPluginTrait:: |
|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PluginWithFormsTrait:: |
public | function | ||
PluginWithFormsTrait:: |
public | function | ||
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TypedDataTrait:: |
protected | property | The typed data manager used for creating the data types. | |
TypedDataTrait:: |
public | function | Gets the typed data manager. | 2 |
TypedDataTrait:: |
public | function | Sets the typed data manager. | 2 |