Révision b0dc3a2e
Ajouté par Julien Enselme il y a plus de 7 ans
drupal7/includes/bootstrap.inc | ||
---|---|---|
8 | 8 |
/** |
9 | 9 |
* The current system version. |
10 | 10 |
*/ |
11 |
define('VERSION', '7.44');
|
|
11 |
define('VERSION', '7.52');
|
|
12 | 12 |
|
13 | 13 |
/** |
14 | 14 |
* Core API compatibility. |
... | ... | |
828 | 828 |
* @param $filename |
829 | 829 |
* The filename of the item if it is to be set explicitly rather |
830 | 830 |
* than by consulting the database. |
831 |
* @param bool $trigger_error |
|
832 |
* Whether to trigger an error when a file is missing or has unexpectedly |
|
833 |
* moved. This defaults to TRUE, but can be set to FALSE by calling code that |
|
834 |
* merely wants to check whether an item exists in the filesystem. |
|
831 | 835 |
* |
832 | 836 |
* @return |
833 | 837 |
* The filename of the requested item or NULL if the item is not found. |
834 | 838 |
*/ |
835 |
function drupal_get_filename($type, $name, $filename = NULL) { |
|
839 |
function drupal_get_filename($type, $name, $filename = NULL, $trigger_error = TRUE) { |
|
840 |
// The $files static variable will hold the locations of all requested files. |
|
841 |
// We can be sure that any file listed in this static variable actually |
|
842 |
// exists as all additions have gone through a file_exists() check. |
|
836 | 843 |
// The location of files will not change during the request, so do not use |
837 | 844 |
// drupal_static(). |
838 |
static $files = array(), $dirs = array();
|
|
845 |
static $files = array(); |
|
839 | 846 |
|
840 | 847 |
// Profiles are a special case: they have a fixed location and naming. |
841 | 848 |
if ($type == 'profile') { |
... | ... | |
847 | 854 |
} |
848 | 855 |
|
849 | 856 |
if (!empty($filename) && file_exists($filename)) { |
857 |
// Prime the static cache with the provided filename. |
|
850 | 858 |
$files[$type][$name] = $filename; |
851 | 859 |
} |
852 | 860 |
elseif (isset($files[$type][$name])) { |
853 |
// nothing |
|
861 |
// This item had already been found earlier in the request, either through |
|
862 |
// priming of the static cache (for example, in system_list()), through a |
|
863 |
// lookup in the {system} table, or through a file scan (cached or not). Do |
|
864 |
// nothing. |
|
854 | 865 |
} |
855 |
// Verify that we have an active database connection, before querying |
|
856 |
// the database. This is required because this function is called both |
|
857 |
// before we have a database connection (i.e. during installation) and |
|
858 |
// when a database connection fails. |
|
859 | 866 |
else { |
867 |
// Look for the filename listed in the {system} table. Verify that we have |
|
868 |
// an active database connection before doing so, since this function is |
|
869 |
// called both before we have a database connection (i.e. during |
|
870 |
// installation) and when a database connection fails. |
|
871 |
$database_unavailable = TRUE; |
|
860 | 872 |
try { |
861 | 873 |
if (function_exists('db_query')) { |
862 | 874 |
$file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField(); |
863 | 875 |
if ($file !== FALSE && file_exists(DRUPAL_ROOT . '/' . $file)) { |
864 | 876 |
$files[$type][$name] = $file; |
865 | 877 |
} |
878 |
$database_unavailable = FALSE; |
|
866 | 879 |
} |
867 | 880 |
} |
868 | 881 |
catch (Exception $e) { |
869 | 882 |
// The database table may not exist because Drupal is not yet installed, |
870 |
// or the database might be down. We have a fallback for this case so we |
|
871 |
// hide the error completely. |
|
883 |
// the database might be down, or we may have done a non-database cache |
|
884 |
// flush while $conf['page_cache_without_database'] = TRUE and |
|
885 |
// $conf['page_cache_invoke_hooks'] = TRUE. We have a fallback for these |
|
886 |
// cases so we hide the error completely. |
|
872 | 887 |
} |
873 |
// Fallback to searching the filesystem if the database could not find the |
|
874 |
// file or the file returned by the database is not found.
|
|
888 |
// Fall back to searching the filesystem if the database could not find the
|
|
889 |
// file or the file does not exist at the path returned by the database.
|
|
875 | 890 |
if (!isset($files[$type][$name])) { |
876 |
// We have a consistent directory naming: modules, themes... |
|
877 |
$dir = $type . 's'; |
|
878 |
if ($type == 'theme_engine') { |
|
879 |
$dir = 'themes/engines'; |
|
880 |
$extension = 'engine'; |
|
881 |
} |
|
882 |
elseif ($type == 'theme') { |
|
883 |
$extension = 'info'; |
|
884 |
} |
|
885 |
else { |
|
886 |
$extension = $type; |
|
887 |
} |
|
891 |
$files[$type][$name] = _drupal_get_filename_fallback($type, $name, $trigger_error, $database_unavailable); |
|
892 |
} |
|
893 |
} |
|
888 | 894 |
|
889 |
if (!isset($dirs[$dir][$extension])) { |
|
890 |
$dirs[$dir][$extension] = TRUE; |
|
891 |
if (!function_exists('drupal_system_listing')) { |
|
892 |
require_once DRUPAL_ROOT . '/includes/common.inc'; |
|
893 |
} |
|
894 |
// Scan the appropriate directories for all files with the requested |
|
895 |
// extension, not just the file we are currently looking for. This |
|
896 |
// prevents unnecessary scans from being repeated when this function is |
|
897 |
// called more than once in the same page request. |
|
898 |
$matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0); |
|
899 |
foreach ($matches as $matched_name => $file) { |
|
900 |
$files[$type][$matched_name] = $file->uri; |
|
895 |
if (isset($files[$type][$name])) { |
|
896 |
return $files[$type][$name]; |
|
897 |
} |
|
898 |
} |
|
899 |
|
|
900 |
/** |
|
901 |
* Performs a cached file system scan as a fallback when searching for a file. |
|
902 |
* |
|
903 |
* This function looks for the requested file by triggering a file scan, |
|
904 |
* caching the new location if the file has moved and caching the miss |
|
905 |
* if the file is missing. If a file had been marked as missing in a previous |
|
906 |
* file scan, or if it has been marked as moved and is still in the last known |
|
907 |
* location, no new file scan will be performed. |
|
908 |
* |
|
909 |
* @param string $type |
|
910 |
* The type of the item (theme, theme_engine, module, profile). |
|
911 |
* @param string $name |
|
912 |
* The name of the item for which the filename is requested. |
|
913 |
* @param bool $trigger_error |
|
914 |
* Whether to trigger an error when a file is missing or has unexpectedly |
|
915 |
* moved. |
|
916 |
* @param bool $database_unavailable |
|
917 |
* Whether this function is being called because the Drupal database could |
|
918 |
* not be queried for the file's location. |
|
919 |
* |
|
920 |
* @return |
|
921 |
* The filename of the requested item or NULL if the item is not found. |
|
922 |
* |
|
923 |
* @see drupal_get_filename() |
|
924 |
*/ |
|
925 |
function _drupal_get_filename_fallback($type, $name, $trigger_error, $database_unavailable) { |
|
926 |
$file_scans = &_drupal_file_scan_cache(); |
|
927 |
$filename = NULL; |
|
928 |
|
|
929 |
// If the cache indicates that the item is missing, or we can verify that the |
|
930 |
// item exists in the location the cache says it exists in, use that. |
|
931 |
if (isset($file_scans[$type][$name]) && ($file_scans[$type][$name] === FALSE || file_exists($file_scans[$type][$name]))) { |
|
932 |
$filename = $file_scans[$type][$name]; |
|
933 |
} |
|
934 |
// Otherwise, perform a new file scan to find the item. |
|
935 |
else { |
|
936 |
$filename = _drupal_get_filename_perform_file_scan($type, $name); |
|
937 |
// Update the static cache, and mark the persistent cache for updating at |
|
938 |
// the end of the page request. See drupal_file_scan_write_cache(). |
|
939 |
$file_scans[$type][$name] = $filename; |
|
940 |
$file_scans['#write_cache'] = TRUE; |
|
941 |
} |
|
942 |
|
|
943 |
// If requested, trigger a user-level warning about the missing or |
|
944 |
// unexpectedly moved file. If the database was unavailable, do not trigger a |
|
945 |
// warning in the latter case, though, since if the {system} table could not |
|
946 |
// be queried there is no way to know if the location found here was |
|
947 |
// "unexpected" or not. |
|
948 |
if ($trigger_error) { |
|
949 |
$error_type = $filename === FALSE ? 'missing' : 'moved'; |
|
950 |
if ($error_type == 'missing' || !$database_unavailable) { |
|
951 |
_drupal_get_filename_fallback_trigger_error($type, $name, $error_type); |
|
952 |
} |
|
953 |
} |
|
954 |
|
|
955 |
// The cache stores FALSE for files that aren't found (to be able to |
|
956 |
// distinguish them from files that have not yet been searched for), but |
|
957 |
// drupal_get_filename() expects NULL for these instead, so convert to NULL |
|
958 |
// before returning. |
|
959 |
if ($filename === FALSE) { |
|
960 |
$filename = NULL; |
|
961 |
} |
|
962 |
return $filename; |
|
963 |
} |
|
964 |
|
|
965 |
/** |
|
966 |
* Returns the current list of cached file system scan results. |
|
967 |
* |
|
968 |
* @return |
|
969 |
* An associative array tracking the most recent file scan results for all |
|
970 |
* files that have had scans performed. The keys are the type and name of the |
|
971 |
* item that was searched for, and the values can be either: |
|
972 |
* - Boolean FALSE if the item was not found in the file system. |
|
973 |
* - A string pointing to the location where the item was found. |
|
974 |
*/ |
|
975 |
function &_drupal_file_scan_cache() { |
|
976 |
$file_scans = &drupal_static(__FUNCTION__, array()); |
|
977 |
|
|
978 |
// The file scan results are stored in a persistent cache (in addition to the |
|
979 |
// static cache) but because this function can be called before the |
|
980 |
// persistent cache is available, we must merge any items that were found |
|
981 |
// earlier in the page request into the results from the persistent cache. |
|
982 |
if (!isset($file_scans['#cache_merge_done'])) { |
|
983 |
try { |
|
984 |
if (function_exists('cache_get')) { |
|
985 |
$cache = cache_get('_drupal_file_scan_cache', 'cache_bootstrap'); |
|
986 |
if (!empty($cache->data)) { |
|
987 |
// File scan results from the current request should take precedence |
|
988 |
// over the results from the persistent cache, since they are newer. |
|
989 |
$file_scans = drupal_array_merge_deep($cache->data, $file_scans); |
|
901 | 990 |
} |
991 |
// Set a flag to indicate that the persistent cache does not need to be |
|
992 |
// merged again. |
|
993 |
$file_scans['#cache_merge_done'] = TRUE; |
|
902 | 994 |
} |
903 | 995 |
} |
996 |
catch (Exception $e) { |
|
997 |
// Hide the error. |
|
998 |
} |
|
904 | 999 |
} |
905 | 1000 |
|
906 |
if (isset($files[$type][$name])) { |
|
907 |
return $files[$type][$name]; |
|
1001 |
return $file_scans; |
|
1002 |
} |
|
1003 |
|
|
1004 |
/** |
|
1005 |
* Performs a file system scan to search for a system resource. |
|
1006 |
* |
|
1007 |
* @param $type |
|
1008 |
* The type of the item (theme, theme_engine, module, profile). |
|
1009 |
* @param $name |
|
1010 |
* The name of the item for which the filename is requested. |
|
1011 |
* |
|
1012 |
* @return |
|
1013 |
* The filename of the requested item or FALSE if the item is not found. |
|
1014 |
* |
|
1015 |
* @see drupal_get_filename() |
|
1016 |
* @see _drupal_get_filename_fallback() |
|
1017 |
*/ |
|
1018 |
function _drupal_get_filename_perform_file_scan($type, $name) { |
|
1019 |
// The location of files will not change during the request, so do not use |
|
1020 |
// drupal_static(). |
|
1021 |
static $dirs = array(), $files = array(); |
|
1022 |
|
|
1023 |
// We have a consistent directory naming: modules, themes... |
|
1024 |
$dir = $type . 's'; |
|
1025 |
if ($type == 'theme_engine') { |
|
1026 |
$dir = 'themes/engines'; |
|
1027 |
$extension = 'engine'; |
|
1028 |
} |
|
1029 |
elseif ($type == 'theme') { |
|
1030 |
$extension = 'info'; |
|
1031 |
} |
|
1032 |
else { |
|
1033 |
$extension = $type; |
|
1034 |
} |
|
1035 |
|
|
1036 |
// Check if we had already scanned this directory/extension combination. |
|
1037 |
if (!isset($dirs[$dir][$extension])) { |
|
1038 |
// Log that we have now scanned this directory/extension combination |
|
1039 |
// into a static variable so as to prevent unnecessary file scans. |
|
1040 |
$dirs[$dir][$extension] = TRUE; |
|
1041 |
if (!function_exists('drupal_system_listing')) { |
|
1042 |
require_once DRUPAL_ROOT . '/includes/common.inc'; |
|
1043 |
} |
|
1044 |
// Scan the appropriate directories for all files with the requested |
|
1045 |
// extension, not just the file we are currently looking for. This |
|
1046 |
// prevents unnecessary scans from being repeated when this function is |
|
1047 |
// called more than once in the same page request. |
|
1048 |
$matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0); |
|
1049 |
foreach ($matches as $matched_name => $file) { |
|
1050 |
// Log the locations found in the file scan into a static variable. |
|
1051 |
$files[$type][$matched_name] = $file->uri; |
|
1052 |
} |
|
1053 |
} |
|
1054 |
|
|
1055 |
// Return the results of the file system scan, or FALSE to indicate the file |
|
1056 |
// was not found. |
|
1057 |
return isset($files[$type][$name]) ? $files[$type][$name] : FALSE; |
|
1058 |
} |
|
1059 |
|
|
1060 |
/** |
|
1061 |
* Triggers a user-level warning for missing or unexpectedly moved files. |
|
1062 |
* |
|
1063 |
* @param $type |
|
1064 |
* The type of the item (theme, theme_engine, module, profile). |
|
1065 |
* @param $name |
|
1066 |
* The name of the item for which the filename is requested. |
|
1067 |
* @param $error_type |
|
1068 |
* The type of the error ('missing' or 'moved'). |
|
1069 |
* |
|
1070 |
* @see drupal_get_filename() |
|
1071 |
* @see _drupal_get_filename_fallback() |
|
1072 |
*/ |
|
1073 |
function _drupal_get_filename_fallback_trigger_error($type, $name, $error_type) { |
|
1074 |
// Hide messages due to known bugs that will appear on a lot of sites. |
|
1075 |
// @todo Remove this in https://www.drupal.org/node/2383823 |
|
1076 |
if (empty($name)) { |
|
1077 |
return; |
|
1078 |
} |
|
1079 |
|
|
1080 |
// Make sure we only show any missing or moved file errors only once per |
|
1081 |
// request. |
|
1082 |
static $errors_triggered = array(); |
|
1083 |
if (empty($errors_triggered[$type][$name][$error_type])) { |
|
1084 |
// Use _drupal_trigger_error_with_delayed_logging() here since these are |
|
1085 |
// triggered during low-level operations that cannot necessarily be |
|
1086 |
// interrupted by a watchdog() call. |
|
1087 |
if ($error_type == 'missing') { |
|
1088 |
_drupal_trigger_error_with_delayed_logging(format_string('The following @type is missing from the file system: %name. For information about how to fix this, see <a href="@documentation">the documentation page</a>.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); |
|
1089 |
} |
|
1090 |
elseif ($error_type == 'moved') { |
|
1091 |
_drupal_trigger_error_with_delayed_logging(format_string('The following @type has moved within the file system: %name. In order to fix this, clear caches or put the @type back in its original location. For more information, see <a href="@documentation">the documentation page</a>.', array('@type' => $type, '%name' => $name, '@documentation' => 'https://www.drupal.org/node/2487215')), E_USER_WARNING); |
|
1092 |
} |
|
1093 |
$errors_triggered[$type][$name][$error_type] = TRUE; |
|
1094 |
} |
|
1095 |
} |
|
1096 |
|
|
1097 |
/** |
|
1098 |
* Invokes trigger_error() with logging delayed until the end of the request. |
|
1099 |
* |
|
1100 |
* This is an alternative to PHP's trigger_error() function which can be used |
|
1101 |
* during low-level Drupal core operations that need to avoid being interrupted |
|
1102 |
* by a watchdog() call. |
|
1103 |
* |
|
1104 |
* Normally, Drupal's error handler calls watchdog() in response to a |
|
1105 |
* trigger_error() call. However, this invokes hook_watchdog() which can run |
|
1106 |
* arbitrary code. If the trigger_error() happens in the middle of an |
|
1107 |
* operation such as a rebuild operation which should not be interrupted by |
|
1108 |
* arbitrary code, that could potentially break or trigger the rebuild again. |
|
1109 |
* This function protects against that by delaying the watchdog() call until |
|
1110 |
* the end of the current page request. |
|
1111 |
* |
|
1112 |
* This is an internal function which should only be called by low-level Drupal |
|
1113 |
* core functions. It may be removed in a future Drupal 7 release. |
|
1114 |
* |
|
1115 |
* @param string $error_msg |
|
1116 |
* The error message to trigger. As with trigger_error() itself, this is |
|
1117 |
* limited to 1024 bytes; additional characters beyond that will be removed. |
|
1118 |
* @param int $error_type |
|
1119 |
* (optional) The type of error. This should be one of the E_USER family of |
|
1120 |
* constants. As with trigger_error() itself, this defaults to E_USER_NOTICE |
|
1121 |
* if not provided. |
|
1122 |
* |
|
1123 |
* @see _drupal_log_error() |
|
1124 |
*/ |
|
1125 |
function _drupal_trigger_error_with_delayed_logging($error_msg, $error_type = E_USER_NOTICE) { |
|
1126 |
$delay_logging = &drupal_static(__FUNCTION__, FALSE); |
|
1127 |
$delay_logging = TRUE; |
|
1128 |
trigger_error($error_msg, $error_type); |
|
1129 |
$delay_logging = FALSE; |
|
1130 |
} |
|
1131 |
|
|
1132 |
/** |
|
1133 |
* Writes the file scan cache to the persistent cache. |
|
1134 |
* |
|
1135 |
* This cache stores all files marked as missing or moved after a file scan |
|
1136 |
* to prevent unnecessary file scans in subsequent requests. This cache is |
|
1137 |
* cleared in system_list_reset() (i.e. after a module/theme rebuild). |
|
1138 |
*/ |
|
1139 |
function drupal_file_scan_write_cache() { |
|
1140 |
// Only write to the persistent cache if requested, and if we know that any |
|
1141 |
// data previously in the cache was successfully loaded and merged in by |
|
1142 |
// _drupal_file_scan_cache(). |
|
1143 |
$file_scans = &_drupal_file_scan_cache(); |
|
1144 |
if (isset($file_scans['#write_cache']) && isset($file_scans['#cache_merge_done'])) { |
|
1145 |
unset($file_scans['#write_cache']); |
|
1146 |
cache_set('_drupal_file_scan_cache', $file_scans, 'cache_bootstrap'); |
|
908 | 1147 |
} |
909 | 1148 |
} |
910 | 1149 |
|
... | ... | |
1261 | 1500 |
|
1262 | 1501 |
$default_headers = array( |
1263 | 1502 |
'Expires' => 'Sun, 19 Nov 1978 05:00:00 GMT', |
1264 |
'Cache-Control' => 'no-cache, must-revalidate, post-check=0, pre-check=0',
|
|
1503 |
'Cache-Control' => 'no-cache, must-revalidate', |
|
1265 | 1504 |
// Prevent browsers from sniffing a response and picking a MIME type |
1266 | 1505 |
// different from the declared content-type, since that can lead to |
1267 | 1506 |
// XSS and other vulnerabilities. |
... | ... | |
1439 | 1678 |
* available to code that needs localization. See st() and get_t() for |
1440 | 1679 |
* alternatives. |
1441 | 1680 |
* |
1681 |
* @section sec_context String context |
|
1682 |
* Matching source strings are normally only translated once, and the same |
|
1683 |
* translation is used everywhere that has a matching string. However, in some |
|
1684 |
* cases, a certain English source string needs to have multiple translations. |
|
1685 |
* One example of this is the string "May", which could be used as either a |
|
1686 |
* full month name or a 3-letter abbreviated month. In other languages where |
|
1687 |
* the month name for May has more than 3 letters, you would need to provide |
|
1688 |
* two different translations (one for the full name and one abbreviated), and |
|
1689 |
* the correct form would need to be chosen, depending on how "May" is being |
|
1690 |
* used. To facilitate this, the "May" string should be provided with two |
|
1691 |
* different contexts in the $options parameter when calling t(). For example: |
|
1692 |
* @code |
|
1693 |
* t('May', array(), array('context' => 'Long month name') |
|
1694 |
* t('May', array(), array('context' => 'Abbreviated month name') |
|
1695 |
* @endcode |
|
1696 |
* See https://localize.drupal.org/node/2109 for more information. |
|
1697 |
* |
|
1442 | 1698 |
* @param $string |
1443 | 1699 |
* A string containing the English string to translate. |
1444 | 1700 |
* @param $args |
... | ... | |
1449 | 1705 |
* An associative array of additional options, with the following elements: |
1450 | 1706 |
* - 'langcode' (defaults to the current language): The language code to |
1451 | 1707 |
* translate to a language other than what is used to display the page. |
1452 |
* - 'context' (defaults to the empty context): The context the source string |
|
1453 |
* belongs to. |
|
1708 |
* - 'context' (defaults to the empty context): A string giving the context |
|
1709 |
* that the source string belongs to. See @ref sec_context above for more |
|
1710 |
* information. |
|
1454 | 1711 |
* |
1455 | 1712 |
* @return |
1456 | 1713 |
* The translated string. |
... | ... | |
2945 | 3202 |
// Eliminate all trusted IPs. |
2946 | 3203 |
$untrusted = array_diff($forwarded, $reverse_proxy_addresses); |
2947 | 3204 |
|
2948 |
// The right-most IP is the most specific we can trust. |
|
2949 |
$ip_address = array_pop($untrusted); |
|
3205 |
if (!empty($untrusted)) { |
|
3206 |
// The right-most IP is the most specific we can trust. |
|
3207 |
$ip_address = array_pop($untrusted); |
|
3208 |
} |
|
3209 |
else { |
|
3210 |
// All IP addresses in the forwarded array are configured proxy IPs |
|
3211 |
// (and thus trusted). We take the leftmost IP. |
|
3212 |
$ip_address = array_shift($forwarded); |
|
3213 |
} |
|
2950 | 3214 |
} |
2951 | 3215 |
} |
2952 | 3216 |
} |
... | ... | |
3187 | 3451 |
$cache_key = $type[0] . $name; |
3188 | 3452 |
if (isset($lookup_cache[$cache_key])) { |
3189 | 3453 |
if ($lookup_cache[$cache_key]) { |
3190 |
require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
|
|
3454 |
include_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
|
|
3191 | 3455 |
} |
3192 | 3456 |
return (bool) $lookup_cache[$cache_key]; |
3193 | 3457 |
} |
... | ... | |
3212 | 3476 |
$lookup_cache[$cache_key] = $file; |
3213 | 3477 |
|
3214 | 3478 |
if ($file) { |
3215 |
require_once DRUPAL_ROOT . '/' . $file;
|
|
3479 |
include_once DRUPAL_ROOT . '/' . $file;
|
|
3216 | 3480 |
return TRUE; |
3217 | 3481 |
} |
3218 | 3482 |
else { |
Formats disponibles : Unified diff
Update to Drupal 7.52