Commit f9a068e5 authored by webchick's avatar webchick

Issue #1875086 by Crell, plach, effulgentsia, sun, msonnabaum, Rob Loach,...

Issue #1875086 by Crell, plach, effulgentsia, sun, msonnabaum, Rob Loach, quicksketch, David_Rothstein: Change notice: Improve DX of drupal_container()->get().
parent 2099b18e
......@@ -595,6 +595,9 @@ function drupal_override_server_variables($variables = array()) {
* Initializes the PHP environment.
*/
function drupal_environment_initialize() {
// Make sure the \Drupal class is available.
require_once DRUPAL_ROOT . '/core/lib/Drupal.php';
if (!isset($_SERVER['HTTP_REFERER'])) {
$_SERVER['HTTP_REFERER'] = '';
}
......@@ -982,17 +985,18 @@ function variable_initialize($conf = array()) {
else {
// Cache miss. Avoid a stampede.
$name = 'variable_init';
if (!lock()->acquire($name, 1)) {
$lock = Drupal::lock();
if (!$lock->acquire($name, 1)) {
// Another request is building the variable cache.
// Wait, then re-run this function.
lock()->wait($name);
$lock->wait($name);
return variable_initialize($conf);
}
else {
// Proceed with variable rebuild.
$variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed());
cache('bootstrap')->set('variables', $variables);
lock()->release($name);
$lock->release($name);
}
}
......@@ -2424,29 +2428,15 @@ function drupal_get_bootstrap_phase() {
/**
* Retrieves the Drupal Container to standardize object construction.
*
* The container is built by the kernel and passed in to this function which
* stores it statically. The container always contains the services from
* \Drupal\Core\CoreBundle, the bundles of enabled modules and any other
* bundles defined in $GLOBALS['conf']['container_bundles'].
*
* @see Drupal\Core\DrupalKernel
*
* @param Symfony\Component\DependencyInjection\ContainerInterface $new_container
* (optional) A new container instance to replace the current.
* @deprecated This function has been replaced by the \Drupal class. Use that
* instead.
*
* @return Symfony\Component\DependencyInjection\ContainerInterface|bool
* The instance of the ContainerInterface used to set up and maintain
* object instances or FALSE if none exist yet.
*/
function drupal_container(ContainerInterface $new_container = NULL) {
// We do not use drupal_static() here because we do not have a mechanism by
// which to reinitialize the stored objects, so a drupal_static_reset() call
// would leave Drupal in a nonfunctional state.
static $container;
if (isset($new_container)) {
$container = $new_container;
}
return $container;
function drupal_container() {
return Drupal::getContainer();
}
/**
......@@ -3542,10 +3532,13 @@ function drupal_check_memory_limit($required, $memory_limit = NULL) {
/**
* Get locking layer instance.
*
* @deprecated Use Drupal::lock() instead, or even better have the lock service
* injected into your object.
*
* @return Drupal\Core\Lock\LockBackendInterface
*/
function lock() {
return drupal_container()->get('lock');
return Drupal::lock();
}
/**
......
......@@ -374,7 +374,7 @@ function install_begin_request(&$install_state) {
))
->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)'));
drupal_container($container);
Drupal::setContainer($container);
}
// Set up $language, so t() caller functions will still work.
......
<?php
/**
* @file
* Contains Drupal.
*/
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Static Service Container wrapper.
*
* Generally, code in Drupal should accept its dependencies via either
* constructor injection or setter method injection. However, there are cases,
* particularly in legacy procedural code, where that is infeasible. This
* class acts as a unified global accessor to arbitrary services within the
* system in order to ease the transition from procedural code to injected OO
* code.
*
* The container is built by the kernel and passed in to this class which stores
* it statically. The container always contains the services from
* \Drupal\Core\CoreBundle, the bundles of enabled modules and any other bundles
* defined in $GLOBALS['conf']['container_bundles'].
*
* This class exists only to support legacy code that cannot be dependency
* injected. If your code needs it, consider refactoring it to be object
* oriented, if possible. When this is not possible, for instance in the case of
* hook implementations, and your code is more than a few non-reusable lines, it
* is recommended to instantiate an object implementing the actual logic.
*
* @code
* // Legacy procedural code.
* function hook_do_stuff() {
* $lock = lock()->acquire('stuff_lock');
* // ...
* }
*
* // Correct procedural code.
* function hook_do_stuff() {
* $lock = Drupal::lock()->acquire('stuff_lock');
* // ...
* }
*
* // The preferred way: dependency injected code.
* function hook_do_stuff() {
* // Move the actual implementation to a class and instantiate it.
* $instance = new StuffDoingClass(Drupal::lock());
* $instance->doStuff();
*
* // Or, even better, rely on the service container to avoid hard coding a
* // specific interface implementation, so that the actual logic can be
* // swapped. This might not always make sense, but in general it is a good
* // practice.
* Drupal::service('stuff.doing')->doStuff();
* }
*
* interface StuffDoingInterface {
* public function doStuff();
* }
*
* class StuffDoingClass implements StuffDoingInterface {
* protected $lockBackend;
*
* public function __construct(LockBackendInterface $lockBackend) {
* $this->lockBackend = $lockBackend;
* }
*
* public function doStuff() {
* $lock = $this->lockBackend->acquire('stuff_lock');
* // ...
* }
* }
* @endcode
*
* @see \Drupal\Core\DrupalKernel
*/
class Drupal {
/**
* The currently active container object.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected static $container;
/**
* Sets a new global container.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* A new container instance to replace the current.
*/
public static function setContainer(ContainerInterface $container) {
static::$container = $container;
}
/**
* Returns the currently active global container.
*
* @deprecated This method is only useful for the testing environment, and as
* a BC shiv for drupal_container(). It should not be used otherwise.
*
* @return \Symfony\Component\DependencyInjection\ContainerInterface
*/
public static function getContainer() {
return static::$container;
}
/**
* Retrieves a service from the container.
*
* Use this method if the desired service is not one of those with a dedicated
* accessor method below. If it is listed below, those methods are preferred
* as they can return useful type hints.
*
* @param string $id
* The ID of the service to retrieve.
* @return mixed
* The specified service.
*/
public static function service($id) {
return static::$container->get($id);
}
/**
* Returns the current primary database.
*
* @return \Drupal\Core\Database\Connection
* The current active database's master connection.
*/
public static function database() {
return static::$container->get('database');
}
/**
* Returns the locking layer instance.
*
* @return \Drupal\Core\Lock\LockBackendInterface
*/
public static function lock() {
return static::$container->get('lock');
}
}
......@@ -326,7 +326,7 @@ protected function initializeContainer() {
// Set the class loader which was registered as a synthetic service.
$this->container->set('class_loader', $this->classLoader);
drupal_container($this->container);
\Drupal::setContainer($this->container);
}
/**
......
......@@ -92,7 +92,7 @@ function contact_flood_control() {
$config = config('contact.settings');
$limit = $config->get('flood.limit');
$interval = $config->get('flood.interval');
if (!drupal_container()->get('flood')->isAllowed('contact', $limit, $interval)) {
if (!Drupal::service('flood')->isAllowed('contact', $limit, $interval)) {
drupal_set_message(t("You cannot send more than %limit messages in @interval. Try again later.", array(
'%limit' => $limit,
'@interval' => format_interval($interval),
......
......@@ -191,7 +191,7 @@ public function save(array $form, array &$form_state) {
drupal_mail('contact', 'page_autoreply', $sender->mail, $language_interface->langcode, $params);
}
drupal_container()->get('flood')->register('contact', config('contact.settings')->get('flood.interval'));
\Drupal::service('flood')->register('contact', config('contact.settings')->get('flood.interval'));
if ($message->category) {
watchdog('contact', '%sender-name (@sender-from) sent an e-mail regarding %category.', array(
'%sender-name' => $sender->name,
......
......@@ -207,7 +207,7 @@ function testAutoReply() {
// We are testing the auto-reply, so there should be one e-mail going to the sender.
$captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email));
$this->assertEqual(count($captured_emails), 1);
$this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($foo_autoreply));
$this->assertEqual(trim($captured_emails[0]['body']), trim(drupal_html_to_text($foo_autoreply)));
// Test the auto-reply for category 'bar'.
$email = $this->randomName(32) . '@example.com';
......@@ -216,7 +216,7 @@ function testAutoReply() {
// Auto-reply for category 'bar' should result in one auto-reply e-mail to the sender.
$captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email));
$this->assertEqual(count($captured_emails), 1);
$this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($bar_autoreply));
$this->assertEqual(trim($captured_emails[0]['body']), trim(drupal_html_to_text($bar_autoreply)));
// Verify that no auto-reply is sent when the auto-reply field is left blank.
$email = $this->randomName(32) . '@example.com';
......
......@@ -901,7 +901,7 @@ protected function prepareEnvironment() {
// Reset and create a new service container.
$this->container = new ContainerBuilder();
drupal_container($this->container);
\Drupal::setContainer($this->container);
// Unset globals.
unset($GLOBALS['theme_key']);
......@@ -1046,7 +1046,7 @@ protected function tearDown() {
new Settings($this->originalSettings);
// Restore original statics and globals.
drupal_container($this->originalContainer);
\Drupal::setContainer($this->originalContainer);
$GLOBALS['config_directories'] = $this->originalConfigDirectories;
if (isset($this->originalPrefix)) {
drupal_valid_test_ua($this->originalPrefix);
......
......@@ -30,20 +30,21 @@ function testCleanUp() {
$name = 'flood_test_cleanup';
// Register expired event.
drupal_container()->get('flood')->register($name, $window_expired);
$flood = \Drupal::service('flood');
$flood->register($name, $window_expired);
// Verify event is not allowed.
$this->assertFalse(drupal_container()->get('flood')->isAllowed($name, $threshold));
$this->assertFalse($flood->isAllowed($name, $threshold));
// Run cron and verify event is now allowed.
$this->cronRun();
$this->assertTrue(drupal_container()->get('flood')->isAllowed($name, $threshold));
$this->assertTrue($flood->isAllowed($name, $threshold));
// Register unexpired event.
drupal_container()->get('flood')->register($name);
$flood->register($name);
// Verify event is not allowed.
$this->assertFalse(drupal_container()->get('flood')->isAllowed($name, $threshold));
$this->assertFalse($flood->isAllowed($name, $threshold));
// Run cron and verify event is still not allowed.
$this->cronRun();
$this->assertFalse(drupal_container()->get('flood')->isAllowed($name, $threshold));
$this->assertFalse($flood->isAllowed($name, $threshold));
}
/**
......
......@@ -3519,7 +3519,7 @@ function system_get_module_admin_tasks($module, $info) {
*/
function system_cron() {
// Cleanup the flood.
drupal_container()->get('flood')->garbageCollection();
Drupal::service('flood')->garbageCollection();
$cache_bins = array_merge(module_invoke_all('cache_flush'), array('form', 'menu'));
foreach ($cache_bins as $bin) {
......
......@@ -868,7 +868,7 @@ function translation_entity_field_info_alter(&$info) {
function translation_entity_field_attach_presave(EntityInterface $entity) {
if (translation_entity_enabled($entity->entityType(), $entity->bundle())) {
$attributes = drupal_container()->get('request')->attributes;
drupal_container()->get('translation_entity.synchronizer')->synchronizeFields($entity, $attributes->get('working_langcode'), $attributes->get('source_langcode'));
Drupal::service('translation_entity.synchronizer')->synchronizeFields($entity, $attributes->get('working_langcode'), $attributes->get('source_langcode'));
}
}
......
......@@ -1331,13 +1331,14 @@ function user_login_name_validate($form, &$form_state) {
function user_login_authenticate_validate($form, &$form_state) {
$password = trim($form_state['values']['pass']);
$flood_config = config('user.flood');
$flood = Drupal::service('flood');
if (!empty($form_state['values']['name']) && !empty($password)) {
// Do not allow any login from the current user's IP if the limit has been
// reached. Default is 50 failed attempts allowed in one hour. This is
// independent of the per-user limit to catch attempts from one IP to log
// in to many different user accounts. We have a reasonably high limit
// since there may be only one apparent IP for all users at an institution.
if (!drupal_container()->get('flood')->isAllowed('user.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
if (!$flood->isAllowed('user.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
$form_state['flood_control_triggered'] = 'ip';
return;
}
......@@ -1358,7 +1359,7 @@ function user_login_authenticate_validate($form, &$form_state) {
// Don't allow login if the limit for this user has been reached.
// Default is to allow 5 failed attempts every 6 hours.
if (!drupal_container()->get('flood')->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
if (!$flood->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
$form_state['flood_control_triggered'] = 'user';
return;
}
......@@ -1378,12 +1379,13 @@ function user_login_authenticate_validate($form, &$form_state) {
*/
function user_login_final_validate($form, &$form_state) {
$flood_config = config('user.flood');
$flood = Drupal::service('flood');
if (empty($form_state['uid'])) {
// Always register an IP-based failed login event.
drupal_container()->get('flood')->register('user.failed_login_ip', $flood_config->get('ip_window'));
$flood->register('user.failed_login_ip', $flood_config->get('ip_window'));
// Register a per-user failed login event.
if (isset($form_state['flood_control_user_identifier'])) {
drupal_container()->get('flood')->register('user.failed_login_user', $flood_config->get('user_window'), $form_state['flood_control_user_identifier']);
$flood->register('user.failed_login_user', $flood_config->get('user_window'), $form_state['flood_control_user_identifier']);
}
if (isset($form_state['flood_control_triggered'])) {
......@@ -1403,7 +1405,7 @@ function user_login_final_validate($form, &$form_state) {
elseif (isset($form_state['flood_control_user_identifier'])) {
// Clear past failures for this user so as not to block a user who might
// log in and out more than once in an hour.
drupal_container()->get('flood')->clear('user.failed_login_user', $form_state['flood_control_user_identifier']);
$flood->clear('user.failed_login_user', $form_state['flood_control_user_identifier']);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment