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