diff --git a/ctools_automodal.module b/ctools_automodal.module index e706bc2..df967b2 100644 --- a/ctools_automodal.module +++ b/ctools_automodal.module @@ -16,8 +16,9 @@ function ctools_automodal_module_implements_alter(&$implementations, $hook) { * Implements hook_menu_alter(). */ function ctools_automodal_menu_alter(&$items) { - $modal_paths = array(); + $modal_paths = $modal_regexp_pieces = array(); + $all_paths = array_keys($items); foreach ($items as $path => $item) { if (!empty($item['modal']) && strpos($path, '%ctools_js') === FALSE) { if ($item['page callback'] == 'drupal_get_form') { @@ -33,29 +34,60 @@ function ctools_automodal_menu_alter(&$items) { $items["$path/%ctools_js"]['page arguments'][] = substr_count($path, '/') + 1; $items["$path/%ctools_js"]['type'] = MENU_CALLBACK; } - $modal_paths[] = preg_replace('/%[^\/]*/', '*', $path); + // Convert modal paths to regexp, replacing arguments with wildcards. + $modal_regexp_pieces[] = _ctools_automodal_menu_alter_regex($path); + $modal_paths[] = $path; } } - variable_set('ctools_automodal_paths', $modal_paths); + // Store the regexps matching modal paths in variables for use in + // hook_preprocess_link(). + if (!empty($modal_paths)) { + $modal_regexp = '@^' . implode('|^', $modal_regexp_pieces) . '@'; + // Look for non-modal paths matching our regexp. + $matches = array_map('_ctools_automodal_menu_alter_regex', array_diff(preg_grep($modal_regexp, $all_paths), $modal_paths)); + if (count($matches)) { + // If any are found, store them so we will not erroneously match them in + // hook_preprocess_link(). + $not_modal_regexp = '@^' . implode('|^', $matches) . '@'; + } + else { + $not_modal_regexp = ''; + } + } + else { + $modal_regexp = $not_modal_regexp = ''; + } + + variable_set('ctools_automodal_regexp', $modal_regexp); + variable_set('ctools_automodal_not_regexp', $not_modal_regexp); +} + +/** + * A helper function that matches a path in ctools_automodal_menu_alter(). + */ +function _ctools_automodal_menu_alter_regex($value) { + return preg_replace('/%[^\/]*/', '[^/]+', $value); } /** * Check if an internal Drupal path should be converted to a modal link. */ function ctools_automodal_is_path_modal($path) { - static $modal_paths_regex; - - if (!isset($modal_paths_regex)) { - $modal_paths = variable_get('ctools_automodal_paths', array()); - foreach ($modal_paths as &$modal_path) { - $modal_path = preg_quote($modal_path, '/'); - $modal_path = str_replace('\*', '.*', $modal_path); - } - $modal_paths_regex = '/^(' . implode('|', $modal_paths) . ')$/'; + $modal_regexp = variable_get('ctools_automodal_regexp'); + $not_modal_regexp = variable_get('ctools_automodal_not_regexp'); + if (!$modal_regexp) { + // If there are no paths to match, return here. + return FALSE; } - - return (bool) preg_match($modal_paths_regex, $path); + elseif (!$not_modal_regexp) { + // There are no similar paths to worry about, so just check the path + // against the modal regexp. + return preg_match($modal_regexp, $path); + } + // This path is modal if it matches the modal regexp and does *not* + // match any of the non-modal paths. + return preg_match($modal_regexp, $path) && !preg_match($not_modal_regexp, $path); } /**