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 | | } |