| Line # | Frequency | Source Line | | 1 | | <?php |
| 2 | | // $Id: path.inc,v 1.20 2008/02/18 16:49:23 dries Exp $ |
| 3 | | |
| 4 | | /** |
| 5 | | * @file |
| 6 | | * Functions to handle paths in Drupal, including path aliasing. |
| 7 | | * |
| 8 | | * These functions are not loaded for cached pages, but modules that need |
| 9 | | * to use them in hook_init() or hook exit() can make them available, by |
| 10 | | * executing "drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);". |
| 11 | | */ |
| 12 | | |
| 13 | | /** |
| 14 | | * Initialize the $_GET['q'] variable to the proper normal path. |
| 15 | | */ |
| 16 | | function drupal_init_path() { |
| 17 | | if (!empty($_GET['q'])) { |
| 18 | | $_GET['q'] = drupal_get_normal_path(trim($_GET['q'], '/')); |
| 19 | | } |
| 20 | | else { |
| 21 | | $_GET['q'] = drupal_get_normal_path(variable_get('site_frontpage', 'node')); |
| 22 | | } |
| 23 | | } |
| 24 | | |
| 25 | | /** |
| 26 | | * Given an alias, return its Drupal system URL if one exists. Given a Drupal |
| 27 | | * system URL return one of its aliases if such a one exists. Otherwise, |
| 28 | | * return FALSE. |
| 29 | | * |
| 30 | | * @param $action |
| 31 | | * One of the following values: |
| 32 | | * - wipe: delete the alias cache. |
| 33 | | * - alias: return an alias for a given Drupal system path (if one exists). |
| 34 | | * - source: return the Drupal system URL for a path alias (if one exists). |
| 35 | | * @param $path |
| 36 | | * The path to investigate for corresponding aliases or system URLs. |
| 37 | | * @param $path_language |
| 38 | | * Optional language code to search the path with. Defaults to the page language. |
| 39 | | * If there's no path defined for that language it will search paths without |
| 40 | | * language. |
| 41 | | * |
| 42 | | * @return |
| 43 | | * Either a Drupal system path, an aliased path, or FALSE if no path was |
| 44 | | * found. |
| 45 | | */ |
| 46 | | function drupal_lookup_path($action, $path = '', $path_language = '') { |
| 47 | 1 | global $language; |
| 48 | | // $map is an array with language keys, holding arrays of Drupal paths to alias relations |
| 49 | | static $map = array(), $no_src = array(); |
| 50 | | |
| 51 | 1 | $path_language = $path_language ? $path_language : $language->language; |
| 52 | | |
| 53 | 1 | if ($action == 'wipe') { |
| 54 | | $map = array(); |
| 55 | | $no_src = array(); |
| 56 | | } |
| 57 | 1 | elseif (module_exists('path') && $path != '') { |
| 58 | | if ($action == 'alias') { |
| 59 | | if (isset($map[$path_language][$path])) { |
| 60 | | return $map[$path_language][$path]; |
| 61 | | } |
| 62 | | // Get the most fitting result falling back with alias without language |
| 63 | | $alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language)); |
| 64 | | $map[$path_language][$path] = $alias; |
| 65 | | return $alias; |
| 66 | | } |
| 67 | | // Check $no_src for this $path in case we've already determined that there |
| 68 | | // isn't a path that has this alias |
| 69 | | elseif ($action == 'source' && !isset($no_src[$path_language][$path])) { |
| 70 | | // Look for the value $path within the cached $map |
| 71 | | $src = ''; |
| 72 | | if (!isset($map[$path_language]) || !($src = array_search($path, $map[$path_language]))) { |
| 73 | | // Get the most fitting result falling back with alias without language |
| 74 | | if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC", $path, $path_language))) { |
| 75 | | $map[$path_language][$src] = $path; |
| 76 | | } |
| 77 | | else { |
| 78 | | // We can't record anything into $map because we do not have a valid |
| 79 | | // index and there is no need because we have not learned anything |
| 80 | | // about any Drupal path. Thus cache to $no_src. |
| 81 | | $no_src[$path_language][$path] = TRUE; |
| 82 | | } |
| 83 | | } |
| 84 | | return $src; |
| 85 | | } |
| 86 | | } |
| 87 | | |
| 88 | 1 | return FALSE; |
| 89 | | } |
| 90 | | |
| 91 | | /** |
| 92 | | * Given an internal Drupal path, return the alias set by the administrator. |
| 93 | | * |
| 94 | | * @param $path |
| 95 | | * An internal Drupal path. |
| 96 | | * @param $path_language |
| 97 | | * An optional language code to look up the path in. |
| 98 | | * |
| 99 | | * @return |
| 100 | | * An aliased path if one was found, or the original path if no alias was |
| 101 | | * found. |
| 102 | | */ |
| 103 | | function drupal_get_path_alias($path, $path_language = '') { |
| 104 | 1 | $result = $path; |
| 105 | 1 | if ($alias = drupal_lookup_path('alias', $path, $path_language)) { |
| 106 | | $result = $alias; |
| 107 | | } |
| 108 | 1 | return $result; |
| 109 | | } |
| 110 | | |
| 111 | | /** |
| 112 | | * Given a path alias, return the internal path it represents. |
| 113 | | * |
| 114 | | * @param $path |
| 115 | | * A Drupal path alias. |
| 116 | | * @param $path_language |
| 117 | | * An optional language code to look up the path in. |
| 118 | | * |
| 119 | | * @return |
| 120 | | * The internal path represented by the alias, or the original alias if no |
| 121 | | * internal path was found. |
| 122 | | */ |
| 123 | | function drupal_get_normal_path($path, $path_language = '') { |
| 124 | | $result = $path; |
| 125 | | if ($src = drupal_lookup_path('source', $path, $path_language)) { |
| 126 | | $result = $src; |
| 127 | | } |
| 128 | | if (function_exists('custom_url_rewrite_inbound')) { |
| 129 | | // Modules may alter the inbound request path by reference. |
| 130 | | custom_url_rewrite_inbound($result, $path, $path_language); |
| 131 | | } |
| 132 | | return $result; |
| 133 | | } |
| 134 | | |
| 135 | | /** |
| 136 | | * Return a component of the current Drupal path. |
| 137 | | * |
| 138 | | * When viewing a page at the path "admin/content/types", for example, arg(0) |
| 139 | | * would return "admin", arg(1) would return "content", and arg(2) would return |
| 140 | | * "types". |
| 141 | | * |
| 142 | | * Avoid use of this function where possible, as resulting code is hard to read. |
| 143 | | * Instead, attempt to use named arguments in menu callback functions. See the |
| 144 | | * explanation in menu.inc for how to construct callbacks that take arguments. |
| 145 | | * |
| 146 | | * @param $index |
| 147 | | * The index of the component, where each component is separated by a '/' |
| 148 | | * (forward-slash), and where the first component has an index of 0 (zero). |
| 149 | | * |
| 150 | | * @return |
| 151 | | * The component specified by $index, or NULL if the specified component was |
| 152 | | * not found. |
| 153 | | */ |
| 154 | | function arg($index = NULL, $path = NULL) { |
| 155 | | static $arguments; |
| 156 | | |
| 157 | | if (!isset($path)) { |
| 158 | | $path = $_GET['q']; |
| 159 | | } |
| 160 | | if (!isset($arguments[$path])) { |
| 161 | | $arguments[$path] = explode('/', $path); |
| 162 | | } |
| 163 | | if (!isset($index)) { |
| 164 | | return $arguments[$path]; |
| 165 | | } |
| 166 | | if (isset($arguments[$path][$index])) { |
| 167 | | return $arguments[$path][$index]; |
| 168 | | } |
| 169 | | } |
| 170 | | |
| 171 | | /** |
| 172 | | * Get the title of the current page, for display on the page and in the title bar. |
| 173 | | * |
| 174 | | * @return |
| 175 | | * The current page's title. |
| 176 | | */ |
| 177 | | function drupal_get_title() { |
| 178 | | $title = drupal_set_title(); |
| 179 | | |
| 180 | | // during a bootstrap, menu.inc is not included and thus we cannot provide a title |
| 181 | | if (!isset($title) && function_exists('menu_get_active_title')) { |
| 182 | | $title = check_plain(menu_get_active_title()); |
| 183 | | } |
| 184 | | |
| 185 | | return $title; |
| 186 | | } |
| 187 | | |
| 188 | | /** |
| 189 | | * Set the title of the current page, for display on the page and in the title bar. |
| 190 | | * |
| 191 | | * @param $title |
| 192 | | * Optional string value to assign to the page title; or if set to NULL |
| 193 | | * (default), leaves the current title unchanged. |
| 194 | | * |
| 195 | | * @return |
| 196 | | * The updated title of the current page. |
| 197 | | */ |
| 198 | | function drupal_set_title($title = NULL) { |
| 199 | | static $stored_title; |
| 200 | | |
| 201 | | if (isset($title)) { |
| 202 | | $stored_title = $title; |
| 203 | | } |
| 204 | | return $stored_title; |
| 205 | | } |
| 206 | | |
| 207 | | /** |
| 208 | | * Check if the current page is the front page. |
| 209 | | * |
| 210 | | * @return |
| 211 | | * Boolean value: TRUE if the current page is the front page; FALSE if otherwise. |
| 212 | | */ |
| 213 | | function drupal_is_front_page() { |
| 214 | | // As drupal_init_path updates $_GET['q'] with the 'site_frontpage' path, |
| 215 | | // we can check it against the 'site_frontpage' variable. |
| 216 | | return $_GET['q'] == drupal_get_normal_path(variable_get('site_frontpage', 'node')); |
| 217 | | } |
| 218 | | |
| 219 | | /** |
| 220 | | * Check if a path matches any pattern in a set of patterns. |
| 221 | | * |
| 222 | | * @param $path |
| 223 | | * The path to match. |
| 224 | | * @param $patterns |
| 225 | | * String containing a set of patterns separated by \n, \r or \r\n. |
| 226 | | * |
| 227 | | * @return |
| 228 | | * Boolean value: TRUE if the path matches a pattern, FALSE otherwise. |
| 229 | | */ |
| 230 | | function drupal_match_path($path, $patterns) { |
| 231 | | static $regexps; |
| 232 | | |
| 233 | | if (!isset($regexps[$patterns])) { |
| 234 | | $regexps[$patterns] = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($patterns, '/')) .')$/'; |
| 235 | | } |
| 236 | | return preg_match($regexps[$patterns], $path); |
| 237 | | } |