View source
<?php
define('GLOBAL_FILTER_DEF_OPTION_ALL_TEXT', t('All'));
define('GLOBAL_FILTER_VIEWS_COUNTRY_FIELD', 'country');
define('GLOBAL_FILTER_VIEWS_PROXIMITY_FIELD', 'distance');
define('GLOBAL_FILTER_VIEWS_SEARCH_TERMS_FIELD', 'keys');
define('GLOBAL_FILTER_VIEWS_SEARCH_API_FULLTEXT', 'search_api_views_fulltext');
$path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'global_filter');
include_once $path . '/widgets/global_filter.datewidget.inc';
include_once $path . '/widgets/global_filter.linkswidget.inc';
include_once $path . '/widgets/global_filter.proximitywidget.inc';
include_once $path . '/widgets/global_filter.rangewidget.inc';
include_once $path . '/widgets/global_filter.simplewidget.inc';
function global_filter_forms($form_id, $args) {
if (strpos($form_id, GLOBAL_FILTER_BLOCK_ID_PREFIX) === 0) {
$block_number = drupal_substr($form_id, -1);
$form = array(
$form_id => array(
'callback' => 'global_filter_submission_form',
'callback arguments' => array(
$block_number,
),
),
);
return $form;
}
}
function global_filter_submission_form($form, &$form_state, $block_number) {
if (!isset($form_state['language'])) {
$form_state['language'] = LANGUAGE_NONE;
}
foreach (global_filter_get_filters_for_block($block_number) as $key => $filter) {
$form_state['global_filters'][$key]['name'] = $filter['name'];
$form_state['global_filters'][$key]['widget'] = $filter['widget'];
$form_state['global_filters'][$key]['label'] = $filter['label'];
global_filter_create_widget($key, $form, $form_state);
}
global_filter_finalise_form($form, $block_number);
$path = drupal_get_path('module', 'global_filter');
$form['#attached']['css'][] = $path . '/global_filter.css';
$form['#attributes']['class'][] = drupal_html_class('global-filter');
return $form;
}
function global_filter_create_widget($filter_key, &$form, &$form_state) {
$name = $form_state['global_filters'][$filter_key]['name'];
$widget_label = $form_state['global_filters'][$filter_key]['label'];
$option_all_text = global_filter_get_parameter($filter_key, 'option_all_text');
$options = empty($option_all_text) ? array(
'' => GLOBAL_FILTER_DEF_OPTION_ALL_TEXT,
) : ($option_all_text == '<none>' ? array() : array(
'' => $option_all_text,
));
$exceptions = array(
GLOBAL_FILTER_VIEWS_PROXIMITY_FIELD,
GLOBAL_FILTER_VIEWS_SEARCH_TERMS_FIELD,
GLOBAL_FILTER_VIEWS_SEARCH_API_FULLTEXT,
);
if (strpos($name, 'view') === 0) {
$requested_widget = $form_state['global_filters'][$filter_key]['widget'];
if (empty($requested_widget) || $requested_widget == 'default') {
$requested_widget = 'select';
}
$view_name = drupal_substr($name, 5);
global_filter_add_view_results($options, $view_name);
}
elseif (in_array($name, $exceptions) || in_array($name, array_keys(global_filter_get_node_properties()))) {
$requested_widget = $form_state['global_filters'][$filter_key]['widget'];
if ($requested_widget != 'proximity' && $requested_widget != 'range') {
$requested_widget = 'textfield';
}
}
else {
if ($name == GLOBAL_FILTER_VIEWS_COUNTRY_FIELD) {
$requested_widget = 'select';
if (global_filter_get_module_parameter('take_countries_from_location_module', TRUE) && module_exists('location')) {
$countries = array();
$result = db_query('SELECT DISTINCT country FROM {location}');
foreach ($result as $country) {
$countries[$country->country] = location_country_name($country->country);
}
}
else {
include_once DRUPAL_ROOT . '/includes/locale.inc';
$countries = country_get_list();
}
natcasesort($countries);
$options = array_merge($options, $countries);
}
else {
$field = field_info_field($name);
if (!$field) {
if ($name) {
drupal_set_message(t('The field %name used for filter #@filter does not exist. Please re-configure the associated Global Filter block.', array(
'%name' => $name,
'@filter' => $filter_key,
)), 'error');
}
return;
}
$instances = global_filter_get_field_instances($name);
if (empty($instances)) {
global_filter_debug(t('Global filter: no instances found of field %name', array(
'%name' => $name,
)));
return;
}
if (!($requested_widget = $form_state['global_filters'][$filter_key]['widget'])) {
$requested_widget = 'default';
}
foreach ($instances as $instance) {
if ('default_' . $instance['widget']['type'] == $requested_widget) {
break;
}
}
if (strpos($requested_widget, 'default') === 0 || strpos($instance['widget']['type'], 'date') === 0 && $requested_widget != 'textfield') {
$form_state['global_filters'][$filter_key]['widget'] = $instance['widget']['type'];
global_filter_debug(t('Global Filter @name (on %bundle) uses %widget widget', array(
'%bundle' => $instance['bundle'],
'@name' => $name,
'%widget' => $instance['widget']['type'],
)));
if (!empty($widget_label)) {
$instance['label'] = $widget_label == '<none>' ? NULL : $widget_label;
}
global_filter_create_field_instance_widget($option_all_text, $field, $instance, $form, $form_state);
$lang = $form_state['language'];
$form[$name][$lang]['#required'] = FALSE;
if (empty($form[$name][$lang]['#title'])) {
unset($form[$name][$lang]['#title']);
}
foreach (element_children($form[$name][$lang]) as $key0) {
$form[$name][$lang][$key0]['#required'] = FALSE;
if (empty($form[$name][$lang][$key0]['#title'])) {
unset($form[$name][$lang][$key0]['#title']);
}
foreach (element_children($form[$name][$lang][$key0]) as $key) {
$form[$name][$lang][$key0][$key]['#required'] = FALSE;
if (empty($form[$name][$lang][$key0][$key]['#title'])) {
unset($form[$name][$lang][$key0][$key]['#title']);
}
}
}
return;
}
if ($field['type'] == 'taxonomy_term_reference') {
$vocabulary_name = $field['settings']['allowed_values'][0]['vocabulary'];
$show_depth = drupal_substr($requested_widget, -6) == 'select';
_global_filter_add_terms($options, $vocabulary_name, $show_depth);
}
elseif (!empty($field['settings']['allowed_values'])) {
foreach (list_allowed_values($field) as $value => $label) {
$options[$value] = $label;
}
}
}
}
global_filter_debug(t('Global Filter @name uses %widget widget', array(
'@name' => $name,
'%widget' => $requested_widget,
)));
$form_state['global_filters'][$filter_key]['widget'] = $requested_widget;
switch ($requested_widget) {
case 'links':
global_filter_create_links_widget($filter_key, $options, $form, $form_state);
break;
case 'range':
global_filter_create_range_widget($filter_key, $form, $form_state);
break;
case 'proximity':
global_filter_create_proximity_widget($filter_key, $form, $form_state);
break;
default:
global_filter_create_simple_widget($filter_key, $options, $form, $form_state);
}
if (!empty($widget_label) && $widget_label != '<none>') {
$form[$name]['#title'] = check_plain($widget_label);
}
}
function global_filter_create_field_instance_widget($option_all_text, $field, $instance, &$form, &$form_state) {
if (!isset($form['#parents'])) {
$form['#parents'] = array();
}
$instance['widget']['is_global_filter'] = TRUE;
if ($instance['widget']['module'] == 'date') {
$items = global_filter_set_instance_date_widget_value($field, $instance, $form_state);
}
else {
$session_value = global_filter_get_session_value($field['field_name']);
$items = global_filter_set_instance_widget_value($session_value, $field, $form_state);
}
$lang = $form_state['language'];
$form += field_default_form($instance['entity_type'], NULL, $field, $instance, $lang, $items, $form, $form_state, 0);
}
function global_filter_finalise_form(&$form, $block_number) {
$num_filters = 0;
foreach ($form as $key => &$filter_element) {
if (drupal_substr($key, 0, 1) != '#') {
$filter_element['#weight'] = ++$num_filters;
}
}
$submit_required = $button_required = FALSE;
foreach ($filters = global_filter_get_filters_for_block($block_number) as $key => $filter) {
$name = $filter['name'];
$filter_delta = GLOBAL_FILTER_FILTER_KEY_PREFIX . $key;
$form[$name]['#attributes']['class'][] = drupal_html_class("{$filter_delta}-{$name}");
$confirm_question = global_filter_get_parameter($key, 'confirm_question');
$autosubmit = global_filter_get_parameter($key, 'set_on_select');
if ($filter['widget'] != 'links') {
$submit_required = TRUE;
if (!$autosubmit) {
$button_required = TRUE;
}
}
if ($confirm_question || $autosubmit) {
drupal_add_js(array(
$filter_delta => array(
drupal_html_class("{$filter_delta}-{$name}"),
$confirm_question,
$autosubmit,
),
), 'setting');
$form[$name]['#attached']['js'][] = drupal_get_path('module', 'global_filter') . '/js/global_filter_all.js';
}
}
if ($submit_required) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Set'),
'#submit' => array(
'global_filter_set_form_on_session',
),
'#attributes' => array(
'class' => array(
drupal_html_class('global-filter-set-' . ($num_filters > 1 ? 'all' : $filter['widget'])),
),
),
'#weight' => ++$num_filters,
);
if (!$button_required) {
$form['submit']['#attributes']['style'][] = 'display:none';
}
}
}
function global_filter_field_widget_form_alter(&$element, &$form_state, $context) {
if (!isset($context['instance']['widget']['is_global_filter'])) {
return;
}
switch ($context['instance']['widget']['module']) {
case 'date':
global_filter_field_date_widget_form_alter($element, $form_state, $context);
break;
case 'slide_with_style':
global_filter_field_slider_widget_form_alter($element, $form_state, $context);
break;
}
}
function global_filter_add_view_results(&$options, $view_id) {
$view = views_get_view($view_id);
if (!is_object($view)) {
drupal_set_message(t('Global Filter: could not find view: %view.', array(
'%view' => empty($view_id) ? t('no name specified') : $view_id,
)), 'error');
return FALSE;
}
$view
->init_display();
$view
->pre_execute();
$view
->execute();
foreach ($view->result as $row) {
$row_as_array = (array) $row;
foreach ($row_as_array as $fid => $value) {
if ($fid != $view->base_field) {
break;
}
}
$key = isset($row_as_array[$view->base_field]) ? $row_as_array[$view->base_field] : NULL;
$options[empty($key) ? $value : $key] = $value;
}
}
function global_filter_get_field_instances($field_name) {
$instances = array();
foreach (field_info_instances() as $entity_type => $type_bundles) {
foreach ($type_bundles as $bundle => $bundle_instances) {
foreach ($bundle_instances as $f_name => $instance) {
if ($f_name == $field_name) {
$instances[] = $instance;
}
}
}
}
return array_reverse($instances);
}
function global_filter_set_instance_widget_value($session_value, $field, $form_state) {
$name = $field['field_name'];
$lang = $form_state['language'];
$form_input = isset($form_state['input'][$name][$lang]) ? $form_state['input'][$name][$lang] : NULL;
$form_values = isset($form_state['values'][$name][$lang]) ? $form_state['values'][$name][$lang] : NULL;
if (is_array($form_input)) {
$value = $form_input;
}
if (is_array($form_values)) {
$form_values = reset($form_values);
$value = empty($form_values['tid']) ? $form_values['name'] : $form_values['tid'];
}
if (empty($value)) {
$value = $session_value;
}
$items = array();
$key = key($field['columns']);
if (!empty($value) && is_array($value)) {
foreach (global_filter_array_flatten($value) as $value) {
$items[] = array(
$key => $value,
);
}
}
else {
$items[0][$key] = $value;
}
return empty($items) ? array(
0 => array(),
) : $items;
}
function global_filter_set_form_on_session($form, &$form_state) {
foreach ($form_state['global_filters'] as $filter_key => $info) {
$name = $info['name'];
$widget = $info['widget'];
if (strpos($widget, 'date') === 0) {
$form_value = global_filter_extract_date_range($form_state, $filter_key);
}
elseif ($widget == 'range') {
$form_value = global_filter_extract_alphanumeric_range($form_state, $name);
}
elseif ($widget == 'proximity') {
$form_value = global_filter_extract_proximity($form_state);
}
elseif (isset($form_state['values'][$name])) {
$lang = isset($form_state['language']) ? $form_state['language'] : LANGUAGE_NONE;
$form_value = global_filter_extract_values($form_state['values'][$name], $lang);
}
else {
continue;
}
global_filter_set_on_session($name, $form_value);
}
$form_state['rebuild'] = FALSE;
$form_state['no_redirect'] = TRUE;
}
function global_filter_extract_values($form_values, $language = NULL) {
if (!is_array($form_values)) {
return $form_values;
}
if (!isset($language)) {
$language = array_keys($form_values);
$language = reset($language);
if (is_numeric($language)) {
return array_values($form_values);
}
}
if (empty($form_values[$language])) {
return array_values($form_values);
}
$values = array();
foreach ($form_values[$language] as $v) {
$values[] = is_array($v) ? reset($v) : $v;
}
return $values;
}
function _global_filter_add_terms(&$options, $vocabulary_machine_name, $show_depth = TRUE) {
if (!module_exists('taxonomy')) {
drupal_set_message(t('Global Filter: using vocabulary %vocabulary, but Taxonomy module is not enabled.', array(
'%vocabulary' => $vocabulary_machine_name,
)), 'error');
return;
}
if (!empty($vocabulary_machine_name)) {
foreach (taxonomy_get_vocabularies() as $vid => $vocabulary) {
$found = $vocabulary->machine_name == $vocabulary_machine_name;
if ($found) {
break;
}
}
}
if (empty($found)) {
drupal_set_message(t('Global Filter: the vocabulary %vocabulary does not exist.', array(
'%vocabulary' => $vocabulary_machine_name,
)), 'error');
}
else {
foreach (taxonomy_get_tree($vid) as $term) {
$options[$term->tid] = $show_depth ? str_repeat('-', $term->depth) . $term->name : $term->name;
}
}
}
function global_filter_array_flatten($array) {
foreach ($array as $key => $value) {
$array[$key] = (array) $value;
}
return call_user_func_array('array_merge', $array);
}
function global_filter_theme_registry_alter(&$theme_registry) {
$theme_registry['options_none']['function'] = 'global_filter_options_none';
$theme_registry['options_none']['theme_path'] = drupal_get_path('module', 'global_filter');
}
function global_filter_options_none($variables) {
if (!empty($variables['global_filter_context'])) {
$filter_key = global_filter_key_by_name($variables['instance']['field_name']);
$option_all_text = global_filter_get_parameter($filter_key, 'option_all_text');
if (!empty($option_all_text)) {
return $option_all_text == t('<none>') ? '' : check_plain($option_all_text);
}
}
return theme_options_none($variables);
}
function global_filter_options_list($field, $instance) {
$options = (array) module_invoke($field['real_module'], 'options_list', $field, $instance);
return $options;
}