| 1 |
<?php |
<?php |
| 2 |
// $Id: bootstrap.inc,v 1.319 2009/11/02 03:12:05 webchick Exp $ |
// $Id: bootstrap.inc,v 1.320 2009/11/02 03:46:43 webchick Exp $ |
| 3 |
|
|
| 4 |
/** |
/** |
| 5 |
* @file |
* @file |
| 782 |
* from a form submission, the contents of a shopping cart, or other user- |
* from a form submission, the contents of a shopping cart, or other user- |
| 783 |
* specific content that should not be cached and displayed to other users. |
* specific content that should not be cached and displayed to other users. |
| 784 |
* |
* |
| 785 |
|
* @param $check_only |
| 786 |
|
* (optional) Set to TRUE to only return whether a previous call found a |
| 787 |
|
* cache entry. |
| 788 |
|
* |
| 789 |
* @return |
* @return |
| 790 |
* The cache object, if the page was found in the cache, NULL otherwise. |
* The cache object, if the page was found in the cache, NULL otherwise. |
| 791 |
*/ |
*/ |
| 792 |
function drupal_page_get_cache() { |
function drupal_page_get_cache($check_only = FALSE) { |
| 793 |
global $base_root; |
global $base_root; |
| 794 |
|
static $cache_hit = FALSE; |
| 795 |
|
|
| 796 |
|
if ($check_only) { |
| 797 |
|
return $cache_hit; |
| 798 |
|
} |
| 799 |
|
|
| 800 |
if (drupal_page_is_cacheable()) { |
if (drupal_page_is_cacheable()) { |
| 801 |
return cache_get($base_root . request_uri(), 'cache_page'); |
$cache = cache_get($base_root . request_uri(), 'cache_page'); |
| 802 |
|
if ($cache !== FALSE) { |
| 803 |
|
$cache_hit = TRUE; |
| 804 |
|
} |
| 805 |
|
return $cache; |
| 806 |
} |
} |
| 807 |
} |
} |
| 808 |
|
|
| 810 |
* Determine the cacheability of the current page. |
* Determine the cacheability of the current page. |
| 811 |
* |
* |
| 812 |
* @param $allow_caching |
* @param $allow_caching |
| 813 |
* Set to FALSE if you want to prevent this page to get cached. |
* Set to FALSE if you want to prevent this page to get cached. |
| 814 |
|
* |
| 815 |
* @return |
* @return |
| 816 |
* TRUE if the current page can be cached, FALSE otherwise. |
* TRUE if the current page can be cached, FALSE otherwise. |
| 817 |
*/ |
*/ |
| 818 |
function drupal_page_is_cacheable($allow_caching = NULL) { |
function drupal_page_is_cacheable($allow_caching = NULL) { |
| 819 |
$allow_caching_static = &drupal_static(__FUNCTION__, TRUE); |
$allow_caching_static = &drupal_static(__FUNCTION__, TRUE); |
| 1461 |
// phase. |
// phase. |
| 1462 |
while ($phases && $phase > $completed_phase && $final_phase > $completed_phase) { |
while ($phases && $phase > $completed_phase && $final_phase > $completed_phase) { |
| 1463 |
$current_phase = array_shift($phases); |
$current_phase = array_shift($phases); |
| 1464 |
_drupal_bootstrap($current_phase); |
switch ($current_phase) { |
| 1465 |
|
case DRUPAL_BOOTSTRAP_CONFIGURATION: |
| 1466 |
|
_drupal_bootstrap_configuration(); |
| 1467 |
|
break; |
| 1468 |
|
|
| 1469 |
|
case DRUPAL_BOOTSTRAP_PAGE_CACHE: |
| 1470 |
|
_drupal_bootstrap_page_cache(); |
| 1471 |
|
break; |
| 1472 |
|
|
| 1473 |
|
case DRUPAL_BOOTSTRAP_DATABASE: |
| 1474 |
|
_drupal_bootstrap_database(); |
| 1475 |
|
break; |
| 1476 |
|
|
| 1477 |
|
case DRUPAL_BOOTSTRAP_VARIABLES: |
| 1478 |
|
_drupal_bootstrap_variables(); |
| 1479 |
|
break; |
| 1480 |
|
|
| 1481 |
|
case DRUPAL_BOOTSTRAP_SESSION: |
| 1482 |
|
require_once DRUPAL_ROOT . '/' . variable_get('session_inc', 'includes/session.inc'); |
| 1483 |
|
drupal_session_initialize(); |
| 1484 |
|
break; |
| 1485 |
|
|
| 1486 |
|
case DRUPAL_BOOTSTRAP_PAGE_HEADER: |
| 1487 |
|
_drupal_bootstrap_page_header(); |
| 1488 |
|
break; |
| 1489 |
|
|
| 1490 |
|
case DRUPAL_BOOTSTRAP_LANGUAGE: |
| 1491 |
|
drupal_language_initialize(); |
| 1492 |
|
break; |
| 1493 |
|
|
| 1494 |
|
case DRUPAL_BOOTSTRAP_FULL: |
| 1495 |
|
require_once DRUPAL_ROOT . '/includes/common.inc'; |
| 1496 |
|
_drupal_bootstrap_full(); |
| 1497 |
|
break; |
| 1498 |
|
} |
| 1499 |
// This function is reentrant. Only update the completed phase when the |
// This function is reentrant. Only update the completed phase when the |
| 1500 |
// current call actually resulted in a progress in the bootstrap process. |
// current call actually resulted in a progress in the bootstrap process. |
| 1501 |
if ($current_phase > $completed_phase) { |
if ($current_phase > $completed_phase) { |
| 1507 |
} |
} |
| 1508 |
|
|
| 1509 |
/** |
/** |
| 1510 |
* Return the current bootstrap phase for this Drupal process. The |
* Bootstrap configuration: Setup script environment and load settings.php. |
|
* current phase is the one most recently completed by |
|
|
* drupal_bootstrap(). |
|
|
* |
|
|
* @see drupal_bootstrap |
|
| 1511 |
*/ |
*/ |
| 1512 |
function drupal_get_bootstrap_phase() { |
function _drupal_bootstrap_configuration() { |
| 1513 |
return drupal_bootstrap(); |
drupal_environment_initialize(); |
| 1514 |
|
// Start a page timer: |
| 1515 |
|
timer_start('page'); |
| 1516 |
|
// Initialize the configuration, including variables from settings.php. |
| 1517 |
|
drupal_settings_initialize(); |
| 1518 |
} |
} |
| 1519 |
|
|
| 1520 |
function _drupal_bootstrap($phase) { |
/** |
| 1521 |
global $conf, $user; |
* Bootstrap page cache: Try to serve a page from cache. |
| 1522 |
static $cache; |
*/ |
| 1523 |
|
function _drupal_bootstrap_page_cache() { |
| 1524 |
switch ($phase) { |
global $user; |
| 1525 |
|
|
| 1526 |
case DRUPAL_BOOTSTRAP_CONFIGURATION: |
// Allow specifying special cache handlers in settings.php, like |
| 1527 |
drupal_environment_initialize(); |
// using memcached or files for storing cache information. |
| 1528 |
// Start a page timer: |
require_once DRUPAL_ROOT . '/' . variable_get('cache_inc', 'includes/cache.inc'); |
| 1529 |
timer_start('page'); |
// Check for a cache mode force from settings.php. |
| 1530 |
// Initialize the configuration, including variables from settings.php. |
if (variable_get('page_cache_without_database')) { |
| 1531 |
drupal_settings_initialize(); |
$cache_mode = CACHE_NORMAL; |
| 1532 |
break; |
} |
| 1533 |
|
else { |
| 1534 |
case DRUPAL_BOOTSTRAP_PAGE_CACHE: |
drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE); |
| 1535 |
// Allow specifying special cache handlers in settings.php, like |
$cache_mode = variable_get('cache'); |
| 1536 |
// using memcached or files for storing cache information. |
} |
| 1537 |
require_once DRUPAL_ROOT . '/' . variable_get('cache_inc', 'includes/cache.inc'); |
drupal_block_denied(ip_address()); |
| 1538 |
// Check for a cache mode force from settings.php. |
// If there is no session cookie and cache is enabled (or forced), try |
| 1539 |
if (variable_get('page_cache_without_database')) { |
// to serve a cached page. |
| 1540 |
$cache_mode = CACHE_NORMAL; |
if (!isset($_COOKIE[session_name()]) && $cache_mode == CACHE_NORMAL) { |
| 1541 |
} |
// Make sure there is a user object because it's timestamp will be |
| 1542 |
else { |
// checked, hook_boot might check for anonymous user etc. |
| 1543 |
drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE); |
$user = drupal_anonymous_user(); |
| 1544 |
$cache_mode = variable_get('cache'); |
// Get the page from the cache. |
| 1545 |
} |
$cache = drupal_page_get_cache(); |
| 1546 |
drupal_block_denied(ip_address()); |
// If there is a cached page, display it. |
| 1547 |
// If there is no session cookie and cache is enabled (or forced), try |
if (is_object($cache)) { |
| 1548 |
// to serve a cached page. |
// If the skipping of the bootstrap hooks is not enforced, call |
| 1549 |
if (!isset($_COOKIE[session_name()]) && $cache_mode == CACHE_NORMAL) { |
// hook_boot. |
| 1550 |
// Make sure there is a user object because it's timestamp will be |
if (variable_get('page_cache_invoke_hooks', TRUE)) { |
| 1551 |
// checked, hook_boot might check for anonymous user etc. |
bootstrap_invoke_all('boot'); |
| 1552 |
$user = drupal_anonymous_user(); |
} |
| 1553 |
// Get the page from the cache. |
header('X-Drupal-Cache: HIT'); |
| 1554 |
$cache = drupal_page_get_cache(); |
drupal_serve_page_from_cache($cache); |
| 1555 |
// If there is a cached page, display it. |
// If the skipping of the bootstrap hooks is not enforced, call |
| 1556 |
if (is_object($cache)) { |
// hook_exit. |
| 1557 |
// If the skipping of the bootstrap hooks is not enforced, call |
if (variable_get('page_cache_invoke_hooks', TRUE)) { |
| 1558 |
// hook_boot. |
bootstrap_invoke_all('exit'); |
|
if (variable_get('page_cache_invoke_hooks', TRUE)) { |
|
|
bootstrap_invoke_all('boot'); |
|
|
} |
|
|
header('X-Drupal-Cache: HIT'); |
|
|
drupal_serve_page_from_cache($cache); |
|
|
// If the skipping of the bootstrap hooks is not enforced, call |
|
|
// hook_exit. |
|
|
if (variable_get('page_cache_invoke_hooks', TRUE)) { |
|
|
bootstrap_invoke_all('exit'); |
|
|
} |
|
|
// We are done. |
|
|
exit; |
|
|
} |
|
| 1559 |
} |
} |
| 1560 |
break; |
// We are done. |
| 1561 |
|
exit; |
| 1562 |
|
} |
| 1563 |
|
} |
| 1564 |
|
} |
| 1565 |
|
|
| 1566 |
|
/** |
| 1567 |
|
* Bootstrap database: Initialize database system and register autoload functions. |
| 1568 |
|
*/ |
| 1569 |
|
function _drupal_bootstrap_database() { |
| 1570 |
|
// The user agent header is used to pass a database prefix in the request when |
| 1571 |
|
// running tests. However, for security reasons, it is imperative that we |
| 1572 |
|
// validate we ourselves made the request. |
| 1573 |
|
if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], "simpletest") !== FALSE) && !drupal_valid_test_ua($_SERVER['HTTP_USER_AGENT'])) { |
| 1574 |
|
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); |
| 1575 |
|
exit; |
| 1576 |
|
} |
| 1577 |
|
// Initialize the database system. Note that the connection |
| 1578 |
|
// won't be initialized until it is actually requested. |
| 1579 |
|
require_once DRUPAL_ROOT . '/includes/database/database.inc'; |
| 1580 |
|
// Register autoload functions so that we can access classes and interfaces. |
| 1581 |
|
spl_autoload_register('drupal_autoload_class'); |
| 1582 |
|
spl_autoload_register('drupal_autoload_interface'); |
| 1583 |
|
} |
| 1584 |
|
|
| 1585 |
|
/** |
| 1586 |
|
* Bootstrap variables: Load system variables and all enabled bootstrap modules. |
| 1587 |
|
*/ |
| 1588 |
|
function _drupal_bootstrap_variables() { |
| 1589 |
|
global $conf; |
| 1590 |
|
|
| 1591 |
case DRUPAL_BOOTSTRAP_DATABASE: |
// Load variables from the database, but do not overwrite variables set in settings.php. |
| 1592 |
// The user agent header is used to pass a database prefix in the request when |
$conf = variable_initialize(isset($conf) ? $conf : array()); |
| 1593 |
// running tests. However, for security reasons, it is imperative that we |
// Load bootstrap modules. |
| 1594 |
// validate we ourselves made the request. |
require_once DRUPAL_ROOT . '/includes/module.inc'; |
| 1595 |
if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], "simpletest") !== FALSE) && !drupal_valid_test_ua($_SERVER['HTTP_USER_AGENT'])) { |
module_load_all(TRUE); |
| 1596 |
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden'); |
} |
|
exit; |
|
|
} |
|
|
// Initialize the database system. Note that the connection |
|
|
// won't be initialized until it is actually requested. |
|
|
require_once DRUPAL_ROOT . '/includes/database/database.inc'; |
|
|
// Register autoload functions so that we can access classes and interfaces. |
|
|
spl_autoload_register('drupal_autoload_class'); |
|
|
spl_autoload_register('drupal_autoload_interface'); |
|
|
break; |
|
|
|
|
|
case DRUPAL_BOOTSTRAP_VARIABLES: |
|
|
// Load variables from the database, but do not overwrite variables set in settings.php. |
|
|
$conf = variable_initialize(isset($conf) ? $conf : array()); |
|
|
// Load bootstrap modules. |
|
|
require_once DRUPAL_ROOT . '/includes/module.inc'; |
|
|
module_load_all(TRUE); |
|
|
break; |
|
|
|
|
|
case DRUPAL_BOOTSTRAP_SESSION: |
|
|
require_once DRUPAL_ROOT . '/' . variable_get('session_inc', 'includes/session.inc'); |
|
|
drupal_session_initialize(); |
|
|
break; |
|
|
|
|
|
case DRUPAL_BOOTSTRAP_PAGE_HEADER: |
|
|
bootstrap_invoke_all('boot'); |
|
|
if (!$cache && drupal_page_is_cacheable()) { |
|
|
header('X-Drupal-Cache: MISS'); |
|
|
} |
|
|
|
|
|
// Prepare for non-cached page workflow. |
|
|
require_once DRUPAL_ROOT . '/' . variable_get('lock_inc', 'includes/lock.inc'); |
|
|
lock_initialize(); |
|
|
|
|
|
if (!drupal_is_cli()) { |
|
|
ob_start(); |
|
|
drupal_page_header(); |
|
|
} |
|
|
break; |
|
|
|
|
|
case DRUPAL_BOOTSTRAP_LANGUAGE: |
|
|
drupal_language_initialize(); |
|
|
break; |
|
| 1597 |
|
|
| 1598 |
case DRUPAL_BOOTSTRAP_FULL: |
/** |
| 1599 |
require_once DRUPAL_ROOT . '/includes/common.inc'; |
* Bootstrap page header: Invoke hook_boot(), intialize locking system, and send default HTTP headers. |
| 1600 |
_drupal_bootstrap_full(); |
*/ |
| 1601 |
break; |
function _drupal_bootstrap_page_header() { |
| 1602 |
|
bootstrap_invoke_all('boot'); |
| 1603 |
|
if (!drupal_page_get_cache(TRUE) && drupal_page_is_cacheable()) { |
| 1604 |
|
header('X-Drupal-Cache: MISS'); |
| 1605 |
|
} |
| 1606 |
|
|
| 1607 |
|
// Prepare for non-cached page workflow. |
| 1608 |
|
require_once DRUPAL_ROOT . '/' . variable_get('lock_inc', 'includes/lock.inc'); |
| 1609 |
|
lock_initialize(); |
| 1610 |
|
|
| 1611 |
|
if (!drupal_is_cli()) { |
| 1612 |
|
ob_start(); |
| 1613 |
|
drupal_page_header(); |
| 1614 |
} |
} |
| 1615 |
} |
} |
| 1616 |
|
|
| 1617 |
/** |
/** |
| 1618 |
|
* Returns the current bootstrap phase for this Drupal process. |
| 1619 |
|
* |
| 1620 |
|
* The current phase is the one most recently completed by drupal_bootstrap(). |
| 1621 |
|
* |
| 1622 |
|
* @see drupal_bootstrap() |
| 1623 |
|
*/ |
| 1624 |
|
function drupal_get_bootstrap_phase() { |
| 1625 |
|
return drupal_bootstrap(); |
| 1626 |
|
} |
| 1627 |
|
|
| 1628 |
|
/** |
| 1629 |
* Validate the HMAC and timestamp of a user agent header from simpletest. |
* Validate the HMAC and timestamp of a user agent header from simpletest. |
| 1630 |
*/ |
*/ |
| 1631 |
function drupal_valid_test_ua($user_agent) { |
function drupal_valid_test_ua($user_agent) { |