upgrades core to 8.4.2

This commit is contained in:
Bachir Soussi Chiadmi
2017-11-14 16:09:54 +01:00
parent bd60eff9b3
commit c2b4e25be4
3504 changed files with 140306 additions and 38684 deletions
@@ -30,7 +30,7 @@ class MockFileFinder implements ClassFinderInterface {
/**
* Creates new mock file finder objects.
*/
static public function create($filename) {
public static function create($filename) {
$object = new static();
$object->filename = $filename;
return $object;
@@ -8,9 +8,9 @@
"php": ">=5.5.9",
"doctrine/common": "2.5.*",
"doctrine/annotations": "1.2.*",
"drupal/core-fileCache": "~8.2",
"drupal/core-plugin": "~8.2",
"drupal/core-utility": "~8.2"
"drupal/core-file-cache": "^8.2",
"drupal/core-plugin": "^8.2",
"drupal/core-utility": "^8.2"
},
"autoload": {
"psr-4": {
@@ -25,7 +25,7 @@ class Handle {
require __DIR__ . '/global_namespace_php5.php';
}
// PHP 5 - create a handler to throw the exception directly.
assert_options(ASSERT_CALLBACK, function($file = '', $line = 0, $code = '', $message = '') {
assert_options(ASSERT_CALLBACK, function ($file = '', $line = 0, $code = '', $message = '') {
if (empty($message)) {
$message = $code;
}
@@ -205,9 +205,9 @@ class Inspector {
* @return bool
* TRUE if $traversable can be traversed and all members have all keys.
*/
public static function assertAllHaveKey() {
public static function assertAllHaveKey($traversable) {
$args = func_get_args();
$traversable = array_shift($args);
unset($args[0]);
if (static::assertTraversable($traversable)) {
foreach ($traversable as $member) {
@@ -396,9 +396,9 @@ class Inspector {
* TRUE if $traversable can be traversed and all members are objects with
* at least one of the listed classes or interfaces.
*/
public static function assertAllObjects() {
public static function assertAllObjects($traversable) {
$args = func_get_args();
$traversable = array_shift($args);
unset($args[0]);
if (static::assertTraversable($traversable)) {
foreach ($traversable as $member) {
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"zendframework/zend-feed": "~2.4"
"zendframework/zend-feed": "^2.4"
},
"autoload": {
"psr-4": {
@@ -1,6 +1,7 @@
<?php
namespace Drupal\Component\Datetime;
use Drupal\Component\Utility\ToStringTrait;
/**
@@ -250,7 +251,11 @@ class DateTimePlus {
* (optional) A date/time string. Defaults to 'now'.
* @param mixed $timezone
* (optional) \DateTimeZone object, time zone string or NULL. NULL uses the
* default system time zone. Defaults to NULL.
* default system time zone. Defaults to NULL. Note that the $timezone
* parameter and the current timezone are ignored when the $time parameter
* either is a UNIX timestamp (e.g. @946684800) or specifies a timezone
* (e.g. 2010-01-28T15:00:00+02:00).
* @see http://php.net/manual/en/datetime.construct.php
* @param array $settings
* (optional) Keyed array of settings. Defaults to empty array.
* - langcode: (optional) String two letter language code used to control
@@ -301,8 +306,25 @@ class DateTimePlus {
* Implements the magic __call method.
*
* Passes through all unknown calls onto the DateTime object.
*
* @param string $method
* The method to call on the decorated object.
* @param array $args
* Call arguments.
*
* @return mixed
* The return value from the method on the decorated object. If the proxied
* method call returns a DateTime object, then return the original
* DateTimePlus object, which allows function chaining to work properly.
* Otherwise, the value from the proxied method call is returned.
*
* @throws \Exception
* Thrown when the DateTime object is not set.
* @throws \BadMethodCallException
* Thrown when there is no corresponding method on the DateTime object to
* call.
*/
public function __call($method, $args) {
public function __call($method, array $args) {
// @todo consider using assert() as per https://www.drupal.org/node/2451793.
if (!isset($this->dateTimeObject)) {
throw new \Exception('DateTime object not set.');
@@ -310,19 +332,22 @@ class DateTimePlus {
if (!method_exists($this->dateTimeObject, $method)) {
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method));
}
return call_user_func_array([$this->dateTimeObject, $method], $args);
$result = call_user_func_array([$this->dateTimeObject, $method], $args);
return $result === $this->dateTimeObject ? $this : $result;
}
/**
* Returns the difference between two DateTimePlus objects.
*
* @param \Drupal\Component\Datetime\DateTimePlus|\DateTime $datetime2
* The date to compare to.
* The date to compare to.
* @param bool $absolute
* Should the interval be forced to be positive?
* Should the interval be forced to be positive?
*
* @return \DateInterval
* A DateInterval object representing the difference between the two dates.
* A DateInterval object representing the difference between the two dates.
*
* @throws \BadMethodCallException
* If the input isn't a DateTime or DateTimePlus object.
@@ -428,7 +453,6 @@ class DateTimePlus {
}
/**
* Examines getLastErrors() to see what errors to report.
*
@@ -627,8 +651,9 @@ class DateTimePlus {
* - timezone: (optional) String timezone name. Defaults to the timezone
* of the date object.
*
* @return string
* The formatted value of the date.
* @return string|null
* The formatted value of the date or NULL if there were construction
* errors.
*/
public function format($format, $settings = []) {
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"drupal/core-utility": "~8.2"
"drupal/core-utility": "^8.2"
},
"autoload": {
"psr-4": {
@@ -3,9 +3,7 @@
namespace Drupal\Component\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
use Symfony\Component\DependencyInjection\ScopeInterface;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
@@ -43,14 +41,10 @@ use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceExce
* getAServiceWithAnIdByCamelCase().
* - The function getServiceIds() was added as it has a use-case in core and
* contrib.
* - Scopes are explicitly not allowed, because Symfony 2.8 has deprecated
* them and they will be removed in Symfony 3.0.
* - Synchronized services are explicitly not supported, because Symfony 2.8 has
* deprecated them and they will be removed in Symfony 3.0.
*
* @ingroup container
*/
class Container implements IntrospectableContainerInterface, ResettableContainerInterface {
class Container implements ContainerInterface, ResettableContainerInterface {
/**
* The parameters of the container.
@@ -311,12 +305,8 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
}
}
// Share the service if it is public.
if (!isset($definition['public']) || $definition['public'] !== FALSE) {
// Forward compatibility fix for Symfony 2.8 update.
if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
$this->services[$id] = $service;
}
if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
$this->services[$id] = $service;
}
if (isset($definition['calls'])) {
@@ -361,11 +351,7 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
/**
* {@inheritdoc}
*/
public function set($id, $service, $scope = ContainerInterface::SCOPE_CONTAINER) {
if (!in_array($scope, ['container', 'request']) || ('request' === $scope && 'request' !== $id)) {
@trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
}
public function set($id, $service) {
$this->services[$id] = $service;
}
@@ -587,61 +573,6 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
return $this->getAlternatives($name, array_keys($this->parameters));
}
/**
* {@inheritdoc}
*/
public function enterScope($name) {
if ('request' !== $name) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
/**
* {@inheritdoc}
*/
public function leaveScope($name) {
if ('request' !== $name) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
/**
* {@inheritdoc}
*/
public function addScope(ScopeInterface $scope) {
$name = $scope->getName();
if ('request' !== $name) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
/**
* {@inheritdoc}
*/
public function hasScope($name) {
if ('request' !== $name) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
}
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
/**
* {@inheritdoc}
*/
public function isScopeActive($name) {
@trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
}
/**
* Gets all defined service IDs.
*
@@ -237,18 +237,6 @@ class OptimizedPhpArrayDumper extends Dumper {
$service['calls'] = $this->dumpMethodCalls($definition->getMethodCalls());
}
if (($scope = $definition->getScope()) !== ContainerInterface::SCOPE_CONTAINER) {
if ($scope === ContainerInterface::SCOPE_PROTOTYPE) {
// Scope prototype has been replaced with 'shared' => FALSE.
// This is a Symfony 2.8 forward compatibility fix.
// Reference: https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#dependencyinjection
$service['shared'] = FALSE;
}
else {
throw new InvalidArgumentException("The 'scope' definition is deprecated in Symfony 3.0 and not supported by Drupal 8.");
}
}
// By default services are shared, so just provide the flag, when needed.
if ($definition->isShared() === FALSE) {
$service['shared'] = $definition->isShared();
@@ -136,12 +136,8 @@ class PhpArrayContainer extends Container {
}
}
// Share the service if it is public.
if (!isset($definition['public']) || $definition['public'] !== FALSE) {
// Forward compatibility fix for Symfony 2.8 update.
if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
$this->services[$id] = $service;
}
if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
$this->services[$id] = $service;
}
if (isset($definition['calls'])) {
@@ -12,7 +12,7 @@
},
"require": {
"php": ">=5.5.9",
"symfony/dependency-injection": "~2.8"
"symfony/dependency-injection": "^2.8"
},
"suggest": {
"symfony/expression-language": "For using expressions in service container configuration"
+7 -5
View File
@@ -27,9 +27,11 @@ class Diff {
* Constructor.
* Computes diff between sequences of strings.
*
* @param $from_lines array An array of strings.
* (Typically these are lines from a file.)
* @param $to_lines array An array of strings.
* @param array $from_lines
* An array of strings.
* (Typically these are lines from a file.)
* @param array $to_lines
* An array of strings.
*/
public function __construct($from_lines, $to_lines) {
$eng = new DiffEngine();
@@ -44,8 +46,8 @@ class Diff {
*
* $diff = new Diff($lines1, $lines2);
* $rev = $diff->reverse();
* @return object A Diff object representing the inverse of the
* original diff.
* @return object
* A Diff object representing the inverse of the original diff.
*/
public function reverse() {
$rev = $this;
@@ -195,7 +195,7 @@ class DiffEngine {
}
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $chunk) / $nchunks);
for ( ; $x < $x1; $x++) {
for (; $x < $x1; $x++) {
$line = $flip ? $this->yv[$x] : $this->xv[$x];
if (empty($ymatches[$line])) {
continue;
@@ -302,8 +302,7 @@ class DiffEngine {
//$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
//$nchunks = max(2, min(8, (int)$nchunks));
$nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
list($lcs, $seps)
= $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
list($lcs, $seps) = $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
}
if ($lcs == 0) {
+10 -9
View File
@@ -19,16 +19,17 @@ class MappedDiff extends Diff {
* case-insensitive diffs, or diffs which ignore
* changes in white-space.
*
* @param $from_lines array An array of strings.
* @param array $from_lines
* An array of strings.
* (Typically these are lines from a file.)
* @param $to_lines array An array of strings.
* @param $mapped_from_lines array This array should
* have the same size number of elements as $from_lines.
* The elements in $mapped_from_lines and
* $mapped_to_lines are what is actually compared
* when computing the diff.
* @param $mapped_to_lines array This array should
* have the same number of elements as $to_lines.
* @param array $to_lines
* An array of strings.
* @param array $mapped_from_lines
* This array should have the same size number of elements as $from_lines.
* The elements in $mapped_from_lines and $mapped_to_lines are what is
* actually compared when computing the diff.
* @param array $mapped_to_lines
* This array should have the same number of elements as $to_lines.
*/
public function __construct($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) {
+1 -1
View File
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"drupal/utility": "~8.2"
"drupal/core-utility": "^8.2"
},
"autoload": {
"psr-4": {
@@ -6,8 +6,8 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"drupal/core-filecache": "~8.2",
"drupal/core-serialization": "~8.2"
"drupal/core-file-cache": "^8.2",
"drupal/core-serialization": "^8.2"
},
"autoload": {
"psr-4": {
@@ -2,7 +2,7 @@
namespace Drupal\Component\EventDispatcher;
use Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -36,7 +36,7 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
/**
* The service container.
*
* @var \Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
* @var \Symfony\Component\DependencyInjection\ContainerInterface;
*/
protected $container;
@@ -66,7 +66,7 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
/**
* Constructs a container aware event dispatcher.
*
* @param \Symfony\Component\DependencyInjection\IntrospectableContainerInterface $container
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The service container.
* @param array $listeners
* A nested array of listener definitions keyed by event name and priority.
@@ -77,7 +77,7 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
* A service entry will be resolved to a callable only just before its
* invocation.
*/
public function __construct(IntrospectableContainerInterface $container, array $listeners = []) {
public function __construct(ContainerInterface $container, array $listeners = []) {
$this->container = $container;
$this->listeners = $listeners;
$this->unsorted = [];
@@ -91,9 +91,6 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
$event = new Event();
}
$event->setDispatcher($this);
$event->setName($event_name);
if (isset($this->listeners[$event_name])) {
// Sort listeners if necessary.
if (isset($this->unsorted[$event_name])) {
@@ -6,8 +6,8 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"symfony/dependency-injection": "~2.8",
"symfony/event-dispatcher": "~2.7"
"symfony/dependency-injection": "^2.8",
"symfony/event-dispatcher": "^2.7"
},
"autoload": {
"psr-4": {
@@ -15,7 +15,7 @@ class FileCacheFactory {
/**
* The configuration used to create FileCache objects.
*
* @var array $configuration
* @var array
*/
protected static $configuration;
+2 -2
View File
@@ -104,7 +104,7 @@ class PoItem {
* Set the source string or the array of strings if the translation has
* plurals.
*
* @param string or array $source
* @param string|array $source
*/
public function setSource($source) {
$this->_source = $source;
@@ -124,7 +124,7 @@ class PoItem {
* Set the translation string or the array of strings if the translation has
* plurals.
*
* @param string or array $translation
* @param string|array $translation
*/
public function setTranslation($translation) {
$this->_translation = $translation;
@@ -104,7 +104,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
* If writing the data is not possible.
*/
private function write($data) {
$result = fputs($this->_fd, $data);
$result = fwrite($this->_fd, $data);
if ($result === FALSE) {
throw new Exception('Unable to write data: ' . substr($data, 0, 20));
}
@@ -10,7 +10,7 @@
},
"require": {
"php": ">=5.5.9",
"drupal/core-utility": "~8.2"
"drupal/core-utility": "^8.2"
},
"autoload": {
"psr-4": {
@@ -2,7 +2,7 @@
namespace Drupal\Component\HttpFoundation;
use \Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Provides a common base class for safe redirects.
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"symfony/http-foundation": "~2.7"
"symfony/http-foundation": "^2.7"
},
"autoload": {
"psr-4": {
@@ -44,7 +44,7 @@ interface PhpStorageInterface {
* @param string $name
* The virtual file name. Can be a relative path.
* @param string $code
* The PHP code to be saved.
* The PHP code to be saved.
*
* @return bool
* TRUE if the save succeeded, FALSE if it failed.
@@ -2,7 +2,7 @@
namespace Drupal\Component\Plugin;
use \Drupal\Component\Plugin\Context\ContextInterface;
use Drupal\Component\Plugin\Context\ContextInterface;
/**
* Interface for defining context aware plugins.
@@ -5,4 +5,4 @@ namespace Drupal\Component\Plugin\Exception;
/**
* An exception class to be thrown for context plugin exceptions.
*/
class ContextException extends \Exception implements ExceptionInterface { }
class ContextException extends \Exception implements ExceptionInterface {}
@@ -5,4 +5,4 @@ namespace Drupal\Component\Plugin\Exception;
/**
* Exception interface for all exceptions thrown by the Plugin component.
*/
interface ExceptionInterface { }
interface ExceptionInterface {}
@@ -2,10 +2,10 @@
namespace Drupal\Component\Plugin\Exception;
use \BadMethodCallException;
use BadMethodCallException;
/**
* Exception thrown when a decorator's _call() method is triggered, but the
* decorated object does not contain the requested method.
*/
class InvalidDecoratedMethod extends BadMethodCallException implements ExceptionInterface { }
class InvalidDecoratedMethod extends BadMethodCallException implements ExceptionInterface {}
@@ -5,4 +5,4 @@ namespace Drupal\Component\Plugin\Exception;
/**
* Exception to be thrown if a plugin tries to use an invalid deriver.
*/
class InvalidDeriverException extends PluginException { }
class InvalidDeriverException extends PluginException {}
@@ -8,4 +8,4 @@ namespace Drupal\Component\Plugin\Exception;
* Extended interface for exceptions thrown specifically by the Mapper subsystem
* within the Plugin component.
*/
interface MapperExceptionInterface extends ExceptionInterface { }
interface MapperExceptionInterface extends ExceptionInterface {}
@@ -6,4 +6,4 @@ namespace Drupal\Component\Plugin\Exception;
* Generic Plugin exception class to be thrown when no more specific class
* is applicable.
*/
class PluginException extends \Exception implements ExceptionInterface { }
class PluginException extends \Exception implements ExceptionInterface {}
@@ -22,7 +22,7 @@ interface MapperInterface {
*
* @return object|false
* A fully configured plugin instance. The interface of the plugin instance
* will depends on the plugin type. If no instance can be retrieved, FALSE
* will depend on the plugin type. If no instance can be retrieved, FALSE
* will be returned.
*/
public function getInstance(array $options);
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"symfony/validator": "~2.7"
"symfony/validator": "^2.7"
},
"autoload": {
"psr-4": {
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"drupal/core-utility": "~8.2"
"drupal/core-utility": "^8.2"
},
"autoload": {
"psr-4": {
@@ -29,6 +29,9 @@ class YamlPecl implements SerializationInterface {
public static function decode($raw) {
static $init;
if (!isset($init)) {
// Decode binary, since Symfony YAML parser encodes binary from 3.1
// onwards.
ini_set('yaml.decode_binary', 1);
// We never want to unserialize !php/object.
ini_set('yaml.decode_php', 0);
$init = TRUE;
@@ -5,6 +5,7 @@ namespace Drupal\Component\Serialization;
use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Yaml\Dumper;
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
/**
* Default serialization for YAML using the Symfony component.
@@ -16,9 +17,9 @@ class YamlSymfony implements SerializationInterface {
*/
public static function encode($data) {
try {
$yaml = new Dumper();
$yaml->setIndentation(2);
return $yaml->dump($data, PHP_INT_MAX, 0, TRUE, FALSE);
// Set the indentation to 2 to match Drupal's coding standards.
$yaml = new Dumper(2);
return $yaml->dump($data, PHP_INT_MAX, 0, SymfonyYaml::DUMP_EXCEPTION_ON_INVALID_TYPE);
}
catch (\Exception $e) {
throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e);
@@ -33,7 +34,7 @@ class YamlSymfony implements SerializationInterface {
$yaml = new Parser();
// Make sure we have a single trailing newline. A very simple config like
// 'foo: bar' with no newline will fail to parse otherwise.
return $yaml->parse($raw, TRUE, FALSE);
return $yaml->parse($raw, SymfonyYaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
}
catch (\Exception $e) {
throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e);
@@ -6,7 +6,7 @@
"license": "GPL-2.0+",
"require": {
"php": ">=5.5.9",
"symfony/yaml": "~2.7"
"symfony/yaml": "^2.7"
},
"autoload": {
"psr-4": {
@@ -328,7 +328,7 @@ class NestedArray {
// Renumber integer keys as array_merge_recursive() does unless
// $preserve_integer_keys is set to TRUE. Note that PHP automatically
// converts array keys that are integer strings (e.g., '1') to integers.
if (is_integer($key) && !$preserve_integer_keys) {
if (is_int($key) && !$preserve_integer_keys) {
$result[] = $value;
}
// Recurse when both values are arrays.
+1 -1
View File
@@ -50,7 +50,7 @@ class Number {
// can't be represented with single precision floats are acceptable. The
// fractional part of a float has 24 bits. That means remainders smaller than
// $step * 2^-24 are acceptable.
$computed_acceptable_error = (double)($step / pow(2.0, 24));
$computed_acceptable_error = (double) ($step / pow(2.0, 24));
return $computed_acceptable_error >= $remainder || $remainder >= ($step - $computed_acceptable_error);
}
+5 -2
View File
@@ -143,7 +143,9 @@ class Random {
$vowels = ["a", "e", "i", "o", "u"];
$cons = ["b", "c", "d", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "u", "v", "w", "tr",
"cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr", "sl", "cl", "sh"];
"cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr",
"sl", "cl", "sh",
];
$num_vowels = count($vowels);
$num_cons = count($cons);
@@ -219,7 +221,8 @@ class Random {
"utrum", "uxor", "valde", "valetudo", "validus", "vel", "velit",
"veniam", "venio", "vereor", "vero", "verto", "vicis", "vindico",
"virtus", "voco", "volutpat", "vulpes", "vulputate", "wisi", "ymo",
"zelus"];
"zelus",
];
$dictionary_flipped = array_flip($dictionary);
$greeking = '';
+3 -3
View File
@@ -20,7 +20,7 @@ class Timer {
* @param $name
* The name of the timer.
*/
static public function start($name) {
public static function start($name) {
static::$timers[$name]['start'] = microtime(TRUE);
static::$timers[$name]['count'] = isset(static::$timers[$name]['count']) ? ++static::$timers[$name]['count'] : 1;
}
@@ -34,7 +34,7 @@ class Timer {
* @return int
* The current timer value in ms.
*/
static public function read($name) {
public static function read($name) {
if (isset(static::$timers[$name]['start'])) {
$stop = microtime(TRUE);
$diff = round(($stop - static::$timers[$name]['start']) * 1000, 2);
@@ -57,7 +57,7 @@ class Timer {
* A timer array. The array contains the number of times the timer has been
* started and stopped (count) and the accumulated timer value in ms (time).
*/
static public function stop($name) {
public static function stop($name) {
if (isset(static::$timers[$name]['start'])) {
$stop = microtime(TRUE);
$diff = round(($stop - static::$timers[$name]['start']) * 1000, 2);
@@ -264,7 +264,9 @@ EOD;
return substr($string, 0, $len);
}
// Scan backwards to beginning of the byte sequence.
while (--$len >= 0 && ord($string[$len]) >= 0x80 && ord($string[$len]) < 0xC0);
// @todo Make the code more readable in https://www.drupal.org/node/2911497.
while (--$len >= 0 && ord($string[$len]) >= 0x80 && ord($string[$len]) < 0xC0) {
}
return substr($string, 0, $len);
}
@@ -376,7 +378,7 @@ EOD;
*/
public static function ucwords($text) {
$regex = '/(^|[' . static::PREG_CLASS_WORD_BOUNDARY . '])([^' . static::PREG_CLASS_WORD_BOUNDARY . '])/u';
return preg_replace_callback($regex, function(array $matches) {
return preg_replace_callback($regex, function (array $matches) {
return $matches[1] . Unicode::strtoupper($matches[2]);
}, $text);
}
@@ -580,7 +582,7 @@ EOD;
* Returns < 0 if $str1 is less than $str2; > 0 if $str1 is greater than
* $str2, and 0 if they are equal.
*/
public static function strcasecmp($str1 , $str2) {
public static function strcasecmp($str1, $str2) {
return strcmp(static::strtoupper($str1), static::strtoupper($str2));
}
@@ -607,7 +609,8 @@ EOD;
*/
public static function mimeHeaderEncode($string) {
if (preg_match('/[^\x20-\x7E]/', $string)) {
$chunk_size = 47; // floor((75 - strlen("=?UTF-8?B??=")) * 0.75);
// floor((75 - strlen("=?UTF-8?B??=")) * 0.75);
$chunk_size = 47;
$len = strlen($string);
$output = '';
while ($len > 0) {
@@ -148,6 +148,11 @@ class UrlHelper {
$scheme_delimiter_position = strpos($url, '://');
$query_delimiter_position = strpos($url, '?');
if ($scheme_delimiter_position !== FALSE && ($query_delimiter_position === FALSE || $scheme_delimiter_position < $query_delimiter_position)) {
// Split off the fragment, if any.
if (strpos($url, '#') !== FALSE) {
list($url, $options['fragment']) = explode('#', $url, 2);
}
// Split off everything before the query string into 'path'.
$parts = explode('?', $url);
@@ -158,12 +163,7 @@ class UrlHelper {
}
// If there is a query string, transform it into keyed query parameters.
if (isset($parts[1])) {
$query_parts = explode('#', $parts[1]);
parse_str($query_parts[0], $options['query']);
// Take over the fragment, if there is any.
if (isset($query_parts[1])) {
$options['fragment'] = $query_parts[1];
}
parse_str($parts[1], $options['query']);
}
}
// Internal URLs.
@@ -7,7 +7,7 @@
"require": {
"php": ">=5.5.9",
"paragonie/random_compat": "^1.0|^2.0",
"drupal/core-render": "~8.2"
"drupal/core-render": "^8.2"
},
"autoload": {
"psr-4": {
+1 -1
View File
@@ -10,7 +10,7 @@
},
"require": {
"php": ">=5.5.9",
"drupal/core-utility": "~8.2"
"drupal/core-utility": "^8.2"
},
"autoload": {
"psr-4": {
@@ -18,7 +18,7 @@ class AccessResultForbidden extends AccessResult implements AccessResultReasonIn
* Constructs a new AccessResultForbidden instance.
*
* @param null|string $reason
* (optional) a message to provide details about this access result
* (optional) A message to provide details about this access result.
*/
public function __construct($reason = NULL) {
$this->reason = $reason;
@@ -18,7 +18,7 @@ class AccessResultNeutral extends AccessResult implements AccessResultReasonInte
* Constructs a new AccessResultNeutral instance.
*
* @param null|string $reason
* (optional) a message to provide details about this access result
* (optional) A message to provide details about this access result
*/
public function __construct($reason = NULL) {
$this->reason = $reason;
@@ -17,7 +17,7 @@ abstract class ConfigurableActionBase extends ActionBase implements Configurable
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->configuration += $this->defaultConfiguration();
$this->setConfiguration($configuration);
}
/**
@@ -38,7 +38,7 @@ abstract class ConfigurableActionBase extends ActionBase implements Configurable
* {@inheritdoc}
*/
public function setConfiguration(array $configuration) {
$this->configuration = $configuration;
$this->configuration = $configuration + $this->defaultConfiguration();
}
/**
+1 -1
View File
@@ -45,7 +45,7 @@ class AssetResolver implements AssetResolverInterface {
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface $language_manager
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
@@ -175,7 +175,7 @@ class CssCollectionOptimizer implements AssetCollectionOptimizerInterface {
public function deleteAll() {
$this->state->delete('drupal_css_cache_files');
$delete_stale = function($uri) {
$delete_stale = function ($uri) {
// Default stale file threshold is 30 days.
if (REQUEST_TIME - filemtime($uri) > \Drupal::config('system.performance')->get('stale_file_threshold')) {
file_unmanaged_delete($uri);
@@ -4,7 +4,6 @@ namespace Drupal\Core\Asset;
use Drupal\Core\State\StateInterface;
/**
* Optimizes JavaScript assets.
*/
@@ -178,7 +177,7 @@ class JsCollectionOptimizer implements AssetCollectionOptimizerInterface {
*/
public function deleteAll() {
$this->state->delete('system.js_cache_files');
$delete_stale = function($uri) {
$delete_stale = function ($uri) {
// Default stale file threshold is 30 days.
if (REQUEST_TIME - filemtime($uri) > \Drupal::config('system.performance')->get('stale_file_threshold')) {
file_unmanaged_delete($uri);
@@ -129,13 +129,17 @@ class LibraryDiscoveryParser {
// properly resolve dependencies for all (css) libraries per category,
// and only once prior to rendering out an HTML page.
if ($type == 'css' && !empty($library[$type])) {
assert('\Drupal\Core\Asset\LibraryDiscoveryParser::validateCssLibrary($library[$type]) < 2', 'CSS files should be specified as key/value pairs, where the values are configuration options. See https://www.drupal.org/node/2274843.');
assert('\Drupal\Core\Asset\LibraryDiscoveryParser::validateCssLibrary($library[$type]) === 0', 'CSS must be nested under a category. See https://www.drupal.org/node/2274843.');
foreach ($library[$type] as $category => $files) {
$category_weight = 'CSS_' . strtoupper($category);
assert('defined($category_weight)', 'Invalid CSS category: ' . $category . '. See https://www.drupal.org/node/2274843.');
foreach ($files as $source => $options) {
if (!isset($options['weight'])) {
$options['weight'] = 0;
}
// Apply the corresponding weight defined by CSS_* constants.
$options['weight'] += constant('CSS_' . strtoupper($category));
$options['weight'] += constant($category_weight);
$library[$type][$source] = $options;
}
unset($library[$type][$category]);
@@ -460,4 +464,34 @@ class LibraryDiscoveryParser {
return $overriding_asset;
}
/**
* Validates CSS library structure.
*
* @param array $library
* The library definition array.
*
* @return int
* Returns based on validity:
* - 0 if the library definition is valid
* - 1 if the library definition has improper nesting
* - 2 if the library definition specifies files as an array
*/
public static function validateCssLibrary($library) {
$categories = [];
// Verify options first and return early if invalid.
foreach ($library as $category => $files) {
if (!is_array($files)) {
return 2;
}
$categories[] = $category;
foreach ($files as $source => $options) {
if (!is_array($options)) {
return 1;
}
}
}
return 0;
}
}
@@ -200,6 +200,8 @@ class BatchStorage implements BatchStorageInterface {
/**
* Defines the schema for the batch table.
*
* @internal
*/
public function schemaDefinition() {
return [
@@ -12,4 +12,4 @@ namespace Drupal\Core\Block;
*
* @ingroup block_api
*/
interface MessagesBlockPluginInterface extends BlockPluginInterface { }
interface MessagesBlockPluginInterface extends BlockPluginInterface {}
@@ -1,6 +1,7 @@
<?php
namespace Drupal\Core\Cache;
/**
* Defines a chained cache implementation for combining multiple cache backends.
*
+6 -6
View File
@@ -20,9 +20,9 @@ class Cache {
* Merges arrays of cache contexts and removes duplicates.
*
* @param array $a
* Cache contexts array to merge.
* Cache contexts array to merge.
* @param array $b
* Cache contexts array to merge.
* Cache contexts array to merge.
*
* @return string[]
* The merged array of cache contexts.
@@ -46,9 +46,9 @@ class Cache {
* they're constituted from.
*
* @param array $a
* Cache tags array to merge.
* Cache tags array to merge.
* @param array $b
* Cache tags array to merge.
* Cache tags array to merge.
*
* @return string[]
* The merged array of cache tags.
@@ -67,9 +67,9 @@ class Cache {
* Ensures infinite max-age (Cache::PERMANENT) is taken into account.
*
* @param int $a
* Max age value to merge.
* Max age value to merge.
* @param int $b
* Max age value to merge.
* Max age value to merge.
*
* @return int
* The minimum max-age value.
@@ -91,7 +91,7 @@ interface CacheBackendInterface {
* identify objects used to build the cache item, which should trigger
* cache invalidation when updated. For example if a cached item represents
* a node, both the node ID and the author's user ID might be passed in as
* tags. For example array('node' => array(123), 'user' => array(92)).
* tags. For example ['node:123', 'node:456', 'user:789'].
*
* @see \Drupal\Core\Cache\CacheBackendInterface::get()
* @see \Drupal\Core\Cache\CacheBackendInterface::getMultiple()
@@ -1,6 +1,7 @@
<?php
namespace Drupal\Core\Cache;
use Drupal\Core\Site\Settings;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
@@ -25,11 +25,28 @@ class HeadersCacheContext extends RequestStackCacheContextBase implements Calcul
*/
public function getContext($header = NULL) {
if ($header === NULL) {
return $this->requestStack->getCurrentRequest()->headers->all();
$headers = $this->requestStack->getCurrentRequest()->headers->all();
// Order headers by name to have less cache variations.
ksort($headers);
$result = '';
foreach ($headers as $name => $value) {
if ($result) {
$result .= '&';
}
// Sort values to minimize cache variations.
sort($value);
$result .= $name . '=' . implode(',', $value);
}
return $result;
}
else {
return $this->requestStack->getCurrentRequest()->headers->get($header);
elseif ($this->requestStack->getCurrentRequest()->headers->has($header)) {
$value = $this->requestStack->getCurrentRequest()->headers->get($header);
if ($value !== '') {
return $value;
}
return '?valueless?';
}
return '';
}
/**
@@ -22,8 +22,11 @@ class SessionCacheContext extends RequestStackCacheContextBase {
* {@inheritdoc}
*/
public function getContext() {
$sid = $this->requestStack->getCurrentRequest()->getSession()->getId();
return Crypt::hashBase64($sid);
$request = $this->requestStack->getCurrentRequest();
if ($request->hasSession()) {
return Crypt::hashBase64($request->getSession()->getId());
}
return 'none';
}
}
+57 -1
View File
@@ -16,6 +16,30 @@ use Drupal\Core\Database\SchemaObjectExistsException;
*/
class DatabaseBackend implements CacheBackendInterface {
/**
* The default maximum number of rows that this cache bin table can store.
*
* This maximum is introduced to ensure that the database is not filled with
* hundred of thousand of cache entries with gigabytes in size.
*
* Read about how to change it in the @link cache Cache API topic. @endlink
*/
const DEFAULT_MAX_ROWS = 5000;
/**
* -1 means infinite allows numbers of rows for the cache backend.
*/
const MAXIMUM_NONE = -1;
/**
* The maximum number of rows that this cache bin table is allowed to store.
*
* @see ::MAXIMUM_NONE
*
* @var int
*/
protected $maxRows;
/**
* @var string
*/
@@ -45,14 +69,18 @@ class DatabaseBackend implements CacheBackendInterface {
* The cache tags checksum provider.
* @param string $bin
* The cache bin for which the object is created.
* @param int $max_rows
* (optional) The maximum number of rows that are allowed in this cache bin
* table.
*/
public function __construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider, $bin) {
public function __construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider, $bin, $max_rows = NULL) {
// All cache tables should be prefixed with 'cache_'.
$bin = 'cache_' . $bin;
$this->bin = $bin;
$this->connection = $connection;
$this->checksumProvider = $checksum_provider;
$this->maxRows = $max_rows === NULL ? static::DEFAULT_MAX_ROWS : $max_rows;
}
/**
@@ -326,6 +354,22 @@ class DatabaseBackend implements CacheBackendInterface {
*/
public function garbageCollection() {
try {
// Bounded size cache bin, using FIFO.
if ($this->maxRows !== static::MAXIMUM_NONE) {
$first_invalid_create_time = $this->connection->select($this->bin)
->fields($this->bin, ['created'])
->orderBy("{$this->bin}.created", 'DESC')
->range($this->maxRows, $this->maxRows + 1)
->execute()
->fetchField();
if ($first_invalid_create_time) {
$this->connection->delete($this->bin)
->condition('created', $first_invalid_create_time, '<=')
->execute();
}
}
$this->connection->delete($this->bin)
->condition('expire', Cache::PERMANENT, '<>')
->condition('expire', REQUEST_TIME, '<')
@@ -417,6 +461,8 @@ class DatabaseBackend implements CacheBackendInterface {
/**
* Defines the schema for the {cache_*} bin tables.
*
* @internal
*/
public function schemaDefinition() {
$schema = [
@@ -472,10 +518,20 @@ class DatabaseBackend implements CacheBackendInterface {
],
'indexes' => [
'expire' => ['expire'],
'created' => ['created'],
],
'primary key' => ['cid'],
];
return $schema;
}
/**
* The maximum number of rows that this cache bin table is allowed to store.
*
* @return int
*/
public function getMaxRows() {
return $this->maxRows;
}
}
@@ -3,6 +3,7 @@
namespace Drupal\Core\Cache;
use Drupal\Core\Database\Connection;
use Drupal\Core\Site\Settings;
class DatabaseBackendFactory implements CacheFactoryInterface {
@@ -20,6 +21,13 @@ class DatabaseBackendFactory implements CacheFactoryInterface {
*/
protected $checksumProvider;
/**
* The settings array.
*
* @var \Drupal\Core\Site\Settings
*/
protected $settings;
/**
* Constructs the DatabaseBackendFactory object.
*
@@ -27,10 +35,15 @@ class DatabaseBackendFactory implements CacheFactoryInterface {
* Database connection
* @param \Drupal\Core\Cache\CacheTagsChecksumInterface $checksum_provider
* The cache tags checksum provider.
* @param \Drupal\Core\Site\Settings $settings
* (optional) The settings array.
*
* @throws \BadMethodCallException
*/
public function __construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider) {
public function __construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider, Settings $settings = NULL) {
$this->connection = $connection;
$this->checksumProvider = $checksum_provider;
$this->settings = $settings ?: Settings::getInstance();
}
/**
@@ -43,7 +56,35 @@ class DatabaseBackendFactory implements CacheFactoryInterface {
* The cache backend object for the specified cache bin.
*/
public function get($bin) {
return new DatabaseBackend($this->connection, $this->checksumProvider, $bin);
$max_rows = $this->getMaxRowsForBin($bin);
return new DatabaseBackend($this->connection, $this->checksumProvider, $bin, $max_rows);
}
/**
* Gets the max rows for the specified cache bin.
*
* @param string $bin
* The cache bin for which the object is created.
*
* @return int
* The maximum number of rows for the given bin. Defaults to
* DatabaseBackend::DEFAULT_MAX_ROWS.
*/
protected function getMaxRowsForBin($bin) {
$max_rows_settings = $this->settings->get('database_cache_max_rows');
// First, look for a cache bin specific setting.
if (isset($max_rows_settings['bins'][$bin])) {
$max_rows = $max_rows_settings['bins'][$bin];
}
// Second, use configured default backend.
elseif (isset($max_rows_settings['default'])) {
$max_rows = $max_rows_settings['default'];
}
else {
// Fall back to the default max rows if nothing else is configured.
$max_rows = DatabaseBackend::DEFAULT_MAX_ROWS;
}
return $max_rows;
}
}
@@ -163,6 +163,8 @@ class DatabaseCacheTagsChecksum implements CacheTagsChecksumInterface, CacheTags
/**
* Defines the schema for the {cachetags} table.
*
* @internal
*/
public function schemaDefinition() {
$schema = [
@@ -69,7 +69,7 @@ class DbDumpCommand extends DbCommandBase {
* The database connection to use.
* @param array $schema_only
* Table patterns for which to only dump the schema, no data.
* @return string The PHP script.
* @return string
* The PHP script.
*/
protected function generateScript(Connection $connection, array $schema_only = []) {
@@ -102,7 +102,7 @@ class DbDumpCommand extends DbCommandBase {
*
* @param \Drupal\Core\Database\Connection $connection
* The database connection to use.
* @return array An array of table names.
* @return array
* An array of table names.
*/
protected function getTables(Connection $connection) {
+20 -13
View File
@@ -72,35 +72,42 @@ class Composer {
* Add vendor classes to Composer's static classmap.
*/
public static function preAutoloadDump(Event $event) {
// Get the configured vendor directory.
$vendor_dir = $event->getComposer()->getConfig()->get('vendor-dir');
// We need the root package so we can add our classmaps to its loader.
$package = $event->getComposer()->getPackage();
// We need the local repository so that we can query and see if it's likely
// that our files are present there.
$repository = $event->getComposer()->getRepositoryManager()->getLocalRepository();
// This is, essentially, a null constraint. We only care whether the package
// is present in vendor/ yet, but findPackage() requires it.
// is present in the vendor directory yet, but findPackage() requires it.
$constraint = new Constraint('>', '');
// It's possible that there is no classmap specified in a custom project
// composer.json file. We need one so we can optimize lookup for some of our
// dependencies.
$autoload = $package->getAutoload();
if (!isset($autoload['classmap'])) {
$autoload['classmap'] = [];
}
// Check for our packages, and then optimize them if they're present.
if ($repository->findPackage('symfony/http-foundation', $constraint)) {
$autoload = $package->getAutoload();
$autoload['classmap'] = array_merge($autoload['classmap'], [
'vendor/symfony/http-foundation/Request.php',
'vendor/symfony/http-foundation/ParameterBag.php',
'vendor/symfony/http-foundation/FileBag.php',
'vendor/symfony/http-foundation/ServerBag.php',
'vendor/symfony/http-foundation/HeaderBag.php',
$vendor_dir . '/symfony/http-foundation/Request.php',
$vendor_dir . '/symfony/http-foundation/ParameterBag.php',
$vendor_dir . '/symfony/http-foundation/FileBag.php',
$vendor_dir . '/symfony/http-foundation/ServerBag.php',
$vendor_dir . '/symfony/http-foundation/HeaderBag.php',
]);
$package->setAutoload($autoload);
}
if ($repository->findPackage('symfony/http-kernel', $constraint)) {
$autoload = $package->getAutoload();
$autoload['classmap'] = array_merge($autoload['classmap'], [
'vendor/symfony/http-kernel/HttpKernel.php',
'vendor/symfony/http-kernel/HttpKernelInterface.php',
'vendor/symfony/http-kernel/TerminableInterface.php',
$vendor_dir . '/symfony/http-kernel/HttpKernel.php',
$vendor_dir . '/symfony/http-kernel/HttpKernelInterface.php',
$vendor_dir . '/symfony/http-kernel/TerminableInterface.php',
]);
$package->setAutoload($autoload);
}
$package->setAutoload($autoload);
}
/**
@@ -278,7 +278,7 @@ class CachedStorage implements StorageInterface, StorageCacheInterface {
*/
protected function getCacheKeys(array $names) {
$prefix = $this->getCollectionPrefix();
$cache_keys = array_map(function($name) use ($prefix) {
$cache_keys = array_map(function ($name) use ($prefix) {
return $prefix . $name;
}, $names);
+1 -1
View File
@@ -7,7 +7,7 @@ use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
use Drupal\Core\Cache\RefinableCacheableDependencyTrait;
use \Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
/**
* Provides a base class for configuration objects with get/set support.
@@ -306,7 +306,7 @@ class ConfigFactory implements ConfigFactoryInterface, EventSubscriberInterface
* An array of cache keys that match the provided config name.
*/
protected function getConfigCacheKeys($name) {
return array_filter(array_keys($this->cache), function($key) use ($name) {
return array_filter(array_keys($this->cache), function ($key) use ($name) {
// Return TRUE if the key is the name or starts with the configuration
// name plus the delimiter.
return $key === $name || strpos($key, $name . ':') === 0;
@@ -185,7 +185,7 @@ class ConfigInstaller implements ConfigInstallerInterface {
$existing_config = $this->getActiveStorages()->listAll();
$list = array_unique(array_merge($storage->listAll(), $optional_profile_config));
$list = array_filter($list, function($config_name) use ($existing_config) {
$list = array_filter($list, function ($config_name) use ($existing_config) {
// Only list configuration that:
// - does not already exist
// - is a configuration entity (this also excludes config that has an
@@ -233,7 +233,7 @@ class ConfigManager implements ConfigManagerInterface {
// dependencies on the config entity classes. Assume data with UUID is a
// config entity. Only configuration entities can be depended on so we can
// ignore everything else.
$data = array_map(function($config) {
$data = array_map(function ($config) {
$data = $config->get();
if (isset($data['uuid'])) {
return $data;
@@ -452,7 +452,9 @@ class ConfigManager implements ConfigManagerInterface {
// Key the entity arrays by config dependency name to make searching easy.
foreach (['config', 'content'] as $dependency_type) {
$affected_dependencies[$dependency_type] = array_combine(
array_map(function ($entity) { return $entity->getConfigDependencyName(); }, $affected_dependencies[$dependency_type]),
array_map(function ($entity) {
return $entity->getConfigDependencyName();
}, $affected_dependencies[$dependency_type]),
$affected_dependencies[$dependency_type]
);
}
@@ -180,6 +180,8 @@ class DatabaseStorage implements StorageInterface {
/**
* Defines the schema for the configuration table.
*
* @internal
*/
protected static function schemaDefinition() {
$schema = [
@@ -318,7 +320,8 @@ class DatabaseStorage implements StorageInterface {
public function getAllCollectionNames() {
try {
return $this->connection->query('SELECT DISTINCT collection FROM {' . $this->connection->escapeTable($this->table) . '} WHERE collection <> :collection ORDER by collection', [
':collection' => StorageInterface::DEFAULT_COLLECTION]
':collection' => StorageInterface::DEFAULT_COLLECTION,
]
)->fetchCol();
}
catch (\Exception $e) {
@@ -316,6 +316,13 @@ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStora
return !$config->isNew();
}
/**
* {@inheritdoc}
*/
public function hasData() {
return (bool) $this->configFactory->listAll($this->getPrefix());
}
/**
* Gets entities from the static cache.
*
@@ -50,7 +50,7 @@ class Condition extends ConditionBase {
// matter and this config object does not match.
// If OR and it is matching, then the rest of conditions do not
// matter and this config object does match.
if ($and != $match ) {
if ($and != $match) {
break;
}
}
@@ -154,6 +154,13 @@ class Condition extends ConditionBase {
* TRUE when matches else FALSE.
*/
protected function match(array $condition, $value) {
// "IS NULL" and "IS NOT NULL" conditions can also deal with array values,
// so we return early for them to avoid problems.
if (in_array($condition['operator'], ['IS NULL', 'IS NOT NULL'], TRUE)) {
$should_be_set = $condition['operator'] === 'IS NOT NULL';
return $should_be_set === isset($value);
}
if (isset($value)) {
// We always want a case-insensitive match.
if (!is_bool($value)) {
@@ -183,15 +190,11 @@ class Condition extends ConditionBase {
return strpos($value, $condition['value']) !== FALSE;
case 'ENDS_WITH':
return substr($value, -strlen($condition['value'])) === (string) $condition['value'];
case 'IS NOT NULL':
return TRUE;
case 'IS NULL':
return FALSE;
default:
throw new QueryException('Invalid condition operator.');
}
}
return $condition['operator'] === 'IS NULL';
return FALSE;
}
}
@@ -88,7 +88,7 @@ class Query extends QueryBase implements QueryInterface {
foreach ($this->sort as $sort) {
$direction = $sort['direction'] == 'ASC' ? -1 : 1;
$field = $sort['field'];
uasort($result, function($a, $b) use ($field, $direction) {
uasort($result, function ($a, $b) use ($field, $direction) {
return ($a[$field] <= $b[$field]) ? $direction : -$direction;
});
}
@@ -133,7 +133,7 @@ class InstallStorage extends FileStorage {
else {
$return = [];
foreach ($names as $index => $name) {
if (strpos($name, $prefix) === 0 ) {
if (strpos($name, $prefix) === 0) {
$return[$index] = $names[$index];
}
}
@@ -2,10 +2,12 @@
namespace Drupal\Core\Config\Schema;
use Drupal\Core\TypedData\ComplexDataInterface;
/**
* Defines a generic configuration element that contains multiple properties.
*/
abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface {
abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface, ComplexDataInterface {
/**
* Parsed elements.
@@ -46,7 +48,7 @@ abstract class ArrayElement extends Element implements \IteratorAggregate, Typed
*
* @return \Drupal\Core\TypedData\DataDefinitionInterface
*/
protected abstract function getElementDefinition($key);
abstract protected function getElementDefinition($key);
/**
* {@inheritdoc}
@@ -161,4 +163,25 @@ abstract class ArrayElement extends Element implements \IteratorAggregate, Typed
return isset($this->definition['nullable']) && $this->definition['nullable'] == TRUE;
}
/**
* {@inheritdoc}
*/
public function set($property_name, $value, $notify = TRUE) {
$this->value[$property_name] = $value;
// Config schema elements do not make use of notifications. Thus, we skip
// notifying parents.
return $this;
}
/**
* {@inheritdoc}
*/
public function getProperties($include_computed = FALSE) {
$properties = [];
foreach (array_keys($this->value) as $name) {
$properties[$name] = $this->get($name);
}
return $properties;
}
}
@@ -55,9 +55,7 @@ trait SchemaCheckTrait {
if (!$typed_config->hasConfigSchema($config_name)) {
return FALSE;
}
$definition = $typed_config->getDefinition($config_name);
$data_definition = $typed_config->buildDataDefinition($definition, $config_data);
$this->schema = $typed_config->create($data_definition, $config_data);
$this->schema = $typed_config->createFromNameAndData($config_name, $config_data);
$errors = [];
foreach ($config_data as $key => $value) {
$errors = array_merge($errors, $this->checkValue($key, $value));
@@ -10,6 +10,12 @@ namespace Drupal\Core\Config\Schema;
*
* Read https://www.drupal.org/node/1905070 for more details about configuration
* schema, types and type resolution.
*
* Note that sequences implement the typed data ComplexDataInterface (via the
* parent ArrayElement) rather than the ListInterface. This is because sequences
* may have named keys, which is not supported by ListInterface. From the typed
* data API perspective sequences are handled as ordered mappings without
* metadata about existing properties.
*/
class Sequence extends ArrayElement {
@@ -0,0 +1,28 @@
<?php
namespace Drupal\Core\Config\Schema;
use Drupal\Core\TypedData\ListDataDefinition;
/**
* A typed data definition class for defining sequences in configuration.
*/
class SequenceDataDefinition extends ListDataDefinition {
/**
* Gets the description of how the sequence should be sorted.
*
* Only the top level of the array should be sorted. Top-level keys should be
* discarded when using 'value' sorting. If the sequence is an associative
* array 'key' sorting is recommended, if not 'value' sorting is recommended.
*
* @return string|null
* May be 'key' (to sort by key), 'value' (to sort by value, discarding
* keys), or NULL (if the schema does not describe how the sequence should
* be sorted).
*/
public function getOrderBy() {
return isset($this->definition['orderby']) ? $this->definition['orderby'] : NULL;
}
}
@@ -3,6 +3,8 @@
namespace Drupal\Core\Config;
use Drupal\Core\Config\Schema\Ignore;
use Drupal\Core\Config\Schema\Sequence;
use Drupal\Core\Config\Schema\SequenceDataDefinition;
use Drupal\Core\TypedData\PrimitiveInterface;
use Drupal\Core\TypedData\Type\FloatInterface;
use Drupal\Core\TypedData\Type\IntegerInterface;
@@ -129,9 +131,7 @@ abstract class StorableConfigBase extends ConfigBase {
*/
protected function getSchemaWrapper() {
if (!isset($this->schemaWrapper)) {
$definition = $this->typedConfigManager->getDefinition($this->name);
$data_definition = $this->typedConfigManager->buildDataDefinition($definition, $this->data);
$this->schemaWrapper = $this->typedConfigManager->create($data_definition, $this->data);
$this->schemaWrapper = $this->typedConfigManager->createFromNameAndData($this->name, $this->data);
}
return $this->schemaWrapper;
}
@@ -210,6 +210,29 @@ abstract class StorableConfigBase extends ConfigBase {
foreach ($value as $nested_value_key => $nested_value) {
$value[$nested_value_key] = $this->castValue($key . '.' . $nested_value_key, $nested_value);
}
if ($element instanceof Sequence) {
$data_definition = $element->getDataDefinition();
if ($data_definition instanceof SequenceDataDefinition) {
// Apply any sorting defined on the schema.
switch ($data_definition->getOrderBy()) {
case 'key':
ksort($value);
break;
case 'value':
// The PHP documentation notes that "Be careful when sorting
// arrays with mixed types values because sort() can produce
// unpredictable results". There is no risk here because
// \Drupal\Core\Config\StorableConfigBase::castValue() has
// already cast all values to the same type using the
// configuration schema.
sort($value);
break;
}
}
}
}
return $value;
}
@@ -433,8 +433,8 @@ class StorageComparer implements StorageComparerInterface {
*
* @see \Drupal\Core\Config\StorageComparerInterface::extractRenameNames()
*/
protected function createRenameName($name1, $name2) {
return $name1 . '::' . $name2;
protected function createRenameName($old_name, $new_name) {
return $old_name . '::' . $new_name;
}
/**
@@ -6,6 +6,7 @@ use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\Schema\ConfigSchemaAlterException;
use Drupal\Core\Config\Schema\ConfigSchemaDiscovery;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Config\Schema\Undefined;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\TypedData\TypedDataManager;
@@ -45,13 +46,18 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
* The storage object to use for reading schema data
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache backend to use for caching the definitions.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
* (optional) The class resolver.
*/
public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache, ModuleHandlerInterface $module_handler) {
public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ClassResolverInterface $class_resolver = NULL) {
$this->configStorage = $configStorage;
$this->schemaStorage = $schemaStorage;
$this->setCacheBackend($cache, 'typed_config_definitions');
$this->alterInfo('config_schema_info');
$this->moduleHandler = $module_handler;
$this->classResolver = $class_resolver ?: \Drupal::service('class_resolver');
}
/**
@@ -69,9 +75,7 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
*/
public function get($name) {
$data = $this->configStorage->read($name);
$type_definition = $this->getDefinition($name);
$data_definition = $this->buildDataDefinition($type_definition, $data);
return $this->create($data_definition, $data);
return $this->createFromNameAndData($name, $data);
}
/**
@@ -184,6 +188,7 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
$definition += [
'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
'type' => $type,
'unwrap_for_canonical_representation' => TRUE,
];
return $definition;
}
@@ -380,4 +385,13 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
}
}
/**
* {@inheritdoc}
*/
public function createFromNameAndData($config_name, array $config_data) {
$definition = $this->getDefinition($config_name);
$data_definition = $this->buildDataDefinition($definition, $config_data);
return $this->create($data_definition, $config_data);
}
}
@@ -72,4 +72,18 @@ interface TypedConfigManagerInterface extends TypedDataManagerInterface {
*/
public function getDefinition($plugin_id, $exception_on_invalid = TRUE);
/**
* Gets typed data for a given configuration name and its values.
*
* @param string $config_name
* The machine name of the configuration.
* @param array $config_data
* The data associated with the configuration. Note: This configuration
* doesn't yet have to be stored.
*
* @return \Drupal\Core\TypedData\TraversableTypedDataInterface
* The typed configuration element.
*/
public function createFromNameAndData($config_name, array $config_data);
}
+1 -1
View File
@@ -81,7 +81,7 @@ class Cron implements CronInterface {
* @param \Drupal\Core\State\StateInterface $state
* The state service.
* @param \Drupal\Core\Session\AccountSwitcherInterface $account_switcher
* The account switching service.
* The account switching service.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Queue\QueueWorkerManagerInterface $queue_manager
+3 -2
View File
@@ -187,7 +187,7 @@ abstract class Connection {
* @return \PDO
* A \PDO object.
*/
public static function open(array &$connection_options = []) { }
public static function open(array &$connection_options = []) {}
/**
* Destroys this Connection object.
@@ -503,8 +503,9 @@ abstract class Connection {
* A sanitized comment string.
*/
public function makeComment($comments) {
if (empty($comments))
if (empty($comments)) {
return '';
}
// Flatten the array of comments.
$comment = implode('. ', $comments);
@@ -1,4 +1,5 @@
<?php
// @codingStandardsIgnoreFile
namespace Drupal\Core\Database;
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Query\Delete as QueryDelete;
/**
* MySQL implementation of \Drupal\Core\Database\Query\Delete.
*/
class Delete extends QueryDelete { }
class Delete extends QueryDelete {}
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Query\Merge as QueryMerge;
/**
* MySQL implementation of \Drupal\Core\Database\Query\Merge.
*/
class Merge extends QueryMerge { }
class Merge extends QueryMerge {}
@@ -226,6 +226,9 @@ class Schema extends DatabaseSchema {
return $field;
}
/**
* {@inheritdoc}
*/
public function getFieldTypeMap() {
// Put :normal last so it gets preserved by array_flip. This makes
// it much easier for modules (such as schema.module) to map
@@ -366,6 +369,9 @@ class Schema extends DatabaseSchema {
return implode(', ', $return);
}
/**
* {@inheritdoc}
*/
public function renameTable($table, $new_name) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", ['@table' => $table, '@table_new' => $new_name]));
@@ -378,6 +384,9 @@ class Schema extends DatabaseSchema {
return $this->connection->query('ALTER TABLE {' . $table . '} RENAME TO `' . $info['table'] . '`');
}
/**
* {@inheritdoc}
*/
public function dropTable($table) {
if (!$this->tableExists($table)) {
return FALSE;
@@ -387,6 +396,9 @@ class Schema extends DatabaseSchema {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function addField($table, $field, $spec, $keys_new = []) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", ['@field' => $field, '@table' => $table]));
@@ -432,6 +444,9 @@ class Schema extends DatabaseSchema {
}
}
/**
* {@inheritdoc}
*/
public function dropField($table, $field) {
if (!$this->fieldExists($table, $field)) {
return FALSE;
@@ -441,6 +456,9 @@ class Schema extends DatabaseSchema {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function fieldSetDefault($table, $field, $default) {
if (!$this->fieldExists($table, $field)) {
throw new SchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", ['@table' => $table, '@field' => $field]));
@@ -449,6 +467,9 @@ class Schema extends DatabaseSchema {
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` SET DEFAULT ' . $this->escapeDefaultValue($default));
}
/**
* {@inheritdoc}
*/
public function fieldSetNoDefault($table, $field) {
if (!$this->fieldExists($table, $field)) {
throw new SchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", ['@table' => $table, '@field' => $field]));
@@ -457,6 +478,9 @@ class Schema extends DatabaseSchema {
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN `' . $field . '` DROP DEFAULT');
}
/**
* {@inheritdoc}
*/
public function indexExists($table, $name) {
// Returns one row for each column in the index. Result is string or FALSE.
// Details at http://dev.mysql.com/doc/refman/5.0/en/show-index.html
@@ -464,6 +488,9 @@ class Schema extends DatabaseSchema {
return isset($row['Key_name']);
}
/**
* {@inheritdoc}
*/
public function addPrimaryKey($table, $fields) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", ['@table' => $table]));
@@ -475,6 +502,9 @@ class Schema extends DatabaseSchema {
$this->connection->query('ALTER TABLE {' . $table . '} ADD PRIMARY KEY (' . $this->createKeySql($fields) . ')');
}
/**
* {@inheritdoc}
*/
public function dropPrimaryKey($table) {
if (!$this->indexExists($table, 'PRIMARY')) {
return FALSE;
@@ -484,6 +514,9 @@ class Schema extends DatabaseSchema {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function addUniqueKey($table, $name, $fields) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", ['@table' => $table, '@name' => $name]));
@@ -495,6 +528,9 @@ class Schema extends DatabaseSchema {
$this->connection->query('ALTER TABLE {' . $table . '} ADD UNIQUE KEY `' . $name . '` (' . $this->createKeySql($fields) . ')');
}
/**
* {@inheritdoc}
*/
public function dropUniqueKey($table, $name) {
if (!$this->indexExists($table, $name)) {
return FALSE;
@@ -521,6 +557,9 @@ class Schema extends DatabaseSchema {
$this->connection->query('ALTER TABLE {' . $table . '} ADD INDEX `' . $name . '` (' . $this->createKeySql($indexes[$name]) . ')');
}
/**
* {@inheritdoc}
*/
public function dropIndex($table, $name) {
if (!$this->indexExists($table, $name)) {
return FALSE;
@@ -530,6 +569,9 @@ class Schema extends DatabaseSchema {
return TRUE;
}
/**
* {@inheritdoc}
*/
public function changeField($table, $field, $field_new, $spec, $keys_new = []) {
if (!$this->fieldExists($table, $field)) {
throw new SchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", ['@table' => $table, '@name' => $field]));
@@ -545,6 +587,9 @@ class Schema extends DatabaseSchema {
$this->connection->query($sql);
}
/**
* {@inheritdoc}
*/
public function prepareComment($comment, $length = NULL) {
// Truncate comment to maximum comment length.
if (isset($length)) {
@@ -574,6 +619,9 @@ class Schema extends DatabaseSchema {
return preg_replace('/; InnoDB free:.*$/', '', $comment);
}
/**
* {@inheritdoc}
*/
public function tableExists($table) {
// The information_schema table is very slow to query under MySQL 5.0.
// Instead, we try to select from the table in question. If it fails,
@@ -591,6 +639,9 @@ class Schema extends DatabaseSchema {
}
}
/**
* {@inheritdoc}
*/
public function fieldExists($table, $column) {
// The information_schema table is very slow to query under MySQL 5.0.
// Instead, we try to select from the table and field in question. If it
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Query\Select as QuerySelect;
/**
* MySQL implementation of \Drupal\Core\Database\Query\Select.
*/
class Select extends QuerySelect { }
class Select extends QuerySelect {}
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Transaction as DatabaseTransaction;
/**
* MySQL implementation of \Drupal\Core\Database\Transaction.
*/
class Transaction extends DatabaseTransaction { }
class Transaction extends DatabaseTransaction {}
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Query\Truncate as QueryTruncate;
/**
* MySQL implementation of \Drupal\Core\Database\Query\Truncate.
*/
class Truncate extends QueryTruncate { }
class Truncate extends QueryTruncate {}
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Query\Update as QueryUpdate;
/**
* MySQL implementation of \Drupal\Core\Database\Query\Update.
*/
class Update extends QueryUpdate { }
class Update extends QueryUpdate {}
@@ -54,20 +54,21 @@ class Connection extends DatabaseConnection {
* @see http://www.postgresql.org/docs/9.4/static/sql-keywords-appendix.html
*/
protected $postgresqlReservedKeyWords = ['all', 'analyse', 'analyze', 'and',
'any', 'array', 'as', 'asc', 'asymmetric', 'authorization', 'binary', 'both',
'case', 'cast', 'check', 'collate', 'collation', 'column', 'concurrently',
'constraint', 'create', 'cross', 'current_catalog', 'current_date',
'current_role', 'current_schema', 'current_time', 'current_timestamp',
'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do', 'else',
'end', 'except', 'false', 'fetch', 'for', 'foreign', 'freeze', 'from', 'full',
'grant', 'group', 'having', 'ilike', 'in', 'initially', 'inner', 'intersect',
'into', 'is', 'isnull', 'join', 'lateral', 'leading', 'left', 'like', 'limit',
'localtime', 'localtimestamp', 'natural', 'not', 'notnull', 'null', 'offset',
'on', 'only', 'or', 'order', 'outer', 'over', 'overlaps', 'placing',
'primary', 'references', 'returning', 'right', 'select', 'session_user',
'similar', 'some', 'symmetric', 'table', 'then', 'to', 'trailing', 'true',
'union', 'unique', 'user', 'using', 'variadic', 'verbose', 'when', 'where',
'window', 'with'];
'any', 'array', 'as', 'asc', 'asymmetric', 'authorization', 'binary', 'both',
'case', 'cast', 'check', 'collate', 'collation', 'column', 'concurrently',
'constraint', 'create', 'cross', 'current_catalog', 'current_date',
'current_role', 'current_schema', 'current_time', 'current_timestamp',
'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do', 'else',
'end', 'except', 'false', 'fetch', 'for', 'foreign', 'freeze', 'from', 'full',
'grant', 'group', 'having', 'ilike', 'in', 'initially', 'inner', 'intersect',
'into', 'is', 'isnull', 'join', 'lateral', 'leading', 'left', 'like', 'limit',
'localtime', 'localtimestamp', 'natural', 'not', 'notnull', 'null', 'offset',
'on', 'only', 'or', 'order', 'outer', 'over', 'overlaps', 'placing',
'primary', 'references', 'returning', 'right', 'select', 'session_user',
'similar', 'some', 'symmetric', 'table', 'then', 'to', 'trailing', 'true',
'union', 'unique', 'user', 'using', 'variadic', 'verbose', 'when', 'where',
'window', 'with',
];
/**
* Constructs a connection object.
@@ -111,7 +112,7 @@ class Connection extends DatabaseConnection {
// so backslashes in the password need to be doubled up.
// The bug was reported against pdo_pgsql 1.0.2, backslashes in passwords
// will break on this doubling up when the bug is fixed, so check the version
//elseif (phpversion('pdo_pgsql') < 'version_this_was_fixed_in') {
// elseif (phpversion('pdo_pgsql') < 'version_this_was_fixed_in') {
else {
$connection_options['password'] = str_replace('\\', '\\\\', $connection_options['password']);
}
@@ -66,7 +66,7 @@ class Insert extends QueryInsert {
// used twice. However, trying to insert a value into a serial
// column should only be done in very rare cases and is not thread
// safe by definition.
$this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', GREATEST(MAX(" . $serial_field . "), :serial_value)) FROM {" . $this->table . "}", [':serial_value' => (int)$serial_value]);
$this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', GREATEST(MAX(" . $serial_field . "), :serial_value)) FROM {" . $this->table . "}", [':serial_value' => (int) $serial_value]);
}
}
}
@@ -128,7 +128,9 @@ class Insert extends QueryInsert {
// Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields);
$insert_fields = array_map(function($f) { return $this->connection->escapeField($f); }, $insert_fields);
$insert_fields = array_map(function ($f) {
return $this->connection->escapeField($f);
}, $insert_fields);
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
@@ -254,7 +254,7 @@ class Tasks extends InstallTasks {
\'SELECT random();\'
LANGUAGE \'sql\'',
[],
[ 'allow_delimiter_in_query' => TRUE ]
['allow_delimiter_in_query' => TRUE]
);
}
@@ -263,7 +263,7 @@ class Tasks extends InstallTasks {
\'SELECT array_to_string((string_to_array($1, $2)) [1:$3], $2);\'
LANGUAGE \'sql\'',
[],
[ 'allow_delimiter_in_query' => TRUE ]
['allow_delimiter_in_query' => TRUE]
);
}
$connection->query('SELECT pg_advisory_unlock(1)');
@@ -7,4 +7,4 @@ use Drupal\Core\Database\Query\Merge as QueryMerge;
/**
* PostgreSQL implementation of \Drupal\Core\Database\Query\Merge.
*/
class Merge extends QueryMerge { }
class Merge extends QueryMerge {}
@@ -60,7 +60,7 @@ class NativeUpsert extends QueryUpsert {
// used twice. However, trying to insert a value into a serial
// column should only be done in very rare cases and is not thread
// safe by definition.
$this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', GREATEST(MAX(" . $serial_field . "), :serial_value)) FROM {" . $this->table . "}", [':serial_value' => (int)$serial_value]);
$this->connection->query("SELECT setval('" . $table_information->sequences[$index] . "', GREATEST(MAX(" . $serial_field . "), :serial_value)) FROM {" . $this->table . "}", [':serial_value' => (int) $serial_value]);
}
}
}
@@ -100,7 +100,9 @@ class NativeUpsert extends QueryUpsert {
// Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields);
$insert_fields = array_map(function($f) { return $this->connection->escapeField($f); }, $insert_fields);
$insert_fields = array_map(function ($f) {
return $this->connection->escapeField($f);
}, $insert_fields);
$query = $comments . 'INSERT INTO {' . $this->table . '} (' . implode(', ', $insert_fields) . ') VALUES ';
@@ -297,9 +297,9 @@ EOD;
* function it has to be processed by _db_process_field().
*
* @param $name
* Name of the field.
* Name of the field.
* @param $spec
* The field specification, as per the schema data structure format.
* The field specification, as per the schema data structure format.
*/
protected function createFieldSql($name, $spec) {
// The PostgreSQL server converts names into lowercase, unless quoted.
@@ -383,8 +383,7 @@ EOD;
}
/**
* This maps a generic data type in combination with its data size
* to the engine-specific data type.
* {@inheritdoc}
*/
public function getFieldTypeMap() {
// Put :normal last so it gets preserved by array_flip. This makes
@@ -471,6 +470,9 @@ EOD;
return (bool) $this->connection->query("SELECT 1 FROM pg_tables WHERE schemaname = :schema AND tablename = :table", [':schema' => $prefixInfo['schema'], ':table' => $prefixInfo['table']])->fetchField();
}
/**
* {@inheritdoc}
*/
public function renameTable($table, $new_name) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot rename @table to @table_new: table @table doesn't exist.", ['@table' => $table, '@table_new' => $new_name]));
@@ -525,6 +527,9 @@ EOD;
$this->resetTableInformation($table);
}
/**
* {@inheritdoc}
*/
public function dropTable($table) {
if (!$this->tableExists($table)) {
return FALSE;
@@ -535,6 +540,9 @@ EOD;
return TRUE;
}
/**
* {@inheritdoc}
*/
public function addField($table, $field, $spec, $new_keys = []) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot add field @table.@field: table doesn't exist.", ['@field' => $field, '@table' => $table]));
@@ -583,6 +591,9 @@ EOD;
$this->resetTableInformation($table);
}
/**
* {@inheritdoc}
*/
public function dropField($table, $field) {
if (!$this->fieldExists($table, $field)) {
return FALSE;
@@ -593,6 +604,9 @@ EOD;
return TRUE;
}
/**
* {@inheritdoc}
*/
public function fieldSetDefault($table, $field, $default) {
if (!$this->fieldExists($table, $field)) {
throw new SchemaObjectDoesNotExistException(t("Cannot set default value of field @table.@field: field doesn't exist.", ['@table' => $table, '@field' => $field]));
@@ -603,6 +617,9 @@ EOD;
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" SET DEFAULT ' . $default);
}
/**
* {@inheritdoc}
*/
public function fieldSetNoDefault($table, $field) {
if (!$this->fieldExists($table, $field)) {
throw new SchemaObjectDoesNotExistException(t("Cannot remove default value of field @table.@field: field doesn't exist.", ['@table' => $table, '@field' => $field]));
@@ -611,6 +628,9 @@ EOD;
$this->connection->query('ALTER TABLE {' . $table . '} ALTER COLUMN "' . $field . '" DROP DEFAULT');
}
/**
* {@inheritdoc}
*/
public function indexExists($table, $name) {
// Details http://www.postgresql.org/docs/9.1/interactive/view-pg-indexes.html
$index_name = $this->ensureIdentifiersLength($table, $name, 'idx');
@@ -651,6 +671,9 @@ EOD;
return (bool) $this->connection->query("SELECT 1 FROM pg_constraint WHERE conname = '$constraint_name'")->fetchField();
}
/**
* {@inheritdoc}
*/
public function addPrimaryKey($table, $fields) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot add primary key to table @table: table doesn't exist.", ['@table' => $table]));
@@ -663,6 +686,9 @@ EOD;
$this->resetTableInformation($table);
}
/**
* {@inheritdoc}
*/
public function dropPrimaryKey($table) {
if (!$this->constraintExists($table, 'pkey')) {
return FALSE;
@@ -673,6 +699,9 @@ EOD;
return TRUE;
}
/**
* {@inheritdoc}
*/
public function addUniqueKey($table, $name, $fields) {
if (!$this->tableExists($table)) {
throw new SchemaObjectDoesNotExistException(t("Cannot add unique key @name to table @table: table doesn't exist.", ['@table' => $table, '@name' => $name]));
@@ -685,6 +714,9 @@ EOD;
$this->resetTableInformation($table);
}
/**
* {@inheritdoc}
*/
public function dropUniqueKey($table, $name) {
if (!$this->constraintExists($table, $name . '__key')) {
return FALSE;
@@ -710,6 +742,9 @@ EOD;
$this->resetTableInformation($table);
}
/**
* {@inheritdoc}
*/
public function dropIndex($table, $name) {
if (!$this->indexExists($table, $name)) {
return FALSE;
@@ -720,6 +755,9 @@ EOD;
return TRUE;
}
/**
* {@inheritdoc}
*/
public function changeField($table, $field, $field_new, $spec, $new_keys = []) {
if (!$this->fieldExists($table, $field)) {
throw new SchemaObjectDoesNotExistException(t("Cannot change the definition of field @table.@name: field doesn't exist.", ['@table' => $table, '@name' => $field]));

Some files were not shown because too many files have changed in this diff Show More