2006-12-12 06:27:17 +00:00
< ? php
2016-09-19 10:39:40 +00:00
2014-04-16 22:49:23 +00:00
/**
* @ file
* Functions that need to be loaded on every Drupal request .
*/
2003-11-18 19:44:36 +00:00
2013-05-02 04:46:53 +00:00
use Drupal\Component\Utility\Crypt ;
2015-08-21 15:01:46 +00:00
use Drupal\Component\Utility\Html ;
2018-05-01 15:14:09 +00:00
use Drupal\Component\Render\FormattableMarkup ;
2013-05-07 23:29:47 +00:00
use Drupal\Component\Utility\Unicode ;
Issue #2156401 by alexpott, moshe weitzman, tedbow, dawehner, greg.1.anderson, phenaproxima, chris.smith, heddn, balsama, xjm, Mile23, izus, Manuel Garcia, sun, pwolanin, Berdir: Write install_profile value to configuration and only to settings.php if it is writeable
2017-01-31 10:32:31 +00:00
use Drupal\Core\Config\BootstrapConfigStorageFactory ;
2014-10-14 08:43:11 +00:00
use Drupal\Core\Logger\RfcLogLevel ;
2016-09-16 10:35:51 +00:00
use Drupal\Core\Test\TestDatabase ;
2015-03-14 21:50:47 +00:00
use Drupal\Core\Session\AccountInterface ;
2019-06-24 13:04:44 +00:00
use Drupal\Core\Site\Settings ;
2014-01-09 11:50:54 +00:00
use Drupal\Core\Utility\Error ;
2016-02-23 07:03:02 +00:00
use Drupal\Core\StringTranslation\TranslatableMarkup ;
Issue #2659940 by almaudoh, alexpott, phenaproxima, Jo Fitzgerald, markcarver, oriol_e9g, dawehner, dsnopek, jibran, larowlan: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList
2018-11-29 12:15:17 +00:00
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException ;
2012-01-13 14:14:07 +00:00
2009-10-30 22:33:35 +00:00
/**
2019-03-29 07:19:57 +00:00
* Minimum allowed version of PHP .
*
* Below this version :
* - The installer cannot be run .
* - Updates cannot be run .
* - Modules and themes cannot be enabled .
* - If a site managed to bypass all of the above , then an error is shown in
* the status report and various fatal errors occur on various pages .
Issue #2670966 by xjm, Crell, claudiu.cristea, alexpott, timmillwood, rakesh.gectcr, catch, dawehner, David_Rothstein, hchonov, martin107, tstoeckler, andypost, cilefen, RobLoach, Fabianx, salvis, hussainweb, JeroenT, larowlan, pfrenssen, daffie, webchick, wturrell: Warn users of old PHP versions
2017-12-03 05:03:36 +00:00
*
2019-03-29 07:19:57 +00:00
* @ see install . php
2018-02-01 11:37:06 +00:00
*
* @ todo Move this to an appropriate autoloadable class . See
* https :// www . drupal . org / project / drupal / issues / 2908079
2014-10-07 22:14:37 +00:00
*/
2019-05-24 10:36:30 +00:00
const DRUPAL_MINIMUM_PHP = '7.0.8' ;
2009-10-30 22:33:35 +00:00
2019-03-29 07:19:57 +00:00
/**
* Minimum supported version of PHP .
*
* Below this version :
* - New sites cannot be installed , except from within tests .
* - Updates from previous Drupal versions can be run , but users are warned
* that Drupal no longer supports that PHP version .
* - An error is shown in the status report that the PHP version is too old .
*
* @ todo Move this to an appropriate autoloadable class . See
* https :// www . drupal . org / project / drupal / issues / 2908079
*/
const DRUPAL_MINIMUM_SUPPORTED_PHP = '7.0.8' ;
Issue #2670966 by xjm, Crell, claudiu.cristea, alexpott, timmillwood, rakesh.gectcr, catch, dawehner, David_Rothstein, hchonov, martin107, tstoeckler, andypost, cilefen, RobLoach, Fabianx, salvis, hussainweb, JeroenT, larowlan, pfrenssen, daffie, webchick, wturrell: Warn users of old PHP versions
2017-12-03 05:03:36 +00:00
/**
* Minimum recommended version of PHP .
*
* Sites installing Drupal on PHP versions lower than this will see a warning
* message , but Drupal can still be installed . Used for ( e . g . ) PHP versions
* that have reached their EOL or will in the near future .
2018-02-01 11:37:06 +00:00
*
* @ todo Move this to an appropriate autoloadable class . See
* https :// www . drupal . org / project / drupal / issues / 2908079
Issue #2670966 by xjm, Crell, claudiu.cristea, alexpott, timmillwood, rakesh.gectcr, catch, dawehner, David_Rothstein, hchonov, martin107, tstoeckler, andypost, cilefen, RobLoach, Fabianx, salvis, hussainweb, JeroenT, larowlan, pfrenssen, daffie, webchick, wturrell: Warn users of old PHP versions
2017-12-03 05:03:36 +00:00
*/
2019-03-04 15:21:50 +00:00
const DRUPAL_RECOMMENDED_PHP = '7.2' ;
Issue #2670966 by xjm, Crell, claudiu.cristea, alexpott, timmillwood, rakesh.gectcr, catch, dawehner, David_Rothstein, hchonov, martin107, tstoeckler, andypost, cilefen, RobLoach, Fabianx, salvis, hussainweb, JeroenT, larowlan, pfrenssen, daffie, webchick, wturrell: Warn users of old PHP versions
2017-12-03 05:03:36 +00:00
2009-10-30 22:33:35 +00:00
/**
* Minimum recommended value of PHP memory_limit .
2014-07-22 09:24:02 +00:00
*
2015-05-14 10:52:50 +00:00
* 64 M was chosen as a minimum requirement in order to allow for additional
* contributed modules to be installed prior to hitting the limit . However ,
* 40 M is the target for the Standard installation profile .
2018-02-01 11:37:06 +00:00
*
* @ todo Move this to an appropriate autoloadable class . See
* https :// www . drupal . org / project / drupal / issues / 2908079
2009-10-30 22:33:35 +00:00
*/
2014-07-22 09:24:02 +00:00
const DRUPAL_MINIMUM_PHP_MEMORY_LIMIT = '64M' ;
2009-10-30 22:33:35 +00:00
2012-09-07 04:31:33 +00:00
/**
* Error reporting level : display no errors .
*/
const ERROR_REPORTING_HIDE = 'hide' ;
/**
* Error reporting level : display errors and warnings .
*/
const ERROR_REPORTING_DISPLAY_SOME = 'some' ;
/**
* Error reporting level : display all messages .
*/
const ERROR_REPORTING_DISPLAY_ALL = 'all' ;
/**
* Error reporting level : display all messages , plus backtrace information .
*/
const ERROR_REPORTING_DISPLAY_VERBOSE = 'verbose' ;
2006-12-11 12:00:07 +00:00
/**
* Role ID for anonymous users ; should match what ' s in the " role " table .
2015-03-14 21:50:47 +00:00
*
* @ deprecated in Drupal 8.0 . 0 , will be removed before Drupal 9.0 . 0.
* Use Drupal\Core\Session\AccountInterface :: ANONYMOUS_ROLE or
* \Drupal\user\RoleInterface :: ANONYMOUS_ID instead .
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 1619504
2006-12-11 12:00:07 +00:00
*/
2015-03-14 21:50:47 +00:00
const DRUPAL_ANONYMOUS_RID = AccountInterface :: ANONYMOUS_ROLE ;
2006-12-11 12:00:07 +00:00
/**
* Role ID for authenticated users ; should match what ' s in the " role " table .
2015-03-14 21:50:47 +00:00
*
* @ deprecated in Drupal 8.0 . 0 , will be removed before Drupal 9.0 . 0.
* Use Drupal\Core\Session\AccountInterface :: AUTHENTICATED_ROLE or
* \Drupal\user\RoleInterface :: AUTHENTICATED_ID instead .
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 1619504
2006-12-11 12:00:07 +00:00
*/
2015-03-14 21:50:47 +00:00
const DRUPAL_AUTHENTICATED_RID = AccountInterface :: AUTHENTICATED_ROLE ;
2006-01-21 08:28:55 +00:00
2013-06-19 09:14:55 +00:00
/**
* The maximum number of characters in a module or theme name .
*/
const DRUPAL_EXTENSION_NAME_MAX_LENGTH = 50 ;
2008-09-17 07:11:59 +00:00
/**
2011-11-23 01:12:55 +00:00
* Time of the current request in seconds elapsed since the Unix Epoch .
2011-07-05 13:37:34 +00:00
*
2011-11-23 01:12:55 +00:00
* This differs from $_SERVER [ 'REQUEST_TIME' ], which is stored as a float
* since PHP 5.4 . 0. Float timestamps confuse most PHP functions
* ( including date_create ()) .
*
* @ see http :// php . net / manual / reserved . variables . server . php
* @ see http :// php . net / manual / function . time . php
2016-10-13 09:42:53 +00:00
*
* @ deprecated in Drupal 8.3 . 0 , will be removed before Drupal 9.0 . 0.
* Use \Drupal :: time () -> getRequestTime ();
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 2785211
2008-09-17 07:11:59 +00:00
*/
2011-07-05 13:37:34 +00:00
define ( 'REQUEST_TIME' , ( int ) $_SERVER [ 'REQUEST_TIME' ]);
2008-09-17 07:11:59 +00:00
2010-11-19 20:35:31 +00:00
/**
* Regular expression to match PHP function names .
*
2012-03-24 06:14:35 +00:00
* @ see http :// php . net / manual / language . functions . php
2010-11-19 20:35:31 +00:00
*/
2011-11-29 09:56:53 +00:00
const DRUPAL_PHP_FUNCTION_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*' ;
2010-11-19 20:35:31 +00:00
2012-08-30 17:30:12 +00:00
/**
* $config_directories key for active directory .
*
2012-11-29 00:46:39 +00:00
* @ see config_get_config_directory ()
2015-09-09 12:06:17 +00:00
*
* @ deprecated in Drupal 8.0 . x and will be removed before 9.0 . 0. Drupal core no
* longer creates an active directory .
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 2501187
2012-08-30 17:30:12 +00:00
*/
const CONFIG_ACTIVE_DIRECTORY = 'active' ;
2015-10-05 23:29:54 +00:00
/**
* $config_directories key for sync directory .
*
2019-06-24 13:04:44 +00:00
* @ deprecated in drupal : 8.8 . 0 and is removed from drupal : 9.0 . 0. Use
* \Drupal\Core\Site\Settings :: get ( 'config_sync_directory' ) instead .
*
* @ see https :// www . drupal . org / node / 3018145
2015-10-05 23:29:54 +00:00
*/
const CONFIG_SYNC_DIRECTORY = 'sync' ;
2012-08-30 17:30:12 +00:00
/**
* $config_directories key for staging directory .
*
2012-11-29 00:46:39 +00:00
* @ see config_get_config_directory ()
2015-10-05 23:29:54 +00:00
* @ see CONFIG_SYNC_DIRECTORY
*
* @ deprecated in Drupal 8.0 . x and will be removed before 9.0 . 0. The staging
* directory was renamed to sync .
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 2574957
2012-08-30 17:30:12 +00:00
*/
const CONFIG_STAGING_DIRECTORY = 'staging' ;
2013-03-17 06:36:36 +00:00
/**
* Defines the root directory of the Drupal installation .
*
* This strips two levels of directories off the current directory .
*/
define ( 'DRUPAL_ROOT' , dirname ( dirname ( __DIR__ )));
2012-06-29 17:35:06 +00:00
/**
2012-08-30 17:30:12 +00:00
* Returns the path of a configuration directory .
*
2015-09-09 12:06:17 +00:00
* Configuration directories are configured using $config_directories in
* settings . php .
*
2012-08-30 17:30:12 +00:00
* @ param string $type
2015-09-09 12:06:17 +00:00
* The type of config directory to return . Drupal core provides the
2015-10-05 23:29:54 +00:00
* CONFIG_SYNC_DIRECTORY constant to access the sync directory .
2012-06-29 17:35:06 +00:00
*
* @ return string
* The configuration directory path .
2015-09-09 12:06:17 +00:00
*
* @ throws \Exception
2019-06-24 13:04:44 +00:00
*
* @ deprecated in drupal : 8.8 . 0 and is removed from drupal : 9.0 . 0. Use
* \Drupal\Core\Site\Settings :: get ( 'config_sync_directory' ) instead .
*
* @ see https :// www . drupal . org / node / 3018145
2012-06-29 17:35:06 +00:00
*/
2015-09-09 12:06:17 +00:00
function config_get_config_directory ( $type ) {
2012-08-30 17:30:12 +00:00
global $config_directories ;
2019-06-24 13:04:44 +00:00
@ trigger_error ( 'config_get_config_directory() is deprecated in drupal:8.8.0 and is removed from drupal:9.0.0. Use \Drupal\Core\Site\Settings::get(\'config_sync_directory\') instead. See https://www.drupal.org/node/3018145' , E_USER_DEPRECATED );
$config_sync_directory = Settings :: get ( 'config_sync_directory' , FALSE );
if ( $config_sync_directory ) {
$config_directories [ CONFIG_SYNC_DIRECTORY ] = $config_sync_directory ;
}
2015-10-05 23:29:54 +00:00
// @todo Remove fallback in Drupal 9. https://www.drupal.org/node/2574943
if ( $type == CONFIG_SYNC_DIRECTORY && ! isset ( $config_directories [ CONFIG_SYNC_DIRECTORY ]) && isset ( $config_directories [ CONFIG_STAGING_DIRECTORY ])) {
$type = CONFIG_STAGING_DIRECTORY ;
}
2013-04-05 22:50:11 +00:00
if ( ! empty ( $config_directories [ $type ])) {
2013-12-30 17:53:00 +00:00
return $config_directories [ $type ];
2012-06-29 17:35:06 +00:00
}
2016-06-07 10:32:46 +00:00
// @todo https://www.drupal.org/node/2696103 Throw a more specific exception.
2015-07-28 15:57:01 +00:00
throw new \Exception ( " The configuration directory type ' $type ' does not exist " );
2012-06-29 17:35:06 +00:00
}
2004-11-25 06:14:59 +00:00
/**
2011-12-05 12:52:27 +00:00
* Returns and optionally sets the filename for a system resource .
*
* The filename , whether provided , cached , or retrieved from the database , is
* only returned if the file exists .
2004-11-25 06:14:59 +00:00
*
2006-11-24 10:16:50 +00:00
* This function plays a key role in allowing Drupal ' s resources ( modules
* and themes ) to be located in different places depending on a site ' s
2013-07-17 14:37:04 +00:00
* configuration . For example , a module 'foo' may legally be located
2006-11-24 10:16:50 +00:00
* in any of these three places :
*
Issue #340723 by ParisLiakos, sun, Berdir, glennpratt, Cottser, swentel, alexpott, tstoeckler, Xano, tim.plunkett, BassistJimmyJam | beejeebus: Make modules and installation profiles only require .info.yml files.
2014-03-17 14:43:29 +00:00
* core / modules / foo / foo . info . yml
* modules / foo / foo . info . yml
* sites / example . com / modules / foo / foo . info . yml
2006-11-24 10:16:50 +00:00
*
* Calling drupal_get_filename ( 'module' , 'foo' ) will give you one of
* the above , depending on where the module is located .
*
2004-11-25 06:14:59 +00:00
* @ param $type
2014-04-02 07:05:28 +00:00
* The type of the item ; one of 'core' , 'profile' , 'module' , 'theme' , or
* 'theme_engine' .
2004-11-25 06:14:59 +00:00
* @ param $name
2014-04-02 07:05:28 +00:00
* The name of the item for which the filename is requested . Ignored for
* $type 'core' .
2004-11-25 06:14:59 +00:00
* @ param $filename
* The filename of the item if it is to be set explicitly rather
* than by consulting the database .
*
2018-01-22 17:09:31 +00:00
* @ return string
2013-02-11 17:35:27 +00:00
* The filename of the requested item or NULL if the item is not found .
2004-11-25 06:14:59 +00:00
*/
2006-11-24 10:16:50 +00:00
function drupal_get_filename ( $type , $name , $filename = NULL ) {
2014-04-02 07:05:28 +00:00
// Type 'core' only exists to simplify application-level logic; it always maps
// to the /core directory, whereas $name is ignored. It is only requested via
// drupal_get_path(). /core/core.info.yml does not exist, but is required
// since drupal_get_path() returns the dirname() of the returned pathname.
if ( $type === 'core' ) {
return 'core/core.info.yml' ;
}
Issue #2659940 by almaudoh, alexpott, phenaproxima, Jo Fitzgerald, markcarver, oriol_e9g, dawehner, dsnopek, jibran, larowlan: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList
2018-11-29 12:15:17 +00:00
try {
Issue #2208429 by dawehner, almaudoh, alexpott, jibran, Xano, donquixote, amitgoyal, bircher, stefan.r, Mile23, alvar0hurtad0, Berdir, andypost, larowlan: Extension System, Part III: ExtensionList, ModuleExtensionList and ProfileExtensionList
2018-01-24 15:21:31 +00:00
/** @var \Drupal\Core\Extension\ExtensionList $extension_list */
Issue #2659940 by almaudoh, alexpott, phenaproxima, Jo Fitzgerald, markcarver, oriol_e9g, dawehner, dsnopek, jibran, larowlan: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList
2018-11-29 12:15:17 +00:00
$extension_list = \Drupal :: service ( " extension.list. $type " );
Issue #2208429 by dawehner, almaudoh, alexpott, jibran, Xano, donquixote, amitgoyal, bircher, stefan.r, Mile23, alvar0hurtad0, Berdir, andypost, larowlan: Extension System, Part III: ExtensionList, ModuleExtensionList and ProfileExtensionList
2018-01-24 15:21:31 +00:00
if ( isset ( $filename )) {
// Manually add the info file path of an extension.
$extension_list -> setPathname ( $name , $filename );
}
Issue #2659940 by almaudoh, alexpott, phenaproxima, Jo Fitzgerald, markcarver, oriol_e9g, dawehner, dsnopek, jibran, larowlan: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList
2018-11-29 12:15:17 +00:00
return $extension_list -> getPathname ( $name );
2004-11-25 06:14:59 +00:00
}
Issue #2659940 by almaudoh, alexpott, phenaproxima, Jo Fitzgerald, markcarver, oriol_e9g, dawehner, dsnopek, jibran, larowlan: Extension System, Part III: ThemeExtensionList and ThemeEngineExtensionList
2018-11-29 12:15:17 +00:00
catch ( ServiceNotFoundException $e ) {
// Catch the exception. This will result in triggering an error.
// If the service is unknown, create a user-level error message.
trigger_error (
sprintf ( 'Unknown type specified: "%s". Must be one of: "core", "profile", "module", "theme", or "theme_engine".' , $type ),
E_USER_WARNING
);
}
catch ( \InvalidArgumentException $e ) {
// Catch the exception. This will result in triggering an error.
// If the filename is still unknown, create a user-level error message.
trigger_error (
sprintf ( 'The following %s is missing from the file system: %s' , $type , $name ),
E_USER_WARNING
);
2007-03-27 05:13:55 +00:00
}
2004-11-25 06:14:59 +00:00
}
2015-01-12 11:37:32 +00:00
/**
* Returns the path to a system item ( module , theme , etc . ) .
*
* @ param $type
* The type of the item ; one of 'core' , 'profile' , 'module' , 'theme' , or
* 'theme_engine' .
* @ param $name
* The name of the item for which the path is requested . Ignored for
* $type 'core' .
*
2018-01-22 17:09:31 +00:00
* @ return string
2015-01-12 11:37:32 +00:00
* The path to the requested item or an empty string if the item is not found .
*/
function drupal_get_path ( $type , $name ) {
return dirname ( drupal_get_filename ( $type , $name ));
}
2010-02-17 02:52:15 +00:00
/**
2010-04-29 05:03:28 +00:00
* Translates a string to the current language or to a given language .
2010-02-17 02:52:15 +00:00
*
2015-10-27 12:46:40 +00:00
* In order for strings to be localized , make them available in one of the ways
2016-02-04 12:19:52 +00:00
* supported by the @ link i18n Localization API . @ endlink When possible , use
* the \Drupal\Core\StringTranslation\StringTranslationTrait $this -> t () .
* Otherwise create a new \Drupal\Core\StringTranslation\TranslatableMarkup
* object directly .
2015-10-27 12:46:40 +00:00
*
* See \Drupal\Core\StringTranslation\TranslatableMarkup :: __construct () for
* important security information and usage guidelines .
*
* @ param string $string
* A string containing the English text to translate .
* @ param array $args
* ( optional ) An associative array of replacements to make after translation .
* Based on the first character of the key , the value is escaped and / or
* themed . See
* \Drupal\Component\Render\FormattableMarkup :: placeholderFormat () for
* details .
* @ param array $options
* ( optional ) An associative array of additional options , with the following
* elements :
* - 'langcode' ( defaults to the current language ) : A language code , to
2011-01-13 01:04:13 +00:00
* translate to a language other than what is used to display the page .
* - 'context' ( defaults to the empty context ) : The context the source string
2016-03-08 23:29:53 +00:00
* belongs to . See the @ link i18n Internationalization topic @ endlink for
* more information about string contexts .
2010-04-29 05:03:28 +00:00
*
2015-10-22 23:24:23 +00:00
* @ return \Drupal\Core\StringTranslation\TranslatableMarkup
2015-10-27 12:46:40 +00:00
* An object that , when cast to a string , returns the translated string .
*
* @ see \Drupal\Component\Render\FormattableMarkup :: placeholderFormat ()
* @ see \Drupal\Core\StringTranslation\StringTranslationTrait :: t ()
* @ see \Drupal\Core\StringTranslation\TranslatableMarkup :: __construct ()
2010-04-24 14:53:59 +00:00
*
* @ ingroup sanitization
2010-02-17 02:52:15 +00:00
*/
2017-03-04 01:20:24 +00:00
function t ( $string , array $args = [], array $options = []) {
2016-02-23 07:03:02 +00:00
return new TranslatableMarkup ( $string , $args , $options );
2011-08-07 15:01:39 +00:00
}
/**
2012-12-27 02:53:33 +00:00
* Formats a string for HTML display by replacing variable placeholders .
*
Issue #2228741 by rpayanm, mikelutz, voleger, epari.siva, malotor, Rolf van de Krol, quietone, Mile23, andypost, ianthomas_uk, Lendude, alexpott, dawehner, xjm, Gábor Hojtsy, Berdir, catch: Replace calls to format_string() with Drupal\Component\Render\FormattableMarkup
2019-07-11 08:06:33 +00:00
* @ deprecated in drupal : 8.0 . 0 and is removed from drupal : 9.0 . 0.
* Use \Drupal\Component\Render\FormattableMarkup instead .
*
* @ see https :// www . drupal . org / node / 2302363
2016-04-04 23:43:20 +00:00
* @ see \Drupal\Component\Render\FormattableMarkup :: placeholderFormat ()
* @ see \Drupal\Component\Render\FormattableMarkup
2011-08-07 15:01:39 +00:00
* @ see t ()
* @ ingroup sanitization
*/
2015-08-19 22:10:08 +00:00
function format_string ( $string , array $args ) {
Issue #2228741 by rpayanm, mikelutz, voleger, epari.siva, malotor, Rolf van de Krol, quietone, Mile23, andypost, ianthomas_uk, Lendude, alexpott, dawehner, xjm, Gábor Hojtsy, Berdir, catch: Replace calls to format_string() with Drupal\Component\Render\FormattableMarkup
2019-07-11 08:06:33 +00:00
@ trigger_error ( " format_string() is deprecated in drupal:8.0.0 and is removed from drupal:9.0.0. Use \ Drupal \ Component \R ender \ FormattableMarkup instead. See https://www.drupal.org/node/2302363 " , E_USER_DEPRECATED );
2018-05-01 15:14:09 +00:00
return new FormattableMarkup ( $string , $args );
2010-02-17 02:52:15 +00:00
}
2008-01-10 22:47:17 +00:00
/**
* Checks whether a string is valid UTF - 8.
*
* All functions designed to filter input should use drupal_validate_utf8
* to ensure they operate on valid UTF - 8 strings to prevent bypass of the
* filter .
*
* When text containing an invalid UTF - 8 lead byte ( 0xC0 - 0xFF ) is presented
* as UTF - 8 to Internet Explorer 6 , the program may misinterpret subsequent
* bytes . When these subsequent bytes are HTML control characters such as
* quotes or angle brackets , parts of the text that were deemed safe by filters
* end up in locations that are potentially unsafe ; An onerror attribute that
* is outside of a tag , and thus deemed safe by a filter , can be interpreted
* by the browser as if it were inside the tag .
*
2008-11-07 17:21:54 +00:00
* The function does not return FALSE for strings containing character codes
* above U + 10 FFFF , even though these are prohibited by RFC 3629.
2008-01-10 22:47:17 +00:00
*
* @ param $text
* The text to check .
2011-12-05 12:52:27 +00:00
*
2015-10-23 18:22:51 +00:00
* @ return bool
2008-01-10 22:47:17 +00:00
* TRUE if the text is valid UTF - 8 , FALSE if not .
2013-05-28 21:48:53 +00:00
*
* @ see \Drupal\Component\Utility\Unicode :: validateUtf8 ()
2015-08-20 21:42:55 +00:00
*
* @ deprecated in Drupal 8.0 . 0 , will be removed before Drupal 9.0 . 0.
* Use \Drupal\Component\Utility\Unicode :: validateUtf8 () .
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 1992584
2008-01-10 22:47:17 +00:00
*/
function drupal_validate_utf8 ( $text ) {
2013-05-28 21:48:53 +00:00
return Unicode :: validateUtf8 ( $text );
2005-11-29 20:37:19 +00:00
}
2010-05-26 07:52:13 +00:00
/**
2011-12-05 12:52:27 +00:00
* Logs an exception .
2010-05-26 07:52:13 +00:00
*
2014-10-05 12:00:50 +00:00
* This is a wrapper logging function which automatically decodes an exception .
2010-05-26 07:52:13 +00:00
*
* @ param $type
* The category to which this message belongs .
* @ param $exception
* The exception that is going to be logged .
* @ param $message
* The message to store in the log . If empty , a text that contains all useful
2011-04-12 20:54:16 +00:00
* information about the passed - in exception is used .
2010-05-26 07:52:13 +00:00
* @ param $variables
2012-12-03 13:08:48 +00:00
* Array of variables to replace in the message on display or
* NULL if message is already translated or not possible to
* translate .
2010-05-26 07:52:13 +00:00
* @ param $severity
* The severity of the message , as per RFC 3164.
* @ param $link
* A link to associate with the message .
*
2014-01-09 11:50:54 +00:00
* @ see \Drupal\Core\Utility\Error :: decodeException ()
2010-05-26 07:52:13 +00:00
*/
2017-03-04 01:20:24 +00:00
function watchdog_exception ( $type , Exception $exception , $message = NULL , $variables = [], $severity = RfcLogLevel :: ERROR , $link = NULL ) {
2010-05-26 07:52:13 +00:00
2014-06-26 18:55:12 +00:00
// Use a default value if $message is not set.
if ( empty ( $message )) {
Issue #2501319 by joelpittet, cwells, stefan.r, YesCT, nlisgo, Cottser, cmanalansan, dawehner, xjm, alexpott, josephdpurcell: Remove SafeMarkup::set() in Error::renderExceptionSafe() and _drupal_log_error() and improve backtrace formatting consistency in _drupal_log_error(), Error::renderExceptionSafe(), and DefaultExceptionSubscriber::onHtml()
2015-08-20 08:56:42 +00:00
$message = '%type: @message in %function (line %line of %file).' ;
2014-06-26 18:55:12 +00:00
}
if ( $link ) {
$variables [ 'link' ] = $link ;
}
$variables += Error :: decodeException ( $exception );
\Drupal :: logger ( $type ) -> log ( $severity , $message , $variables );
2010-05-26 07:52:13 +00:00
}
2004-07-13 07:21:14 +00:00
/**
2012-07-26 18:43:28 +00:00
* Sets a message to display to the user .
2004-07-13 07:21:14 +00:00
*
2013-05-24 16:46:19 +00:00
* Messages are stored in a session variable and displayed in the page template
* via the $messages theme variable .
2004-07-13 07:21:14 +00:00
*
2012-07-26 18:43:28 +00:00
* Example usage :
* @ code
* drupal_set_message ( t ( 'An error occurred and processing did not complete.' ), 'error' );
* @ endcode
*
2015-10-01 23:25:03 +00:00
* @ param string | \Drupal\Component\Render\MarkupInterface $message
2012-07-26 18:43:28 +00:00
* ( optional ) The translated message to be displayed to the user . For
* consistency with other messages , it should begin with a capital letter and
* end with a period .
* @ param string $type
* ( optional ) The message 's type. Defaults to ' status ' . These values are
* supported :
2005-05-14 18:32:22 +00:00
* - 'status'
2007-10-17 12:11:30 +00:00
* - 'warning'
2005-05-14 18:32:22 +00:00
* - 'error'
2012-07-26 18:43:28 +00:00
* @ param bool $repeat
* ( optional ) If this is FALSE and the message is already set , then the
2012-10-17 20:58:38 +00:00
* message won ' t be repeated . Defaults to FALSE .
2012-07-26 18:43:28 +00:00
*
* @ return array | null
* A multidimensional array with keys corresponding to the set message types .
Issue #1825952 by Fabianx, joelpittet, bdragon, heddn, chx, xjm, pwolanin, mikey_p, ti2m, bfr, dags, cilefen, scor, mgifford: Turn on twig autoescape by default
2014-07-18 09:05:22 +00:00
* The indexed array values of each contain the set messages for that type ,
* and each message is an associative array with the following format :
* - safe : Boolean indicating whether the message string has been marked as
* safe . Non - safe strings will be escaped automatically .
* - message : The message string .
* So , the following is an example of the full return array structure :
* @ code
* array (
* 'status' => array (
* array (
* 'safe' => TRUE ,
* 'message' => 'A <em>safe</em> markup string.' ,
* ),
* array (
* 'safe' => FALSE ,
* 'message' => " $arbitrary_user_input to escape. " ,
* ),
* ),
* );
* @ endcode
* If there are no messages set , the function returns NULL .
2012-07-26 18:43:28 +00:00
*
* @ see drupal_get_messages ()
2014-12-11 10:35:52 +00:00
* @ see status - messages . html . twig
2017-12-15 22:41:56 +00:00
* @ see https :// www . drupal . org / node / 2774931
*
* @ deprecated in Drupal 8.5 . 0 and will be removed before Drupal 9.0 . 0.
* Use \Drupal\Core\Messenger\MessengerInterface :: addMessage () instead .
2004-07-13 07:21:14 +00:00
*/
2012-10-17 20:58:38 +00:00
function drupal_set_message ( $message = NULL , $type = 'status' , $repeat = FALSE ) {
2017-12-15 22:41:56 +00:00
@ trigger_error ( 'drupal_set_message() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Messenger\MessengerInterface::addMessage() instead. See https://www.drupal.org/node/2774931' , E_USER_DEPRECATED );
$messenger = \Drupal :: messenger ();
if ( isset ( $message )) {
$messenger -> addMessage ( $message , $type , $repeat );
}
Issue #2278383 by dawehner, Xano, kim.pepper, twistor, jibran, Jo Fitzgerald, joelpittet, pritish.kumar, Fabianx, Crell, larowlan, alexpott, catch, Wim Leers: Create an injectible service for drupal_set_message()
2017-09-01 09:02:44 +00:00
return $messenger -> all ();
2004-06-28 20:00:53 +00:00
}
2004-07-13 07:21:14 +00:00
/**
2012-09-04 16:38:50 +00:00
* Returns all messages that have been set with drupal_set_message () .
2004-07-13 07:21:14 +00:00
*
2012-09-04 16:38:50 +00:00
* @ param string $type
* ( optional ) Limit the messages returned by type . Defaults to NULL , meaning
* all types . These values are supported :
* - NULL
* - 'status'
* - 'warning'
* - 'error'
* @ param bool $clear_queue
* ( optional ) If this is TRUE , the queue will be cleared of messages of the
* type specified in the $type parameter . Otherwise the queue will be left
* intact . Defaults to TRUE .
2011-12-05 12:52:27 +00:00
*
2012-09-04 16:38:50 +00:00
* @ return array
Issue #1825952 by Fabianx, joelpittet, bdragon, heddn, chx, xjm, pwolanin, mikey_p, ti2m, bfr, dags, cilefen, scor, mgifford: Turn on twig autoescape by default
2014-07-18 09:05:22 +00:00
* An associative , nested array of messages grouped by message type , with
* the top - level keys as the message type . The messages returned are
* limited to the type specified in the $type parameter , if any . If there
* are no messages of the specified type , an empty array is returned . See
2014-09-18 14:21:39 +00:00
* drupal_set_message () for the array structure of individual messages .
2012-09-04 16:38:50 +00:00
*
* @ see drupal_set_message ()
2014-12-11 10:35:52 +00:00
* @ see status - messages . html . twig
2017-12-15 22:41:56 +00:00
* @ see https :// www . drupal . org / node / 2774931
*
* @ deprecated in Drupal 8.5 . 0 and will be removed before Drupal 9.0 . 0.
* Use \Drupal\Core\Messenger\MessengerInterface :: all () or
* \Drupal\Core\Messenger\MessengerInterface :: messagesByType () instead .
2004-07-13 07:21:14 +00:00
*/
2006-09-07 07:11:15 +00:00
function drupal_get_messages ( $type = NULL , $clear_queue = TRUE ) {
2017-12-15 22:41:56 +00:00
@ trigger_error ( 'drupal_get_message() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Messenger\MessengerInterface::all() or \Drupal\Core\Messenger\MessengerInterface::messagesByType() instead. See https://www.drupal.org/node/2774931' , E_USER_DEPRECATED );
$messenger = \Drupal :: messenger ();
if ( $messages = $messenger -> all ()) {
2006-07-13 13:14:25 +00:00
if ( $type ) {
2006-09-07 07:11:15 +00:00
if ( $clear_queue ) {
Issue #2278383 by dawehner, Xano, kim.pepper, twistor, jibran, Jo Fitzgerald, joelpittet, pritish.kumar, Fabianx, Crell, larowlan, alexpott, catch, Wim Leers: Create an injectible service for drupal_set_message()
2017-09-01 09:02:44 +00:00
$messenger -> deleteByType ( $type );
2006-09-07 07:11:15 +00:00
}
2007-04-04 20:50:53 +00:00
if ( isset ( $messages [ $type ])) {
2017-03-04 01:20:24 +00:00
return [ $type => $messages [ $type ]];
2007-04-04 20:50:53 +00:00
}
2006-07-13 13:14:25 +00:00
}
else {
2006-09-07 07:11:15 +00:00
if ( $clear_queue ) {
Issue #2278383 by dawehner, Xano, kim.pepper, twistor, jibran, Jo Fitzgerald, joelpittet, pritish.kumar, Fabianx, Crell, larowlan, alexpott, catch, Wim Leers: Create an injectible service for drupal_set_message()
2017-09-01 09:02:44 +00:00
$messenger -> deleteAll ();
2006-09-07 07:11:15 +00:00
}
2006-07-13 13:14:25 +00:00
return $messages ;
}
2006-04-01 14:53:03 +00:00
}
2017-03-04 01:20:24 +00:00
return [];
2004-06-28 20:00:53 +00:00
}
2010-04-11 18:33:44 +00:00
/**
2011-12-05 12:52:27 +00:00
* Returns the time zone of the current user .
2018-01-22 17:09:31 +00:00
*
* @ return string
* The name of the current user ' s timezone or the name of the default timezone .
2010-04-11 18:33:44 +00:00
*/
function drupal_get_user_timezone () {
2015-02-21 17:29:58 +00:00
$user = \Drupal :: currentUser ();
2013-09-16 03:58:06 +00:00
$config = \Drupal :: config ( 'system.date' );
2012-11-29 07:37:55 +00:00
2013-08-01 13:46:05 +00:00
if ( $user && $config -> get ( 'timezone.user.configurable' ) && $user -> isAuthenticated () && $user -> getTimezone ()) {
2013-07-24 19:40:03 +00:00
return $user -> getTimezone ();
2010-04-11 18:33:44 +00:00
}
else {
2011-02-19 16:59:43 +00:00
// Ignore PHP strict notice if time zone has not yet been set in the php.ini
// configuration.
2013-08-01 13:46:05 +00:00
$config_data_default_timezone = $config -> get ( 'timezone.default' );
2012-11-29 07:37:55 +00:00
return ! empty ( $config_data_default_timezone ) ? $config_data_default_timezone : @ date_default_timezone_get ();
2010-04-11 18:33:44 +00:00
}
}
2010-02-15 15:52:27 +00:00
/**
2011-12-05 12:52:27 +00:00
* Provides custom PHP error handling .
2010-02-15 15:52:27 +00:00
*
* @ param $error_level
* The level of the error raised .
* @ param $message
* The error message .
* @ param $filename
2018-10-26 11:57:37 +00:00
* ( optional ) The filename that the error was raised in .
2010-02-15 15:52:27 +00:00
* @ param $line
2018-10-26 11:57:37 +00:00
* ( optional ) The line number the error was raised at .
2010-02-15 15:52:27 +00:00
* @ param $context
2018-10-26 11:57:37 +00:00
* ( optional ) An array that points to the active symbol table at the point the
* error occurred .
2010-02-15 15:52:27 +00:00
*/
2018-10-26 11:57:37 +00:00
function _drupal_error_handler ( $error_level , $message , $filename = NULL , $line = NULL , $context = NULL ) {
2013-05-09 09:25:10 +00:00
require_once __DIR__ . '/errors.inc' ;
2010-02-15 15:52:27 +00:00
_drupal_error_handler_real ( $error_level , $message , $filename , $line , $context );
}
/**
2011-12-05 12:52:27 +00:00
* Provides custom PHP exception handling .
2010-02-15 15:52:27 +00:00
*
* Uncaught exceptions are those not enclosed in a try / catch block . They are
* always fatal : the execution of the script will stop as soon as the exception
* handler exits .
*
2015-07-22 15:46:53 +00:00
* @ param \Exception | \Throwable $exception
2010-02-15 15:52:27 +00:00
* The exception object that was thrown .
*/
function _drupal_exception_handler ( $exception ) {
2013-05-09 09:25:10 +00:00
require_once __DIR__ . '/errors.inc' ;
2010-04-03 03:36:11 +00:00
try {
// Log the message to the watchdog and return an error page to the user.
2014-01-09 11:50:54 +00:00
_drupal_log_error ( Error :: decodeException ( $exception ), TRUE );
2010-04-03 03:36:11 +00:00
}
2019-05-24 10:36:30 +00:00
// Catch \Throwable, which covers both Error and Exception throwables.
2015-07-22 15:46:53 +00:00
catch ( \Throwable $error ) {
_drupal_exception_handler_additional ( $exception , $error );
2015-04-13 11:11:11 +00:00
}
}
/**
* Displays any additional errors caught while handling an exception .
*
2015-07-22 15:46:53 +00:00
* @ param \Exception | \Throwable $exception
2015-04-13 11:11:11 +00:00
* The first exception object that was thrown .
2015-07-22 15:46:53 +00:00
* @ param \Exception | \Throwable $exception2
2015-04-13 11:11:11 +00:00
* The second exception object that was thrown .
*/
function _drupal_exception_handler_additional ( $exception , $exception2 ) {
// Another uncaught exception was thrown while handling the first one.
// If we are displaying errors, then do so with no possibility of a further
// uncaught exception being thrown.
if ( error_displayable ()) {
print '<h1>Additional uncaught exception thrown while handling exception.</h1>' ;
print '<h2>Original</h2><p>' . Error :: renderExceptionSafe ( $exception ) . '</p>' ;
print '<h2>Additional</h2><p>' . Error :: renderExceptionSafe ( $exception2 ) . '</p><hr />' ;
2010-04-03 03:36:11 +00:00
}
2010-02-15 15:52:27 +00:00
}
2009-07-22 04:45:35 +00:00
/**
2011-12-05 12:52:27 +00:00
* Returns the test prefix if this is an internal request from SimpleTest .
2010-11-05 19:05:02 +00:00
*
2012-10-09 20:32:40 +00:00
* @ param string $new_prefix
2014-02-10 17:31:31 +00:00
* Internal use only . A new prefix to be stored .
2012-10-09 20:32:40 +00:00
*
2016-08-28 11:25:45 +00:00
* @ return string | false
2010-11-05 19:05:02 +00:00
* Either the simpletest prefix ( the string " simpletest " followed by any
* number of digits ) or FALSE if the user agent does not contain a valid
* HMAC and timestamp .
2009-07-22 04:45:35 +00:00
*/
2012-10-09 20:32:40 +00:00
function drupal_valid_test_ua ( $new_prefix = NULL ) {
2010-11-05 19:05:02 +00:00
static $test_prefix ;
2012-10-09 20:32:40 +00:00
if ( isset ( $new_prefix )) {
$test_prefix = $new_prefix ;
}
2010-11-05 19:05:02 +00:00
if ( isset ( $test_prefix )) {
return $test_prefix ;
}
2014-02-10 17:31:31 +00:00
// Unless the below User-Agent and HMAC validation succeeds, we are not in
// a test environment.
$test_prefix = FALSE ;
2009-07-22 04:45:35 +00:00
Issue #2232861 by grom358, daffie, alexpott, larowlan, pfrenssen, hussainweb, pcambra, jibran, phenaproxima, moshe weitzman, nick_schuch: Create BrowserTestBase for web-testing on top of Mink
2015-04-12 11:08:53 +00:00
// A valid Simpletest request will contain a hashed and salted authentication
// code. Check if this code is present in a cookie or custom user agent
// string.
$http_user_agent = isset ( $_SERVER [ 'HTTP_USER_AGENT' ]) ? $_SERVER [ 'HTTP_USER_AGENT' ] : NULL ;
$user_agent = isset ( $_COOKIE [ 'SIMPLETEST_USER_AGENT' ]) ? $_COOKIE [ 'SIMPLETEST_USER_AGENT' ] : $http_user_agent ;
2016-09-16 10:35:51 +00:00
if ( isset ( $user_agent ) && preg_match ( " /^simple( \ w+ \ d+):(.+):(.+):(.+) $ / " , $user_agent , $matches )) {
2010-11-05 19:05:02 +00:00
list (, $prefix , $time , $salt , $hmac ) = $matches ;
2016-04-29 11:02:20 +00:00
$check_string = $prefix . ':' . $time . ':' . $salt ;
2014-02-10 17:31:31 +00:00
// Read the hash salt prepared by drupal_generate_test_ua().
// This function is called before settings.php is read and Drupal's error
// handlers are set up. While Drupal's error handling may be properly
// configured on production sites, the server's PHP error_reporting may not.
// Ensure that no information leaks on production sites.
2016-09-16 10:35:51 +00:00
$test_db = new TestDatabase ( $prefix );
$key_file = DRUPAL_ROOT . '/' . $test_db -> getTestSitePath () . '/.htkey' ;
2014-02-10 17:31:31 +00:00
if ( ! is_readable ( $key_file )) {
header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 403 Forbidden' );
exit ;
}
$private_key = file_get_contents ( $key_file );
// The file properties add more entropy not easily accessible to others.
$key = $private_key . filectime ( __FILE__ ) . fileinode ( __FILE__ );
2010-11-05 19:05:02 +00:00
$time_diff = REQUEST_TIME - $time ;
2014-02-10 17:31:31 +00:00
$test_hmac = Crypt :: hmacBase64 ( $check_string , $key );
2016-08-26 17:37:15 +00:00
// Since we are making a local request a 600 second time window is allowed,
2010-11-05 19:05:02 +00:00
// and the HMAC must match.
2019-06-10 13:28:03 +00:00
if ( $time_diff >= 0 && $time_diff <= 600 && hash_equals ( $test_hmac , $hmac )) {
2010-11-05 19:05:02 +00:00
$test_prefix = $prefix ;
}
2016-08-26 17:37:15 +00:00
else {
header ( $_SERVER [ 'SERVER_PROTOCOL' ] . ' 403 Forbidden (SIMPLETEST_USER_AGENT invalid)' );
exit ;
}
2010-11-05 19:05:02 +00:00
}
2012-02-11 05:24:47 +00:00
return $test_prefix ;
2009-07-22 04:45:35 +00:00
}
/**
2011-12-05 12:52:27 +00:00
* Generates a user agent string with a HMAC and timestamp for simpletest .
2009-07-22 04:45:35 +00:00
*/
function drupal_generate_test_ua ( $prefix ) {
2014-02-10 17:31:31 +00:00
static $key , $last_prefix ;
if ( ! isset ( $key ) || $last_prefix != $prefix ) {
$last_prefix = $prefix ;
2016-09-16 10:35:51 +00:00
$test_db = new TestDatabase ( $prefix );
$key_file = DRUPAL_ROOT . '/' . $test_db -> getTestSitePath () . '/.htkey' ;
2014-02-10 17:31:31 +00:00
// When issuing an outbound HTTP client request from within an inbound test
// request, then the outbound request has to use the same User-Agent header
// as the inbound request. A newly generated private key for the same test
// prefix would invalidate all subsequent inbound requests.
2019-07-30 21:35:12 +00:00
// @see \Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware
2014-02-10 17:31:31 +00:00
if ( DRUPAL_TEST_IN_CHILD_SITE && $parent_prefix = drupal_valid_test_ua ()) {
if ( $parent_prefix != $prefix ) {
throw new \RuntimeException ( " Malformed User-Agent: Expected ' $parent_prefix ' but got ' $prefix '. " );
}
// If the file is not readable, a PHP warning is expected in this case.
$private_key = file_get_contents ( $key_file );
}
else {
// Generate and save a new hash salt for a test run.
// Consumed by drupal_valid_test_ua() before settings.php is loaded.
2014-02-27 04:48:12 +00:00
$private_key = Crypt :: randomBytesBase64 ( 55 );
2014-02-10 17:31:31 +00:00
file_put_contents ( $key_file , $private_key );
}
// The file properties add more entropy not easily accessible to others.
$key = $private_key . filectime ( __FILE__ ) . fileinode ( __FILE__ );
2009-07-22 04:45:35 +00:00
}
2010-11-05 19:05:02 +00:00
// Generate a moderately secure HMAC based on the database credentials.
$salt = uniqid ( '' , TRUE );
Issue #2469713 by dawehner, pfrenssen, alexpott, elachlan, Mixologic, larowlan, hussainweb, benjy, jibran, Wim Leers, isntall: Step 2: Create a JavaScriptTestBase using PhantomJs Driver/Binary
2016-04-07 11:25:35 +00:00
$check_string = $prefix . ':' . time () . ':' . $salt ;
2016-09-16 10:35:51 +00:00
return 'simple' . $check_string . ':' . Crypt :: hmacBase64 ( $check_string , $key );
2009-07-22 04:45:35 +00:00
}
2005-07-27 01:58:43 +00:00
/**
2007-11-30 12:19:10 +00:00
* Enables use of the theme system without requiring database access .
*
* Loads and initializes the theme system for site installs , updates and when
2009-04-19 19:10:08 +00:00
* the site is in maintenance mode . This also applies when the database fails .
2007-11-30 12:19:10 +00:00
*
* @ see _drupal_maintenance_theme ()
2005-07-27 01:58:43 +00:00
*/
function drupal_maintenance_theme () {
2013-05-09 09:25:10 +00:00
require_once __DIR__ . '/theme.maintenance.inc' ;
2007-11-30 12:19:10 +00:00
_drupal_maintenance_theme ();
2005-07-27 01:58:43 +00:00
}
2006-09-01 08:44:53 +00:00
2009-07-28 12:13:47 +00:00
/**
2011-12-05 12:52:27 +00:00
* Returns TRUE if a Drupal installation is currently being attempted .
2009-07-28 12:13:47 +00:00
*/
function drupal_installation_attempted () {
2012-09-24 21:08:10 +00:00
// This cannot rely on the MAINTENANCE_MODE constant, since that would prevent
// tests from using the non-interactive installer, in which case Drupal
// only happens to be installed within the same request, but subsequently
// executed code does not involve the installer at all.
// @see install_drupal()
return isset ( $GLOBALS [ 'install_state' ]) && empty ( $GLOBALS [ 'install_state' ][ 'installation_finished' ]);
2009-07-28 12:13:47 +00:00
}
2015-01-12 11:37:32 +00:00
/**
* Gets the name of the currently active installation profile .
*
* When this function is called during Drupal ' s initial installation process ,
* the name of the profile that ' s about to be installed is stored in the global
* installation state . At all other times , the " install_profile " setting will be
Issue #2156401 by alexpott, moshe weitzman, tedbow, dawehner, greg.1.anderson, phenaproxima, chris.smith, heddn, balsama, xjm, Mile23, izus, Manuel Garcia, sun, pwolanin, Berdir: Write install_profile value to configuration and only to settings.php if it is writeable
2017-01-31 10:32:31 +00:00
* available in container as a parameter .
2015-01-12 11:37:32 +00:00
*
2017-02-11 22:02:19 +00:00
* @ return string | null
2015-01-12 11:37:32 +00:00
* The name of the installation profile or NULL if no installation profile is
* currently active . This is the case for example during the first steps of
* the installer or during unit tests .
Issue #2156401 by alexpott, moshe weitzman, tedbow, dawehner, greg.1.anderson, phenaproxima, chris.smith, heddn, balsama, xjm, Mile23, izus, Manuel Garcia, sun, pwolanin, Berdir: Write install_profile value to configuration and only to settings.php if it is writeable
2017-01-31 10:32:31 +00:00
*
2019-07-22 08:31:06 +00:00
* @ deprecated in drupal : 8.3 . 0 and is removed from drupal : 9.0 . 0.
Issue #2156401 by alexpott, moshe weitzman, tedbow, dawehner, greg.1.anderson, phenaproxima, chris.smith, heddn, balsama, xjm, Mile23, izus, Manuel Garcia, sun, pwolanin, Berdir: Write install_profile value to configuration and only to settings.php if it is writeable
2017-01-31 10:32:31 +00:00
* Use the install_profile container parameter or \Drupal :: installProfile ()
* instead . If you are accessing the value before it is written to
* configuration during the installer use the $install_state global . If you
* need to access the value before container is available you can use
* BootstrapConfigStorageFactory to load the value directly from
* configuration .
2017-05-08 10:41:45 +00:00
*
* @ see https :// www . drupal . org / node / 2538996
2015-01-12 11:37:32 +00:00
*/
function drupal_get_profile () {
global $install_state ;
2019-07-22 08:31:06 +00:00
@ trigger_error ( 'drupal_get_profile() is deprecated in drupal:8.3.0 and is removed from drupal:9.0.0. Use the install_profile container parameter or \Drupal::installProfile() instead. If you are accessing the value before it is written to configuration during the installer use the $install_state global. If you need to access the value before container is available you can use BootstrapConfigStorageFactory to load the value directly from configuration. See https://www.drupal.org/node/2538996' , E_USER_DEPRECATED );
2015-01-12 11:37:32 +00:00
if ( drupal_installation_attempted ()) {
// If the profile has been selected return it.
if ( isset ( $install_state [ 'parameters' ][ 'profile' ])) {
$profile = $install_state [ 'parameters' ][ 'profile' ];
}
else {
$profile = NULL ;
}
}
else {
Issue #2156401 by alexpott, moshe weitzman, tedbow, dawehner, greg.1.anderson, phenaproxima, chris.smith, heddn, balsama, xjm, Mile23, izus, Manuel Garcia, sun, pwolanin, Berdir: Write install_profile value to configuration and only to settings.php if it is writeable
2017-01-31 10:32:31 +00:00
if ( \Drupal :: hasContainer ()) {
$profile = \Drupal :: installProfile ();
}
else {
$profile = BootstrapConfigStorageFactory :: getDatabaseStorage () -> read ( 'core.extension' )[ 'profile' ];
}
2015-01-12 11:37:32 +00:00
}
return $profile ;
}
2012-03-14 08:55:55 +00:00
/**
* Registers an additional namespace .
*
* @ param string $name
* The namespace component to register ; e . g . , 'node' .
* @ param string $path
* The relative path to the Drupal component in the filesystem .
2019-04-11 03:08:45 +00:00
*
* @ deprecated in Drupal 8.8 . 0 , will be removed before Drupal 9.0 . 0. Use the
* class loader as injected service instance to register the namespace :
* @ code
* $this -> classLoader -> addPsr4 ( 'Drupal\\' . $name . '\\' , \Drupal :: root () . '/' . $path . '/src' );
* @ endcode
* or the following code if the service cannot be injected :
* @ code
* \Drupal :: service ( 'class_loader' ) -> addPsr4 ( 'Drupal\\' . $name . '\\' , \Drupal :: root () . '/' . $path . '/src' );
* @ endcode
*
* @ see https :// www . drupal . org / node / 3035275
2012-03-14 08:55:55 +00:00
*/
function drupal_classloader_register ( $name , $path ) {
2019-04-11 03:08:45 +00:00
@ trigger_error ( 'drupal_classloader_register() is deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0. Use the method ::addPsr4() of the class_loader service to register the namespace. See https://www.drupal.org/node/3035275.' , E_USER_DEPRECATED );
2014-09-03 13:02:51 +00:00
$loader = \Drupal :: service ( 'class_loader' );
2014-11-17 12:20:57 +00:00
$loader -> addPsr4 ( 'Drupal\\' . $name . '\\' , \Drupal :: root () . '/' . $path . '/src' );
2012-03-14 08:55:55 +00:00
}
2009-04-02 20:39:45 +00:00
/**
2011-12-05 12:52:27 +00:00
* Provides central static variable storage .
2009-04-02 20:39:45 +00:00
*
2009-11-20 06:12:45 +00:00
* All functions requiring a static variable to persist or cache data within
* a single page request are encouraged to use this function unless it is
* absolutely certain that the static variable will not need to be reset during
* the page request . By centralizing static variable storage through this
* function , other functions can rely on a consistent API for resetting any
* other function ' s static variables .
*
* Example :
* @ code
2012-01-23 15:46:29 +00:00
* function example_list ( $field = 'default' ) {
* $examples = & drupal_static ( __FUNCTION__ );
* if ( ! isset ( $examples )) {
2009-11-20 06:12:45 +00:00
* // If this function is being called for the first time after a reset,
* // query the database and execute any other code needed to retrieve
2012-01-23 15:46:29 +00:00
* // information.
2009-11-20 06:12:45 +00:00
* ...
* }
2012-01-23 15:46:29 +00:00
* if ( ! isset ( $examples [ $field ])) {
2009-11-20 06:12:45 +00:00
* // If this function is being called for the first time for a particular
* // index field, then execute code needed to index the information already
2012-01-23 15:46:29 +00:00
* // available in $examples by the desired field.
2009-11-20 06:12:45 +00:00
* ...
* }
* // Subsequent invocations of this function for a particular index field
* // skip the above two code blocks and quickly return the already indexed
* // information.
2012-01-23 15:46:29 +00:00
* return $examples [ $field ];
2009-11-20 06:12:45 +00:00
* }
2012-01-23 15:46:29 +00:00
* function examples_admin_overview () {
* // When building the content for the overview page, make sure to get
* // completely fresh information.
* drupal_static_reset ( 'example_list' );
2009-11-20 06:12:45 +00:00
* ...
* }
* @ endcode
*
* In a few cases , a function can have certainty that there is no legitimate
* use - case for resetting that function ' s static variable . This is rare ,
* because when writing a function , it ' s hard to forecast all the situations in
* which it will be used . A guideline is that if a function ' s static variable
* does not depend on any information outside of the function that might change
* during a single page request , then it ' s ok to use the " static " keyword
* instead of the drupal_static () function .
*
* Example :
* @ code
2014-04-10 17:30:54 +00:00
* function mymodule_log_stream_handle ( $new_handle = NULL ) {
* static $handle ;
* if ( isset ( $new_handle )) {
* $handle = $new_handle ;
2009-11-20 06:12:45 +00:00
* }
2014-04-10 17:30:54 +00:00
* return $handle ;
2009-11-20 06:12:45 +00:00
* }
* @ endcode
*
* In a few cases , a function needs a resettable static variable , but the
* function is called many times ( 100 + ) during a single page request , so
* every microsecond of execution time that can be removed from the function
* counts . These functions can use a more cumbersome , but faster variant of
2010-01-07 04:54:18 +00:00
* calling drupal_static () . It works by storing the reference returned by
* drupal_static () in the calling function ' s own static variable , thereby
* removing the need to call drupal_static () for each iteration of the function .
* Conceptually , it replaces :
* @ code
* $foo = & drupal_static ( __FUNCTION__ );
* @ endcode
* with :
* @ code
* // Unfortunately, this does not work.
* static $foo = & drupal_static ( __FUNCTION__ );
* @ endcode
* However , the above line of code does not work , because PHP only allows static
2014-09-18 14:21:39 +00:00
* variables to be initialized by literal values , and does not allow static
2010-01-07 04:54:18 +00:00
* variables to be assigned to references .
2012-03-24 06:14:35 +00:00
* - http :// php . net / manual / language . variables . scope . php #language.variables.scope.static
* - http :// php . net / manual / language . variables . scope . php #language.variables.scope.references
2010-01-07 04:54:18 +00:00
* The example below shows the syntax needed to work around both limitations .
2015-05-24 20:08:46 +00:00
* For benchmarks and more information , see https :// www . drupal . org / node / 619666.
2009-11-20 06:12:45 +00:00
*
* Example :
* @ code
2014-07-20 10:28:21 +00:00
* function example_default_format_type () {
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 )) {
2014-07-20 10:28:21 +00:00
* $drupal_static_fast [ 'format_type' ] = & drupal_static ( __FUNCTION__ );
2010-01-07 04:54:18 +00:00
* }
2014-07-20 10:28:21 +00:00
* $format_type = & $drupal_static_fast [ 'format_type' ];
2009-11-20 06:12:45 +00:00
* ...
* }
* @ endcode
*
2009-04-02 20:39:45 +00:00
* @ param $name
* Globally unique name for the variable . For a function with only one static ,
* variable , the function name ( e . g . via the PHP magic __FUNCTION__ constant )
2009-05-24 17:39:35 +00:00
* is recommended . For a function with multiple static variables add a
2009-04-02 20:39:45 +00:00
* distinguishing suffix to the function name for each one .
* @ param $default_value
* Optional default value .
* @ param $reset
2014-09-16 11:51:03 +00:00
* TRUE to reset one or all variables ( s ) . This parameter is only used
* internally and should not be passed in ; use drupal_static_reset () instead .
* ( This function ' s return value should not be used when TRUE is passed in . )
2009-04-02 20:39:45 +00:00
*
2018-01-22 17:09:31 +00:00
* @ return array
2009-11-08 20:36:12 +00:00
* Returns a variable by reference .
2009-11-20 06:12:45 +00:00
*
* @ see drupal_static_reset ()
2009-04-02 20:39:45 +00:00
*/
function & drupal_static ( $name , $default_value = NULL , $reset = FALSE ) {
2017-03-04 01:20:24 +00:00
static $data = [], $default = [];
2010-07-18 01:22:53 +00:00
// First check if dealing with a previously defined static variable.
if ( isset ( $data [ $name ]) || array_key_exists ( $name , $data )) {
// Non-NULL $name and both $data[$name] and $default[$name] statics exist.
if ( $reset ) {
// Reset pre-existing static variable to its default value.
2009-11-08 20:36:12 +00:00
$data [ $name ] = $default [ $name ];
2009-04-02 20:39:45 +00:00
}
2010-07-18 01:22:53 +00:00
return $data [ $name ];
}
// Neither $data[$name] nor $default[$name] static variables exist.
if ( isset ( $name )) {
if ( $reset ) {
2009-11-08 20:36:12 +00:00
// Reset was called before a default is set and yet a variable must be
// returned.
return $data ;
2009-04-02 20:39:45 +00:00
}
2010-07-18 01:22:53 +00:00
// First call with new non-NULL $name. Initialize a new static variable.
2009-11-08 20:36:12 +00:00
$default [ $name ] = $data [ $name ] = $default_value ;
2010-07-18 01:22:53 +00:00
return $data [ $name ];
}
// Reset all: ($name == NULL). This needs to be done one at a time so that
// references returned by earlier invocations of drupal_static() also get
// reset.
foreach ( $default as $name => $value ) {
$data [ $name ] = $value ;
2009-04-02 20:39:45 +00:00
}
2010-07-18 01:22:53 +00:00
// As the function returns a reference, the return should always be a
// variable.
return $data ;
2009-04-02 20:39:45 +00:00
}
/**
2011-12-05 12:52:27 +00:00
* Resets one or all centrally stored static variable ( s ) .
2009-04-02 20:39:45 +00:00
*
* @ param $name
* Name of the static variable to reset . Omit to reset all variables .
2014-09-16 11:51:03 +00:00
* Resetting all variables should only be used , for example , for running
* unit tests with a clean environment .
2009-04-02 20:39:45 +00:00
*/
function drupal_static_reset ( $name = NULL ) {
drupal_static ( $name , NULL , TRUE );
}
2009-09-19 10:38:47 +00:00
2009-12-22 14:47:14 +00:00
/**
* Formats text for emphasized display in a placeholder inside a sentence .
2011-12-05 12:52:27 +00:00
*
2015-08-21 15:01:46 +00:00
* @ deprecated in Drupal 8.0 . 0 , will be removed before Drupal 9.0 . 0. Use
2018-05-01 15:14:09 +00:00
* \Drupal\Component\Render\FormattableMarkup or Twig ' s " placeholder " filter
* instead . Note this method should not be used to simply emphasize a string
* and therefore has few valid use - cases . Note also , that this method does not
* mark the string as safe .
2015-08-21 15:01:46 +00:00
*
2017-05-08 10:41:45 +00:00
* @ see https :// www . drupal . org / node / 2302363
2009-12-22 14:47:14 +00:00
*/
2010-08-17 13:50:52 +00:00
function drupal_placeholder ( $text ) {
2015-08-21 15:01:46 +00:00
return '<em class="placeholder">' . Html :: escape ( $text ) . '</em>' ;
2009-12-22 14:47:14 +00:00
}
2010-02-17 22:44:52 +00:00
/**
2011-12-05 12:52:27 +00:00
* Registers a function for execution on shutdown .
2010-02-17 22:44:52 +00:00
*
2010-08-22 14:11:47 +00:00
* Wrapper for register_shutdown_function () that catches thrown exceptions to
* avoid " Exception thrown without a stack frame in Unknown " .
2010-02-17 22:44:52 +00:00
*
2018-01-23 12:14:26 +00:00
* @ param callable $callback
2010-02-17 22:44:52 +00:00
* The shutdown function to register .
2010-08-22 14:11:47 +00:00
* @ param ...
* Additional arguments to pass to the shutdown function .
*
2018-01-22 17:09:31 +00:00
* @ return array
2010-02-17 22:44:52 +00:00
* Array of shutdown functions to be executed .
*
* @ see register_shutdown_function ()
2010-06-11 11:00:18 +00:00
* @ ingroup php_wrappers
2010-02-17 22:44:52 +00:00
*/
2010-08-22 14:11:47 +00:00
function & drupal_register_shutdown_function ( $callback = NULL ) {
// We cannot use drupal_static() here because the static cache is reset during
// batch processing, which breaks batch handling.
2017-03-04 01:20:24 +00:00
static $callbacks = [];
2010-02-17 22:44:52 +00:00
if ( isset ( $callback )) {
// Only register the internal shutdown function once.
if ( empty ( $callbacks )) {
register_shutdown_function ( '_drupal_shutdown_function' );
}
$args = func_get_args ();
2014-02-14 12:35:19 +00:00
// Remove $callback from the arguments.
unset ( $args [ 0 ]);
2010-02-17 22:44:52 +00:00
// Save callback and arguments
2017-03-04 01:20:24 +00:00
$callbacks [] = [ 'callback' => $callback , 'arguments' => $args ];
2010-02-17 22:44:52 +00:00
}
return $callbacks ;
}
/**
2011-12-05 12:52:27 +00:00
* Executes registered shutdown functions .
2010-02-17 22:44:52 +00:00
*/
function _drupal_shutdown_function () {
$callbacks = & drupal_register_shutdown_function ();
2011-01-01 22:46:02 +00:00
// Set the CWD to DRUPAL_ROOT as it is not guaranteed to be the same as it
// was in the normal context of execution.
chdir ( DRUPAL_ROOT );
2010-02-17 22:44:52 +00:00
try {
2018-10-20 07:14:35 +00:00
reset ( $callbacks );
// Do not use foreach() here because it is possible that the callback will
// add to the $callbacks array via drupal_register_shutdown_function().
while ( $callback = current ( $callbacks )) {
2010-02-17 22:44:52 +00:00
call_user_func_array ( $callback [ 'callback' ], $callback [ 'arguments' ]);
2018-10-20 07:14:35 +00:00
next ( $callbacks );
2010-02-17 22:44:52 +00:00
}
}
2019-05-24 10:36:30 +00:00
// Catch \Throwable, which covers both Error and Exception throwables.
2015-07-22 15:46:53 +00:00
catch ( \Throwable $error ) {
_drupal_shutdown_function_handle_exception ( $error );
2015-04-13 11:11:11 +00:00
}
}
/**
* Displays and logs any errors that may happen during shutdown .
*
2015-07-22 15:46:53 +00:00
* @ param \Exception | \Throwable $exception
2015-04-13 11:11:11 +00:00
* The exception object that was thrown .
*
* @ see _drupal_shutdown_function ()
*/
function _drupal_shutdown_function_handle_exception ( $exception ) {
// If using PHP-FPM then fastcgi_finish_request() will have been fired
// preventing further output to the browser.
if ( ! function_exists ( 'fastcgi_finish_request' )) {
// If we are displaying errors, then do so with no possibility of a
// further uncaught exception being thrown.
require_once __DIR__ . '/errors.inc' ;
if ( error_displayable ()) {
print '<h1>Uncaught exception thrown in shutdown function.</h1>' ;
print '<p>' . Error :: renderExceptionSafe ( $exception ) . '</p><hr />' ;
2010-04-03 03:36:11 +00:00
}
2010-02-17 22:44:52 +00:00
}
2015-04-13 11:11:11 +00:00
error_log ( $exception );
2010-02-17 22:44:52 +00:00
}