views_dependent_filters.module 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. <?php
  2. /**
  3. * @file views_dependent_filters.module
  4. * Provides a Views exposed filter which makes other filters depend on values
  5. * in yet further filters for their visiblity and processing.
  6. * For example: if the 'node type' filter is set to 'article', show a filter for
  7. * a field that is only present on articles.
  8. */
  9. /**
  10. * Implements hook_views_api().
  11. */
  12. function views_dependent_filters_views_api() {
  13. return array(
  14. 'api' => '3.0-alpha1',
  15. 'path' => drupal_get_path('module', 'views_dependent_filters'),
  16. );
  17. }
  18. /**
  19. * After build form processor for the views exposed form.
  20. *
  21. * This is added by the exposed filter handler so that we can add a CTools
  22. * visiblity dependency.
  23. * We don't use Drupal core #states because as far as I can tell they don't
  24. * work here.
  25. * See also merlinofchaos's comment here: http://drupal.org/node/1406470
  26. */
  27. function views_dependent_filters_exposed_form_after_build($form, $form_state) {
  28. // We may have multiple dependency info arrays from more than one copies
  29. // of the views_dependent_filters_handler_filter_dependent handler.
  30. foreach ($form_state['dependent_exposed_filters'] as $dependency_info) {
  31. // Build up the CTools #dependency item to put onto each dependent element.
  32. $form_dependency = array();
  33. foreach ($dependency_info['controllers'] as $filter_id => $controller_values) {
  34. $identifier = $dependency_info['identifiers'][$filter_id];
  35. // Regular form.
  36. $filter_html_id = views_dependent_filters_recreate_html_id($identifier);
  37. $form_dependency['edit-' . $filter_html_id] = $controller_values;
  38. // better_exposed_filters form.
  39. foreach ($controller_values as $value) {
  40. $value = views_dependent_filters_recreate_html_id($value);
  41. $key = 'edit-' . $filter_html_id . '-' . $value;
  42. $form_dependency[$key] = array(TRUE);
  43. }
  44. }
  45. // Set the dependency on each form element as required.
  46. foreach ($dependency_info['dependents'] as $dependent_filter_id) {
  47. $identifier = $dependency_info['identifiers'][$dependent_filter_id];
  48. $form[$identifier]['#process'][] = 'ctools_dependent_process';
  49. if (!isset($form[$identifier]['#dependency'])) {
  50. $form[$identifier]['#dependency'] = array();
  51. }
  52. $form[$identifier]['#dependency'] += $form_dependency;
  53. }
  54. }
  55. return $form;
  56. }
  57. /**
  58. * Convert a string to an HTML id matching one made with drupal_html_id().
  59. *
  60. * We can't simply call drupal_html_id() because that only returns unique
  61. * ids; this is intended for when the ID already exists and we want to recreate
  62. * it from the original input.
  63. */
  64. function views_dependent_filters_recreate_html_id($id) {
  65. $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => ''));
  66. // As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can
  67. // only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"),
  68. // colons (":"), and periods ("."). We strip out any character not in that
  69. // list. Note that the CSS spec doesn't allow colons or periods in identifiers
  70. // (http://www.w3.org/TR/CSS21/syndata.html#characters), so we strip those two
  71. // characters as well.
  72. $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id);
  73. // Removing multiple consecutive hyphens.
  74. $id = preg_replace('/\-+/', '-', $id);
  75. return $id;
  76. }