2006-01-24 08:18:26 +00:00
< ? php
// $Id$
2006-01-23 07:54:08 +00:00
/**
* @ file
* Functions to handle paths in Drupal , including path aliasing .
*
* These functions are not loaded for cached pages , but modules that need
2009-10-24 05:13:44 +00:00
* to use them in hook_boot () or hook exit () can make them available , by
* executing " drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); " .
2006-01-23 07:54:08 +00:00
*/
/**
* Initialize the $_GET [ 'q' ] variable to the proper normal path .
*/
2009-07-14 10:22:17 +00:00
function drupal_path_initialize () {
2006-01-23 07:54:08 +00:00
if ( ! empty ( $_GET [ 'q' ])) {
$_GET [ 'q' ] = drupal_get_normal_path ( trim ( $_GET [ 'q' ], '/' ));
}
else {
$_GET [ 'q' ] = drupal_get_normal_path ( variable_get ( 'site_frontpage' , 'node' ));
}
}
/**
* Given an alias , return its Drupal system URL if one exists . Given a Drupal
2006-11-26 01:55:37 +00:00
* system URL return one of its aliases if such a one exists . Otherwise ,
* return FALSE .
2006-01-23 07:54:08 +00:00
*
* @ param $action
* One of the following values :
* - wipe : delete the alias cache .
* - alias : return an alias for a given Drupal system path ( if one exists ) .
* - source : return the Drupal system URL for a path alias ( if one exists ) .
* @ param $path
* The path to investigate for corresponding aliases or system URLs .
2007-03-26 01:32:22 +00:00
* @ param $path_language
* Optional language code to search the path with . Defaults to the page language .
* If there ' s no path defined for that language it will search paths without
* language .
2006-01-23 07:54:08 +00:00
*
* @ return
* Either a Drupal system path , an aliased path , or FALSE if no path was
* found .
*/
2009-12-02 19:26:23 +00:00
function drupal_lookup_path ( $action , $path = '' , $path_language = NULL ) {
2007-03-26 01:32:22 +00:00
global $language ;
2009-11-20 06:12:45 +00:00
// Use the advanced drupal_static() pattern, since this is called very often.
2010-01-07 04:54:18 +00:00
static $drupal_static_fast ;
if ( ! isset ( $drupal_static_fast )) {
$drupal_static_fast [ 'cache' ] = & drupal_static ( __FUNCTION__ );
}
$cache = & $drupal_static_fast [ 'cache' ];
2009-11-20 06:12:45 +00:00
if ( ! isset ( $cache )) {
$cache = array (
'map' => array (),
'no_source' => array (),
'whitelist' => NULL ,
'system_paths' => array (),
'no_aliases' => array (),
'first_call' => TRUE ,
);
}
2007-03-26 01:32:22 +00:00
2009-06-01 11:23:27 +00:00
// Retrieve the path alias whitelist.
2009-08-02 06:48:24 +00:00
if ( ! isset ( $cache [ 'whitelist' ])) {
$cache [ 'whitelist' ] = variable_get ( 'path_alias_whitelist' , NULL );
if ( ! isset ( $cache [ 'whitelist' ])) {
$cache [ 'whitelist' ] = drupal_path_alias_whitelist_rebuild ();
2009-06-01 11:23:27 +00:00
}
2008-06-24 22:12:15 +00:00
}
2009-06-01 11:23:27 +00:00
$path_language = $path_language ? $path_language : $language -> language ;
2006-01-23 07:54:08 +00:00
if ( $action == 'wipe' ) {
2009-08-02 06:48:24 +00:00
$cache = array ();
$cache [ 'whitelist' ] = drupal_path_alias_whitelist_rebuild ();
2006-01-23 07:54:08 +00:00
}
2009-08-02 06:48:24 +00:00
elseif ( $cache [ 'whitelist' ] && $path != '' ) {
2006-01-23 07:54:08 +00:00
if ( $action == 'alias' ) {
2009-05-16 19:07:02 +00:00
// During the first call to drupal_lookup_path() per language, load the
// expected system paths for the page from cache.
2009-08-02 06:48:24 +00:00
if ( ! empty ( $cache [ 'first_call' ])) {
$cache [ 'first_call' ] = FALSE ;
2009-06-01 11:23:27 +00:00
2009-08-02 06:48:24 +00:00
$cache [ 'map' ][ $path_language ] = array ();
2009-05-16 19:07:02 +00:00
// Load system paths from cache.
$cid = current_path ();
2009-08-02 06:48:24 +00:00
if ( $cached = cache_get ( $cid , 'cache_path' )) {
$cache [ 'system_paths' ] = $cached -> data ;
2009-05-16 19:07:02 +00:00
// Now fetch the aliases corresponding to these system paths.
// We order by ASC and overwrite array keys to ensure the correct
// alias is used when there are multiple aliases per path.
2009-12-02 19:26:23 +00:00
$cache [ 'map' ][ $path_language ] = db_query ( " SELECT source, alias FROM { url_alias} WHERE source IN (:system) AND language IN (:language, :language_none) ORDER BY language ASC, pid ASC " , array (
2009-08-02 06:48:24 +00:00
':system' => $cache [ 'system_paths' ],
2009-12-02 19:26:23 +00:00
':language' => $path_language ,
':language_none' => LANGUAGE_NONE ,
2009-05-16 19:07:02 +00:00
)) -> fetchAllKeyed ();
// Keep a record of paths with no alias to avoid querying twice.
2009-08-02 06:48:24 +00:00
$cache [ 'no_aliases' ][ $path_language ] = array_flip ( array_diff_key ( $cache [ 'system_paths' ], array_keys ( $cache [ 'map' ][ $path_language ])));
2009-05-16 19:07:02 +00:00
}
}
// If the alias has already been loaded, return it.
2009-08-02 06:48:24 +00:00
if ( isset ( $cache [ 'map' ][ $path_language ][ $path ])) {
return $cache [ 'map' ][ $path_language ][ $path ];
2006-01-23 07:54:08 +00:00
}
2009-06-01 11:23:27 +00:00
// Check the path whitelist, if the top_level part before the first /
// is not in the list, then there is no need to do anything further,
// it is not in the database.
2009-08-02 06:48:24 +00:00
elseif ( ! isset ( $cache [ 'whitelist' ][ strtok ( $path , '/' )])) {
2009-06-01 11:23:27 +00:00
return FALSE ;
}
2009-05-16 19:07:02 +00:00
// For system paths which were not cached, query aliases individually.
2009-08-02 06:48:24 +00:00
else if ( ! isset ( $cache [ 'no_aliases' ][ $path_language ][ $path ])) {
2009-05-16 19:07:02 +00:00
// Get the most fitting result falling back with alias without language
2009-12-02 19:26:23 +00:00
$alias = db_query ( " SELECT alias FROM { url_alias} WHERE source = :source AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC " , array (
2009-10-15 17:53:34 +00:00
':source' => $path ,
2009-12-02 19:26:23 +00:00
':language' => $path_language ,
':language_none' => LANGUAGE_NONE ,
2009-05-16 19:07:02 +00:00
)) -> fetchField ();
2009-08-02 06:48:24 +00:00
$cache [ 'map' ][ $path_language ][ $path ] = $alias ;
2009-05-16 19:07:02 +00:00
return $alias ;
}
2006-01-23 07:54:08 +00:00
}
2009-10-15 17:53:34 +00:00
// Check $no_source for this $path in case we've already determined that there
2006-11-26 01:55:37 +00:00
// isn't a path that has this alias
2009-10-15 17:53:34 +00:00
elseif ( $action == 'source' && ! isset ( $cache [ 'no_source' ][ $path_language ][ $path ])) {
2006-11-26 01:55:37 +00:00
// Look for the value $path within the cached $map
2009-10-15 17:53:34 +00:00
$source = '' ;
if ( ! isset ( $cache [ 'map' ][ $path_language ]) || ! ( $source = array_search ( $path , $cache [ 'map' ][ $path_language ]))) {
2007-03-26 01:32:22 +00:00
// Get the most fitting result falling back with alias without language
2009-12-02 19:26:23 +00:00
if ( $source = db_query ( " SELECT source FROM { url_alias} WHERE alias = :alias AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC " , array (
2009-10-15 17:53:34 +00:00
':alias' => $path ,
2009-12-02 19:26:23 +00:00
':language' => $path_language ,
':language_none' => LANGUAGE_NONE ))
2009-01-03 13:17:25 +00:00
-> fetchField ()) {
2009-10-15 17:53:34 +00:00
$cache [ 'map' ][ $path_language ][ $source ] = $path ;
2006-11-26 01:55:37 +00:00
}
else {
// We can't record anything into $map because we do not have a valid
// index and there is no need because we have not learned anything
2009-10-15 17:53:34 +00:00
// about any Drupal path. Thus cache to $no_source.
$cache [ 'no_source' ][ $path_language ][ $path ] = TRUE ;
2006-01-23 07:54:08 +00:00
}
}
2009-10-15 17:53:34 +00:00
return $source ;
2006-01-23 07:54:08 +00:00
}
}
return FALSE ;
}
2009-05-16 19:07:02 +00:00
/**
* Cache system paths for a page .
*
* Cache an array of the system paths available on each page . We assume
* that aiases will be needed for the majority of these paths during
* subsequent requests , and load them in a single query during
* drupal_lookup_path () .
*/
function drupal_cache_system_paths () {
// Check if the system paths for this page were loaded from cache in this
// request to avoid writing to cache on every request.
2009-08-02 06:48:24 +00:00
$cache = & drupal_static ( 'drupal_lookup_path' , array ());
2009-12-07 06:07:19 +00:00
if ( empty ( $cache [ 'system_paths' ]) && ! empty ( $cache [ 'map' ])) {
2009-05-16 19:07:02 +00:00
// Generate a cache ID (cid) specifically for this page.
$cid = current_path ();
2009-08-02 06:48:24 +00:00
// The static $map array used by drupal_lookup_path() includes all
// system paths for the page request.
if ( $paths = current ( $cache [ 'map' ])) {
2009-05-16 19:07:02 +00:00
$data = array_keys ( $paths );
$expire = REQUEST_TIME + ( 60 * 60 * 24 );
cache_set ( $cid , $data , 'cache_path' , $expire );
}
}
}
2006-01-23 07:54:08 +00:00
/**
* Given an internal Drupal path , return the alias set by the administrator .
*
2009-05-07 15:49:57 +00:00
* If no path is provided , the function will return the alias of the current
* page .
*
2006-01-23 07:54:08 +00:00
* @ param $path
* An internal Drupal path .
2007-03-26 01:32:22 +00:00
* @ param $path_language
* An optional language code to look up the path in .
2006-01-23 07:54:08 +00:00
*
* @ return
* An aliased path if one was found , or the original path if no alias was
* found .
*/
2009-12-02 19:26:23 +00:00
function drupal_get_path_alias ( $path = NULL , $path_language = NULL ) {
2009-05-07 15:49:57 +00:00
// If no path is specified, use the current page's path.
if ( $path == NULL ) {
$path = $_GET [ 'q' ];
}
2006-01-23 07:54:08 +00:00
$result = $path ;
2007-03-26 01:32:22 +00:00
if ( $alias = drupal_lookup_path ( 'alias' , $path , $path_language )) {
2006-01-23 07:54:08 +00:00
$result = $alias ;
}
return $result ;
}
/**
* Given a path alias , return the internal path it represents .
*
* @ param $path
* A Drupal path alias .
2007-03-26 01:32:22 +00:00
* @ param $path_language
* An optional language code to look up the path in .
2006-01-23 07:54:08 +00:00
*
* @ return
* The internal path represented by the alias , or the original alias if no
* internal path was found .
*/
2009-12-02 19:26:23 +00:00
function drupal_get_normal_path ( $path , $path_language = NULL ) {
2009-10-24 05:13:44 +00:00
$original_path = $path ;
// Lookup the path alias first.
2009-10-15 17:53:34 +00:00
if ( $source = drupal_lookup_path ( 'source' , $path , $path_language )) {
2009-10-24 05:13:44 +00:00
$path = $source ;
2006-01-23 07:54:08 +00:00
}
2009-10-24 05:13:44 +00:00
// Allow other modules to alter the inbound URL. We cannot use drupal_alter()
// here because we need to run hook_url_inbound_alter() in the reverse order
// of hook_url_outbound_alter().
foreach ( array_reverse ( module_implements ( 'url_inbound_alter' )) as $module ) {
$function = $module . '_url_inbound_alter' ;
$function ( $path , $original_path , $path_language );
2006-01-23 07:54:08 +00:00
}
2009-10-24 05:13:44 +00:00
return $path ;
2006-01-23 07:54:08 +00:00
}
/**
* Return a component of the current Drupal path .
*
2009-07-20 18:51:36 +00:00
* When viewing a page at the path " admin/structure/types " , for example , arg ( 0 )
2009-01-04 20:04:32 +00:00
* returns " admin " , arg ( 1 ) returns " content " , and arg ( 2 ) returns " types " .
2006-01-23 07:54:08 +00:00
*
* Avoid use of this function where possible , as resulting code is hard to read .
2009-01-04 20:04:32 +00:00
* In menu callback functions , attempt to use named arguments . See the explanation
* in menu . inc for how to construct callbacks that take arguments . When attempting
* to use this function to load an element from the current path , e . g . loading the
* node on a node page , please use menu_get_object () instead .
2006-01-23 07:54:08 +00:00
*
* @ param $index
* The index of the component , where each component is separated by a '/'
* ( forward - slash ), and where the first component has an index of 0 ( zero ) .
2009-07-27 19:28:38 +00:00
* @ param $path
* A path to break into components . Defaults to the path of the current page .
2006-01-23 07:54:08 +00:00
*
* @ return
2007-11-04 16:42:45 +00:00
* The component specified by $index , or NULL if the specified component was
2006-01-23 07:54:08 +00:00
* not found .
*/
2007-01-24 14:48:36 +00:00
function arg ( $index = NULL , $path = NULL ) {
2009-11-20 06:12:45 +00:00
// Even though $arguments doesn't need to be resettable for any functional
// reasons (the result of explode() does not depend on any run-time
// information), it should be resettable anyway in case a module needs to
// free up the memory used by it.
// Use the advanced drupal_static() pattern, since this is called very often.
2010-01-07 04:54:18 +00:00
static $drupal_static_fast ;
if ( ! isset ( $drupal_static_fast )) {
$drupal_static_fast [ 'arguments' ] = & drupal_static ( __FUNCTION__ );
}
$arguments = & $drupal_static_fast [ 'arguments' ];
2006-01-23 07:54:08 +00:00
2007-01-24 14:48:36 +00:00
if ( ! isset ( $path )) {
$path = $_GET [ 'q' ];
2006-01-23 07:54:08 +00:00
}
2007-01-24 14:48:36 +00:00
if ( ! isset ( $arguments [ $path ])) {
$arguments [ $path ] = explode ( '/' , $path );
}
if ( ! isset ( $index )) {
return $arguments [ $path ];
}
if ( isset ( $arguments [ $path ][ $index ])) {
return $arguments [ $path ][ $index ];
2006-01-23 07:54:08 +00:00
}
}
/**
* Get the title of the current page , for display on the page and in the title bar .
*
* @ return
* The current page ' s title .
*/
function drupal_get_title () {
$title = drupal_set_title ();
2009-05-26 09:12:29 +00:00
// During a bootstrap, menu.inc is not included and thus we cannot provide a title.
2006-01-23 07:54:08 +00:00
if ( ! isset ( $title ) && function_exists ( 'menu_get_active_title' )) {
$title = check_plain ( menu_get_active_title ());
}
return $title ;
}
/**
* Set the title of the current page , for display on the page and in the title bar .
*
* @ param $title
* Optional string value to assign to the page title ; or if set to NULL
* ( default ), leaves the current title unchanged .
2008-10-14 11:01:08 +00:00
* @ param $output
* Optional flag - normally should be left as CHECK_PLAIN . Only set to
* PASS_THROUGH if you have already removed any possibly dangerous code
* from $title using a function like check_plain () or filter_xss () . With this
* flag the string will be passed through unchanged .
2006-01-23 07:54:08 +00:00
*
* @ return
* The updated title of the current page .
*/
2008-10-14 11:01:08 +00:00
function drupal_set_title ( $title = NULL , $output = CHECK_PLAIN ) {
2009-04-03 17:41:32 +00:00
$stored_title = & drupal_static ( __FUNCTION__ );
2006-01-23 07:54:08 +00:00
if ( isset ( $title )) {
2008-10-14 11:01:08 +00:00
$stored_title = ( $output == PASS_THROUGH ) ? $title : check_plain ( $title );
2006-01-23 07:54:08 +00:00
}
2008-12-09 07:16:10 +00:00
2006-01-23 07:54:08 +00:00
return $stored_title ;
}
2006-04-24 19:25:37 +00:00
/**
* Check if the current page is the front page .
*
* @ return
* Boolean value : TRUE if the current page is the front page ; FALSE if otherwise .
*/
function drupal_is_front_page () {
2009-11-20 06:12:45 +00:00
// Use the advanced drupal_static() pattern, since this is called very often.
2010-01-07 04:54:18 +00:00
static $drupal_static_fast ;
if ( ! isset ( $drupal_static_fast )) {
$drupal_static_fast [ 'is_front_page' ] = & drupal_static ( __FUNCTION__ );
}
$is_front_page = & $drupal_static_fast [ 'is_front_page' ];
2008-12-09 07:16:10 +00:00
if ( ! isset ( $is_front_page )) {
2009-07-14 10:22:17 +00:00
// As drupal_path_initialize updates $_GET['q'] with the 'site_frontpage' path,
2008-12-09 07:16:10 +00:00
// we can check it against the 'site_frontpage' variable.
2009-12-01 18:39:56 +00:00
$is_front_page = ( $_GET [ 'q' ] == variable_get ( 'site_frontpage' , 'node' ));
2008-12-09 07:16:10 +00:00
}
return $is_front_page ;
2006-04-24 19:25:37 +00:00
}
2007-10-16 14:10:33 +00:00
/**
* Check if a path matches any pattern in a set of patterns .
*
* @ param $path
* The path to match .
* @ param $patterns
* String containing a set of patterns separated by \n , \r or \r\n .
*
* @ return
* Boolean value : TRUE if the path matches a pattern , FALSE otherwise .
*/
function drupal_match_path ( $path , $patterns ) {
2009-04-03 17:41:32 +00:00
$regexps = & drupal_static ( __FUNCTION__ );
2007-10-17 12:34:16 +00:00
2007-10-16 14:10:33 +00:00
if ( ! isset ( $regexps [ $patterns ])) {
2008-04-14 17:48:46 +00:00
$regexps [ $patterns ] = '/^(' . preg_replace ( array ( '/(\r\n?|\n)/' , '/\\\\\*/' , '/(^|\|)\\\\<front\\\\>($|\|)/' ), array ( '|' , '.*' , '\1' . preg_quote ( variable_get ( 'site_frontpage' , 'node' ), '/' ) . '\2' ), preg_quote ( $patterns , '/' )) . ')$/' ;
2007-10-16 14:10:33 +00:00
}
2008-06-18 03:36:24 +00:00
return ( bool ) preg_match ( $regexps [ $patterns ], $path );
2007-10-16 14:10:33 +00:00
}
2009-05-06 15:51:36 +00:00
/**
* Return the current URL path of the page being viewed .
*
* Examples :
* - http :// example . com / node / 306 returns " node/306 " .
* - http :// example . com / drupalfolder / node / 306 returns " node/306 " while
* base_path () returns " /drupalfolder/ " .
* - http :// example . com / path / alias ( which is a path alias for node / 306 ) returns
* " node/306 " as opposed to the path alias .
*
* This function is not available in hook_boot () so use $_GET [ 'q' ] instead .
* However , be careful when doing that because in the case of Example #3
* $_GET [ 'q' ] will contain " path/alias " . If " node/306 " is needed , calling
2009-10-24 05:13:44 +00:00
* drupal_bootstrap ( DRUPAL_BOOTSTRAP_FULL ) makes this function available .
2009-05-06 15:51:36 +00:00
*
* @ return
* The current Drupal URL path .
*/
function current_path () {
return $_GET [ 'q' ];
}
2009-06-01 11:23:27 +00:00
/**
* Rebuild the path alias white list .
*
* @ return
* An array containing a white list of path aliases .
*/
function drupal_path_alias_whitelist_rebuild () {
// For each alias in the database, get the top level component of the system
// path it corresponds to. This is the portion of the path before the first /
// if present, otherwise the whole path itself.
$whitelist = array ();
2009-10-15 17:53:34 +00:00
$result = db_query ( " SELECT SUBSTRING_INDEX(source, '/', 1) AS path FROM { url_alias} GROUP BY path " );
2009-06-01 11:23:27 +00:00
foreach ( $result as $row ) {
$whitelist [ $row -> path ] = TRUE ;
}
variable_set ( 'path_alias_whitelist' , $whitelist );
return $whitelist ;
}
2009-10-22 01:27:18 +00:00
/**
* Fetch a specific URL alias from the database .
*
* @ param $conditions
* A string representing the source , a number representing the pid , or an
* array of query conditions .
*
* @ return
* FALSE if no alias was found or an associative array containing the
* following keys :
* - source : The internal system path .
* - alias : The URL alias .
* - pid : Unique path alias identifier .
* - language : The language of the alias .
*/
function path_load ( $conditions ) {
if ( is_numeric ( $conditions )) {
$conditions = array ( 'pid' => $conditions );
}
elseif ( is_string ( $conditions )) {
$conditions = array ( 'source' => $conditions );
}
elseif ( ! is_array ( $conditions )) {
return FALSE ;
}
$select = db_select ( 'url_alias' );
foreach ( $conditions as $field => $value ) {
$select -> condition ( $field , $value );
}
return $select
-> fields ( 'url_alias' )
-> execute ()
-> fetchAssoc ();
}
/**
* Save a path alias to the database .
*
* @ param $path
* An associative array containing the following keys :
* - source : The internal system path .
* - alias : The URL alias .
* - pid : ( optional ) Unique path alias identifier .
* - language : ( optional ) The language of the alias .
*/
function path_save ( & $path ) {
2009-12-02 19:26:23 +00:00
$path += array ( 'pid' => NULL , 'language' => LANGUAGE_NONE );
2009-10-22 01:27:18 +00:00
// Insert or update the alias.
$status = drupal_write_record ( 'url_alias' , $path , ( ! empty ( $path [ 'pid' ]) ? 'pid' : NULL ));
// Verify that a record was written.
if ( isset ( $status ) && $status ) {
if ( $status === SAVED_NEW ) {
module_invoke_all ( 'path_insert' , $path );
}
else {
module_invoke_all ( 'path_update' , $path );
}
drupal_clear_path_cache ();
}
}
/**
* Delete a URL alias .
*
* @ param $criteria
* A number representing the pid or an array of criteria .
*/
function path_delete ( $criteria ) {
if ( ! is_array ( $criteria )) {
$criteria = array ( 'pid' => $criteria );
}
$path = path_load ( $criteria );
$query = db_delete ( 'url_alias' );
foreach ( $criteria as $field => $value ) {
$query -> condition ( $field , $value );
}
$query -> execute ();
module_invoke_all ( 'path_delete' , $path );
drupal_clear_path_cache ();
}
#610234 by Gábor Hojtsy, ksenzee, cwgordon7, David_Rothstein, seutje, marcvangend, sun, JoshuaRogers, markus_petrux, Bojhan, Rob Loach, Everett Zufelt, drifter, markboulton, leisareichelt, et al: Added Overlay module to core, which shows administrative pages in a JS overlay, retaining context on the front-end site.
2009-12-02 07:28:22 +00:00
/**
* Determine whether a path is in the administrative section of the site .
*
* By default , paths are considered to be non - administrative . If a path does not
* match any of the patterns in path_get_admin_paths (), or if it matches both
* administrative and non - administrative patterns , it is considered
* non - administrative .
*
* @ param $path
* A Drupal path .
* @ return
* TRUE if the path is administrative , FALSE otherwise .
*
* @ see path_get_admin_paths ()
* @ see hook_admin_paths ()
* @ see hook_admin_paths_alter ()
*/
function path_is_admin ( $path ) {
$path_map = & drupal_static ( __FUNCTION__ );
if ( ! isset ( $path_map [ 'admin' ][ $path ])) {
$patterns = path_get_admin_paths ();
$path_map [ 'admin' ][ $path ] = drupal_match_path ( $path , $patterns [ 'admin' ]);
$path_map [ 'non_admin' ][ $path ] = drupal_match_path ( $path , $patterns [ 'non_admin' ]);
}
return $path_map [ 'admin' ][ $path ] && ! $path_map [ 'non_admin' ][ $path ];
}
/**
* Get a list of administrative and non - administrative paths .
*
* @ return array
* An associative array containing the following keys :
* 'admin' : An array of administrative paths and regular expressions
* in a format suitable for drupal_match_path () .
* 'non_admin' : An array of non - administrative paths and regular expressions .
*
* @ see hook_admin_paths ()
* @ see hook_admin_paths_alter ()
*/
function path_get_admin_paths () {
$patterns = & drupal_static ( __FUNCTION__ );
if ( ! isset ( $patterns )) {
$paths = module_invoke_all ( 'admin_paths' );
drupal_alter ( 'admin_paths' , $paths );
// Combine all admin paths into one array, and likewise for non-admin paths,
// for easier handling.
$patterns = array ();
$patterns [ 'admin' ] = array ();
$patterns [ 'non_admin' ] = array ();
foreach ( $paths as $path => $enabled ) {
if ( $enabled ) {
$patterns [ 'admin' ][] = $path ;
}
else {
$patterns [ 'non_admin' ][] = $path ;
}
}
$patterns [ 'admin' ] = implode ( " \n " , $patterns [ 'admin' ]);
$patterns [ 'non_admin' ] = implode ( " \n " , $patterns [ 'non_admin' ]);
}
return $patterns ;
}
2009-12-17 13:10:19 +00:00
/**
* Checks a path exists and the current user has access to it .
*
* @ param $path
* The path to check .
* @ param $dynamic_allowed
* Whether paths with menu wildcards ( like user /% ) should be allowed .
*
* @ return
* TRUE if it is a valid path AND the current user has access permission ,
* FALSE otherwise .
*/
function drupal_valid_path ( $path , $dynamic_allowed = FALSE ) {
global $menu_admin ;
// We indicate that a menu administrator is running the menu access check.
$menu_admin = TRUE ;
if ( $path == '<front>' || url_is_external ( $path )) {
$item = array ( 'access' => TRUE );
}
elseif ( $dynamic_allowed && preg_match ( '/\/\%/' , $path )) {
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
if ( $item = db_query ( " SELECT * FROM { menu_router} where path = :path " , array ( ':path' => $path )) -> fetchAssoc ()) {
$item [ 'link_path' ] = $form_item [ 'link_path' ];
$item [ 'link_title' ] = $form_item [ 'link_title' ];
$item [ 'external' ] = FALSE ;
$item [ 'options' ] = '' ;
_menu_link_translate ( $item );
}
}
else {
$item = menu_get_item ( $path );
}
$menu_admin = FALSE ;
return $item && $item [ 'access' ];
}