context_condition_path.inc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. /**
  3. * Expose paths as a context condition.
  4. */
  5. class context_condition_path extends context_condition {
  6. /**
  7. * Omit condition values. We will provide a custom input form for our conditions.
  8. */
  9. function condition_values() {
  10. return array();
  11. }
  12. /**
  13. * Condition form.
  14. */
  15. function condition_form($context) {
  16. $form = parent::condition_form($context);
  17. unset($form['#options']);
  18. $form['#type'] = 'textarea';
  19. $form['#default_value'] = implode("\n", $this->fetch_from_context($context, 'values'));
  20. return $form;
  21. }
  22. /**
  23. * Condition form submit handler.
  24. */
  25. function condition_form_submit($values) {
  26. $parsed = array();
  27. $items = explode("\n", $values);
  28. if (!empty($items)) {
  29. foreach ($items as $v) {
  30. $v = trim($v);
  31. if (!empty($v)) {
  32. $parsed[$v] = $v;
  33. }
  34. }
  35. }
  36. return $parsed;
  37. }
  38. /**
  39. * Execute.
  40. */
  41. function execute() {
  42. if ($this->condition_used()) {
  43. // Include both the path alias and normal path for matching.
  44. $current_path = array(drupal_get_path_alias($_GET['q']));
  45. if ($current_path[0] != $_GET['q']) {
  46. $current_path[] = $_GET['q'];
  47. }
  48. foreach ($this->get_contexts() as $context) {
  49. $paths = $this->fetch_from_context($context, 'values');
  50. if ($this->match($current_path, $paths, TRUE)) {
  51. $this->condition_met($context);
  52. }
  53. }
  54. }
  55. }
  56. /**
  57. * Match the subject against a set of regex patterns.
  58. * Similar to drupal_match_path() but also handles negation through the use
  59. * of the ~ character.
  60. *
  61. * @param mixed $subject
  62. * The subject string or an array of strings to be matched.
  63. * @param array $patterns
  64. * An array of patterns. Any patterns that begin with ~ are considered
  65. * negative or excluded conditions.
  66. * @param boolean $path
  67. * Whether the given subject should be matched as a Drupal path. If TRUE,
  68. * '<front>' will be replaced with the site frontpage when matching against
  69. * $patterns.
  70. */
  71. protected function match($subject, $patterns, $path = FALSE) {
  72. static $regexps;
  73. $match = FALSE;
  74. $positives = $negatives = 0;
  75. $subject = !is_array($subject) ? array($subject) : $subject;
  76. foreach ($patterns as $pattern) {
  77. if (strpos($pattern, '~') === 0) {
  78. $negate = TRUE;
  79. $negatives++;
  80. }
  81. else {
  82. $negate = FALSE;
  83. $positives++;
  84. }
  85. $pattern = ltrim($pattern, '~');
  86. if (!isset($regexps[$pattern])) {
  87. if ($path) {
  88. $regexps[$pattern] = '/^(' . preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1' . preg_quote(variable_get('site_frontpage', 'node'), '/') . '\2'), preg_quote($pattern, '/')) . ')$/';
  89. }
  90. else {
  91. $regexps[$pattern] = '/^(' . preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/'), array('|', '.*'), preg_quote($pattern, '/')) . ')$/';
  92. }
  93. }
  94. foreach ($subject as $value) {
  95. if (preg_match($regexps[$pattern], $value)) {
  96. if ($negate) {
  97. return FALSE;
  98. }
  99. $match = TRUE;
  100. }
  101. }
  102. }
  103. // If there are **only** negative conditions and we've gotten this far none
  104. // we actually have a match.
  105. if ($positives === 0 && $negatives) {
  106. return TRUE;
  107. }
  108. return $match;
  109. }
  110. }