diff --git a/core/composer.json b/core/composer.json index 8c4113a..64928b1 100644 --- a/core/composer.json +++ b/core/composer.json @@ -7,8 +7,7 @@ "symfony/http-kernel": "2.1.*", "symfony/routing": "2.1.*", "symfony/yaml": "2.1.*", - "twig/twig": "1.9.*", - "doctrine/common": "2.2.*" + "twig/twig": "1.8.*" }, "minimum-stability": "beta" } diff --git a/core/composer.lock b/core/composer.lock index 367a060..c861d34 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -1,41 +1,37 @@ { - "hash": "59ca4d3072dd16454bdbfb24795d55f9", + "hash": "ec77094fc475b57afb7a27f63983ead1", "packages": [ { - "package": "doctrine/common", - "version": "2.2.2" - }, - { "package": "symfony/class-loader", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "symfony/dependency-injection", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "symfony/event-dispatcher", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "symfony/http-foundation", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "symfony/http-kernel", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "symfony/routing", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "symfony/yaml", - "version": "v2.1.0-BETA2" + "version": "v2.1.0-BETA1" }, { "package": "twig/twig", - "version": "v1.9.0" + "version": "v1.8.3" } ], "packages-dev": null, diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 7b1313a..95adc95 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -3047,15 +3047,11 @@ function drupal_classloader() { 'Symfony\Component\HttpKernel' => DRUPAL_ROOT . '/core/vendor/symfony/http-kernel', 'Symfony\Component\Routing' => DRUPAL_ROOT . '/core/vendor/symfony/routing', 'Symfony\Component\Yaml' => DRUPAL_ROOT . '/core/vendor/symfony/yaml', - 'Doctrine\Common' => DRUPAL_ROOT . '/core/vendor/doctrine/common/lib', )); // Register PEAR-style vendor namespaces. $loader->registerPrefixes(array( // All Twig-borrowed code lives in /core/vendor/twig. 'Twig' => DRUPAL_ROOT . '/core/vendor/twig/twig/lib', - // All Symfony-borrowed code lives in /core/vendor/Symfony. - 'Symfony' => DRUPAL_ROOT . '/core/vendor', - 'Doctrine' => DRUPAL_ROOT . '/core/vendor', )); // Register the Drupal namespace for classes in core as a fallback. // This allows to register additional namespaces within the Drupal namespace diff --git a/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php b/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php deleted file mode 100644 index bb07069..0000000 --- a/core/lib/Drupal/Component/Plugin/Derivative/DerivativeInterface.php +++ /dev/null @@ -1,44 +0,0 @@ -decorated = $decorated; - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinition(). - */ - public function getDefinition($plugin_id) { - - list($base_plugin_id, $derivative_id) = $this->decodePluginId($plugin_id); - - $plugin_definition = $this->decorated->getDefinition($base_plugin_id); - if (isset($plugin_definition)) { - $derivative_fetcher = $this->getDerivativeFetcher($base_plugin_id, $plugin_definition); - if ($derivative_fetcher) { - $plugin_definition = $derivative_fetcher->getDerivativeDefinition($derivative_id, $plugin_definition); - } - } - - return $plugin_definition; - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions(). - */ - public function getDefinitions() { - $plugin_definitions = $this->decorated->getDefinitions(); - return $this->getDerivatives($plugin_definitions); - } - - /** - * Adds derivatives to a list of plugin definitions. - * - * This should be called by the class extending this in - * DiscoveryInterface::getDefinitions(). - */ - protected function getDerivatives(array $base_plugin_definitions) { - $plugin_definitions = array(); - foreach ($base_plugin_definitions as $base_plugin_id => $plugin_definition) { - $derivative_fetcher = $this->getDerivativeFetcher($base_plugin_id, $plugin_definition); - if ($derivative_fetcher) { - $derivative_definitions = $derivative_fetcher->getDerivativeDefinitions($plugin_definition); - foreach ($derivative_definitions as $derivative_id => $derivative_definition) { - $plugin_id = $this->encodePluginId($base_plugin_id, $derivative_id); - $plugin_definitions[$plugin_id] = $derivative_definition; - } - } - else { - $plugin_definitions[$base_plugin_id] = $plugin_definition; - } - } - - return $plugin_definitions; - } - - /** - * Decodes derivative id and plugin id from a string. - * - * @param string $plugin_id - * Plugin identifier that may point to a derivative plugin. - * - * @return array - * An array with the base plugin id as the first index and the derivative id - * as the second. If there is no derivative id it will be null. - */ - protected function decodePluginId($plugin_id) { - // Try and split the passed plugin definition into a plugin and a - // derivative id. We don't need to check for !== FALSE because a leading - // colon would break the derivative system and doesn't makes sense. - if (strpos($plugin_id, ':')) { - return explode(':', $plugin_id, 2); - } - - return array($plugin_id, NULL); - } - - /** - * Encodes plugin and derivative id's into a string. - * - * @param string $base_plugin_id - * The base plugin identifier. - * @param string $derivative_id - * The derivative identifier. - * - * @return string - * A uniquely encoded combination of the $base_plugin_id and $derivative_id. - */ - protected function encodePluginId($base_plugin_id, $derivative_id) { - if ($derivative_id) { - return "$base_plugin_id:$derivative_id"; - } - - // By returning the unmerged plugin_id, we are able to support derivative - // plugins that support fetching the base definitions. - return $base_plugin_id; - } - - /** - * Finds a Drupal\Component\Plugin\Discovery\DerivativeInterface. - * - * This Drupal\Component\Plugin\Discovery\DerivativeInterface can fetch - * derivatives for the plugin. - * - * @param string $base_plugin_id - * The base plugin id of the plugin. - * @param array $base_definition - * The base plugin definition to build derivatives. - * - * @return Drupal\Component\Plugin\Discovery\DerivativeInterface|null - * A DerivativeInterface or null if none exists for the plugin. - */ - protected function getDerivativeFetcher($base_plugin_id, array $base_definition) { - if (!isset($this->derivativeFetchers[$base_plugin_id])) { - $this->derivativeFetchers[$base_plugin_id] = FALSE; - if (isset($base_definition['derivative'])) { - $class = $base_definition['derivative']; - $this->derivativeFetchers[$base_plugin_id] = new $class($base_plugin_id); - } - } - return $this->derivativeFetchers[$base_plugin_id] ?: NULL; - } - - /** - * Passes through all unknown calls onto the decorated object. - */ - public function __call($method, $args) { - return call_user_func_array(array($this->decorated, $method), $args); - } -} diff --git a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php b/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php deleted file mode 100644 index dee79ea..0000000 --- a/core/lib/Drupal/Component/Plugin/Discovery/DiscoveryInterface.php +++ /dev/null @@ -1,35 +0,0 @@ -definitions[$base_plugin_id]) ? $this->definitions[$base_plugin_id] : NULL; - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DiscoveryInterface::getDefinitions(). - */ - public function getDefinitions() { - return $this->definitions; - } - - /** - * Sets a plugin definition. - */ - public function setDefinition($plugin, array $definition) { - $this->definitions[$plugin] = $definition; - } - - /** - * Deletes a plugin definition. - */ - public function deleteDefinition($plugin) { - unset($this->definitions[$plugin]); - } -} diff --git a/core/lib/Drupal/Component/Plugin/Exception/ExceptionInterface.php b/core/lib/Drupal/Component/Plugin/Exception/ExceptionInterface.php deleted file mode 100644 index 57fb25b..0000000 --- a/core/lib/Drupal/Component/Plugin/Exception/ExceptionInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -discovery = $discovery; - $this->classKey = $class_key; - } - - /** - * Implements Drupal\Component\Plugin\Factory\FactoryInterface::createInstance(). - */ - public function createInstance($plugin_id, array $configuration) { - $plugin_class = $this->getPluginClass($plugin_id); - return new $plugin_class($configuration, $plugin_id, $this->discovery); - } - - /** - * Finds the class relevant for a given plugin. - * - * @param array $plugin_id - * The id of a plugin. - * - * @return string - * The appropriate class name. - */ - protected function getPluginClass($plugin_id) { - if (empty($this->classKey)) { - throw new PluginException('The plugin manager did not specify a valid key for determining the plugin instance class.'); - } - - $plugin_definition = $this->discovery->getDefinition($plugin_id); - if (empty($plugin_definition[$this->classKey])) { - throw new PluginException('The plugin did not specify an instance class.'); - } - - $class = $plugin_definition[$this->classKey]; - - if (!class_exists($class)) { - throw new PluginException(sprintf('Plugin instance class "%s" does not exist.', $class)); - } - - return $class; - } -} diff --git a/core/lib/Drupal/Component/Plugin/Factory/FactoryInterface.php b/core/lib/Drupal/Component/Plugin/Factory/FactoryInterface.php deleted file mode 100644 index 7954745..0000000 --- a/core/lib/Drupal/Component/Plugin/Factory/FactoryInterface.php +++ /dev/null @@ -1,29 +0,0 @@ -getPluginClass($plugin_id); - - // Lets figure out of there's a constructor for this class and pull - // arguments from the $options array if so to populate it. - $reflector = new ReflectionClass($plugin_class); - if ($reflector->hasMethod('__construct')) { - $arguments = $this->getInstanceArguments($reflector, $plugin_id, $configuration); - $instance = $reflector->newInstanceArgs($arguments); - } - else { - $instance = new $plugin_class(); - } - - return $instance; - } - - /** - * Inspects the plugin class and build a list of arguments for the constructor. - * - * This is provided as a helper method so factories extending this class can - * replace this and insert their own reflection logic. - * - * @param ReflectionClass $reflector - * The reflector object being used to inspect the plugin class. - * @param string $plugin_id - * The identifier of the plugin implementation. - * @param array $configuration - * An array of configuration that may be passed to the instance. - * - * @return array - * An array of arguments to be passed to the constructor. - */ - protected function getInstanceArguments(ReflectionClass $reflector, $plugin_id, array $configuration) { - - $arguments = array(); - foreach ($reflector->getMethod('__construct')->getParameters() as $param) { - $param_name = $param->getName(); - $param_class = $param->getClass(); - - if ($param_name == 'plugin_id') { - $arguments[] = $plugin_id; - } - elseif ($param_name == 'configuration') { - $arguments[] = $configuration; - } - elseif ($param_class && $param_class->isInstance($this->discovery)) { - $arguments[] = $this->discovery; - } - elseif (isset($configuration[$param_name]) || array_key_exists($param_name, $configuration)) { - $arguments[] = $configuration[$param_name]; - } - elseif ($param->isDefaultValueAvailable()) { - $arguments[] = $param->getDefaultValue(); - } - else { - // Missing constructor argument. - // TODO - Do we throw an exception or just skip and let sub classes - // extend this. - } - } - return $arguments; - } -} diff --git a/core/lib/Drupal/Component/Plugin/Mapper/MapperInterface.php b/core/lib/Drupal/Component/Plugin/Mapper/MapperInterface.php deleted file mode 100644 index 03610e6..0000000 --- a/core/lib/Drupal/Component/Plugin/Mapper/MapperInterface.php +++ /dev/null @@ -1,33 +0,0 @@ -plugin_id = $plugin_id; - $this->discovery = $discovery; - $this->configuration = $configuration; - } - - /** - * Implements Drupal\Component\Plugin\PluginInterface::getPluginId(). - */ - public function getPluginId() { - return $this->plugin_id; - } - - /** - * Implements Drupal\Component\Plugin\PluginInterface::getDefinition(). - */ - public function getDefinition() { - return $this->discovery->getDefinition($this->plugin_id); - } - - // Note: Plugin configuration is optional so its left to the plugin type to - // require a getter as part of its interface. -} diff --git a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php b/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php deleted file mode 100644 index 9157d7c..0000000 --- a/core/lib/Drupal/Component/Plugin/PluginInspectionInterface.php +++ /dev/null @@ -1,33 +0,0 @@ -processDefinition() if - * additional processing of plugins is necessary or helpful for development - * purposes. - * - * @var array - */ - protected $defaults = array(); - - /** - * Implements Drupal\Component\Plugin\PluginManagerInterface::getDefinition(). - */ - public function getDefinition($plugin_id) { - $definition = $this->discovery->getDefinition($plugin_id); - if (isset($definition)) { - $this->processDefinition($definition, $plugin_id); - } - return $definition; - } - - /** - * Implements Drupal\Component\Plugin\PluginManagerInterface::getDefinitions(). - */ - public function getDefinitions() { - $definitions = $this->discovery->getDefinitions(); - foreach ($definitions as $plugin_id => &$definition) { - $this->processDefinition($definition, $plugin_id); - } - - return $definitions; - } - - /** - * Implements Drupal\Component\Plugin\PluginManagerInterface::createInstance(). - */ - public function createInstance($plugin_id, array $configuration = array()) { - return $this->factory->createInstance($plugin_id, $configuration); - } - - /** - * Implements Drupal\Component\Plugin\PluginManagerInterface::getInstance(). - */ - public function getInstance(array $options) { - return $this->mapper->getInstance($options); - } - - /** - * Performs extra processing on plugin definitions. - * - * By default we add defaults for the type to the definition. If a type has - * additional processing logic they can do that by replacing or extending the - * method. - */ - protected function processDefinition(&$definition, $plugin_id) { - $definition += $this->defaults; - } -} diff --git a/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php b/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php deleted file mode 100644 index a7d74a8..0000000 --- a/core/lib/Drupal/Component/Plugin/PluginManagerInterface.php +++ /dev/null @@ -1,31 +0,0 @@ - $value) { - if ($value instanceof Translation) { - $this->definition[$key] = $value->getTranslation(); - } - else { - $this->definition[$key] = $value; - } - } - } - - public function getDefinition() { - return $this->definition; - } -} diff --git a/core/lib/Drupal/Core/Annotation/Translation.php b/core/lib/Drupal/Core/Annotation/Translation.php deleted file mode 100644 index 44d5e8b..0000000 --- a/core/lib/Drupal/Core/Annotation/Translation.php +++ /dev/null @@ -1,25 +0,0 @@ - $values['context'], - ); - } - $this->translation = t($string, array(), $options); - } - - public function getTranslation() { - return $this->translation; - } -} diff --git a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php b/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php deleted file mode 100644 index 49a0d28..0000000 --- a/core/lib/Drupal/Core/Plugin/Discovery/CacheDecorator.php +++ /dev/null @@ -1,124 +0,0 @@ -decorated = $decorated; - $this->cacheKey = $cache_key; - $this->cacheBin = $cache_bin; - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition(). - */ - public function getDefinition($plugin_id) { - $definitions = $this->getCachedDefinitions(); - if (isset($definitions)) { - $definition = isset($definitions[$plugin_id]) ? $definitions[$plugin_id] : NULL; - } - else { - $definition = $this->decorated->getDefinition($plugin_id); - } - return $definition; - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions(). - */ - public function getDefinitions() { - $definitions = $this->getCachedDefinitions(); - if (!isset($definitions)) { - $definitions = $this->decorated->getDefinitions(); - $this->setCachedDefinitions($definitions); - } - return $definitions; - } - - /** - * Returns the cached plugin definitions of the decorated discovery class. - * - * @return mixed - * On success this will return an array of plugin definitions. On failure - * this should return NULL, indicating to other methods that this has not - * yet been defined. Success with no values should return as an empty array - * and would actually be returned by the getDefinitions() method. - */ - protected function getCachedDefinitions() { - if (!isset($this->definitions) && isset($this->cacheKey) && $cache = cache($this->cacheBin)->get($this->cacheKey)) { - $this->definitions = $cache->data; - } - return $this->definitions; - } - - /** - * Sets a cache of plugin definitions for the decorated discovery class. - * - * @param array $definitions - * List of definitions to store in cache. - */ - protected function setCachedDefinitions($definitions) { - if (isset($this->cacheKey)) { - cache($this->cacheBin)->set($this->cacheKey, $definitions); - } - $this->definitions = $definitions; - } - - /** - * Passes through all unknown calls onto the decorated object. - */ - public function __call($method, $args) { - return call_user_func_array(array($this->decorated, $method), $args); - } -} diff --git a/core/lib/Drupal/Core/Plugin/Discovery/DirectoryDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/DirectoryDiscovery.php deleted file mode 100644 index 4fc5f5f..0000000 --- a/core/lib/Drupal/Core/Plugin/Discovery/DirectoryDiscovery.php +++ /dev/null @@ -1,69 +0,0 @@ -owner = $owner; - $this->type = $type; - } - - /** - * Implements DerivativeAwareDiscovery::getBasePluginDefinition(). - */ - public function getDefinition($plugin_id) { - $plugins = $this->getDefinitions(); - return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : array(); - } - - /** - * Implements DerivativeAwareDiscovery::getBasePluginDefinitions(). - */ - public function getDefinitions() { - $definitions = array(); - $reader = new AnnotationReader(); - AnnotationRegistry::registerAutoloadNamespace('Drupal\Core\Annotation', array(DRUPAL_ROOT . '/core/lib')); - $namespaces = drupal_classloader()->getNamespaces(); - foreach ($namespaces as $ns => $namespace_dirs) { - $ns = str_replace('\\', DIRECTORY_SEPARATOR, $ns); - foreach ($namespace_dirs as $dir) { - $prefix = implode(DIRECTORY_SEPARATOR, array( - $ns, - 'Plugins', - $this->owner, - $this->type - )); - $dir .= DIRECTORY_SEPARATOR . $prefix; - if (file_exists($dir)) { - foreach (new DirectoryIterator($dir) as $fileinfo) { - if ($fileinfo->getExtension() == 'php') { - $reflectionClass = new ReflectionClass(str_replace(DIRECTORY_SEPARATOR, '\\', "$prefix/". $fileinfo->getBasename('.php'))); - if ($annotation = $reader->getClassAnnotation($reflectionClass, 'Drupal\Core\Annotation\Plugin')) { - $definition = $annotation->getDefinition(); - $definition['class'] = $reflectionClass->name; - $definitions[$definition['plugin_id']] = $definition; - } - } - } - } - } - } - return $definitions; - } -} - diff --git a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php deleted file mode 100644 index 3ff05f9..0000000 --- a/core/lib/Drupal/Core/Plugin/Discovery/HookDiscovery.php +++ /dev/null @@ -1,57 +0,0 @@ -hook = $hook; - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinition(). - */ - public function getDefinition($plugin_id) { - $plugins = $this->getDefinitions(); - return isset($plugins[$plugin_id]) ? $plugins[$plugin_id] : array(); - } - - /** - * Implements Drupal\Component\Plugin\Discovery\DicoveryInterface::getDefinitions(). - */ - public function getDefinitions() { - foreach (module_implements($this->hook) as $module) { - $function = $module . '_' . $this->hook; - foreach ($function() as $plugin_id => $definition) { - $definition['module'] = $module; - $definitions[$plugin_id] = $definition; - } - } - drupal_alter($this->hook, $definitions); - return $definitions; - } -} diff --git a/core/modules/aggregator/aggregator.admin.inc b/core/modules/aggregator/aggregator.admin.inc index 0ee5ee6..7759750 100644 --- a/core/modules/aggregator/aggregator.admin.inc +++ b/core/modules/aggregator/aggregator.admin.inc @@ -6,7 +6,6 @@ */ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -use Drupal\aggregator\Plugin\FetcherManager; /** * Page callback: Displays the aggregator administration page. @@ -443,11 +442,16 @@ function aggregator_admin_form($form, $form_state) { aggregator_sanitize_configuration(); // Get all available fetchers. - $fetcher_manager = new FetcherManager(); - $fetchers = array(); - foreach ($fetcher_manager->getDefinitions() as $id => $definition) { - $label = $definition['title'] . ' ' . $definition['description'] . ''; - $fetchers[$id] = $label; + $fetchers = module_implements('aggregator_fetch'); + foreach ($fetchers as $k => $module) { + if ($info = module_invoke($module, 'aggregator_fetch_info')) { + $label = $info['title'] . ' ' . $info['description'] . ''; + } + else { + $label = $module; + } + unset($fetchers[$k]); + $fetchers[$module] = $label; } // Get all available parsers. diff --git a/core/modules/aggregator/aggregator.api.php b/core/modules/aggregator/aggregator.api.php index 3d7f499..0f708eb 100644 --- a/core/modules/aggregator/aggregator.api.php +++ b/core/modules/aggregator/aggregator.api.php @@ -11,29 +11,58 @@ */ /** - * Specify the class, title, and short description of your fetcher plugins. + * Create an alternative fetcher for aggregator.module. + * + * A fetcher downloads feed data to a Drupal site. The fetcher is called at the + * first of the three aggregation stages: first, data is downloaded by the + * active fetcher; second, it is converted to a common format by the active + * parser; and finally, it is passed to all active processors, which manipulate + * or store the data. + * + * Modules that define this hook can be set as active fetcher on + * admin/config/services/aggregator. Only one fetcher can be active at a time. + * + * @param $feed + * A feed object representing the resource to be downloaded. $feed->url + * contains the link to the feed. Download the data at the URL and expose it + * to other modules by attaching it to $feed->source_string. + * + * @return + * TRUE if fetching was successful, FALSE otherwise. + * + * @see hook_aggregator_fetch_info() + * @see hook_aggregator_parse() + * @see hook_aggregator_process() + * + * @ingroup aggregator + */ +function hook_aggregator_fetch($feed) { + $feed->source_string = mymodule_fetch($feed->url); +} + +/** + * Specify the title and short description of your fetcher. * * The title and the description provided are shown on - * admin/config/services/aggregator among other places. + * admin/config/services/aggregator among other places. Use as title the human + * readable name of the fetcher and as description a brief (40 to 80 characters) + * explanation of the fetcher's functionality. + * + * This hook is only called if your module implements hook_aggregator_fetch(). + * If this hook is not implemented aggregator will use your module's file name + * as title and there will be no description. * * @return - * An associative array whose keys define the fetcher id and whose values - * contain the fetcher definitions. Each fetcher definition is itself an - * associative array, with the following key-value pairs: - * - class: (required) The PHP class containing the fetcher implementation. - * - title: (required) A human readable name of the fetcher. - * - description: (required) A brief (40 to 80 characters) explanation of the - * fetcher's functionality. + * An associative array defining a title and a description string. + * + * @see hook_aggregator_fetch() * * @ingroup aggregator */ function hook_aggregator_fetch_info() { return array( - 'aggregator' => array( - 'class' => 'Drupal\aggregator\Plugin\aggregator\fetcher\DefaultFetcher', - 'title' => t('Default fetcher'), - 'description' => t('Downloads data from a URL using Drupal\'s HTTP request handler.'), - ), + 'title' => t('Default fetcher'), + 'description' => t('Default fetcher for resources available by URL.'), ); } diff --git a/core/modules/aggregator/aggregator.fetcher.inc b/core/modules/aggregator/aggregator.fetcher.inc new file mode 100644 index 0000000..831ea78 --- /dev/null +++ b/core/modules/aggregator/aggregator.fetcher.inc @@ -0,0 +1,61 @@ + t('Default fetcher'), + 'description' => t('Downloads data from a URL using Drupal\'s HTTP request handler.'), + ); +} + +/** + * Implements hook_aggregator_fetch(). + */ +function aggregator_aggregator_fetch($feed) { + $feed->source_string = FALSE; + + // Generate conditional GET headers. + $headers = array(); + if ($feed->etag) { + $headers['If-None-Match'] = $feed->etag; + } + if ($feed->modified) { + $headers['If-Modified-Since'] = gmdate(DATE_RFC1123, $feed->modified); + } + + // Request feed. + $result = drupal_http_request($feed->url, array('headers' => $headers)); + + // Process HTTP response code. + switch ($result->code) { + case 304: + break; + case 301: + $feed->url = $result->redirect_url; + // Do not break here. + case 200: + case 302: + case 307: + if (!isset($result->data)) { + $result->data = ''; + } + if (!isset($result->headers)) { + $result->headers = array(); + } + $feed->source_string = $result->data; + $feed->http_headers = $result->headers; + break; + default: + watchdog('aggregator', 'The feed from %site seems to be broken due to "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error), WATCHDOG_WARNING); + drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error))); + } + + return $feed->source_string === FALSE ? FALSE : TRUE; +} diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index 2d37b73..0626f72 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -5,8 +5,6 @@ * Used to aggregate syndicated content (RSS, RDF, and Atom). */ -use Drupal\aggregator\Plugin\FetcherManager; - /** * Denotes that a feed's items should never expire. */ @@ -596,18 +594,19 @@ function aggregator_remove($feed) { * An array containing the fetcher, parser, and processors. */ function _aggregator_get_variables() { + // Fetch the feed. $fetcher = variable_get('aggregator_fetcher', 'aggregator'); - + if ($fetcher == 'aggregator') { + include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.fetcher.inc'; + } $parser = variable_get('aggregator_parser', 'aggregator'); if ($parser == 'aggregator') { include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.parser.inc'; } - $processors = variable_get('aggregator_processors', array('aggregator')); if (in_array('aggregator', $processors)) { include_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'aggregator') . '/aggregator.processor.inc'; } - return array($fetcher, $parser, $processors); } @@ -621,16 +620,9 @@ function aggregator_refresh($feed) { // Store feed URL to track changes. $feed_url = $feed->url; - list($fetcher, $parser, $processors) = _aggregator_get_variables(); - // Fetch the feed. - $fetcher_manager = new FetcherManager(); - try { - $success = $fetcher_manager->createInstance($fetcher)->fetch($feed); - } - catch (PluginException $e) { - $success = FALSE; - } + list($fetcher, $parser, $processors) = _aggregator_get_variables(); + $success = module_invoke($fetcher, 'aggregator_fetch', $feed); // We store the hash of feed data in the database. When refreshing a // feed we compare stored hash and new hash calculated from downloaded @@ -797,19 +789,6 @@ function _aggregator_items($count) { } /** - * Implements hook_aggregator_fetch_info(). - */ -function aggregator_aggregator_fetch_info() { - return array( - 'aggregator' => array( - 'class' => 'Drupal\aggregator\Plugin\aggregator\fetcher\DefaultFetcher', - 'title' => t('Default fetcher'), - 'description' => t('Downloads data from a URL using Drupal\'s HTTP request handler.'), - ), - ); -} - -/** * Implements hook_preprocess_HOOK() for block.tpl.php. */ function aggregator_preprocess_block(&$variables) { diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php deleted file mode 100644 index 39fc19d..0000000 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php +++ /dev/null @@ -1,33 +0,0 @@ -url - * contains the link to the feed. Download the data at the URL and expose it - * to other modules by attaching it to $feed->source_string. - * - * @return - * TRUE if fetching was successful, FALSE otherwise. - */ - public function fetch(&$feed); - -} diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherManager.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherManager.php deleted file mode 100644 index ae24934..0000000 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherManager.php +++ /dev/null @@ -1,23 +0,0 @@ -discovery = new HookDiscovery('aggregator_fetch_info'); - $this->factory = new DefaultFactory($this->discovery); - } -} diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php deleted file mode 100644 index e4b663b..0000000 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php +++ /dev/null @@ -1,63 +0,0 @@ -source_string = FALSE; - - // Generate conditional GET headers. - $headers = array(); - if ($feed->etag) { - $headers['If-None-Match'] = $feed->etag; - } - if ($feed->modified) { - $headers['If-Modified-Since'] = gmdate(DATE_RFC1123, $feed->modified); - } - - // Request feed. - $result = drupal_http_request($feed->url, array('headers' => $headers)); - - // Process HTTP response code. - switch ($result->code) { - case 304: - break; - case 301: - $feed->url = $result->redirect_url; - // Do not break here. - case 200: - case 302: - case 307: - if (!isset($result->data)) { - $result->data = ''; - } - if (!isset($result->headers)) { - $result->headers = array(); - } - $feed->source_string = $result->data; - $feed->http_headers = $result->headers; - break; - default: - watchdog('aggregator', 'The feed from %site seems to be broken due to "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error), WATCHDOG_WARNING); - drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', array('%site' => $feed->title, '%error' => $result->code . ' ' . $result->error))); - } - - return !($feed->source_string === FALSE); - } -} diff --git a/core/modules/block/lib/Drupal/block/Plugins/owner/type/test.php b/core/modules/block/lib/Drupal/block/Plugins/owner/type/test.php deleted file mode 100644 index 992c5d0..0000000 --- a/core/modules/block/lib/Drupal/block/Plugins/owner/type/test.php +++ /dev/null @@ -1,11 +0,0 @@ - 'Derivative Discovery', - 'description' => 'Tests the the plugin system derivative integration.', - 'group' => 'Plugin API', - ); - } - - public function setUp() { - parent::setUp(); - - // Real modules implementing plugin types may expose a module-specific API - // for retrieving each type's plugin manager, or make them available in - // Drupal's dependency injection container, but for unit testing, we get - // the manager directly. - $this->mockBlockManager = new MockBlockManager(); - } - - /** - * Tests getDefinitions() and getDefinition() with a derivativeDecorator. - */ - function testDerivativeDecorator() { - - // @see MockBlockManager::_construct(). - $expected = array( - 'user_login' => array( - 'label' => 'User login', - 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', - ), - 'menu:main_menu' => array( - 'label' => 'Main menu', - 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', - ), - 'menu:navigation' => array( - 'label' => 'Navigation', - 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockMenuBlock', - ), - 'layout' => array( - 'label' => 'Layout', - 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlock', - ), - 'layout:foo' => array( - 'label' => 'Layout Foo', - 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockLayoutBlock', - ), - ); - - // Ensure that getDefinitions() returns the expected definitions. - $this->assertIdentical($this->mockBlockManager->getDefinitions(), $expected); - - // Ensure that getDefinition() returns the expected definition. - foreach ($expected as $id => $definition) { - $this->assertIdentical($this->mockBlockManager->getDefinition($id), $definition); - } - - // Ensure that NULL is returned as the definition of a non-existing base - // plugin, a non-existing derivative plugin, or a base plugin that may not - // be used without deriving. - $this->assertIdentical($this->mockBlockManager->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing base plugin.'); - $this->assertIdentical($this->mockBlockManager->getDefinition('menu:non_existing'), NULL, 'NULL returned as the definition of a non-existing derivative plugin.'); - $this->assertIdentical($this->mockBlockManager->getDefinition('menu'), NULL, 'NULL returned as the definition of a base plugin that may not be used without deriving.'); - } -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/DiscoveryPluginTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/DiscoveryPluginTest.php deleted file mode 100644 index d935d04..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Plugin/DiscoveryPluginTest.php +++ /dev/null @@ -1,60 +0,0 @@ - 'Discovery API', - 'description' => 'Tests the the plugin system API.', - 'group' => 'Plugin API', - ); - } - - public function setUp() { - parent::setUp(); - - // Real modules implementing plugin types may expose a module-specific API - // for retrieving each type's plugin manager, or make them available in - // Drupal's dependency injection container, but for unit testing, we get - // the manager directly. - $this->testPluginManager = new TestPluginManager(); - } - - /** - * Tests getDefinitions() and getDefinition(). - */ - function testDiscoveryInterface() { - - // @see TestPluginManager::_construct(). - $expected = array( - 'user_login' => array( - 'label' => 'User login', - 'class' => 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', - ), - ); - - // Ensure that getDefinitions() returns the expected definitions. - $this->assertIdentical($this->testPluginManager->getDefinitions(), $expected); - - // Ensure that getDefinition() returns the expected definition. - foreach ($expected as $id => $definition) { - $this->assertIdentical($this->testPluginManager->getDefinition($id), $definition); - } - - // Ensure that NULL is returned as the definition of a non-existing plugin. - $this->assertIdentical($this->testPluginManager->getDefinition('non_existing'), NULL, 'NULL returned as the definition of a non-existing base plugin.'); - } -} diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/FactoryPluginTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/FactoryPluginTest.php deleted file mode 100644 index 0701d4b..0000000 --- a/core/modules/system/lib/Drupal/system/Tests/Plugin/FactoryPluginTest.php +++ /dev/null @@ -1,106 +0,0 @@ - 'Factory Tests', - 'description' => 'Test the base plugin factories.', - 'group' => 'Plugin API', - ); - } - - public function setUp() { - parent::setUp(); - - // Real modules implementing plugin types may expose a module-specific API - // for retrieving each type's plugin manager, or make them available in - // Drupal's dependency injection container, but for unit testing, we get - // the manager directly. - - // A very basic mock plugin manager. - $this->testPluginManager = new TestPluginManager(); - - // A slightly more advanced plugin manager mocking a block system with - // derivatives. - $this->mockBlockManager = new MockBlockManager(); - } - - /** - * Test that DefaultFactory can create a plugin instance. - */ - function testDefaultFactory() { - // Ensure a non-derivative plugin can be instantiated. - $plugin = $this->testPluginManager->createInstance('user_login', array('title' => 'Please enter your login name and password')); - $this->assertIdentical(get_class($plugin), 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', 'Correct plugin class instantiated with default factory.'); - $this->assertIdentical($plugin->getTitle(), 'Please enter your login name and password', 'Plugin instance correctly configured.'); - - // Ensure that attempting to instantiate non-existing plugins throws a - // PluginException. - try { - $this->testPluginManager->createInstance('non_existing'); - $this->fail('Drupal\Component\Plugin\Exception\ExceptionInterface expected'); - } - catch (ExceptionInterface $e) { - $this->pass('Drupal\Component\Plugin\Exception\ExceptionInterface expected and caught.'); - } - catch (Exception $e) { - $this->fail('Drupal\Component\Plugin\Exception\ExceptionInterface expected, but ' . get_class($e) . ' was thrown.'); - } - } - - /** - * Test that the Reflection factory can create a plugin instance. - * - * The mock plugin classes use different values for their constructors - * allowing us to test the reflection capabilities as well. - * - * We use derivative classes here because the block test type has the - * reflection factory and it provides some additional variety in plugin - * object creation. - */ - function testReflectionFactory() { - // Ensure a non-derivative plugin can be instantiated. - $plugin = $this->mockBlockManager->createInstance('user_login', array('title' => 'Please enter your login name and password')); - $this->assertIdentical(get_class($plugin), 'Drupal\plugin_test\Plugin\plugin_test\mock_block\MockUserLoginBlock', 'Correct plugin class instantiated.'); - $this->assertIdentical($plugin->getTitle(), 'Please enter your login name and password', 'Plugin instance correctly configured.'); - - // Ensure a derivative plugin can be instantiated. - $plugin = $this->mockBlockManager->createInstance('menu:main_menu', array('depth' => 2)); - $this->assertIdentical($plugin->getContent(), '
ReflectionClass
object.
- * @return array A list with use statements in the form (Alias => FQN).
- */
- public function parseClass(\ReflectionClass $class)
- {
- if (false === $filename = $class->getFilename()) {
- return array();
- }
-
- $content = $this->getFileContent($filename, $class->getStartLine());
- $namespace = str_replace('\\', '\\\\', $class->getNamespaceName());
- $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
- $this->tokens = token_get_all('numTokens = count($this->tokens);
- $this->pointer = 0;
-
- $statements = $this->parseUseStatements($class->getNamespaceName());
-
- return $statements;
- }
-
- /**
- * Get the content of the file right up to the given line number.
- *
- * @param string $filename The name of the file to load.
- * @param int $lineNumber The number of lines to read from file.
- * @return string The content of the file.
- */
- private function getFileContent($filename, $lineNumber)
- {
- $content = '';
- $lineCnt = 0;
- $file = new SplFileObject($filename);
- while(!$file->eof()) {
- if ($lineCnt++ == $lineNumber) {
- break;
- }
-
- $content .= $file->fgets();
- }
-
- return $content;
- }
-
- /**
- * Gets the next non whitespace and non comment token.
- *
- * @return array The token if exists, null otherwise.
- */
- private function next()
- {
- for ($i = $this->pointer; $i < $this->numTokens; $i++) {
- $this->pointer++;
- if ($this->tokens[$i][0] === T_WHITESPACE ||
- $this->tokens[$i][0] === T_COMMENT ||
- $this->tokens[$i][0] === T_DOC_COMMENT) {
-
- continue;
- }
-
- return $this->tokens[$i];
- }
-
- return null;
- }
-
- /**
- * Get all use statements.
- *
- * @param string $namespaceName The namespace name of the reflected class.
- * @return array A list with all found use statements.
- */
- private function parseUseStatements($namespaceName)
- {
- $statements = array();
- while (($token = $this->next())) {
- if ($token[0] === T_USE) {
- $statements = array_merge($statements, $this->parseUseStatement());
- continue;
- } else if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) {
- continue;
- }
-
- // Get fresh array for new namespace. This is to prevent the parser to collect the use statements
- // for a previous namespace with the same name. This is the case if a namespace is defined twice
- // or if a namespace with the same name is commented out.
- $statements = array();
- }
-
- return $statements;
- }
-
- /**
- * Get the namespace name.
- *
- * @return string The found namespace name.
- */
- private function parseNamespace()
- {
- $namespace = '';
- while (($token = $this->next())){
- if ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR) {
- $namespace .= $token[1];
- } else {
- break;
- }
- }
-
- return $namespace;
- }
-
- /**
- * Parse a single use statement.
- *
- * @return array A list with all found class names for a use statement.
- */
- private function parseUseStatement()
- {
- $class = '';
- $alias = '';
- $statements = array();
- $explicitAlias = false;
- while (($token = $this->next())) {
- $isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR;
- if (!$explicitAlias && $isNameToken) {
- $class .= $token[1];
- $alias = $token[1];
- } else if ($explicitAlias && $isNameToken) {
- $alias .= $token[1];
- } else if ($token[0] === T_AS) {
- $explicitAlias = true;
- $alias = '';
- } else if ($token === ',') {
- $statements[strtolower($alias)] = $class;
- $class = '';
- $alias = '';
- $explicitAlias = false;
- } else if ($token === ';') {
- $statements[strtolower($alias)] = $class;
- break;
- } else {
- break;
- }
- }
-
- return $statements;
- }
-}
\ No newline at end of file
diff --git a/core/vendor/Doctrine/Common/lib/Doctrine/Common/Annotations/Reader.php b/core/vendor/Doctrine/Common/lib/Doctrine/Common/Annotations/Reader.php
deleted file mode 100644
index 8e85d39..0000000
--- a/core/vendor/Doctrine/Common/lib/Doctrine/Common/Annotations/Reader.php
+++ /dev/null
@@ -1,35 +0,0 @@
-.
- */
-
-namespace Doctrine\Common\Annotations;
-
-/**
- * Interface for annotation readers.
- *
- * @author Johannes M. Schmitt include_path
.
- *
- * @author Roman Borschel - Welcome to my awesome homepage. + Welcome on my awesome homepage.
{% endblock %} @@ -371,24 +371,16 @@ Twig supports both, automatic escaping is enabled by default. Working with Manual Escaping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If manual escaping is enabled, it is **your** responsibility to escape -variables if needed. What to escape? Any variable you don't trust. - -Escaping works by piping the variable through the -:doc:`escape- * {{ post.published_at|modify("-1day")|date("m/d/Y") }} - *- * - * @param Twig_Environment $env A Twig_Environment instance - * @param DateTime|string $date A date - * @param string $modifier A modifier string - * - * @return DateTime A new date object - */ -function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) -{ - if ($date instanceof DateTime) { - $date = clone $date; - } else { - $date = twig_date_converter($env, $date); - } - - $date->modify($modifier); - - return $date; -} - -/** * Converts an input to a DateTime instance. * *
@@ -480,7 +453,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu * * @param Twig_Environment $env A Twig_Environment instance * @param mixed $number A float/int/string of the number to format - * @param integer $decimal The number of decimal points to display. + * @param int $decimal The number of decimal points to display. * @param string $decimalPoint The character(s) to use for the decimal point. * @param string $thousandSep The character(s) to use for the thousands separator. * @@ -793,46 +766,10 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $string = twig_convert_encoding($string, 'UTF-8', $charset); } - if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { - throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); - } - - $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string); - - if ('UTF-8' != $charset) { - $string = twig_convert_encoding($string, $charset, 'UTF-8'); - } - - return $string; - - case 'css': - if ('UTF-8' != $charset) { - $string = twig_convert_encoding($string, 'UTF-8', $charset); - } - - if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { + if (null === $string = preg_replace_callback('#[^\p{L}\p{N} ]#u', '_twig_escape_js_callback', $string)) { throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); } - $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string); - - if ('UTF-8' != $charset) { - $string = twig_convert_encoding($string, $charset, 'UTF-8'); - } - - return $string; - - case 'html_attr': - if ('UTF-8' != $charset) { - $string = twig_convert_encoding($string, 'UTF-8', $charset); - } - - if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) { - throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.'); - } - - $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string); - if ('UTF-8' != $charset) { $string = twig_convert_encoding($string, $charset, 'UTF-8'); } @@ -871,15 +808,8 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', return twig_convert_encoding($string, $charset, 'UTF-8'); - case 'url': - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - return str_replace('%7E', '~', rawurlencode($string)); - } - - return rawurlencode($string); - default: - throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy)); + throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js).', $strategy)); } } @@ -920,87 +850,13 @@ function _twig_escape_js_callback($matches) // \xHH if (!isset($char[1])) { - return '\\x'.strtoupper(substr('00'.bin2hex($char), -2)); + return '\\x'.substr('00'.bin2hex($char), -2); } // \uHHHH $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); - return '\\u'.strtoupper(substr('0000'.bin2hex($char), -4)); -} - -function _twig_escape_css_callback($matches) -{ - $char = $matches[0]; - - // \xHH - if (!isset($char[1])) { - $hex = ltrim(strtoupper(bin2hex($char)), '0'); - if (0 === strlen($hex)) { - $hex = '0'; - } - return '\\'.$hex.' '; - } - - // \uHHHH - $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8'); - - return '\\'.ltrim(strtoupper(bin2hex($char)), '0').' '; -} - -/** - * This function is adapted from code coming from Zend Framework. - * - * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) - * @license http://framework.zend.com/license/new-bsd New BSD License - */ -function _twig_escape_html_attr_callback($matches) -{ - /* - * While HTML supports far more named entities, the lowest common denominator - * has become HTML5's XML Serialisation which is restricted to the those named - * entities that XML supports. Using HTML entities would result in this error: - * XML Parsing Error: undefined entity - */ - static $entityMap = array( - 34 => 'quot', /* quotation mark */ - 38 => 'amp', /* ampersand */ - 60 => 'lt', /* less-than sign */ - 62 => 'gt', /* greater-than sign */ - ); - - $chr = $matches[0]; - $ord = ord($chr); - - /** - * The following replaces characters undefined in HTML with the - * hex entity for the Unicode replacement character. - */ - if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") || ($ord >= 0x7f && $ord <= 0x9f)) { - return '�'; - } - - /** - * Check if the current character to escape has a name entity we should - * replace it with while grabbing the hex value of the character. - */ - if (strlen($chr) == 1) { - $hex = strtoupper(substr('00'.bin2hex($chr), -2)); - } else { - $chr = twig_convert_encoding($chr, 'UTF-16BE', 'UTF-8'); - $hex = strtoupper(substr('0000'.bin2hex($chr), -4)); - } - - $int = hexdec($hex); - if (array_key_exists($int, $entityMap)) { - return sprintf('&%s;', $entityMap[$int]); - } - - /** - * Per OWASP recommendations, we'll use hex entities for any other - * characters where a named entity does not exist. - */ - return sprintf('%s;', $hex); + return '\\u'.substr('0000'.bin2hex($char), -4); } // add multibyte extensions if possible diff --git a/core/vendor/twig/twig/lib/Twig/Loader/String.php b/core/vendor/twig/twig/lib/Twig/Loader/String.php index a103bce..bc792b1 100644 --- a/core/vendor/twig/twig/lib/Twig/Loader/String.php +++ b/core/vendor/twig/twig/lib/Twig/Loader/String.php @@ -12,10 +12,6 @@ /** * Loads a template from a string. * - * This loader should only be used for unit testing as it has many limitations - * (for instance, the include or extends tag does not make any sense for a string - * loader). - * * When using this loader with a cache mechanism, you should know that a new cache * key is generated each time a template content "changes" (the cache key being the * source code of the template). If you don't want to see your cache grows out of diff --git a/core/vendor/twig/twig/lib/Twig/Parser.php b/core/vendor/twig/twig/lib/Twig/Parser.php index 66f5d2a..8c578fd 100644 --- a/core/vendor/twig/twig/lib/Twig/Parser.php +++ b/core/vendor/twig/twig/lib/Twig/Parser.php @@ -30,6 +30,7 @@ class Twig_Parser implements Twig_ParserInterface protected $env; protected $reservedMacroNames; protected $importedFunctions; + protected $tmpVarCount; protected $traits; protected $embeddedTemplates = array(); @@ -50,7 +51,7 @@ class Twig_Parser implements Twig_ParserInterface public function getVarName() { - return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false)); + return sprintf('__internal_%s_%d', substr($this->env->getTemplateClass($this->stream->getFilename()), strlen($this->env->getTemplateClassPrefix())), ++$this->tmpVarCount); } /** @@ -67,6 +68,8 @@ class Twig_Parser implements Twig_ParserInterface unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']); $this->stack[] = $vars; + $this->tmpVarCount = 0; + // tag handlers if (null === $this->handlers) { $this->handlers = $this->env->getTokenParsers(); @@ -272,7 +275,7 @@ class Twig_Parser implements Twig_ParserInterface public function embedTemplate(Twig_Node_Module $template) { - $template->setIndex(mt_rand()); + $template->setIndex(count($this->embeddedTemplates) + 1); $this->embeddedTemplates[] = $template; } diff --git a/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php b/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php index 76731ea..bb31690 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/EnvironmentTest.php @@ -25,7 +25,7 @@ class Twig_Tests_EnvironmentTest extends PHPUnit_Framework_TestCase )); $this->assertEquals('foo<br/ > foo<br/ >', $twig->render('html', array('foo' => 'foo
'))); - $this->assertEquals('foo\x3Cbr\x2F\x20\x3E foo\x3Cbr\x2F\x20\x3E', $twig->render('js', array('bar' => 'foo
'))); + $this->assertEquals('foo\x3cbr\x2f \x3e foo\x3cbr\x2f \x3e', $twig->render('js', array('bar' => 'foo
'))); } public function escapingStrategyCallback($filename) diff --git a/core/vendor/twig/twig/test/Twig/Tests/ErrorTest.php b/core/vendor/twig/twig/test/Twig/Tests/ErrorTest.php index 9d20c4d..d0e48be 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/ErrorTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/ErrorTest.php @@ -78,6 +78,7 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); $template = $twig->loadTemplate('index'); + try { $template->render(array()); @@ -87,43 +88,6 @@ class Twig_Tests_ErrorTest extends PHPUnit_Framework_TestCase $this->assertEquals(3, $e->getTemplateLine()); $this->assertEquals('index', $e->getTemplateFile()); } - - try { - $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo())); - - $this->fail(); - } catch (Twig_Error_Runtime $e) { - $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index" at line 3.', $e->getMessage()); - $this->assertEquals(3, $e->getTemplateLine()); - $this->assertEquals('index', $e->getTemplateFile()); - } - } - - public function testTwigExceptionAddsFileAndLineWhenMissingWithInheritanceOnDisk() - { - $loader = new Twig_Loader_Filesystem(dirname(__FILE__).'/Fixtures/errors'); - $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); - - $template = $twig->loadTemplate('index.html'); - try { - $template->render(array()); - - $this->fail(); - } catch (Twig_Error_Runtime $e) { - $this->assertEquals('Variable "foo" does not exist in "index.html" at line 3', $e->getMessage()); - $this->assertEquals(3, $e->getTemplateLine()); - $this->assertEquals('index.html', $e->getTemplateFile()); - } - - try { - $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo())); - - $this->fail(); - } catch (Twig_Error_Runtime $e) { - $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage()); - $this->assertEquals(3, $e->getTemplateLine()); - $this->assertEquals('index.html', $e->getTemplateFile()); - } } } diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html deleted file mode 100644 index cb0dbe4..0000000 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/base.html +++ /dev/null @@ -1 +0,0 @@ -{% block content %}{% endblock %} diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html deleted file mode 100644 index df57c82..0000000 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/errors/index.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'base.html' %} -{% block content %} - {{ foo.bar }} -{% endblock %} -{% block foo %} - {{ foo.bar }} -{% endblock %} diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test deleted file mode 100644 index 53d3a69..0000000 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/date_modify.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"date_modify" filter ---TEMPLATE-- -{{ date1|date_modify('-1day')|date('Y-m-d H:i:s') }} -{{ date2|date_modify('-1day')|date('Y-m-d H:i:s') }} ---DATA-- -date_default_timezone_set('UTC'); -return array( - 'date1' => '2010-10-04 13:45', - 'date2' => new DateTime('2010-10-04 13:45'), -) ---EXPECT-- -2010-10-03 13:45:00 -2010-10-03 13:45:00 diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test index 85a9b71..3690e71 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/filters/force_escape.test @@ -14,5 +14,5 @@ return array() --EXPECT-- foo<br /> -\x20\x20\x20\x20foo\x3Cbr\x20\x2F\x3E\x0A + foo\x3cbr \x2f\x3e\x0a foo
diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test index ce7ea78..864655c 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test @@ -80,4 +80,4 @@ unsafe_br()|escape autoescape js safe_br -\x3Cbr\x20\x2F\x3E +\x3cbr \x2f\x3e diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test index cf8ccee..101d5af 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test @@ -11,7 +11,7 @@ --DATA-- return array('var' => '
"') --EXPECT-- -\x3Cbr\x20\x2F\x3E\x22 +\x3cbr \x2f\x3e\x22 <br />" -\x3Cbr\x20\x2F\x3E\x22 +\x3cbr \x2f\x3e\x22 <br />" diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test index 4f41520..10fd63f 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test +++ b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test @@ -44,15 +44,15 @@ return array('msg' => "<>\n'\"") 1. autoescape 'html' |escape('js') - + 2. autoescape 'html' |escape('js') - + 3. autoescape 'js' |escape('js') - + 4. no escape @@ -61,9 +61,9 @@ return array('msg' => "<>\n'\"") 5. |escape('js')|escape('html') - + 6. autoescape 'html' |escape('js')|escape('html') - + diff --git a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test b/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test deleted file mode 100644 index 81563dc..0000000 --- a/core/vendor/twig/twig/test/Twig/Tests/Fixtures/tags/embed/nested.test +++ /dev/null @@ -1,42 +0,0 @@ ---TEST-- -"embed" tag ---TEMPLATE-- -{% embed "foo.twig" %} - {% block c1 %} - {{ parent() }} - {% embed "foo.twig" %} - {% block c1 %} - {{ parent() }} - block1extended - {% endblock %} - {% endembed %} - - {% endblock %} -{% endembed %} ---TEMPLATE(foo.twig)-- -A -{% block c1 %} - block1 -{% endblock %} -B -{% block c2 %} - block2 -{% endblock %} -C ---DATA-- -return array() ---EXPECT-- -A - block1 - - -A - block1 - - block1extended - B - block2 -C - B - block2 -C diff --git a/core/vendor/twig/twig/test/Twig/Tests/ParserTest.php b/core/vendor/twig/twig/test/Twig/Tests/ParserTest.php index 1e773a6..76f257a 100644 --- a/core/vendor/twig/twig/test/Twig/Tests/ParserTest.php +++ b/core/vendor/twig/twig/test/Twig/Tests/ParserTest.php @@ -115,26 +115,6 @@ class Twig_Tests_ParserTest extends PHPUnit_Framework_TestCase $this->assertEquals(null, $parser->getParent()); } - // The getVarName() must not depend on the template loaders, - // If this test does not throw any exception, that's good. - // see https://github.com/symfony/symfony/issues/4218 - public function testGetVarName() - { - $twig = new Twig_Environment(null, array( - 'autoescape' => false, - 'optimizations' => 0, - )); - - $twig->parse($twig->tokenize(<<''', - '"' => '"', - '<' => '<', - '>' => '>', - '&' => '&' - ); - - protected $htmlAttrSpecialChars = array( - '\'' => ''', - '"' => '"', - '<' => '<', - '>' => '>', - '&' => '&', - /* Characters beyond ASCII value 255 to unicode escape */ - 'Ā' => 'Ā', - /* Immune chars excluded */ - ',' => ',', - '.' => '.', - '-' => '-', - '_' => '_', - /* Basic alnums exluded */ - 'a' => 'a', - 'A' => 'A', - 'z' => 'z', - 'Z' => 'Z', - '0' => '0', - '9' => '9', - /* Basic control characters and null */ - "\r" => ' ', - "\n" => ' ', - "\t" => ' ', - "\0" => '�', // should use Unicode replacement char - /* Encode chars as named entities where possible */ - '<' => '<', - '>' => '>', - '&' => '&', - '"' => '"', - /* Encode spaces for quoteless attribute protection */ - ' ' => ' ', - ); - - protected $jsSpecialChars = array( - /* HTML special chars - escape without exception to hex */ - '<' => '\\x3C', - '>' => '\\x3E', - '\'' => '\\x27', - '"' => '\\x22', - '&' => '\\x26', - /* Characters beyond ASCII value 255 to unicode escape */ - 'Ā' => '\\u0100', - /* Immune chars excluded */ - ',' => ',', - '.' => '.', - '_' => '_', - /* Basic alnums exluded */ - 'a' => 'a', - 'A' => 'A', - 'z' => 'z', - 'Z' => 'Z', - '0' => '0', - '9' => '9', - /* Basic control characters and null */ - "\r" => '\\x0D', - "\n" => '\\x0A', - "\t" => '\\x09', - "\0" => '\\x00', - /* Encode spaces for quoteless attribute protection */ - ' ' => '\\x20', - ); - - protected $urlSpecialChars = array( - /* HTML special chars - escape without exception to percent encoding */ - '<' => '%3C', - '>' => '%3E', - '\'' => '%27', - '"' => '%22', - '&' => '%26', - /* Characters beyond ASCII value 255 to hex sequence */ - 'Ā' => '%C4%80', - /* Punctuation and unreserved check */ - ',' => '%2C', - '.' => '.', - '_' => '_', - '-' => '-', - ':' => '%3A', - ';' => '%3B', - '!' => '%21', - /* Basic alnums excluded */ - 'a' => 'a', - 'A' => 'A', - 'z' => 'z', - 'Z' => 'Z', - '0' => '0', - '9' => '9', - /* Basic control characters and null */ - "\r" => '%0D', - "\n" => '%0A', - "\t" => '%09', - "\0" => '%00', - /* PHP quirks from the past */ - ' ' => '%20', - '~' => '~', - '+' => '%2B', - ); - - protected $cssSpecialChars = array( - /* HTML special chars - escape without exception to hex */ - '<' => '\\3C ', - '>' => '\\3E ', - '\'' => '\\27 ', - '"' => '\\22 ', - '&' => '\\26 ', - /* Characters beyond ASCII value 255 to unicode escape */ - 'Ā' => '\\100 ', - /* Immune chars excluded */ - ',' => '\\2C ', - '.' => '\\2E ', - '_' => '\\5F ', - /* Basic alnums exluded */ - 'a' => 'a', - 'A' => 'A', - 'z' => 'z', - 'Z' => 'Z', - '0' => '0', - '9' => '9', - /* Basic control characters and null */ - "\r" => '\\D ', - "\n" => '\\A ', - "\t" => '\\9 ', - "\0" => '\\0 ', - /* Encode spaces for quoteless attribute protection */ - ' ' => '\\20 ', - ); - - protected $env; - - public function setUp() - { - $this->env = new Twig_Environment(); - } - - public function testHtmlEscapingConvertsSpecialChars() - { - foreach ($this->htmlSpecialChars as $key => $value) { - $this->assertEquals($value, twig_escape_filter($this->env, $key, 'html'), 'Failed to escape: '.$key); - } - } - - public function testHtmlAttributeEscapingConvertsSpecialChars() - { - foreach ($this->htmlAttrSpecialChars as $key => $value) { - $this->assertEquals($value, twig_escape_filter($this->env, $key, 'html_attr'), 'Failed to escape: '.$key); - } - } - - public function testJavascriptEscapingConvertsSpecialChars() - { - foreach ($this->jsSpecialChars as $key => $value) { - $this->assertEquals($value, twig_escape_filter($this->env, $key, 'js'), 'Failed to escape: '.$key); - } - } - - public function testJavascriptEscapingReturnsStringIfZeroLength() - { - $this->assertEquals('', twig_escape_filter($this->env, '', 'js')); - } - - public function testJavascriptEscapingReturnsStringIfContainsOnlyDigits() - { - $this->assertEquals('123', twig_escape_filter($this->env, '123', 'js')); - } - - public function testCssEscapingConvertsSpecialChars() - { - foreach ($this->cssSpecialChars as $key => $value) { - $this->assertEquals($value, twig_escape_filter($this->env, $key, 'css'), 'Failed to escape: '.$key); - } - } - - public function testCssEscapingReturnsStringIfZeroLength() - { - $this->assertEquals('', twig_escape_filter($this->env, '', 'css')); - } - - public function testCssEscapingReturnsStringIfContainsOnlyDigits() - { - $this->assertEquals('123', twig_escape_filter($this->env, '123', 'css')); - } - - public function testUrlEscapingConvertsSpecialChars() - { - foreach ($this->urlSpecialChars as $key => $value) { - $this->assertEquals($value, twig_escape_filter($this->env, $key, 'url'), 'Failed to escape: '.$key); - } - } - - /** - * Range tests to confirm escaped range of characters is within OWASP recommendation - */ - - /** - * Only testing the first few 2 ranges on this prot. function as that's all these - * other range tests require - */ - public function testUnicodeCodepointConversionToUtf8() - { - $expected = " ~ޙ"; - $codepoints = array(0x20, 0x7e, 0x799); - $result = ''; - foreach ($codepoints as $value) { - $result .= $this->codepointToUtf8($value); - } - $this->assertEquals($expected, $result); - } - - /** - * Convert a Unicode Codepoint to a literal UTF-8 character. - * - * @param int Unicode codepoint in hex notation - * @return string UTF-8 literal string - */ - protected function codepointToUtf8($codepoint) - { - if ($codepoint < 0x80) { - return chr($codepoint); - } - if ($codepoint < 0x800) { - return chr($codepoint >> 6 & 0x3f | 0xc0) - . chr($codepoint & 0x3f | 0x80); - } - if ($codepoint < 0x10000) { - return chr($codepoint >> 12 & 0x0f | 0xe0) - . chr($codepoint >> 6 & 0x3f | 0x80) - . chr($codepoint & 0x3f | 0x80); - } - if ($codepoint < 0x110000) { - return chr($codepoint >> 18 & 0x07 | 0xf0) - . chr($codepoint >> 12 & 0x3f | 0x80) - . chr($codepoint >> 6 & 0x3f | 0x80) - . chr($codepoint & 0x3f | 0x80); - } - throw new Exception('Codepoint requested outside of Unicode range'); - } - - public function testJavascriptEscapingEscapesOwaspRecommendedRanges() - { - $immune = array(',', '.', '_'); // Exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { - if ($chr >= 0x30 && $chr <= 0x39 - || $chr >= 0x41 && $chr <= 0x5A - || $chr >= 0x61 && $chr <= 0x7A) { - $literal = $this->codepointToUtf8($chr); - $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'js')); - } else { - $literal = $this->codepointToUtf8($chr); - if (in_array($literal, $immune)) { - $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'js')); - } else { - $this->assertNotEquals( - $literal, - twig_escape_filter($this->env, $literal, 'js'), - "$literal should be escaped!"); - } - } - } - } - - public function testHtmlAttributeEscapingEscapesOwaspRecommendedRanges() - { - $immune = array(',', '.', '-', '_'); // Exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { - if ($chr >= 0x30 && $chr <= 0x39 - || $chr >= 0x41 && $chr <= 0x5A - || $chr >= 0x61 && $chr <= 0x7A) { - $literal = $this->codepointToUtf8($chr); - $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'html_attr')); - } else { - $literal = $this->codepointToUtf8($chr); - if (in_array($literal, $immune)) { - $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'html_attr')); - } else { - $this->assertNotEquals( - $literal, - twig_escape_filter($this->env, $literal, 'html_attr'), - "$literal should be escaped!"); - } - } - } - } - - public function testCssEscapingEscapesOwaspRecommendedRanges() - { - $immune = array(); // CSS has no exceptions to escaping ranges - for ($chr=0; $chr < 0xFF; $chr++) { - if ($chr >= 0x30 && $chr <= 0x39 - || $chr >= 0x41 && $chr <= 0x5A - || $chr >= 0x61 && $chr <= 0x7A) { - $literal = $this->codepointToUtf8($chr); - $this->assertEquals($literal, twig_escape_filter($this->env, $literal, 'css')); - } else { - $literal = $this->codepointToUtf8($chr); - $this->assertNotEquals( - $literal, - twig_escape_filter($this->env, $literal, 'css'), - "$literal should be escaped!"); - } - } - } -}