diff --git a/.gitattributes b/.gitattributes index b61177d..c5aee50 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ /Tests/ export-ignore /.gitattributes export-ignore /.travis.yml export-ignore +/Libraries export-ignore diff --git a/Libraries/autoload.php b/Libraries/autoload.php new file mode 100644 index 0000000..5f559e1 --- /dev/null +++ b/Libraries/autoload.php @@ -0,0 +1,7 @@ +=7.2.0 <7.4", + "symfony/web-link": "^4.3", + "symfony/asset": "^5.0" + }, + "config": { + "vendor-dir": "." + } +} diff --git a/Libraries/composer.lock b/Libraries/composer.lock new file mode 100644 index 0000000..fe8a733 --- /dev/null +++ b/Libraries/composer.lock @@ -0,0 +1,256 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "0d0500692f449fa9a07ccb6a68a6a156", + "packages": [ + { + "name": "psr/link", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/link.git", + "reference": "eea8e8662d5cd3ae4517c9b864493f59fca95562" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/link/zipball/eea8e8662d5cd3ae4517c9b864493f59fca95562", + "reference": "eea8e8662d5cd3ae4517c9b864493f59fca95562", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Link\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for HTTP links", + "keywords": [ + "http", + "http-link", + "link", + "psr", + "psr-13", + "rest" + ], + "time": "2016-10-28T16:06:13+00:00" + }, + { + "name": "symfony/asset", + "version": "v5.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset.git", + "reference": "6b66969b9f5cd53c1ce69bdc651aa962f211b6b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset/zipball/6b66969b9f5cd53c1ce69bdc651aa962f211b6b6", + "reference": "6b66969b9f5cd53c1ce69bdc651aa962f211b6b6", + "shasum": "" + }, + "require": { + "php": "^7.2.5" + }, + "require-dev": { + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" + }, + "suggest": { + "symfony/http-foundation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Asset\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Asset Component", + "homepage": "https://symfony.com", + "time": "2019-11-18T17:27:11+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.13.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-11-27T13:56:44+00:00" + }, + { + "name": "symfony/web-link", + "version": "v4.4.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/web-link.git", + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/web-link/zipball/bc6432b92681b2f28ced2f3bbcf051e75eea569c", + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/link": "^1.0", + "symfony/polyfill-php72": "^1.5" + }, + "conflict": { + "symfony/http-kernel": "<4.3" + }, + "provide": { + "psr/link-implementation": "1.0" + }, + "require-dev": { + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.3|^5.0" + }, + "suggest": { + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\WebLink\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony WebLink Component", + "homepage": "https://symfony.com", + "keywords": [ + "dns-prefetch", + "http", + "http2", + "link", + "performance", + "prefetch", + "preload", + "prerender", + "psr13", + "push" + ], + "time": "2019-10-12T00:35:04+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.2.0 <7.4" + }, + "platform-dev": [] +} diff --git a/Libraries/composer/ClassLoader.php b/Libraries/composer/ClassLoader.php new file mode 100644 index 0000000..fce8549 --- /dev/null +++ b/Libraries/composer/ClassLoader.php @@ -0,0 +1,445 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/Libraries/composer/LICENSE b/Libraries/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/Libraries/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/Libraries/composer/autoload_classmap.php b/Libraries/composer/autoload_classmap.php new file mode 100644 index 0000000..1bd6482 --- /dev/null +++ b/Libraries/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/symfony/polyfill-php72/bootstrap.php', +); diff --git a/Libraries/composer/autoload_namespaces.php b/Libraries/composer/autoload_namespaces.php new file mode 100644 index 0000000..71c9e91 --- /dev/null +++ b/Libraries/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/symfony/polyfill-php72'), + 'Symfony\\Component\\WebLink\\' => array($vendorDir . '/symfony/web-link'), + 'Symfony\\Component\\Asset\\' => array($vendorDir . '/symfony/asset'), + 'Psr\\Link\\' => array($vendorDir . '/psr/link/src'), +); diff --git a/Libraries/composer/autoload_real.php b/Libraries/composer/autoload_real.php new file mode 100644 index 0000000..19263fa --- /dev/null +++ b/Libraries/composer/autoload_real.php @@ -0,0 +1,70 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit6cd53400e6383e07fb1f963bcc202063::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit6cd53400e6383e07fb1f963bcc202063::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire6cd53400e6383e07fb1f963bcc202063($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire6cd53400e6383e07fb1f963bcc202063($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/Libraries/composer/autoload_static.php b/Libraries/composer/autoload_static.php new file mode 100644 index 0000000..5757f90 --- /dev/null +++ b/Libraries/composer/autoload_static.php @@ -0,0 +1,53 @@ + __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symfony\\Polyfill\\Php72\\' => 23, + 'Symfony\\Component\\WebLink\\' => 26, + 'Symfony\\Component\\Asset\\' => 24, + ), + 'P' => + array ( + 'Psr\\Link\\' => 9, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Php72\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', + ), + 'Symfony\\Component\\WebLink\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/web-link', + ), + 'Symfony\\Component\\Asset\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/asset', + ), + 'Psr\\Link\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/link/src', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit6cd53400e6383e07fb1f963bcc202063::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit6cd53400e6383e07fb1f963bcc202063::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/Libraries/composer/installed.json b/Libraries/composer/installed.json new file mode 100644 index 0000000..be67ba7 --- /dev/null +++ b/Libraries/composer/installed.json @@ -0,0 +1,246 @@ +[ + { + "name": "psr/link", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/link.git", + "reference": "eea8e8662d5cd3ae4517c9b864493f59fca95562" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/link/zipball/eea8e8662d5cd3ae4517c9b864493f59fca95562", + "reference": "eea8e8662d5cd3ae4517c9b864493f59fca95562", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-10-28T16:06:13+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Link\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for HTTP links", + "keywords": [ + "http", + "http-link", + "link", + "psr", + "psr-13", + "rest" + ] + }, + { + "name": "symfony/asset", + "version": "v5.0.2", + "version_normalized": "5.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset.git", + "reference": "6b66969b9f5cd53c1ce69bdc651aa962f211b6b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset/zipball/6b66969b9f5cd53c1ce69bdc651aa962f211b6b6", + "reference": "6b66969b9f5cd53c1ce69bdc651aa962f211b6b6", + "shasum": "" + }, + "require": { + "php": "^7.2.5" + }, + "require-dev": { + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" + }, + "suggest": { + "symfony/http-foundation": "" + }, + "time": "2019-11-18T17:27:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Asset\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Asset Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.13.1", + "version_normalized": "1.13.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", + "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2019-11-27T13:56:44+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ] + }, + { + "name": "symfony/web-link", + "version": "v4.4.2", + "version_normalized": "4.4.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/web-link.git", + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/web-link/zipball/bc6432b92681b2f28ced2f3bbcf051e75eea569c", + "reference": "bc6432b92681b2f28ced2f3bbcf051e75eea569c", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "psr/link": "^1.0", + "symfony/polyfill-php72": "^1.5" + }, + "conflict": { + "symfony/http-kernel": "<4.3" + }, + "provide": { + "psr/link-implementation": "1.0" + }, + "require-dev": { + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.3|^5.0" + }, + "suggest": { + "symfony/http-kernel": "" + }, + "time": "2019-10-12T00:35:04+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\WebLink\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony WebLink Component", + "homepage": "https://symfony.com", + "keywords": [ + "dns-prefetch", + "http", + "http2", + "link", + "performance", + "prefetch", + "preload", + "prerender", + "psr13", + "push" + ] + } +] diff --git a/Libraries/psr/link/.editorconfig b/Libraries/psr/link/.editorconfig new file mode 100644 index 0000000..48542cb --- /dev/null +++ b/Libraries/psr/link/.editorconfig @@ -0,0 +1,12 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/Libraries/psr/link/LICENSE.md b/Libraries/psr/link/LICENSE.md new file mode 100644 index 0000000..e49a7c8 --- /dev/null +++ b/Libraries/psr/link/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2016 PHP Framework Interoperability Group + +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. diff --git a/Libraries/psr/link/README.md b/Libraries/psr/link/README.md new file mode 100644 index 0000000..8f57601 --- /dev/null +++ b/Libraries/psr/link/README.md @@ -0,0 +1,8 @@ +PSR Http Link +============= + +This repository holds all interfaces/classes/traits related to +[PSR-13](https://github.com/php-fig/fig-standards/blob/master/proposed/links.md). + +Note that this is not an HTTP link implementation of its own. It is merely an +interface that describes an HTTP link. See the specification for more details. diff --git a/Libraries/psr/link/composer.json b/Libraries/psr/link/composer.json new file mode 100644 index 0000000..1ef25fe --- /dev/null +++ b/Libraries/psr/link/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/link", + "description": "Common interfaces for HTTP links", + "keywords": ["psr", "psr-13", "http", "http-link", "link", "rest"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Link\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/Libraries/psr/link/src/EvolvableLinkInterface.php b/Libraries/psr/link/src/EvolvableLinkInterface.php new file mode 100644 index 0000000..926d4e4 --- /dev/null +++ b/Libraries/psr/link/src/EvolvableLinkInterface.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\Context; + +/** + * Holds information about the current request. + * + * @author Fabien Potencier + */ +interface ContextInterface +{ + /** + * Gets the base path. + * + * @return string The base path + */ + public function getBasePath(); + + /** + * Checks whether the request is secure or not. + * + * @return bool true if the request is secure, false otherwise + */ + public function isSecure(); +} diff --git a/Libraries/symfony/asset/Context/NullContext.php b/Libraries/symfony/asset/Context/NullContext.php new file mode 100644 index 0000000..0743d8c --- /dev/null +++ b/Libraries/symfony/asset/Context/NullContext.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\Context; + +/** + * A context that does nothing. + * + * @author Fabien Potencier + */ +class NullContext implements ContextInterface +{ + /** + * {@inheritdoc} + */ + public function getBasePath() + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function isSecure() + { + return false; + } +} diff --git a/Libraries/symfony/asset/Context/RequestStackContext.php b/Libraries/symfony/asset/Context/RequestStackContext.php new file mode 100644 index 0000000..b63f466 --- /dev/null +++ b/Libraries/symfony/asset/Context/RequestStackContext.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\Context; + +use Symfony\Component\HttpFoundation\RequestStack; + +/** + * Uses a RequestStack to populate the context. + * + * @author Fabien Potencier + */ +class RequestStackContext implements ContextInterface +{ + private $requestStack; + private $basePath; + private $secure; + + public function __construct(RequestStack $requestStack, string $basePath = '', bool $secure = false) + { + $this->requestStack = $requestStack; + $this->basePath = $basePath; + $this->secure = $secure; + } + + /** + * {@inheritdoc} + */ + public function getBasePath() + { + if (!$request = $this->requestStack->getMasterRequest()) { + return $this->basePath; + } + + return $request->getBasePath(); + } + + /** + * {@inheritdoc} + */ + public function isSecure() + { + if (!$request = $this->requestStack->getMasterRequest()) { + return $this->secure; + } + + return $request->isSecure(); + } +} diff --git a/Libraries/symfony/asset/Exception/ExceptionInterface.php b/Libraries/symfony/asset/Exception/ExceptionInterface.php new file mode 100644 index 0000000..777f64b --- /dev/null +++ b/Libraries/symfony/asset/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\Exception; + +/** + * Base ExceptionInterface for the Asset component. + * + * @author Fabien Potencier + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/Libraries/symfony/asset/Exception/InvalidArgumentException.php b/Libraries/symfony/asset/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..0945d8f --- /dev/null +++ b/Libraries/symfony/asset/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\Exception; + +/** + * Base InvalidArgumentException for the Asset component. + * + * @author Fabien Potencier + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/Libraries/symfony/asset/Exception/LogicException.php b/Libraries/symfony/asset/Exception/LogicException.php new file mode 100644 index 0000000..f291d88 --- /dev/null +++ b/Libraries/symfony/asset/Exception/LogicException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\Exception; + +/** + * Base LogicException for the Asset component. + * + * @author Fabien Potencier + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/Libraries/symfony/asset/LICENSE b/Libraries/symfony/asset/LICENSE new file mode 100644 index 0000000..a677f43 --- /dev/null +++ b/Libraries/symfony/asset/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Libraries/symfony/asset/Package.php b/Libraries/symfony/asset/Package.php new file mode 100644 index 0000000..b3b1c0b --- /dev/null +++ b/Libraries/symfony/asset/Package.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset; + +use Symfony\Component\Asset\Context\ContextInterface; +use Symfony\Component\Asset\Context\NullContext; +use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface; + +/** + * Basic package that adds a version to asset URLs. + * + * @author Kris Wallsmith + * @author Fabien Potencier + */ +class Package implements PackageInterface +{ + private $versionStrategy; + private $context; + + public function __construct(VersionStrategyInterface $versionStrategy, ContextInterface $context = null) + { + $this->versionStrategy = $versionStrategy; + $this->context = $context ?: new NullContext(); + } + + /** + * {@inheritdoc} + */ + public function getVersion(string $path) + { + return $this->versionStrategy->getVersion($path); + } + + /** + * {@inheritdoc} + */ + public function getUrl(string $path) + { + if ($this->isAbsoluteUrl($path)) { + return $path; + } + + return $this->versionStrategy->applyVersion($path); + } + + /** + * @return ContextInterface + */ + protected function getContext() + { + return $this->context; + } + + /** + * @return VersionStrategyInterface + */ + protected function getVersionStrategy() + { + return $this->versionStrategy; + } + + /** + * @return bool + */ + protected function isAbsoluteUrl(string $url) + { + return false !== strpos($url, '://') || '//' === substr($url, 0, 2); + } +} diff --git a/Libraries/symfony/asset/PackageInterface.php b/Libraries/symfony/asset/PackageInterface.php new file mode 100644 index 0000000..644a30a --- /dev/null +++ b/Libraries/symfony/asset/PackageInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset; + +/** + * Asset package interface. + * + * @author Kris Wallsmith + */ +interface PackageInterface +{ + /** + * Returns the asset version for an asset. + * + * @return string The version string + */ + public function getVersion(string $path); + + /** + * Returns an absolute or root-relative public path. + * + * @return string The public path + */ + public function getUrl(string $path); +} diff --git a/Libraries/symfony/asset/Packages.php b/Libraries/symfony/asset/Packages.php new file mode 100644 index 0000000..12aba72 --- /dev/null +++ b/Libraries/symfony/asset/Packages.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset; + +use Symfony\Component\Asset\Exception\InvalidArgumentException; +use Symfony\Component\Asset\Exception\LogicException; + +/** + * Helps manage asset URLs. + * + * @author Fabien Potencier + * @author Kris Wallsmith + */ +class Packages +{ + private $defaultPackage; + private $packages = []; + + /** + * @param PackageInterface[] $packages Additional packages indexed by name + */ + public function __construct(PackageInterface $defaultPackage = null, array $packages = []) + { + $this->defaultPackage = $defaultPackage; + + foreach ($packages as $name => $package) { + $this->addPackage($name, $package); + } + } + + public function setDefaultPackage(PackageInterface $defaultPackage) + { + $this->defaultPackage = $defaultPackage; + } + + public function addPackage(string $name, PackageInterface $package) + { + $this->packages[$name] = $package; + } + + /** + * Returns an asset package. + * + * @param string $name The name of the package or null for the default package + * + * @return PackageInterface An asset package + * + * @throws InvalidArgumentException If there is no package by that name + * @throws LogicException If no default package is defined + */ + public function getPackage(string $name = null) + { + if (null === $name) { + if (null === $this->defaultPackage) { + throw new LogicException('There is no default asset package, configure one first.'); + } + + return $this->defaultPackage; + } + + if (!isset($this->packages[$name])) { + throw new InvalidArgumentException(sprintf('There is no "%s" asset package.', $name)); + } + + return $this->packages[$name]; + } + + /** + * Gets the version to add to public URL. + * + * @param string $path A public path + * @param string $packageName A package name + * + * @return string The current version + */ + public function getVersion(string $path, string $packageName = null) + { + return $this->getPackage($packageName)->getVersion($path); + } + + /** + * Returns the public path. + * + * Absolute paths (i.e. http://...) are returned unmodified. + * + * @param string $path A public path + * @param string $packageName The name of the asset package to use + * + * @return string A public path which takes into account the base path and URL path + */ + public function getUrl(string $path, string $packageName = null) + { + return $this->getPackage($packageName)->getUrl($path); + } +} diff --git a/Libraries/symfony/asset/PathPackage.php b/Libraries/symfony/asset/PathPackage.php new file mode 100644 index 0000000..1a7e8fa --- /dev/null +++ b/Libraries/symfony/asset/PathPackage.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset; + +use Symfony\Component\Asset\Context\ContextInterface; +use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface; + +/** + * Package that adds a base path to asset URLs in addition to a version. + * + * In addition to the provided base path, this package also automatically + * prepends the current request base path if a Context is available to + * allow a website to be hosted easily under any given path under the Web + * Server root directory. + * + * @author Fabien Potencier + */ +class PathPackage extends Package +{ + private $basePath; + + /** + * @param string $basePath The base path to be prepended to relative paths + */ + public function __construct(string $basePath, VersionStrategyInterface $versionStrategy, ContextInterface $context = null) + { + parent::__construct($versionStrategy, $context); + + if (!$basePath) { + $this->basePath = '/'; + } else { + if ('/' != $basePath[0]) { + $basePath = '/'.$basePath; + } + + $this->basePath = rtrim($basePath, '/').'/'; + } + } + + /** + * {@inheritdoc} + */ + public function getUrl(string $path) + { + $versionedPath = parent::getUrl($path); + + // if absolute or begins with /, we're done + if ($this->isAbsoluteUrl($versionedPath) || ($versionedPath && '/' === $versionedPath[0])) { + return $versionedPath; + } + + return $this->getBasePath().ltrim($versionedPath, '/'); + } + + /** + * Returns the base path. + * + * @return string The base path + */ + public function getBasePath() + { + return $this->getContext()->getBasePath().$this->basePath; + } +} diff --git a/Libraries/symfony/asset/README.md b/Libraries/symfony/asset/README.md new file mode 100644 index 0000000..3291698 --- /dev/null +++ b/Libraries/symfony/asset/README.md @@ -0,0 +1,14 @@ +Asset Component +=============== + +The Asset component manages URL generation and versioning of web assets such as +CSS stylesheets, JavaScript files and image files. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/asset/introduction.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/Libraries/symfony/asset/UrlPackage.php b/Libraries/symfony/asset/UrlPackage.php new file mode 100644 index 0000000..98bc128 --- /dev/null +++ b/Libraries/symfony/asset/UrlPackage.php @@ -0,0 +1,133 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset; + +use Symfony\Component\Asset\Context\ContextInterface; +use Symfony\Component\Asset\Exception\InvalidArgumentException; +use Symfony\Component\Asset\Exception\LogicException; +use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface; + +/** + * Package that adds a base URL to asset URLs in addition to a version. + * + * The package allows to use more than one base URLs in which case + * it randomly chooses one for each asset; it also guarantees that + * any given path will always use the same base URL to be nice with + * HTTP caching mechanisms. + * + * When the request context is available, this package can choose the + * best base URL to use based on the current request scheme: + * + * * For HTTP request, it chooses between all base URLs; + * * For HTTPs requests, it chooses between HTTPs base URLs and relative protocol URLs + * or falls back to any base URL if no secure ones are available. + * + * @author Fabien Potencier + */ +class UrlPackage extends Package +{ + private $baseUrls = []; + private $sslPackage; + + /** + * @param string|string[] $baseUrls Base asset URLs + */ + public function __construct($baseUrls, VersionStrategyInterface $versionStrategy, ContextInterface $context = null) + { + parent::__construct($versionStrategy, $context); + + if (!\is_array($baseUrls)) { + $baseUrls = (array) $baseUrls; + } + + if (!$baseUrls) { + throw new LogicException('You must provide at least one base URL.'); + } + + foreach ($baseUrls as $baseUrl) { + $this->baseUrls[] = rtrim($baseUrl, '/'); + } + + $sslUrls = $this->getSslUrls($baseUrls); + + if ($sslUrls && $baseUrls !== $sslUrls) { + $this->sslPackage = new self($sslUrls, $versionStrategy); + } + } + + /** + * {@inheritdoc} + */ + public function getUrl(string $path) + { + if ($this->isAbsoluteUrl($path)) { + return $path; + } + + if (null !== $this->sslPackage && $this->getContext()->isSecure()) { + return $this->sslPackage->getUrl($path); + } + + $url = $this->getVersionStrategy()->applyVersion($path); + + if ($this->isAbsoluteUrl($url)) { + return $url; + } + + if ($url && '/' != $url[0]) { + $url = '/'.$url; + } + + return $this->getBaseUrl($path).$url; + } + + /** + * Returns the base URL for a path. + * + * @return string The base URL + */ + public function getBaseUrl(string $path) + { + if (1 === \count($this->baseUrls)) { + return $this->baseUrls[0]; + } + + return $this->baseUrls[$this->chooseBaseUrl($path)]; + } + + /** + * Determines which base URL to use for the given path. + * + * Override this method to change the default distribution strategy. + * This method should always return the same base URL index for a given path. + * + * @return int The base URL index for the given path + */ + protected function chooseBaseUrl(string $path) + { + return (int) fmod(hexdec(substr(hash('sha256', $path), 0, 10)), \count($this->baseUrls)); + } + + private function getSslUrls(array $urls) + { + $sslUrls = []; + foreach ($urls as $url) { + if ('https://' === substr($url, 0, 8) || '//' === substr($url, 0, 2)) { + $sslUrls[] = $url; + } elseif (null === parse_url($url, PHP_URL_SCHEME)) { + throw new InvalidArgumentException(sprintf('"%s" is not a valid URL', $url)); + } + } + + return $sslUrls; + } +} diff --git a/Libraries/symfony/asset/VersionStrategy/EmptyVersionStrategy.php b/Libraries/symfony/asset/VersionStrategy/EmptyVersionStrategy.php new file mode 100644 index 0000000..8ee048c --- /dev/null +++ b/Libraries/symfony/asset/VersionStrategy/EmptyVersionStrategy.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\VersionStrategy; + +/** + * Disable version for all assets. + * + * @author Fabien Potencier + */ +class EmptyVersionStrategy implements VersionStrategyInterface +{ + /** + * {@inheritdoc} + */ + public function getVersion(string $path) + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function applyVersion(string $path) + { + return $path; + } +} diff --git a/Libraries/symfony/asset/VersionStrategy/JsonManifestVersionStrategy.php b/Libraries/symfony/asset/VersionStrategy/JsonManifestVersionStrategy.php new file mode 100644 index 0000000..cc4bf5a --- /dev/null +++ b/Libraries/symfony/asset/VersionStrategy/JsonManifestVersionStrategy.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\VersionStrategy; + +/** + * Reads the versioned path of an asset from a JSON manifest file. + * + * For example, the manifest file might look like this: + * { + * "main.js": "main.abc123.js", + * "css/styles.css": "css/styles.555abc.css" + * } + * + * You could then ask for the version of "main.js" or "css/styles.css". + */ +class JsonManifestVersionStrategy implements VersionStrategyInterface +{ + private $manifestPath; + private $manifestData; + + /** + * @param string $manifestPath Absolute path to the manifest file + */ + public function __construct(string $manifestPath) + { + $this->manifestPath = $manifestPath; + } + + /** + * With a manifest, we don't really know or care about what + * the version is. Instead, this returns the path to the + * versioned file. + */ + public function getVersion(string $path) + { + return $this->applyVersion($path); + } + + public function applyVersion(string $path) + { + return $this->getManifestPath($path) ?: $path; + } + + private function getManifestPath(string $path): ?string + { + if (null === $this->manifestData) { + if (!file_exists($this->manifestPath)) { + throw new \RuntimeException(sprintf('Asset manifest file "%s" does not exist.', $this->manifestPath)); + } + + $this->manifestData = json_decode(file_get_contents($this->manifestPath), true); + if (0 < json_last_error()) { + throw new \RuntimeException(sprintf('Error parsing JSON from asset manifest file "%s" - %s', $this->manifestPath, json_last_error_msg())); + } + } + + return isset($this->manifestData[$path]) ? $this->manifestData[$path] : null; + } +} diff --git a/Libraries/symfony/asset/VersionStrategy/StaticVersionStrategy.php b/Libraries/symfony/asset/VersionStrategy/StaticVersionStrategy.php new file mode 100644 index 0000000..3111e55 --- /dev/null +++ b/Libraries/symfony/asset/VersionStrategy/StaticVersionStrategy.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\VersionStrategy; + +/** + * Returns the same version for all assets. + * + * @author Fabien Potencier + */ +class StaticVersionStrategy implements VersionStrategyInterface +{ + private $version; + private $format; + + /** + * @param string $version Version number + * @param string $format Url format + */ + public function __construct(string $version, string $format = null) + { + $this->version = $version; + $this->format = $format ?: '%s?%s'; + } + + /** + * {@inheritdoc} + */ + public function getVersion(string $path) + { + return $this->version; + } + + /** + * {@inheritdoc} + */ + public function applyVersion(string $path) + { + $versionized = sprintf($this->format, ltrim($path, '/'), $this->getVersion($path)); + + if ($path && '/' == $path[0]) { + return '/'.$versionized; + } + + return $versionized; + } +} diff --git a/Libraries/symfony/asset/VersionStrategy/VersionStrategyInterface.php b/Libraries/symfony/asset/VersionStrategy/VersionStrategyInterface.php new file mode 100644 index 0000000..3381928 --- /dev/null +++ b/Libraries/symfony/asset/VersionStrategy/VersionStrategyInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Asset\VersionStrategy; + +/** + * Asset version strategy interface. + * + * @author Fabien Potencier + */ +interface VersionStrategyInterface +{ + /** + * Returns the asset version for an asset. + * + * @return string The version string + */ + public function getVersion(string $path); + + /** + * Applies version to the supplied path. + * + * @return string The versionized path + */ + public function applyVersion(string $path); +} diff --git a/Libraries/symfony/asset/composer.json b/Libraries/symfony/asset/composer.json new file mode 100644 index 0000000..4d6ca77 --- /dev/null +++ b/Libraries/symfony/asset/composer.json @@ -0,0 +1,40 @@ +{ + "name": "symfony/asset", + "type": "library", + "description": "Symfony Asset Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^7.2.5" + }, + "suggest": { + "symfony/http-foundation": "" + }, + "require-dev": { + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Asset\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + } +} diff --git a/Libraries/symfony/polyfill-php72/LICENSE b/Libraries/symfony/polyfill-php72/LICENSE new file mode 100644 index 0000000..4cd8bdd --- /dev/null +++ b/Libraries/symfony/polyfill-php72/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Libraries/symfony/polyfill-php72/Php72.php b/Libraries/symfony/polyfill-php72/Php72.php new file mode 100644 index 0000000..d531e84 --- /dev/null +++ b/Libraries/symfony/polyfill-php72/Php72.php @@ -0,0 +1,216 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php72; + +/** + * @author Nicolas Grekas + * @author Dariusz Rumiński + * + * @internal + */ +final class Php72 +{ + private static $hashMask; + + public static function utf8_encode($s) + { + $s .= $s; + $len = \strlen($s); + + for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) { + switch (true) { + case $s[$i] < "\x80": $s[$j] = $s[$i]; break; + case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break; + default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break; + } + } + + return substr($s, 0, $j); + } + + public static function utf8_decode($s) + { + $s = (string) $s; + $len = \strlen($s); + + for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { + switch ($s[$i] & "\xF0") { + case "\xC0": + case "\xD0": + $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F"); + $s[$j] = $c < 256 ? \chr($c) : '?'; + break; + + case "\xF0": + ++$i; + // no break + + case "\xE0": + $s[$j] = '?'; + $i += 2; + break; + + default: + $s[$j] = $s[$i]; + } + } + + return substr($s, 0, $j); + } + + public static function php_os_family() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + return 'Windows'; + } + + $map = array( + 'Darwin' => 'Darwin', + 'DragonFly' => 'BSD', + 'FreeBSD' => 'BSD', + 'NetBSD' => 'BSD', + 'OpenBSD' => 'BSD', + 'Linux' => 'Linux', + 'SunOS' => 'Solaris', + ); + + return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown'; + } + + public static function spl_object_id($object) + { + if (null === self::$hashMask) { + self::initHashMask(); + } + if (null === $hash = spl_object_hash($object)) { + return; + } + + return self::$hashMask ^ hexdec(substr($hash, 16 - \PHP_INT_SIZE, \PHP_INT_SIZE)); + } + + public static function sapi_windows_vt100_support($stream, $enable = null) + { + if (!\is_resource($stream)) { + trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING); + + return false; + } + + $meta = stream_get_meta_data($stream); + + if ('STDIO' !== $meta['stream_type']) { + trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', E_USER_WARNING); + + return false; + } + + // We cannot actually disable vt100 support if it is set + if (false === $enable || !self::stream_isatty($stream)) { + return false; + } + + // The native function does not apply to stdin + $meta = array_map('strtolower', $meta); + $stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri']; + + return !$stdin + && (false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM') + || 'Hyper' === getenv('TERM_PROGRAM')); + } + + public static function stream_isatty($stream) + { + if (!\is_resource($stream)) { + trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING); + + return false; + } + + if ('\\' === \DIRECTORY_SEPARATOR) { + $stat = @fstat($stream); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + return \function_exists('posix_isatty') && @posix_isatty($stream); + } + + private static function initHashMask() + { + $obj = (object) array(); + self::$hashMask = -1; + + // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below + $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'); + foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) { + if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) { + $frame['line'] = 0; + break; + } + } + if (!empty($frame['line'])) { + ob_start(); + debug_zval_dump($obj); + self::$hashMask = (int) substr(ob_get_clean(), 17); + } + + self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - \PHP_INT_SIZE, \PHP_INT_SIZE)); + } + + public static function mb_chr($code, $encoding = null) + { + if (0x80 > $code %= 0x200000) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); + } elseif (0x10000 > $code) { + $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } else { + $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } + + if ('UTF-8' !== $encoding) { + $s = mb_convert_encoding($s, $encoding, 'UTF-8'); + } + + return $s; + } + + public static function mb_ord($s, $encoding = null) + { + if (null == $encoding) { + $s = mb_convert_encoding($s, 'UTF-8'); + } elseif ('UTF-8' !== $encoding) { + $s = mb_convert_encoding($s, 'UTF-8', $encoding); + } + + if (1 === \strlen($s)) { + return \ord($s); + } + + $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; + if (0xF0 <= $code) { + return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; + } + if (0xE0 <= $code) { + return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; + } + if (0xC0 <= $code) { + return (($code - 0xC0) << 6) + $s[2] - 0x80; + } + + return $code; + } +} diff --git a/Libraries/symfony/polyfill-php72/README.md b/Libraries/symfony/polyfill-php72/README.md new file mode 100644 index 0000000..82c45f7 --- /dev/null +++ b/Libraries/symfony/polyfill-php72/README.md @@ -0,0 +1,27 @@ +Symfony Polyfill / Php72 +======================== + +This component provides functions added to PHP 7.2 core: + +- [`spl_object_id`](https://php.net/spl_object_id) +- [`stream_isatty`](https://php.net/stream_isatty) + +On Windows only: + +- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support) + +Moved to core since 7.2 (was in the optional XML extension earlier): + +- [`utf8_encode`](https://php.net/utf8_encode) +- [`utf8_decode`](https://php.net/utf8_decode) + +Also, it provides a constant added to PHP 7.2: +- [`PHP_OS_FAMILY`](http://php.net/manual/en/reserved.constants.php#constant.php-os-family) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/Libraries/symfony/polyfill-php72/bootstrap.php b/Libraries/symfony/polyfill-php72/bootstrap.php new file mode 100644 index 0000000..519056d --- /dev/null +++ b/Libraries/symfony/polyfill-php72/bootstrap.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php72 as p; + +if (PHP_VERSION_ID < 70200) { + if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) { + function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); } + } + if (!function_exists('stream_isatty')) { + function stream_isatty($stream) { return p\Php72::stream_isatty($stream); } + } + if (!function_exists('utf8_encode')) { + function utf8_encode($s) { return p\Php72::utf8_encode($s); } + function utf8_decode($s) { return p\Php72::utf8_decode($s); } + } + if (!function_exists('spl_object_id')) { + function spl_object_id($s) { return p\Php72::spl_object_id($s); } + } + if (!defined('PHP_OS_FAMILY')) { + define('PHP_OS_FAMILY', p\Php72::php_os_family()); + } + if (!function_exists('mb_chr')) { + function mb_ord($s, $enc = null) { return p\Php72::mb_ord($s, $enc); } + function mb_chr($code, $enc = null) { return p\Php72::mb_chr($code, $enc); } + function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); } + } +} diff --git a/Libraries/symfony/polyfill-php72/composer.json b/Libraries/symfony/polyfill-php72/composer.json new file mode 100644 index 0000000..0d37167 --- /dev/null +++ b/Libraries/symfony/polyfill-php72/composer.json @@ -0,0 +1,31 @@ +{ + "name": "symfony/polyfill-php72", + "type": "library", + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php72\\": "" }, + "files": [ "bootstrap.php" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "1.13-dev" + } + } +} diff --git a/Libraries/symfony/web-link/.gitattributes b/Libraries/symfony/web-link/.gitattributes new file mode 100644 index 0000000..ebb9287 --- /dev/null +++ b/Libraries/symfony/web-link/.gitattributes @@ -0,0 +1,3 @@ +/Tests export-ignore +/phpunit.xml.dist export-ignore +/.gitignore export-ignore diff --git a/Libraries/symfony/web-link/CHANGELOG.md b/Libraries/symfony/web-link/CHANGELOG.md new file mode 100644 index 0000000..28dad5a --- /dev/null +++ b/Libraries/symfony/web-link/CHANGELOG.md @@ -0,0 +1,12 @@ +CHANGELOG +========= + +4.4.0 +----- + + * implement PSR-13 directly + +3.3.0 +----- + + * added the component diff --git a/Libraries/symfony/web-link/EventListener/AddLinkHeaderListener.php b/Libraries/symfony/web-link/EventListener/AddLinkHeaderListener.php new file mode 100644 index 0000000..3027529 --- /dev/null +++ b/Libraries/symfony/web-link/EventListener/AddLinkHeaderListener.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\WebLink\EventListener; + +use Psr\Link\LinkProviderInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\ResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\WebLink\HttpHeaderSerializer; + +/** + * Adds the Link HTTP header to the response. + * + * @author Kévin Dunglas + * + * @final + */ +class AddLinkHeaderListener implements EventSubscriberInterface +{ + private $serializer; + + public function __construct() + { + $this->serializer = new HttpHeaderSerializer(); + } + + public function onKernelResponse(ResponseEvent $event) + { + if (!$event->isMasterRequest()) { + return; + } + + $linkProvider = $event->getRequest()->attributes->get('_links'); + if (!$linkProvider instanceof LinkProviderInterface || !$links = $linkProvider->getLinks()) { + return; + } + + $event->getResponse()->headers->set('Link', $this->serializer->serialize($links), false); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents(): array + { + return [KernelEvents::RESPONSE => 'onKernelResponse']; + } +} diff --git a/Libraries/symfony/web-link/GenericLinkProvider.php b/Libraries/symfony/web-link/GenericLinkProvider.php new file mode 100644 index 0000000..9dd0e67 --- /dev/null +++ b/Libraries/symfony/web-link/GenericLinkProvider.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\WebLink; + +use Psr\Link\EvolvableLinkProviderInterface; +use Psr\Link\LinkInterface; + +class GenericLinkProvider implements EvolvableLinkProviderInterface +{ + /** + * @var LinkInterface[] + */ + private $links = []; + + /** + * @param LinkInterface[] $links + */ + public function __construct(array $links = []) + { + $that = $this; + + foreach ($links as $link) { + $that = $that->withLink($link); + } + + $this->links = $that->links; + } + + /** + * {@inheritdoc} + */ + public function getLinks(): array + { + return array_values($this->links); + } + + /** + * {@inheritdoc} + */ + public function getLinksByRel($rel): array + { + $links = []; + + foreach ($this->links as $link) { + if (\in_array($rel, $link->getRels())) { + $links[] = $link; + } + } + + return $links; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withLink(LinkInterface $link) + { + $that = clone $this; + $that->links[spl_object_id($link)] = $link; + + return $that; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withoutLink(LinkInterface $link) + { + $that = clone $this; + unset($that->links[spl_object_id($link)]); + + return $that; + } +} diff --git a/Libraries/symfony/web-link/HttpHeaderSerializer.php b/Libraries/symfony/web-link/HttpHeaderSerializer.php new file mode 100644 index 0000000..d80d96e --- /dev/null +++ b/Libraries/symfony/web-link/HttpHeaderSerializer.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\WebLink; + +use Psr\Link\LinkInterface; + +/** + * Serializes a list of Link instances to a HTTP Link header. + * + * @see https://tools.ietf.org/html/rfc5988 + * + * @author Kévin Dunglas + */ +final class HttpHeaderSerializer +{ + /** + * Builds the value of the "Link" HTTP header. + * + * @param LinkInterface[]|\Traversable $links + */ + public function serialize(iterable $links): ?string + { + $elements = []; + foreach ($links as $link) { + if ($link->isTemplated()) { + continue; + } + + $attributesParts = ['', sprintf('rel="%s"', implode(' ', $link->getRels()))]; + foreach ($link->getAttributes() as $key => $value) { + if (\is_array($value)) { + foreach ($value as $v) { + $attributesParts[] = sprintf('%s="%s"', $key, $v); + } + + continue; + } + + if (!\is_bool($value)) { + $attributesParts[] = sprintf('%s="%s"', $key, $value); + + continue; + } + + if (true === $value) { + $attributesParts[] = $key; + } + } + + $elements[] = sprintf('<%s>%s', $link->getHref(), implode('; ', $attributesParts)); + } + + return $elements ? implode(',', $elements) : null; + } +} diff --git a/Libraries/symfony/web-link/LICENSE b/Libraries/symfony/web-link/LICENSE new file mode 100644 index 0000000..a677f43 --- /dev/null +++ b/Libraries/symfony/web-link/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Libraries/symfony/web-link/Link.php b/Libraries/symfony/web-link/Link.php new file mode 100644 index 0000000..a430284 --- /dev/null +++ b/Libraries/symfony/web-link/Link.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\WebLink; + +use Psr\Link\EvolvableLinkInterface; + +class Link implements EvolvableLinkInterface +{ + // Relations defined in https://www.w3.org/TR/html5/links.html#links and applicable on link elements + public const REL_ALTERNATE = 'alternate'; + public const REL_AUTHOR = 'author'; + public const REL_HELP = 'help'; + public const REL_ICON = 'icon'; + public const REL_LICENSE = 'license'; + public const REL_SEARCH = 'search'; + public const REL_STYLESHEET = 'stylesheet'; + public const REL_NEXT = 'next'; + public const REL_PREV = 'prev'; + + // Relation defined in https://www.w3.org/TR/preload/ + public const REL_PRELOAD = 'preload'; + + // Relations defined in https://www.w3.org/TR/resource-hints/ + public const REL_DNS_PREFETCH = 'dns-prefetch'; + public const REL_PRECONNECT = 'preconnect'; + public const REL_PREFETCH = 'prefetch'; + public const REL_PRERENDER = 'prerender'; + + // Extra relations + public const REL_MERCURE = 'mercure'; + + private $href = ''; + + /** + * @var string[] + */ + private $rel = []; + + /** + * @var string[] + */ + private $attributes = []; + + public function __construct(string $rel = null, string $href = '') + { + if (null !== $rel) { + $this->rel[$rel] = $rel; + } + $this->href = $href; + } + + /** + * {@inheritdoc} + */ + public function getHref(): string + { + return $this->href; + } + + /** + * {@inheritdoc} + */ + public function isTemplated(): bool + { + return $this->hrefIsTemplated($this->href); + } + + /** + * {@inheritdoc} + */ + public function getRels(): array + { + return array_values($this->rel); + } + + /** + * {@inheritdoc} + */ + public function getAttributes(): array + { + return $this->attributes; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withHref($href) + { + $that = clone $this; + $that->href = $href; + $that->templated = $this->hrefIsTemplated($href); + + return $that; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withRel($rel) + { + $that = clone $this; + $that->rel[$rel] = $rel; + + return $that; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withoutRel($rel) + { + $that = clone $this; + unset($that->rel[$rel]); + + return $that; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withAttribute($attribute, $value) + { + $that = clone $this; + $that->attributes[$attribute] = $value; + + return $that; + } + + /** + * {@inheritdoc} + * + * @return static + */ + public function withoutAttribute($attribute) + { + $that = clone $this; + unset($that->attributes[$attribute]); + + return $that; + } + + private function hrefIsTemplated(string $href): bool + { + return false !== strpos($href, '{') || false !== strpos($href, '}'); + } +} diff --git a/Libraries/symfony/web-link/README.md b/Libraries/symfony/web-link/README.md new file mode 100644 index 0000000..d246e50 --- /dev/null +++ b/Libraries/symfony/web-link/README.md @@ -0,0 +1,18 @@ +WebLink Component +================= + +The WebLink component manages links between resources. It is particularly useful to advise clients +to preload and prefetch documents through HTTP and HTTP/2 pushes. + +This component implements the [HTML5's Links](https://www.w3.org/TR/html5/links.html), [Preload](https://www.w3.org/TR/preload/) +and [Resource Hints](https://www.w3.org/TR/resource-hints/) W3C's specifications. +It can also be used with extensions defined in the [HTML5 link type extensions wiki](http://microformats.org/wiki/existing-rel-values#HTML5_link_type_extensions). + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/web_link.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/Libraries/symfony/web-link/composer.json b/Libraries/symfony/web-link/composer.json new file mode 100644 index 0000000..87eccfb --- /dev/null +++ b/Libraries/symfony/web-link/composer.json @@ -0,0 +1,48 @@ +{ + "name": "symfony/web-link", + "type": "library", + "description": "Symfony WebLink Component", + "keywords": ["link", "psr13", "http", "http2", "preload", "prefetch", "prerender", "dns-prefetch", "push", "performance"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "provide": { + "psr/link-implementation": "1.0" + }, + "require": { + "php": "^7.1.3", + "psr/link": "^1.0", + "symfony/polyfill-php72": "^1.5" + }, + "suggest": { + "symfony/http-kernel": "" + }, + "require-dev": { + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.3|^5.0" + }, + "conflict": { + "symfony/http-kernel": "<4.3" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\WebLink\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + } +} diff --git a/ext_localconf.php b/ext_localconf.php index 26ef00d..fc03c5f 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,5 +1,10 @@ registerImplementation(\Ssch\Typo3Encore\Asset\VersionStrategyInterface::class, Ssch\Typo3Encore\Asset\JsonManifestVersionStrategy::class); + \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\Container\Container::class)->registerImplementation( + \Ssch\Typo3Encore\Asset\VersionStrategyInterface::class, + Ssch\Typo3Encore\Asset\JsonManifestVersionStrategy::class + ); // Enable for Frontend and Backend at the same time $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess'][$packageKey] = \Ssch\Typo3Encore\Integration\PageRendererHooks::class . '->renderPreProcess';