diff --git a/src/Form/ServiceSearchForm.php b/src/Form/ServiceSearchForm.php new file mode 100644 index 0000000000000000000000000000000000000000..11f5d607fa7c13c80ea5528cbee954105cce5885 --- /dev/null +++ b/src/Form/ServiceSearchForm.php @@ -0,0 +1,292 @@ +<?php + +namespace Drupal\uw_ct_service\Form; + +use Drupal\Core\Form\FormBase; +use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Drupal\Core\Path\CurrentPathStack; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\path_alias\AliasManager; +use Drupal\Core\Messenger\MessengerInterface; + +/** + * Class ServiceSearchForm. + * + * Form for searching services. + */ +class ServiceSearchForm extends FormBase { + + /** + * Entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * The variable for current path. + * + * @var \Drupal\Core\Path\CurrentPathStack + */ + protected $currentPath; + + /** + * The variable for route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $routeMatch; + + /** + * The variable for alias manager. + * + * @var \Drupal\path_alias\AliasManager + */ + protected $aliasManager; + + /** + * The Messenger service. + * + * @var \Drupal\Core\Messenger\MessengerInterface + */ + protected $messenger; + + /** + * Class constructor. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + * @param \Drupal\Core\Path\CurrentPathStack $currentPath + * The currentPath. + * @param \Drupal\Core\Routing\RouteMatchInterface $routeMatch + * The routeMatch. + * @param \Drupal\path_alias\AliasManager $aliasManager + * The aliasManager. + * @param Drupal\Core\Messenger\MessengerInterface $messenger + * The Drupal messenger. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + public function __construct(EntityTypeManagerInterface $entityTypeManager, CurrentPathStack $currentPath, RouteMatchInterface $routeMatch, AliasManager $aliasManager, MessengerInterface $messenger) { + $this->entityTypeManager = $entityTypeManager; + $this->currentPath = $currentPath; + $this->routeMatch = $routeMatch; + $this->aliasManager = $aliasManager; + $this->messenger = $messenger; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + // Instantiates this form class. + return new static( + $container->get('entity_type.manager'), + $container->get('path.current'), + $container->get('current_route_match'), + $container->get('path_alias.manager'), + $container->get('messenger') + ); + } + + /** + * Returns a unique string identifying the form. + * + * The returned ID should be a unique string that can be a valid PHP function + * name, since it's used in hook implementation names such as + * hook_form_FORM_ID_alter(). + * + * @return string + * The unique string identifying the form. + */ + public function getFormId(): string { + return 'service_search_form'; + } + + /** + * Form constructor. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * @param int $tid + * The term id. + * @param string $description + * The description for the input element. + * @param bool $use_placeholder + * A flag to use a placeholder. + * @param string $placeholder + * The placeholder string. + * + * @return array + * The form structure. + */ + public function buildForm(array $form, FormStateInterface $form_state, int $tid = NULL, string $description = NULL, bool $use_placeholder = TRUE, string $placeholder = NULL): array { + + // Get the current route. + $route = $this->routeMatch->getRouteName(); + + // If the route is the all services page, set placeholder to + // search with all services. + if ($route == 'view.uw_view_services.services_page') { + + // Set the placeholder for all services. + $placeholder = 'Search within all services'; + } + + // If this is a service term page, then set placeholder to + // search within <service_name>. + elseif ($route == 'entity.taxonomy_term.canonical') { + + // Load the term. + $term = $this->routeMatch->getParameter('taxonomy_term'); + + // Ensure that we are going to use a placeholder then set it. + if ($use_placeholder && !$placeholder) { + + // Set the placeholder for specific catalog. + $placeholder = 'Search within ' . $term->label(); + } + } + + // If this is a node page, we need to set the tid in the form + // state so that it can be used later to load name and path. + elseif ($route == 'entity.node.canonical') { + + // If we are to use a placeholder, set it. + if ($use_placeholder && !$placeholder) { + + // Load the term in from the tid. + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + + // Set the placeholder. + $placeholder = 'Search within ' . $term->label(); + } + + // Set the tid in the form state. + $form_state->set('tid', $tid); + } + + // If this is any other route mainly: + // /services/<service_name>/<new,category,audience, etc...>, + // Then we have to get the tid from the URL, but ensure that + // we are not in layout builder or error will be thrown. + else { + + // Ensure that we are not on a layout builder page. + // We do not need the tid on a layout builder page, because + // this form can never get submitted on a layout builder page. + if (strpos($route, 'layout_builder') !== 0) { + + // Get the current path. + $url = $this->currentPath->getPath(); + + // Break the path into parts. + $url = explode('/', $url); + + // The tid will always be the 4th element. + $tid = $url[3] ?? NULL; + + // One last check to ensure that we have a tid. + // If we do not have a tid, throw a Drupal error. + if (is_numeric($tid)) { + + // If we are to use a placeholder, set it. + if ($use_placeholder && !$placeholder) { + + // Load the term in from the tid. + $term = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + + // Set the placeholder. + $placeholder = 'Search within ' . $term->label(); + } + + // Set the tid into the form state, so it can be used + // in the form submit. + $form_state->set('tid', $url[3]); + } + else { + + // Throw a Drupal error that there was no service to search. + $this->messenger->addError('There is no specific service to be searched.'); + } + } + } + + // The search input. + $form['search_input'] = [ + '#type' => 'textfield', + '#placeholder' => $use_placeholder ? $placeholder : NULL, + '#description' => $description ?? NULL, + '#required' => TRUE, + ]; + + // Add a submit button that handles the submission of the form. + $form['submit'] = [ + '#type' => 'submit', + '#value' => '', + '#attributes' => ['aria-label' => 'search'], + ]; + + return $form; + } + + /** + * Form submission handler. + * + * @param array $form + * An associative array containing the structure of the form. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + + // Get the values of the form state. + $values = $form_state->getValues(); + + // Get the tid from form state, if there is not one + // it will be NULL. + $tid = $form_state->get('tid'); + + // This is an internal URL. + $url = 'internal:'; + + // If the tid is NULL, we are on a /catalogs page, so we + // can just build the url from the current route. + // If tid is not NULL, we have to determine if this is a + // search all catalogs or specific and set things accordingly. + if ($tid === NULL) { + + // Get the current route as the view for catalog + // search will handle all and specific, based on URL. + $url .= Url::fromRoute('<current>')->toString(); + } + else { + + // If the tid is 0, this is a search all catalogs, + // so set the URL to the /services. + // If not set the search to /services/<service_path>. + if ($tid == 0) { + $url .= '/services'; + } + else { + $url .= $this->aliasManager->getAliasByPath('/taxonomy/term/' . $tid); + } + } + + // Add the search string. + $url .= '/search?search-input=' . $values['search_input']; + + // Get a URL object. + $url = Url::fromUri($url); + + // Set the form redirection URL. + $form_state->setRedirectUrl($url); + } + +} diff --git a/uw_ct_service.module b/uw_ct_service.module index 3bfaa87ffc8bd9c0a5e2d0dd8d4b0a0b6161ed9c..c90240806ee60d093c178a2d4e27b5800b159951 100644 --- a/uw_ct_service.module +++ b/uw_ct_service.module @@ -6,6 +6,7 @@ */ use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Url; /** * Implements hook_geofield_map_latlon_element_alter(). @@ -117,3 +118,95 @@ function uw_ct_service_form_alter(array &$form, FormStateInterface $form_state, break; } } + +/** + * Implements hook_preprocess_views_view(). + */ +function uw_ct_service_preprocess_views_view(&$variables) +{ + + // Get the view variable. + $view = $variables['view']; + + // Get the display of the view. + $id = $view->getDisplay()->display['id']; + + // The array of view ids for services. + $services_ids = [ + 'services_page', + 'popular_services_page', + 'service_for_audience_page', + 'services_in_category_page', + 'all_services_page', + ]; + + // Putting the service search form into + // variables so that views template can use it. + if (in_array($id, $services_ids)) { + $variables['form_search'] = \Drupal::formBuilder()->getForm('Drupal\uw_ct_service\Form\ServiceSearchForm'); + + // Get the current path and put into array based on + // the slashes. + $current_path = \Drupal::service('path.current')->getPath(); + $current_path_parts = explode('/', $current_path); + + if (isset($current_path_parts[2])) { + $content_list[] = [ + 'url' => '/taxonomy/term/' . end($current_path_parts), + 'text' => 'Category', + 'active' => strpos($current_path, '/taxonomy/term/') !== false ? 1 : 0, + ]; + + $content_list[] = [ + 'url' => '/services/all', + 'text' => 'A-Z', + 'active' => $current_path == '/services/all' ? 1 : 0, + ]; + + $content_list[] = [ + 'url' => '/services/audience/' . end($current_path_parts), + 'text' => 'Audience', + 'active' => strpos($current_path, '/services/audience/') !== false ? 1 : 0, + ]; + + $test = ''; + } + + $variables['content_list'] = $content_list; + } + + // If we are on a service view that needs the tab + // links, then process the tabs links. + if ($id == 'uw_view_service_show_nodes' || $id == 'uw_view_service_show_terms') { +// // Taxonomy term id from views argument. +// $term_id = reset($variables['view']->args); +// +// // Building path from route for taxonomy term. +// // If there is an alias it will be used. +// $path = Url::fromRoute('entity.taxonomy_term.canonical', ['taxonomy_term' => $term_id])->toString(); +// +// // Get the current path and put into array based on +// // the slashes. +// $current_path = explode('/', \Drupal::service('path.current')->getPath()); +// +// // Get the taxonomy term. +// $term = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($term_id); +// +// // Get the tabs to be displayed. +// $tabs = $term->field_uw_catalog_tabs_display->getValue(); +// +// // Only show the A-Z tab if there are other tabs. +// $content_list = []; +// if ($tabs) { +// // Setup the variable for the content list to be passed +// // to pattern-lab. +// $content_list[] = [ +// 'url' => $path, +// 'text' => 'A-Z', +// 'active' => end($current_path) == $term_id ? 1 : 0, +// ]; +// } +// +// $variables['content_list'] = $content_list; + } +}