ext_search_page.module in Extended search page 7
Extended search page module.
File
ext_search_page.moduleView source
<?php
/**
* @file
* Extended search page module.
*/
/**
* Implements hook_form_alter().
*/
function ext_search_page_form_alter(&$form, &$form_state, $form_id) {
switch ($form_id) {
case 'search_api_page_admin_edit':
module_load_include('inc', 'ext_search_page', 'ext_search_page.admin');
ext_search_page_admin_edit_alter_form($form, $form_state, $form_id);
break;
}
}
/**
* Implements hook_menu_alter().
*/
function ext_search_page_menu_alter(&$items) {
// During uninstallation, this would lead to a fatal error otherwise.
if (module_exists('ext_search_page')) {
foreach (ext_search_page_load_pages(array(
'extended' => TRUE,
)) as $page) {
$items[$page->path]['page callback'] = 'ext_search_page_view';
$items[$page->path]['access arguments'] = array(
'access ext_search_page',
);
$items[$page->path]['file'] = 'ext_search_page.pages.inc';
$items[$page->path]['file path'] = drupal_get_path('module', 'ext_search_page');
}
}
}
/**
* Implements hook_block_info().
*/
function ext_search_page_block_info() {
$blocks = array();
foreach (ext_search_page_load_pages(array(
'block' => TRUE,
)) as $page) {
$blocks[$page->id] = array(
'info' => t('Search @page', array(
'@page' => $page->name,
)),
'cache' => DRUPAL_CACHE_GLOBAL,
);
}
return $blocks;
}
/**
* Implements hook_block_view().
*/
function ext_search_page_block_view($delta = '') {
$page = ext_search_page_load_pages($delta);
if (!$page) {
return FALSE;
}
module_load_include('inc', 'ext_search_page', 'ext_search_page.pages');
$content = drupal_get_form('ext_search_page_search_form', $page, '', array(), 'block');
return array(
'subject' => t('Search @page', array(
'@page' => $page->name,
)),
'content' => $content,
);
}
/**
* Implements hook_theme().
*/
function ext_search_page_theme() {
$themes = array();
$themes['ext_search_page_filters_table'] = array(
'render element' => 'form',
'file' => 'ext_search_page.admin.inc',
'status' => 0,
'region' => -1,
);
$themes['ext_search_default_page_results'] = array(
'variables' => array(
'page' => NULL,
'results' => array(
'result count' => 0,
),
'entities' => array(),
'keys' => '',
),
'file' => 'ext_search_page.admin.inc',
);
return $themes;
}
/**
* Implements hook_permission().
*/
function ext_search_page_permission() {
return array(
'access ext_search_page' => array(
'title' => t('Access extended search pages'),
'description' => t('Execute searches using the Extended search pages module.'),
),
);
}
/**
* Implements hook_entity_property_info_alter()
*/
function ext_search_page_entity_property_info_alter(&$info) {
$info['search_api_page']['properties']['ext_search_options'] = array(
'label' => t('Extended search options'),
'type' => 'struct',
'description' => t('Options for extended search.'),
);
}
/**
* Filter weight comp callback.
*
* @param array $a
* @param array $b
*
* @return number
*/
function ext_search_page_cmp_filter($a, $b) {
if ($a['weight'] == $b['weight']) {
return 0;
}
return $a['weight'] < $b['weight'] ? -1 : 1;
}
/**
* Get the index fields
* @param SearchApiIndex $index
* @return array
*/
function ext_search_page_get_index_fields($index) {
return $index
->getFields(FALSE);
}
/**
* Get the fields from index which are usable as filter.
* Fulltext fields are not eligible.
*
* @param Entity $page
*/
function ext_search_page_get_available_filters($page) {
$filters_registry =& drupal_static(__FUNCTION__);
if (!isset($filters_registry[$page->index_id])) {
$index = search_api_index_load($page->index_id);
$filters_registry[$page->index_id] = array();
foreach (ext_search_page_get_index_fields($index) as $field => $field_info) {
// filter only if non fulltext index
if (!search_api_is_text_type($field_info['type']) && !empty($field_info['indexed'])) {
// do not allow system language filter if no content translation module ?
if ($field == 'search_api_language' && !module_exists('translation')) {
continue;
}
$filters_registry[$page->index_id][$field] = $field_info;
$filters_registry[$page->index_id][$field]['default_name'] = isset($filters_registry[$page->index_id][$field]['name']) ? $filters_registry[$page->index_id][$field]['name'] : $field;
foreach (array(
'weight',
'default',
'wid',
'display',
'block',
'display_name',
'widget_settings',
) as $param) {
$filters_registry[$page->index_id][$field][$param] = isset($page->ext_search_options['filters'][$field][$param]) ? $page->ext_search_options['filters'][$field][$param] : null;
}
if (!$filters_registry[$page->index_id][$field]['display_name']) {
$filters_registry[$page->index_id][$field]['display_name'] = '<default>';
}
switch ($filters_registry[$page->index_id][$field]['display_name']) {
case '<none>':
$filters_registry[$page->index_id][$field]['name'] = NULL;
break;
case '<default>':
$filters_registry[$page->index_id][$field]['name'] = $filters_registry[$page->index_id][$field]['default_name'];
break;
default:
$filters_registry[$page->index_id][$field]['name'] = $filters_registry[$page->index_id][$field]['display_name'];
}
}
}
uasort($filters_registry[$page->index_id], 'ext_search_page_cmp_filter');
}
return $filters_registry[$page->index_id];
}
/**
* Map index type to native type.
*
* @param string $type
*/
function ext_search_page_get_native_type($type) {
switch ($type) {
case 'search_api_et_node':
return 'node';
}
return $type;
}
/**
* Build and return the widget registry.
* Allow other module to alter the registry with hook_ext_search_page_widgets_registry_alter().
*
* @param Entity $page
* @param string $field
* Field id, optional, returns only the widgets for this field
* @return array
* The widgets registry for the page or for the field
*/
function ext_search_page_get_widgets_registry($page, $field = NULL) {
$registry =& drupal_static(__FUNCTION__);
if (!isset($registry[$page->index_id])) {
$index = search_api_index_load($page->index_id);
$top_wrapper = $index
->entityWrapper();
foreach (ext_search_page_get_available_filters($page) as $field_id => $field_info) {
$registry[$page->index_id][$field_id] = $field_info;
// special fields
switch ($field_id) {
case 'search_api_language':
if ($languages = module_invoke('locale', 'language_list')) {
$languages = array(
LANGUAGE_NONE => t('Language neutral'),
) + $languages;
$registry[$page->index_id][$field_id]['widgets']['search_api_language'] = array(
'name' => t('Language selector'),
'wid' => 'search_api_language',
'type' => 'select',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'options' => array(
'*' => t('All'),
) + $languages,
'default_value' => '*',
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
}
break;
case 'type':
if (ext_search_page_get_native_type($top_wrapper
->type()) == 'node') {
$registry[$page->index_id][$field_id]['widgets']['type'] = array(
'name' => t('Content type selector'),
'wid' => 'type',
'type' => 'select',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'options' => array(
'*' => t('All'),
) + node_type_get_names(),
'default_value' => '*',
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
}
break;
case 'status':
if (ext_search_page_get_native_type($top_wrapper
->type()) == 'node') {
$registry[$page->index_id][$field_id]['widgets']['type'] = array(
'name' => t('Status selector'),
'wid' => 'status',
'type' => 'select',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'options' => array(
'*' => t('All'),
'yes' => t('Published'),
'no' => t('Not published'),
),
'default_value' => '*',
'operator' => 'boolean',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
}
break;
}
// more complex cases use entity wrapper
$wrapper = $top_wrapper;
$parent_wrapper = NULL;
foreach (explode(':', $field_id) as $element) {
if (!isset($wrapper->{$element})) {
break;
}
$parent_wrapper = $wrapper;
$wrapper = $wrapper->{$element};
}
$taxonomy = FALSE;
$list = FALSE;
if ($wrapper) {
$wrapper_info = $wrapper
->info();
if ($parent_wrapper) {
$parent_wrapper_info = $parent_wrapper
->info();
}
else {
$parent_wrapper_info = array(
'type' => NULL,
);
}
// taxonomy terms ?
if ($wrapper_info['type'] == 'list<taxonomy_term>') {
// bundle seams to be the vocabulary
$taxonomy = $wrapper_info['bundle'];
$multiple = TRUE;
}
else {
if ($wrapper_info['type'] == 'taxonomy_term') {
// bundle seams to be the vocabulary
$taxonomy = $wrapper_info['bundle'];
}
elseif ($parent_wrapper_info['type'] == 'taxonomy_term' && $wrapper_info['type'] == 'integer') {
// parent bundle seams to be the vocabulary and maybe this is a tid
$taxonomy = $parent_wrapper_info['bundle'];
}
}
}
if ($taxonomy) {
if ($vocabulary = taxonomy_vocabulary_machine_name_load($taxonomy)) {
// taxo select
$registry[$page->index_id][$field_id]['widgets']['taxonomy'] = array(
'name' => t('Taxonomy @vocabulary selector', array(
'@vocabulary' => $vocabulary->name,
)),
'wid' => 'taxonomy',
'type' => 'select',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'vid' => $vocabulary->vid,
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
$registry[$page->index_id][$field_id]['widgets']['taxonomy_multiple'] = $registry[$page->index_id][$field_id]['widgets']['taxonomy'];
$registry[$page->index_id][$field_id]['widgets']['taxonomy_multiple']['operator'] = 'IN';
$registry[$page->index_id][$field_id]['widgets']['taxonomy_multiple']['name'] = t('Taxonomy @vocabulary multiple selector', array(
'@vocabulary' => $vocabulary->name,
));
$registry[$page->index_id][$field_id]['widgets']['taxonomy_multiple']['wid'] = 'taxonomy_multiple';
// taxo autocomplete
$registry[$page->index_id][$field_id]['widgets']['taxonomy_autocomplete'] = array(
'name' => t('Taxonomy @vocabulary autocomplete', array(
'@vocabulary' => $vocabulary->name,
)),
'wid' => 'taxonomy_autocomplete',
'type' => 'autocomplete',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'vocabulary' => $taxonomy,
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
$registry[$page->index_id][$field_id]['widgets']['taxonomy_autocomplete_multiple'] = $registry[$page->index_id][$field_id]['widgets']['taxonomy_autocomplete'];
$registry[$page->index_id][$field_id]['widgets']['taxonomy_autocomplete_multiple']['operator'] = 'IN';
$registry[$page->index_id][$field_id]['widgets']['taxonomy_autocomplete_multiple']['name'] = t('Taxonomy @vocabulary multiple autocomplete', array(
'@vocabulary' => $vocabulary->name,
));
$registry[$page->index_id][$field_id]['widgets']['taxonomy_autocomplete_multiple']['wid'] = 'taxonomy_autocomplete_multiple';
}
}
else {
switch ($field_info['type']) {
case 'boolean':
$registry[$page->index_id][$field_id]['widgets']['boolean'] = array(
'name' => t('Boolean'),
'wid' => 'boolean',
'type' => 'select',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'options' => array(
'*' => t('All'),
'yes' => t('Yes'),
'no' => t('No'),
),
'default_value' => '*',
'operator' => 'boolean',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
break;
case 'integer':
case 'number':
$registry[$page->index_id][$field_id]['widgets']['number_input'] = array(
'name' => t('Number input'),
'wid' => 'number_input',
'type' => 'textfield',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'default_value' => '*',
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
break;
case 'string':
$registry[$page->index_id][$field_id]['widgets']['string_input'] = array(
'name' => t('String input'),
'wid' => 'string_input',
'type' => 'textfield',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'default_value' => '*',
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
/*
$ops = array('*' => t('All'));
if (isset($registry[$page->index_id][$field_id]['widget_settings']['params'])) {
foreach (explode('|', ))
}*/
$registry[$page->index_id][$field_id]['widgets']['string_select'] = array(
'name' => t('String select'),
'wid' => 'string_select',
'type' => 'select',
//'options' => $ops,
'title' => $field_info['name'] ? t($field_info['name']) : null,
'default_value' => '*',
'operator' => '=',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
'widget_settings' => array(
'form_callback' => 'ext_search_page_filter_widget_basic_settings',
'alter_callback' => 'ext_search_page_filter_widget_basic_settings_string_select_alter',
'description' => t('Enter pipe (|) separated select options.'),
'size' => 32,
),
);
break;
case 'date':
$registry[$page->index_id][$field_id]['widgets']['date_range'] = array(
'name' => t('Date range'),
'wid' => 'date_range',
'title' => $field_info['name'] ? t($field_info['name']) : null,
'operator' => 'range',
'add_form' => 'ext_search_page_add_filter_widget_form',
'get_values' => 'ext_search_page_get_filter_widget_values',
'add_condition' => 'ext_search_page_add_filter_widget_condition',
);
break;
default:
}
}
$field_info = $registry[$page->index_id][$field_id];
// alter current widget with settings if available
$wid = isset($field_info['wid']) ? $field_info['wid'] : NULL;
if ($wid && isset($field_info['widgets'][$wid]['widget_settings'])) {
$wsettings = $field_info['widgets'][$wid]['widget_settings'];
$f = $wsettings['alter_callback'];
$wsettings['field'] = $field;
$f($registry[$page->index_id][$field_id]['widgets'][$wid], $field_info, $wsettings);
}
}
// invoke other module hook_ext_search_page_widgets_registry_alter()
drupal_alter('ext_search_page_widgets_registry', $registry[$page->index_id], $page);
}
if ($field) {
return $registry[$page->index_id][$field];
}
return $registry[$page->index_id];
}
/**
* Return the chosen widgets for current page.
*
* @param Entity $page
* The search page object
*
* @return array
* An array of widgets for the given page.
*/
function ext_search_page_get_filter_widgets($page) {
$widgets =& drupal_static(__FUNCTION__);
if (!isset($widgets[$page->id])) {
$widgets[$page->id] = array();
foreach (ext_search_page_get_widgets_registry($page) as $field => $field_infos) {
// paranoid : be sure it is a full coded widget...
if (isset($field_infos['widgets'][$field_infos['wid']]['wid'])) {
$widgets[$page->id][$field] = $field_infos['widgets'][$field_infos['wid']];
foreach (array(
'display',
'block',
'default',
) as $param) {
$widgets[$page->id][$field][$param] = $field_infos[$param];
}
}
}
}
return $widgets[$page->id];
}
/**
* Default get values callback. Get the value of widget from form.
* Returns an array because some widget may need complex value.
*
* @param string $field
* Field id
* @param array $widget
* Widget definition
* @param array $form_values
* Form state format values
* @return array
* The values
*/
function ext_search_page_get_filter_widget_values($field, array $widget, array &$form_values) {
if (!isset($form_values[$field])) {
return NULL;
}
$values = NULL;
switch ($widget['wid']) {
//dumb implementation to show how to manage different cases.
case 'search_api_language':
if (isset($form_values[$field])) {
$values = array(
$form_values[$field],
);
}
break;
case 'date_range':
if ($form_values[$field]['drb'] && $form_values[$field]['isdrb']) {
$values[0] = mktime(0, 0, 0, $form_values[$field]['drb']['month'], $form_values[$field]['drb']['day'], $form_values[$field]['drb']['year']);
$values[1] = '';
}
if ($form_values[$field]['dre'] && $form_values[$field]['isdre']) {
if (!isset($values[0])) {
$values[0] = '';
}
$values[1] = mktime(0, 0, 0, $form_values[$field]['dre']['month'], $form_values[$field]['dre']['day'], $form_values[$field]['dre']['year']);
}
break;
case 'taxonomy_multiple':
case 'taxonomy_autocomplete_multiple':
if (isset($form_values[$field]) && $form_values[$field]) {
$values = $form_values[$field];
if (isset($values['*'])) {
$values = array(
'*',
);
}
}
break;
default:
switch ($widget['type']) {
case 'autocomplete':
if (isset($form_values[$field]) && $form_values[$field]) {
$values = array(
$form_values[$field],
);
}
break;
default:
if (isset($form_values[$field])) {
$values = array(
$form_values[$field],
);
}
}
}
if (isset($widget['default']) && $values == $widget['default']) {
return NULL;
}
return $values;
}
function _ext_search_page_page_mode($mode) {
return !($mode == 'admin');
}
/**
* Default add form calback. Modify the form to add the corresponding filter widget.
*
* @param array $form
* The form element to be modified
* @param string $field
* Field id
* @param string $widget
* Widget definition
* @param array|null $values
* Values for the widget
* @param boolean $mode
* Render mode
*/
function ext_search_page_add_filter_widget_form(array &$form, $field, array $widget, $values, $mode = 'default') {
switch ($widget['wid']) {
case 'date_range':
if (_ext_search_page_page_mode($mode)) {
if (isset($values[0]) && $values[0] != '*') {
// display filter status
if ($widget['title']) {
$form['current'][] = array(
'#markup' => t('%property from %from to %to', array(
'%property' => $widget['title'],
'%from' => $values[0] ? format_date($values[0], 'short') : t('*ever*'),
'%to' => $values[1] ? format_date($values[1], 'short') : t('*ever*'),
)),
);
}
}
}
// display a widget
$drb = NULL;
if (isset($values[0]) && $values[0]) {
$drb = array(
'year' => (int) strftime('%Y', $values[0]),
// (int) cast seams important
'month' => (int) strftime('%m', $values[0]),
'day' => (int) strftime('%d', $values[0]),
);
}
$dre = NULL;
if (isset($values[1]) && $values[1]) {
$dre = array(
'year' => (int) strftime('%Y', $values[1]),
'month' => (int) strftime('%m', $values[1]),
'day' => (int) strftime('%d', $values[1]),
);
}
$form[$field] = array(
'#prefix' => '<div class="date-range">',
'#suffix' => '</div>',
);
if ($mode != 'admin' && $widget['title']) {
$form[$field]['title'] = array(
'#markup' => '<label>' . t("Date range for %field", array(
'%field' => $widget['title'],
)) . '</label>',
);
}
$form[$field]['isdrb'] = array(
'#type' => 'checkbox',
'#title' => t('Begin'),
'#default_value' => $drb != NULL,
);
$form[$field]['drb'] = array(
'#type' => 'date',
'#default_value' => $drb,
);
$form[$field]['isdre'] = array(
'#type' => 'checkbox',
'#title' => t('End'),
'#default_value' => $dre != NULL,
);
$form[$field]['dre'] = array(
'#type' => 'date',
'#default_value' => $dre,
);
return TRUE;
case 'taxonomy':
case 'taxonomy_multiple':
$filter = '';
if ($widget['wid'] == 'taxonomy_multiple') {
$tags = array();
if (isset($values) && is_array($values) && !isset($values['*'])) {
foreach ($values as $tid) {
$term = taxonomy_term_load($tid);
if ($term) {
$tags[$tid] = $term;
}
}
$filter = taxonomy_implode_tags($tags);
}
}
else {
if (isset($values[0]) && $values[0] != '*') {
$term = taxonomy_term_load($values[0]);
if ($term) {
$filter = $term->name;
}
}
}
if (_ext_search_page_page_mode($mode)) {
if (isset($values[0]) && $values[0] != '*') {
// display filter status
$form['current'][] = array(
'#markup' => t('%property !op %value', array(
'%property' => $widget['title'],
'%value' => $filter,
'!op' => $widget['wid'] == 'taxonomy_multiple' ? 'in' : 'is',
)),
);
}
}
// put this at last moment because taxonomy_get_tree() can explode memory on large vocabulary
// so using autocomplete will not make ext_search explode !
$options = array(
'*' => t('All'),
);
if ($terms = taxonomy_get_tree($widget['vid'])) {
foreach ($terms as $term) {
$options[$term->tid] = str_repeat('-', $term->depth) . $term->name;
}
}
// display a widget
$form[$field] = array(
'#type' => 'select',
'#options' => $options,
'#size' => $widget['wid'] == 'taxonomy_multiple' ? min(12, count($options)) : 0,
'#multiple' => $widget['wid'] == 'taxonomy_multiple',
'#default_value' => $widget['wid'] == 'taxonomy_multiple' ? isset($values) && is_array($values) ? array_values($values) : array(
'*',
) : (isset($values[0]) ? $values[0] : '*'),
);
if ($mode != 'admin') {
$form[$field]['#title'] = $widget['title'];
}
return TRUE;
case 'taxonomy_autocomplete':
case 'taxonomy_autocomplete_multiple':
$filter = '';
if ($widget['wid'] == 'taxonomy_autocomplete_multiple') {
$tags = array();
if (isset($values) && is_array($values) && !isset($values['*'])) {
foreach ($values as $tid) {
$term = taxonomy_term_load($tid);
if ($term) {
$tags[$tid] = $term;
}
}
$filter = taxonomy_implode_tags($tags);
}
}
else {
if (isset($values[0]) && $values[0] != '*') {
$term = taxonomy_term_load($values[0]);
if ($term) {
$filter = $term->name;
}
}
}
if (_ext_search_page_page_mode($mode)) {
if (isset($values[0]) && $values[0] != '*') {
// display filter status
$form['current'][] = array(
'#markup' => t('%property !op %value', array(
'%property' => $widget['title'],
'%value' => $filter,
'!op' => $widget['wid'] == 'taxonomy_autocomplete_multiple' ? 'in' : 'is',
)),
);
}
}
// display a widget
$form[$field] = array(
'#type' => 'textfield',
'#autocomplete_path' => 'ext_search_page/taxonomy_autocomplete/' . $widget['vocabulary'],
'#vocabulary' => $widget['vocabulary'],
'#maxlength' => 1024,
'#size' => $widget['wid'] == 'taxonomy_autocomplete_multiple' ? 64 : 16,
'#default_value' => $filter,
'#multiple' => $widget['wid'] == 'taxonomy_autocomplete_multiple',
'#element_validate' => array(
'ext_search_page_taxonomy_autocomplete_validate',
),
);
if ($mode != 'admin') {
$form[$field]['#title'] = $widget['title'];
}
return TRUE;
}
switch ($widget['type']) {
case 'select':
if (_ext_search_page_page_mode($mode)) {
if (isset($values[0]) && $values[0] != '*') {
// display filter status
$form['current'][] = array(
'#markup' => t('%property is %value', array(
'%property' => $widget['title'],
'%value' => $widget['options'][$values[0]],
)),
);
}
}
// display a widget
$form[$field] = array(
'#type' => 'select',
'#options' => $widget['options'],
'#default_value' => isset($values[0]) ? $values[0] : '*',
);
if ($mode != 'admin') {
$form[$field]['#title'] = $widget['title'];
}
return TRUE;
case 'textfield':
if (_ext_search_page_page_mode($mode)) {
if (isset($values[0]) && $values[0] != '*') {
// display filter status
$form['current'][] = array(
'#markup' => t('%property is %value', array(
'%property' => $widget['title'],
'%value' => isset($values[0]) ? $values[0] : '*',
)),
);
}
}
// display a widget
$form[$field] = array(
'#type' => 'textfield',
'#size' => isset($widget['size']) ? $widget['size'] : NULL,
'#default_value' => isset($values[0]) ? $values[0] == '*' ? '' : $values[0] : '',
);
if ($mode != 'admin') {
$form[$field]['#title'] = $widget['title'];
}
return TRUE;
}
return FALSE;
}
/**
* Form element validate handler for taxonomy term autocomplete element.
*/
function ext_search_page_taxonomy_autocomplete_validate($element, &$form_state) {
// Autocomplete widgets do not send their tids in the form, so we must detect
// them here and process them independently.
$value = array();
if ($tags = $element['#value']) {
$vocabulary = taxonomy_vocabulary_machine_name_load($element['#vocabulary']);
// Translate term names into actual terms.
$typed_terms = drupal_explode_tags($tags);
foreach ($typed_terms as $typed_term) {
// See if the term exists in the chosen vocabulary and return the tid;
if ($possibilities = taxonomy_term_load_multiple(array(), array(
'name' => trim($typed_term),
'vid' => $vocabulary->vid,
))) {
$term = array_pop($possibilities);
$value[$term->tid] = $term->tid;
if (!$element['#multiple']) {
break;
}
}
}
}
if (empty($value)) {
$value = array(
'*',
);
}
if (!$element['#multiple']) {
$value = reset($value);
}
form_set_value($element, $value, $form_state);
}
/**
* Default add condition callback. Add a condition to the search api query reflecting the widget state.
*
* @param SearchApiQueryInterface $query
* The search api quey
* @param string $field
* Field id
* @param array $widget
* Widget definition
* @param array|null $values
*
*/
function ext_search_page_add_filter_widget_condition(SearchApiQueryInterface $query, $field, array $widget, $values) {
if ($values === NULL) {
return;
}
if (count($values) == 1 && $values[0] == '*') {
return;
}
switch ($widget['wid']) {
case 'date_range':
if ($values[0]) {
$query
->condition($field, $values[0], '>=');
}
if ($values[1]) {
$query
->condition($field, $values[1] + 3600 * 24, '<');
}
break;
default:
switch ($widget['operator']) {
case 'boolean':
$query
->condition($field, $values[0] == 'yes' ? 1 : 0);
break;
case 'IN':
$filter = new SearchApiQueryFilter('OR');
foreach ($values as $value) {
$filter
->condition($field, $value);
}
$query
->filter($filter);
break;
default:
$query
->condition($field, $values[0], $widget['operator']);
}
}
}
/**
* Executes a search.
*
* @param Entity $page
* The page for which a search should be executed.
* @param $keys
* The keywords to search for.
* @param $values
* Filters values
* @param $sort
* Field or array or field to sort with.
* @param $offset
* @param $limit
*
* @return array
* The search results as returned by SearchApiQueryInterface::execute().
*/
function ext_search_page_search_execute($page, $keys, $values, $sort = FALSE, $limit = 50, $offset = 0) {
$query = ext_search_page_search_query($page, $keys, $values, $sort, $limit, $offset);
$results = $query
->execute();
if (!$keys && $page->options['empty_behavior'] === 'blocks' && !search_api_page_query_has_facets($query)) {
return FALSE;
}
return $results;
}
/**
* Create the search page query.
*
* @param Entity $page
* The page for which a search should be executed.
* @param $keys
* The keywords to search for.
* @param $values
* Filters values.
* @param $sort
* Field or array or field to sort with.
* @param $offset
* @param $limit
* @param $search_id Seach API ID (cache ?)
* @return SearchApiQueryInterface
* An object for searching on the page.
*/
function ext_search_page_search_query($page, $keys, $values, $sort = FALSE, $limit = 50, $offset = 0, $search_id = NULL) {
if (!$search_id) {
// needed for cache
$search_id = 'ext_search_page:' . $page->path . ':' . md5(serialize($values));
}
$options = array(
'search id' => $search_id,
'search_api_page id' => $page->machine_name,
'parse mode' => $page->options['mode'],
);
if (!empty($page->options['search_api_spellcheck'])) {
$options['search_api_spellcheck'] = TRUE;
}
$query = search_api_query($page->index_id, $options)
->keys($keys)
->range($offset, $limit);
// refactor ext>
if (count($values)) {
// we call add condition callback (even for hidden widgets)
foreach (ext_search_page_get_filter_widgets($page) as $field => $widget) {
// call add condition callback.
$f = $widget['add_condition'];
$f($query, $field, $widget, isset($values[$field]) ? $values[$field] : null);
}
}
// <refactor ext
if (!empty($page->options['fields'])) {
$query
->fields($page->options['fields']);
}
if (!empty($page->options['language_filter'])) {
$languages = array_unique(array_map('_search_api_page_map_languages', $page->options['language_filter']));
if (count($languages) == 1) {
$query
->condition('search_api_language', reset($languages));
}
else {
$filter = $query
->createFilter('OR');
foreach ($languages as $lang) {
$filter
->condition('search_api_language', $lang);
}
$query
->filter($filter);
}
}
if ($sort) {
if (!is_array($sort)) {
$sort = array(
$sort,
);
}
foreach ($sort as $field => $order) {
if (!is_string($field)) {
$field = $order;
$order = 'ASC';
}
$query
->sort($field, $order);
}
}
return $query;
}
/**
* Get filters values from $_GET and from default.
*
* @param $page
* @param boolean &$non_default
* Tells if we got non default values.
* @param string $mode
* Render mode
*/
function ext_search_page_get_filter_values($page, &$non_default = NULL, $mode = 'default') {
switch ($mode) {
case 'admin_content':
$storage = isset($_SESSION['ext_search_page_filter']) ? $_SESSION['ext_search_page_filter'] : array();
break;
default:
$storage = $_GET;
}
$non_default = FALSE;
$filter_values = array();
foreach (ext_search_page_get_widgets_registry($page) as $field => $field_info) {
if (isset($field_info['default']) && $field_info['default']) {
$filter_values[$field] = $field_info['default'];
}
// we do not care about get for admin and block
if (_ext_search_page_page_mode($mode) && isset($field_info['display']) && $field_info['display']) {
// the widget is enabled we can retrieve values from user...
if (isset($storage[$field]) && $storage[$field]) {
$filter_values[$field] = explode('|', $storage[$field]);
if (isset($field_info['default']) && $filter_values[$field] != $field_info['default']) {
//just to know if we have to unfolde the advanced fieldset
$non_default = TRUE;
}
}
}
}
return $filter_values;
}
/**
* Implements hook_menu().
*/
function ext_search_page_menu() {
$items['ext_search_page/taxonomy_autocomplete'] = array(
'title' => 'Autocomplete taxonomy',
'page callback' => 'ext_search_page_taxonomy_autocomplete',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
'file' => 'ext_search_page.pages.inc',
);
return $items;
}
/**
* Basic callback to add a text input widget setting
*/
function ext_search_page_filter_widget_basic_settings_add(&$element, $field_info, $settings) {
$element['param'] = array(
'#type' => 'textfield',
'#default_value' => isset($field_info['widget_settings']['param']) ? $field_info['widget_settings']['param'] : '',
'#size' => 16,
);
if (isset($settings['title'])) {
$element['param']['#title'] = $settings['title'];
}
if (isset($settings['description'])) {
$element['param']['#description'] = $settings['description'];
}
if (isset($settings['size'])) {
$element['param']['#size'] = $settings['size'];
}
}
/**
* Basic callback function to retrieve the settings text input value
* @see ext_search_page_filter_widget_basic_settings_add()
*/
function ext_search_page_filter_widget_basic_settings_submit($form_state_element, $field_info, $settings) {
return $form_state_element;
}
/**
* Basic callback function to alter the widget
* @see ext_search_page_filter_widget_basic_settings_add()
*/
function ext_search_page_filter_widget_basic_settings_string_select_alter(&$widget, $field_info, $settings) {
$widget['options'] = array(
'*' => t('All'),
);
if (isset($field_info['widget_settings']['param'])) {
foreach (explode('|', $field_info['widget_settings']['param']) as $value) {
$widget['options'][$value] = $value ? $value : t('(empty)');
}
}
}
/**
* Pages loader.
* @param int|array $options
* A page Id or an array of options :
* - type : main entity type
* - extended : extended pages only
*/
function ext_search_page_load_pages($options = array()) {
$pages =& drupal_static(__FUNCTION__, NULL);
$pages_by_type =& drupal_static(__FUNCTION__ . '_by_type', array());
$id = NULL;
$retid = FALSE;
if (!is_array($options)) {
$id = $options;
$retid = TRUE;
$options = array();
}
if (!$pages) {
$pages = array();
foreach (entity_load('search_api_page', FALSE, array(
'enabled' => 1,
), TRUE) as $page) {
if (is_string($page->options)) {
$page->options = unserialize($page->options);
}
if (isset($page->ext_search_options) && is_string($page->ext_search_options)) {
$page->ext_search_options = (array) unserialize($page->ext_search_options);
}
$index = search_api_index_load($page->index_id);
$pages[$page->id] = $page;
$pages_by_type[ext_search_page_get_native_type($index->item_type)][$page->id] = $page;
}
}
if ($retid) {
if (isset($pages[$id])) {
return $pages[$id];
}
return NULL;
}
if (isset($options['type'])) {
if (isset($pages_by_type[$options['type']])) {
$res = $pages_by_type[$options['type']];
}
else {
$res = array();
}
}
else {
$res = $pages;
}
if (isset($options['extended']) || isset($options['block'])) {
foreach (array_keys($res) as $id) {
if (isset($options['extended'])) {
if (!isset($res[$id]->ext_search_options['enabled'])) {
$res[$id]->ext_search_options['enabled'] = FALSE;
}
if ($res[$id]->ext_search_options['enabled'] != $options['extended']) {
unset($res[$id]);
}
continue;
}
if (isset($options['block'])) {
if (!isset($res[$id]->ext_search_options['block'])) {
$res[$id]->ext_search_options['block'] = FALSE;
}
if ($res[$id]->ext_search_options['block'] != $options['block']) {
unset($res[$id]);
}
continue;
}
}
}
return $res;
}
/**
* Helper function to build filters http params
* @param $page
* @return array filter values
*/
function ext_search_page_build_filter_values($page, $raw_values, $form = TRUE) {
$filter_values = array();
foreach (ext_search_page_get_filter_widgets($page) as $field => $widget) {
if ($form) {
$f = $widget['get_values'];
$values = $f($field, $widget, $raw_values);
}
else {
$values = isset($raw_values[$field]) ? $raw_values[$field] : NULL;
}
if ($values === NULL) {
unset($filter_values[$field]);
}
elseif ($widget['default'] == $values) {
//default value not needed to be pass
unset($filter_values[$field]);
}
else {
$filter_values[$field] = is_array($values) ? implode('|', $values) : $values;
}
}
return $filter_values;
}
Functions
Name![]() |
Description |
---|---|
ext_search_page_add_filter_widget_condition | Default add condition callback. Add a condition to the search api query reflecting the widget state. |
ext_search_page_add_filter_widget_form | Default add form calback. Modify the form to add the corresponding filter widget. |
ext_search_page_block_info | Implements hook_block_info(). |
ext_search_page_block_view | Implements hook_block_view(). |
ext_search_page_build_filter_values | Helper function to build filters http params |
ext_search_page_cmp_filter | Filter weight comp callback. |
ext_search_page_entity_property_info_alter | Implements hook_entity_property_info_alter() |
ext_search_page_filter_widget_basic_settings_add | Basic callback to add a text input widget setting |
ext_search_page_filter_widget_basic_settings_string_select_alter | Basic callback function to alter the widget |
ext_search_page_filter_widget_basic_settings_submit | Basic callback function to retrieve the settings text input value |
ext_search_page_form_alter | Implements hook_form_alter(). |
ext_search_page_get_available_filters | Get the fields from index which are usable as filter. Fulltext fields are not eligible. |
ext_search_page_get_filter_values | Get filters values from $_GET and from default. |
ext_search_page_get_filter_widgets | Return the chosen widgets for current page. |
ext_search_page_get_filter_widget_values | Default get values callback. Get the value of widget from form. Returns an array because some widget may need complex value. |
ext_search_page_get_index_fields | Get the index fields |
ext_search_page_get_native_type | Map index type to native type. |
ext_search_page_get_widgets_registry | Build and return the widget registry. Allow other module to alter the registry with hook_ext_search_page_widgets_registry_alter(). |
ext_search_page_load_pages | Pages loader. |
ext_search_page_menu | Implements hook_menu(). |
ext_search_page_menu_alter | Implements hook_menu_alter(). |
ext_search_page_permission | Implements hook_permission(). |
ext_search_page_search_execute | Executes a search. |
ext_search_page_search_query | Create the search page query. |
ext_search_page_taxonomy_autocomplete_validate | Form element validate handler for taxonomy term autocomplete element. |
ext_search_page_theme | Implements hook_theme(). |
_ext_search_page_page_mode |