Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 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;
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
"description": "Annotation discovery and implementation of plugins.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"doctrine/common": "2.5.*",
|
||||
"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;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use Traversable;
|
|||
*
|
||||
* Example call:
|
||||
* @code
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllStrings($array)');
|
||||
* assert(Inspector::assertAllStrings($array));
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup php_assert
|
||||
|
@ -187,8 +187,8 @@ class Inspector {
|
|||
* As an example, this assertion tests for the keys of a theme registry.
|
||||
*
|
||||
* @code
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllHaveKey(
|
||||
* $arrayToTest, "type", "theme path", "function", "template", "variables", "render element", "preprocess functions")');
|
||||
* assert(Inspector::assertAllHaveKey(
|
||||
* $arrayToTest, "type", "theme path", "function", "template", "variables", "render element", "preprocess functions"));
|
||||
* @endcode
|
||||
*
|
||||
* Note: If a method requires certain keys to be present it will usually be
|
||||
|
@ -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) {
|
||||
|
@ -333,7 +333,6 @@ class Inspector {
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that all members are strings matching a regular expression.
|
||||
*
|
||||
|
@ -375,16 +374,13 @@ class Inspector {
|
|||
* Here are some examples:
|
||||
* @code
|
||||
* // Just test all are objects, like a cache.
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
|
||||
* $collection');
|
||||
* assert(Inspector::assertAllObjects($collection));
|
||||
*
|
||||
* // Test if traversable objects (arrays won't pass this)
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
|
||||
* $collection', \'\\Traversable\');
|
||||
* assert(Inspector::assertAllObjects($collection, '\\Traversable'));
|
||||
*
|
||||
* // Test for the Foo class or Bar\None interface
|
||||
* assert('Drupal\\Component\\Assertion\\Inspector::assertAllObjects(
|
||||
* $collection', \'\\Foo\', \'\\Bar\\None\'');
|
||||
* assert(Inspector::assertAllObjects($collection, '\\Foo', '\\Bar\\None'));
|
||||
* @endcode
|
||||
*
|
||||
* @param mixed $traversable
|
||||
|
@ -396,9 +392,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) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Provides runtime assertions similar to those in PHP 7, under PHP 5.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Component\Bridge;
|
|||
|
||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Zend\Feed\Reader\ExtensionManagerInterface as ReaderManagerInterface;
|
||||
use Zend\Feed\Writer\ExtensionManagerInterface as WriterManagerInterface;
|
||||
|
||||
|
@ -48,6 +49,11 @@ class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterMan
|
|||
*/
|
||||
protected $canonicalNames;
|
||||
|
||||
/**
|
||||
* @var \Zend\Feed\Reader\ExtensionManagerInterface|\Zend\Feed\Writer\ExtensionManagerInterface
|
||||
*/
|
||||
protected $standalone;
|
||||
|
||||
/**
|
||||
* Constructs a ZfExtensionManagerSfContainer object.
|
||||
*
|
||||
|
@ -62,14 +68,25 @@ class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterMan
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function get($extension) {
|
||||
return $this->container->get($this->prefix . $this->canonicalizeName($extension));
|
||||
try {
|
||||
return $this->container->get($this->prefix . $this->canonicalizeName($extension));
|
||||
}
|
||||
catch (ServiceNotFoundException $e) {
|
||||
if ($this->standalone && $this->standalone->has($extension)) {
|
||||
return $this->standalone->get($extension);
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function has($extension) {
|
||||
return $this->container->has($this->prefix . $this->canonicalizeName($extension));
|
||||
if ($this->container->has($this->prefix . $this->canonicalizeName($extension))) {
|
||||
return TRUE;
|
||||
}
|
||||
return $this->standalone && $this->standalone->has($extension);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,4 +119,14 @@ class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterMan
|
|||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $class
|
||||
*/
|
||||
public function setStandalone($class) {
|
||||
if (!is_subclass_of($class, ReaderManagerInterface::class) && !is_subclass_of($class, WriterManagerInterface::class)) {
|
||||
throw new \RuntimeException("$class must implement Zend\Feed\Reader\ExtensionManagerInterface or Zend\Feed\Writer\ExtensionManagerInterface");
|
||||
}
|
||||
$this->standalone = new $class();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "Bridge.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"zendframework/zend-feed": "~2.4"
|
||||
"zendframework/zend-feed": "^2.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "This class provides a class finding utility.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"doctrine/common": "2.5.*"
|
||||
"doctrine/common": "^2.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Component\Datetime;
|
||||
|
||||
use Drupal\Component\Utility\ToStringTrait;
|
||||
|
||||
/**
|
||||
|
@ -22,17 +23,30 @@ use Drupal\Component\Utility\ToStringTrait;
|
|||
* errors are. This is less disruptive than allowing datetime exceptions
|
||||
* to abort processing. The calling script can decide what to do about
|
||||
* errors using hasErrors() and getErrors().
|
||||
*
|
||||
* @method $this add(\DateInterval $interval)
|
||||
* @method static array getLastErrors()
|
||||
* @method $this modify(string $modify)
|
||||
* @method $this setDate(int $year, int $month, int $day)
|
||||
* @method $this setISODate(int $year, int $week, int $day = 1)
|
||||
* @method $this setTime(int $hour, int $minute, int $second = 0, int $microseconds = 0)
|
||||
* @method $this setTimestamp(int $unixtimestamp)
|
||||
* @method $this setTimezone(\DateTimeZone $timezone)
|
||||
* @method $this sub(\DateInterval $interval)
|
||||
* @method int getOffset()
|
||||
* @method int getTimestamp()
|
||||
* @method \DateTimeZone getTimezone()
|
||||
*/
|
||||
class DateTimePlus {
|
||||
|
||||
use ToStringTrait;
|
||||
|
||||
const FORMAT = 'Y-m-d H:i:s';
|
||||
const FORMAT = 'Y-m-d H:i:s';
|
||||
|
||||
/**
|
||||
* A RFC7231 Compliant date.
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
||||
* @see http://tools.ietf.org/html/rfc7231#section-7.1.1.1
|
||||
*
|
||||
* Example: Sun, 06 Nov 1994 08:49:37 GMT
|
||||
*/
|
||||
|
@ -52,31 +66,43 @@ class DateTimePlus {
|
|||
|
||||
/**
|
||||
* The value of the time value passed to the constructor.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $inputTimeRaw = '';
|
||||
|
||||
/**
|
||||
* The prepared time, without timezone, for this date.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $inputTimeAdjusted = '';
|
||||
|
||||
/**
|
||||
* The value of the timezone passed to the constructor.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $inputTimeZoneRaw = '';
|
||||
|
||||
/**
|
||||
* The prepared timezone object used to construct this date.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $inputTimeZoneAdjusted = '';
|
||||
|
||||
/**
|
||||
* The value of the format passed to the constructor.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $inputFormatRaw = '';
|
||||
|
||||
/**
|
||||
* The prepared format, if provided.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $inputFormatAdjusted = '';
|
||||
|
||||
|
@ -250,7 +276,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/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 +331,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 +357,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.
|
||||
|
@ -427,8 +477,6 @@ class DateTimePlus {
|
|||
return $format;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Examines getLastErrors() to see what errors to report.
|
||||
*
|
||||
|
@ -622,13 +670,14 @@ class DateTimePlus {
|
|||
* Formats the date for display.
|
||||
*
|
||||
* @param string $format
|
||||
* A format string using either PHP's date().
|
||||
* Format accepted by date().
|
||||
* @param array $settings
|
||||
* - 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 = []) {
|
||||
|
||||
|
@ -654,4 +703,25 @@ class DateTimePlus {
|
|||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default time for an object built from date-only data.
|
||||
*
|
||||
* The default time for a date without time can be anything, so long as it is
|
||||
* consistently applied. If we use noon, dates in most timezones will have the
|
||||
* same value for in both the local timezone and UTC.
|
||||
*/
|
||||
public function setDefaultDateTime() {
|
||||
$this->dateTimeObject->setTime(12, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a clone of the proxied PHP \DateTime object wrapped by this class.
|
||||
*
|
||||
* @return \DateTime
|
||||
* A clone of the wrapped PHP \DateTime object.
|
||||
*/
|
||||
public function getPhpDateTime() {
|
||||
return clone $this->dateTimeObject;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "This class wraps the PHP DateTime class with more flexible initialization parameters, allowing a date to be created from an existing date object, a timestamp, a string with an unknown format, a string with a known format, or an array of date parts. It also adds an errors array and a __toString() method to the date object.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"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.
|
||||
*
|
||||
|
@ -655,8 +586,7 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
|||
/**
|
||||
* Ensure that cloning doesn't work.
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
private function __clone() {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class OptimizedPhpArrayDumper extends Dumper {
|
|||
$definition['aliases'] = $this->getAliases();
|
||||
$definition['parameters'] = $this->getParameters();
|
||||
$definition['services'] = $this->getServiceDefinitions();
|
||||
$definition['frozen'] = $this->container->isFrozen();
|
||||
$definition['frozen'] = $this->container->isCompiled();
|
||||
$definition['machine_format'] = $this->supportsMachineFormat();
|
||||
return $definition;
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ class OptimizedPhpArrayDumper extends Dumper {
|
|||
}
|
||||
|
||||
$parameters = $this->container->getParameterBag()->all();
|
||||
$is_frozen = $this->container->isFrozen();
|
||||
return $this->prepareParameters($parameters, $is_frozen);
|
||||
$is_compiled = $this->container->isCompiled();
|
||||
return $this->prepareParameters($parameters, $is_compiled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
|
@ -294,7 +282,6 @@ class OptimizedPhpArrayDumper extends Dumper {
|
|||
return $code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dumps a collection to a PHP array.
|
||||
*
|
||||
|
@ -321,10 +308,10 @@ class OptimizedPhpArrayDumper extends Dumper {
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (is_object($value)) {
|
||||
$code[$key] = $this->dumpValue($value);
|
||||
if (is_object($code[$key])) {
|
||||
$resolve = TRUE;
|
||||
}
|
||||
$code[$key] = $this->dumpValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,6 +402,9 @@ class OptimizedPhpArrayDumper extends Dumper {
|
|||
elseif ($value instanceof Parameter) {
|
||||
return $this->getParameterCall((string) $value);
|
||||
}
|
||||
elseif (is_string($value) && preg_match('/^\%(.*)\%$/', $value, $matches)) {
|
||||
return $this->getParameterCall($matches[1]);
|
||||
}
|
||||
elseif ($value instanceof Expression) {
|
||||
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||
}
|
||||
|
|
|
@ -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'])) {
|
||||
|
@ -204,7 +200,7 @@ class PhpArrayContainer extends Container {
|
|||
// The PhpArrayDumper just uses the hash of the private service
|
||||
// definition to generate a unique ID.
|
||||
//
|
||||
// @see \Drupal\Component\DependecyInjection\Dumper\OptimizedPhpArrayDumper::getPrivateServiceCall
|
||||
// @see \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper::getPrivateServiceCall
|
||||
if ($type == 'private_service') {
|
||||
$id = $argument->id;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"keywords": ["drupal", "dependency injection"],
|
||||
"type": "library",
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/drupal",
|
||||
"irc": "irc://irc.freenode.net/drupal-contribute",
|
||||
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/dependency-injection": "~2.8"
|
||||
"symfony/dependency-injection": ">=2.8 <4.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/expression-language": "For using expressions in service container configuration"
|
||||
|
|
|
@ -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;
|
||||
|
@ -146,7 +148,6 @@ class Diff {
|
|||
trigger_error("Reversed closing doesn't match", E_USER_ERROR);
|
||||
}
|
||||
|
||||
|
||||
$prevtype = 'none';
|
||||
foreach ($this->edits as $edit) {
|
||||
if ( $prevtype == $edit->type ) {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Drupal\Component\Diff\Engine;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
|
@ -134,7 +132,7 @@ class DiffEngine {
|
|||
* Returns the whole line if it's small enough, or the MD5 hash otherwise.
|
||||
*/
|
||||
protected function _line_hash($line) {
|
||||
if (Unicode::strlen($line) > $this::MAX_XREF_LENGTH) {
|
||||
if (mb_strlen($line) > $this::MAX_XREF_LENGTH) {
|
||||
return md5($line);
|
||||
}
|
||||
else {
|
||||
|
@ -195,34 +193,36 @@ 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;
|
||||
}
|
||||
$matches = $ymatches[$line];
|
||||
reset($matches);
|
||||
while (list ($junk, $y) = each($matches)) {
|
||||
if (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcs_pos($y);
|
||||
$this::USE_ASSERTS && assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
break;
|
||||
$found_empty = FALSE;
|
||||
foreach ($matches as $y) {
|
||||
if (!$found_empty) {
|
||||
if (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcs_pos($y);
|
||||
$this::USE_ASSERTS && assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
$found_empty = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (list ($junk, $y) = each($matches)) {
|
||||
if ($y > $this->seq[$k - 1]) {
|
||||
$this::USE_ASSERTS && assert($y < $this->seq[$k]);
|
||||
// Optimization: this is a common case:
|
||||
// next match is just replacing previous match.
|
||||
$this->in_seq[$this->seq[$k]] = FALSE;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
}
|
||||
elseif (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcs_pos($y);
|
||||
$this::USE_ASSERTS && assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
else {
|
||||
if ($y > $this->seq[$k - 1]) {
|
||||
$this::USE_ASSERTS && assert($y < $this->seq[$k]);
|
||||
// Optimization: this is a common case:
|
||||
// next match is just replacing previous match.
|
||||
$this->in_seq[$this->seq[$k]] = FALSE;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
}
|
||||
elseif (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcs_pos($y);
|
||||
$this::USE_ASSERTS && assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -344,7 +343,7 @@ class DiffEngine {
|
|||
$i = 0;
|
||||
$j = 0;
|
||||
|
||||
$this::USE_ASSERTS && assert('sizeof($lines) == sizeof($changed)');
|
||||
$this::USE_ASSERTS && assert(sizeof($lines) == sizeof($changed));
|
||||
$len = sizeof($lines);
|
||||
$other_len = sizeof($other_changed);
|
||||
|
||||
|
@ -364,7 +363,7 @@ class DiffEngine {
|
|||
$j++;
|
||||
}
|
||||
while ($i < $len && !$changed[$i]) {
|
||||
$this::USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$this::USE_ASSERTS && assert($j < $other_len && ! $other_changed[$j]);
|
||||
$i++;
|
||||
$j++;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
|
@ -400,11 +399,11 @@ class DiffEngine {
|
|||
while ($start > 0 && $changed[$start - 1]) {
|
||||
$start--;
|
||||
}
|
||||
$this::USE_ASSERTS && assert('$j > 0');
|
||||
$this::USE_ASSERTS && assert($j > 0);
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
$this::USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]');
|
||||
$this::USE_ASSERTS && assert($j >= 0 && !$other_changed[$j]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -427,7 +426,7 @@ class DiffEngine {
|
|||
while ($i < $len && $changed[$i]) {
|
||||
$i++;
|
||||
}
|
||||
$this::USE_ASSERTS && assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$this::USE_ASSERTS && assert($j < $other_len && ! $other_changed[$j]);
|
||||
$j++;
|
||||
if ($j < $other_len && $other_changed[$j]) {
|
||||
$corresponding = $i;
|
||||
|
@ -445,11 +444,11 @@ class DiffEngine {
|
|||
while ($corresponding < $i) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = 0;
|
||||
$this::USE_ASSERTS && assert('$j > 0');
|
||||
$this::USE_ASSERTS && assert($j > 0);
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
$this::USE_ASSERTS && assert('$j >= 0 && !$other_changed[$j]');
|
||||
$this::USE_ASSERTS && assert($j >= 0 && !$other_changed[$j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Drupal\Component\Diff\Engine;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
* Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
|
||||
*/
|
||||
|
@ -64,7 +62,7 @@ class HWLDFWordAccumulator {
|
|||
}
|
||||
if ($word[0] == "\n") {
|
||||
$this->_flushLine($tag);
|
||||
$word = Unicode::substr($word, 1);
|
||||
$word = mb_substr($word, 1);
|
||||
}
|
||||
assert(!strstr($word, "\n"));
|
||||
$this->group .= $word;
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\Component\Diff;
|
||||
|
||||
use Drupal\Component\Diff\Engine\HWLDFWordAccumulator;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
* @todo document
|
||||
|
@ -35,7 +34,7 @@ class WordLevelDiff extends MappedDiff {
|
|||
$words[] = "\n";
|
||||
$stripped[] = "\n";
|
||||
}
|
||||
if (Unicode::strlen($line) > $this::MAX_LINE_LENGTH) {
|
||||
if (mb_strlen($line) > $this::MAX_LINE_LENGTH) {
|
||||
$words[] = $line;
|
||||
$stripped[] = $line;
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "Diff.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"drupal/utility": "~8.2"
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
"description": "Discovery.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"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])) {
|
||||
|
@ -107,8 +104,11 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
|
|||
if (!isset($definition['callable'])) {
|
||||
$definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
|
||||
}
|
||||
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
|
||||
$definition['callable'][0] = $definition['callable'][0]();
|
||||
}
|
||||
|
||||
$definition['callable']($event, $event_name, $this);
|
||||
call_user_func($definition['callable'], $event, $event_name, $this);
|
||||
if ($event->isPropagationStopped()) {
|
||||
return $event;
|
||||
}
|
||||
|
@ -147,6 +147,9 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
|
|||
if (!isset($definition['callable'])) {
|
||||
$definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
|
||||
}
|
||||
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
|
||||
$definition['callable'][0] = $definition['callable'][0]();
|
||||
}
|
||||
|
||||
$result[] = $definition['callable'];
|
||||
}
|
||||
|
@ -159,27 +162,29 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getListenerPriority($eventName, $listener) {
|
||||
// Parts copied from \Symfony\Component\EventDispatcher, that's why you see
|
||||
// a yoda condition here.
|
||||
if (!isset($this->listeners[$eventName])) {
|
||||
public function getListenerPriority($event_name, $listener) {
|
||||
if (!isset($this->listeners[$event_name])) {
|
||||
return;
|
||||
}
|
||||
foreach ($this->listeners[$eventName] as $priority => $listeners) {
|
||||
if (FALSE !== ($key = array_search(['callable' => $listener], $listeners, TRUE))) {
|
||||
return $priority;
|
||||
}
|
||||
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
|
||||
$listener[0] = $listener[0]();
|
||||
}
|
||||
// Resolve service definitions if the listener has not been found so far.
|
||||
foreach ($this->listeners[$eventName] as $priority => &$definitions) {
|
||||
foreach ($this->listeners[$event_name] as $priority => &$definitions) {
|
||||
foreach ($definitions as $key => &$definition) {
|
||||
if (!isset($definition['callable'])) {
|
||||
// Once the callable is retrieved we keep it for subsequent method
|
||||
// invocations on this class.
|
||||
$definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
|
||||
if ($definition['callable'] === $listener) {
|
||||
return $priority;
|
||||
}
|
||||
$definition['callable'] = [
|
||||
$this->container->get($definition['service'][0]),
|
||||
$definition['service'][1],
|
||||
];
|
||||
}
|
||||
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
|
||||
$definition['callable'][0] = $definition['callable'][0]();
|
||||
}
|
||||
if ($definition['callable'] === $listener) {
|
||||
return $priority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +194,17 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasListeners($event_name = NULL) {
|
||||
return (bool) count($this->getListeners($event_name));
|
||||
if ($event_name !== NULL) {
|
||||
return !empty($this->listeners[$event_name]);
|
||||
}
|
||||
|
||||
foreach ($this->listeners as $event_listeners) {
|
||||
if ($event_listeners) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,9 +232,22 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
|
|||
$definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
|
||||
}
|
||||
|
||||
if ($definition['callable'] === $listener) {
|
||||
unset($this->listeners[$event_name][$priority][$key]);
|
||||
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure && !$listener instanceof \Closure) {
|
||||
$definition['callable'][0] = $definition['callable'][0]();
|
||||
}
|
||||
|
||||
if (is_array($definition['callable']) && isset($definition['callable'][0]) && !$definition['callable'][0] instanceof \Closure && is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
|
||||
$listener[0] = $listener[0]();
|
||||
}
|
||||
if ($definition['callable'] === $listener) {
|
||||
unset($definitions[$key]);
|
||||
}
|
||||
}
|
||||
if ($definitions) {
|
||||
$this->listeners[$event_name][$priority] = $definitions;
|
||||
}
|
||||
else {
|
||||
unset($this->listeners[$event_name][$priority]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
"description": "EventDispatcher.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/dependency-injection": "~2.8",
|
||||
"symfony/event-dispatcher": "~2.7"
|
||||
"symfony/dependency-injection": ">=2.8 <4.0.0",
|
||||
"symfony/event-dispatcher": ">=2.7 <4.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -15,7 +15,7 @@ class FileCacheFactory {
|
|||
/**
|
||||
* The configuration used to create FileCache objects.
|
||||
*
|
||||
* @var array $configuration
|
||||
* @var array
|
||||
*/
|
||||
protected static $configuration;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "FileCache.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "FileSystem.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
|
|
|
@ -27,42 +27,42 @@ class PoHeader {
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_langcode;
|
||||
protected $langcode;
|
||||
|
||||
/**
|
||||
* Formula for the plural form.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_pluralForms;
|
||||
protected $pluralForms;
|
||||
|
||||
/**
|
||||
* Author(s) of the file.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_authors;
|
||||
protected $authors;
|
||||
|
||||
/**
|
||||
* Date the po file got created.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_po_date;
|
||||
protected $poDate;
|
||||
|
||||
/**
|
||||
* Human readable language name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_languageName;
|
||||
protected $languageName;
|
||||
|
||||
/**
|
||||
* Name of the project the translation belongs to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_projectName;
|
||||
protected $projectName;
|
||||
|
||||
/**
|
||||
* Constructor, creates a PoHeader with default values.
|
||||
|
@ -71,11 +71,11 @@ class PoHeader {
|
|||
* Language code.
|
||||
*/
|
||||
public function __construct($langcode = NULL) {
|
||||
$this->_langcode = $langcode;
|
||||
$this->langcode = $langcode;
|
||||
// Ignore errors when run during site installation before
|
||||
// date_default_timezone_set() is called.
|
||||
$this->_po_date = @date("Y-m-d H:iO");
|
||||
$this->_pluralForms = 'nplurals=2; plural=(n > 1);';
|
||||
$this->poDate = @date("Y-m-d H:iO");
|
||||
$this->pluralForms = 'nplurals=2; plural=(n > 1);';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +86,7 @@ class PoHeader {
|
|||
* 'nplurals=2; plural=(n > 1);'.
|
||||
*/
|
||||
public function getPluralForms() {
|
||||
return $this->_pluralForms;
|
||||
return $this->pluralForms;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ class PoHeader {
|
|||
* Human readable language name.
|
||||
*/
|
||||
public function setLanguageName($languageName) {
|
||||
$this->_languageName = $languageName;
|
||||
$this->languageName = $languageName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +106,7 @@ class PoHeader {
|
|||
* The human readable language name.
|
||||
*/
|
||||
public function getLanguageName() {
|
||||
return $this->_languageName;
|
||||
return $this->languageName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +116,7 @@ class PoHeader {
|
|||
* Human readable project name.
|
||||
*/
|
||||
public function setProjectName($projectName) {
|
||||
$this->_projectName = $projectName;
|
||||
$this->projectName = $projectName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ class PoHeader {
|
|||
* The human readable project name.
|
||||
*/
|
||||
public function getProjectName() {
|
||||
return $this->_projectName;
|
||||
return $this->projectName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,7 +142,7 @@ class PoHeader {
|
|||
// There is only one value relevant for our header implementation when
|
||||
// reading, and that is the plural formula.
|
||||
if (!empty($values['Plural-Forms'])) {
|
||||
$this->_pluralForms = $values['Plural-Forms'];
|
||||
$this->pluralForms = $values['Plural-Forms'];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,11 +152,11 @@ class PoHeader {
|
|||
public function __toString() {
|
||||
$output = '';
|
||||
|
||||
$isTemplate = empty($this->_languageName);
|
||||
$isTemplate = empty($this->languageName);
|
||||
|
||||
$output .= '# ' . ($isTemplate ? 'LANGUAGE' : $this->_languageName) . ' translation of ' . ($isTemplate ? 'PROJECT' : $this->_projectName) . "\n";
|
||||
if (!empty($this->_authors)) {
|
||||
$output .= '# Generated by ' . implode("\n# ", $this->_authors) . "\n";
|
||||
$output .= '# ' . ($isTemplate ? 'LANGUAGE' : $this->languageName) . ' translation of ' . ($isTemplate ? 'PROJECT' : $this->projectName) . "\n";
|
||||
if (!empty($this->authors)) {
|
||||
$output .= '# Generated by ' . implode("\n# ", $this->authors) . "\n";
|
||||
}
|
||||
$output .= "#\n";
|
||||
|
||||
|
@ -164,14 +164,14 @@ class PoHeader {
|
|||
$output .= "msgid \"\"\n";
|
||||
$output .= "msgstr \"\"\n";
|
||||
$output .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
|
||||
$output .= "\"POT-Creation-Date: " . $this->_po_date . "\\n\"\n";
|
||||
$output .= "\"PO-Revision-Date: " . $this->_po_date . "\\n\"\n";
|
||||
$output .= "\"POT-Creation-Date: " . $this->poDate . "\\n\"\n";
|
||||
$output .= "\"PO-Revision-Date: " . $this->poDate . "\\n\"\n";
|
||||
$output .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
|
||||
$output .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
|
||||
$output .= "\"MIME-Version: 1.0\\n\"\n";
|
||||
$output .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
|
||||
$output .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
|
||||
$output .= "\"Plural-Forms: " . $this->_pluralForms . "\\n\"\n";
|
||||
$output .= "\"Plural-Forms: " . $this->pluralForms . "\\n\"\n";
|
||||
$output .= "\n";
|
||||
|
||||
return $output;
|
||||
|
@ -188,7 +188,7 @@ class PoHeader {
|
|||
* - 'nplurals': The number of plural forms defined by the plural formula.
|
||||
* - 'plurals': Array of plural positions keyed by plural value.
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function parsePluralForms($pluralforms) {
|
||||
$plurals = [];
|
||||
|
@ -473,7 +473,7 @@ class PoHeader {
|
|||
* Number of the plural string to be used for the given plural value.
|
||||
*
|
||||
* @see parseArithmetic()
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function evaluatePlural($element_stack, $n) {
|
||||
$count = count($element_stack);
|
||||
|
|
|
@ -13,46 +13,47 @@ class PoItem {
|
|||
/**
|
||||
* The language code this translation is in.
|
||||
*
|
||||
* @car string
|
||||
* @var string
|
||||
*/
|
||||
private $_langcode;
|
||||
protected $langcode;
|
||||
|
||||
/**
|
||||
* The context this translation belongs to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_context = '';
|
||||
protected $context = '';
|
||||
|
||||
/**
|
||||
* The source string or array of strings if it has plurals.
|
||||
*
|
||||
* @var string or array
|
||||
* @see $_plural
|
||||
* @var string|array
|
||||
*
|
||||
* @see $plural
|
||||
*/
|
||||
private $_source;
|
||||
protected $source;
|
||||
|
||||
/**
|
||||
* Flag indicating if this translation has plurals.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_plural;
|
||||
protected $plural;
|
||||
|
||||
/**
|
||||
* The comment of this translation.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_comment;
|
||||
protected $comment;
|
||||
|
||||
/**
|
||||
* The translation string or array of strings if it has plurals.
|
||||
*
|
||||
* @var string or array
|
||||
* @see $_plural
|
||||
* @var string|array
|
||||
* @see $plural
|
||||
*/
|
||||
private $_translation;
|
||||
protected $translation;
|
||||
|
||||
/**
|
||||
* Gets the language code of the currently used language.
|
||||
|
@ -60,7 +61,7 @@ class PoItem {
|
|||
* @return string with langcode
|
||||
*/
|
||||
public function getLangcode() {
|
||||
return $this->_langcode;
|
||||
return $this->langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +70,7 @@ class PoItem {
|
|||
* @param string $langcode
|
||||
*/
|
||||
public function setLangcode($langcode) {
|
||||
$this->_langcode = $langcode;
|
||||
$this->langcode = $langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,7 +79,7 @@ class PoItem {
|
|||
* @return string $context
|
||||
*/
|
||||
public function getContext() {
|
||||
return $this->_context;
|
||||
return $this->context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,7 +88,7 @@ class PoItem {
|
|||
* @param string $context
|
||||
*/
|
||||
public function setContext($context) {
|
||||
$this->_context = $context;
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,17 +98,17 @@ class PoItem {
|
|||
* @return string or array $translation
|
||||
*/
|
||||
public function getSource() {
|
||||
return $this->_source;
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,17 +118,17 @@ class PoItem {
|
|||
* @return string or array $translation
|
||||
*/
|
||||
public function getTranslation() {
|
||||
return $this->_translation;
|
||||
return $this->translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
$this->translation = $translation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,7 +137,7 @@ class PoItem {
|
|||
* @param bool $plural
|
||||
*/
|
||||
public function setPlural($plural) {
|
||||
$this->_plural = $plural;
|
||||
$this->plural = $plural;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,7 +146,7 @@ class PoItem {
|
|||
* @return bool
|
||||
*/
|
||||
public function isPlural() {
|
||||
return $this->_plural;
|
||||
return $this->plural;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,7 +155,7 @@ class PoItem {
|
|||
* @return String $comment
|
||||
*/
|
||||
public function getComment() {
|
||||
return $this->_comment;
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,7 +164,7 @@ class PoItem {
|
|||
* @param string $comment
|
||||
*/
|
||||
public function setComment($comment) {
|
||||
$this->_comment = $comment;
|
||||
$this->comment = $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -184,11 +185,11 @@ class PoItem {
|
|||
if (isset($values['comment'])) {
|
||||
$this->setComment($values['comment']);
|
||||
}
|
||||
if (isset($this->_source) &&
|
||||
strpos($this->_source, LOCALE_PLURAL_DELIMITER) !== FALSE) {
|
||||
$this->setSource(explode(LOCALE_PLURAL_DELIMITER, $this->_source));
|
||||
$this->setTranslation(explode(LOCALE_PLURAL_DELIMITER, $this->_translation));
|
||||
$this->setPlural(count($this->_source) > 1);
|
||||
if (isset($this->source) &&
|
||||
strpos($this->source, LOCALE_PLURAL_DELIMITER) !== FALSE) {
|
||||
$this->setSource(explode(LOCALE_PLURAL_DELIMITER, $this->source));
|
||||
$this->setTranslation(explode(LOCALE_PLURAL_DELIMITER, $this->translation));
|
||||
$this->setPlural(count($this->source) > 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,12 +207,12 @@ class PoItem {
|
|||
$output = '';
|
||||
|
||||
// Format string context.
|
||||
if (!empty($this->_context)) {
|
||||
$output .= 'msgctxt ' . $this->formatString($this->_context);
|
||||
if (!empty($this->context)) {
|
||||
$output .= 'msgctxt ' . $this->formatString($this->context);
|
||||
}
|
||||
|
||||
// Format translation.
|
||||
if ($this->_plural) {
|
||||
if ($this->plural) {
|
||||
$output .= $this->formatPlural();
|
||||
}
|
||||
else {
|
||||
|
@ -231,11 +232,11 @@ class PoItem {
|
|||
$output = '';
|
||||
|
||||
// Format source strings.
|
||||
$output .= 'msgid ' . $this->formatString($this->_source[0]);
|
||||
$output .= 'msgid_plural ' . $this->formatString($this->_source[1]);
|
||||
$output .= 'msgid ' . $this->formatString($this->source[0]);
|
||||
$output .= 'msgid_plural ' . $this->formatString($this->source[1]);
|
||||
|
||||
foreach ($this->_translation as $i => $trans) {
|
||||
if (isset($this->_translation[$i])) {
|
||||
foreach ($this->translation as $i => $trans) {
|
||||
if (isset($this->translation[$i])) {
|
||||
$output .= 'msgstr[' . $i . '] ' . $this->formatString($trans);
|
||||
}
|
||||
else {
|
||||
|
@ -251,8 +252,8 @@ class PoItem {
|
|||
*/
|
||||
private function formatSingular() {
|
||||
$output = '';
|
||||
$output .= 'msgid ' . $this->formatString($this->_source);
|
||||
$output .= 'msgstr ' . (isset($this->_translation) ? $this->formatString($this->_translation) : '""');
|
||||
$output .= 'msgid ' . $this->formatString($this->source);
|
||||
$output .= 'msgstr ' . (isset($this->translation) ? $this->formatString($this->translation) : '""');
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,13 @@ class PoMemoryWriter implements PoWriterInterface {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_items;
|
||||
protected $items;
|
||||
|
||||
/**
|
||||
* Constructor, initialize empty items.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->_items = [];
|
||||
$this->items = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class PoMemoryWriter implements PoWriterInterface {
|
|||
$item->setTranslation(implode(LOCALE_PLURAL_DELIMITER, $item->getTranslation()));
|
||||
}
|
||||
$context = $item->getContext();
|
||||
$this->_items[$context != NULL ? $context : ''][$item->getSource()] = $item->getTranslation();
|
||||
$this->items[$context != NULL ? $context : ''][$item->getSource()] = $item->getTranslation();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,7 +49,7 @@ class PoMemoryWriter implements PoWriterInterface {
|
|||
* @return array PoItem
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->_items;
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Drupal\Component\Gettext;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
|
||||
/**
|
||||
* Implements Gettext PO stream reader.
|
||||
|
@ -17,7 +17,7 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_line_number = 0;
|
||||
protected $lineNumber = 0;
|
||||
|
||||
/**
|
||||
* Parser context for the stream reader state machine.
|
||||
|
@ -32,90 +32,90 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_context = 'COMMENT';
|
||||
protected $context = 'COMMENT';
|
||||
|
||||
/**
|
||||
* Current entry being read. Incomplete.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_current_item = [];
|
||||
protected $currentItem = [];
|
||||
|
||||
/**
|
||||
* Current plural index for plural translations.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $_current_plural_index = 0;
|
||||
protected $currentPluralIndex = 0;
|
||||
|
||||
/**
|
||||
* URI of the PO stream that is being read.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_uri = '';
|
||||
protected $uri = '';
|
||||
|
||||
/**
|
||||
* Language code for the PO stream being read.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_langcode = NULL;
|
||||
protected $langcode = NULL;
|
||||
|
||||
/**
|
||||
* File handle of the current PO stream.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $_fd;
|
||||
protected $fd;
|
||||
|
||||
/**
|
||||
* The PO stream header.
|
||||
*
|
||||
* @var \Drupal\Component\Gettext\PoHeader
|
||||
*/
|
||||
private $_header;
|
||||
protected $header;
|
||||
|
||||
/**
|
||||
* Object wrapper for the last read source/translation pair.
|
||||
*
|
||||
* @var \Drupal\Component\Gettext\PoItem
|
||||
*/
|
||||
private $_last_item;
|
||||
protected $lastItem;
|
||||
|
||||
/**
|
||||
* Indicator of whether the stream reading is finished.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $_finished;
|
||||
protected $finished;
|
||||
|
||||
/**
|
||||
* Array of translated error strings recorded on reading this stream so far.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_errors;
|
||||
protected $errors;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLangcode() {
|
||||
return $this->_langcode;
|
||||
return $this->langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLangcode($langcode) {
|
||||
$this->_langcode = $langcode;
|
||||
$this->langcode = $langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getHeader() {
|
||||
return $this->_header;
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -130,14 +130,14 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getURI() {
|
||||
return $this->_uri;
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setURI($uri) {
|
||||
$this->_uri = $uri;
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,12 +146,12 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
* Opens the stream and reads the header. The stream is ready for reading
|
||||
* items after.
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
* If the URI is not yet set.
|
||||
*/
|
||||
public function open() {
|
||||
if (!empty($this->_uri)) {
|
||||
$this->_fd = fopen($this->_uri, 'rb');
|
||||
if (!empty($this->uri)) {
|
||||
$this->fd = fopen($this->uri, 'rb');
|
||||
$this->readHeader();
|
||||
}
|
||||
else {
|
||||
|
@ -162,12 +162,12 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
/**
|
||||
* Implements Drupal\Component\Gettext\PoStreamInterface::close().
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
* If the stream is not open.
|
||||
*/
|
||||
public function close() {
|
||||
if ($this->_fd) {
|
||||
fclose($this->_fd);
|
||||
if ($this->fd) {
|
||||
fclose($this->fd);
|
||||
}
|
||||
else {
|
||||
throw new \Exception('Cannot close stream that is not open.');
|
||||
|
@ -179,14 +179,14 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
*/
|
||||
public function readItem() {
|
||||
// Clear out the last item.
|
||||
$this->_last_item = NULL;
|
||||
$this->lastItem = NULL;
|
||||
|
||||
// Read until finished with the stream or a complete item was identified.
|
||||
while (!$this->_finished && is_null($this->_last_item)) {
|
||||
while (!$this->finished && is_null($this->lastItem)) {
|
||||
$this->readLine();
|
||||
}
|
||||
|
||||
return $this->_last_item;
|
||||
return $this->lastItem;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -196,14 +196,14 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
* The new seek position to set.
|
||||
*/
|
||||
public function setSeek($seek) {
|
||||
fseek($this->_fd, $seek);
|
||||
fseek($this->fd, $seek);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pointer position of the current PO stream.
|
||||
*/
|
||||
public function getSeek() {
|
||||
return ftell($this->_fd);
|
||||
return ftell($this->fd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,18 +221,18 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
}
|
||||
$header = new PoHeader();
|
||||
$header->setFromString(trim($item->getTranslation()));
|
||||
$this->_header = $header;
|
||||
$this->header = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a line from the PO stream and stores data internally.
|
||||
*
|
||||
* Expands $this->_current_item based on new data for the current item. If
|
||||
* Expands $this->current_item based on new data for the current item. If
|
||||
* this line ends the current item, it is saved with setItemFromArray() with
|
||||
* data from $this->_current_item.
|
||||
* data from $this->current_item.
|
||||
*
|
||||
* An internal state machine is maintained in this reader using
|
||||
* $this->_context as the reading state. PO items are in between COMMENT
|
||||
* $this->context as the reading state. PO items are in between COMMENT
|
||||
* states (when items have at least one line or comment in between them) or
|
||||
* indicated by MSGSTR or MSGSTR_ARR followed immediately by an MSGID or
|
||||
* MSGCTXT (when items closely follow each other).
|
||||
|
@ -245,25 +245,25 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
private function readLine() {
|
||||
// Read a line and set the stream finished indicator if it was not
|
||||
// possible anymore.
|
||||
$line = fgets($this->_fd);
|
||||
$this->_finished = ($line === FALSE);
|
||||
$line = fgets($this->fd);
|
||||
$this->finished = ($line === FALSE);
|
||||
|
||||
if (!$this->_finished) {
|
||||
if (!$this->finished) {
|
||||
|
||||
if ($this->_line_number == 0) {
|
||||
if ($this->lineNumber == 0) {
|
||||
// The first line might come with a UTF-8 BOM, which should be removed.
|
||||
$line = str_replace("\xEF\xBB\xBF", '', $line);
|
||||
// Current plurality for 'msgstr[]'.
|
||||
$this->_current_plural_index = 0;
|
||||
$this->currentPluralIndex = 0;
|
||||
}
|
||||
|
||||
// Track the line number for error reporting.
|
||||
$this->_line_number++;
|
||||
$this->lineNumber++;
|
||||
|
||||
// Initialize common values for error logging.
|
||||
$log_vars = [
|
||||
'%uri' => $this->getURI(),
|
||||
'%line' => $this->_line_number,
|
||||
'%line' => $this->lineNumber,
|
||||
];
|
||||
|
||||
// Trim away the linefeed. \\n might appear at the end of the string if
|
||||
|
@ -273,24 +273,24 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
if (!strncmp('#', $line, 1)) {
|
||||
// Lines starting with '#' are comments.
|
||||
|
||||
if ($this->_context == 'COMMENT') {
|
||||
if ($this->context == 'COMMENT') {
|
||||
// Already in comment context, add to current comment.
|
||||
$this->_current_item['#'][] = substr($line, 1);
|
||||
$this->currentItem['#'][] = substr($line, 1);
|
||||
}
|
||||
elseif (($this->_context == 'MSGSTR') || ($this->_context == 'MSGSTR_ARR')) {
|
||||
elseif (($this->context == 'MSGSTR') || ($this->context == 'MSGSTR_ARR')) {
|
||||
// We are currently in string context, save current item.
|
||||
$this->setItemFromArray($this->_current_item);
|
||||
$this->setItemFromArray($this->currentItem);
|
||||
|
||||
// Start a new entry for the comment.
|
||||
$this->_current_item = [];
|
||||
$this->_current_item['#'][] = substr($line, 1);
|
||||
$this->currentItem = [];
|
||||
$this->currentItem['#'][] = substr($line, 1);
|
||||
|
||||
$this->_context = 'COMMENT';
|
||||
$this->context = 'COMMENT';
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// A comment following any other context is a syntax error.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: "msgstr" was expected but not found on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: "msgstr" was expected but not found on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
return;
|
||||
|
@ -298,9 +298,9 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
elseif (!strncmp('msgid_plural', $line, 12)) {
|
||||
// A plural form for the current source string.
|
||||
|
||||
if ($this->_context != 'MSGID') {
|
||||
if ($this->context != 'MSGID') {
|
||||
// A plural form can only be added to an msgid directly.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: "msgid_plural" was expected but not found on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: "msgid_plural" was expected but not found on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -311,34 +311,34 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$quoted = $this->parseQuoted($line);
|
||||
if ($quoted === FALSE) {
|
||||
// The plural form must be wrapped in quotes.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains a syntax error on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains a syntax error on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Append the plural source to the current entry.
|
||||
if (is_string($this->_current_item['msgid'])) {
|
||||
if (is_string($this->currentItem['msgid'])) {
|
||||
// The first value was stored as string. Now we know the context is
|
||||
// plural, it is converted to array.
|
||||
$this->_current_item['msgid'] = [$this->_current_item['msgid']];
|
||||
$this->currentItem['msgid'] = [$this->currentItem['msgid']];
|
||||
}
|
||||
$this->_current_item['msgid'][] = $quoted;
|
||||
$this->currentItem['msgid'][] = $quoted;
|
||||
|
||||
$this->_context = 'MSGID_PLURAL';
|
||||
$this->context = 'MSGID_PLURAL';
|
||||
return;
|
||||
}
|
||||
elseif (!strncmp('msgid', $line, 5)) {
|
||||
// Starting a new message.
|
||||
|
||||
if (($this->_context == 'MSGSTR') || ($this->_context == 'MSGSTR_ARR')) {
|
||||
if (($this->context == 'MSGSTR') || ($this->context == 'MSGSTR_ARR')) {
|
||||
// We are currently in string context, save current item.
|
||||
$this->setItemFromArray($this->_current_item);
|
||||
$this->setItemFromArray($this->currentItem);
|
||||
|
||||
// Start a new context for the msgid.
|
||||
$this->_current_item = [];
|
||||
$this->currentItem = [];
|
||||
}
|
||||
elseif ($this->_context == 'MSGID') {
|
||||
elseif ($this->context == 'MSGID') {
|
||||
// We are currently already in the context, meaning we passed an id with no data.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: "msgid" is unexpected on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: "msgid" is unexpected on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -349,25 +349,25 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$quoted = $this->parseQuoted($line);
|
||||
if ($quoted === FALSE) {
|
||||
// The message id must be wrapped in quotes.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: invalid format for "msgid" on line %line.', $log_vars, $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: invalid format for "msgid" on line %line.', $log_vars, $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->_current_item['msgid'] = $quoted;
|
||||
$this->_context = 'MSGID';
|
||||
$this->currentItem['msgid'] = $quoted;
|
||||
$this->context = 'MSGID';
|
||||
return;
|
||||
}
|
||||
elseif (!strncmp('msgctxt', $line, 7)) {
|
||||
// Starting a new context.
|
||||
|
||||
if (($this->_context == 'MSGSTR') || ($this->_context == 'MSGSTR_ARR')) {
|
||||
if (($this->context == 'MSGSTR') || ($this->context == 'MSGSTR_ARR')) {
|
||||
// We are currently in string context, save current item.
|
||||
$this->setItemFromArray($this->_current_item);
|
||||
$this->_current_item = [];
|
||||
$this->setItemFromArray($this->currentItem);
|
||||
$this->currentItem = [];
|
||||
}
|
||||
elseif (!empty($this->_current_item['msgctxt'])) {
|
||||
elseif (!empty($this->currentItem['msgctxt'])) {
|
||||
// A context cannot apply to another context.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: "msgctxt" is unexpected on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: "msgctxt" is unexpected on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -378,37 +378,37 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$quoted = $this->parseQuoted($line);
|
||||
if ($quoted === FALSE) {
|
||||
// The context string must be quoted.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: invalid format for "msgctxt" on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: invalid format for "msgctxt" on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->_current_item['msgctxt'] = $quoted;
|
||||
$this->currentItem['msgctxt'] = $quoted;
|
||||
|
||||
$this->_context = 'MSGCTXT';
|
||||
$this->context = 'MSGCTXT';
|
||||
return;
|
||||
}
|
||||
elseif (!strncmp('msgstr[', $line, 7)) {
|
||||
// A message string for a specific plurality.
|
||||
|
||||
if (($this->_context != 'MSGID') &&
|
||||
($this->_context != 'MSGCTXT') &&
|
||||
($this->_context != 'MSGID_PLURAL') &&
|
||||
($this->_context != 'MSGSTR_ARR')) {
|
||||
// Plural message strings must come after msgid, msgxtxt,
|
||||
if (($this->context != 'MSGID') &&
|
||||
($this->context != 'MSGCTXT') &&
|
||||
($this->context != 'MSGID_PLURAL') &&
|
||||
($this->context != 'MSGSTR_ARR')) {
|
||||
// Plural message strings must come after msgid, msgctxt,
|
||||
// msgid_plural, or other msgstr[] entries.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: "msgstr[]" is unexpected on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: "msgstr[]" is unexpected on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Ensure the plurality is terminated.
|
||||
if (strpos($line, ']') === FALSE) {
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: invalid format for "msgstr[]" on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: invalid format for "msgstr[]" on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Extract the plurality.
|
||||
$frombracket = strstr($line, '[');
|
||||
$this->_current_plural_index = substr($frombracket, 1, strpos($frombracket, ']') - 1);
|
||||
$this->currentPluralIndex = substr($frombracket, 1, strpos($frombracket, ']') - 1);
|
||||
|
||||
// Skip to the next whitespace and trim away any further whitespace,
|
||||
// bringing $line to the message text only.
|
||||
|
@ -417,24 +417,24 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$quoted = $this->parseQuoted($line);
|
||||
if ($quoted === FALSE) {
|
||||
// The string must be quoted.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: invalid format for "msgstr[]" on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: invalid format for "msgstr[]" on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
if (!isset($this->_current_item['msgstr']) || !is_array($this->_current_item['msgstr'])) {
|
||||
$this->_current_item['msgstr'] = [];
|
||||
if (!isset($this->currentItem['msgstr']) || !is_array($this->currentItem['msgstr'])) {
|
||||
$this->currentItem['msgstr'] = [];
|
||||
}
|
||||
|
||||
$this->_current_item['msgstr'][$this->_current_plural_index] = $quoted;
|
||||
$this->currentItem['msgstr'][$this->currentPluralIndex] = $quoted;
|
||||
|
||||
$this->_context = 'MSGSTR_ARR';
|
||||
$this->context = 'MSGSTR_ARR';
|
||||
return;
|
||||
}
|
||||
elseif (!strncmp("msgstr", $line, 6)) {
|
||||
// A string pair for an msgid (with optional context).
|
||||
|
||||
if (($this->_context != 'MSGID') && ($this->_context != 'MSGCTXT')) {
|
||||
if (($this->context != 'MSGID') && ($this->context != 'MSGCTXT')) {
|
||||
// Strings are only valid within an id or context scope.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: "msgstr" is unexpected on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: "msgstr" is unexpected on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -445,13 +445,13 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$quoted = $this->parseQuoted($line);
|
||||
if ($quoted === FALSE) {
|
||||
// The string must be quoted.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: invalid format for "msgstr" on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: invalid format for "msgstr" on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->_current_item['msgstr'] = $quoted;
|
||||
$this->currentItem['msgstr'] = $quoted;
|
||||
|
||||
$this->_context = 'MSGSTR';
|
||||
$this->context = 'MSGSTR';
|
||||
return;
|
||||
}
|
||||
elseif ($line != '') {
|
||||
|
@ -460,37 +460,37 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$quoted = $this->parseQuoted($line);
|
||||
if ($quoted === FALSE) {
|
||||
// This string must be quoted.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: string continuation expected on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: string continuation expected on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Append the string to the current item.
|
||||
if (($this->_context == 'MSGID') || ($this->_context == 'MSGID_PLURAL')) {
|
||||
if (is_array($this->_current_item['msgid'])) {
|
||||
if (($this->context == 'MSGID') || ($this->context == 'MSGID_PLURAL')) {
|
||||
if (is_array($this->currentItem['msgid'])) {
|
||||
// Add string to last array element for plural sources.
|
||||
$last_index = count($this->_current_item['msgid']) - 1;
|
||||
$this->_current_item['msgid'][$last_index] .= $quoted;
|
||||
$last_index = count($this->currentItem['msgid']) - 1;
|
||||
$this->currentItem['msgid'][$last_index] .= $quoted;
|
||||
}
|
||||
else {
|
||||
// Singular source, just append the string.
|
||||
$this->_current_item['msgid'] .= $quoted;
|
||||
$this->currentItem['msgid'] .= $quoted;
|
||||
}
|
||||
}
|
||||
elseif ($this->_context == 'MSGCTXT') {
|
||||
elseif ($this->context == 'MSGCTXT') {
|
||||
// Multiline context name.
|
||||
$this->_current_item['msgctxt'] .= $quoted;
|
||||
$this->currentItem['msgctxt'] .= $quoted;
|
||||
}
|
||||
elseif ($this->_context == 'MSGSTR') {
|
||||
elseif ($this->context == 'MSGSTR') {
|
||||
// Multiline translation string.
|
||||
$this->_current_item['msgstr'] .= $quoted;
|
||||
$this->currentItem['msgstr'] .= $quoted;
|
||||
}
|
||||
elseif ($this->_context == 'MSGSTR_ARR') {
|
||||
elseif ($this->context == 'MSGSTR_ARR') {
|
||||
// Multiline plural translation string.
|
||||
$this->_current_item['msgstr'][$this->_current_plural_index] .= $quoted;
|
||||
$this->currentItem['msgstr'][$this->currentPluralIndex] .= $quoted;
|
||||
}
|
||||
else {
|
||||
// No valid context to append to.
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri contains an error: unexpected string on line %line.', $log_vars);
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri contains an error: unexpected string on line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
return;
|
||||
|
@ -498,14 +498,16 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
}
|
||||
|
||||
// Empty line read or EOF of PO stream, close out the last entry.
|
||||
if (($this->_context == 'MSGSTR') || ($this->_context == 'MSGSTR_ARR')) {
|
||||
$this->setItemFromArray($this->_current_item);
|
||||
$this->_current_item = [];
|
||||
if (($this->context == 'MSGSTR') || ($this->context == 'MSGSTR_ARR')) {
|
||||
$this->setItemFromArray($this->currentItem);
|
||||
$this->currentItem = [];
|
||||
}
|
||||
elseif ($this->_context != 'COMMENT') {
|
||||
$this->_errors[] = SafeMarkup::format('The translation stream %uri ended unexpectedly at line %line.', $log_vars);
|
||||
elseif ($this->context != 'COMMENT') {
|
||||
$this->errors[] = new FormattableMarkup('The translation stream %uri ended unexpectedly at line %line.', $log_vars);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -531,11 +533,11 @@ class PoStreamReader implements PoStreamInterface, PoReaderInterface {
|
|||
$item->setTranslation($value['msgstr']);
|
||||
$item->setPlural($plural);
|
||||
$item->setComment($comments);
|
||||
$item->setLangcode($this->_langcode);
|
||||
$item->setLangcode($this->langcode);
|
||||
|
||||
$this->_last_item = $item;
|
||||
$this->lastItem = $item;
|
||||
|
||||
$this->_context = 'COMMENT';
|
||||
$this->context = 'COMMENT';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,21 +12,28 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
private $_uri;
|
||||
protected $uri;
|
||||
|
||||
/**
|
||||
* The Gettext PO header.
|
||||
*
|
||||
* @var \Drupal\Component\Gettext\PoHeader
|
||||
*/
|
||||
private $_header;
|
||||
protected $header;
|
||||
|
||||
/**
|
||||
* File handle of the current PO stream.
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $_fd;
|
||||
protected $fd;
|
||||
|
||||
/**
|
||||
* The language code of this writer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $langcode;
|
||||
|
||||
/**
|
||||
* Gets the PO header of the current stream.
|
||||
|
@ -35,7 +42,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
* The Gettext PO header.
|
||||
*/
|
||||
public function getHeader() {
|
||||
return $this->_header;
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +52,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
* The Gettext PO header to set.
|
||||
*/
|
||||
public function setHeader(PoHeader $header) {
|
||||
$this->_header = $header;
|
||||
$this->header = $header;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +62,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
* The language code.
|
||||
*/
|
||||
public function getLangcode() {
|
||||
return $this->_langcode;
|
||||
return $this->langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +72,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
* The language code.
|
||||
*/
|
||||
public function setLangcode($langcode) {
|
||||
$this->_langcode = $langcode;
|
||||
$this->langcode = $langcode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,7 +80,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
*/
|
||||
public function open() {
|
||||
// Open in write mode. Will overwrite the stream if it already exists.
|
||||
$this->_fd = fopen($this->getURI(), 'w');
|
||||
$this->fd = fopen($this->getURI(), 'w');
|
||||
// Write the header at the start.
|
||||
$this->writeHeader();
|
||||
}
|
||||
|
@ -81,15 +88,15 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
/**
|
||||
* Implements Drupal\Component\Gettext\PoStreamInterface::close().
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
* If the stream is not open.
|
||||
*/
|
||||
public function close() {
|
||||
if ($this->_fd) {
|
||||
fclose($this->_fd);
|
||||
if ($this->fd) {
|
||||
fclose($this->fd);
|
||||
}
|
||||
else {
|
||||
throw new Exception('Cannot close stream that is not open.');
|
||||
throw new \Exception('Cannot close stream that is not open.');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,13 +107,13 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
* Piece of string to write to the stream. If the value is not directly a
|
||||
* string, casting will happen in writing.
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
* If writing the data is not possible.
|
||||
*/
|
||||
private function write($data) {
|
||||
$result = fputs($this->_fd, $data);
|
||||
if ($result === FALSE) {
|
||||
throw new Exception('Unable to write data: ' . substr($data, 0, 20));
|
||||
$result = fwrite($this->fd, $data);
|
||||
if ($result === FALSE || $result != strlen($data)) {
|
||||
throw new \Exception('Unable to write data: ' . substr($data, 0, 20));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +121,7 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
* Write the PO header to the stream.
|
||||
*/
|
||||
private function writeHeader() {
|
||||
$this->write($this->_header);
|
||||
$this->write($this->header);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,21 +144,21 @@ class PoStreamWriter implements PoWriterInterface, PoStreamInterface {
|
|||
/**
|
||||
* Implements Drupal\Component\Gettext\PoStreamInterface::getURI().
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Exception
|
||||
* If the URI is not set.
|
||||
*/
|
||||
public function getURI() {
|
||||
if (empty($this->_uri)) {
|
||||
throw new Exception('No URI set.');
|
||||
if (empty($this->uri)) {
|
||||
throw new \Exception('No URI set.');
|
||||
}
|
||||
return $this->_uri;
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setURI($uri) {
|
||||
$this->_uri = $uri;
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "drupal/core-gettext",
|
||||
"description": "PHP library for reading PO files.",
|
||||
"type": "library",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/drupal",
|
||||
"irc": "irc://irc.freenode.net/drupal-contribute",
|
||||
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"drupal/core-utility": "~8.2"
|
||||
"drupal/core-utility": "^8.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Graph.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
|
|
|
@ -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.
|
||||
|
@ -36,7 +36,7 @@ abstract class SecuredRedirectResponse extends RedirectResponse {
|
|||
* Copies over the values from the given response.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\RedirectResponse $response
|
||||
* The redirect reponse object.
|
||||
* The redirect response object.
|
||||
*/
|
||||
protected function fromResponse(RedirectResponse $response) {
|
||||
$this->setProtocolVersion($response->getProtocolVersion());
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "HttpFoundation.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/http-foundation": "~2.7"
|
||||
"symfony/http-foundation": ">=2.7 <4.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -95,6 +95,7 @@ EOF;
|
|||
<IfModule !mod_authz_core.c>
|
||||
Deny from all
|
||||
</IfModule>
|
||||
|
||||
$lines
|
||||
EOF;
|
||||
}
|
||||
|
@ -138,34 +139,42 @@ EOF;
|
|||
* The directory path.
|
||||
* @param int $mode
|
||||
* The mode, permissions, the directory should have.
|
||||
* @param bool $is_backwards_recursive
|
||||
* Internal use only.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the directory exists or has been created, FALSE otherwise.
|
||||
*/
|
||||
protected function createDirectory($directory, $mode = 0777, $is_backwards_recursive = FALSE) {
|
||||
protected function createDirectory($directory, $mode = 0777) {
|
||||
// If the directory exists already, there's nothing to do.
|
||||
if (is_dir($directory)) {
|
||||
return TRUE;
|
||||
}
|
||||
// Otherwise, try to create the directory and ensure to set its permissions,
|
||||
// because mkdir() obeys the umask of the current process.
|
||||
if (is_dir($parent = dirname($directory))) {
|
||||
// If the parent directory exists, then the backwards recursion must end,
|
||||
// regardless of whether the subdirectory could be created.
|
||||
if ($status = mkdir($directory)) {
|
||||
// Only try to chmod() if the subdirectory could be created.
|
||||
$status = chmod($directory, $mode);
|
||||
}
|
||||
return $is_backwards_recursive ? TRUE : $status;
|
||||
|
||||
// If the parent directory doesn't exist, try to create it.
|
||||
$parent_exists = is_dir($parent = dirname($directory));
|
||||
if (!$parent_exists) {
|
||||
$parent_exists = $this->createDirectory($parent, $mode);
|
||||
}
|
||||
// If the parent directory and the requested directory does not exist and
|
||||
// could not be created above, walk the requested directory path back up
|
||||
// until an existing directory is hit, and from there, recursively create
|
||||
// the sub-directories. Only if that recursion succeeds, create the final,
|
||||
// originally requested subdirectory.
|
||||
return $this->createDirectory($parent, $mode, TRUE) && mkdir($directory) && chmod($directory, $mode);
|
||||
|
||||
// If parent exists, try to create the directory and ensure to set its
|
||||
// permissions, because mkdir() obeys the umask of the current process.
|
||||
if ($parent_exists) {
|
||||
// We hide warnings and ignore the return because there may have been a
|
||||
// race getting here and the directory could already exist.
|
||||
@mkdir($directory);
|
||||
// Only try to chmod() if the subdirectory could be created.
|
||||
if (is_dir($directory)) {
|
||||
// Avoid writing permissions if possible.
|
||||
if (fileperms($directory) !== $mode) {
|
||||
return chmod($directory, $mode);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
// Something failed and the directory doesn't exist.
|
||||
trigger_error('mkdir(): Permission Denied', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "PhpStorage.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Component\Plugin\Definition;
|
||||
|
||||
use Drupal\Component\Plugin\Context\ContextDefinitionInterface;
|
||||
|
||||
/**
|
||||
* Provides an interface for plugin definitions which use contexts.
|
||||
*
|
||||
* @ingroup Plugin
|
||||
*/
|
||||
interface ContextAwarePluginDefinitionInterface extends PluginDefinitionInterface {
|
||||
|
||||
/**
|
||||
* Checks if the plugin defines a particular context.
|
||||
*
|
||||
* @param string $name
|
||||
* The context name.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the plugin defines the given context, otherwise FALSE.
|
||||
*/
|
||||
public function hasContextDefinition($name);
|
||||
|
||||
/**
|
||||
* Returns all context definitions for this plugin.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Context\ContextDefinitionInterface[]
|
||||
* The context definitions.
|
||||
*/
|
||||
public function getContextDefinitions();
|
||||
|
||||
/**
|
||||
* Returns a particular context definition for this plugin.
|
||||
*
|
||||
* @param string $name
|
||||
* The context name.
|
||||
*
|
||||
* @return \Drupal\Component\Plugin\Context\ContextDefinitionInterface
|
||||
* The context definition.
|
||||
*
|
||||
* @throws \Drupal\Component\Plugin\Exception\ContextException
|
||||
* Thrown if the plugin does not define the given context.
|
||||
*/
|
||||
public function getContextDefinition($name);
|
||||
|
||||
/**
|
||||
* Adds a context to this plugin definition.
|
||||
*
|
||||
* @param string $name
|
||||
* The context name.
|
||||
* @param \Drupal\Component\Plugin\Context\ContextDefinitionInterface $definition
|
||||
* The context definition.
|
||||
*
|
||||
* @return $this
|
||||
* The called object.
|
||||
*/
|
||||
public function addContextDefinition($name, ContextDefinitionInterface $definition);
|
||||
|
||||
/**
|
||||
* Removes a context definition from this plugin.
|
||||
*
|
||||
* @param string $name
|
||||
* The context name.
|
||||
*
|
||||
* @return $this
|
||||
* The called object.
|
||||
*/
|
||||
public function removeContextDefinition($name);
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Component\Plugin\Definition;
|
||||
|
||||
use Drupal\Component\Plugin\Context\ContextDefinitionInterface;
|
||||
use Drupal\Component\Plugin\Exception\ContextException;
|
||||
|
||||
/**
|
||||
* Provides a trait for context-aware object-based plugin definitions.
|
||||
*/
|
||||
trait ContextAwarePluginDefinitionTrait {
|
||||
|
||||
/**
|
||||
* The context definitions for this plugin definition.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Context\ContextDefinitionInterface[]
|
||||
*/
|
||||
protected $contextDefinitions = [];
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface::hasContextDefinition().
|
||||
*/
|
||||
public function hasContextDefinition($name) {
|
||||
return array_key_exists($name, $this->contextDefinitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface::getContextDefinitions().
|
||||
*/
|
||||
public function getContextDefinitions() {
|
||||
return $this->contextDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface::getContextDefinition().
|
||||
*/
|
||||
public function getContextDefinition($name) {
|
||||
if ($this->hasContextDefinition($name)) {
|
||||
return $this->contextDefinitions[$name];
|
||||
}
|
||||
throw new ContextException($this->id() . " does not define a '$name' context");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface::addContextDefinition().
|
||||
*/
|
||||
public function addContextDefinition($name, ContextDefinitionInterface $definition) {
|
||||
$this->contextDefinitions[$name] = $definition;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements \Drupal\Component\Plugin\Definition\ContextAwarePluginDefinitionInterface::removeContextDefinition().
|
||||
*/
|
||||
public function removeContextDefinition($name) {
|
||||
unset($this->contextDefinitions[$name]);
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
|
@ -33,6 +33,8 @@ interface DiscoveryInterface {
|
|||
* @return mixed[]
|
||||
* An array of plugin definitions (empty array if no definitions were
|
||||
* found). Keys are plugin IDs.
|
||||
*
|
||||
* @see \Drupal\Core\Plugin\FilteredPluginManagerInterface::getFilteredDefinitions()
|
||||
*/
|
||||
public function getDefinitions();
|
||||
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Component\Plugin\Exception;
|
||||
|
||||
/**
|
||||
* An exception class thrown when contexts exist but are missing a value.
|
||||
*/
|
||||
class MissingValueContextException extends ContextException {
|
||||
|
||||
/**
|
||||
* MissingValueContextException constructor.
|
||||
*
|
||||
* @param string[] $contexts_without_value
|
||||
* List of contexts with missing value.
|
||||
*/
|
||||
public function __construct(array $contexts_without_value = []) {
|
||||
$message = 'Required contexts without a value: ' . implode(', ', $contexts_without_value);
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {}
|
||||
|
|
|
@ -63,7 +63,7 @@ class DefaultFactory implements FactoryInterface {
|
|||
* @param \Drupal\Component\Plugin\Definition\PluginDefinitionInterface|mixed[] $plugin_definition
|
||||
* The plugin definition associated with the plugin ID.
|
||||
* @param string $required_interface
|
||||
* (optional) THe required plugin interface.
|
||||
* (optional) The required plugin interface.
|
||||
*
|
||||
* @return string
|
||||
* The appropriate class name.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -41,7 +41,7 @@ abstract class PluginBase implements PluginInspectionInterface, DerivativeInspec
|
|||
protected $configuration;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\Component\Plugin\PluginBase object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
|
@ -29,7 +29,7 @@ abstract class PluginManagerBase implements PluginManagerInterface {
|
|||
/**
|
||||
* The object that returns the preconfigured plugin instance appropriate for a particular runtime condition.
|
||||
*
|
||||
* @var \Drupal\Component\Plugin\Mapper\MapperInterface
|
||||
* @var \Drupal\Component\Plugin\Mapper\MapperInterface|null
|
||||
*/
|
||||
protected $mapper;
|
||||
|
||||
|
@ -76,8 +76,7 @@ abstract class PluginManagerBase implements PluginManagerInterface {
|
|||
return $this->getFactory()->createInstance($plugin_id, $configuration);
|
||||
}
|
||||
catch (PluginNotFoundException $e) {
|
||||
$fallback_id = $this->getFallbackPluginId($plugin_id, $configuration);
|
||||
return $this->getFactory()->createInstance($fallback_id, $configuration);
|
||||
return $this->handlePluginNotFound($plugin_id, $configuration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -85,10 +84,29 @@ abstract class PluginManagerBase implements PluginManagerInterface {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows plugin managers to specify custom behavior if a plugin is not found.
|
||||
*
|
||||
* @param string $plugin_id
|
||||
* The ID of the missing requested plugin.
|
||||
* @param array $configuration
|
||||
* An array of configuration relevant to the plugin instance.
|
||||
*
|
||||
* @return object
|
||||
* A fallback plugin instance.
|
||||
*/
|
||||
protected function handlePluginNotFound($plugin_id, array $configuration) {
|
||||
$fallback_id = $this->getFallbackPluginId($plugin_id, $configuration);
|
||||
return $this->getFactory()->createInstance($fallback_id, $configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getInstance(array $options) {
|
||||
if (!$this->mapper) {
|
||||
throw new \BadMethodCallException(sprintf('%s does not support this method unless %s::$mapper is set.', static::class, static::class));
|
||||
}
|
||||
return $this->mapper->getInstance($options);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "Base building block for a scalable and extensible plug-in system for PHP components and application framework extensions.",
|
||||
"keywords": ["drupal", "plugin", "plugins"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/validator": "~2.7"
|
||||
"symfony/validator": ">=2.7 <4.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Provides a lightweight mechanism to provide lazy loaded proxies.",
|
||||
"keywords": ["drupal", "proxy"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9"
|
||||
},
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\Component\Render;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Component\Utility\UrlHelper;
|
||||
|
||||
/**
|
||||
|
@ -61,6 +60,13 @@ use Drupal\Component\Utility\UrlHelper;
|
|||
*/
|
||||
class FormattableMarkup implements MarkupInterface, \Countable {
|
||||
|
||||
/**
|
||||
* The string containing placeholders.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $string;
|
||||
|
||||
/**
|
||||
* The arguments to replace placeholders with.
|
||||
*
|
||||
|
@ -100,7 +106,7 @@ class FormattableMarkup implements MarkupInterface, \Countable {
|
|||
* The length of the string.
|
||||
*/
|
||||
public function count() {
|
||||
return Unicode::strlen($this->string);
|
||||
return mb_strlen($this->string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
namespace Drupal\Component\Render;
|
||||
|
||||
use Drupal\Component\Utility\Html;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
* Escapes HTML syntax characters to HTML entities for display in markup.
|
||||
|
@ -43,7 +42,7 @@ class HtmlEscapedText implements MarkupInterface, \Countable {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function count() {
|
||||
return Unicode::strlen($this->string);
|
||||
return mb_strlen($this->string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Drupal\Component\Render;
|
||||
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
|
||||
/**
|
||||
* Implements MarkupInterface and Countable for rendered objects.
|
||||
*
|
||||
|
@ -61,7 +59,7 @@ trait MarkupTrait {
|
|||
* The length of the string.
|
||||
*/
|
||||
public function count() {
|
||||
return Unicode::strlen($this->string);
|
||||
return mb_strlen($this->string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "Renders placeholder variables for HTML and plain-text display.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"drupal/core-utility": "~8.2"
|
||||
"drupal/core-utility": "^8.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -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;
|
||||
|
@ -44,7 +47,7 @@ class YamlPecl implements SerializationInterface {
|
|||
// and then restore it after decoding has occurred. This allows us to turn
|
||||
// parsing errors into a throwable exception.
|
||||
// @see Drupal\Component\Serialization\Exception\InvalidDataTypeException
|
||||
// @see http://php.net/manual/en/class.errorexception.php
|
||||
// @see http://php.net/manual/class.errorexception.php
|
||||
set_error_handler([__CLASS__, 'errorHandler']);
|
||||
$ndocs = 0;
|
||||
$data = yaml_parse($raw, 0, $ndocs, [
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
"description": "Serialization.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"symfony/yaml": "~2.7"
|
||||
"symfony/yaml": ">=2.7 <4.0.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
|
@ -2,7 +2,7 @@
|
|||
"name": "drupal/core-transliteration",
|
||||
"description": "Transliteration.",
|
||||
"type": "library",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/drupal",
|
||||
"irc": "irc://irc.freenode.net/drupal-contribute",
|
||||
|
|
|
@ -14,11 +14,11 @@ $base = [
|
|||
0x50 => NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
0x60 => '', '', '', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
0x70 => NULL, NULL, NULL, NULL, '\'', ',', NULL, NULL, NULL, NULL, 'i', NULL, NULL, NULL, '?', NULL,
|
||||
0x80 => NULL, NULL, NULL, NULL, '', '', 'A', ':', 'E', 'E', 'I', NULL, 'O', NULL, 'Y', 'O',
|
||||
0x90 => 'i', 'A', 'B', 'G', 'D', 'E', 'Z', 'E', 'TH', 'I', 'K', 'L', 'M', 'N', 'X', 'O',
|
||||
0xA0 => 'P', 'R', NULL, 'S', 'T', 'Y', 'PH', 'CH', 'PS', 'O', 'I', 'Y', 'a', 'e', 'e', 'i',
|
||||
0xB0 => 'y', 'a', 'b', 'g', 'd', 'e', 'z', 'e', 'th', 'i', 'k', 'l', 'm', 'n', 'x', 'o',
|
||||
0xC0 => 'p', 'r', 's', 's', 't', 'y', 'ph', 'ch', 'ps', 'o', 'i', 'y', 'o', 'y', 'o', NULL,
|
||||
0x80 => NULL, NULL, NULL, NULL, '', '', 'A', ';', 'E', 'I', 'I', NULL, 'O', NULL, 'U', 'O',
|
||||
0x90 => 'I', 'A', 'B', 'G', 'D', 'E', 'Z', 'I', 'Th', 'I', 'K', 'L', 'M', 'N', 'X', 'O',
|
||||
0xA0 => 'P', 'R', NULL, 'S', 'T', 'Y', 'F', 'H', 'Ps', 'O', 'I', 'Y', 'a', 'e', 'i', 'i',
|
||||
0xB0 => 'y', 'a', 'b', 'g', 'd', 'e', 'z', 'i', 'th', 'i', 'k', 'l', 'm', 'n', 'x', 'o',
|
||||
0xC0 => 'p', 'r', 's', 's', 't', 'y', 'f', 'h', 'ps', 'o', 'i', 'y', 'o', 'y', 'o', NULL,
|
||||
0xD0 => 'b', 'th', 'Y', 'Y', 'Y', 'ph', 'p', '&', NULL, NULL, 'St', 'st', 'W', 'w', 'Q', 'q',
|
||||
0xE0 => 'Sp', 'sp', 'Sh', 'sh', 'F', 'f', 'Kh', 'kh', 'H', 'h', 'G', 'g', 'CH', 'ch', 'Ti', 'ti',
|
||||
0xF0 => 'k', 'r', 's', 'j', 'TH', 'e', NULL, 'S', 's', 'S', 'S', 's', NULL, NULL, NULL, NULL,
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
*/
|
||||
|
||||
$base = [
|
||||
0x00 => 'E', 'E', 'D', 'G', 'E', 'Z', 'I', 'I', 'J', 'L', 'N', 'C', 'K', 'I', 'U', 'D',
|
||||
0x10 => 'A', 'B', 'V', 'G', 'D', 'E', 'Z', 'Z', 'I', 'I', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
0x20 => 'R', 'S', 'T', 'U', 'F', 'H', 'C', 'C', 'S', 'S', '', 'Y', '', 'E', 'U', 'A',
|
||||
0x30 => 'a', 'b', 'v', 'g', 'd', 'e', 'z', 'z', 'i', 'i', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
0x40 => 'r', 's', 't', 'u', 'f', 'h', 'c', 'c', 's', 's', '', 'y', '', 'e', 'u', 'a',
|
||||
0x50 => 'e', 'e', 'd', 'g', 'e', 'z', 'i', 'i', 'j', 'l', 'n', 'c', 'k', 'i', 'u', 'd',
|
||||
0x00 => 'E', 'YO', 'D', 'G', 'E', 'Z', 'I', 'I', 'J', 'L', 'N', 'C', 'K', 'I', 'U', 'D',
|
||||
0x10 => 'A', 'B', 'V', 'G', 'D', 'E', 'ZH', 'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
0x20 => 'R', 'S', 'T', 'U', 'F', 'KH', 'C', 'CH', 'SH', 'SCH', '', 'Y', '', 'E', 'YU', 'YA',
|
||||
0x30 => 'a', 'b', 'v', 'g', 'd', 'e', 'zh', 'z', 'i', 'y', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
0x40 => 'r', 's', 't', 'u', 'f', 'kh', 'c', 'ch', 'sh', 'sch', '', 'y', '', 'e', 'yu', 'ya',
|
||||
0x50 => 'e', 'yo', 'd', 'g', 'e', 'z', 'i', 'i', 'j', 'l', 'n', 'c', 'k', 'i', 'u', 'd',
|
||||
0x60 => 'O', 'o', 'E', 'e', 'Ie', 'ie', 'E', 'e', 'Ie', 'ie', 'O', 'o', 'Io', 'io', 'Ks', 'ks',
|
||||
0x70 => 'Ps', 'ps', 'F', 'f', 'Y', 'y', 'Y', 'y', 'u', 'u', 'O', 'o', 'O', 'o', 'Ot', 'ot',
|
||||
0x80 => 'Q', 'q', '*1000*', '', '', '', '', NULL, '*100.000*', '*1.000.000*', NULL, NULL, '"', '"', 'R\'', 'r\'',
|
||||
|
|
|
@ -23,7 +23,7 @@ class Color {
|
|||
// Hash prefix is optional.
|
||||
$hex = ltrim($hex, '#');
|
||||
// Must be either RGB or RRGGBB.
|
||||
$length = Unicode::strlen($hex);
|
||||
$length = mb_strlen($hex);
|
||||
$valid = $valid && ($length === 3 || $length === 6);
|
||||
// Must be a valid hex value.
|
||||
$valid = $valid && ctype_xdigit($hex);
|
||||
|
@ -94,4 +94,28 @@ class Color {
|
|||
return '#' . str_pad(dechex($out), 6, 0, STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the hex color length to 6 characters for comparison.
|
||||
*
|
||||
* @param string $hex
|
||||
* The hex color to normalize.
|
||||
*
|
||||
* @return string
|
||||
* The 6 character hex color.
|
||||
*/
|
||||
public static function normalizeHexLength($hex) {
|
||||
// Ignore '#' prefixes.
|
||||
$hex = ltrim($hex, '#');
|
||||
|
||||
if (strlen($hex) === 3) {
|
||||
$hex[5] = $hex[2];
|
||||
$hex[4] = $hex[2];
|
||||
$hex[3] = $hex[1];
|
||||
$hex[2] = $hex[1];
|
||||
$hex[1] = $hex[0];
|
||||
}
|
||||
|
||||
return '#' . $hex;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class Html {
|
|||
public static function getClass($class) {
|
||||
$class = (string) $class;
|
||||
if (!isset(static::$classes[$class])) {
|
||||
static::$classes[$class] = static::cleanCssIdentifier(Unicode::strtolower($class));
|
||||
static::$classes[$class] = static::cleanCssIdentifier(mb_strtolower($class));
|
||||
}
|
||||
return static::$classes[$class];
|
||||
}
|
||||
|
@ -79,9 +79,10 @@ class Html {
|
|||
/**
|
||||
* Prepares a string for use as a CSS identifier (element, class, or ID name).
|
||||
*
|
||||
* http://www.w3.org/TR/CSS21/syndata.html#characters shows the syntax for
|
||||
* valid CSS identifiers (including element names, classes, and IDs in
|
||||
* selectors.)
|
||||
* Link below shows the syntax for valid CSS identifiers (including element
|
||||
* names, classes, and IDs in selectors).
|
||||
*
|
||||
* @see http://www.w3.org/TR/CSS21/syndata.html#characters
|
||||
*
|
||||
* @param string $identifier
|
||||
* The identifier to clean.
|
||||
|
@ -124,7 +125,7 @@ class Html {
|
|||
// Identifiers cannot start with a digit, two hyphens, or a hyphen followed by a digit.
|
||||
$identifier = preg_replace([
|
||||
'/^[0-9]/',
|
||||
'/^(-[0-9])|^(--)/'
|
||||
'/^(-[0-9])|^(--)/',
|
||||
], ['_', '__'], $identifier);
|
||||
return $identifier;
|
||||
}
|
||||
|
@ -215,7 +216,7 @@ class Html {
|
|||
* @see self::getUniqueId()
|
||||
*/
|
||||
public static function getId($id) {
|
||||
$id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], Unicode::strtolower($id));
|
||||
$id = str_replace([' ', '_', '[', ']'], ['-', '-', '-', ''], mb_strtolower($id));
|
||||
|
||||
// As defined in http://www.w3.org/TR/html4/types.html#type-name, HTML IDs can
|
||||
// only contain letters, digits ([0-9]), hyphens ("-"), underscores ("_"),
|
||||
|
@ -451,9 +452,9 @@ EOD;
|
|||
* The updated (X)HTML snippet.
|
||||
*/
|
||||
public static function transformRootRelativeUrlsToAbsolute($html, $scheme_and_host) {
|
||||
assert('empty(array_diff(array_keys(parse_url($scheme_and_host)), ["scheme", "host", "port"]))', '$scheme_and_host contains scheme, host and port at most.');
|
||||
assert('isset(parse_url($scheme_and_host)["scheme"])', '$scheme_and_host is absolute and hence has a scheme.');
|
||||
assert('isset(parse_url($scheme_and_host)["host"])', '$base_url is absolute and hence has a host.');
|
||||
assert(empty(array_diff(array_keys(parse_url($scheme_and_host)), ["scheme", "host", "port"])), '$scheme_and_host contains scheme, host and port at most.');
|
||||
assert(isset(parse_url($scheme_and_host)["scheme"]), '$scheme_and_host is absolute and hence has a scheme.');
|
||||
assert(isset(parse_url($scheme_and_host)["host"]), '$base_url is absolute and hence has a host.');
|
||||
|
||||
$html_dom = Html::load($html);
|
||||
$xpath = new \DOMXpath($html_dom);
|
||||
|
|
|
@ -69,7 +69,7 @@ class NestedArray {
|
|||
public static function &getValue(array &$array, array $parents, &$key_exists = NULL) {
|
||||
$ref = &$array;
|
||||
foreach ($parents as $parent) {
|
||||
if (is_array($ref) && array_key_exists($parent, $ref)) {
|
||||
if (is_array($ref) && (isset($ref[$parent]) || array_key_exists($parent, $ref))) {
|
||||
$ref = &$ref[$parent];
|
||||
}
|
||||
else {
|
||||
|
@ -219,7 +219,7 @@ class NestedArray {
|
|||
public static function unsetValue(array &$array, array $parents, &$key_existed = NULL) {
|
||||
$unset_key = array_pop($parents);
|
||||
$ref = &self::getValue($array, $parents, $key_existed);
|
||||
if ($key_existed && is_array($ref) && array_key_exists($unset_key, $ref)) {
|
||||
if ($key_existed && is_array($ref) && (isset($ref[$unset_key]) || array_key_exists($unset_key, $ref))) {
|
||||
$key_existed = TRUE;
|
||||
unset($ref[$unset_key]);
|
||||
}
|
||||
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 = '';
|
||||
|
||||
|
@ -256,7 +259,6 @@ class Random {
|
|||
return $output;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a placeholder image.
|
||||
*
|
||||
|
|
|
@ -13,6 +13,8 @@ use Drupal\Component\Render\MarkupInterface;
|
|||
* @link sanitization sanitization functions @endlink or the @link theme_render theme and render systems @endlink
|
||||
* so that the output can can be themed, escaped, and altered properly.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2549395
|
||||
*
|
||||
* @see TwigExtension::escapeFilter()
|
||||
* @see twig_render_template()
|
||||
* @see sanitization
|
||||
|
@ -34,8 +36,11 @@ class SafeMarkup {
|
|||
* @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
|
||||
* Instead, you should just check if a variable is an instance of
|
||||
* \Drupal\Component\Render\MarkupInterface.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2549395
|
||||
*/
|
||||
public static function isSafe($string, $strategy = 'html') {
|
||||
@trigger_error('SafeMarkup::isSafe() is scheduled for removal in Drupal 9.0.0. Instead, you should just check if a variable is an instance of \Drupal\Component\Render\MarkupInterface. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
|
||||
return $string instanceof MarkupInterface;
|
||||
}
|
||||
|
||||
|
@ -58,9 +63,11 @@ class SafeMarkup {
|
|||
* possible, \Drupal\Component\Utility\Html::escape() can be used in places
|
||||
* where explicit escaping is needed.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2549395
|
||||
* @see drupal_validate_utf8()
|
||||
*/
|
||||
public static function checkPlain($text) {
|
||||
@trigger_error('SafeMarkup::checkPlain() is scheduled for removal in Drupal 9.0.0. Rely on Twig\'s auto-escaping feature, or use the @link theme_render #plain_text @endlink key when constructing a render array that contains plain text in order to use the renderer\'s auto-escaping feature. If neither of these are possible, \Drupal\Component\Utility\Html::escape() can be used in places where explicit escaping is needed. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
|
||||
return new HtmlEscapedText($text);
|
||||
}
|
||||
|
||||
|
@ -84,8 +91,11 @@ class SafeMarkup {
|
|||
*
|
||||
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
|
||||
* Use \Drupal\Component\Render\FormattableMarkup.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2549395
|
||||
*/
|
||||
public static function format($string, array $args) {
|
||||
@trigger_error('SafeMarkup::format() is scheduled for removal in Drupal 9.0.0. Use \Drupal\Component\Render\FormattableMarkup. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
|
||||
return new FormattableMarkup($string, $args);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -87,13 +87,6 @@ EOD;
|
|||
*/
|
||||
const STATUS_ERROR = -1;
|
||||
|
||||
/**
|
||||
* Holds the multibyte capabilities of the current environment.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected static $status = 0;
|
||||
|
||||
/**
|
||||
* Gets the current status of unicode/multibyte support on this environment.
|
||||
*
|
||||
|
@ -107,7 +100,13 @@ EOD;
|
|||
* An error occurred. No unicode support.
|
||||
*/
|
||||
public static function getStatus() {
|
||||
return static::$status;
|
||||
switch (static::check()) {
|
||||
case 'mb_strlen':
|
||||
return Unicode::STATUS_SINGLEBYTE;
|
||||
case '':
|
||||
return Unicode::STATUS_MULTIBYTE;
|
||||
}
|
||||
return Unicode::STATUS_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,12 +122,16 @@ EOD;
|
|||
*
|
||||
* @param int $status
|
||||
* The new status of multibyte support.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In
|
||||
* Drupal 9 there will be no way to set the status and in Drupal 8 this
|
||||
* ability has been removed because mb_*() functions are supplied using
|
||||
* Symfony's polyfill.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2850048
|
||||
*/
|
||||
public static function setStatus($status) {
|
||||
if (!in_array($status, [static::STATUS_SINGLEBYTE, static::STATUS_MULTIBYTE, static::STATUS_ERROR])) {
|
||||
throw new \InvalidArgumentException('Invalid status value for unicode support.');
|
||||
}
|
||||
static::$status = $status;
|
||||
@trigger_error('\Drupal\Component\Utility\Unicode::setStatus() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. In Drupal 9 there will be no way to set the status and in Drupal 8 this ability has been removed because mb_*() functions are supplied using Symfony\'s polyfill. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,38 +146,33 @@ EOD;
|
|||
* Otherwise, an empty string.
|
||||
*/
|
||||
public static function check() {
|
||||
// Set appropriate configuration.
|
||||
mb_internal_encoding('utf-8');
|
||||
mb_language('uni');
|
||||
|
||||
// Check for mbstring extension.
|
||||
if (!function_exists('mb_strlen')) {
|
||||
static::$status = static::STATUS_SINGLEBYTE;
|
||||
if (!extension_loaded('mbstring')) {
|
||||
return 'mb_strlen';
|
||||
}
|
||||
|
||||
// Check mbstring configuration.
|
||||
if (ini_get('mbstring.func_overload') != 0) {
|
||||
static::$status = static::STATUS_ERROR;
|
||||
return 'mbstring.func_overload';
|
||||
}
|
||||
if (ini_get('mbstring.encoding_translation') != 0) {
|
||||
static::$status = static::STATUS_ERROR;
|
||||
return 'mbstring.encoding_translation';
|
||||
}
|
||||
// mbstring.http_input and mbstring.http_output are deprecated and empty by
|
||||
// default in PHP 5.6.
|
||||
if (version_compare(PHP_VERSION, '5.6.0') == -1) {
|
||||
if (ini_get('mbstring.http_input') != 'pass') {
|
||||
static::$status = static::STATUS_ERROR;
|
||||
return 'mbstring.http_input';
|
||||
}
|
||||
if (ini_get('mbstring.http_output') != 'pass') {
|
||||
static::$status = static::STATUS_ERROR;
|
||||
return 'mbstring.http_output';
|
||||
}
|
||||
}
|
||||
|
||||
// Set appropriate configuration.
|
||||
mb_internal_encoding('utf-8');
|
||||
mb_language('uni');
|
||||
static::$status = static::STATUS_MULTIBYTE;
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -224,17 +222,7 @@ EOD;
|
|||
* Converted data or FALSE.
|
||||
*/
|
||||
public static function convertToUtf8($data, $encoding) {
|
||||
if (function_exists('iconv')) {
|
||||
return @iconv($encoding, 'utf-8', $data);
|
||||
}
|
||||
elseif (function_exists('mb_convert_encoding')) {
|
||||
return @mb_convert_encoding($data, 'utf-8', $encoding);
|
||||
}
|
||||
elseif (function_exists('recode_string')) {
|
||||
return @recode_string($encoding . '..utf-8', $data);
|
||||
}
|
||||
// Cannot convert.
|
||||
return FALSE;
|
||||
return @iconv($encoding, 'utf-8', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,7 +252,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);
|
||||
}
|
||||
|
@ -279,15 +269,15 @@ EOD;
|
|||
*
|
||||
* @return int
|
||||
* The length of the string.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
|
||||
* mb_strlen() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2850048
|
||||
*/
|
||||
public static function strlen($text) {
|
||||
if (static::getStatus() == static::STATUS_MULTIBYTE) {
|
||||
return mb_strlen($text);
|
||||
}
|
||||
else {
|
||||
// Do not count UTF-8 continuation bytes.
|
||||
return strlen(preg_replace("/[\x80-\xBF]/", '', $text));
|
||||
}
|
||||
@trigger_error('\Drupal\Component\Utility\Unicode::strlen() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strlen() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
|
||||
return mb_strlen($text);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,18 +288,15 @@ EOD;
|
|||
*
|
||||
* @return string
|
||||
* The string in uppercase.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
|
||||
* mb_strtoupper() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2850048
|
||||
*/
|
||||
public static function strtoupper($text) {
|
||||
if (static::getStatus() == static::STATUS_MULTIBYTE) {
|
||||
return mb_strtoupper($text);
|
||||
}
|
||||
else {
|
||||
// Use C-locale for ASCII-only uppercase.
|
||||
$text = strtoupper($text);
|
||||
// Case flip Latin-1 accented letters.
|
||||
$text = preg_replace_callback('/\xC3[\xA0-\xB6\xB8-\xBE]/', '\Drupal\Component\Utility\Unicode::caseFlip', $text);
|
||||
return $text;
|
||||
}
|
||||
@trigger_error('\Drupal\Component\Utility\Unicode::strtoupper() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtoupper() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
|
||||
return mb_strtoupper($text);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -320,18 +307,15 @@ EOD;
|
|||
*
|
||||
* @return string
|
||||
* The string in lowercase.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
|
||||
* mb_strtolower() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2850048
|
||||
*/
|
||||
public static function strtolower($text) {
|
||||
if (static::getStatus() == static::STATUS_MULTIBYTE) {
|
||||
return mb_strtolower($text);
|
||||
}
|
||||
else {
|
||||
// Use C-locale for ASCII-only lowercase.
|
||||
$text = strtolower($text);
|
||||
// Case flip Latin-1 accented letters.
|
||||
$text = preg_replace_callback('/\xC3[\x80-\x96\x98-\x9E]/', '\Drupal\Component\Utility\Unicode::caseFlip', $text);
|
||||
return $text;
|
||||
}
|
||||
@trigger_error('\Drupal\Component\Utility\Unicode::strtolower() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strtolower() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
|
||||
return mb_strtolower($text);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,7 +328,7 @@ EOD;
|
|||
* The string with the first character as uppercase.
|
||||
*/
|
||||
public static function ucfirst($text) {
|
||||
return static::strtoupper(static::substr($text, 0, 1)) . static::substr($text, 1);
|
||||
return mb_strtoupper(mb_substr($text, 0, 1)) . mb_substr($text, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,7 +344,7 @@ EOD;
|
|||
*/
|
||||
public static function lcfirst($text) {
|
||||
// Note: no mbstring equivalent!
|
||||
return static::strtolower(static::substr($text, 0, 1)) . static::substr($text, 1);
|
||||
return mb_strtolower(mb_substr($text, 0, 1)) . mb_substr($text, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -376,8 +360,8 @@ 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 $matches[1] . Unicode::strtoupper($matches[2]);
|
||||
return preg_replace_callback($regex, function (array $matches) {
|
||||
return $matches[1] . mb_strtoupper($matches[2]);
|
||||
}, $text);
|
||||
}
|
||||
|
||||
|
@ -397,92 +381,15 @@ EOD;
|
|||
*
|
||||
* @return string
|
||||
* The shortened string.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
|
||||
* mb_substr() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2850048
|
||||
*/
|
||||
public static function substr($text, $start, $length = NULL) {
|
||||
if (static::getStatus() == static::STATUS_MULTIBYTE) {
|
||||
return $length === NULL ? mb_substr($text, $start) : mb_substr($text, $start, $length);
|
||||
}
|
||||
else {
|
||||
$strlen = strlen($text);
|
||||
// Find the starting byte offset.
|
||||
$bytes = 0;
|
||||
if ($start > 0) {
|
||||
// Count all the characters except continuation bytes from the start
|
||||
// until we have found $start characters or the end of the string.
|
||||
$bytes = -1; $chars = -1;
|
||||
while ($bytes < $strlen - 1 && $chars < $start) {
|
||||
$bytes++;
|
||||
$c = ord($text[$bytes]);
|
||||
if ($c < 0x80 || $c >= 0xC0) {
|
||||
$chars++;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($start < 0) {
|
||||
// Count all the characters except continuation bytes from the end
|
||||
// until we have found abs($start) characters.
|
||||
$start = abs($start);
|
||||
$bytes = $strlen; $chars = 0;
|
||||
while ($bytes > 0 && $chars < $start) {
|
||||
$bytes--;
|
||||
$c = ord($text[$bytes]);
|
||||
if ($c < 0x80 || $c >= 0xC0) {
|
||||
$chars++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$istart = $bytes;
|
||||
|
||||
// Find the ending byte offset.
|
||||
if ($length === NULL) {
|
||||
$iend = $strlen;
|
||||
}
|
||||
elseif ($length > 0) {
|
||||
// Count all the characters except continuation bytes from the starting
|
||||
// index until we have found $length characters or reached the end of
|
||||
// the string, then backtrace one byte.
|
||||
$iend = $istart - 1;
|
||||
$chars = -1;
|
||||
$last_real = FALSE;
|
||||
while ($iend < $strlen - 1 && $chars < $length) {
|
||||
$iend++;
|
||||
$c = ord($text[$iend]);
|
||||
$last_real = FALSE;
|
||||
if ($c < 0x80 || $c >= 0xC0) {
|
||||
$chars++;
|
||||
$last_real = TRUE;
|
||||
}
|
||||
}
|
||||
// Backtrace one byte if the last character we found was a real
|
||||
// character and we don't need it.
|
||||
if ($last_real && $chars >= $length) {
|
||||
$iend--;
|
||||
}
|
||||
}
|
||||
elseif ($length < 0) {
|
||||
// Count all the characters except continuation bytes from the end
|
||||
// until we have found abs($start) characters, then backtrace one byte.
|
||||
$length = abs($length);
|
||||
$iend = $strlen; $chars = 0;
|
||||
while ($iend > 0 && $chars < $length) {
|
||||
$iend--;
|
||||
$c = ord($text[$iend]);
|
||||
if ($c < 0x80 || $c >= 0xC0) {
|
||||
$chars++;
|
||||
}
|
||||
}
|
||||
// Backtrace one byte if we are not at the beginning of the string.
|
||||
if ($iend > 0) {
|
||||
$iend--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// $length == 0, return an empty string.
|
||||
return '';
|
||||
}
|
||||
|
||||
return substr($text, $istart, max(0, $iend - $istart + 1));
|
||||
}
|
||||
@trigger_error('\Drupal\Component\Utility\Unicode::substr() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_substr() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
|
||||
return mb_substr($text, $start, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -524,15 +431,15 @@ EOD;
|
|||
$max_length = max($max_length, 0);
|
||||
$min_wordsafe_length = max($min_wordsafe_length, 0);
|
||||
|
||||
if (static::strlen($string) <= $max_length) {
|
||||
if (mb_strlen($string) <= $max_length) {
|
||||
// No truncation needed, so don't add ellipsis, just return.
|
||||
return $string;
|
||||
}
|
||||
|
||||
if ($add_ellipsis) {
|
||||
// Truncate ellipsis in case $max_length is small.
|
||||
$ellipsis = static::substr('…', 0, $max_length);
|
||||
$max_length -= static::strlen($ellipsis);
|
||||
$ellipsis = mb_substr('…', 0, $max_length);
|
||||
$max_length -= mb_strlen($ellipsis);
|
||||
$max_length = max($max_length, 0);
|
||||
}
|
||||
|
||||
|
@ -546,16 +453,16 @@ EOD;
|
|||
// Find the last word boundary, if there is one within $min_wordsafe_length
|
||||
// to $max_length characters. preg_match() is always greedy, so it will
|
||||
// find the longest string possible.
|
||||
$found = preg_match('/^(.{' . $min_wordsafe_length . ',' . $max_length . '})[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']/u', $string, $matches);
|
||||
$found = preg_match('/^(.{' . $min_wordsafe_length . ',' . $max_length . '})[' . Unicode::PREG_CLASS_WORD_BOUNDARY . ']/us', $string, $matches);
|
||||
if ($found) {
|
||||
$string = $matches[1];
|
||||
}
|
||||
else {
|
||||
$string = static::substr($string, 0, $max_length);
|
||||
$string = mb_substr($string, 0, $max_length);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$string = static::substr($string, 0, $max_length);
|
||||
$string = mb_substr($string, 0, $max_length);
|
||||
}
|
||||
|
||||
if ($add_ellipsis) {
|
||||
|
@ -580,8 +487,8 @@ 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) {
|
||||
return strcmp(static::strtoupper($str1), static::strtoupper($str2));
|
||||
public static function strcasecmp($str1, $str2) {
|
||||
return strcmp(mb_strtoupper($str1), mb_strtoupper($str2));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -601,18 +508,24 @@ EOD;
|
|||
*
|
||||
* @param string $string
|
||||
* The header to encode.
|
||||
* @param bool $shorten
|
||||
* If TRUE, only return the first chunk of a multi-chunk encoded string.
|
||||
*
|
||||
* @return string
|
||||
* The mime-encoded header.
|
||||
*/
|
||||
public static function mimeHeaderEncode($string) {
|
||||
public static function mimeHeaderEncode($string, $shorten = FALSE) {
|
||||
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) {
|
||||
$chunk = static::truncateBytes($string, $chunk_size);
|
||||
$output .= ' =?UTF-8?B?' . base64_encode($chunk) . "?=\n";
|
||||
if ($shorten) {
|
||||
break;
|
||||
}
|
||||
$c = strlen($chunk);
|
||||
$string = substr($string, $c);
|
||||
$len -= $c;
|
||||
|
@ -707,18 +620,15 @@ EOD;
|
|||
* The position where $needle occurs in $haystack, always relative to the
|
||||
* beginning (independent of $offset), or FALSE if not found. Note that
|
||||
* a return value of 0 is not the same as FALSE.
|
||||
*
|
||||
* @deprecated in Drupal 8.6.0, will be removed before Drupal 9.0.0. Use
|
||||
* mb_strpos() instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2850048
|
||||
*/
|
||||
public static function strpos($haystack, $needle, $offset = 0) {
|
||||
if (static::getStatus() == static::STATUS_MULTIBYTE) {
|
||||
return mb_strpos($haystack, $needle, $offset);
|
||||
}
|
||||
else {
|
||||
// Remove Unicode continuation characters, to be compatible with
|
||||
// Unicode::strlen() and Unicode::substr().
|
||||
$haystack = preg_replace("/[\x80-\xBF]/", '', $haystack);
|
||||
$needle = preg_replace("/[\x80-\xBF]/", '', $needle);
|
||||
return strpos($haystack, $needle, $offset);
|
||||
}
|
||||
@trigger_error('\Drupal\Component\Utility\Unicode::strpos() is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0. Use mb_strpos() instead. See https://www.drupal.org/node/2850048.', E_USER_DEPRECATED);
|
||||
return mb_strpos($haystack, $needle, $offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class UrlHelper {
|
|||
/**
|
||||
* Parses an array into a valid, rawurlencoded query string.
|
||||
*
|
||||
* rawurlencode() is RFC3986 compliant, and as a consequence RFC3987
|
||||
* Function rawurlencode() is RFC3986 compliant, and as a consequence RFC3987
|
||||
* compliant. The latter defines the required format of "URLs" in HTML5.
|
||||
* urlencode() is almost the same as rawurlencode(), except that it encodes
|
||||
* spaces as "+" instead of "%20". This makes its result non compliant to
|
||||
|
@ -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.
|
||||
|
@ -248,6 +248,16 @@ class UrlHelper {
|
|||
* Exception thrown when a either $url or $bath_url are not fully qualified.
|
||||
*/
|
||||
public static function externalIsLocal($url, $base_url) {
|
||||
// Some browsers treat \ as / so normalize to forward slashes.
|
||||
$url = str_replace('\\', '/', $url);
|
||||
|
||||
// Leading control characters may be ignored or mishandled by browsers, so
|
||||
// assume such a path may lead to an non-local location. The \p{C} character
|
||||
// class matches all UTF-8 control, unassigned, and private characters.
|
||||
if (preg_match('/^\p{C}/u', $url) !== 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$url_parts = parse_url($url);
|
||||
$base_parts = parse_url($base_url);
|
||||
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
"description": "Mostly static utility classes for string, xss, array, image, and other commonly needed manipulations.",
|
||||
"keywords": ["drupal"],
|
||||
"homepage": "https://www.drupal.org/project/drupal",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"paragonie/random_compat": "^1.0|^2.0",
|
||||
"drupal/core-render": "~8.2"
|
||||
"drupal/core-render": "^8.2",
|
||||
"symfony/polyfill-iconv": "~1.0",
|
||||
"symfony/polyfill-mbstring": "~1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace Drupal\Component\Uuid;
|
|||
* @see http://php.net/com_create_guid
|
||||
*/
|
||||
class Com implements UuidInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"name": "drupal/core-uuid",
|
||||
"description": "PHP library for reading PO files.",
|
||||
"description": "UUID generation and validation.",
|
||||
"type": "library",
|
||||
"license": "GPL-2.0+",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"support": {
|
||||
"issues": "https://www.drupal.org/project/issues/drupal",
|
||||
"irc": "irc://irc.freenode.net/drupal-contribute",
|
||||
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"drupal/core-utility": "~8.2"
|
||||
"drupal/core-utility": "^8.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
|
@ -38,7 +38,7 @@ interface AccessManagerInterface {
|
|||
/**
|
||||
* Execute access checks against the incoming request.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The incoming request.
|
||||
* @param \Drupal\Core\Session\AccountInterface $account
|
||||
* (optional) Run access checks for this account. Defaults to the current
|
||||
|
|
|
@ -39,7 +39,7 @@ abstract class AccessResult implements AccessResultInterface, RefinableCacheable
|
|||
* isNeutral() will be TRUE.
|
||||
*/
|
||||
public static function neutral($reason = NULL) {
|
||||
assert('is_string($reason) || is_null($reason)');
|
||||
assert(is_string($reason) || is_null($reason));
|
||||
return new AccessResultNeutral($reason);
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ abstract class AccessResult implements AccessResultInterface, RefinableCacheable
|
|||
* isForbidden() will be TRUE.
|
||||
*/
|
||||
public static function forbidden($reason = NULL) {
|
||||
assert('is_string($reason) || is_null($reason)');
|
||||
assert(is_string($reason) || is_null($reason));
|
||||
return new AccessResultForbidden($reason);
|
||||
}
|
||||
|
||||
|
@ -87,13 +87,16 @@ abstract class AccessResult implements AccessResultInterface, RefinableCacheable
|
|||
*
|
||||
* @param bool $condition
|
||||
* The condition to evaluate.
|
||||
* @param string|null $reason
|
||||
* (optional) The reason why access is forbidden. Intended for developers,
|
||||
* hence not translatable
|
||||
*
|
||||
* @return \Drupal\Core\Access\AccessResult
|
||||
* If $condition is TRUE, isForbidden() will be TRUE, otherwise isNeutral()
|
||||
* will be TRUE.
|
||||
*/
|
||||
public static function forbiddenIf($condition) {
|
||||
return $condition ? static::forbidden() : static::neutral();
|
||||
public static function forbiddenIf($condition, $reason = NULL) {
|
||||
return $condition ? static::forbidden($reason) : static::neutral();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,10 +336,10 @@ abstract class AccessResult implements AccessResultInterface, RefinableCacheable
|
|||
$merge_other = TRUE;
|
||||
}
|
||||
|
||||
if ($this->isForbidden() && $this instanceof AccessResultReasonInterface) {
|
||||
if ($this->isForbidden() && $this instanceof AccessResultReasonInterface && !is_null($this->getReason())) {
|
||||
$result->setReason($this->getReason());
|
||||
}
|
||||
elseif ($other->isForbidden() && $other instanceof AccessResultReasonInterface) {
|
||||
elseif ($other->isForbidden() && $other instanceof AccessResultReasonInterface && !is_null($other->getReason())) {
|
||||
$result->setReason($other->getReason());
|
||||
}
|
||||
}
|
||||
|
@ -350,14 +353,13 @@ abstract class AccessResult implements AccessResultInterface, RefinableCacheable
|
|||
$result = static::neutral();
|
||||
if (!$this->isNeutral() || ($this->getCacheMaxAge() === 0 && $other->isNeutral()) || ($this->getCacheMaxAge() !== 0 && $other instanceof CacheableDependencyInterface && $other->getCacheMaxAge() !== 0)) {
|
||||
$merge_other = TRUE;
|
||||
if ($other instanceof AccessResultReasonInterface) {
|
||||
$result->setReason($other->getReason());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($this instanceof AccessResultReasonInterface) {
|
||||
$result->setReason($this->getReason());
|
||||
}
|
||||
|
||||
if ($this instanceof AccessResultReasonInterface && !is_null($this->getReason())) {
|
||||
$result->setReason($this->getReason());
|
||||
}
|
||||
elseif ($other instanceof AccessResultReasonInterface && !is_null($other->getReason())) {
|
||||
$result->setReason($other->getReason());
|
||||
}
|
||||
}
|
||||
$result->inheritCacheability($this);
|
||||
|
@ -424,9 +426,9 @@ abstract class AccessResult implements AccessResultInterface, RefinableCacheable
|
|||
/**
|
||||
* Inherits the cacheability of the other access result, if any.
|
||||
*
|
||||
* inheritCacheability() differs from addCacheableDependency() in how it
|
||||
* handles max-age, because it is designed to inherit the cacheability of the
|
||||
* second operand in the andIf() and orIf() operations. There, the situation
|
||||
* This method differs from addCacheableDependency() in how it handles
|
||||
* max-age, because it is designed to inherit the cacheability of the second
|
||||
* operand in the andIf() and orIf() operations. There, the situation
|
||||
* "allowed, max-age=0 OR allowed, max-age=1000" needs to yield max-age 1000
|
||||
* as the end result.
|
||||
*
|
||||
|
|
|
@ -18,13 +18,12 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -142,6 +142,7 @@ class CheckProvider implements CheckProviderInterface, ContainerAwareInterface {
|
|||
|
||||
return $checks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a mapping of requirement keys to access checker service IDs.
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,6 @@ use Symfony\Component\Routing\RouteCollection;
|
|||
*/
|
||||
interface CheckProviderInterface {
|
||||
|
||||
|
||||
/**
|
||||
* For each route, saves a list of applicable access checks to the route.
|
||||
*
|
||||
|
|
|
@ -61,7 +61,14 @@ class CustomAccessCheck implements RoutingAccessInterface {
|
|||
* The access result.
|
||||
*/
|
||||
public function access(Route $route, RouteMatchInterface $route_match, AccountInterface $account) {
|
||||
$callable = $this->controllerResolver->getControllerFromDefinition($route->getRequirement('_custom_access'));
|
||||
try {
|
||||
$callable = $this->controllerResolver->getControllerFromDefinition($route->getRequirement('_custom_access'));
|
||||
}
|
||||
catch (\InvalidArgumentException $e) {
|
||||
// The custom access controller method was not found.
|
||||
throw new \BadMethodCallException(sprintf('The "%s" method is not callable as a _custom_access callback in route "%s"', $route->getRequirement('_custom_access'), $route->getPath()));
|
||||
}
|
||||
|
||||
$arguments_resolver = $this->argumentsResolverFactory->getArgumentsResolver($route_match, $account);
|
||||
$arguments = $arguments_resolver->getArguments($callable);
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\TempStore\PrivateTempStoreFactory;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Redirects to an entity deletion form.
|
||||
*
|
||||
* @Action(
|
||||
* id = "entity:delete_action",
|
||||
* action_label = @Translation("Delete"),
|
||||
* deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityDeleteActionDeriver",
|
||||
* )
|
||||
*/
|
||||
class DeleteAction extends EntityActionBase {
|
||||
|
||||
/**
|
||||
* The tempstore object.
|
||||
*
|
||||
* @var \Drupal\Core\TempStore\SharedTempStore
|
||||
*/
|
||||
protected $tempStore;
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Constructs a new DeleteAction object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
||||
* The tempstore factory.
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* Current user.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
||||
$this->currentUser = $current_user;
|
||||
$this->tempStore = $temp_store_factory->get('entity_delete_multiple_confirm');
|
||||
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('tempstore.private'),
|
||||
$container->get('current_user')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function executeMultiple(array $entities) {
|
||||
/** @var \Drupal\Core\Entity\EntityInterface[] $entities */
|
||||
$selection = [];
|
||||
foreach ($entities as $entity) {
|
||||
$langcode = $entity->language()->getId();
|
||||
$selection[$entity->id()][$langcode] = $langcode;
|
||||
}
|
||||
$this->tempStore->set($this->currentUser->id() . ':' . $this->getPluginDefinition()['type'], $selection);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($object = NULL) {
|
||||
$this->executeMultiple([$object]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
return $object->access('delete', $account, $return_as_object);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action\Derivative;
|
||||
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Core\StringTranslation\TranslationInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a base action for each entity type with specific interfaces.
|
||||
*/
|
||||
abstract class EntityActionDeriverBase extends DeriverBase implements ContainerDeriverInterface {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Constructs a new EntityActionDeriverBase object.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
|
||||
* The string translation service.
|
||||
*/
|
||||
public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation) {
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
$this->stringTranslation = $string_translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, $base_plugin_id) {
|
||||
return new static(
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('string_translation')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the deriver can be used for the provided entity type.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the entity type can be used, FALSE otherwise.
|
||||
*/
|
||||
abstract protected function isApplicable(EntityTypeInterface $entity_type);
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
if (empty($this->derivatives)) {
|
||||
$definitions = [];
|
||||
foreach ($this->getApplicableEntityTypes() as $entity_type_id => $entity_type) {
|
||||
$definition = $base_plugin_definition;
|
||||
$definition['type'] = $entity_type_id;
|
||||
$definition['label'] = sprintf('%s %s', $base_plugin_definition['action_label'], $entity_type->getSingularLabel());
|
||||
$definitions[$entity_type_id] = $definition;
|
||||
}
|
||||
$this->derivatives = $definitions;
|
||||
}
|
||||
|
||||
return parent::getDerivativeDefinitions($base_plugin_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of applicable entity types.
|
||||
*
|
||||
* The list consists of all entity types which match the conditions for the
|
||||
* given deriver.
|
||||
* For example, if the action applies to entities that are publishable,
|
||||
* this method will find all entity types that are publishable.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityTypeInterface[]
|
||||
* The applicable entity types, keyed by entity type ID.
|
||||
*/
|
||||
protected function getApplicableEntityTypes() {
|
||||
$entity_types = $this->entityTypeManager->getDefinitions();
|
||||
$entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) {
|
||||
return $this->isApplicable($entity_type);
|
||||
});
|
||||
|
||||
return $entity_types;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action\Derivative;
|
||||
|
||||
use Drupal\Core\Entity\EntityChangedInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
|
||||
/**
|
||||
* Provides an action deriver that finds entity types of EntityChangedInterface.
|
||||
*
|
||||
* @see \Drupal\Core\Action\Plugin\Action\SaveAction
|
||||
*/
|
||||
class EntityChangedActionDeriver extends EntityActionDeriverBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function isApplicable(EntityTypeInterface $entity_type) {
|
||||
return $entity_type->entityClassImplements(EntityChangedInterface::class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action\Derivative;
|
||||
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
|
||||
/**
|
||||
* Provides an action deriver that finds entity types with delete form.
|
||||
*
|
||||
* @see \Drupal\Core\Action\Plugin\Action\DeleteAction
|
||||
*/
|
||||
class EntityDeleteActionDeriver extends EntityActionDeriverBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDerivativeDefinitions($base_plugin_definition) {
|
||||
if (empty($this->derivatives)) {
|
||||
$definitions = [];
|
||||
foreach ($this->getApplicableEntityTypes() as $entity_type_id => $entity_type) {
|
||||
$definition = $base_plugin_definition;
|
||||
$definition['type'] = $entity_type_id;
|
||||
$definition['label'] = $this->t('Delete @entity_type', ['@entity_type' => $entity_type->getSingularLabel()]);
|
||||
$definition['confirm_form_route_name'] = 'entity.' . $entity_type->id() . '.delete_multiple_form';
|
||||
$definitions[$entity_type_id] = $definition;
|
||||
}
|
||||
$this->derivatives = $definitions;
|
||||
}
|
||||
|
||||
return $this->derivatives;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function isApplicable(EntityTypeInterface $entity_type) {
|
||||
return $entity_type->hasLinkTemplate('delete-multiple-form');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action\Derivative;
|
||||
|
||||
use Drupal\Core\Entity\EntityPublishedInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
|
||||
/**
|
||||
* Provides an action deriver that finds publishable entity types.
|
||||
*
|
||||
* @see \Drupal\Core\Action\Plugin\Action\PublishAction
|
||||
* @see \Drupal\Core\Action\Plugin\Action\UnpublishAction
|
||||
*/
|
||||
class EntityPublishedActionDeriver extends EntityActionDeriverBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function isApplicable(EntityTypeInterface $entity_type) {
|
||||
return $entity_type->entityClassImplements(EntityPublishedInterface::class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action;
|
||||
|
||||
use Drupal\Component\Plugin\DependentPluginInterface;
|
||||
use Drupal\Core\Action\ActionBase;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Base class for entity-based actions.
|
||||
*/
|
||||
abstract class EntityActionBase extends ActionBase implements DependentPluginInterface, ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The entity type manager.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
|
||||
*/
|
||||
protected $entityTypeManager;
|
||||
|
||||
/**
|
||||
* Constructs a EntityActionBase object.
|
||||
*
|
||||
* @param mixed[] $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->entityTypeManager = $entity_type_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity_type.manager')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
$module_name = $this->entityTypeManager
|
||||
->getDefinition($this->getPluginDefinition()['type'])
|
||||
->getProvider();
|
||||
return ['module' => [$module_name]];
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Publishes an entity.
|
||||
*
|
||||
* @Action(
|
||||
* id = "entity:publish_action",
|
||||
* action_label = @Translation("Publish"),
|
||||
* deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver",
|
||||
* )
|
||||
*/
|
||||
class PublishAction extends EntityActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setPublished()->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
$key = $object->getEntityType()->getKey('published');
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $object */
|
||||
$result = $object->access('update', $account, TRUE)
|
||||
->andIf($object->$key->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
|
||||
}
|
79
web/core/lib/Drupal/Core/Action/Plugin/Action/SaveAction.php
Normal file
79
web/core/lib/Drupal/Core/Action/Plugin/Action/SaveAction.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action;
|
||||
|
||||
use Drupal\Component\Datetime\TimeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides an action that can save any entity.
|
||||
*
|
||||
* @Action(
|
||||
* id = "entity:save_action",
|
||||
* action_label = @Translation("Save"),
|
||||
* deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityChangedActionDeriver",
|
||||
* )
|
||||
*/
|
||||
class SaveAction extends EntityActionBase {
|
||||
|
||||
/**
|
||||
* The time service.
|
||||
*
|
||||
* @var \Drupal\Component\Datetime\TimeInterface
|
||||
*/
|
||||
protected $time;
|
||||
|
||||
/**
|
||||
* Constructs a SaveAction object.
|
||||
*
|
||||
* @param mixed[] $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
* @param string $plugin_id
|
||||
* The plugin ID for the plugin instance.
|
||||
* @param mixed $plugin_definition
|
||||
* The plugin implementation definition.
|
||||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
||||
* The entity type manager.
|
||||
* @param \Drupal\Component\Datetime\TimeInterface $time
|
||||
* The time service.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, TimeInterface $time) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager);
|
||||
$this->time = $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$configuration,
|
||||
$plugin_id,
|
||||
$plugin_definition,
|
||||
$container->get('entity_type.manager'),
|
||||
$container->get('datetime.time')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setChangedTime($this->time->getRequestTime())->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
// It's not necessary to check the changed field access here, because
|
||||
// Drupal\Core\Field\ChangedFieldItemList would anyway return 'not allowed'.
|
||||
// Also changing the changed field value is only a workaround to trigger an
|
||||
// entity resave. Without a field change, this would not be possible.
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $object */
|
||||
return $object->access('update', $account, $return_as_object);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Action\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Unpublishes an entity.
|
||||
*
|
||||
* @Action(
|
||||
* id = "entity:unpublish_action",
|
||||
* action_label = @Translation("Unpublish"),
|
||||
* deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver",
|
||||
* )
|
||||
*/
|
||||
class UnpublishAction extends EntityActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute($entity = NULL) {
|
||||
$entity->setUnpublished()->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
$key = $object->getEntityType()->getKey('published');
|
||||
|
||||
/** @var \Drupal\Core\Entity\EntityInterface $object */
|
||||
$result = $object->access('update', $account, TRUE)
|
||||
->andIf($object->$key->access('edit', $account, TRUE));
|
||||
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
|
||||
}
|
56
web/core/lib/Drupal/Core/Ajax/AjaxFormHelperTrait.php
Normal file
56
web/core/lib/Drupal/Core/Ajax/AjaxFormHelperTrait.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Ajax;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
|
||||
/**
|
||||
* Provides a helper to for submitting an AJAX form.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait AjaxFormHelperTrait {
|
||||
|
||||
use AjaxHelperTrait;
|
||||
|
||||
/**
|
||||
* Submit form dialog #ajax callback.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*
|
||||
* @return \Drupal\Core\Ajax\AjaxResponse
|
||||
* An AJAX response that display validation error messages or represents a
|
||||
* successful submission.
|
||||
*/
|
||||
public function ajaxSubmit(array &$form, FormStateInterface $form_state) {
|
||||
if ($form_state->hasAnyErrors()) {
|
||||
$form['status_messages'] = [
|
||||
'#type' => 'status_messages',
|
||||
'#weight' => -1000,
|
||||
];
|
||||
$response = new AjaxResponse();
|
||||
$response->addCommand(new ReplaceCommand('[data-drupal-selector="' . $form['#attributes']['data-drupal-selector'] . '"]', $form));
|
||||
}
|
||||
else {
|
||||
$response = $this->successfulAjaxSubmit($form, $form_state);
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the form to respond to a successful AJAX submission.
|
||||
*
|
||||
* @param array $form
|
||||
* An associative array containing the structure of the form.
|
||||
* @param \Drupal\Core\Form\FormStateInterface $form_state
|
||||
* The current state of the form.
|
||||
*
|
||||
* @return \Drupal\Core\Ajax\AjaxResponse
|
||||
* An AJAX response.
|
||||
*/
|
||||
abstract protected function successfulAjaxSubmit(array $form, FormStateInterface $form_state);
|
||||
|
||||
}
|
39
web/core/lib/Drupal/Core/Ajax/AjaxHelperTrait.php
Normal file
39
web/core/lib/Drupal/Core/Ajax/AjaxHelperTrait.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Ajax;
|
||||
|
||||
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
|
||||
|
||||
/**
|
||||
* Provides a helper to determine if the current request is via AJAX.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait AjaxHelperTrait {
|
||||
|
||||
/**
|
||||
* Determines if the current request is via AJAX.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the current request is via AJAX, FALSE otherwise.
|
||||
*/
|
||||
protected function isAjax() {
|
||||
foreach (['drupal_ajax', 'drupal_modal', 'drupal_dialog'] as $wrapper) {
|
||||
if (strpos($this->getRequestWrapperFormat(), $wrapper) !== FALSE) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapper format of the current request.
|
||||
*
|
||||
* @string
|
||||
* The wrapper format.
|
||||
*/
|
||||
protected function getRequestWrapperFormat() {
|
||||
return \Drupal::request()->get(MainContentViewSubscriber::WRAPPER_FORMAT);
|
||||
}
|
||||
|
||||
}
|
|
@ -119,7 +119,7 @@ class OpenDialogCommand implements CommandInterface, CommandWithAttachedAssetsIn
|
|||
* The new title of the dialog.
|
||||
*/
|
||||
public function setDialogTitle($title) {
|
||||
$this->setDialogOptions('title', $title);
|
||||
$this->setDialogOption('title', $title);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace Drupal\Core\Ajax;
|
|||
* @ingroup ajax
|
||||
*/
|
||||
class OpenModalDialogCommand extends OpenDialogCommand {
|
||||
|
||||
/**
|
||||
* Constructs an OpenModalDialog object.
|
||||
*
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue