-
$info ) {
- printf( '', esc_html( $id ), selected( $id, get_term_meta( $tag->term_id, '_ss_header', true ), false), esc_html( $info['name'] ) );
+ printf( '', esc_html( $id ), selected( $id, get_term_meta( $tag->term_id, '_ss_header', true ), false ), esc_html( $info['name'] ) );
}
?>
@@ -26,7 +26,7 @@
$info ) {
- printf( '', esc_html( $id ), selected( $id, get_term_meta( $tag->term_id, '_ss_sidebar', true ), false), esc_html( $info['name'] ) );
+ printf( '', esc_html( $id ), selected( $id, get_term_meta( $tag->term_id, '_ss_sidebar', true ), false ), esc_html( $info['name'] ) );
}
?>
@@ -41,7 +41,7 @@
$info ) {
- printf( '', esc_html( $id ), selected( $id, get_term_meta( $tag->term_id, '_ss_sidebar_alt', true ) , false), esc_html( $info['name'] ) );
+ printf( '', esc_html( $id ), selected( $id, get_term_meta( $tag->term_id, '_ss_sidebar_alt', true ), false ), esc_html( $info['name'] ) );
}
?>
diff --git a/plugin.php b/plugin.php
index a3c3cb8..29fee8c 100644
--- a/plugin.php
+++ b/plugin.php
@@ -1,20 +1,16 @@
+ * 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/vendor/composer/LICENSE b/vendor/composer/LICENSE
new file mode 100644
index 0000000..f27399a
--- /dev/null
+++ b/vendor/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/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..7a91153
--- /dev/null
+++ b/vendor/composer/autoload_classmap.php
@@ -0,0 +1,9 @@
+ array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'),
+ 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
+);
diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..4ec682d
--- /dev/null
+++ b/vendor/composer/autoload_real.php
@@ -0,0 +1,52 @@
+= 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\ComposerStaticInit38f89291455175ece97b2e2261f1b531::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);
+
+ return $loader;
+ }
+}
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..674baf3
--- /dev/null
+++ b/vendor/composer/autoload_static.php
@@ -0,0 +1,39 @@
+
+ array (
+ 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => 55,
+ ),
+ 'C' =>
+ array (
+ 'Composer\\Installers\\' => 20,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/dealerdirect/phpcodesniffer-composer-installer/src',
+ ),
+ 'Composer\\Installers\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
+ ),
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInit38f89291455175ece97b2e2261f1b531::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInit38f89291455175ece97b2e2261f1b531::$prefixDirsPsr4;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
new file mode 100644
index 0000000..9adbbb6
--- /dev/null
+++ b/vendor/composer/installed.json
@@ -0,0 +1,454 @@
+[
+ {
+ "name": "composer/installers",
+ "version": "v1.6.0",
+ "version_normalized": "1.6.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/installers.git",
+ "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/installers/zipball/cfcca6b1b60bc4974324efb5783c13dca6932b5b",
+ "reference": "cfcca6b1b60bc4974324efb5783c13dca6932b5b",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "replace": {
+ "roundcube/plugin-installer": "*",
+ "shama/baton": "*"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev",
+ "phpunit/phpunit": "^4.8.36"
+ },
+ "time": "2018-08-27T06:10:37+00:00",
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Composer\\Installers\\": "src/Composer/Installers"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "description": "A multi-framework Composer library installer",
+ "homepage": "https://composer.github.io/installers/",
+ "keywords": [
+ "Craft",
+ "Dolibarr",
+ "Eliasis",
+ "Hurad",
+ "ImageCMS",
+ "Kanboard",
+ "Lan Management System",
+ "MODX Evo",
+ "Mautic",
+ "Maya",
+ "OXID",
+ "Plentymarkets",
+ "Porto",
+ "RadPHP",
+ "SMF",
+ "Thelia",
+ "WolfCMS",
+ "agl",
+ "aimeos",
+ "annotatecms",
+ "attogram",
+ "bitrix",
+ "cakephp",
+ "chef",
+ "cockpit",
+ "codeigniter",
+ "concrete5",
+ "croogo",
+ "dokuwiki",
+ "drupal",
+ "eZ Platform",
+ "elgg",
+ "expressionengine",
+ "fuelphp",
+ "grav",
+ "installer",
+ "itop",
+ "joomla",
+ "kohana",
+ "laravel",
+ "lavalite",
+ "lithium",
+ "magento",
+ "majima",
+ "mako",
+ "mediawiki",
+ "modulework",
+ "modx",
+ "moodle",
+ "osclass",
+ "phpbb",
+ "piwik",
+ "ppi",
+ "puppet",
+ "pxcms",
+ "reindex",
+ "roundcube",
+ "shopware",
+ "silverstripe",
+ "sydes",
+ "symfony",
+ "typo3",
+ "wordpress",
+ "yawik",
+ "zend",
+ "zikula"
+ ]
+ },
+ {
+ "name": "dealerdirect/phpcodesniffer-composer-installer",
+ "version": "v0.5.0",
+ "version_normalized": "0.5.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git",
+ "reference": "e749410375ff6fb7a040a68878c656c2e610b132"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132",
+ "reference": "e749410375ff6fb7a040a68878c656c2e610b132",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0",
+ "php": "^5.3|^7",
+ "squizlabs/php_codesniffer": "^2|^3"
+ },
+ "require-dev": {
+ "composer/composer": "*",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "sensiolabs/security-checker": "^4.1.0"
+ },
+ "time": "2018-10-26T13:21:45+00:00",
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Franck Nijhof",
+ "email": "franck.nijhof@dealerdirect.com",
+ "homepage": "http://www.frenck.nl",
+ "role": "Developer / IT Manager"
+ }
+ ],
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
+ "homepage": "http://www.dealerdirect.com",
+ "keywords": [
+ "PHPCodeSniffer",
+ "PHP_CodeSniffer",
+ "code quality",
+ "codesniffer",
+ "composer",
+ "installer",
+ "phpcs",
+ "plugin",
+ "qa",
+ "quality",
+ "standard",
+ "standards",
+ "style guide",
+ "stylecheck",
+ "tests"
+ ]
+ },
+ {
+ "name": "phpcompatibility/php-compatibility",
+ "version": "9.1.1",
+ "version_normalized": "9.1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
+ "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/2b63c5d284ab8857f7b1d5c240ddb507a6b2293c",
+ "reference": "2b63c5d284ab8857f7b1d5c240ddb507a6b2293c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3",
+ "squizlabs/php_codesniffer": "^2.3 || ^3.0.2"
+ },
+ "conflict": {
+ "squizlabs/php_codesniffer": "2.6.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "suggest": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "time": "2018-12-30T23:16:27+00:00",
+ "type": "phpcodesniffer-standard",
+ "installation-source": "dist",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
+ },
+ {
+ "name": "Wim Godden",
+ "homepage": "https://github.com/wimg",
+ "role": "lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "homepage": "https://github.com/jrfnl",
+ "role": "lead"
+ }
+ ],
+ "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
+ "homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
+ "keywords": [
+ "compatibility",
+ "phpcs",
+ "standards"
+ ]
+ },
+ {
+ "name": "phpcompatibility/phpcompatibility-paragonie",
+ "version": "1.0.1",
+ "version_normalized": "1.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git",
+ "reference": "9160de79fcd683b5c99e9c4133728d91529753ea"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/9160de79fcd683b5c99e9c4133728d91529753ea",
+ "reference": "9160de79fcd683b5c99e9c4133728d91529753ea",
+ "shasum": ""
+ },
+ "require": {
+ "phpcompatibility/php-compatibility": "^9.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4"
+ },
+ "suggest": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "time": "2018-12-16T19:10:44+00:00",
+ "type": "phpcodesniffer-standard",
+ "installation-source": "dist",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Wim Godden",
+ "role": "lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "role": "lead"
+ }
+ ],
+ "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
+ "homepage": "http://phpcompatibility.com/",
+ "keywords": [
+ "compatibility",
+ "paragonie",
+ "phpcs",
+ "polyfill",
+ "standards"
+ ]
+ },
+ {
+ "name": "phpcompatibility/phpcompatibility-wp",
+ "version": "2.0.0",
+ "version_normalized": "2.0.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git",
+ "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/cb303f0067cd5b366a41d4fb0e254fb40ff02efd",
+ "reference": "cb303f0067cd5b366a41d4fb0e254fb40ff02efd",
+ "shasum": ""
+ },
+ "require": {
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpcompatibility/phpcompatibility-paragonie": "^1.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
+ },
+ "suggest": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "time": "2018-10-07T18:31:37+00:00",
+ "type": "phpcodesniffer-standard",
+ "installation-source": "dist",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Wim Godden",
+ "role": "lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "role": "lead"
+ }
+ ],
+ "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
+ "homepage": "http://phpcompatibility.com/",
+ "keywords": [
+ "compatibility",
+ "phpcs",
+ "standards",
+ "wordpress"
+ ]
+ },
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.4.2",
+ "version_normalized": "3.4.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8",
+ "reference": "b8a7362af1cc1aadb5bd36c3defc4dda2cf5f0a8",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "time": "2019-04-10T23:49:02+00:00",
+ "bin": [
+ "bin/phpcs",
+ "bin/phpcbf"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "keywords": [
+ "phpcs",
+ "standards"
+ ]
+ },
+ {
+ "name": "wp-coding-standards/wpcs",
+ "version": "1.2.1",
+ "version_normalized": "1.2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git",
+ "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c",
+ "reference": "f328bcafd97377e8e5e5d7b244d5ddbf301a3a5c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3",
+ "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2"
+ },
+ "require-dev": {
+ "phpcompatibility/php-compatibility": "^9.0"
+ },
+ "suggest": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically."
+ },
+ "time": "2018-12-18T09:43:51+00:00",
+ "type": "phpcodesniffer-standard",
+ "installation-source": "dist",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors"
+ }
+ ],
+ "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions",
+ "keywords": [
+ "phpcs",
+ "standards",
+ "wordpress"
+ ]
+ }
+]
diff --git a/vendor/composer/installers/LICENSE b/vendor/composer/installers/LICENSE
new file mode 100644
index 0000000..85f97fc
--- /dev/null
+++ b/vendor/composer/installers/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2012 Kyle Robinson Young
+
+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.
\ No newline at end of file
diff --git a/vendor/composer/installers/composer.json b/vendor/composer/installers/composer.json
new file mode 100644
index 0000000..6de4085
--- /dev/null
+++ b/vendor/composer/installers/composer.json
@@ -0,0 +1,105 @@
+{
+ "name": "composer/installers",
+ "type": "composer-plugin",
+ "license": "MIT",
+ "description": "A multi-framework Composer library installer",
+ "keywords": [
+ "installer",
+ "Aimeos",
+ "AGL",
+ "AnnotateCms",
+ "Attogram",
+ "Bitrix",
+ "CakePHP",
+ "Chef",
+ "Cockpit",
+ "CodeIgniter",
+ "concrete5",
+ "Craft",
+ "Croogo",
+ "DokuWiki",
+ "Dolibarr",
+ "Drupal",
+ "Elgg",
+ "Eliasis",
+ "ExpressionEngine",
+ "eZ Platform",
+ "FuelPHP",
+ "Grav",
+ "Hurad",
+ "ImageCMS",
+ "iTop",
+ "Joomla",
+ "Kanboard",
+ "Kohana",
+ "Lan Management System",
+ "Laravel",
+ "Lavalite",
+ "Lithium",
+ "Magento",
+ "majima",
+ "Mako",
+ "Mautic",
+ "Maya",
+ "MODX",
+ "MODX Evo",
+ "MediaWiki",
+ "OXID",
+ "osclass",
+ "MODULEWork",
+ "Moodle",
+ "Piwik",
+ "pxcms",
+ "phpBB",
+ "Plentymarkets",
+ "PPI",
+ "Puppet",
+ "Porto",
+ "RadPHP",
+ "ReIndex",
+ "Roundcube",
+ "shopware",
+ "SilverStripe",
+ "SMF",
+ "SyDES",
+ "symfony",
+ "Thelia",
+ "TYPO3",
+ "WolfCMS",
+ "WordPress",
+ "YAWIK",
+ "Zend",
+ "Zikula"
+ ],
+ "homepage": "https://composer.github.io/installers/",
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "autoload": {
+ "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
+ },
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "replace": {
+ "shama/baton": "*",
+ "roundcube/plugin-installer": "*"
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev",
+ "phpunit/phpunit": "^4.8.36"
+ },
+ "scripts": {
+ "test": "phpunit"
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/vendor/composer/installers/src/Composer/Installers/AglInstaller.php
new file mode 100644
index 0000000..01b8a41
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AglInstaller.php
@@ -0,0 +1,21 @@
+ 'More/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) {
+ return strtoupper($matches[1]);
+ }, $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
new file mode 100644
index 0000000..79a0e95
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php
@@ -0,0 +1,9 @@
+ 'ext/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
new file mode 100644
index 0000000..89d7ad9
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php
@@ -0,0 +1,11 @@
+ 'addons/modules/{$name}/',
+ 'component' => 'addons/components/{$name}/',
+ 'service' => 'addons/services/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
new file mode 100644
index 0000000..22dad1b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php
@@ -0,0 +1,49 @@
+ 'Modules/{$name}/',
+ 'theme' => 'Themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type asgard-module, cut off a trailing '-plugin' if present.
+ *
+ * For package type asgard-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'asgard-module') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'asgard-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
new file mode 100644
index 0000000..d62fd8f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
new file mode 100644
index 0000000..7082bf2
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php
@@ -0,0 +1,136 @@
+composer = $composer;
+ $this->package = $package;
+ $this->io = $io;
+ }
+
+ /**
+ * Return the install path based on package type.
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ $type = $this->package->getType();
+
+ $prettyName = $this->package->getPrettyName();
+ if (strpos($prettyName, '/') !== false) {
+ list($vendor, $name) = explode('/', $prettyName);
+ } else {
+ $vendor = '';
+ $name = $prettyName;
+ }
+
+ $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));
+
+ $extra = $package->getExtra();
+ if (!empty($extra['installer-name'])) {
+ $availableVars['name'] = $extra['installer-name'];
+ }
+
+ if ($this->composer->getPackage()) {
+ $extra = $this->composer->getPackage()->getExtra();
+ if (!empty($extra['installer-paths'])) {
+ $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor);
+ if ($customPath !== false) {
+ return $this->templatePath($customPath, $availableVars);
+ }
+ }
+ }
+
+ $packageType = substr($type, strlen($frameworkType) + 1);
+ $locations = $this->getLocations();
+ if (!isset($locations[$packageType])) {
+ throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
+ }
+
+ return $this->templatePath($locations[$packageType], $availableVars);
+ }
+
+ /**
+ * For an installer to override to modify the vars per installer.
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ return $vars;
+ }
+
+ /**
+ * Gets the installer's locations
+ *
+ * @return array
+ */
+ public function getLocations()
+ {
+ return $this->locations;
+ }
+
+ /**
+ * Replace vars in a path
+ *
+ * @param string $path
+ * @param array $vars
+ * @return string
+ */
+ protected function templatePath($path, array $vars = array())
+ {
+ if (strpos($path, '{') !== false) {
+ extract($vars);
+ preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches);
+ if (!empty($matches[1])) {
+ foreach ($matches[1] as $var) {
+ $path = str_replace('{$' . $var . '}', $$var, $path);
+ }
+ }
+ }
+
+ return $path;
+ }
+
+ /**
+ * Search through a passed paths array for a custom install path.
+ *
+ * @param array $paths
+ * @param string $name
+ * @param string $type
+ * @param string $vendor = NULL
+ * @return string
+ */
+ protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL)
+ {
+ foreach ($paths as $path => $names) {
+ if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) {
+ return $path;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
new file mode 100644
index 0000000..e80cd1e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php
@@ -0,0 +1,126 @@
+.`.
+ * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`.
+ * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`.
+ *
+ * You can set custom path to directory with Bitrix kernel in `composer.json`:
+ *
+ * ```json
+ * {
+ * "extra": {
+ * "bitrix-dir": "s1/bitrix"
+ * }
+ * }
+ * ```
+ *
+ * @author Nik Samokhvalov
+ * @author Denis Kulichkin
+ */
+class BitrixInstaller extends BaseInstaller
+{
+ protected $locations = array(
+ 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken)
+ 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/',
+ 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/',
+ 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/',
+ );
+
+ /**
+ * @var array Storage for informations about duplicates at all the time of installation packages.
+ */
+ private static $checkedDuplicates = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($this->composer->getPackage()) {
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (isset($extra['bitrix-dir'])) {
+ $vars['bitrix_dir'] = $extra['bitrix-dir'];
+ }
+ }
+
+ if (!isset($vars['bitrix_dir'])) {
+ $vars['bitrix_dir'] = 'bitrix';
+ }
+
+ return parent::inflectPackageVars($vars);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function templatePath($path, array $vars = array())
+ {
+ $templatePath = parent::templatePath($path, $vars);
+ $this->checkDuplicates($templatePath, $vars);
+
+ return $templatePath;
+ }
+
+ /**
+ * Duplicates search packages.
+ *
+ * @param string $path
+ * @param array $vars
+ */
+ protected function checkDuplicates($path, array $vars = array())
+ {
+ $packageType = substr($vars['type'], strlen('bitrix') + 1);
+ $localDir = explode('/', $vars['bitrix_dir']);
+ array_pop($localDir);
+ $localDir[] = 'local';
+ $localDir = implode('/', $localDir);
+
+ $oldPath = str_replace(
+ array('{$bitrix_dir}', '{$name}'),
+ array($localDir, $vars['name']),
+ $this->locations[$packageType]
+ );
+
+ if (in_array($oldPath, static::$checkedDuplicates)) {
+ return;
+ }
+
+ if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) {
+
+ $this->io->writeError(' Duplication of packages:');
+ $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . '');
+
+ while (true) {
+ switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) {
+ case 'y':
+ $fs = new Filesystem();
+ $fs->removeDirectory($oldPath);
+ break 2;
+
+ case 'n':
+ break 2;
+
+ case '?':
+ default:
+ $this->io->writeError(array(
+ ' y - delete package ' . $oldPath . ' and to continue with the installation',
+ ' n - don\'t delete and to continue with the installation',
+ ));
+ $this->io->writeError(' ? - print help');
+ break;
+ }
+ }
+ }
+
+ static::$checkedDuplicates[] = $oldPath;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
new file mode 100644
index 0000000..da3aad2
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php
@@ -0,0 +1,9 @@
+ 'Packages/{$vendor}/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
new file mode 100644
index 0000000..6352beb
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php
@@ -0,0 +1,82 @@
+ 'Plugin/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
+ return $vars;
+ }
+
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+
+ return $vars;
+ }
+
+ /**
+ * Change the default plugin location when cakephp >= 3.0
+ */
+ public function getLocations()
+ {
+ if ($this->matchesCakeVersion('>=', '3.0.0')) {
+ $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/';
+ }
+ return $this->locations;
+ }
+
+ /**
+ * Check if CakePHP version matches against a version
+ *
+ * @param string $matcher
+ * @param string $version
+ * @return bool
+ */
+ protected function matchesCakeVersion($matcher, $version)
+ {
+ if (class_exists('Composer\Semver\Constraint\MultiConstraint')) {
+ $multiClass = 'Composer\Semver\Constraint\MultiConstraint';
+ $constraintClass = 'Composer\Semver\Constraint\Constraint';
+ } else {
+ $multiClass = 'Composer\Package\LinkConstraint\MultiConstraint';
+ $constraintClass = 'Composer\Package\LinkConstraint\VersionConstraint';
+ }
+
+ $repositoryManager = $this->composer->getRepositoryManager();
+ if ($repositoryManager) {
+ $repos = $repositoryManager->getLocalRepository();
+ if (!$repos) {
+ return false;
+ }
+ $cake3 = new $multiClass(array(
+ new $constraintClass($matcher, $version),
+ new $constraintClass('!=', '9999999-dev'),
+ ));
+ $pool = new Pool('dev');
+ $pool->addRepository($repos);
+ $packages = $pool->whatProvides('cakephp/cakephp');
+ foreach ($packages as $package) {
+ $installed = new $constraintClass('=', $package->getVersion());
+ if ($cake3->matches($installed)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
new file mode 100644
index 0000000..ab2f9aa
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php
@@ -0,0 +1,11 @@
+ 'Chef/{$vendor}/{$name}/',
+ 'role' => 'Chef/roles/{$name}/',
+ );
+}
+
diff --git a/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
new file mode 100644
index 0000000..6673aea
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php
@@ -0,0 +1,9 @@
+ 'ext/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
new file mode 100644
index 0000000..c887815
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php
@@ -0,0 +1,10 @@
+ 'CCF/orbit/{$name}/',
+ 'theme' => 'CCF/app/themes/{$name}/',
+ );
+}
\ No newline at end of file
diff --git a/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
new file mode 100644
index 0000000..c7816df
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php
@@ -0,0 +1,34 @@
+ 'cockpit/modules/addons/{$name}/',
+ );
+
+ /**
+ * Format module name.
+ *
+ * Strip `module-` prefix from package name.
+ *
+ * @param array @vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'cockpit-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ return $vars;
+ }
+
+ public function inflectModuleVars($vars)
+ {
+ $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
new file mode 100644
index 0000000..3b4a4ec
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php
@@ -0,0 +1,11 @@
+ 'application/libraries/{$name}/',
+ 'third-party' => 'application/third_party/{$name}/',
+ 'module' => 'application/modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
new file mode 100644
index 0000000..5c01baf
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php
@@ -0,0 +1,13 @@
+ 'concrete/',
+ 'block' => 'application/blocks/{$name}/',
+ 'package' => 'packages/{$name}/',
+ 'theme' => 'application/themes/{$name}/',
+ 'update' => 'updates/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
new file mode 100644
index 0000000..d37a77a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php
@@ -0,0 +1,35 @@
+ 'craft/plugins/{$name}/',
+ );
+
+ /**
+ * Strip `craft-` prefix and/or `-plugin` suffix from package names
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ final public function inflectPackageVars($vars)
+ {
+ return $this->inflectPluginVars($vars);
+ }
+
+ private function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']);
+ $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
new file mode 100644
index 0000000..d94219d
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php
@@ -0,0 +1,21 @@
+ 'Plugin/{$name}/',
+ 'theme' => 'View/Themed/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name']));
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
new file mode 100644
index 0000000..f4837a6
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php
@@ -0,0 +1,10 @@
+ 'app/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
new file mode 100644
index 0000000..cfd638d
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php
@@ -0,0 +1,50 @@
+ 'lib/plugins/{$name}/',
+ 'template' => 'lib/tpl/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type dokuwiki-plugin, cut off a trailing '-plugin',
+ * or leading dokuwiki_ if present.
+ *
+ * For package type dokuwiki-template, cut off a trailing '-template' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] === 'dokuwiki-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'dokuwiki-template') {
+ return $this->inflectTemplateVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectTemplateVars($vars)
+ {
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']);
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
new file mode 100644
index 0000000..21f7e8e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php
@@ -0,0 +1,16 @@
+
+ */
+class DolibarrInstaller extends BaseInstaller
+{
+ //TODO: Add support for scripts and themes
+ protected $locations = array(
+ 'module' => 'htdocs/custom/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
new file mode 100644
index 0000000..fef7c52
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php
@@ -0,0 +1,16 @@
+ 'core/',
+ 'module' => 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ 'profile' => 'profiles/{$name}/',
+ 'drush' => 'drush/{$name}/',
+ 'custom-theme' => 'themes/custom/{$name}/',
+ 'custom-module' => 'modules/custom/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
new file mode 100644
index 0000000..c0bb609
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php
@@ -0,0 +1,9 @@
+ 'mod/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
new file mode 100644
index 0000000..6f3dc97
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php
@@ -0,0 +1,12 @@
+ 'components/{$name}/',
+ 'module' => 'modules/{$name}/',
+ 'plugin' => 'plugins/{$name}/',
+ 'template' => 'templates/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
new file mode 100644
index 0000000..d5321a8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php
@@ -0,0 +1,29 @@
+ 'system/expressionengine/third_party/{$name}/',
+ 'theme' => 'themes/third_party/{$name}/',
+ );
+
+ private $ee3Locations = array(
+ 'addon' => 'system/user/addons/{$name}/',
+ 'theme' => 'themes/user/{$name}/',
+ );
+
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+
+ $version = "{$frameworkType}Locations";
+ $this->locations = $this->$version;
+
+ return parent::getInstallPath($package, $frameworkType);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
new file mode 100644
index 0000000..f30ebcc
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php
@@ -0,0 +1,10 @@
+ 'web/assets/ezplatform/',
+ 'assets' => 'web/assets/ezplatform/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
new file mode 100644
index 0000000..6eba2e3
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php
@@ -0,0 +1,11 @@
+ 'fuel/app/modules/{$name}/',
+ 'package' => 'fuel/packages/{$name}/',
+ 'theme' => 'fuel/app/themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
new file mode 100644
index 0000000..29d980b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php
@@ -0,0 +1,9 @@
+ 'components/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/vendor/composer/installers/src/Composer/Installers/GravInstaller.php
new file mode 100644
index 0000000..dbe63e0
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/GravInstaller.php
@@ -0,0 +1,30 @@
+ 'user/plugins/{$name}/',
+ 'theme' => 'user/themes/{$name}/',
+ );
+
+ /**
+ * Format package name
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $restrictedWords = implode('|', array_keys($this->locations));
+
+ $vars['name'] = strtolower($vars['name']);
+ $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui',
+ '$1',
+ $vars['name']
+ );
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
new file mode 100644
index 0000000..8fe017f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php
@@ -0,0 +1,25 @@
+ 'plugins/{$name}/',
+ 'theme' => 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
new file mode 100644
index 0000000..5e2142e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php
@@ -0,0 +1,11 @@
+ 'templates/{$name}/',
+ 'module' => 'application/modules/{$name}/',
+ 'library' => 'application/libraries/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Installer.php b/vendor/composer/installers/src/Composer/Installers/Installer.php
new file mode 100644
index 0000000..352cb7f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Installer.php
@@ -0,0 +1,274 @@
+ 'AimeosInstaller',
+ 'asgard' => 'AsgardInstaller',
+ 'attogram' => 'AttogramInstaller',
+ 'agl' => 'AglInstaller',
+ 'annotatecms' => 'AnnotateCmsInstaller',
+ 'bitrix' => 'BitrixInstaller',
+ 'bonefish' => 'BonefishInstaller',
+ 'cakephp' => 'CakePHPInstaller',
+ 'chef' => 'ChefInstaller',
+ 'civicrm' => 'CiviCrmInstaller',
+ 'ccframework' => 'ClanCatsFrameworkInstaller',
+ 'cockpit' => 'CockpitInstaller',
+ 'codeigniter' => 'CodeIgniterInstaller',
+ 'concrete5' => 'Concrete5Installer',
+ 'craft' => 'CraftInstaller',
+ 'croogo' => 'CroogoInstaller',
+ 'dokuwiki' => 'DokuWikiInstaller',
+ 'dolibarr' => 'DolibarrInstaller',
+ 'decibel' => 'DecibelInstaller',
+ 'drupal' => 'DrupalInstaller',
+ 'elgg' => 'ElggInstaller',
+ 'eliasis' => 'EliasisInstaller',
+ 'ee3' => 'ExpressionEngineInstaller',
+ 'ee2' => 'ExpressionEngineInstaller',
+ 'ezplatform' => 'EzPlatformInstaller',
+ 'fuel' => 'FuelInstaller',
+ 'fuelphp' => 'FuelphpInstaller',
+ 'grav' => 'GravInstaller',
+ 'hurad' => 'HuradInstaller',
+ 'imagecms' => 'ImageCMSInstaller',
+ 'itop' => 'ItopInstaller',
+ 'joomla' => 'JoomlaInstaller',
+ 'kanboard' => 'KanboardInstaller',
+ 'kirby' => 'KirbyInstaller',
+ 'kodicms' => 'KodiCMSInstaller',
+ 'kohana' => 'KohanaInstaller',
+ 'lms' => 'LanManagementSystemInstaller',
+ 'laravel' => 'LaravelInstaller',
+ 'lavalite' => 'LavaLiteInstaller',
+ 'lithium' => 'LithiumInstaller',
+ 'magento' => 'MagentoInstaller',
+ 'majima' => 'MajimaInstaller',
+ 'mako' => 'MakoInstaller',
+ 'maya' => 'MayaInstaller',
+ 'mautic' => 'MauticInstaller',
+ 'mediawiki' => 'MediaWikiInstaller',
+ 'microweber' => 'MicroweberInstaller',
+ 'modulework' => 'MODULEWorkInstaller',
+ 'modx' => 'ModxInstaller',
+ 'modxevo' => 'MODXEvoInstaller',
+ 'moodle' => 'MoodleInstaller',
+ 'october' => 'OctoberInstaller',
+ 'ontowiki' => 'OntoWikiInstaller',
+ 'oxid' => 'OxidInstaller',
+ 'osclass' => 'OsclassInstaller',
+ 'pxcms' => 'PxcmsInstaller',
+ 'phpbb' => 'PhpBBInstaller',
+ 'pimcore' => 'PimcoreInstaller',
+ 'piwik' => 'PiwikInstaller',
+ 'plentymarkets'=> 'PlentymarketsInstaller',
+ 'ppi' => 'PPIInstaller',
+ 'puppet' => 'PuppetInstaller',
+ 'radphp' => 'RadPHPInstaller',
+ 'phifty' => 'PhiftyInstaller',
+ 'porto' => 'PortoInstaller',
+ 'redaxo' => 'RedaxoInstaller',
+ 'reindex' => 'ReIndexInstaller',
+ 'roundcube' => 'RoundcubeInstaller',
+ 'shopware' => 'ShopwareInstaller',
+ 'sitedirect' => 'SiteDirectInstaller',
+ 'silverstripe' => 'SilverStripeInstaller',
+ 'smf' => 'SMFInstaller',
+ 'sydes' => 'SyDESInstaller',
+ 'symfony1' => 'Symfony1Installer',
+ 'thelia' => 'TheliaInstaller',
+ 'tusk' => 'TuskInstaller',
+ 'typo3-cms' => 'TYPO3CmsInstaller',
+ 'typo3-flow' => 'TYPO3FlowInstaller',
+ 'userfrosting' => 'UserFrostingInstaller',
+ 'vanilla' => 'VanillaInstaller',
+ 'whmcs' => 'WHMCSInstaller',
+ 'wolfcms' => 'WolfCMSInstaller',
+ 'wordpress' => 'WordPressInstaller',
+ 'yawik' => 'YawikInstaller',
+ 'zend' => 'ZendInstaller',
+ 'zikula' => 'ZikulaInstaller',
+ 'prestashop' => 'PrestashopInstaller'
+ );
+
+ /**
+ * Installer constructor.
+ *
+ * Disables installers specified in main composer extra installer-disable
+ * list
+ *
+ * @param IOInterface $io
+ * @param Composer $composer
+ * @param string $type
+ * @param Filesystem|null $filesystem
+ * @param BinaryInstaller|null $binaryInstaller
+ */
+ public function __construct(
+ IOInterface $io,
+ Composer $composer,
+ $type = 'library',
+ Filesystem $filesystem = null,
+ BinaryInstaller $binaryInstaller = null
+ ) {
+ parent::__construct($io, $composer, $type, $filesystem,
+ $binaryInstaller);
+ $this->removeDisabledInstallers();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getInstallPath(PackageInterface $package)
+ {
+ $type = $package->getType();
+ $frameworkType = $this->findFrameworkType($type);
+
+ if ($frameworkType === false) {
+ throw new \InvalidArgumentException(
+ 'Sorry the package type of this package is not yet supported.'
+ );
+ }
+
+ $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
+ $installer = new $class($package, $this->composer, $this->getIO());
+
+ return $installer->getInstallPath($package, $frameworkType);
+ }
+
+ public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package)
+ {
+ parent::uninstall($repo, $package);
+ $installPath = $this->getPackageBasePath($package);
+ $this->io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted'));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function supports($packageType)
+ {
+ $frameworkType = $this->findFrameworkType($packageType);
+
+ if ($frameworkType === false) {
+ return false;
+ }
+
+ $locationPattern = $this->getLocationPattern($frameworkType);
+
+ return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1;
+ }
+
+ /**
+ * Finds a supported framework type if it exists and returns it
+ *
+ * @param string $type
+ * @return string
+ */
+ protected function findFrameworkType($type)
+ {
+ $frameworkType = false;
+
+ krsort($this->supportedTypes);
+
+ foreach ($this->supportedTypes as $key => $val) {
+ if ($key === substr($type, 0, strlen($key))) {
+ $frameworkType = substr($type, 0, strlen($key));
+ break;
+ }
+ }
+
+ return $frameworkType;
+ }
+
+ /**
+ * Get the second part of the regular expression to check for support of a
+ * package type
+ *
+ * @param string $frameworkType
+ * @return string
+ */
+ protected function getLocationPattern($frameworkType)
+ {
+ $pattern = false;
+ if (!empty($this->supportedTypes[$frameworkType])) {
+ $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType];
+ /** @var BaseInstaller $framework */
+ $framework = new $frameworkClass(null, $this->composer, $this->getIO());
+ $locations = array_keys($framework->getLocations());
+ $pattern = $locations ? '(' . implode('|', $locations) . ')' : false;
+ }
+
+ return $pattern ? : '(\w+)';
+ }
+
+ /**
+ * Get I/O object
+ *
+ * @return IOInterface
+ */
+ private function getIO()
+ {
+ return $this->io;
+ }
+
+ /**
+ * Look for installers set to be disabled in composer's extra config and
+ * remove them from the list of supported installers.
+ *
+ * Globals:
+ * - true, "all", and "*" - disable all installers.
+ * - false - enable all installers (useful with
+ * wikimedia/composer-merge-plugin or similar)
+ *
+ * @return void
+ */
+ protected function removeDisabledInstallers()
+ {
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) {
+ // No installers are disabled
+ return;
+ }
+
+ // Get installers to disable
+ $disable = $extra['installer-disable'];
+
+ // Ensure $disabled is an array
+ if (!is_array($disable)) {
+ $disable = array($disable);
+ }
+
+ // Check which installers should be disabled
+ $all = array(true, "all", "*");
+ $intersect = array_intersect($all, $disable);
+ if (!empty($intersect)) {
+ // Disable all installers
+ $this->supportedTypes = array();
+ } else {
+ // Disable specified installers
+ foreach ($disable as $key => $installer) {
+ if (is_string($installer) && key_exists($installer, $this->supportedTypes)) {
+ unset($this->supportedTypes[$installer]);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
new file mode 100644
index 0000000..c6c1b33
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php
@@ -0,0 +1,9 @@
+ 'extensions/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
new file mode 100644
index 0000000..9ee7759
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php
@@ -0,0 +1,15 @@
+ 'components/{$name}/',
+ 'module' => 'modules/{$name}/',
+ 'template' => 'templates/{$name}/',
+ 'plugin' => 'plugins/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ );
+
+ // TODO: Add inflector for mod_ and com_ names
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
new file mode 100644
index 0000000..9cb7b8c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php
@@ -0,0 +1,18 @@
+ 'plugins/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
new file mode 100644
index 0000000..36b2f84
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php
@@ -0,0 +1,11 @@
+ 'site/plugins/{$name}/',
+ 'field' => 'site/fields/{$name}/',
+ 'tag' => 'site/tags/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
new file mode 100644
index 0000000..7143e23
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php
@@ -0,0 +1,10 @@
+ 'cms/plugins/{$name}/',
+ 'media' => 'cms/media/vendor/{$name}/'
+ );
+}
\ No newline at end of file
diff --git a/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
new file mode 100644
index 0000000..dcd6d26
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
new file mode 100644
index 0000000..903143a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php
@@ -0,0 +1,27 @@
+ 'plugins/{$name}/',
+ 'template' => 'templates/{$name}/',
+ 'document-template' => 'documents/templates/{$name}/',
+ 'userpanel-module' => 'userpanel/modules/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
new file mode 100644
index 0000000..be4d53a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php
@@ -0,0 +1,9 @@
+ 'libraries/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
new file mode 100644
index 0000000..412c0b5
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php
@@ -0,0 +1,10 @@
+ 'packages/{$vendor}/{$name}/',
+ 'theme' => 'public/themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
new file mode 100644
index 0000000..47bbd4c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php
@@ -0,0 +1,10 @@
+ 'libraries/{$name}/',
+ 'source' => 'libraries/_source/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
new file mode 100644
index 0000000..9c2e9fb
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
new file mode 100644
index 0000000..5a66460
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php
@@ -0,0 +1,16 @@
+ 'assets/snippets/{$name}/',
+ 'plugin' => 'assets/plugins/{$name}/',
+ 'module' => 'assets/modules/{$name}/',
+ 'template' => 'assets/templates/{$name}/',
+ 'lib' => 'assets/lib/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
new file mode 100644
index 0000000..cf18e94
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php
@@ -0,0 +1,11 @@
+ 'app/design/frontend/{$name}/',
+ 'skin' => 'skin/frontend/default/{$name}/',
+ 'library' => 'lib/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
new file mode 100644
index 0000000..e463756
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php
@@ -0,0 +1,37 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Transforms the names
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ return $this->correctPluginName($vars);
+ }
+
+ /**
+ * Change hyphenated names to camelcase
+ * @param array $vars
+ * @return array
+ */
+ private function correctPluginName($vars)
+ {
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+ $vars['name'] = ucfirst($camelCasedName);
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
new file mode 100644
index 0000000..ca3cfac
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php
@@ -0,0 +1,9 @@
+ 'app/packages/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
new file mode 100644
index 0000000..3e1ce2b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php
@@ -0,0 +1,25 @@
+ 'plugins/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name of mautic-plugins to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'mautic-plugin') {
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, ucfirst($vars['name']));
+ }
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
new file mode 100644
index 0000000..30a9167
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php
@@ -0,0 +1,33 @@
+ 'modules/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type maya-module, cut off a trailing '-module' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'maya-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
new file mode 100644
index 0000000..f5a8957
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php
@@ -0,0 +1,51 @@
+ 'core/',
+ 'extension' => 'extensions/{$name}/',
+ 'skin' => 'skins/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform
+ * to CamelCase keeping existing uppercase chars.
+ *
+ * For package type mediawiki-skin, cut off a trailing '-skin' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+
+ if ($vars['type'] === 'mediawiki-extension') {
+ return $this->inflectExtensionVars($vars);
+ }
+
+ if ($vars['type'] === 'mediawiki-skin') {
+ return $this->inflectSkinVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectExtensionVars($vars)
+ {
+ $vars['name'] = preg_replace('/-extension$/', '', $vars['name']);
+ $vars['name'] = str_replace('-', ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectSkinVars($vars)
+ {
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
new file mode 100644
index 0000000..4bbbec8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php
@@ -0,0 +1,111 @@
+ 'userfiles/modules/{$name}/',
+ 'module-skin' => 'userfiles/modules/{$name}/templates/',
+ 'template' => 'userfiles/templates/{$name}/',
+ 'element' => 'userfiles/elements/{$name}/',
+ 'vendor' => 'vendor/{$name}/',
+ 'components' => 'components/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type microweber-module, cut off a trailing '-module' if present
+ *
+ * For package type microweber-template, cut off a trailing '-template' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'microweber-template') {
+ return $this->inflectTemplateVars($vars);
+ }
+ if ($vars['type'] === 'microweber-templates') {
+ return $this->inflectTemplatesVars($vars);
+ }
+ if ($vars['type'] === 'microweber-core') {
+ return $this->inflectCoreVars($vars);
+ }
+ if ($vars['type'] === 'microweber-adapter') {
+ return $this->inflectCoreVars($vars);
+ }
+ if ($vars['type'] === 'microweber-module') {
+ return $this->inflectModuleVars($vars);
+ }
+ if ($vars['type'] === 'microweber-modules') {
+ return $this->inflectModulesVars($vars);
+ }
+ if ($vars['type'] === 'microweber-skin') {
+ return $this->inflectSkinVars($vars);
+ }
+ if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') {
+ return $this->inflectElementVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectTemplateVars($vars)
+ {
+ $vars['name'] = preg_replace('/-template$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/template-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectTemplatesVars($vars)
+ {
+ $vars['name'] = preg_replace('/-templates$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/templates-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectCoreVars($vars)
+ {
+ $vars['name'] = preg_replace('/-providers$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-provider$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-adapter$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/module-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectModulesVars($vars)
+ {
+ $vars['name'] = preg_replace('/-modules$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/modules-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectSkinVars($vars)
+ {
+ $vars['name'] = preg_replace('/-skin$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/skin-$/', '', $vars['name']);
+
+ return $vars;
+ }
+
+ protected function inflectElementVars($vars)
+ {
+ $vars['name'] = preg_replace('/-elements$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/elements-$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-element$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/element-$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
new file mode 100644
index 0000000..0ee140a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php
@@ -0,0 +1,12 @@
+ 'core/packages/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
new file mode 100644
index 0000000..a89c82f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php
@@ -0,0 +1,57 @@
+ 'mod/{$name}/',
+ 'admin_report' => 'admin/report/{$name}/',
+ 'atto' => 'lib/editor/atto/plugins/{$name}/',
+ 'tool' => 'admin/tool/{$name}/',
+ 'assignment' => 'mod/assignment/type/{$name}/',
+ 'assignsubmission' => 'mod/assign/submission/{$name}/',
+ 'assignfeedback' => 'mod/assign/feedback/{$name}/',
+ 'auth' => 'auth/{$name}/',
+ 'availability' => 'availability/condition/{$name}/',
+ 'block' => 'blocks/{$name}/',
+ 'booktool' => 'mod/book/tool/{$name}/',
+ 'cachestore' => 'cache/stores/{$name}/',
+ 'cachelock' => 'cache/locks/{$name}/',
+ 'calendartype' => 'calendar/type/{$name}/',
+ 'format' => 'course/format/{$name}/',
+ 'coursereport' => 'course/report/{$name}/',
+ 'datafield' => 'mod/data/field/{$name}/',
+ 'datapreset' => 'mod/data/preset/{$name}/',
+ 'editor' => 'lib/editor/{$name}/',
+ 'enrol' => 'enrol/{$name}/',
+ 'filter' => 'filter/{$name}/',
+ 'gradeexport' => 'grade/export/{$name}/',
+ 'gradeimport' => 'grade/import/{$name}/',
+ 'gradereport' => 'grade/report/{$name}/',
+ 'gradingform' => 'grade/grading/form/{$name}/',
+ 'local' => 'local/{$name}/',
+ 'logstore' => 'admin/tool/log/store/{$name}/',
+ 'ltisource' => 'mod/lti/source/{$name}/',
+ 'ltiservice' => 'mod/lti/service/{$name}/',
+ 'message' => 'message/output/{$name}/',
+ 'mnetservice' => 'mnet/service/{$name}/',
+ 'plagiarism' => 'plagiarism/{$name}/',
+ 'portfolio' => 'portfolio/{$name}/',
+ 'qbehaviour' => 'question/behaviour/{$name}/',
+ 'qformat' => 'question/format/{$name}/',
+ 'qtype' => 'question/type/{$name}/',
+ 'quizaccess' => 'mod/quiz/accessrule/{$name}/',
+ 'quiz' => 'mod/quiz/report/{$name}/',
+ 'report' => 'report/{$name}/',
+ 'repository' => 'repository/{$name}/',
+ 'scormreport' => 'mod/scorm/report/{$name}/',
+ 'search' => 'search/engine/{$name}/',
+ 'theme' => 'theme/{$name}/',
+ 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
+ 'profilefield' => 'user/profile/field/{$name}/',
+ 'webservice' => 'webservice/{$name}/',
+ 'workshopallocation' => 'mod/workshop/allocation/{$name}/',
+ 'workshopeval' => 'mod/workshop/eval/{$name}/',
+ 'workshopform' => 'mod/workshop/form/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
new file mode 100644
index 0000000..08d5dc4
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php
@@ -0,0 +1,47 @@
+ 'modules/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type october-plugin, cut off a trailing '-plugin' if present.
+ *
+ * For package type october-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'october-plugin') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'october-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']);
+ $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']);
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
new file mode 100644
index 0000000..5dd3438
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php
@@ -0,0 +1,24 @@
+ 'extensions/{$name}/',
+ 'theme' => 'extensions/themes/{$name}/',
+ 'translation' => 'extensions/translations/{$name}/',
+ );
+
+ /**
+ * Format package name to lower case and remove ".ontowiki" suffix
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower($vars['name']);
+ $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
new file mode 100644
index 0000000..3ca7954
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php
@@ -0,0 +1,14 @@
+ 'oc-content/plugins/{$name}/',
+ 'theme' => 'oc-content/themes/{$name}/',
+ 'language' => 'oc-content/languages/{$name}/',
+ );
+
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
new file mode 100644
index 0000000..49940ff
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php
@@ -0,0 +1,59 @@
+.+)\/.+/';
+
+ protected $locations = array(
+ 'module' => 'modules/{$name}/',
+ 'theme' => 'application/views/{$name}/',
+ 'out' => 'out/{$name}/',
+ );
+
+ /**
+ * getInstallPath
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return void
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ $installPath = parent::getInstallPath($package, $frameworkType);
+ $type = $this->package->getType();
+ if ($type === 'oxid-module') {
+ $this->prepareVendorDirectory($installPath);
+ }
+ return $installPath;
+ }
+
+ /**
+ * prepareVendorDirectory
+ *
+ * Makes sure there is a vendormetadata.php file inside
+ * the vendor folder if there is a vendor folder.
+ *
+ * @param string $installPath
+ * @return void
+ */
+ protected function prepareVendorDirectory($installPath)
+ {
+ $matches = '';
+ $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches);
+ if (!$hasVendorDirectory) {
+ return;
+ }
+
+ $vendorDirectory = $matches['vendor'];
+ $vendorPath = getcwd() . '/modules/' . $vendorDirectory;
+ if (!file_exists($vendorPath)) {
+ mkdir($vendorPath, 0755, true);
+ }
+
+ $vendorMetaDataPath = $vendorPath . '/vendormetadata.php';
+ touch($vendorMetaDataPath);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
new file mode 100644
index 0000000..170136f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php
@@ -0,0 +1,9 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
new file mode 100644
index 0000000..4e59a8a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php
@@ -0,0 +1,11 @@
+ 'bundles/{$name}/',
+ 'library' => 'libraries/{$name}/',
+ 'framework' => 'frameworks/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
new file mode 100644
index 0000000..deb2b77
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php
@@ -0,0 +1,11 @@
+ 'ext/{$vendor}/{$name}/',
+ 'language' => 'language/{$name}/',
+ 'style' => 'styles/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
new file mode 100644
index 0000000..4781fa6
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php
@@ -0,0 +1,21 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
new file mode 100644
index 0000000..c17f457
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php
@@ -0,0 +1,32 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
new file mode 100644
index 0000000..903e55f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php
@@ -0,0 +1,29 @@
+ '{$name}/'
+ );
+
+ /**
+ * Remove hyphen, "plugin" and format to camelcase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = explode("-", $vars['name']);
+ foreach ($vars['name'] as $key => $name) {
+ $vars['name'][$key] = ucfirst($vars['name'][$key]);
+ if (strcasecmp($name, "Plugin") == 0) {
+ unset($vars['name'][$key]);
+ }
+ }
+ $vars['name'] = implode("",$vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Plugin.php b/vendor/composer/installers/src/Composer/Installers/Plugin.php
new file mode 100644
index 0000000..5eb04af
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Plugin.php
@@ -0,0 +1,17 @@
+getInstallationManager()->addInstaller($installer);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
new file mode 100644
index 0000000..dbf85e6
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php
@@ -0,0 +1,9 @@
+ 'app/Containers/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
new file mode 100644
index 0000000..4c8421e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
new file mode 100644
index 0000000..77cc3dd
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php
@@ -0,0 +1,11 @@
+ 'modules/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
new file mode 100644
index 0000000..6551058
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php
@@ -0,0 +1,63 @@
+ 'app/Modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format package name.
+ *
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'pxcms-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'pxcms-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ /**
+ * For package type pxcms-module, cut off a trailing '-plugin' if present.
+ *
+ * return string
+ */
+ protected function inflectModuleVars($vars)
+ {
+ $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
+ $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module-
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module
+ $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
+ $vars['name'] = ucwords($vars['name']); // make module name camelcased
+
+ return $vars;
+ }
+
+
+ /**
+ * For package type pxcms-module, cut off a trailing '-plugin' if present.
+ *
+ * return string
+ */
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy)
+ $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme-
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme
+ $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s
+ $vars['name'] = ucwords($vars['name']); // make module name camelcased
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
new file mode 100644
index 0000000..0f78b5c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php
@@ -0,0 +1,24 @@
+ 'src/{$name}/'
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $nameParts = explode('/', $vars['name']);
+ foreach ($nameParts as &$value) {
+ $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value));
+ $value = str_replace(array('-', '_'), ' ', $value);
+ $value = str_replace(' ', '', ucwords($value));
+ }
+ $vars['name'] = implode('/', $nameParts);
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
new file mode 100644
index 0000000..252c733
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php
@@ -0,0 +1,10 @@
+ 'themes/{$name}/',
+ 'plugin' => 'plugins/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
new file mode 100644
index 0000000..0954457
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php
@@ -0,0 +1,10 @@
+ 'redaxo/include/addons/{$name}/',
+ 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
new file mode 100644
index 0000000..d8d795b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php
@@ -0,0 +1,22 @@
+ 'plugins/{$name}/',
+ );
+
+ /**
+ * Lowercase name and changes the name to a underscores
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(str_replace('-', '_', $vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
new file mode 100644
index 0000000..1acd3b1
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php
@@ -0,0 +1,10 @@
+ 'Sources/{$name}/',
+ 'theme' => 'Themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
new file mode 100644
index 0000000..7d20d27
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php
@@ -0,0 +1,60 @@
+ 'engine/Shopware/Plugins/Local/Backend/{$name}/',
+ 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/',
+ 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/',
+ 'theme' => 'templates/{$name}/',
+ 'plugin' => 'custom/plugins/{$name}/',
+ 'frontend-theme' => 'themes/Frontend/{$name}/',
+ );
+
+ /**
+ * Transforms the names
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'shopware-theme') {
+ return $this->correctThemeName($vars);
+ }
+
+ return $this->correctPluginName($vars);
+ }
+
+ /**
+ * Changes the name to a camelcased combination of vendor and name
+ * @param array $vars
+ * @return array
+ */
+ private function correctPluginName($vars)
+ {
+ $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+
+ $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName);
+
+ return $vars;
+ }
+
+ /**
+ * Changes the name to a underscore separated name
+ * @param array $vars
+ * @return array
+ */
+ private function correctThemeName($vars)
+ {
+ $vars['name'] = str_replace('-', '_', $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
new file mode 100644
index 0000000..81910e9
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php
@@ -0,0 +1,35 @@
+ '{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Return the install path based on package type.
+ *
+ * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework
+ * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0
+ *
+ * @param PackageInterface $package
+ * @param string $frameworkType
+ * @return string
+ */
+ public function getInstallPath(PackageInterface $package, $frameworkType = '')
+ {
+ if (
+ $package->getName() == 'silverstripe/framework'
+ && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion())
+ && version_compare($package->getVersion(), '2.999.999') < 0
+ ) {
+ return $this->templatePath($this->locations['module'], array('name' => 'sapphire'));
+ }
+
+ return parent::getInstallPath($package, $frameworkType);
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
new file mode 100644
index 0000000..762d94c
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php
@@ -0,0 +1,25 @@
+ 'modules/{$vendor}/{$name}/',
+ 'plugin' => 'plugins/{$vendor}/{$name}/'
+ );
+
+ public function inflectPackageVars($vars)
+ {
+ return $this->parseVars($vars);
+ }
+
+ protected function parseVars($vars)
+ {
+ $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor'];
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
new file mode 100644
index 0000000..83ef9d0
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php
@@ -0,0 +1,49 @@
+ 'app/modules/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+
+ /**
+ * Format module name.
+ *
+ * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
+ *
+ * @param array @vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] == 'sydes-module') {
+ return $this->inflectModuleVars($vars);
+ }
+
+ if ($vars['type'] === 'sydes-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ public function inflectModuleVars($vars)
+ {
+ $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']);
+ $vars['name'] = strtolower($vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
new file mode 100644
index 0000000..1675c4f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php
@@ -0,0 +1,26 @@
+
+ */
+class Symfony1Installer extends BaseInstaller
+{
+ protected $locations = array(
+ 'plugin' => 'plugins/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) {
+ return strtoupper($matches[0][1]);
+ }, $vars['name']);
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
new file mode 100644
index 0000000..b1663e8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php
@@ -0,0 +1,16 @@
+
+ */
+class TYPO3CmsInstaller extends BaseInstaller
+{
+ protected $locations = array(
+ 'extension' => 'typo3conf/ext/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
new file mode 100644
index 0000000..42572f4
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php
@@ -0,0 +1,38 @@
+ 'Packages/Application/{$name}/',
+ 'framework' => 'Packages/Framework/{$name}/',
+ 'plugin' => 'Packages/Plugins/{$name}/',
+ 'site' => 'Packages/Sites/{$name}/',
+ 'boilerplate' => 'Packages/Boilerplates/{$name}/',
+ 'build' => 'Build/{$name}/',
+ );
+
+ /**
+ * Modify the package name to be a TYPO3 Flow style key.
+ *
+ * @param array $vars
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $autoload = $this->package->getAutoload();
+ if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) {
+ $namespace = key($autoload['psr-0']);
+ $vars['name'] = str_replace('\\', '.', $namespace);
+ }
+ if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) {
+ $namespace = key($autoload['psr-4']);
+ $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.');
+ }
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
new file mode 100644
index 0000000..158af52
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php
@@ -0,0 +1,12 @@
+ 'local/modules/{$name}/',
+ 'frontoffice-template' => 'templates/frontOffice/{$name}/',
+ 'backoffice-template' => 'templates/backOffice/{$name}/',
+ 'email-template' => 'templates/email/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
new file mode 100644
index 0000000..7c0113b
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php
@@ -0,0 +1,14 @@
+
+ */
+ class TuskInstaller extends BaseInstaller
+ {
+ protected $locations = array(
+ 'task' => '.tusk/tasks/{$name}/',
+ 'command' => '.tusk/commands/{$name}/',
+ 'asset' => 'assets/tusk/{$name}/',
+ );
+ }
diff --git a/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
new file mode 100644
index 0000000..fcb414a
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php
@@ -0,0 +1,9 @@
+ 'app/sprinkles/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
new file mode 100644
index 0000000..24ca645
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php
@@ -0,0 +1,10 @@
+ 'plugins/{$name}/',
+ 'theme' => 'themes/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
new file mode 100644
index 0000000..7d90c5e
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php
@@ -0,0 +1,49 @@
+ 'src/{$vendor}/{$name}/',
+ 'theme' => 'themes/{$name}/'
+ );
+
+ /**
+ * Format package name.
+ *
+ * For package type vgmcp-bundle, cut off a trailing '-bundle' if present.
+ *
+ * For package type vgmcp-theme, cut off a trailing '-theme' if present.
+ *
+ */
+ public function inflectPackageVars($vars)
+ {
+ if ($vars['type'] === 'vgmcp-bundle') {
+ return $this->inflectPluginVars($vars);
+ }
+
+ if ($vars['type'] === 'vgmcp-theme') {
+ return $this->inflectThemeVars($vars);
+ }
+
+ return $vars;
+ }
+
+ protected function inflectPluginVars($vars)
+ {
+ $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+
+ protected function inflectThemeVars($vars)
+ {
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
new file mode 100644
index 0000000..2cbb4a4
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/gateways/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
new file mode 100644
index 0000000..cb38788
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php
@@ -0,0 +1,9 @@
+ 'wolf/plugins/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
new file mode 100644
index 0000000..91c46ad
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php
@@ -0,0 +1,12 @@
+ 'wp-content/plugins/{$name}/',
+ 'theme' => 'wp-content/themes/{$name}/',
+ 'muplugin' => 'wp-content/mu-plugins/{$name}/',
+ 'dropin' => 'wp-content/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
new file mode 100644
index 0000000..27f429f
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php
@@ -0,0 +1,32 @@
+ 'module/{$name}/',
+ );
+
+ /**
+ * Format package name to CamelCase
+ * @param array $vars
+ *
+ * @return array
+ */
+ public function inflectPackageVars($vars)
+ {
+ $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name']));
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
+
+ return $vars;
+ }
+}
\ No newline at end of file
diff --git a/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
new file mode 100644
index 0000000..bde9bc8
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php
@@ -0,0 +1,11 @@
+ 'library/{$name}/',
+ 'extra' => 'extras/library/{$name}/',
+ 'module' => 'module/{$name}/',
+ );
+}
diff --git a/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
new file mode 100644
index 0000000..56cdf5d
--- /dev/null
+++ b/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php
@@ -0,0 +1,10 @@
+ 'modules/{$vendor}-{$name}/',
+ 'theme' => 'themes/{$vendor}-{$name}/'
+ );
+}
diff --git a/vendor/composer/installers/src/bootstrap.php b/vendor/composer/installers/src/bootstrap.php
new file mode 100644
index 0000000..0de276e
--- /dev/null
+++ b/vendor/composer/installers/src/bootstrap.php
@@ -0,0 +1,13 @@
+=5.4.0,<8.0.0-dev",
+ "squizlabs/php_codesniffer" : "^3.0"
+ },
+ "type" : "phpcodesniffer-standard"
+}
+```
+
+Requirements:
+* The repository may contain one or more standards.
+* Each standard can have a separate directory no deeper than 3 levels from the repository root.
+* The package `type` must be `phpcodesniffer-standard`. Without this, the plugin will not trigger.
+
+## Changelog
+
+This repository does not contain a `CHANGELOG.md` file, however, we do publish a changelog on each release
+using the [GitHub releases][changelog] functionality.
+
+## Contributing
+
+This is an active open-source project. We are always open to people who want to
+use the code or contribute to it.
+
+We've set up a separate document for our [contribution guidelines][contributing-guidelines].
+
+Thank you for being involved! :heart_eyes:
+
+## Authors & contributors
+
+The original idea and setup of this repository is by [Franck Nijhof][frenck], employee @ Dealerdirect.
+
+For a full list of all author and/or contributors, check [the contributors page][contributors].
+
+## License
+
+The MIT License (MIT)
+
+Copyright (c) 2016-2018 Dealerdirect B.V.
+
+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.
+
+[awesome-shield]: https://img.shields.io/badge/awesome%3F-yes-brightgreen.svg
+[changelog]: https://github.com/Dealerdirect/phpcodesniffer-composer-installer/releases
+[codesniffer]: https://github.com/squizlabs/PHP_CodeSniffer
+[composer-manual-scripts]: https://getcomposer.org/doc/articles/scripts.md
+[composer]: https://getcomposer.org/
+[contributing-guidelines]: CONTRIBUTING.md
+[contributors]: https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors
+[dealerdirectcom]: http://www.dealerdirect.com/en
+[definition-ci]: https://en.wikipedia.org/wiki/Continuous_integration
+[frenck]: https://github.com/frenck
+[get-in-touch]: https://www.dealerdirect.com/en/contact
+[license-shield]: https://img.shields.io/github/license/dealerdirect/phpcodesniffer-composer-installer.svg
+[last-updated-shield]: https://img.shields.io/github/last-commit/Dealerdirect/phpcodesniffer-composer-installer.svg
+[packagist-shield]: https://img.shields.io/packagist/dt/dealerdirect/phpcodesniffer-composer-installer.svg
+[packagist-version-shield]: https://img.shields.io/packagist/v/dealerdirect/phpcodesniffer-composer-installer.svg
+[packagist-version]: https://packagist.org/packages/dealerdirect/phpcodesniffer-composer-installer
+[packagist]: https://packagist.org/packages/dealerdirect/phpcodesniffer-composer-installer
+[project-stage-shield]: https://img.shields.io/badge/Project%20Stage-Development-yellowgreen.svg
+[scrutinizer-shield]: https://img.shields.io/scrutinizer/g/dealerdirect/phpcodesniffer-composer-installer.svg
+[scrutinizer]: https://scrutinizer-ci.com/g/dealerdirect/phpcodesniffer-composer-installer/
+[travis-shield]: https://img.shields.io/travis/Dealerdirect/phpcodesniffer-composer-installer.svg
+[travis]: https://travis-ci.org/Dealerdirect/phpcodesniffer-composer-installer
+[tutorial]: https://github.com/squizlabs/PHP_CodeSniffer/wiki/Coding-Standard-Tutorial
+[using-composer-plugins]: https://getcomposer.org/doc/articles/plugins.md#using-plugins
+[vacancies]: https://www.dealerdirect.com/en/vacancies
diff --git a/vendor/dealerdirect/phpcodesniffer-composer-installer/composer.json b/vendor/dealerdirect/phpcodesniffer-composer-installer/composer.json
new file mode 100644
index 0000000..46bf597
--- /dev/null
+++ b/vendor/dealerdirect/phpcodesniffer-composer-installer/composer.json
@@ -0,0 +1,48 @@
+{
+ "name": "dealerdirect/phpcodesniffer-composer-installer",
+ "description": "PHP_CodeSniffer Standards Composer Installer Plugin",
+ "type": "composer-plugin",
+ "keywords": [
+ "composer", "installer", "plugin",
+ "phpcs", "codesniffer", "phpcodesniffer", "php_codesniffer",
+ "standard", "standards", "style guide", "stylecheck",
+ "qa", "quality", "code quality", "tests"
+ ],
+ "homepage": "http://www.dealerdirect.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Franck Nijhof",
+ "email": "franck.nijhof@dealerdirect.com",
+ "homepage": "http://www.frenck.nl",
+ "role": "Developer / IT Manager"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
+ "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
+ },
+ "require": {
+ "php": "^5.3|^7",
+ "composer-plugin-api": "^1.0",
+ "squizlabs/php_codesniffer": "^2|^3"
+ },
+ "require-dev": {
+ "composer/composer": "*",
+ "sensiolabs/security-checker": "^4.1.0",
+ "phpcompatibility/php-compatibility": "^9.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
+ }
+ },
+ "extra": {
+ "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
+ },
+ "scripts": {
+ "install-codestandards": [
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin::run"
+ ]
+ }
+}
diff --git a/vendor/dealerdirect/phpcodesniffer-composer-installer/src/Plugin.php b/vendor/dealerdirect/phpcodesniffer-composer-installer/src/Plugin.php
new file mode 100644
index 0000000..77e4ef5
--- /dev/null
+++ b/vendor/dealerdirect/phpcodesniffer-composer-installer/src/Plugin.php
@@ -0,0 +1,478 @@
+
+ */
+class Plugin implements PluginInterface, EventSubscriberInterface
+{
+
+ const KEY_MAX_DEPTH = 'phpcodesniffer-search-depth';
+
+ const MESSAGE_ERROR_WRONG_MAX_DEPTH =
+ 'The value of "%s" (in the composer.json "extra".section) must be an integer larger then %d, %s given.';
+ const MESSAGE_NOT_INSTALLED = 'PHPCodeSniffer is not installed';
+ const MESSAGE_NOTHING_TO_INSTALL = 'Nothing to install or update';
+ const MESSAGE_RUNNING_INSTALLER = 'Running PHPCodeSniffer Composer Installer';
+
+ const PACKAGE_NAME = 'squizlabs/php_codesniffer';
+ const PACKAGE_TYPE = 'phpcodesniffer-standard';
+
+ const PHPCS_CONFIG_KEY = 'installed_paths';
+
+ /**
+ * @var Composer
+ */
+ private $composer;
+
+ /**
+ * @var string
+ */
+ private $cwd;
+
+ /**
+ * @var Filesystem
+ */
+ private $filesystem;
+
+ /**
+ * @var array
+ */
+ private $installedPaths;
+
+ /**
+ * @var IOInterface
+ */
+ private $io;
+
+ /**
+ * @var ProcessExecutor
+ */
+ private $processExecutor;
+
+ /**
+ * Triggers the plugin's main functionality.
+ *
+ * Makes it possible to run the plugin as a custom command.
+ *
+ * @param Event $event
+ *
+ * @throws \InvalidArgumentException
+ * @throws \RuntimeException
+ * @throws LogicException
+ * @throws ProcessFailedException
+ * @throws RuntimeException
+ */
+ public static function run(Event $event)
+ {
+ $io = $event->getIO();
+ $composer = $event->getComposer();
+
+ $instance = new static();
+
+ $instance->io = $io;
+ $instance->composer = $composer;
+ $instance->init();
+ $instance->onDependenciesChangedEvent();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws \RuntimeException
+ * @throws LogicException
+ * @throws ProcessFailedException
+ * @throws RuntimeException
+ */
+ public function activate(Composer $composer, IOInterface $io)
+ {
+ $this->composer = $composer;
+ $this->io = $io;
+
+ $this->init();
+ }
+
+ /**
+ * Prepares the plugin so it's main functionality can be run.
+ *
+ * @throws \RuntimeException
+ * @throws LogicException
+ * @throws ProcessFailedException
+ * @throws RuntimeException
+ */
+ private function init()
+ {
+ $this->cwd = getcwd();
+ $this->installedPaths = array();
+
+ $this->processExecutor = new ProcessExecutor($this->io);
+ $this->filesystem = new Filesystem($this->processExecutor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public static function getSubscribedEvents()
+ {
+ return array(
+ ScriptEvents::POST_INSTALL_CMD => array(
+ array('onDependenciesChangedEvent', 0),
+ ),
+ ScriptEvents::POST_UPDATE_CMD => array(
+ array('onDependenciesChangedEvent', 0),
+ ),
+ );
+ }
+
+ /**
+ * Entry point for post install and post update events.
+ *
+ * @throws \InvalidArgumentException
+ * @throws LogicException
+ * @throws ProcessFailedException
+ * @throws RuntimeException
+ */
+ public function onDependenciesChangedEvent()
+ {
+ $io = $this->io;
+ $isVerbose = $io->isVerbose();
+
+ if ($isVerbose) {
+ $io->write(sprintf('%s', self::MESSAGE_RUNNING_INSTALLER));
+ }
+
+ if ($this->isPHPCodeSnifferInstalled() === true) {
+ $this->loadInstalledPaths();
+ $installPathCleaned = $this->cleanInstalledPaths();
+ $installPathUpdated = $this->updateInstalledPaths();
+
+ if ($installPathCleaned === true || $installPathUpdated === true) {
+ $this->saveInstalledPaths();
+ } elseif ($isVerbose) {
+ $io->write(sprintf('%s', self::MESSAGE_NOTHING_TO_INSTALL));
+ }
+ } elseif ($isVerbose) {
+ $io->write(sprintf('%s', self::MESSAGE_NOT_INSTALLED));
+ }
+ }
+
+ /**
+ * Load all paths from PHP_CodeSniffer into an array.
+ *
+ * @throws LogicException
+ * @throws ProcessFailedException
+ * @throws RuntimeException
+ */
+ private function loadInstalledPaths()
+ {
+ if ($this->isPHPCodeSnifferInstalled() === true) {
+ $this->processExecutor->execute(
+ sprintf(
+ 'phpcs --config-show %s',
+ self::PHPCS_CONFIG_KEY
+ ),
+ $output,
+ $this->composer->getConfig()->get('bin-dir')
+ );
+
+ $phpcsInstalledPaths = str_replace(self::PHPCS_CONFIG_KEY . ': ', '', $output);
+ $phpcsInstalledPaths = trim($phpcsInstalledPaths);
+
+ if ($phpcsInstalledPaths !== '') {
+ $this->installedPaths = explode(',', $phpcsInstalledPaths);
+ }
+ }
+ }
+
+ /**
+ * Save all coding standard paths back into PHP_CodeSniffer
+ *
+ * @throws LogicException
+ * @throws ProcessFailedException
+ * @throws RuntimeException
+ */
+ private function saveInstalledPaths()
+ {
+ // Check if we found installed paths to set.
+ if (count($this->installedPaths) !== 0) {
+ $paths = implode(',', $this->installedPaths);
+ $arguments = array('--config-set', self::PHPCS_CONFIG_KEY, $paths);
+ $configMessage = sprintf(
+ 'PHP CodeSniffer Config %sset to%s',
+ self::PHPCS_CONFIG_KEY,
+ $paths
+ );
+ } else {
+ // Delete the installed paths if none were found.
+ $arguments = array('--config-delete', self::PHPCS_CONFIG_KEY);
+ $configMessage = sprintf(
+ 'PHP CodeSniffer Config %sdelete',
+ self::PHPCS_CONFIG_KEY
+ );
+ }
+
+ $this->io->write($configMessage);
+
+ $this->processExecutor->execute(
+ sprintf(
+ 'phpcs %s',
+ implode(' ', $arguments)
+ ),
+ $configResult,
+ $this->composer->getConfig()->get('bin-dir')
+ );
+
+ if ($this->io->isVerbose() && !empty($configResult)) {
+ $this->io->write(sprintf('%s', $configResult));
+ }
+ }
+
+ /**
+ * Iterate trough all known paths and check if they are still valid.
+ *
+ * If path does not exists, is not an directory or isn't readable, the path
+ * is removed from the list.
+ *
+ * @return bool True if changes where made, false otherwise
+ */
+ private function cleanInstalledPaths()
+ {
+ $changes = false;
+ foreach ($this->installedPaths as $key => $path) {
+ // This might be a relative path as well
+ $alternativePath = realpath($this->getPHPCodeSnifferInstallPath() . DIRECTORY_SEPARATOR . $path);
+
+ if ((is_dir($path) === false || is_readable($path) === false) &&
+ (is_dir($alternativePath) === false || is_readable($alternativePath) === false)
+ ) {
+ unset($this->installedPaths[$key]);
+ $changes = true;
+ }
+ }
+ return $changes;
+ }
+
+ /**
+ * Check all installed packages (including the root package) against
+ * the installed paths from PHP_CodeSniffer and add the missing ones.
+ *
+ * @return bool True if changes where made, false otherwise
+ *
+ * @throws \InvalidArgumentException
+ * @throws \RuntimeException
+ */
+ private function updateInstalledPaths()
+ {
+ $changes = false;
+
+ $searchPaths = array($this->cwd);
+ $codingStandardPackages = $this->getPHPCodingStandardPackages();
+ foreach ($codingStandardPackages as $package) {
+ $installPath = $this->composer->getInstallationManager()->getInstallPath($package);
+ if ($this->filesystem->isAbsolutePath($installPath) === false) {
+ $installPath = $this->filesystem->normalizePath(
+ $this->cwd . DIRECTORY_SEPARATOR . $installPath
+ );
+ }
+ $searchPaths[] = $installPath;
+ }
+
+ $finder = new Finder();
+ $finder->files()
+ ->depth('<= ' . $this->getMaxDepth())
+ ->depth('>= ' . $this->getMinDepth())
+ ->ignoreUnreadableDirs()
+ ->ignoreVCS(true)
+ ->in($searchPaths)
+ ->name('ruleset.xml');
+
+ // Process each found possible ruleset.
+ foreach ($finder as $ruleset) {
+ $standardsPath = $ruleset->getPath();
+
+ // Pick the directory above the directory containing the standard, unless this is the project root.
+ if ($standardsPath !== $this->cwd) {
+ $standardsPath = dirname($standardsPath);
+ }
+
+ // Use relative paths for local project repositories.
+ if ($this->isRunningGlobally() === false) {
+ $standardsPath = $this->filesystem->findShortestPath(
+ $this->getPHPCodeSnifferInstallPath(),
+ $standardsPath,
+ true
+ );
+ }
+
+ // De-duplicate and add when directory is not configured.
+ if (in_array($standardsPath, $this->installedPaths, true) === false) {
+ $this->installedPaths[] = $standardsPath;
+ $changes = true;
+ }
+ }
+
+ return $changes;
+ }
+
+ /**
+ * Iterates through Composers' local repository looking for valid Coding
+ * Standard packages.
+ *
+ * If the package is the RootPackage (the one the plugin is installed into),
+ * the package is ignored for now since it needs a different install path logic.
+ *
+ * @return array Composer packages containing coding standard(s)
+ */
+ private function getPHPCodingStandardPackages()
+ {
+ $codingStandardPackages = array_filter(
+ $this->composer->getRepositoryManager()->getLocalRepository()->getPackages(),
+ function (PackageInterface $package) {
+ if ($package instanceof AliasPackage) {
+ return false;
+ }
+ return $package->getType() === Plugin::PACKAGE_TYPE;
+ }
+ );
+
+ if (! $this->composer->getPackage() instanceof RootpackageInterface
+ && $this->composer->getPackage()->getType() === self::PACKAGE_TYPE
+ ) {
+ $codingStandardPackages[] = $this->composer->getPackage();
+ }
+
+ return $codingStandardPackages;
+ }
+
+ /**
+ * Searches for the installed PHP_CodeSniffer Composer package
+ *
+ * @param null|string|\Composer\Semver\Constraint\ConstraintInterface $versionConstraint to match against
+ *
+ * @return PackageInterface|null
+ */
+ private function getPHPCodeSnifferPackage($versionConstraint = null)
+ {
+ $packages = $this
+ ->composer
+ ->getRepositoryManager()
+ ->getLocalRepository()
+ ->findPackages(self::PACKAGE_NAME, $versionConstraint);
+
+ return array_shift($packages);
+ }
+
+ /**
+ * Returns the path to the PHP_CodeSniffer package installation location
+ *
+ * @return string
+ */
+ private function getPHPCodeSnifferInstallPath()
+ {
+ return $this->composer->getInstallationManager()->getInstallPath($this->getPHPCodeSnifferPackage());
+ }
+
+ /**
+ * Simple check if PHP_CodeSniffer is installed.
+ *
+ * @param null|string|\Composer\Semver\Constraint\ConstraintInterface $versionConstraint to match against
+ *
+ * @return bool Whether PHP_CodeSniffer is installed
+ */
+ private function isPHPCodeSnifferInstalled($versionConstraint = null)
+ {
+ return ($this->getPHPCodeSnifferPackage($versionConstraint) !== null);
+ }
+
+ /**
+ * Test if composer is running "global"
+ * This check kinda dirty, but it is the "Composer Way"
+ *
+ * @return bool Whether Composer is running "globally"
+ *
+ * @throws \RuntimeException
+ */
+ private function isRunningGlobally()
+ {
+ return ($this->composer->getConfig()->get('home') === $this->cwd);
+ }
+
+ /**
+ * Determines the maximum search depth when searching for Coding Standards.
+ *
+ * @return int
+ *
+ * @throws \InvalidArgumentException
+ */
+ private function getMaxDepth()
+ {
+ $maxDepth = 3;
+
+ $extra = $this->composer->getPackage()->getExtra();
+
+ if (array_key_exists(self::KEY_MAX_DEPTH, $extra)) {
+ $maxDepth = $extra[self::KEY_MAX_DEPTH];
+ $minDepth = $this->getMinDepth();
+
+ if (is_int($maxDepth) === false /* Must be an integer */
+ || $maxDepth <= $minDepth /* Larger than the minimum */
+ || is_float($maxDepth) === true /* Within the boundaries of integer */
+ ) {
+ $message = vsprintf(
+ self::MESSAGE_ERROR_WRONG_MAX_DEPTH,
+ array(
+ 'key' => self::KEY_MAX_DEPTH,
+ 'min' => $minDepth,
+ 'given' => var_export($maxDepth, true),
+ )
+ );
+
+ throw new \InvalidArgumentException($message);
+ }
+ }
+
+ return $maxDepth;
+ }
+
+ /**
+ * Returns the minimal search depth for Coding Standard packages.
+ *
+ * Usually this is 0, unless PHP_CodeSniffer >= 3 is used.
+ *
+ * @return int
+ */
+ private function getMinDepth()
+ {
+ if ($this->isPHPCodeSnifferInstalled('>= 3.0.0') !== true) {
+ return 1;
+ }
+ return 0;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/CHANGELOG.md b/vendor/phpcompatibility/php-compatibility/CHANGELOG.md
new file mode 100644
index 0000000..2163869
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/CHANGELOG.md
@@ -0,0 +1,1257 @@
+# Change Log for the PHPCompatibility standard for PHP Codesniffer
+
+All notable changes to this project will be documented in this file.
+
+This projects adheres to [Keep a CHANGELOG](http://keepachangelog.com/).
+
+Up to version 8.0.0, the `major.minor` version numbers were based on the PHP version for which compatibility check support was added, with `patch` version numbers being specific to this library.
+From version 8.0.0 onwards, [Semantic Versioning](http://semver.org/) is used.
+
+
+
+
+## [Unreleased]
+
+_Nothing yet._
+
+## [9.1.1] - 2018-12-31
+
+See all related issues and PRs in the [9.1.1 milestone].
+
+### Fixed
+- :bug: `ForbiddenThisUseContexts`: false positive for unsetting `$this['key']` on objects implementing `ArrayAccess`. [#781](https://github.com/PHPCompatibility/PHPCompatibility/pull/781). Fixes [#780](https://github.com/PHPCompatibility/PHPCompatibility/issues/780)
+
+## [9.1.0] - 2018-12-16
+
+See all related issues and PRs in the [9.1.0 milestone].
+
+### Added
+- :star2: New `PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue` sniff to detect code which could be affected by the PHP 7.0 change in the values reported by `func_get_arg()`, `func_get_args()`, `debug_backtrace()` and exception backtraces. [#750](https://github.com/PHPCompatibility/PHPCompatibility/pull/750). Fixes [#585](https://github.com/PHPCompatibility/PHPCompatibility/pull/585).
+- :star2: New `PHPCompatibility.MethodUse.NewDirectCallsToClone` sniff to detect direct call to a `__clone()` magic method which wasn't allowed prior to PHP 7.0. [#743](https://github.com/PHPCompatibility/PHPCompatibility/pull/743). Fixes [#629](https://github.com/PHPCompatibility/PHPCompatibility/issues/629).
+- :star2: New `PHPCompatibility.Variables.ForbiddenThisUseContext` sniff to detect most of the inconsistencies surrounding the use of the `$this` variable, which were removed in PHP 7.1. [#762](https://github.com/PHPCompatibility/PHPCompatibility/pull/762), [#771](https://github.com/PHPCompatibility/PHPCompatibility/pull/771). Fixes [#262](https://github.com/PHPCompatibility/PHPCompatibility/issues/262) and [#740](https://github.com/PHPCompatibility/PHPCompatibility/issues/740).
+- :star: `NewClasses`: detection of more native PHP Exceptions. [#743](https://github.com/PHPCompatibility/PHPCompatibility/pull/743), [#753](https://github.com/PHPCompatibility/PHPCompatibility/pull/753)
+- :star: `NewConstants` : detection of the new PHP 7.3 Curl, Stream Crypto and LDAP constants and some more PHP 7.0 Tokenizer constants. [#752](https://github.com/PHPCompatibility/PHPCompatibility/pull/752), [#767](https://github.com/PHPCompatibility/PHPCompatibility/pull/767), [#778](https://github.com/PHPCompatibility/PHPCompatibility/pull/778)
+- :star: `NewFunctions` sniff: recognize (more) new LDAP functions as introduced in PHP 7.3. [#768](https://github.com/PHPCompatibility/PHPCompatibility/pull/768)
+- :star: `NewFunctionParameters` sniff: recognize the new `$serverctrls` parameter which was added to a number of LDAP functions in PHP 7.3. [#769](https://github.com/PHPCompatibility/PHPCompatibility/pull/769)
+- :star: `NewIniDirectives` sniff: recognize the new `imap.enable_insecure_rsh` ini directive as introduced in PHP 7.1.25, 7.2.13 and 7.3.0. [#770](https://github.com/PHPCompatibility/PHPCompatibility/pull/770)
+- :star: `NewInterfaces` sniff: recognize two more Session related interfaces which were introduced in PHP 5.5.1 and 7.0 respectively. [#748](https://github.com/PHPCompatibility/PHPCompatibility/pull/748)
+- :star: Duplicate of upstream `findStartOfStatement()` method to the `PHPCompatibility\PHPCSHelper` class to allow for PHPCS cross-version usage of that method. [#750](https://github.com/PHPCompatibility/PHPCompatibility/pull/750)
+
+### Changed
+- :pushpin: `RemovedPHP4StyleConstructors`: will now also detect PHP4-style constructors when declared in interfaces. [#751](https://github.com/PHPCompatibility/PHPCompatibility/pull/751)
+- :pushpin: `Sniff::validDirectScope()`: the return value of this method has changed. Previously it would always be a boolean. It will stil return `false` when no valid direct scope has been found, but it will now return the `stackPtr` to the scope token if a _valid_ direct scope was encountered. [#758](https://github.com/PHPCompatibility/PHPCompatibility/pull/758)
+- :rewind: `NewOperators` : updated the version number for `T_COALESCE_EQUAL`. [#746](https://github.com/PHPCompatibility/PHPCompatibility/pull/746)
+- :pencil: Minor improvement to an error message in the unit test suite. [#742](https://github.com/PHPCompatibility/PHPCompatibility/pull/742)
+- :recycle: Various code clean-up and improvements. [#745](https://github.com/PHPCompatibility/PHPCompatibility/pull/745), [#756](https://github.com/PHPCompatibility/PHPCompatibility/pull/756), [#774](https://github.com/PHPCompatibility/PHPCompatibility/pull/774)
+- :recycle: Various minor inline documentation fixes. [#749](https://github.com/PHPCompatibility/PHPCompatibility/pull/749), [#757](https://github.com/PHPCompatibility/PHPCompatibility/pull/757)
+- :umbrella: Improved code coverage recording. [#744](https://github.com/PHPCompatibility/PHPCompatibility/pull/744), [#776](https://github.com/PHPCompatibility/PHPCompatibility/pull/776)
+- :green_heart: Travis: build tests are now being run against PHP 7.3 as well. [#511](https://github.com/wimg/PHPCompatibility/pull/511)
+ Note: full PHP 7.3 support is only available in combination with PHP_CodeSniffer 2.9.2 or 3.3.1+ due to an incompatibility within PHP_CodeSniffer itself.
+
+### Fixed
+- :white_check_mark: Compatibility with the upcoming release of PHPCS 3.4.0. Deal with changed behaviour of the PHPCS `Tokenizer` regarding binary type casts. [#760](https://github.com/PHPCompatibility/PHPCompatibility/pull/760)
+- :bug: `InternalInterfaces`: false negative for implemented/extended interfaces prefixed with a namespace separator. [#775](https://github.com/PHPCompatibility/PHPCompatibility/pull/775)
+- :bug: `NewClasses`: the introduction version of various native PHP Exceptions has been corrected. [#743](https://github.com/PHPCompatibility/PHPCompatibility/pull/743), [#753](https://github.com/PHPCompatibility/PHPCompatibility/pull/753)
+- :bug: `NewInterfaces`: false negative for implemented/extended interfaces prefixed with a namespace separator. [#775](https://github.com/PHPCompatibility/PHPCompatibility/pull/775)
+- :bug: `RemovedPHP4StyleConstructors`: the sniff would examine methods in nested anonymous classes as if they were methods of the higher level class. [#751](https://github.com/PHPCompatibility/PHPCompatibility/pull/751)
+- :rewind: `RemovedPHP4StyleConstructors`: the sniff will no longer throw false positives for the first method in an anonymous class when used in combination with PHPCS 2.3.x. [#751](https://github.com/PHPCompatibility/PHPCompatibility/pull/751)
+- :rewind: `ReservedFunctionNames`: fixed incorrect error message text for methods in anonymous classes when used in combination with PHPCS 2.3.x. [#755](https://github.com/PHPCompatibility/PHPCompatibility/pull/755)
+- :bug: `ReservedFunctionNames`: prevent duplicate errors being thrown for methods in nested anonymous classes. [#755](https://github.com/PHPCompatibility/PHPCompatibility/pull/755)
+- :bug: `PHPCSHelper::findEndOfStatement()`: minor bug fix. [#749](https://github.com/PHPCompatibility/PHPCompatibility/pull/749)
+- :bug: `Sniff::isClassProperty()`: class properties for classes nested in conditions or function calls were not always recognized as class properties. [#758](https://github.com/PHPCompatibility/PHPCompatibility/pull/758)
+
+### Credits
+Thanks go out to [Jonathan Champ] for his contribution to this version. :clap:
+
+
+## [9.0.0] - 2018-10-07
+
+**IMPORTANT**: This release contains **breaking changes**. Please read the below information carefully before upgrading!
+
+All sniffs have been placed in meaningful categories and a number of sniffs have been renamed to have more consistent, meaningful and future-proof names.
+
+Both the `PHPCompatibilityJoomla` [[GH](https://github.com/PHPCompatibility/PHPCompatibilityJoomla) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-joomla)] as well as the `PHPCompatibilityWP` [[GH](https://github.com/PHPCompatibility/PHPCompatibilityWP)|[Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-wp)] rulesets have already been adjusted for this change and have released a new version which is compatible with this version of PHPCompatibility.
+
+Aside from those CMS-based rulesets, this project now also offers a number of polyfill-library specific rulesets, such as `PHPCompatibilityPasswordCompat` [[GH](https://github.com/PHPCompatibility/PHPCompatibilityPasswordCompat) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-passwordcompat)] for @ircmaxell's [`password_compat`](https://github.com/ircmaxell/password_compat) libary, `PHPCompatibilityParagonieRandomCompat` and `PHPCompatibilityParagonieSodiumCompat` [[GH](https://github.com/PHPCompatibility/PHPCompatibilityParagonie)|[Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-paragonie)] for the [Paragonie polyfills](https://github.com/paragonie?utf8=?&q=polyfill) and a number of rulesets related to various [polyfills offered by the Symfony project](https://github.com/symfony?utf8=?&q=polyfill) [[GH](https://github.com/PHPCompatibility/PHPCompatibilitySymfony)|[Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-symfony)].
+
+If your project uses one of these polyfills, please consider using these special polyfill rulesets to prevent false positives.
+
+Also as of this version, [Juliette Reinders Folmer] is now officially a co-maintainer of this package.
+
+### Upgrade instructions
+
+* If you have `` directives in your own project's custom ruleset which relate to sniffs from the PHPCompatibility library, you will need to update your ruleset to use the new sniff names.
+* If you use the new [PHPCS 3.2+ inline annotations](https://github.com/squizlabs/PHP_CodeSniffer/releases/3.2.0), i.e. `// phpcs:ignore Standard.Category.SniffName`, in combination with PHPCompatibility sniff names, you will need to update these annotations.
+* If you use neither of the above, you should be fine and upgrading should be painless.
+
+### Overview of all the sniff renames:
+
+Old Category.SniffName | New Category.SniffName
+--- | ---
+**PHP**.ArgumentFunctionsUsage | **FunctionUse**.ArgumentFunctionsUsage
+**PHP**.CaseSensitiveKeywords | **Keywords**.CaseSensitiveKeywords
+**PHP**.ConstantArraysUsingConst | **InitialValue**.**New**ConstantArraysUsingConst
+**PHP**.ConstantArraysUsingDefine | **InitialValue**.**New**ConstantArraysUsingDefine
+**PHP**.**Deprecated**Functions | **FunctionUse**.**Removed**Functions
+**PHP**.**Deprecated**IniDirectives | **IniDirectives**.**Removed**IniDirectives
+**PHP**.**Deprecated**MagicAutoload | **FunctionNameRestrictions**.**Removed**MagicAutoload
+**PHP**.**Deprecated**NewReference | **Syntax**.**Removed**NewReference
+**PHP**.**Deprecated**PHP4StyleConstructors | **FunctionNameRestrictions**.**Removed**PHP4StyleConstructors
+**PHP**.**Deprecated**TypeCasts | **TypeCasts**.**Removed**TypeCasts
+**PHP**.DiscouragedSwitchContinue | **ControlStructures**.DiscouragedSwitchContinue
+**PHP**.DynamicAccessToStatic | **Syntax**.**New**DynamicAccessToStatic
+**PHP**.EmptyNonVariable | **LanguageConstructs**.**New**EmptyNonVariable
+**PHP**.ForbiddenBreakContinueOutsideLoop | **ControlStructures**.ForbiddenBreakContinueOutsideLoop
+**PHP**.ForbiddenBreakContinueVariableArguments | **ControlStructures**.ForbiddenBreakContinueVariableArguments
+**PHP**.ForbiddenCallTimePassByReference | **Syntax**.ForbiddenCallTimePassByReference
+**PHP**.Forbidden**ClosureUseVariableNames** | **FunctionDeclarations**.Forbidden**VariableNamesInClosureUse**
+**PHP**.ForbiddenEmptyListAssignment | **Lists**.ForbiddenEmptyListAssignment
+**PHP**.Forbidden**Function**ParametersWithSameName | **FunctionDeclarations**.ForbiddenParametersWithSameName
+**PHP**.ForbiddenGlobalVariableVariable | **Variables**.ForbiddenGlobalVariableVariable
+**PHP**.ForbiddenNames | **Keywords**.ForbiddenNames
+**PHP**.ForbiddenNamesAsDeclared | **Keywords**.ForbiddenNamesAsDeclared
+**PHP**.ForbiddenNamesAsInvokedFunctions | **Keywords**.ForbiddenNamesAsInvokedFunctions
+**PHP**.ForbiddenNegativeBitshift | **Operators**.ForbiddenNegativeBitshift
+**PHP**.ForbiddenSwitchWithMultipleDefaultBlocks | **ControlStructures**.ForbiddenSwitchWithMultipleDefaultBlocks
+**PHP**.InternalInterfaces | **Interfaces**.InternalInterfaces
+**PHP**.LateStaticBinding | **Classes**.**New**LateStaticBinding
+**PHP**.**MbstringReplaceE**Modifier | **ParameterValues**.**RemovedMbstring**Modifier**s**
+**PHP**.NewAnonymousClasses | **Classes**.NewAnonymousClasses
+**PHP**.NewArrayStringDereferencing | **Syntax**.NewArrayStringDereferencing
+**PHP**.NewClasses | **Classes**.NewClasses
+**PHP**.NewClassMemberAccess | **Syntax**.NewClassMemberAccess
+**PHP**.NewClosure | **FunctionDeclarations**.NewClosure
+**PHP**.NewConstants | **Constants**.NewConstants
+**PHP**.NewConstantScalarExpressions | **InitialValue**.NewConstantScalarExpressions
+**PHP**.NewConstVisibility | **Classes**.NewConstVisibility
+**PHP**.NewExecutionDirectives | **ControlStructures**.NewExecutionDirectives
+**PHP**.NewFunctionArrayDereferencing | **Syntax**.NewFunctionArrayDereferencing
+**PHP**.NewFunctionParameters | **FunctionUse**.NewFunctionParameters
+**PHP**.NewFunctions | **FunctionUse**.NewFunctions
+**PHP**.NewGeneratorReturn | **Generators**.NewGeneratorReturn
+**PHP**.NewGroupUseDeclarations | **UseDeclarations**.NewGroupUseDeclarations
+**PHP**.NewHashAlgorithms | **ParameterValues**.NewHashAlgorithms
+**PHP**.NewHeredoc**Initialize** | **InitialValue**.NewHeredoc
+**PHP**.NewIniDirectives | **IniDirectives**.NewIniDirectives
+**PHP**.NewInterfaces | **Interfaces**.NewInterfaces
+**PHP**.NewKeywords | **Keywords**.NewKeywords
+**PHP**.NewLanguageConstructs | **LanguageConstructs**.NewLanguageConstructs
+**PHP**.NewMagicClassConstant | **Constants**.NewMagicClassConstant
+**PHP**.NewMagicMethods | **FunctionNameRestrictions**.NewMagicMethods
+**PHP**.NewMultiCatch | **ControlStructures**.NewMultiCatch
+**PHP**.NewNullableTypes | **FunctionDeclarations**.NewNullableTypes
+**PHP**.NewReturnTypeDeclarations | **FunctionDeclarations**.NewReturnTypeDeclarations
+**PHP**.New**Scalar**TypeDeclarations | **FunctionDeclarations**.New**Param**TypeDeclarations
+**PHP**.NewTrailingComma | **Syntax**.New**FunctionCall**TrailingComma
+**PHP**.NewTypeCasts | **TypeCasts**.NewTypeCasts
+**PHP**.NewUseConstFunction | **UseDeclarations**.NewUseConstFunction
+**PHP**.NonStaticMagicMethods | **FunctionDeclarations**.NonStaticMagicMethods
+**PHP**.OptionalRequiredFunctionParameters | **FunctionUse**.Optional**To**RequiredFunctionParameters
+**PHP**.ParameterShadowSuperGlobals | **FunctionDeclarations**.**Forbidden**ParameterShadowSuperGlobals
+**PHP**.**PCRENew**Modifiers | **ParameterValues**.**NewPCRE**Modifiers
+**PHP**.**PregReplaceE**Modifier | **ParameterValues**.**RemovedPCRE**Modifier**s**
+**PHP**.RemovedAlternativePHPTags | **Miscellaneous**.RemovedAlternativePHPTags
+**PHP**.RemovedConstants | **Constants**.RemovedConstants
+**PHP**.RemovedExtensions | **Extensions**.RemovedExtensions
+**PHP**.RemovedFunctionParameters | **FunctionUse**.RemovedFunctionParameters
+**PHP**.RemovedGlobalVariables | **Variables**.Removed**Predefined**GlobalVariables
+**PHP**.RemovedHashAlgorithms | **ParameterValues**.RemovedHashAlgorithms
+**PHP**.ReservedFunctionNames | **FunctionNameRestrictions**.ReservedFunctionNames
+**PHP**.RequiredOptionalFunctionParameters | **FunctionUse**.Required**To**OptionalFunctionParameters
+**PHP**.ShortArray | **Syntax**.**New**ShortArray
+**PHP**.Ternary**Operators** | **Operators**.**NewShort**Ternary
+**PHP**.ValidIntegers | **Miscellaneous**.ValidIntegers
+**PHP**.**VariableVariables** | **Variables**.**NewUniformVariableSyntax**
+
+### Changelog for version 9.0.0
+
+See all related issues and PRs in the [9.0.0 milestone].
+
+### Added
+- :star2: New `PHPCompatibility.ControlStructures.NewForeachExpressionReferencing` sniff to detect referencing of `$value` within a `foreach()` when the iterated array is not a variable. This was not supported prior to PHP 5.5. [#664](https://github.com/PHPCompatibility/PHPCompatibility/pull/664)
+- :star2: New `PHPCompatibility.ControlStructures.NewListInForeach` sniff to detect unpacking nested arrays into separate variables via the `list()` construct in a `foreach()` statement. This was not supported prior to PHP 5.5. [#657](https://github.com/PHPCompatibility/PHPCompatibility/pull/657)
+- :star2: New `PHPCompatibility.FunctionNameRestrictions.RemovedNamespacedAssert` sniff to detect declaring a function called `assert()` within a namespace. This has been deprecated as of PHP 7.3. [#735](https://github.com/PHPCompatibility/PHPCompatibility/pull/735). Partially fixes [#718](https://github.com/PHPCompatibility/PHPCompatibility/issues/718).
+- :star2: New `PHPCompatibility.Lists.AssignmentOrder` sniff to detect `list()` constructs affected by the change in assignment order in PHP 7.0. [#656](https://github.com/PHPCompatibility/PHPCompatibility/pull/656)
+- :star2: New `PHPCompatibility.Lists.NewKeyedList` sniff to detect usage of keys in `list()`, support for which was added in PHP 7.1. [#655](https://github.com/PHPCompatibility/PHPCompatibility/pull/655). Fixes [#252](https://github.com/PHPCompatibility/PHPCompatibility/issues/252).
+- :star2: New `PHPCompatibility.Lists.NewListReferenceAssignment` sniff to detect reference assignments being used in `list()` constructs, support for which has been added in PHP 7.3. [#731](https://github.com/PHPCompatibility/PHPCompatibility/pull/731)
+- :star2: New `PHPCompatibility.Lists.NewShortList` sniff to detect the shorthand array syntax `[]` being used for symmetric array destructuring as introduced in PHP 7.1. [#654](https://github.com/PHPCompatibility/PHPCompatibility/pull/654). Fixes [#248](https://github.com/PHPCompatibility/PHPCompatibility/issues/248).
+- :star2: New `PHPCompatibility.Operators.NewOperators` sniff which checks for usage of the pow, pow equals, spaceship and coalesce (equals) operators. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738)
+ These checks were previously contained within the `PHPCompatibility.LanguageConstructs.NewLanguageConstructs` sniff.
+- :star2: New `PHPCompatibility.ParameterValues.ForbiddenGetClassNull` sniff to detect `null` being passed to `get_class()`, support for which has been removed in PHP 7.2 [#659](https://github.com/PHPCompatibility/PHPCompatibility/pull/659). Fixes [#557](https://github.com/PHPCompatibility/PHPCompatibility/issues/557).
+- :star2: New `PHPCompatibility.ParameterValues.NewArrayReduceInitialType` sniff to detect non-integers being passed as the `$initial` parameter to the `array_reduce()` function, which was not supported before PHP 5.3. [#666](https://github.com/PHPCompatibility/PHPCompatibility/pull/666). Fixes [#649](https://github.com/PHPCompatibility/PHPCompatibility/issues/649)
+- :star2: New `PHPCompatibility.ParameterValues.NewFopenModes` sniff to examine the `$mode` parameter passed to `fopen()` for modes not available in older PHP versions. [#658](https://github.com/PHPCompatibility/PHPCompatibility/pull/658)
+- :star2: New `PHPCompatibility.ParameterValues.NewNegativeStringOffset` sniff to detect negative string offsets being passed to string manipulation functions which was not supported before PHP 7.1. [#662](https://github.com/PHPCompatibility/PHPCompatibility/pull/662). Partially fixes [#253](https://github.com/PHPCompatibility/PHPCompatibility/issues/253).
+- :star2: New `PHPCompatibility.ParameterValues.NewPackFormats` sniff to examine the `$format` parameter passed to `pack()` for formats not available in older PHP versions. [#665](https://github.com/PHPCompatibility/PHPCompatibility/pull/665)
+- :star2: New `PHPCompatibility.ParameterValues.RemovedIconvEncoding` sniff to detect the PHP 5.6 deprecated encoding `$type`s being passed to `iconv_set_encoding()`. [#660](https://github.com/PHPCompatibility/PHPCompatibility/pull/660). Fixes [#475](https://github.com/PHPCompatibility/PHPCompatibility/issues/475).
+- :star2: New `PHPCompatibility.ParameterValues.RemovedNonCryptoHashes` sniff to detect non-cryptographic hash algorithms being passed to various `hash_*()` functions. This is no longer accepted as of PHP 7.2. [#663](https://github.com/PHPCompatibility/PHPCompatibility/pull/663). Fixes [#559](https://github.com/PHPCompatibility/PHPCompatibility/issues/559)
+- :star2: New `PHPCompatibility.ParameterValues.RemovedSetlocaleString` sniff to detect string literals being passed to the `$category` parameter of the `setlocale()` function. This behaviour was deprecated in PHP 4.2 and support has been removed in PHP 7.0. [#661](https://github.com/PHPCompatibility/PHPCompatibility/pull/661)
+- :star2: New `PHPCompatibility.Syntax.NewFlexibleHeredocNowdoc` sniff to detect the new heredoc/nowdoc format as allowed as of PHP 7.3. [#736](https://github.com/PHPCompatibility/PHPCompatibility/pull/736). Fixes [#705](https://github.com/PHPCompatibility/PHPCompatibility/issues/705).
+ Note: This sniff is only supported in combination with PHP_CodeSniffer 2.6.0 and higher.
+- :star: `PHPCompatibility.Classes.NewClasses` sniff: recognize the new `CompileError` and `JsonException` classes as introduced in PHP 7.3. [#676](https://github.com/PHPCompatibility/PHPCompatibility/pull/676)
+- :star: `PHPCompatibility.Constants.NewConstants` sniff: recognize new constants which are being introduced in PHP 7.3. [#678](https://github.com/PHPCompatibility/PHPCompatibility/pull/678)
+- :star: `PHPCompatibility.Constants.RemovedConstants` sniff: recognize constants which have been deprecated or removed in PHP 7.3. [#710](https://github.com/PHPCompatibility/PHPCompatibility/pull/710). Partially fixes [#718](https://github.com/PHPCompatibility/PHPCompatibility/issues/718).
+- :star: `PHPCompatibility.FunctionUse.NewFunctions` sniff: recognize various new functions being introduced in PHP 7.3. [#679](https://github.com/PHPCompatibility/PHPCompatibility/pull/679)
+- :star: `PHPCompatibility.FunctionUse.NewFunctions` sniff: recognize the `sapi_windows_*()`, `hash_hkdf()` and `pcntl_signal_get_handler()` functions as introduced in PHP 7.1. [#728](https://github.com/PHPCompatibility/PHPCompatibility/pull/728)
+- :star: `PHPCompatibility.FunctionUse.RemovedFunctionParameters` sniff: recognize the deprecation of the `$case_insensitive` parameter for the `define()` function in PHP 7.3. [#706](https://github.com/PHPCompatibility/PHPCompatibility/pull/706)
+- :star: `PHPCompatibility.FunctionUse.RemovedFunctions` sniff: recognize the PHP 7.3 deprecation of the `image2wbmp()`, `fgetss()` and `gzgetss()` functions, as well as the deprecation of undocumented Mbstring function aliases. [#681](https://github.com/PHPCompatibility/PHPCompatibility/pull/681), [#714](https://github.com/PHPCompatibility/PHPCompatibility/pull/714), [#720](https://github.com/PHPCompatibility/PHPCompatibility/pull/720). Partially fixes [#718](https://github.com/PHPCompatibility/PHPCompatibility/issues/718).
+- :star: `PHPCompatibility.FunctionUse.RequiredToOptionalFunctionParameters` sniff: account for the second parameter for `array_push()` and `array_unshift()` becoming optional in PHP 7.3, as well as for the `$mode` parameter for a range of `ftp_*()` functions becoming optional. [#680](https://github.com/PHPCompatibility/PHPCompatibility/pull/680)
+- :star: `PHPCompatibility.IniDirectives.NewIniDirectives` sniff: recognize new `syslog` and `session` ini directives as introduced in PHP 7.3. [#702](https://github.com/PHPCompatibility/PHPCompatibility/pull/702), [#719](https://github.com/PHPCompatibility/PHPCompatibility/pull/719), [#730](https://github.com/PHPCompatibility/PHPCompatibility/pull/730)
+- :star: `PHPCompatibility.IniDirectives.NewIniDirectives` sniff: recognize some more ini directives which were introduced in PHP 7.1. [#727](https://github.com/PHPCompatibility/PHPCompatibility/pull/727)
+- :star: `PHPCompatibility.IniDirectives.RemovedIniDirectived` sniff: recognize ini directives removed in PHP 7.3. [#677](https://github.com/PHPCompatibility/PHPCompatibility/pull/677), [#717](https://github.com/PHPCompatibility/PHPCompatibility/pull/717). Partially fixes [#718](https://github.com/PHPCompatibility/PHPCompatibility/issues/718).
+- :star: New `isNumericCalculation()` and `isVariable()` utility methods to the `PHPCompatibility\Sniff` class. [#664](https://github.com/PHPCompatibility/PHPCompatibility/pull/664), [#666](https://github.com/PHPCompatibility/PHPCompatibility/pull/666)
+- :books: A section about the new sniff naming conventions to the `Contributing` file. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738)
+
+### Changed
+- :fire: All sniffs have been placed in meaningful categories and a number of sniffs have been renamed to have more consistent, meaningful and future-proof names. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738). Fixes [#601](https://github.com/PHPCompatibility/PHPCompatibility/issues/601), [#692](https://github.com/PHPCompatibility/PHPCompatibility/issues/692)
+ See the table at the top of this changelog for details of all the file renames.
+- :umbrella: The unit test files have been moved about as well. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738)
+ * The directory structure for these now mirrors the default directory structure used by PHPCS itself.
+ * The file names of the unit test files have been adjusted for the changes made in the sniffs.
+ * The unit test case files have been renamed and moved to the same directory as the actual test file they apply to.
+ * The `BaseSniffTest::sniffFile()` method has been adjusted to match. The signature of this method has changed. Where it previously expected a relative path to the unit test case file, it now expects an absolute path.
+ * The unit tests for the utility methods in the `PHPCompatibility\Sniff` class have been moved to a new `PHPCompatibility\Util\Tests\Core` subdirectory.
+ * The bootstrap file used for PHPUnit has been moved to the project root directory and renamed `phpunit-bootstrap.php`.
+- :twisted_rightwards_arrows: The `PHPCompatibility.LanguageConstructs.NewLanguageConstructs` sniff has been split into two sniffs. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738)
+ The `PHPCompatibility.LanguageConstructs.NewLanguageConstructs` sniff now contains just the checks for the namespace separator and the ellipsis.
+ The new `PHPCompatibility.Operators.NewOperators` sniff now contains the checks regarding the pow, pow equals, spaceship and coalesce (equals) operators.
+- :pushpin: The `PHPCompatibility.ParameterValues.RemovedMbstringModifiers` sniff will now also recognize removed regex modifiers when used within a function call to one of the undocumented Mbstring function aliases for the Mbstring regex functions. [#715](https://github.com/PHPCompatibility/PHPCompatibility/pull/715)
+- :pushpin: The `PHPCompatibility\Sniff::getFunctionCallParameter()` utility method now allows for closures called via a variable. [#723](https://github.com/PHPCompatibility/PHPCompatibility/pull/723)
+- :pencil2: `PHPCompatibility.Upgrade.LowPHPCS`: the minimum supported PHPCS version is now 2.3.0. [#699](https://github.com/PHPCompatibility/PHPCompatibility/pull/699)
+- :pencil2: Minor inline documentation improvements. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738)
+- :umbrella: Minor improvements to the unit tests for the `PHPCompatibility.FunctionNameRestrctions.RemovedMagicAutoload` sniff. [#716](https://github.com/PHPCompatibility/PHPCompatibility/pull/716)
+- :recycle: Minor other optimizations. [#698](https://github.com/PHPCompatibility/PHPCompatibility/pull/698), [#697](https://github.com/PHPCompatibility/PHPCompatibility/pull/697)
+- :wrench: Minor improvements to the build tools. [#701](https://github.com/PHPCompatibility/PHPCompatibility/pull/701)
+- :wrench: Removed some unnecessary inline annotations. [#700](https://github.com/PHPCompatibility/PHPCompatibility/pull/700)
+- :books: Replaced some of the badges in the Readme file. [#721](https://github.com/PHPCompatibility/PHPCompatibility/pull/721), [#722](https://github.com/PHPCompatibility/PHPCompatibility/pull/722)
+- :books: Composer: updated the list of package authors. [#739](https://github.com/PHPCompatibility/PHPCompatibility/pull/739)
+
+### Removed
+- :no_entry_sign: Support for PHP_CodeSniffer 1.x and low 2.x versions. The new minimum version of PHP_CodeSniffer to be able to use this library is 2.3.0. [#699](https://github.com/PHPCompatibility/PHPCompatibility/pull/699). Fixes [#691](https://github.com/PHPCompatibility/PHPCompatibility/issues/691).
+ The minimum _recommended_ version of PHP_CodeSniffer remains the same, i.e. 2.6.0.
+- :no_entry_sign: The `\PHPCompatibility\Sniff::inUseScope()` method has been removed as it is no longer needed now support for PHPCS 1.x has been dropped. [#699](https://github.com/PHPCompatibility/PHPCompatibility/pull/699)
+- :no_entry_sign: Composer: The `autoload` section has been removed from the `composer.json` file. [#738](https://github.com/PHPCompatibility/PHPCompatibility/pull/738). Fixes [#568](https://github.com/PHPCompatibility/PHPCompatibility/issues/568).
+ Autoloading for this library is done via the PHP_CodeSniffer default mechanism, enhanced with our own autoloader, so the Composer autoloader shouldn't be needed and was causing issues in a particular use-case.
+
+### Fixed
+- :bug: `PHPCompatibility.FunctionUse.NewFunctionParameters` sniff: The new `$mode` parameter of the `php_uname()` function was added in PHP 4.3, not in PHP 7.0 as was previously being reported.
+ The previous implementation of this check was based on an error in the PHP documentation. The error in the PHP documentation has been rectified and the sniff has followed suit. [#711](https://github.com/PHPCompatibility/PHPCompatibility/pull/711)
+- :bug: `PHPCompatibility.Generators.NewGeneratorReturn` sniff: The sniff would throw false positives for `return` statements in nested constructs and did not correctly detect the scope which should be examined. [#725](https://github.com/PHPCompatibility/PHPCompatibility/pull/725). Fixes [#724](https://github.com/PHPCompatibility/PHPCompatibility/pull/724).
+- :bug: `PHPCompatibility.Keywords.NewKeywords` sniff: PHP magic constants are case _in_sensitive. This sniff now accounts for this. [#707](https://github.com/PHPCompatibility/PHPCompatibility/pull/707)
+- :bug: Various bugs in the `PHPCompatibility.Syntax.ForbiddenCallTimePassByReference` sniff [#723](https://github.com/PHPCompatibility/PHPCompatibility/pull/723):
+ - Closures called via a variable will now also be examined. (false negative)
+ - References within arrays/closures passed as function call parameters would incorrectly trigger an error. (false positive)
+- :green_heart: Compatibility with PHPUnit 7.2. [#712](https://github.com/PHPCompatibility/PHPCompatibility/pull/712)
+
+### Credits
+Thanks go out to [Jonathan Champ] for his contribution to this version. :clap:
+
+
+## [8.2.0] - 2018-07-17
+
+See all related issues and PRs in the [8.2.0 milestone].
+
+### Important changes
+
+#### The repository has moved
+As of July 13 2018, the PHPCompatibility repository has moved from the personal account of Wim Godden `wimg` to its own organization `PHPCompatibility`.
+Composer users are advised to update their `composer.json`. The dependency is now called `phpcompatibility/php-compatibility`.
+
+#### Framework/CMS specific PHPCompatibility rulesets
+Within this new organization, hosting will be offered for framework/CMS specific PHPCompatibility rulesets.
+
+The first two such repositories have been created and are now available for use:
+* PHPCompatibilityJoomla [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityJoomla)|[Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-joomla)
+* PHPCompatibilityWP [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityWP)|[Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-wp)
+
+If you want to make sure you have all PHPCompatibility rulesets available at any time, you can use the PHPCompatibilityAll package [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityAll)|[Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-all).
+
+For more information, see the [Readme](https://github.com/PHPCompatibility/PHPCompatibility#using-a-frameworkcms-specific-ruleset) and [Contributing guidelines](https://github.com/PHPCompatibility/PHPCompatibility/blob/master/.github/CONTRIBUTING.md#frameworkcms-specific-rulesets).
+
+#### Changes expected in PHPCompatibility 9.0.0
+The next version of PHPCompatibility will include a major directory layout restructuring which means that the sniff codes of all sniffs will change.
+
+In this same release, support for PHP_CodeSniffer 1.5.x will be dropped. The new minimum supported PHPCS version will be 2.3.0.
+
+For more information about these upcoming changes, please read the [announcement](https://github.com/PHPCompatibility/PHPCompatibility/issues/688).
+
+The `9.0.0` release is expected to be ready later this summer.
+
+
+### Added
+- :star2: New `ArgumentFunctionsUsage` sniff to detect usage of the `func_get_args()`, `func_get_arg()` and `func_num_args()` functions and the changes regarding these functions introduced in PHP 5.3. [#596](https://github.com/PHPCompatibility/PHPCompatibility/pull/596). Fixes [#372](https://github.com/PHPCompatibility/PHPCompatibility/issues/372).
+- :star2: New `DiscouragedSwitchContinue` sniff to detect `continue` targetting a `switch` control structure for which `E_WARNINGS` will be thrown as of PHP 7.3. [#687](https://github.com/PHPCompatibility/PHPCompatibility/pull/687)
+- :star2: New `NewClassMemberAccess` sniff to detect class member access on instantiation as added in PHP 5.4 and class member access on cloning as added in PHP 7.0. [#619](https://github.com/PHPCompatibility/PHPCompatibility/pull/619). Fixes [#53](https://github.com/PHPCompatibility/PHPCompatibility/issues/53).
+- :star2: New `NewConstantScalarExpressions` sniff to detect PHP 5.6 scalar expression in contexts where PHP previously only allowed static values. [#617](https://github.com/PHPCompatibility/PHPCompatibility/pull/617). Fixes [#399](https://github.com/PHPCompatibility/PHPCompatibility/issues/399).
+- :star2: New `NewGeneratorReturn` sniff to detect `return` statements within generators as introduced in PHP 7.0. [#618](https://github.com/PHPCompatibility/PHPCompatibility/pull/618)
+- :star2: New `PCRENewModifiers` sniff to initially detect the new `J` regex modifier as introduced in PHP 7.2. [#600](https://github.com/PHPCompatibility/PHPCompatibility/pull/600). Fixes [#556](https://github.com/PHPCompatibility/PHPCompatibility/issues/556).
+- :star2: New `ReservedFunctionNames` sniff to report on double underscore prefixed functions and methods. This was previously reported via an upstream sniff. [#581](https://github.com/PHPCompatibility/PHPCompatibility/pull/581)
+- :star2: New `NewTrailingComma` sniff to detect trailing comma's in function calls, method calls, `isset()` and `unset()` as will be introduced in PHP 7.3. [#632](https://github.com/PHPCompatibility/PHPCompatibility/pull/632)
+- :star2: New `Upgrade/LowPHPCS` sniff to give users of old PHP_CodeSniffer versions advance warning when support will be dropped in the near future. [#693](https://github.com/PHPCompatibility/PHPCompatibility/pull/693)
+- :star: `NewClasses` sniff: check for some 40+ additional PHP native classes added in various PHP versions. [#573](https://github.com/PHPCompatibility/PHPCompatibility/pull/573)
+- :star: `NewClosure` sniff: check for usage of `self`/`parent`/`static::` being used within closures, support for which was only added in PHP 5.4. [#669](https://github.com/PHPCompatibility/PHPCompatibility/pull/669). Fixes [#668](https://github.com/PHPCompatibility/PHPCompatibility/pull/668).
+- :star: `NewConstants` sniff: recognize constants added by the PHP 5.5+ password extension. [#626](https://github.com/PHPCompatibility/PHPCompatibility/pull/626)
+- :star: `NewFunctionParameters` sniff: recognize a number of additional function parameters added in PHP 7.0, 7.1 and 7.2. [#602](https://github.com/PHPCompatibility/PHPCompatibility/pull/602)
+- :star: `NewFunctions` sniff: recognize the PHP 5.1 SPL extension functions, the PHP 5.1.1 `hash_hmac()` function, the PHP 5.6 `pg_lo_truncate()` function, more PHP 7.2 Sodium functions and the new PHP 7.3 `is_countable()` function. [#606](https://github.com/PHPCompatibility/PHPCompatibility/pull/606), [#625](https://github.com/PHPCompatibility/PHPCompatibility/pull/625), [#640](https://github.com/PHPCompatibility/PHPCompatibility/pull/640), [#651](https://github.com/PHPCompatibility/PHPCompatibility/pull/651)
+- :star: `NewHashAlgorithms` sniff: recognize the new hash algorithms which were added in PHP 7.1. [#599](https://github.com/PHPCompatibility/PHPCompatibility/pull/599)
+- :star: `NewInterfaces` sniff: check for the PHP 5.0 `Reflector` interface. [#572](https://github.com/PHPCompatibility/PHPCompatibility/pull/572)
+- :star: `OptionalRequiredFunctionParameters` sniff: detect missing `$salt` parameter in calls to the `crypt()` function (PHP 5.6+). [#605](https://github.com/PHPCompatibility/PHPCompatibility/pull/605)
+- :star: `RequiredOptionalFunctionParameters` sniff: recognize that the `$varname` parameter of `getenv()` and the `$scale` parameter of `bcscale()` have become optional as of PHP 7.1 and 7.3 respectively. [#598](https://github.com/PHPCompatibility/PHPCompatibility/pull/598), [#612](https://github.com/PHPCompatibility/PHPCompatibility/pull/612)
+- :star: New `AbstractFunctionCallParameterSniff` to be used as a basis for sniffs examining function call parameters. [#636](https://github.com/PHPCompatibility/PHPCompatibility/pull/636)
+- :star: New `getReturnTypeHintName()` utility method to the `PHPCompatibility\Sniff` class. [#578](https://github.com/PHPCompatibility/PHPCompatibility/pull/578), [#642](https://github.com/PHPCompatibility/PHPCompatibility/pull/642)
+- :star: New `isNumber()`, `isPositiveNumber()` and `isNegativeNumber()` utility methods to the `PHPCompatibility\Sniff` class. [#610](https://github.com/PHPCompatibility/PHPCompatibility/pull/610), [#650](https://github.com/PHPCompatibility/PHPCompatibility/pull/650)
+- :star: New `isShortList()` utility method to the `PHPCompatibility\Sniff` class. [#635](https://github.com/PHPCompatibility/PHPCompatibility/pull/635)
+- :star: New `getCommandLineData()` method to the `PHPCompatibility\PHPCSHelper` class to provide PHPCS cross-version compatible access to command line info at run time. [#693](https://github.com/PHPCompatibility/PHPCompatibility/pull/693)
+- :star: Duplicate of upstream `findEndOfStatement()` method to the `PHPCompatibility\PHPCSHelper` class to allow for PHPCS cross-version usage of that method. [#614](https://github.com/PHPCompatibility/PHPCompatibility/pull/614)
+- :umbrella: additional unit test to confirm that the `PHPCompatibility\Sniff::isUseOfGlobalConstant()` method handles multi-constant declarations correctly. [#587](https://github.com/PHPCompatibility/PHPCompatibility/pull/587)
+- :umbrella: additional unit tests to confirm that the `PHPCompatibility\Sniff::isClassProperty()` method handles multi-property declarations correctly. [#583](https://github.com/PHPCompatibility/PHPCompatibility/pull/583)
+- :books: [Readme](https://github.com/PHPCompatibility/PHPCompatibility#using-a-frameworkcms-specific-ruleset) & [Contributing](https://github.com/PHPCompatibility/PHPCompatibility/blob/master/.github/CONTRIBUTING.md#frameworkcms-specific-rulesets): add information about the framework/CMS specific rulesets. Related PRs: [#615](https://github.com/PHPCompatibility/PHPCompatibility/pull/615), [#624](https://github.com/PHPCompatibility/PHPCompatibility/pull/624), [#648](https://github.com/PHPCompatibility/PHPCompatibility/pull/648), [#674](https://github.com/PHPCompatibility/PHPCompatibility/pull/674), [#685](https://github.com/PHPCompatibility/PHPCompatibility/pull/685), [#694](https://github.com/PHPCompatibility/PHPCompatibility/pull/694). Related to issue [#530](https://github.com/PHPCompatibility/PHPCompatibility/issues/530).
+- :books: Readme: information about the PHPCS 3.3.0 change which allows for a `testVersion` in a custom ruleset to be overruled by the command-line. [#607](https://github.com/PHPCompatibility/PHPCompatibility/pull/607)
+
+### Changed
+- :books: Adjusted references to the old repository location throughout the codebase to reflect the move to a GitHub organization. [#689](https://github.com/PHPCompatibility/PHPCompatibility/pull/689)
+ This repository will now live in [https://github.com/PHPCompatibility/PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) and the Packagist reference will now be `phpcompatibility/php-compatibility`.
+- :white_check_mark: The `getReturnTypeHintToken()` utility method has been made compatible with the changes in the PHPCS tokenizer which were introduced in PHP_CodeSniffer 3.3.0. [#642](https://github.com/PHPCompatibility/PHPCompatibility/pull/642). Fixes [#639](https://github.com/PHPCompatibility/PHPCompatibility/issues/639).
+- :pushpin: `ConstantArrayUsingConst`: improved handling of multi-constant declarations. [#593](https://github.com/PHPCompatibility/PHPCompatibility/pull/593)
+- :pushpin: `NewHeredocInitialize`: improved handling of constant declarations using the `const` keyword.
+ The sniff will now also report on multi-declarations for variables, constants and class properties and on using heredoc as a function parameter default. [#641](https://github.com/PHPCompatibility/PHPCompatibility/pull/641)
+- :pushpin: `ForbiddenEmptyListAssignment`: this sniff will now also report on empty list assignments when the PHP 7.1 short list syntax is used. [#653](https://github.com/PHPCompatibility/PHPCompatibility/pull/653)
+- :pushpin: The `ForbiddenNegativeBitshift` sniff would previously only report on "bitshift right". As of this version, "bitshift left" and bitshift assignments will also be recognized. [#614](https://github.com/PHPCompatibility/PHPCompatibility/pull/614)
+- :pushpin: The `NewClasses` and `NewInterfaces` sniffs will now also report on new classes/interfaces when used as _return type_ declarations. [#578](https://github.com/PHPCompatibility/PHPCompatibility/pull/578)
+- :pushpin: The `NewScalarTypeDeclarations` sniff will now recognize `parent` as a valid type declaration.
+ The sniff will now also throw an error about using `self` and `parent` when PHP < 5.2 needs to be supported as PHP 5.1 and lower would presume these to be class names instead of keywords. [#595](https://github.com/PHPCompatibility/PHPCompatibility/pull/595)
+- :pushpin: The `PregReplaceEModifier` sniff - and the `PCRENewModifiers` sniff by extension - will now correctly examine and report on modifiers in regexes passed via calls to `preg_replace_callback_array()`. [#600](https://github.com/PHPCompatibility/PHPCompatibility/pull/600), [#636](https://github.com/PHPCompatibility/PHPCompatibility/pull/636)
+- :pushpin: `getReturnTypeHintToken()` utility method: improved support for interface methods and abstract function declarations. [#652](https://github.com/PHPCompatibility/PHPCompatibility/pull/652)
+- :pushpin: The `findExtendedClassName()`, `findImplementedInterfaceNames()`, `getMethodParameters()` utility methods which are duplicates of upstream PHPCS methods, have been moved from the `PHPCompatibility\Sniff` class to the `PHPCompatibility\PHPCSHelper` class and have become static methods. [#613](https://github.com/PHPCompatibility/PHPCompatibility/pull/613)
+- :white_check_mark: `getReturnTypeHintToken()` utility method: align returned `$stackPtr` with native PHPCS behaviour by returning the last token of the type declaration. [#575](https://github.com/PHPCompatibility/PHPCompatibility/pull/575)
+- :white_check_mark: PHPCS cross-version compatibility: sync `getMethodParameters()` method with improved upstream version. [#643](https://github.com/PHPCompatibility/PHPCompatibility/pull/643)
+- :pencil2: The `MbstringReplaceEModifier`, `PregReplaceEModifier` and the `PregReplaceEModifier` sniffs now `extend` the new `AbstractFunctionCallParameterSniff` class. This should yield more accurate results when checking whether one of the target PHP functions was called. [#636](https://github.com/PHPCompatibility/PHPCompatibility/pull/636)
+- :pencil2: `DeprecatedNewReference` sniff: minor change to the error text and code - was `Forbidden`, now `Removed` -. Custom rulesets which explicitly excluded this error code will need to be updated. [#594](https://github.com/PHPCompatibility/PHPCompatibility/pull/594)
+- :pencil2: `NewScalarTypeDeclarations` sniff: minor change to the error message text.[#644](https://github.com/PHPCompatibility/PHPCompatibility/pull/644)
+- :umbrella: The unit test framework now allows for sniffs in categories other than `PHP`. [#634](https://github.com/PHPCompatibility/PHPCompatibility/pull/634)
+- :umbrella: Boyscouting: fixed up some (non-relevant) parse errors in a unit test case file. [#576](https://github.com/PHPCompatibility/PHPCompatibility/pull/576)
+- :green_heart: Travis: build tests are now also being run against the lowest supported PHPCS 3.x version. Previously only the highest supported PHPCS 3.x version was tested against. [#633](https://github.com/PHPCompatibility/PHPCompatibility/pull/633)
+- :books: Readme: Improved Composer install instructions. [#690](https://github.com/PHPCompatibility/PHPCompatibility/pull/690)
+- :books: Minor documentation fixes. [#672](https://github.com/PHPCompatibility/PHPCompatibility/pull/672)
+- :wrench: Minor performance optimizations and code simplifications. [#592](https://github.com/PHPCompatibility/PHPCompatibility/pull/592), [#630](https://github.com/PHPCompatibility/PHPCompatibility/pull/630), [#671](https://github.com/PHPCompatibility/PHPCompatibility/pull/671)
+- :wrench: Composer: Various improvements, including improved information about the suggested packages, suggesting `roave/security-advisories`, allowing for PHPUnit 7.x. [#604](https://github.com/PHPCompatibility/PHPCompatibility/pull/604/files), [#616](https://github.com/PHPCompatibility/PHPCompatibility/pull/616), [#622](https://github.com/PHPCompatibility/PHPCompatibility/pull/622), [#646](https://github.com/PHPCompatibility/PHPCompatibility/pull/646)
+- :wrench: Various Travis build script improvements, including tweaks for faster build time, validation of the `composer.json` file, validation of the framework specific rulesets. [#570](https://github.com/PHPCompatibility/PHPCompatibility/pull/570), [#571](https://github.com/PHPCompatibility/PHPCompatibility/pull/571), [#579](https://github.com/PHPCompatibility/PHPCompatibility/pull/579), [#621](https://github.com/PHPCompatibility/PHPCompatibility/pull/621), [#631](https://github.com/PHPCompatibility/PHPCompatibility/pull/631)
+- :wrench: Build/PHPCS: made some more CS conventions explicit and start using PHPCS 3.x options for the PHPCompatibility native ruleset. [#586](https://github.com/PHPCompatibility/PHPCompatibility/pull/586), [#667](https://github.com/PHPCompatibility/PHPCompatibility/pull/667), [#673](https://github.com/PHPCompatibility/PHPCompatibility/pull/673)
+- :wrench: Some code style clean up and start using the new inline PHPCS 3.2+ annotations where applicable. [#586](https://github.com/PHPCompatibility/PHPCompatibility/pull/586), [#591](https://github.com/PHPCompatibility/PHPCompatibility/pull/591), [#620](https://github.com/PHPCompatibility/PHPCompatibility/pull/620), [#673](https://github.com/PHPCompatibility/PHPCompatibility/pull/673)
+
+### Removed
+- :no_entry_sign: PHPCompatibility no longer explicitly supports PHP_CodeSniffer 2.2.0. [#687](https://github.com/PHPCompatibility/PHPCompatibility/pull/687), [#690](https://github.com/PHPCompatibility/PHPCompatibility/pull/690)
+- :no_entry_sign: The PHPCompatibility ruleset no longer includes the PHPCS native `Generic.NamingConventions.CamelCapsFunctionName`. Double underscore prefixed function names are now being reported on by a new dedicated sniff. [#581](https://github.com/PHPCompatibility/PHPCompatibility/pull/581)
+- :no_entry_sign: PHPCompatibility no longer explicitly supports HHVM and builds are no longer tested against HHVM.
+ For now, running PHPCompatibility on HHVM to test PHP code may still work for a little while, but HHVM has announced they are [dropping PHP support](https://hhvm.com/blog/2017/09/18/the-future-of-hhvm.html). [#623](https://github.com/PHPCompatibility/PHPCompatibility/pull/623). Fixes [#603](https://github.com/PHPCompatibility/PHPCompatibility/issues/603).
+- :books: Readme: badges from services which are no longer supported or inaccurate. [#609](https://github.com/PHPCompatibility/PHPCompatibility/pull/609), [#628](https://github.com/PHPCompatibility/PHPCompatibility/pull/628)
+
+### Fixed
+- :bug: Previously, the PHPCS native `Generic.NamingConventions.CamelCapsFunctionName` sniff was included in PHPCompatibility. Some error codes of this sniff were excluded, as well as some error messages changed (via the ruleset).
+ If/when PHPCompatibility would be used in combination with a code style-type ruleset, this could inadvertently lead to underreporting of issues which the CS-type ruleset intends to have reported - i.e. the error codes excluded by PHPCompatibility -. This has now been fixed. [#581](https://github.com/PHPCompatibility/PHPCompatibility/pull/581)
+- :bug: The `ForbiddenNegativeBitshift` sniff would incorrectly throw an error when a bitshift was based on a calculation which included a negative number, but would not necessarily result in a negative number. [#614](https://github.com/PHPCompatibility/PHPCompatibility/pull/614). Fixes [#294](https://github.com/PHPCompatibility/PHPCompatibility/issues/294), [#466](https://github.com/PHPCompatibility/PHPCompatibility/issues/466).
+- :bug: The `NewClosure` sniff would report the same issue twice when the issue was encountered in a nested closure. [#669](https://github.com/PHPCompatibility/PHPCompatibility/pull/669)
+- :bug: The `NewKeywords` sniff would underreport on non-lowercase keywords. [#627](https://github.com/PHPCompatibility/PHPCompatibility/pull/627)
+- :bug: The `NewKeywords` sniff would incorrectly report on the use of class constants and class properties using the same name as a keyword. [#627](https://github.com/PHPCompatibility/PHPCompatibility/pull/627)
+- :bug: The `NewNullableTypes` sniff would potentially underreport when comments where interspersed in the (return) type declarations. [#577](https://github.com/PHPCompatibility/PHPCompatibility/pull/577)
+- :bug: The `Sniff::getFunctionCallParameters()` utility method would in rare cases return incorrect results when it encountered a closure as a parameter. [#682](https://github.com/PHPCompatibility/PHPCompatibility/pull/682)
+- :bug: The `Sniff::getReturnTypeHintToken()` utility method would not always return a `$stackPtr`. [#645](https://github.com/PHPCompatibility/PHPCompatibility/pull/645)
+- :bug: Minor miscellanous other bugfixes. [#670](https://github.com/PHPCompatibility/PHPCompatibility/pull/670)
+- :umbrella: `PHPCompatibility\Tests\BaseClass\MethodTestFrame::getTargetToken()` could potentially not find the correct token to run a test against. [#588](https://github.com/PHPCompatibility/PHPCompatibility/pull/588)
+
+### Credits
+Thanks go out to [Michael Babker] and [Juliette Reinders Folmer] for their contributions to this version. :clap:
+
+
+## [8.1.0] - 2017-12-27
+
+See all related issues and PRs in the [8.1.0 milestone].
+
+### Added
+- :star2: New `NewConstants` and `RemovedConstants` sniffs to detect usage of new/removed PHP constants for all PHP versions from PHP 5 up. [#526](https://github.com/wimg/PHPCompatibility/pull/525), [#551](https://github.com/wimg/PHPCompatibility/pull/551), [#566](https://github.com/wimg/PHPCompatibility/pull/566). Fixes [#263](https://github.com/wimg/PHPCompatibility/issues/263).
+- :star2: New `MagicAutoloadDeprecation` sniff to detect deprecated `__autoload()` functions as deprecated in PHP 7.2. [#540](https://github.com/wimg/PHPCompatibility/pull/540)
+- :star2: New `OptionalRequiredFunctionParameter` sniff to check for missing function call parameters which were required and only became optional in a later PHP version. [#524](https://github.com/wimg/PHPCompatibility/pull/524)
+- :star2: New `DynamicAccessToStatic` sniff to detect dynamic access to static methods and properties, as well as class constants, prior to PHP 5.3. [#535](https://github.com/wimg/PHPCompatibility/pull/535). Fixes [#534](https://github.com/wimg/PHPCompatibility/issues/534).
+- :star: `DeprecatedFunctions` sniff: recognize yet more PHP 7.2 deprecated functions. [#561](https://github.com/wimg/PHPCompatibility/pull/561), [#566](https://github.com/wimg/PHPCompatibility/pull/566)
+- :star: `DeprecatedIniDirectives` sniff: recognize the last of the PHP 7.2 deprecated ini directives. [#566](https://github.com/wimg/PHPCompatibility/pull/566), [#567](https://github.com/wimg/PHPCompatibility/pull/567)
+- :star: `NewFunctions` : detection of all new PHP 7.2 functions added. [#522](https://github.com/wimg/PHPCompatibility/pull/522), [#545](https://github.com/wimg/PHPCompatibility/pull/545), [#551](https://github.com/wimg/PHPCompatibility/pull/551), [#565](https://github.com/wimg/PHPCompatibility/pull/565)
+- :star: `RemovedExtensions` : report on usage of the `mcrypt` extension which has been removed in PHP 7.2. [#566](https://github.com/wimg/PHPCompatibility/pull/566)
+- :star: `RemovedGlobalVariables` : detection of the use of `$php_errormsg` with `track_errors` which has been deprecated in PHP 7.2. [#528](https://github.com/wimg/PHPCompatibility/pull/528)
+- :books: Documentation : added reporting usage instructions. [#533](https://github.com/wimg/PHPCompatibility/pull/533), [#552](https://github.com/wimg/PHPCompatibility/pull/552)
+
+### Changed
+- :pushpin: `NewClosures` : downgraded "$this found in closure outside class" to warning. [#536](https://github.com/wimg/PHPCompatibility/pull/535). Fixes [#527](https://github.com/wimg/PHPCompatibility/issues/527).
+- :pushpin: `ForbiddenGlobalVariableVariable` : the sniff will now throw an error for each variable in a `global` statement which is no longer supported and show the variable found to make it easier to fix this. Previously only one error would be thrown per `global` statement. [#564](https://github.com/wimg/PHPCompatibility/pull/564)
+- :pushpin: `ForbiddenGlobalVariableVariable` : the sniff will now throw `warning`s for non-bare variables used in a `global` statement as those are discouraged since PHP 7.0. [#564](https://github.com/wimg/PHPCompatibility/pull/564)
+- :rewind: `NewLanguageConstructs` : updated the version number for `T_COALESCE_EQUAL`. [#523](https://github.com/wimg/PHPCompatibility/pull/523)
+- :pencil2: `Sniff::getTestVersion()` : simplified regex logic. [#520](https://github.com/wimg/PHPCompatibility/pull/520)
+- :green_heart: Travis : build tests are now being run against PHP 7.2 as well. [#511](https://github.com/wimg/PHPCompatibility/pull/511)
+- :wrench: Improved check for superfluous whitespaces in files. [#542](https://github.com/wimg/PHPCompatibility/pull/542)
+- :wrench: Build/PHPCS : stabilized the exclude patterns. [#529](https://github.com/wimg/PHPCompatibility/pull/529)
+- :wrench: Build/PHPCS : added array indentation check. [#538](https://github.com/wimg/PHPCompatibility/pull/538)
+- :white_check_mark: PHPCS cross-version compatibility : sync `FindExtendedClassname()` method with upstream. [#507](https://github.com/wimg/PHPCompatibility/pull/507)
+- :wrench: The minimum version for the recommended `DealerDirect/phpcodesniffer-composer-installer` Composer plugin has been upped to `0.4.3`. [#548](https://github.com/wimg/PHPCompatibility/pull/548)
+
+### Fixed
+- :bug: `ForbiddenCallTimePassByReference` : a false positive was being thrown when a global constant was followed by a _bitwise and_. [#562](https://github.com/wimg/PHPCompatibility/pull/562). Fixes [#39](https://github.com/wimg/PHPCompatibility/issues/39).
+- :bug: `ForbiddenGlobalVariableVariable` : the sniff was overzealous and would also report on `global` in combination with variable variables which are still supported. [#564](https://github.com/wimg/PHPCompatibility/pull/564). Fixes [#537](https://github.com/wimg/PHPCompatibility/issues/537).
+- :bug: `ForbiddenGlobalVariableVariable` : variables interspersed with whitespace and/or comments were not being reported. [#564](https://github.com/wimg/PHPCompatibility/pull/564)
+- :rewind: `ForbiddenNamesAsInvokedFunctions` : improved recognition of function invocations using forbidden words and prevent warnings for keywords which are no longer forbidden as method names in PHP 7.0+. [#516](https://github.com/wimg/PHPCompatibility/pull/516). Fixes [#515](https://github.com/wimg/PHPCompatibility/issues/515)
+- :bug: `VariableVariables` : variables interspersed with whitespace and/or comments were not being reported. [#563](https://github.com/wimg/PHPCompatibility/pull/563)
+- :umbrella: Fixed some unintentional syntax errors in test files. [#539](https://github.com/wimg/PHPCompatibility/pull/539)
+- :umbrella: Tests : fixed case numbering error. [#525](https://github.com/wimg/PHPCompatibility/pull/525)
+- :books: Tests : added missing test skip explanation. [#521](https://github.com/wimg/PHPCompatibility/pull/521)
+- :wrench: Fixed PHPCS whitespaces. [#543](https://github.com/wimg/PHPCompatibility/pull/543)
+- :wrench: Fixed code test coverage verification. [#550](https://github.com/wimg/PHPCompatibility/pull/550). Fixes [#549](https://github.com/wimg/PHPCompatibility/issues/549).
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] and [Jonathan Van Belle] for their contributions to this version. :clap:
+
+
+## [8.0.1] - 2017-08-07
+
+See all related issues and PRs in the [8.0.1 milestone].
+
+### Added
+- :star2: New `DeprecatedTypeCasts` sniff to detect deprecated and removed type casts, such as the `(unset)` type cast as deprecated in PHP 7.2. [#498](https://github.com/wimg/PHPCompatibility/pull/498)
+- :star2: New `NewTypeCasts` sniff to detect type casts not present in older PHP versions such as the `(binary)` type cast as added in PHP 5.2.1. [#497](https://github.com/wimg/PHPCompatibility/pull/497)
+- :star: `NewGroupUseDeclaration`: Detection of PHP 7.2 trailing comma's in group use statements. [#504](https://github.com/wimg/PHPCompatibility/pull/504)
+- :star: `DeprecatedFunctions` sniff: recognize some more PHP 7.2 deprecated functions. [#501](https://github.com/wimg/PHPCompatibility/pull/501)
+- :star: `DeprecatedIniDirectives` sniff: recognize more PHP 7.2 deprecated ini directives. [#500](https://github.com/wimg/PHPCompatibility/pull/500)
+- :star: `ForbiddenNames` sniff: recognize `object` as a forbidden keyword since PHP 7.2. [#499](https://github.com/wimg/PHPCompatibility/pull/499)
+- :star: `NewReturnTypeDeclarations` sniff: recognize generic `parent`, PHP 7.1 `iterable` and PHP 7.2 `object` return type declarations. [#505](https://github.com/wimg/PHPCompatibility/pull/505), [#499](https://github.com/wimg/PHPCompatibility/pull/499)
+- :star: `NewScalarTypeDeclarations` sniff: recognize PHP 7.2 `object` type declarion. [#499](https://github.com/wimg/PHPCompatibility/pull/499)
+
+### Changed
+- :pencil2: Improved clarity of the deprecated functions alternative in the error message. [#502](https://github.com/wimg/PHPCompatibility/pull/502)
+
+### Fixed
+- :fire_engine: Temporary hotfix for installed_paths (pending [upstream fix](https://github.com/squizlabs/PHP_CodeSniffer/issues/1591).) [#503](https://github.com/wimg/PHPCompatibility/pull/503)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+
+## [8.0.0] - 2017-08-03
+
+**IMPORTANT**: This release contains a **breaking change**. Please read the below information carefully before upgrading!
+
+The directory layout of the PHPCompatibility standard has been changed for improved compatibility with Composer.
+This means that the PHPCompatibility standard no longer extends from the root directory of the repository, but now lives in its own subdirectory `/PHPCompatibility`.
+
+This release also bring compatibility with PHPCS 3.x to the PHPCompatibility standard.
+
+There are two things you will need to be aware of:
+* The path to the PHPCompatibility standard has changed.
+* If you intend to upgrade to PHPCS 3.x, the path to the `phpcs` script has changed (upstream change).
+
+Please follow the below upgrade instructions carefully. This should be a one-time only action.
+
+### Upgrade instructions
+
+### Before upgrading
+
+If you had previously made accommodations for the old directory layout, you should remove any such _"hacks"_ (meant in the kindest of ways) now.
+
+By this we mean: symlinks for the PHPCompatibility install to the `PHP_CodeSniffer/CodeSniffer/Standards` directory, scripts to move the sniffs files to the PHPCS directory, scripts which made symlinks etc.
+
+So, please remove those first.
+
+> **Side-note**:
+>
+> If you had previously forked this repository to solve this issue, please consider reverting your fork to the official version or removing it all together.
+
+### Upgrading: re-registering PHPCompatibility with PHP CodeSniffer
+
+External PHP CodeSniffer standards need to be registered with PHP CodeSniffer. You have probably done this the first time you used PHPCompatibility or have a script or Composer plugin in place to do this for you.
+
+As the directory layout of PHPCompatibility has changed, the path previously registered with PHP CodeSniffer will no longer work and running `phpcs -i` will **_not_** list PHPCompatibility as one of the registered standards.
+
+#### Using a Composer plugin
+
+If you use Composer, we recommend you use a Composer plugin to sort this out. In previous install instructions we recommended the SimplyAdmin plugin for this. This plugin has since been abandoned. We now recommend the DealerDirect plugin.
+```bash
+composer remove --dev simplyadmire/composer-plugins
+composer require --dev dealerdirect/phpcodesniffer-composer-installer:^0.4.3
+composer install
+composer update phpcompatibility/php-compatibility squizlabs/php_codesniffer
+vendor/bin/phpcs -i
+```
+If all went well, you should now see PHPCompatibility listed again in the list of installed standards.
+
+#### Manually re-registering PHPCompatibility
+
+1. First run `phpcs --config-show` to check which path(s) are currently registered with PHP CodeSniffer for external standards.
+2. Check in the below table what the new path for PHPCompatibility will be - the path should point to the root directory of your PHPCompatibility install (not to the sub-directory of the same name):
+
+ Install type | Old path | New path
+ ------------ | -------- | ---------
+ Composer | `vendor/wimg` | `vendor/phpcompatibility/php-compatibility`
+ Unzipped release to arbitrary directory | `path/to/dir/abovePHPCompatibility` | `path/to/dir/abovePHPCompatibility/PHPCompatibility`
+ Git checkout | `path/to/dir/abovePHPCompatibility` | `path/to/dir/abovePHPCompatibility/PHPCompatibility`
+ PEAR | If the old install instruction has been followed, not registered. | `path/to/PHPCompatibility`
+
+ > **Side-note**:
+ >
+ > If you used the old install instructions for a PEAR install, i.e. checking out the latest release to the `PHP/CodeSniffer/Standards/PHPCompatibility` directory, and you intend to upgrade to PHP CodeSniffer 3.x, it is recommended you move the PHPCompatibility folder out of the PEAR directory now, as the layout of the PHPCS directory has changed with PHPCS 3.x and you may otherwise lose your PHPCompatibility install when you upgrade PHP CodeSniffer via PEAR.
+
+3. There are two ways in which you can register the new `installed_paths` value with PHP CodeSniffer. Choose your preferred method:
+ * Run `phpcs --config-set installed_paths ...` and include all previously installed paths including the _adjusted_ path for the PHPCompatibility standard.
+
+ For example, if the previous value of `installed_paths` was
+
+ `/path/to/MyStandard,/path/to/dir/abovePHPCompatibility`
+
+ you should now set it using
+
+ `phpcs --config-set installed_paths /path/to/MyStandard,/path/to/PHPCompatibility`
+
+ * If you use a custom ruleset in combination with PHPCS 2.6.0 or higher, you can pass the value to PHPCS from your custom ruleset:
+ ```xml
+
+ ```
+4. Run `phpcs -i` to verify that the PHPCompatibility standard is now listed again in the list of installed standards.
+
+
+### Upgrading to PHPCS 3.x
+
+The path to the `phpcs` script has changed in PHPCS 3.x which will impact how you call PHPCS.
+
+Version | PHPCS 2.x | PHPCS 3.x
+------- | --------- | ---------
+Generic `phpcs` Command | `path/to/PHP_CodeSniffer/scripts/phpcs ....` | `path/to/PHP_CodeSniffer/bin/phpcs ....`
+Composer command | `vendor/bin/phpcs ...` | `vendor/bin/phpcs ...`
+
+So, for Composer users, nothing changes. For everyone else, you may want to add the `path/to/PHP_CodeSniffer/bin/phpcs` path to your PATH environment variable or adjust any scripts - like build scripts - which call PHPCS.
+
+
+### Upgrading a Travis build script
+
+If you run PHPCompatibility against your code as part of your Travis build:
+* If you use Composer to install PHP CodeSniffer and PHPCompatibility on the travis image and you've made the above mentioned changes, your build should pass again.
+* If you use `git clone` to install PHP CodeSniffer and PHPCompatibility on the travis image, your build will fail until you make the following changes:
+ 1. Check which branch of PHPCS is being checked out. If you previously fixed this to a pre-PHPCS 3.x branch or tag, you can now change this (back) to `master` or a PHPCS 3 tag.
+ 2. Check to which path PHPCompatibility is being cloned and adjust the path if necessary.
+ 3. Adjust the `phpcs --config-set installed_paths` command as described above to point to the root of the cloned PHPCompatibility repo.
+ 4. If you switched to using PHPCS 3.x, adjust the call to PHPCS.
+
+
+
+### Changelog for version 8.0.0
+
+See all related issues and PRs in the [8.0.0 milestone].
+
+### Added
+- :two_hearts: Support for PHP CodeSniffer 3.x. [#482](https://github.com/wimg/PHPCompatibility/pull/482), [#481](https://github.com/wimg/PHPCompatibility/pull/481), [#480](https://github.com/wimg/PHPCompatibility/pull/480), [#488](https://github.com/wimg/PHPCompatibility/pull/488), [#489](https://github.com/wimg/PHPCompatibility/pull/489), [#495](https://github.com/wimg/PHPCompatibility/pull/495)
+
+### Changed
+- :gift: As of this version PHPCompatibility will use semantic versioning.
+- :fire: The directory structure of the repository has changed for better compatibility with installation via Composer. [#446](https://github.com/wimg/PHPCompatibility/pull/446). Fixes [#102](https://github.com/wimg/PHPCompatibility/issues/102), [#107](https://github.com/wimg/PHPCompatibility/issues/107)
+- :pencil2: The custom `functionWhitelist` property for the `PHPCompatibility.PHP.RemovedExtensions` sniff is now only supported in combination with PHP CodeSniffer 2.6.0 or higher (due to an upstream bug which was fixed in PHPCS 2.6.0). [#482](https://github.com/wimg/PHPCompatibility/pull/482)
+- :wrench: Improved the information provided to Composer from the `composer.json` file. [#446](https://github.com/wimg/PHPCompatibility/pull/446), [#482](https://github.com/wimg/PHPCompatibility/pull/482), [#486](https://github.com/wimg/PHPCompatibility/pull/486)
+- :wrench: Release archives will no longer contain the unit tests and other typical development files. You can still get these by using Composer with `--prefer-source` or by checking out a git clone of the repository. [#494](https://github.com/wimg/PHPCompatibility/pull/494)
+- :wrench: A variety of minor improvements to the build process. [#485](https://github.com/wimg/PHPCompatibility/pull/485), [#486](https://github.com/wimg/PHPCompatibility/pull/486), [#487](https://github.com/wimg/PHPCompatibility/pull/487)
+- :wrench: Some files for use by contributors have been renamed to use `.dist` extensions or moved for easier access. [#478](https://github.com/wimg/PHPCompatibility/pull/478), [#479](https://github.com/wimg/PHPCompatibility/pull/479), [#483](https://github.com/wimg/PHPCompatibility/pull/483), [#493](https://github.com/wimg/PHPCompatibility/pull/493)
+- :books: The installation instructions in the Readme. [#496](https://github.com/wimg/PHPCompatibility/pull/496)
+- :books: The unit test instructions in the Contributing file. [#496](https://github.com/wimg/PHPCompatibility/pull/496)
+- :books: Improved the example code in the Readme. [#490](https://github.com/wimg/PHPCompatibility/pull/490)
+
+### Removed
+- :no_entry_sign: Support for PHP 5.1 and 5.2.
+
+ The sniffs can now only be run on PHP 5.3 or higher in combination with PHPCS 1.5.6 or 2.x and on PHP 5.4 or higher in combination with PHPCS 3.x. [#484](https://github.com/wimg/PHPCompatibility/pull/484), [#482](https://github.com/wimg/PHPCompatibility/pull/482)
+
+### Credits
+Thanks go out to [Gary Jones] and [Juliette Reinders Folmer] for their contributions to this version. :clap:
+
+
+## [7.1.5] - 2017-07-17
+
+See all related issues and PRs in the [7.1.5 milestone].
+
+### Added
+- :star: The `NewKeywords` sniff will now also sniff for `yield from` which was introduced in PHP 7.0. [#477](https://github.com/wimg/PHPCompatibility/pull/477). Fixes [#476](https://github.com/wimg/PHPCompatibility/issues/476)
+- :books: The LGPL-3.0 license. [#447](https://github.com/wimg/PHPCompatibility/pull/447)
+
+### Changed
+- :rewind: The `NewExecutionDirectives` sniff will now also report on execution directives when used in combination with PHPCS 2.0.0-2.3.3. [#451](https://github.com/wimg/PHPCompatibility/pull/451)
+- :rewind: The `getMethodParameters()` utility method will no longer break when used with PHPCS 1.5.x < 1.5.6. This affected a number of sniffs. [#452](https://github.com/wimg/PHPCompatibility/pull/452)
+- :rewind: The `inUseScope()` utility method will no longer break when used with PHPCS 2.0.0 - 2.2.0. This affected a number of sniffs. [#454](https://github.com/wimg/PHPCompatibility/pull/454)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#443](https://github.com/wimg/PHPCompatibility/pull/443), [#474](https://github.com/wimg/PHPCompatibility/pull/474)
+- :pencil2: Renamed a test file for consistency. [#453](https://github.com/wimg/PHPCompatibility/pull/453)
+- :wrench: Code style clean up. [#429](https://github.com/wimg/PHPCompatibility/pull/429)
+- :wrench: Prevent Composer installing PHPCS 3.x. **_PHPCS 3.x is not (yet) supported by the PHPCompatibility standard, but will be in the near future._** [#444](https://github.com/wimg/PHPCompatibility/pull/444)
+- :green_heart: The code base will now be checked for consistent code style during build testing. [#429](https://github.com/wimg/PHPCompatibility/pull/429)
+- :green_heart: The sniffs are now also tested against HHVM for consistent results. _Note: the sniffs do not contain any HHVM specific checks nor is there any intention to add them at this time._ [#450](https://github.com/wimg/PHPCompatibility/pull/450)
+- :books: Made it explicit that - at this moment - PHPCS 3.x is not (yet) supported. [#444](https://github.com/wimg/PHPCompatibility/pull/444)
+- :books: Minor improvements to the Readme. [#448](https://github.com/wimg/PHPCompatibility/pull/448), [#449](https://github.com/wimg/PHPCompatibility/pull/449), [#468](https://github.com/wimg/PHPCompatibility/pull/468)
+- :books: Minor improvements to the Contributing guidelines. [#467](https://github.com/wimg/PHPCompatibility/pull/467)
+
+### Removed
+- :no_entry_sign: The `DefaultTimeZoneRequired` sniff. This sniff was checking server settings rather than code. [#458](https://github.com/wimg/PHPCompatibility/pull/458). Fixes [#457](https://github.com/wimg/PHPCompatibility/issues/457)
+- :no_entry_sign: The `NewMagicClassConstant` sniff as introduced in v 7.1.4 contained two additional checks for not strictly compatibility related issues. One of these was plainly wrong, the other opinionated. Both have been removed. [#442](https://github.com/wimg/PHPCompatibility/pull/442). Fixes [#436](https://github.com/wimg/PHPCompatibility/issues/436)
+
+### Fixed
+- :bug: `NewClass` sniff: was reporting an incorrect introduction version number for a few of the Exception classes. [#441](https://github.com/wimg/PHPCompatibility/pull/441). Fixes [#440](https://github.com/wimg/PHPCompatibility/issues/440).
+- :bug: `ForbiddenBreakContinueVariableArguments` sniff: was incorrectly reporting an error if the `break` or `continue` was followed by a PHP closing tag (breaking out of PHP). [#462](https://github.com/wimg/PHPCompatibility/pull/462). Fixes [#460](https://github.com/wimg/PHPCompatibility/issues/460)
+- :bug: `ForbiddenGlobalVariableVariable` sniff: was incorrectly reporting an error if the `global` statement was followed by a PHP closing tag (breaking out of PHP). [#463](https://github.com/wimg/PHPCompatibility/pull/463).
+- :bug: `DeprecatedFunctions` sniff: was reporting false positives for classes using the same name as a deprecated function. [#465](https://github.com/wimg/PHPCompatibility/pull/465). Fixes [#464](https://github.com/wimg/PHPCompatibility/issues/464)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] and [Mark Clements] for their contributions to this version. :clap:
+
+
+## [7.1.4] - 2017-05-06
+
+See all related issues and PRs in the [7.1.4 milestone].
+
+### Added
+- :star2: New `CaseSensitiveKeywords` sniff to detect use of non-lowercase `self`, `static` and `parent` keywords which could cause compatibility issues pre-PHP 5.5. [#382](https://github.com/wimg/PHPCompatibility/pull/382)
+- :star2: New `ConstantArraysUsingConst` sniff to detect constants defined using the `const` keyword being assigned an array value which was not supported prior to PHP 5.6. [#397](https://github.com/wimg/PHPCompatibility/pull/397)
+- :star2: New `ForbiddenClosureUseVariableNames` sniff to detect PHP 7.1 forbidden variable names in closure use statements. [#386](https://github.com/wimg/PHPCompatibility/pull/386). Fixes [#374](https://github.com/wimg/PHPCompatibility/issues/374)
+- :star2: New `NewArrayStringDereferencing` sniff to detect array and string literal dereferencing as introduced in PHP 5.5. [#388](https://github.com/wimg/PHPCompatibility/pull/388)
+- :star2: New `NewHeredocInitialize` sniff to detect initialization of static variables and class properties/constants using the heredoc syntax which is supported since PHP 5.3. [#391](https://github.com/wimg/PHPCompatibility/pull/391). Fixes [#51](https://github.com/wimg/PHPCompatibility/issues/51)
+- :star2: New `NewMagicClassConstant` sniff to detect use of the magic `::class` constant as introduced in PHP 5.5. [#403](https://github.com/wimg/PHPCompatibility/pull/403). Fixes [#364](https://github.com/wimg/PHPCompatibility/issues/364).
+- :star2: New `NewUseConstFunction` sniff to detect use statements importing constants and functions as introduced in PHP 5.6. [#401](https://github.com/wimg/PHPCompatibility/pull/401)
+- :star: `DeprecatedFunctions` sniff: recognize PHP 7.2 deprecated GD functions. [#392](https://github.com/wimg/PHPCompatibility/pull/392)
+- :star: `DeprecatedIniDirectives` sniff: recognize PHP 7.2 deprecated `mbstring.func_overload` directive. [#377](https://github.com/wimg/PHPCompatibility/pull/377)
+- :star: `NewClasses` sniff: check for the PHP 5.1 `libXMLError` class. [#412](https://github.com/wimg/PHPCompatibility/pull/412)
+- :star: `NewClasses` sniff: recognize all native PHP Exception classes. [#418](https://github.com/wimg/PHPCompatibility/pull/418)
+- :star: `NewClosure` sniff: check for closures being declared as static and closures using `$this`. Both of which was not supported pre-PHP 5.4. [#389](https://github.com/wimg/PHPCompatibility/pull/389). Fixes [#24](https://github.com/wimg/PHPCompatibility/issues/24).
+- :star: `NewFunctionParameters` sniff: recognize new `exclude_disabled` parameter for the `get_defined_functions()` function as introduced in PHP 7.0.15. [#375](https://github.com/wimg/PHPCompatibility/pull/375)
+- :star: `NewFunctions` sniff: recognize new PHP 7.2 socket related functions. [#376](https://github.com/wimg/PHPCompatibility/pull/376)
+- :star: `NewInterfaces` sniff: check for some more PHP native interfaces. [#411](https://github.com/wimg/PHPCompatibility/pull/411)
+- :star: New `isClassProperty()`, `isClassConstant()` and `validDirectScope()` utility methods to the `PHPCompatibility_Sniff` class. [#393](https://github.com/wimg/PHPCompatibility/pull/393), [#391](https://github.com/wimg/PHPCompatibility/pull/391).
+- :star: New `getTypeHintsFromFunctionDeclaration()` utility method to the `PHPCompatibility_Sniff` class. [#414](https://github.com/wimg/PHPCompatibility/pull/414).
+- :umbrella: Unit tests against false positives for the `NewMagicMethods` sniff. [#381](https://github.com/wimg/PHPCompatibility/pull/381)
+- :umbrella: More unit tests for the `getTestVersion()` utility method. [#405](https://github.com/wimg/PHPCompatibility/pull/405), [#430](https://github.com/wimg/PHPCompatibility/pull/430)
+- :green_heart: The XML of the ruleset will now be validated and checked for consistent code style during the build testing by Travis. [#433](https://github.com/wimg/PHPCompatibility/pull/433)
+- :books: Readme: information about setting `installed_paths` via a custom ruleset. [#407](https://github.com/wimg/PHPCompatibility/pull/407)
+- :books: `Changelog.md` file containing a record of notable changes since the first tagged release. [#421](https://github.com/wimg/PHPCompatibility/pull/421)
+
+### Changed
+- :pushpin: The `ForbiddenNamesAsDeclared` sniff will now emit `warning`s for soft reserved keywords. [#406](https://github.com/wimg/PHPCompatibility/pull/406), [#370](https://github.com/wimg/PHPCompatibility/pull/370).
+- :pushpin: The `ForbiddenNames` sniff will now allow for the more liberal rules for usage of reserved keywords as of PHP 7.0. [#417](https://github.com/wimg/PHPCompatibility/pull/417)
+- :pushpin: The `InternalInterfaces`, `NewClasses`, `NewConstVisibility`, `NewInterfaces`, `NewMagicMethods`, `NonStaticMagicMethods` and `RemovedGlobalVariables` sniffs will now also sniff for and correctly report violations in combination with anonymous classes. [#378](https://github.com/wimg/PHPCompatibility/pull/378), [#383](https://github.com/wimg/PHPCompatibility/pull/383), [#393](https://github.com/wimg/PHPCompatibility/pull/393), [#394](https://github.com/wimg/PHPCompatibility/pull/394), [#395](https://github.com/wimg/PHPCompatibility/pull/395), [#396](https://github.com/wimg/PHPCompatibility/pull/396). Fixes [#351](https://github.com/wimg/PHPCompatibility/issues/351) and [#333](https://github.com/wimg/PHPCompatibility/issues/333).
+- :pushpin: The `NewClasses` and `NewInterfaces` sniffs will now also report on new classes/interfaces when used as type hints. [#414](https://github.com/wimg/PHPCompatibility/pull/414), [#416](https://github.com/wimg/PHPCompatibility/pull/416). Fixes [#352](https://github.com/wimg/PHPCompatibility/issues/352)
+- :pushpin: The `NewClasses` sniff will now also report on Exception classes when used in (multi-)`catch` statements. [#418](https://github.com/wimg/PHPCompatibility/pull/418). Fixes [#373](https://github.com/wimg/PHPCompatibility/issues/373).
+- :pushpin: The `NewScalarTypeDeclarations` sniff will now report on new type hints even when the type hint is nullable. [#379](https://github.com/wimg/PHPCompatibility/pull/379)
+- :twisted_rightwards_arrows: The `NewNowdoc` sniff has been renamed to `NewNowdocQuotedHeredoc` and will now also check for double quoted heredoc identifiers as introduced in PHP 5.3. [#390](https://github.com/wimg/PHPCompatibility/pull/390)
+- :rewind: The `NewClasses` sniff will now also report anonymous classes which `extend` a new sniff when used in combination with PHPCS 2.4.0-2.8.0. [#432](https://github.com/wimg/PHPCompatibility/pull/432). Fixes [#334](https://github.com/wimg/PHPCompatibility/issues/334).
+- :pencil2: `NewFunctionParameter` sniff: version number precision for two parameters. [#384](https://github.com/wimg/PHPCompatibility/pull/384), [#428](https://github.com/wimg/PHPCompatibility/pull/428)
+- :umbrella: Skipping two unit tests for the `ForbiddenClosureUseVariable` sniff when run on PHPCS 2.5.1 as these cause an infinite loop due to an upstream bug. [#408](https://github.com/wimg/PHPCompatibility/pull/408)
+- :umbrella: Skipping unit tests involving `trait`s in combination with PHP < 5.4 and PHPCS < 2.4.0 as `trait`s are not recognized in those circumstances. [#431](https://github.com/wimg/PHPCompatibility/pull/431)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#385](https://github.com/wimg/PHPCompatibility/pull/385), [#387](https://github.com/wimg/PHPCompatibility/pull/387), [#415](https://github.com/wimg/PHPCompatibility/pull/415), [#423](https://github.com/wimg/PHPCompatibility/pull/423), [#424](https://github.com/wimg/PHPCompatibility/pull/424)
+- :recycle: Minor simplification of the PHPUnit 6 compatibility layer and other test code. [#426](https://github.com/wimg/PHPCompatibility/pull/426), [#425](https://github.com/wimg/PHPCompatibility/pull/425)
+- General housekeeping. [#398](https://github.com/wimg/PHPCompatibility/pull/398), [#400](https://github.com/wimg/PHPCompatibility/pull/400)
+- :wrench: Minor tweaks to the Travis build script. [#409](https://github.com/wimg/PHPCompatibility/pull/409)
+- :green_heart: The sniffs are now also tested against PHP nightly for consistent results. [#380](https://github.com/wimg/PHPCompatibility/pull/380)
+
+### Fixed
+- :fire: Using unbounded ranges in `testVersion` resulted in unreported errors when used with sniffs using the `supportsBelow()` method. This affected the results of approximately half the sniffs. [#430](https://github.com/wimg/PHPCompatibility/pull/430)
+- :bug: The `ForbiddenNames` sniff would throw false positives for `use` statements with the `final` modifier in traits. [#402](https://github.com/wimg/PHPCompatibility/pull/402).
+- :bug: The `ForbiddenNames` sniff would fail to report on functions declared to return by reference using a reserved keyword as the function name. [#413](https://github.com/wimg/PHPCompatibility/pull/413)
+- :bug: The `ForbiddenNames` sniff would only examine the first part of a namespace and not report on reserved keywords used in subsequent parts of a nested namespace. [#419](https://github.com/wimg/PHPCompatibility/pull/419)
+- :bug: The `ForbiddenNames` sniff would not always correctly report on use statements importing constants or functions using reserved keywords. [#420](https://github.com/wimg/PHPCompatibility/pull/420)
+- :bug: The `NewKeywords` sniff would sometimes fail to report on the `const` keyword when used in a class, but not for a class constant. [#424](https://github.com/wimg/PHPCompatibility/pull/424)
+- :green_heart: PHPCS has released version 3.0 and updated the `master` branch to reflect this. This was causing the builds to fail. [#422](https://github.com/wimg/PHPCompatibility/pull/422)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] and [Mark Clements] for their contributions to this version. :clap:
+
+
+## [7.1.3] - 2017-04-02
+
+See all related issues and PRs in the [7.1.3 milestone].
+
+### Added
+- :zap: The `testVersion` config parameter now allows for specifying unbounded ranges.
+ For example: specifying `-5.6` means: check for compatibility with all PHP versions up to and including PHP 5.6;
+ Specifying `7.0-` means: check for compatibility with all PHP versions from PHP 7.0 upwards.
+ For more information about setting the `testVersion`, see [Using the compatibility sniffs](https://github.com/wimg/PHPCompatibility#using-the-compatibility-sniffs) in the readme.
+- :umbrella: Unit test for multi-line short arrays for the `ShortArray` sniff. [#347](https://github.com/wimg/PHPCompatibility/pull/347)
+- :umbrella: Various additional unit tests against false positives. [#345](https://github.com/wimg/PHPCompatibility/pull/345), [#369](https://github.com/wimg/PHPCompatibility/pull/369)
+- :umbrella: Unit tests for the `supportsBelow()`, `supportsAbove()` and `getTestVersion()` utility methods. [#363](https://github.com/wimg/PHPCompatibility/pull/363)
+- :books: Readme: information about installation of the standard using git check-out. [#349](https://github.com/wimg/PHPCompatibility/pull/349)
+- :books: `Contributing.md` file with information about reporting bugs, requesting features, making pull requests and running the unit tests. [#350](https://github.com/wimg/PHPCompatibility/pull/350)
+
+### Changed
+- :pushpin: The `ForbiddenFunctionParametersWithSameName`, `NewScalarTypeDeclarations`, `ParameterShadowSuperGlobals` sniff will now also sniff for and report violations in closures. [#331](https://github.com/wimg/PHPCompatibility/pull/331)
+- :twisted_rightwards_arrows: :rewind: The check for the PHP 5.3 `nowdoc` structure has been moved from the `NewKeywords` sniff to a new stand-alone `NewNowdoc` sniff which will now also recognize this structure when the sniffs are run on PHP 5.2. [#335](https://github.com/wimg/PHPCompatibility/pull/335)
+- :rewind: The `ForbiddenNames` sniff will now also correctly recognize reserved keywords used in a declared namespace when run on PHP 5.2. [#362](https://github.com/wimg/PHPCompatibility/pull/362)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#360](https://github.com/wimg/PHPCompatibility/pull/360)
+- :recycle: The unit tests would previously run each test case file against all PHPCompatibility sniffs. Now, they will only be tested against the sniff which the test case file is intended to test. This allows for more test cases to be tested, more precise testing in combination with `testVersion` settings and makes the unit tests run ~6 x faster.
+ Relevant additional unit tests have been added and others adjusted. [#369](https://github.com/wimg/PHPCompatibility/pull/369)
+- :recycle: Refactoring/tidying up of some unit test code. [#343](https://github.com/wimg/PHPCompatibility/pull/343), [#345](https://github.com/wimg/PHPCompatibility/pull/345), [#356](https://github.com/wimg/PHPCompatibility/pull/356), [#355](https://github.com/wimg/PHPCompatibility/pull/355), [#359](https://github.com/wimg/PHPCompatibility/pull/359)
+- General housekeeping. [#346](https://github.com/wimg/PHPCompatibility/pull/346)
+- :books: Readme: Clarify minimum requirements and influence on the results. [#348](https://github.com/wimg/PHPCompatibility/pull/348)
+
+### Removed
+- :twisted_rightwards_arrows: Removed the `LongArrays` sniff. The checks it contained have been moved into the `RemovedGlobalVariables` sniff. Both sniffs essentially did the same thing, just for different PHP native superglobals. [#354](https://github.com/wimg/PHPCompatibility/pull/354)
+
+### Fixed
+- :bug: The `PregReplaceEModifier` sniff would throw a false positive if a quote character was used as the regex delimiter. [#357](https://github.com/wimg/PHPCompatibility/pull/357)
+- :bug: `RemovedGlobalVariables` sniff would report false positives for class properties shadowing the removed `$HTTP_RAW_POST_DATA` variables. [#354](https://github.com/wimg/PHPCompatibility/pull/354).
+- :bug: The `getFQClassNameFromNewToken()` utility function could go into an infinite loop causing PHP to run out of memory when examining unfinished code (examination during live coding). [#338](https://github.com/wimg/PHPCompatibility/pull/338), [#342](https://github.com/wimg/PHPCompatibility/pull/342)
+- :bug: The `determineNamespace()` utility method would in certain cases not break out a loop. [#358](https://github.com/wimg/PHPCompatibility/pull/358)
+- :wrench: Travis script: Minor tweak for PHP 5.2 compatibility. [#341](https://github.com/wimg/PHPCompatibility/pull/341)
+- :wrench: The unit test suite is now also compatible with PHPUnit 6. [#365](https://github.com/wimg/PHPCompatibility/pull/365)
+- :books: Readme: Typo in the composer instructions. [#344](https://github.com/wimg/PHPCompatibility/pull/344)
+
+### Credits
+Thanks go out to [Arthur Edamov], [Juliette Reinders Folmer], [Mark Clements] and [Tadas Juozapaitis] for their contributions to this version. :clap:
+
+
+## [7.1.2] - 2017-02-17
+
+See all related issues and PRs in the [7.1.2 milestone].
+
+### Added
+- :star2: New `VariableVariables` sniff to detect variables variables for which the behaviour has changed in PHP 7.0. [#310](https://github.com/wimg/PHPCompatibility/pull/310) Fixes [#309](https://github.com/wimg/PHPCompatibility/issues/309).
+- :star: The `NewReturnTypeDeclarations` sniff will now also sniff for non-scalar return type declarations, i.e. `array`, `callable`, `self` or a class name. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :star: The `NewLanguageConstructs` sniff will now also sniff for the null coalesce equal operator `??=`. This operator is slated to be introduced in PHP 7.2 and PHPCS already accounts for it. [#340](https://github.com/wimg/PHPCompatibility/pull/340)
+- :star: New `getReturnTypeHintToken()` utility method to the `PHPCompatibility_Sniff` class to retrieve return type hints from function declarations in a cross-PHPCS-version compatible way. [#323](https://github.com/wimg/PHPCompatibility/pull/323).
+- :star: New `stripVariables()` utility method to the `PHPCompatibility_Sniff` class to strip variables from interpolated text strings. [#341](https://github.com/wimg/PHPCompatibility/pull/314).
+- :umbrella: Additional unit tests covering previously uncovered code. [#308](https://github.com/wimg/PHPCompatibility/pull/308)
+
+### Changed
+- :pushpin: The `MbstringReplaceEModifier`, `PregReplaceEModifier` and `NewExecutionDirectives` sniffs will now also correctly interpret double quoted text strings with interpolated variables. [#341](https://github.com/wimg/PHPCompatibility/pull/314), [#324](https://github.com/wimg/PHPCompatibility/pull/324).
+- :pushpin: The `NewNullableTypes` sniff will now also report on nullable (return) type hints when used with closures. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :pushpin: The `NewReturnTypeDeclarations` sniff will now also report on return type hints when used with closures. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :pushpin: Allow for anonymous classes in the `inClassScope()` utility method. [#315](https://github.com/wimg/PHPCompatibility/pull/315)
+- :pushpin: The function call parameter related utility functions can now also be used to get the individual items from an array declaration. [#300](https://github.com/wimg/PHPCompatibility/pull/300)
+- :twisted_rightwards_arrows: The `NewScalarReturnTypeDeclarations` sniff has been renamed to `NewReturnTypeDeclarations`. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :rewind: The `ForbiddenNames` sniff will now also correctly ignore anonymous classes when used in combination with PHPCS < 2.3.4. [#319](https://github.com/wimg/PHPCompatibility/pull/319)
+- :rewind: The `NewAnonymousClasses` sniff will now correctly recognize and report on anonymous classes when used in combination with PHPCS < 2.5.2. [#325](https://github.com/wimg/PHPCompatibility/pull/325)
+- :rewind: The `NewGroupUseDeclarations` sniff will now correctly recognize and report on group use statements when used in combination with PHPCS < 2.6.0. [#320](https://github.com/wimg/PHPCompatibility/pull/320)
+- :rewind: The `NewNullableTypes` sniff will now correctly recognize and report on nullable return types when used in combination with PHPCS < 2.6.0. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :rewind: The `NewReturnTypeDeclarations` sniff will now correctly recognize and report on new return types when used in combination with PHPCS < 2.6.0. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#317](https://github.com/wimg/PHPCompatibility/pull/317)
+- :recycle: Defer to upstream `hasCondition()` utility method where appropriate. [#315](https://github.com/wimg/PHPCompatibility/pull/315)
+- :recycle: Minor refactoring of some unit test code. [#304](https://github.com/wimg/PHPCompatibility/pull/304), [#303](https://github.com/wimg/PHPCompatibility/pull/303), [#318](https://github.com/wimg/PHPCompatibility/pull/318)
+- :wrench: All unit tests now have appropriate `@group` annotations allowing for quicker/easier testing of a select group of tests/sniffs. [#305](https://github.com/wimg/PHPCompatibility/pull/305)
+- :wrench: All unit tests now have appropriate `@covers` annotations to improve code coverage reporting and remove bleed through of accidental coverage. [#307](https://github.com/wimg/PHPCompatibility/pull/307)
+- :wrench: Minor tweaks to the travis script. [#322](https://github.com/wimg/PHPCompatibility/pull/322)
+- :green_heart: The PHPCompatibility code base itself will now be checked for cross-version compatibility during build testing. [#322](https://github.com/wimg/PHPCompatibility/pull/322)
+
+### Fixed
+- :bug: The `ConstantArraysUsingDefine` sniff would throw false positives if the value of the `define()` was retrieved via a function call and an array parameter was passed. [#327](https://github.com/wimg/PHPCompatibility/pull/327)
+- :bug: The `ForbiddenCallTimePassByReference` sniff would throw false positives on assign by reference within function calls or conditions. [#302](https://github.com/wimg/PHPCompatibility/pull/302) Fixes the last two cases reported in [#68](https://github.com/wimg/PHPCompatibility/issues/68#issuecomment-231366445)
+- :bug: The `ForbiddenGlobalVariableVariableSniff` sniff would only examine the first variable in a `global ...` statement causing unreported issues if subsequent variables were variable variables. [#316](https://github.com/wimg/PHPCompatibility/pull/316)
+- :bug: The `NewKeywords` sniff would throw a false positive for the `const` keyword when encountered in an interface. [#312](https://github.com/wimg/PHPCompatibility/pull/312)
+- :bug: The `NewNullableTypes` sniff would not report on nullable return types for namespaced classnames used as a type hint. [#323](https://github.com/wimg/PHPCompatibility/pull/323)
+- :bug: The `PregReplaceEModifier` sniff would always consider the first parameter passed as a single regex, while it could also be an array of regexes. This led to false positives and potentially unreported use of the `e` modifier when an array of regexes was passed. [#300](https://github.com/wimg/PHPCompatibility/pull/300)
+- :bug: The `PregReplaceEModifier` sniff could misidentify the regex delimiter when the regex to be examined was concatenated together from various text strings taken from a compound parameter leading to false positives. [#300](https://github.com/wimg/PHPCompatibility/pull/300)
+- :white_check_mark: Compatibility with PHPCS 2.7.x. Deal with changed behaviour of the upstream PHP tokenizer and utility function(s). [#313](https://github.com/wimg/PHPCompatibility/pull/313), [#323](https://github.com/wimg/PHPCompatibility/pull/323), [#326](https://github.com/wimg/PHPCompatibility/pull/326), [#340](https://github.com/wimg/PHPCompatibility/pull/340)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.1.1] - 2016-12-14
+
+See all related issues and PRs in the [7.1.1 milestone].
+
+### Added
+- :star: `ForbiddenNamesAsDeclared` sniff: detection of the PHP 7.1 `iterable` and `void` reserved keywords when used to name classes, interfaces or traits. [#298](https://github.com/wimg/PHPCompatibility/pull/298)
+
+### Fixed
+- :bug: The `ForbiddenNamesAsInvokedFunctions` sniff would incorrectly throw an error if the `clone` keyword was used with parenthesis. [#299](https://github.com/wimg/PHPCompatibility/pull/299). Fixes [#284](https://github.com/wimg/PHPCompatibility/issues/284)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.1.0] - 2016-12-14
+
+See all related issues and PRs in the [7.1.0 milestone].
+
+### Added
+- :star: New `stringToErrorCode()`, `arrayKeysToLowercase()` and `addMessage()` utility methods to the `PHPCompatibility_Sniff` class. [#291](https://github.com/wimg/PHPCompatibility/pull/291).
+
+### Changed
+- :pushpin: All sniff error messages now have modular error codes allowing for selectively disabling individual checks - and even selectively disabling individual sniff for specific files - without disabling the complete sniff. [#291](https://github.com/wimg/PHPCompatibility/pull/291)
+- :pencil2: Minor changes to some of the error message texts for consistency across sniffs. [#291](https://github.com/wimg/PHPCompatibility/pull/291)
+- :recycle: Refactored the complex version sniffs to reduce code duplication. [#291](https://github.com/wimg/PHPCompatibility/pull/291)
+- :recycle: Miscellaneous other refactoring for improved performance and sniff accuracy. [#291](https://github.com/wimg/PHPCompatibility/pull/291)
+- :umbrella: The unit tests for the `RemovedExtensions` sniff now verify that the correct alternative extension is being suggested. [#291](https://github.com/wimg/PHPCompatibility/pull/291)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.0.8] - 2016-10-31 - :ghost: Spooky! :jack_o_lantern:
+
+See all related issues and PRs in the [7.0.8 milestone].
+
+### Added
+- :star2: New `ForbiddenNamesAsDeclared` sniff: detection of the [other reserved keywords](http://php.net/manual/en/reserved.other-reserved-words.php) which are reserved as of PHP 7.0 (or higher). [#287](https://github.com/wimg/PHPCompatibility/pull/287). Fixes [#115](https://github.com/wimg/PHPCompatibility/issues/115).
+ These were previously sniffed for by the `ForbiddenNames` and `ForbiddenNamesAsInvokedFunctions` sniffs causing false positives as the rules for their reservation are different from the rules for "normal" [reserved keywords](http://php.net/manual/en/reserved.keywords.php).
+- :star: New `inUseScope()` utility method to the `PHPCompatibility_Sniff` class which handles PHPCS cross-version compatibility when determining the scope of a `use` statement. [#271](https://github.com/wimg/PHPCompatibility/pull/271).
+- :umbrella: More unit tests for the `ForbiddenNames` sniff. [#271](https://github.com/wimg/PHPCompatibility/pull/271).
+
+### Changed
+- :pushpin: _Deprecated_ functionality should throw a `warning`. _Removed_ or otherwise unavailable functionality should throw an `error`. This distinction was previously not consistently applied everywhere. [#286](https://github.com/wimg/PHPCompatibility/pull/286)
+ This change affects the following sniffs:
+ * `DeprecatedPHP4StyleConstructors` will now throw a `warning` instead of an `error` for deprecated PHP4 style class constructors.
+ * `ForbiddenCallTimePassByReference` will now throw a `warning` if the `testVersion` is `5.3` and an `error` if the `testVersion` if `5.4` or higher.
+ * `MbstringReplaceEModifier` will now throw a `warning` instead of an `error` for usage of the deprecated `e` modifier.
+ * `PregReplaceEModifier` will now throw a `warning` if the `testVersion` is `5.5` or `5.6` and an `error` if the `testVersion` if `7.0` or higher. Fixes [#290](https://github.com/wimg/PHPCompatibility/issues/290).
+ * `TernaryOperators` will now throw an `error` when the `testVersion` < `5.3` and the middle part has been omitted.
+ * `ValidIntegers` will now throw a `warning` when an invalid binary integer is detected.
+- :pencil2: `DeprecatedFunctions` and `DeprecatedIniDirectives` sniffs: minor change in the sniff error message text. Use _"removed"_ rather than the ominous _"forbidden"_. [#285](https://github.com/wimg/PHPCompatibility/pull/285)
+ Also updated relevant internal variable names and documentation to match.
+
+### Fixed
+- :bug: `ForbiddenNames` sniff would throw false positives for `use` statements which changed the visibility of methods in traits. [#271](https://github.com/wimg/PHPCompatibility/pull/271).
+- :bug: `ForbiddenNames` sniff would not report reserved keywords when used in combination with `use function` or `use const`. [#271](https://github.com/wimg/PHPCompatibility/pull/271).
+- :bug: `ForbiddenNames` sniff would potentially - unintentionally - skip over tokens, thereby - potentially - not reporting all errors. [#271](https://github.com/wimg/PHPCompatibility/pull/271).
+- :wrench: Composer config: `prefer-stable` should be a root element of the json file. Fixes [#277](https://github.com/wimg/PHPCompatibility/issues/277).
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.0.7] - 2016-10-20
+
+See all related issues and PRs in the [7.0.7 milestone].
+
+### Added
+- :star2: New `ForbiddenBreakContinueOutsideLoop` sniff: verify that `break`/`continue` is not used outside of a loop structure. This will cause fatal errors since PHP 7.0. [#278](https://github.com/wimg/PHPCompatibility/pull/278). Fixes [#275](https://github.com/wimg/PHPCompatibility/issues/275)
+- :star2: New `NewConstVisibility` sniff: detect visibility indicators for `class` and `interface` constants as introduced in PHP 7.1. [#280](https://github.com/wimg/PHPCompatibility/pull/280). Fixes [#249](https://github.com/wimg/PHPCompatibility/issues/249)
+- :star2: New `NewHashAlgorithms` sniff to check used hash algorithms against the PHP version in which they were introduced. [#242](https://github.com/wimg/PHPCompatibility/pull/242)
+- :star2: New `NewMultiCatch` sniff: detect catch statements catching multiple Exceptions as introduced in PHP 7.1. [#281](https://github.com/wimg/PHPCompatibility/pull/281). Fixes [#251](https://github.com/wimg/PHPCompatibility/issues/251)
+- :star2: New `NewNullableTypes` sniff: detect nullable parameter and return type hints (only supported in PHPCS >= 2.3.4) as introduced in PHP 7.1. [#282](https://github.com/wimg/PHPCompatibility/pull/282). Fixes [#247](https://github.com/wimg/PHPCompatibility/issues/247)
+- :star: `DeprecatedIniDirectives` sniff: recognize PHP 7.1 removed `session` ini directives. [#256](https://github.com/wimg/PHPCompatibility/pull/256)
+- :star: `NewFunctions` sniff: recognize new `socket_export_stream()` function as introduced in PHP 7.0.7. [#264](https://github.com/wimg/PHPCompatibility/pull/264)
+- :star: `NewFunctions` sniff: recognize new `curl_...()`, `is_iterable()`, `pcntl_async_signals()`, `session_create_id()`, `session_gc()` functions as introduced in PHP 7.1. [#273](https://github.com/wimg/PHPCompatibility/pull/273)
+- :star: `NewFunctionParameters` sniff: recognize new OpenSSL function parameters as introduced in PHP 7.1. [#258](https://github.com/wimg/PHPCompatibility/pull/258)
+- :star: `NewIniDirectives` sniff: recognize new `session` ini directives as introduced in PHP 7.1. [#259](https://github.com/wimg/PHPCompatibility/pull/259)
+- :star: `NewScalarReturnTypeDeclarations` sniff: recognize PHP 7.1 `void` return type hint. [#250](https://github.com/wimg/PHPCompatibility/pull/250)
+- :star: `NewScalarTypeDeclarations` sniff: recognize PHP 7.1 `iterable` type hint. [#255](https://github.com/wimg/PHPCompatibility/pull/255)
+- :star: Recognize the PHP 7.1 deprecated `mcrypt` functionality in the `RemovedExtensions`, `DeprecatedFunctions` and `DeprecatedIniDirectives` sniffs. [#257](https://github.com/wimg/PHPCompatibility/pull/257)
+
+### Changed
+- :pushpin: `LongArrays` sniff used to only throw `warning`s. It will now throw `error`s for PHP versions in which the long superglobals have been removed. [#270](https://github.com/wimg/PHPCompatibility/pull/270)
+- :pushpin: The `NewIniDirectives` sniff used to always throw an `warning`. Now it will throw an `error` when a new ini directive is used in combination with `ini_set()`. [#246](https://github.com/wimg/PHPCompatibility/pull/246).
+- :pushpin: `RemovedHashAlgorithms` sniff: also recognize removed algorithms when used with the PHP 5.5+ `hash_pbkdf2()` function. [#240](https://github.com/wimg/PHPCompatibility/pull/240)
+- :pushpin: Properly recognize nullable type hints in the `getMethodParameters()` utility method. [#282](https://github.com/wimg/PHPCompatibility/pull/282)
+- :pencil2: `DeprecatedPHP4StyleConstructors` sniff: minor error message text fix. [#236](https://github.com/wimg/PHPCompatibility/pull/236)
+- :pencil2: `NewIniDirectives` sniff: improved precision for the introduction version numbers being reported. [#246](https://github.com/wimg/PHPCompatibility/pull/246)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#238](https://github.com/wimg/PHPCompatibility/pull/238), [#244](https://github.com/wimg/PHPCompatibility/pull/244), [#240](https://github.com/wimg/PHPCompatibility/pull/240), [#276](https://github.com/wimg/PHPCompatibility/pull/276)
+- :umbrella: Re-activate the unit tests for the `NewScalarReturnTypeDeclarations` sniff. [#250](https://github.com/wimg/PHPCompatibility/pull/250)
+
+### Fixed
+- :bug: The `DeprecatedPHP4StyleConstructors` sniff would not report errors when the case of the class name and the PHP4 constructor function name did not match. [#236](https://github.com/wimg/PHPCompatibility/pull/236)
+- :bug: `LongArrays` sniff would report false positives for class properties shadowing removed PHP superglobals. [#270](https://github.com/wimg/PHPCompatibility/pull/270). Fixes [#268](https://github.com/wimg/PHPCompatibility/issues/268).
+- :bug: The `NewClasses` sniff would not report errors when the case of the class name used and "official" class name did not match. [#237](https://github.com/wimg/PHPCompatibility/pull/237)
+- :bug: The `NewIniDirectives` sniff would report violations against the PHP version in which the ini directive was introduced. This should be the version below it. [#246](https://github.com/wimg/PHPCompatibility/pull/246)
+- :bug: `PregReplaceEModifier` sniff would report false positives for compound regex parameters with different quote types. [#266](https://github.com/wimg/PHPCompatibility/pull/266). Fixes [#265](https://github.com/wimg/PHPCompatibility/issues/265).
+- :bug: `RemovedGlobalVariables` sniff would report false positives for lowercase/mixed cased variables shadowing superglobals. [#245](https://github.com/wimg/PHPCompatibility/pull/245).
+- :bug: The `RemovedHashAlgorithms` sniff would not report errors when the case of the hash function name used and "official" class name did not match. [#240](https://github.com/wimg/PHPCompatibility/pull/240)
+- :bug: The `ShortArray` sniff would report all violations on the line of the PHP open tag, not on the lines of the short array open/close tags. [#238](https://github.com/wimg/PHPCompatibility/pull/238)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.0.6] - 2016-09-23
+
+See all related issues and PRs in the [7.0.6 milestone].
+
+### Added
+- :star: New `stripQuotes()` utility method in the `PHPCompatibility_Sniff` base class to strip quotes which surround text strings in a consistent manner. [#224](https://github.com/wimg/PHPCompatibility/pull/224)
+- :books: Readme: Add _PHP Version Support_ section. [#225](https://github.com/wimg/PHPCompatibility/pull/225)
+
+### Changed
+- :pushpin: The `ForbiddenCallTimePassByReference` sniff will now also report the deprecation as of PHP 5.3, not just its removal as of PHP 5.4. [#203](https://github.com/wimg/PHPCompatibility/pull/203)
+- :pushpin: The `NewFunctionArrayDereferencing` sniff will now also check _method_ calls for array dereferencing, not just function calls. [#229](https://github.com/wimg/PHPCompatibility/pull/229). Fixes [#227](https://github.com/wimg/PHPCompatibility/issues/227).
+- :pencil2: The `NewExecutionDirectives` sniff will now throw `warning`s instead of `error`s for invalid values encountered in execution directives. [#223](https://github.com/wimg/PHPCompatibility/pull/223)
+- :pencil2: Minor miscellaneous fixes. [#231](https://github.com/wimg/PHPCompatibility/pull/231)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#219](https://github.com/wimg/PHPCompatibility/pull/219), [#203](https://github.com/wimg/PHPCompatibility/pull/203)
+- :recycle: Defer to upstream `findImplementedInterfaceNames()` utility method when it exists. [#222](https://github.com/wimg/PHPCompatibility/pull/222)
+- :wrench: Exclude the test files from analysis by Scrutinizer CI. [#230](https://github.com/wimg/PHPCompatibility/pull/230)
+
+### Removed
+- :no_entry_sign: Some redundant code. [#232](https://github.com/wimg/PHPCompatibility/pull/232)
+
+### Fixed
+- :bug: The `EmptyNonVariable` sniff would throw false positives for variable variables and for array access with a (partially) variable array index. [#212](https://github.com/wimg/PHPCompatibility/pull/212). Fixes [#210](https://github.com/wimg/PHPCompatibility/issues/210).
+- :bug: The `NewFunctionArrayDereferencing` sniff would throw false positives for lines of code containing both a function call as well as square brackets, even when they were unrelated. [#228](https://github.com/wimg/PHPCompatibility/pull/228). Fixes [#226](https://github.com/wimg/PHPCompatibility/issues/226).
+- :bug: `ParameterShadowSuperGlobals` sniff would report false positives for lowercase/mixed cased variables shadowing superglobals. [#218](https://github.com/wimg/PHPCompatibility/pull/218). Fixes [#214](https://github.com/wimg/PHPCompatibility/issues/214).
+- :bug: The `determineNamespace()` utility method now accounts properly for namespaces within scoped `declare()` statements. [#221](https://github.com/wimg/PHPCompatibility/pull/221)
+- :books: Readme: Logo alignment in the Credits section. [#233](https://github.com/wimg/PHPCompatibility/pull/233)
+
+### Credits
+Thanks go out to [Jason Stallings], [Juliette Reinders Folmer] and [Mark Clements] for their contributions to this version. :clap:
+
+
+## [7.0.5] - 2016-09-08
+
+See all related issues and PRs in the [7.0.5 milestone].
+
+### Added
+- :star2: New `MbstringReplaceEModifier` sniff to detect the use of the PHP 7.1 deprecated `e` modifier in Mbstring regex functions. [#202](https://github.com/wimg/PHPCompatibility/pull/202)
+- :star: The `ForbiddenBreakContinueVariableArguments` sniff will now also report on `break 0`/`continue 0` which is not allowed since PHP 5.4. [#209](https://github.com/wimg/PHPCompatibility/pull/209)
+- :star: New `getFunctionCallParameters()`, `getFunctionCallParameter()` utility methods in the `PHPCompatibility_Sniff` base class. [#170](https://github.com/wimg/PHPCompatibility/pull/170)
+- :star: New `tokenHasScope()` utility method in the `PHPCompatibility_Sniff` base class. [#189](https://github.com/wimg/PHPCompatibility/pull/189)
+- :umbrella: Unit test for `goto` and `callable` detection and some other miscellanous extra unit tests for the `NewKeywords` sniff. [#189](https://github.com/wimg/PHPCompatibility/pull/189)
+- :books: Readme: Information for sniff developers about running unit tests for _other_ sniff libraries using the PHPCS native test framework without running into conflicts with the PHPCompatibility specific unit test framework. [#217](https://github.com/wimg/PHPCompatibility/pull/217)
+
+### Changed
+- :pushpin: The `ForbiddenNames` sniff will now also check interface declarations for usage of reserved keywords. [#200](https://github.com/wimg/PHPCompatibility/pull/200)
+- :pushpin: `PregReplaceEModifier` sniff: improved handling of regexes build up of a combination of variables, function calls and/or text strings. [#201](https://github.com/wimg/PHPCompatibility/pull/201)
+- :rewind: The `NewKeywords` sniff will now also correctly recognize new keywords when used in combination with older PHPCS versions and/or run on older PHP versions. [#189](https://github.com/wimg/PHPCompatibility/pull/189)
+- :pencil2: `PregReplaceEModifier` sniff: minor improvement to the error message text. [#201](https://github.com/wimg/PHPCompatibility/pull/201)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#170](https://github.com/wimg/PHPCompatibility/pull/170), [#188](https://github.com/wimg/PHPCompatibility/pull/188), [#189](https://github.com/wimg/PHPCompatibility/pull/189), [#199](https://github.com/wimg/PHPCompatibility/pull/199), [#200](https://github.com/wimg/PHPCompatibility/pull/200), [#201](https://github.com/wimg/PHPCompatibility/pull/201), [#208](https://github.com/wimg/PHPCompatibility/pull/208)
+- :wrench: The unit tests for the utility methods have been moved to their own subdirectory within `Tests`. [#215](https://github.com/wimg/PHPCompatibility/pull/215)
+- :green_heart: The sniffs are now also tested against PHP 7.1 for consistent results. [#216](https://github.com/wimg/PHPCompatibility/pull/216)
+
+### Removed
+- :no_entry_sign: Some redundant code. [26d0b6](https://github.com/wimg/PHPCompatibility/commit/26d0b6cf0921f75d93a4faaf09c390f386dde9ff) and [841616](https://github.com/wimg/PHPCompatibility/commit/8416162ea81f4067226324f5948f4a50f7958a9b)
+
+### Fixed
+- :bug: `ConstantArraysUsingDefine` sniff: the version check logic was reversed causing the error not to be reported in certain circumstances. [#199](https://github.com/wimg/PHPCompatibility/pull/199)
+- :bug: The `DeprecatedIniDirectives` and `NewIniDirectives` sniffs could potentially trigger on the ini value instead of the ini directive name. [#170](https://github.com/wimg/PHPCompatibility/pull/170)
+- :bug: `ForbiddenNames` sniff: Reserved keywords when used as the name of a constant declared using `define()` would always be reported independently of the `testVersion` set. [#200](https://github.com/wimg/PHPCompatibility/pull/200)
+- :bug: `PregReplaceEModifier` sniff would not report errors when the function name used was not in lowercase. [#201](https://github.com/wimg/PHPCompatibility/pull/201)
+- :bug: `TernaryOperators` sniff: the version check logic was reversed causing the error not to be reported in certain circumstances. [#188](https://github.com/wimg/PHPCompatibility/pull/188)
+- :bug: The `getFQClassNameFromNewToken()` and `getFQClassNameFromDoubleColonToken()` utility methods would get confused when the class name was a variable instead of being hard-coded, resulting in a PHP warning being thown. [#206](https://github.com/wimg/PHPCompatibility/pull/206). Fixes [#205](https://github.com/wimg/PHPCompatibility/issues/205).
+- :bug: The `getFunctionCallParameters()` utility method would incorrectly identify an extra parameter if the last parameter passed to a function would have an - unnecessary - comma after it. The `getFunctionCallParameters()` utility method also did not handle parameters passed as short arrays correctly. [#213](https://github.com/wimg/PHPCompatibility/pull/213). Fixes [#211](https://github.com/wimg/PHPCompatibility/issues/211).
+- :umbrella: Unit tests for the `NewFunctionArrayDereferencing` sniff were not being run due to a naming error. [#208](https://github.com/wimg/PHPCompatibility/pull/208)
+- :books: Readme: Information about setting the `testVersion` from a custom ruleset was incorrect. [#204](https://github.com/wimg/PHPCompatibility/pull/204)
+- :wrench: Path to PHPCS in the unit tests breaking for non-Composer installs. [#198](https://github.com/wimg/PHPCompatibility/pull/198)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] and [Yoshiaki Yoshida] for their contributions to this version. :clap:
+
+
+## [7.0.4] - 2016-08-20
+
+See all related issues and PRs in the [7.0.4 milestone].
+
+### Added
+- :star2: New `EmptyNonVariable` sniff: detection of empty being used on non-variables for PHP < 5.5. [#187](https://github.com/wimg/PHPCompatibility/pull/187)
+- :star2: New `NewMagicMethods` sniff: detection of declaration of magic methods before the method became "magic". Includes a check for the changed behaviour for the `__toString()` magic method in PHP 5.2. [#176](https://github.com/wimg/PHPCompatibility/pull/176). Fixes [#64](https://github.com/wimg/PHPCompatibility/issues/64).
+- :star2: New `RemovedAlternativePHPTags` sniff: detection of ASP and script open tags for which support was removed in PHP 7.0. [#184](https://github.com/wimg/PHPCompatibility/pull/184), [#193](https://github.com/wimg/PHPCompatibility/pull/193). Fixes [#127](https://github.com/wimg/PHPCompatibility/issues/127).
+- :star: `NonStaticMagicMethods` sniff: detection of the `__callStatic()`, `__sleep()`, `__toString()` and `__set_state()` magic methods.
+- :green_heart: Lint all non-test case files for syntax errors during the build testing by Travis. [#192](https://github.com/wimg/PHPCompatibility/pull/192)
+
+### Changed
+- :pushpin: `NonStaticMagicMethods` sniff: will now also sniff `trait`s for magic methods. [#174](https://github.com/wimg/PHPCompatibility/pull/174)
+- :pushpin: `NonStaticMagicMethods` sniff: will now also check for magic methods which should be declared as `static`. [#174](https://github.com/wimg/PHPCompatibility/pull/174)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#178](https://github.com/wimg/PHPCompatibility/pull/178), [#179](https://github.com/wimg/PHPCompatibility/pull/179), [#174](https://github.com/wimg/PHPCompatibility/pull/174), [#171](https://github.com/wimg/PHPCompatibility/pull/171)
+- :recycle: The unit test suite now internally caches PHPCS run results in combination with a set `testVersion` to speed up the running of the unit tests. These are now ~3 x faster. [#148](https://github.com/wimg/PHPCompatibility/pull/148)
+- :books: Readme: Minor clarification of the minimum requirements.
+- :books: Readme: Advise to use the latest stable version of this repository.
+- :wrench: The unit tests can now be run with PHPCS installed in an arbitrary location by passing the location through an environment option. [#191](https://github.com/wimg/PHPCompatibility/pull/191).
+- :wrench: Improved coveralls configuration and compatibility. [#194](https://github.com/wimg/PHPCompatibility/pull/194)
+- :green_heart: The sniffs are now also tested against PHP 5.2 for consistent results. Except for namespace, trait and group use related errors, most sniffs work as intended on PHP 5.2. [#196](https://github.com/wimg/PHPCompatibility/pull/196)
+
+### Fixed
+- :bug: The `ForbiddenBreakContinueVariableArguments` sniff would not report on `break`/`continue` with a closure as an argument. [#171](https://github.com/wimg/PHPCompatibility/pull/171)
+- :bug: The `ForbiddenNamesAsInvokedFunctions` sniff would not report on reserved keywords which were not lowercase. [#186](https://github.com/wimg/PHPCompatibility/pull/186)
+- :bug: The `ForbiddenNamesAsInvokedFunctions` sniff would not report on the `goto` and `namespace` keywords when run on PHP 5.2. [#193](https://github.com/wimg/PHPCompatibility/pull/193)
+- :bug: `NewAnonymousClasses` sniff: the version check logic was reversed causing the error not to be reported in certain circumstances. [#195](https://github.com/wimg/PHPCompatibility/pull/195).
+- :bug: `NewGroupUseDeclarations` sniff: the version check logic was reversed causing the error not to be reported in certain circumstances. [#190](https://github.com/wimg/PHPCompatibility/pull/190).
+- :bug: The `NonStaticMagicMethods` sniff would not report on magic methods when the function name as declared was not in the same case as used in the PHP manual. [#174](https://github.com/wimg/PHPCompatibility/pull/174)
+- :wrench: The unit tests would exit with `0` if PHPCS could not be found. [#191](https://github.com/wimg/PHPCompatibility/pull/191)
+- :green_heart: The PHPCompatibility library itself was not fully compatible with PHP 5.2. [#193](https://github.com/wimg/PHPCompatibility/pull/193)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.0.3] - 2016-08-18
+
+See all related issues and PRs in the [7.0.3 milestone].
+
+### Added
+- :star2: New `InternalInterfaces` sniff: detection of internal PHP interfaces being which should not be implemented by user land classes. [#144](https://github.com/wimg/PHPCompatibility/pull/144)
+- :star2: New `LateStaticBinding` sniff: detection of PHP 5.3 late static binding. [#177](https://github.com/wimg/PHPCompatibility/pull/177)
+- :star2: New `NewExecutionDirectives` sniff: verify execution directives set with `declare()`. [#169](https://github.com/wimg/PHPCompatibility/pull/169)
+- :star2: New `NewInterfaces` sniff: detection of the use of newly introduced PHP native interfaces. This sniff will also detect unsupported methods when a class implements the `Serializable` interface. [#144](https://github.com/wimg/PHPCompatibility/pull/144)
+- :star2: New `RequiredOptionalFunctionParameters` sniff: detection of missing function parameters which were required in earlier PHP versions only to become optional in later versions. [#165](https://github.com/wimg/PHPCompatibility/pull/165)
+- :star2: New `ValidIntegers` sniff: detection of binary integers for PHP < 5.4, detection of hexademical numeric strings for which recognition as hex integers was removed in PHP 7.0, detection of invalid binary and octal integers. [#160](https://github.com/wimg/PHPCompatibility/pull/160). Fixes [#55](https://github.com/wimg/PHPCompatibility/issues/55).
+- :star: `DeprecatedExtensions` sniff: detect removal of the `ereg` extension in PHP 7. [#149](https://github.com/wimg/PHPCompatibility/pull/149)
+- :star: `DeprecatedFunctions` sniff: detection of the PHP 5.0.5 deprecated `php_check_syntax()` and PHP 5.4 deprecated `mysqli_get_cache_stats()` functions. [#155](https://github.com/wimg/PHPCompatibility/pull/155).
+- :star: `DeprecatedFunctions` sniff: detect deprecation of a number of the `mysqli` functions in PHP 5.3. [#149](https://github.com/wimg/PHPCompatibility/pull/149)
+- :star: `DeprecatedFunctions` sniff: detect removal of the `call_user_method()`, `ldap_sort()`, `ereg_*()` and `mysql_*()` functions in PHP 7.0. [#149](https://github.com/wimg/PHPCompatibility/pull/149)
+- :star: `DeprecatedIniDirectives` sniff: detection of a _lot_ more deprecated/removed ini directives. [#146](https://github.com/wimg/PHPCompatibility/pull/146)
+- :star: `NewFunctionParameters` sniff: detection of a _lot_ more new function parameters. [#164](https://github.com/wimg/PHPCompatibility/pull/164)
+- :star: `NewFunctions` sniff: detection of numerous extra new functions. [#161](https://github.com/wimg/PHPCompatibility/pull/161)
+- :star: `NewIniDirectives` sniff: detection of a _lot_ more new ini directives. [#146](https://github.com/wimg/PHPCompatibility/pull/146)
+- :star: `NewLanguageConstructs` sniff: detection of the PHP 5.6 ellipsis `...` construct. [#175](https://github.com/wimg/PHPCompatibility/pull/175)
+- :star: `NewScalarTypeDeclarations` sniff: detection of PHP 5.1 `array` and PHP 5.4 `callable` type hints. [#168](https://github.com/wimg/PHPCompatibility/pull/168)
+- :star: `RemovedFunctionParameters` sniff: detection of a few extra removed function parameters. [#163](https://github.com/wimg/PHPCompatibility/pull/163)
+- :star: Detection of functions and methods with a double underscore prefix as these are reserved by PHP for future use. The existing upstream `Generic.NamingConventions.CamelCapsFunctionName` sniff is re-used for this with some customization. [#173](https://github.com/wimg/PHPCompatibility/pull/173)
+- :star: New `getFQClassNameFromNewToken()`, `getFQExtendedClassName()`, `getFQClassNameFromDoubleColonToken()`, `getFQName()`, `isNamespaced()`, `determineNamespace()` and `getDeclaredNamespaceName()` utility methods in the `PHPCompatibility_Sniff` base class for namespace determination. [#162](https://github.com/wimg/PHPCompatibility/pull/162)
+- :recycle: New `inClassScope()` utility method in the `PHPCompatibility_Sniff` base class. [#168](https://github.com/wimg/PHPCompatibility/pull/168)
+- :recycle: New `doesFunctionCallHaveParameters()` and `getFunctionCallParameterCount()` utility methods in the `PHPCompatibility_Sniff` base class. [#153](https://github.com/wimg/PHPCompatibility/pull/153)
+- :umbrella: Unit test for `__halt_compiler()` detection by the `NewKeywords` sniff.
+- :umbrella: Unit tests for the `NewFunctions` sniff. [#161](https://github.com/wimg/PHPCompatibility/pull/161)
+- :umbrella: Unit tests for the `ParameterShadowSuperGlobals` sniff. [#180](https://github.com/wimg/PHPCompatibility/pull/180)
+- :wrench: Minimal config for Scrutinizer CI. [#145](https://github.com/wimg/PHPCompatibility/pull/145).
+
+### Changed
+- :pushpin: The `DeprecatedIniDirectives` and the `NewIniDirectives` sniffs will now indicate an alternative ini directive in case the directive has been renamed. [#146](https://github.com/wimg/PHPCompatibility/pull/146)
+- :pushpin: The `NewClasses` sniff will now also report on new classes being extended by child classes. [#140](https://github.com/wimg/PHPCompatibility/pull/140).
+- :pushpin: The `NewClasses` sniff will now also report on static use of new classes. [#162](https://github.com/wimg/PHPCompatibility/pull/162).
+- :pushpin: The `NewScalarTypeDeclarations` sniff will now throw an error on use of type hints pre-PHP 5.0. [#168](https://github.com/wimg/PHPCompatibility/pull/168)
+- :pushpin: The `NewScalarTypeDeclarations` sniff will now verify type hints used against typical mistakes. [#168](https://github.com/wimg/PHPCompatibility/pull/168)
+- :pushpin: The `ParameterShadowSuperGlobals` sniff will now do a case-insensitive variable name compare. [#180](https://github.com/wimg/PHPCompatibility/pull/180)
+- :pushpin: The `RemovedFunctionParameters` sniff will now also report `warning`s on deprecation of function parameters. [#163](https://github.com/wimg/PHPCompatibility/pull/163)
+- :twisted_rightwards_arrows: The check for `JsonSerializable` has been moved from the `NewClasses` sniff to the `NewInterfaces` sniff. [#162](https://github.com/wimg/PHPCompatibility/pull/162)
+- :rewind: The `NewLanguageConstructs` sniff will now also recognize new language constructs when used in combination with PHPCS 1.5.x. [#175](https://github.com/wimg/PHPCompatibility/pull/175)
+- :pencil2: `NewFunctionParameters` sniff: use correct name for the new parameter for the `dirname()` function. [#164](https://github.com/wimg/PHPCompatibility/pull/164)
+- :pencil2: `NewScalarTypeDeclarations` sniff: minor change in the sniff error message text. [#168](https://github.com/wimg/PHPCompatibility/pull/168)
+- :pencil2: `RemovedFunctionParameters` sniff: minor change in the sniff error message text. [#163](https://github.com/wimg/PHPCompatibility/pull/163)
+- :pencil2: The `ParameterShadowSuperGlobals` sniff now extends the `PHPCompatibility_Sniff` class. [#180](https://github.com/wimg/PHPCompatibility/pull/180)
+- :recycle: Various (minor) refactoring for improved performance and sniff accuracy. [#181](https://github.com/wimg/PHPCompatibility/pull/181), [#182](https://github.com/wimg/PHPCompatibility/pull/182), [#166](https://github.com/wimg/PHPCompatibility/pull/166), [#167](https://github.com/wimg/PHPCompatibility/pull/167), [#172](https://github.com/wimg/PHPCompatibility/pull/172), [#180](https://github.com/wimg/PHPCompatibility/pull/180), [#146](https://github.com/wimg/PHPCompatibility/pull/146), [#138](https://github.com/wimg/PHPCompatibility/pull/138)
+- :recycle: Various refactoring to remove code duplication in the unit tests and add proper test skip notifications where relevant. [#139](https://github.com/wimg/PHPCompatibility/pull/139), [#149](https://github.com/wimg/PHPCompatibility/pull/149)
+
+### Fixed
+- :bug: The `DeprecatedFunctions` sniff was reporting an incorrect deprecation/removal version number for a few functions. [#149](https://github.com/wimg/PHPCompatibility/pull/149)
+- :bug: The `DeprecatedIniDirectives` sniff was in select cases reporting deprecation of an ini directive prior to removal, while the ini directive was never deprecated prior to its removal. [#146](https://github.com/wimg/PHPCompatibility/pull/146)
+- :bug: The `DeprecatedPHP4StyleConstructors` sniff would cause false positives for methods with the same name as the class in namespaced classes. [#167](https://github.com/wimg/PHPCompatibility/pull/167)
+- :bug: The `ForbiddenEmptyListAssignment` sniff did not report errors when there were only comments or parentheses between the list parentheses. [#166](https://github.com/wimg/PHPCompatibility/pull/166)
+- :bug: The `ForbiddenEmptyListAssignment` sniff will no longer cause false positives during live coding. [#166](https://github.com/wimg/PHPCompatibility/pull/166)
+- :bug: The `NewClasses` sniff would potentially misidentify namespaced classes as PHP native classes. [#161](https://github.com/wimg/PHPCompatibility/pull/162)
+- :bug: The `NewFunctions` sniff would fail to identify called functions when the function call was not lowercase. [#161](https://github.com/wimg/PHPCompatibility/pull/161)
+- :bug: The `NewFunctions` sniff would potentially misidentify namespaced userland functions as new functions. [#161](https://github.com/wimg/PHPCompatibility/pull/161)
+- :bug: The `NewIniDirectives` sniff was reporting an incorrect introduction version number for a few ini directives. [#146](https://github.com/wimg/PHPCompatibility/pull/146)
+- :bug: `NewKeywords` sniff: the use of the `const` keyword should only be reported when used outside of a class for PHP < 5.3. [#147](https://github.com/wimg/PHPCompatibility/pull/147). Fixes [#129](https://github.com/wimg/PHPCompatibility/issues/129).
+- :bug: The `RemovedExtensions` sniff was incorrectly reporting a number of extensions as being removed in PHP 5.3 while they were actually removed in PHP 5.1. [#156](https://github.com/wimg/PHPCompatibility/pull/156)
+- :bug: :recycle: The `NewFunctionParameters` and `RemovedFunctionParameters` now use the new `doesFunctionCallHaveParameters()` and `getFunctionCallParameterCount()` utility methods for improved accuracy in identifying function parameters. This fixes several false positives. [#153](https://github.com/wimg/PHPCompatibility/pull/153) Fixes [#120](https://github.com/wimg/PHPCompatibility/issues/120), [#151](https://github.com/wimg/PHPCompatibility/issues/151), [#152](https://github.com/wimg/PHPCompatibility/issues/152).
+- :bug: A number of sniffs would return `false` if the examined construct was not found. This could potentially cause race conditions/infinite sniff loops. [#138](https://github.com/wimg/PHPCompatibility/pull/138)
+- :wrench: The unit tests would fail to run when used in combination with a PEAR install of PHPCS. [#157](https://github.com/wimg/PHPCompatibility/pull/157).
+- :green_heart: Unit tests failing against PHPCS 2.6.1. [#158](https://github.com/wimg/PHPCompatibility/pull/158)
+ The unit tests *will* still fail against PHPCS 2.6.2 due to a bug in PHPCS itself. This bug does not affect the running of the sniffs outside of a unit test context.
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.0.2] - 2016-08-03
+
+See all related issues and PRs in the [7.0.2 milestone].
+
+### Added
+- :star: `RemovedExtensions` sniff: ability to whitelist userland functions for which the function prefix overlaps with a prefix of a deprecated/removed extension. [#130](https://github.com/wimg/PHPCompatibility/pull/130). Fixes [#123](https://github.com/wimg/PHPCompatibility/issues/123).
+ To use this feature, add the `functionWhitelist` property in your custom ruleset. For more information, see the [README](https://github.com/wimg/PHPCompatibility#phpcompatibility-specific-options).
+
+### Changed
+- :pencil2: A number of sniffs contained `public` class properties. Within PHPCS, `public` properties can be overruled via a custom ruleset. This was not the intention, so the visibility of these properties has been changed to `protected`. [#135](https://github.com/wimg/PHPCompatibility/pull/135)
+- :wrench: Composer config: Stable packages are preferred over unstable/dev.
+- :pencil2: Ruleset name. [#134](https://github.com/wimg/PHPCompatibility/pull/134)
+
+### Credits
+Thanks go out to [Juliette Reinders Folmer] for her contributions to this version. :clap:
+
+
+## [7.0.1] - 2016-08-02
+
+See all related issues and PRs in the [7.0.1 milestone].
+
+### Changed
+- :pushpin: The `DeprecatedIniDirectives` sniff used to throw an `error` when a deprecated ini directive was used in combination with `ini_get()`. It will now throw a `warning` instead. [#122](https://github.com/wimg/PHPCompatibility/pull/122) Fixes [#119](https://github.com/wimg/PHPCompatibility/issues/119).
+ Usage of deprecated ini directives in combination with `ini_set()` will still throw an `error`.
+- :pushpin: The `PregReplaceEModifier` sniff now also detects the `e` modifier when used with the `preg_filter()` function. While this is undocumented, the `e` modifier was supported by the `preg_filter()` function as well. [#128](https://github.com/wimg/PHPCompatibility/pull/128)
+- :pencil2: The `RemovedExtensions` sniff contained superfluous deprecation information in the error message. [#131](https://github.com/wimg/PHPCompatibility/pull/131)
+
+### Removed
+- :wrench: Duplicate builds from the Travis CI build matrix. [#132](https://github.com/wimg/PHPCompatibility/pull/132)
+
+### Fixed
+- :bug: The `ForbiddenNames` sniff did not allow for the PHP 5.6 `use function ...` and `use const ...` syntax. [#126](https://github.com/wimg/PHPCompatibility/pull/126) Fixes [#124](https://github.com/wimg/PHPCompatibility/issues/124).
+- :bug: The `NewClasses` sniff failed to detect new classes when the class was instantiated without parenthesis, i.e. `new NewClass;`. [#121](https://github.com/wimg/PHPCompatibility/pull/121)
+- :bug: The `PregReplaceEModifier` sniff failed to detect the `e` modifier when using bracket delimiters for the regex other than the `{}` brackets. [#128](https://github.com/wimg/PHPCompatibility/pull/128)
+- :green_heart: Unit tests failing against PHPCS 2.6.1.
+
+### Credits
+Thanks go out to [Jason Stallings], [Juliette Reinders Folmer] and [Ryan Neufeld] for their contributions to this version. :clap:
+
+
+## [7.0] - 2016-07-02
+
+See all related issues and PRs in the [7.0 milestone].
+
+### Added
+- :zap: Ability to specify a range of PHP versions against which to test your code base for compatibility, i.e. `--runtime-set testVersion 5.0-5.4` will now test your code for compatibility with PHP 5.0 up to PHP 5.4. [#99](https://github.com/wimg/PHPCompatibility/pull/99)
+- :star2: New `NewFunctionArrayDereferencing` sniff to detect function array dereferencing as introduced in PHP 5.4. Fixes [#52](https://github.com/wimg/PHPCompatibility/issues/52).
+- :star2: New `ShortArray` sniff to detect short array syntax as introduced in PHP 5.4. [#97](https://github.com/wimg/PHPCompatibility/pull/97). Fixes [#47](https://github.com/wimg/PHPCompatibility/issues/47).
+- :star2: New `TernaryOperators` sniff to detect ternaries without the middle part (`elvis` operator) as introduced in PHP 5.3. [#101](https://github.com/wimg/PHPCompatibility/pull/101), [#103](https://github.com/wimg/PHPCompatibility/pull/103). Fixes [#49](https://github.com/wimg/PHPCompatibility/issues/49).
+- :star2: New `ConstantArraysUsingDefine` sniff to detect constants declared using `define()` being assigned an `array` value which was not allowed prior to PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `DeprecatedPHP4StyleConstructors` sniff to detect PHP 4 style class constructor methods which are deprecated as of PHP 7. [#109](https://github.com/wimg/PHPCompatibility/pull/109).
+- :star2: New `ForbiddenEmptyListAssignment` sniff to detect empty list() assignments which have been removed in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `ForbiddenFunctionParametersWithSameName` sniff to detect functions declared with multiple same-named parameters which is no longer accepted since PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `ForbiddenGlobalVariableVariable` sniff to detect variable variables being made `global` which is not allowed since PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `ForbiddenNegativeBitshift` sniff to detect bitwise shifts by negative number which will throw an ArithmeticError in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `ForbiddenSwitchWithMultipleDefaultBlocks` sniff to detect switch statements with multiple default blocks which is not allowed since PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `NewAnonymousClasses` sniff to detect anonymous classes as introduced in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `NewClosure` sniff to detect anonymous functions as introduced in PHP 5.3. Fixes [#35](https://github.com/wimg/PHPCompatibility/issues/35)
+- :star2: New `NewFunctionParameters` sniff to detect use of new parameters in build-in PHP functions. Initially only sniffing for the new PHP 7.0 function parameters and the new PHP 5.3+ `before_needle` parameter for the `strstr()` function. [#110](https://github.com/wimg/PHPCompatibility/pull/110), [#112](https://github.com/wimg/PHPCompatibility/pull/112). Fixes [#27](https://github.com/wimg/PHPCompatibility/issues/27).
+- :star2: New `NewGroupUseDeclarations` sniff to detect group use declarations as introduced in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `NewScalarReturnTypeDeclarations` sniff to detect scalar return type hints as introduced in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `NewScalarTypeDeclarations` sniff to detect scalar function parameter type hints as introduced in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `RemovedFunctionParameters` sniff to detect use of removed parameters in build-in PHP functions. Initially only sniffing for the function parameters removed in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star2: New `RemovedGlobalVariables` sniff to detect the PHP 7.0 removed `$HTTP_RAW_POST_DATA` superglobal. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `DeprecatedFunctions` sniff: detection of the PHP 5.4 deprecated OCI8 functions. [#93](https://github.com/wimg/PHPCompatibility/pull/93)
+- :star: `ForbiddenNamesAsInvokedFunctions` sniff: recognize PHP 5.5 `finally` as a reserved keywords when invoked as a function. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `NewKeywords` sniff: detection of the use of the PHP 5.1+ `__halt_compiler` keyword. Fixes [#50](https://github.com/wimg/PHPCompatibility/issues/50).
+- :star: `NewKeywords` sniff: detection of the PHP 5.3+ `nowdoc` syntax. Fixes [#48](https://github.com/wimg/PHPCompatibility/issues/48).
+- :star: `NewKeywords` sniff: detection of the use of the `const` keyword outside of a class for PHP < 5.3. Fixes [#50](https://github.com/wimg/PHPCompatibility/issues/50).
+- :star: `DeprecatedFunctions` sniff: recognize PHP 7.0 deprecated and removed functions. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `DeprecatedIniDirectives` sniff: recognize PHP 7.0 removed ini directives. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `ForbiddenNamesAsInvokedFunctions` sniff: recognize new PHP 7.0 reserved keywords when invoked as functions. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `ForbiddenNames` sniff: recognize new PHP 7.0 reserved keywords. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `NewFunctions` sniff: recognize new functions as introduced in PHP 7.0. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `NewLanguageConstructs` sniff: recognize new PHP 7.0 `<=>` "spaceship" and `??` null coalescing operators. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :star: `RemovedExtensions` sniff: recognize PHP 7.0 removed `ereg`, `mssql`, `mysql` and `sybase_ct` extensions. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :umbrella: Additional unit tests for the `NewLanguageConstructs` sniff. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :books: Readme: New section containing information about the use of the `testVersion` config variable.
+- :books: Readme: Sponsor credits.
+
+### Changed
+- :pushpin: The `DeprecatedIniDirectives` sniff used to always throw an `warning`. Now it will throw an `error` when a removed ini directive is used. [#110](https://github.com/wimg/PHPCompatibility/pull/110).
+- :pushpin: The `DeprecatedNewReference` sniff will now throw an error when the `testVersion` includes PHP 7.0 or higher. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :pushpin: The `ForbiddenNames` sniff now supports detection of reserved keywords when used in combination with PHP 7 anonymous classes. [#108](https://github.com/wimg/PHPCompatibility/pull/108), [#110](https://github.com/wimg/PHPCompatibility/pull/110).
+- :pushpin: The `PregReplaceEModifier` sniff will now throw an error when the `testVersion` includes PHP 7.0 or higher. [#110](https://github.com/wimg/PHPCompatibility/pull/110)
+- :pencil2: `NewKeywords` sniff: clarified the error message text for the `use` keyword. Fixes [#46](https://github.com/wimg/PHPCompatibility/issues/46).
+- :recycle: Minor refactor of the `testVersion` related utility functions. [#98](https://github.com/wimg/PHPCompatibility/pull/98)
+- :wrench: Add autoload to the `composer.json` file. [#96](https://github.com/wimg/PHPCompatibility/pull/96) Fixes [#67](https://github.com/wimg/PHPCompatibility/issues/67).
+- :wrench: Minor other updates to the `composer.json` file. [#75](https://github.com/wimg/PHPCompatibility/pull/75)
+- :wrench: Improved creation of the code coverage reports needed by coveralls via Travis.
+- :green_heart: The sniffs are now also tested against PHP 7.0 for consistent results.
+
+### Fixed
+- :bug: The `ForbiddenCallTimePassByReference` sniff was throwing `Undefined index` notices when used in combination with PHPCS 2.2.0. [#100](https://github.com/wimg/PHPCompatibility/pull/100). Fixes [#42](https://github.com/wimg/PHPCompatibility/issues/42).
+- :bug: The `ForbiddenNamesAsInvokedFunctions` sniff would incorrectly throw an error if the `throw` keyword was used with parenthesis. Fixes [#118](https://github.com/wimg/PHPCompatibility/issues/118).
+- :bug: The `PregReplaceEModifier` sniff incorrectly identified `e`'s in the pattern as the `e` modifier when using `{}` bracket delimiters for the regex. [#94](https://github.com/wimg/PHPCompatibility/pull/94)
+- :bug: The `RemovedExtensions` sniff was throwing an `error` instead of a `warning` for deprecated, but not (yet) removed extensions. Fixes [#62](https://github.com/wimg/PHPCompatibility/issues/62).
+
+### Credits
+Thanks go out to AlexMiroshnikov, [Chris Abernethy], [dgudgeon], [djaenecke], [Eugene Maslovich], [Ken Guest], Koen Eelen, [Komarov Alexey], [Mark Clements] and [Remko van Bezooijen] for their contributions to this version. :clap:
+
+
+## [5.6] - 2015-09-14
+
+See all related issues and PRs in the [5.6 milestone].
+
+### Added
+- :star2: New: `NewLanguageConstructs` sniff. The initial version of this sniff checks for the PHP 5.6 `**` power operator and the `**=` power assignment operator. [#87](https://github.com/wimg/PHPCompatibility/pull/87). Fixes [#60](https://github.com/wimg/PHPCompatibility/issues/60).
+- :star2: New: `ParameterShadowSuperGlobals` sniff which covers the PHP 5.4 change _Parameter names that shadow super globals now cause a fatal error.`_. [#74](https://github.com/wimg/PHPCompatibility/pull/74)
+- :star2: New: `PregReplaceEModifier` sniff which detects usage of the `e` modifier in literal regular expressions used with `preg_replace()`. The `e` modifier will not (yet) be detected when the regex passed is a variable or constant. [#81](https://github.com/wimg/PHPCompatibility/pull/81), [#84](https://github.com/wimg/PHPCompatibility/pull/84). Fixes [#71](https://github.com/wimg/PHPCompatibility/issues/71), [#83](https://github.com/wimg/PHPCompatibility/issues/83).
+- :star: `DeprecatedIniDirectives` sniff: PHP 5.6 deprecated ini directives.
+- :star: `NewKeywords` sniff: detection of the `goto` keyword introduced in PHP 5.3 and the `callable` keyword introduced in PHP 5.4. [#57](https://github.com/wimg/PHPCompatibility/pull/57)
+- :recycle: `PHPCompatibility_Sniff` base class initially containing the `supportsAbove()` and `supportsBelow()` utility methods. (Nearly) All sniffs now extend this base class and use these methods to determine whether or not violations should be reported for a set `testVersion`. [#77](https://github.com/wimg/PHPCompatibility/pull/77)
+- :books: Readme: Composer installation instructions. [#32](https://github.com/wimg/PHPCompatibility/pull/32), [#61](https://github.com/wimg/PHPCompatibility/pull/61)
+- :wrench: `.gitignore` to ignore vendor and IDE related directories. [#78](https://github.com/wimg/PHPCompatibility/pull/78)
+- :green_heart: Code coverage checking via coveralls.
+
+### Changed
+- :twisted_rightwards_arrows: The check for the `\` namespace separator has been moved from the `NewKeywords` sniff to the `NewLanguageConstructs` sniff. [#88](https://github.com/wimg/PHPCompatibility/pull/88)
+- :pencil2: `DeprecatedIniDirectives` sniff: minor change in the sniff error message text.
+- :pencil2: `DeprecatedFunctions` sniff: minor change in the sniff error message text.
+- :wrench: Minor updates to the `composer.json` file. [#31](https://github.com/wimg/PHPCompatibility/pull/31), [34](https://github.com/wimg/PHPCompatibility/pull/34), [#70](https://github.com/wimg/PHPCompatibility/pull/70)
+- :wrench: Tests: The unit tests can now be run without configuration.
+- :wrench: Tests: Skipped unit tests will now be annotated as such. [#85](https://github.com/wimg/PHPCompatibility/pull/85)
+- :green_heart: The sniffs are now also tested against PHP 5.6 for consistent results.
+- :green_heart: The sniffs are now also tested against PHPCS 2.0+.
+- :green_heart: The sniffs are now tested using the new container-based infrastructure in Travis CI. [#37](https://github.com/wimg/PHPCompatibility/pull/37)
+
+### Fixed
+- :bug: The `ForbiddenCallTimePassByReference` sniff was throwing false positives when a bitwise and `&` was used in combination with class constants and class properties within function calls. [#44](https://github.com/wimg/PHPCompatibility/pull/44). Fixes [#39](https://github.com/wimg/PHPCompatibility/issues/39).
+- :bug: The `ForbiddenNamesAsInvokedFunctions` sniff was throwing false positives in certain cases when a comment separated a `try` from the `catch` block. [#29](https://github.com/wimg/PHPCompatibility/pull/29)
+- :bug: The `ForbiddenNamesAsInvokedFunctions` sniff was incorrectly reporting `instanceof` as being introduced in PHP 5.4 while it has been around since PHP 5.0. [#80](https://github.com/wimg/PHPCompatibility/pull/80)
+- :white_check_mark: Compatibility with PHPCS 2.0 - 2.3. [#63](https://github.com/wimg/PHPCompatibility/pull/63), [#65](https://github.com/wimg/PHPCompatibility/pull/65)
+
+### Credits
+Thanks go out to Daniel Jänecke, [Declan Kelly], [Dominic], [Jaap van Otterdijk], [Marin Crnkovic], [Mark Clements], [Nick Pack], [Oliver Klee], [Rowan Collins] and [Sam Van der Borght] for their contributions to this version. :clap:
+
+
+## 5.5 - 2014-04-04
+
+First tagged release.
+
+See all related issues and PRs in the [5.5 milestone].
+
+
+
+[Unreleased]: https://github.com/wimg/PHPCompatibility/compare/9.1.1...HEAD
+[9.1.1]: https://github.com/wimg/PHPCompatibility/compare/9.1.0...9.1.1
+[9.1.0]: https://github.com/wimg/PHPCompatibility/compare/9.0.0...9.1.0
+[9.0.0]: https://github.com/wimg/PHPCompatibility/compare/8.2.0...9.0.0
+[8.2.0]: https://github.com/wimg/PHPCompatibility/compare/8.1.0...8.2.0
+[8.1.0]: https://github.com/wimg/PHPCompatibility/compare/8.0.1...8.1.0
+[8.0.1]: https://github.com/wimg/PHPCompatibility/compare/8.0.0...8.0.1
+[8.0.0]: https://github.com/wimg/PHPCompatibility/compare/7.1.5...8.0.0
+[7.1.5]: https://github.com/wimg/PHPCompatibility/compare/7.1.4...7.1.5
+[7.1.4]: https://github.com/wimg/PHPCompatibility/compare/7.1.3...7.1.4
+[7.1.3]: https://github.com/wimg/PHPCompatibility/compare/7.1.2...7.1.3
+[7.1.2]: https://github.com/wimg/PHPCompatibility/compare/7.1.1...7.1.2
+[7.1.1]: https://github.com/wimg/PHPCompatibility/compare/7.1.0...7.1.1
+[7.1.0]: https://github.com/wimg/PHPCompatibility/compare/7.0.8...7.1.0
+[7.0.8]: https://github.com/wimg/PHPCompatibility/compare/7.0.7...7.0.8
+[7.0.7]: https://github.com/wimg/PHPCompatibility/compare/7.0.6...7.0.7
+[7.0.6]: https://github.com/wimg/PHPCompatibility/compare/7.0.5...7.0.6
+[7.0.5]: https://github.com/wimg/PHPCompatibility/compare/7.0.4...7.0.5
+[7.0.4]: https://github.com/wimg/PHPCompatibility/compare/7.0.3...7.0.4
+[7.0.3]: https://github.com/wimg/PHPCompatibility/compare/7.0.2...7.0.3
+[7.0.2]: https://github.com/wimg/PHPCompatibility/compare/7.0.1...7.0.2
+[7.0.1]: https://github.com/wimg/PHPCompatibility/compare/7.0...7.0.1
+[7.0]: https://github.com/wimg/PHPCompatibility/compare/5.6...7.0
+[5.6]: https://github.com/wimg/PHPCompatibility/compare/5.5...5.6
+
+[9.1.1 milestone]: https://github.com/PHPCompatibility/PHPCompatibility/milestone/27
+[9.1.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/25
+[9.0.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/24
+[8.2.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/22
+[8.1.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/21
+[8.0.1 milestone]: https://github.com/wimg/PHPCompatibility/milestone/20
+[8.0.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/19
+[7.1.5 milestone]: https://github.com/wimg/PHPCompatibility/milestone/17
+[7.1.4 milestone]: https://github.com/wimg/PHPCompatibility/milestone/15
+[7.1.3 milestone]: https://github.com/wimg/PHPCompatibility/milestone/14
+[7.1.2 milestone]: https://github.com/wimg/PHPCompatibility/milestone/13
+[7.1.1 milestone]: https://github.com/wimg/PHPCompatibility/milestone/12
+[7.1.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/11
+[7.0.8 milestone]: https://github.com/wimg/PHPCompatibility/milestone/10
+[7.0.7 milestone]: https://github.com/wimg/PHPCompatibility/milestone/9
+[7.0.6 milestone]: https://github.com/wimg/PHPCompatibility/milestone/8
+[7.0.5 milestone]: https://github.com/wimg/PHPCompatibility/milestone/7
+[7.0.4 milestone]: https://github.com/wimg/PHPCompatibility/milestone/6
+[7.0.3 milestone]: https://github.com/wimg/PHPCompatibility/milestone/5
+[7.0.2 milestone]: https://github.com/wimg/PHPCompatibility/milestone/4
+[7.0.1 milestone]: https://github.com/wimg/PHPCompatibility/milestone/3
+[7.0 milestone]: https://github.com/wimg/PHPCompatibility/milestone/2
+[5.6 milestone]: https://github.com/wimg/PHPCompatibility/milestone/1
+[5.5 milestone]: https://github.com/wimg/PHPCompatibility/milestone/16
+
+[Arthur Edamov]: https://github.com/edamov
+[Chris Abernethy]: https://github.com/cabernet-zerve
+[Declan Kelly]: https://github.com/declank
+[dgudgeon]: https://github.com/dgudgeon
+[djaenecke]: https://github.com/djaenecke
+[Dominic]: https://github.com/dol
+[Eugene Maslovich]: https://github.com/ehpc
+[Gary Jones]: https://github.com/GaryJones
+[Jaap van Otterdijk]: https://github.com/jaapio
+[Jason Stallings]: https://github.com/octalmage
+[Jonathan Champ]: https://github.com/jrchamp
+[Jonathan Van Belle]: https://github.com/Grummfy
+[Juliette Reinders Folmer]: https://github.com/jrfnl
+[Ken Guest]: https://github.com/kenguest
+[Komarov Alexey]: https://github.com/erdraug
+[Marin Crnkovic]: https://github.com/anorgan
+[Mark Clements]: https://github.com/MarkMaldaba
+[Michael Babker]: https://github.com/mbabker
+[Nick Pack]: https://github.com/nickpack
+[Oliver Klee]: https://github.com/oliverklee
+[Remko van Bezooijen]: https://github.com/emkookmer
+[Rowan Collins]: https://github.com/IMSoP
+[Ryan Neufeld]: https://github.com/ryanneufeld
+[Sam Van der Borght]: https://github.com/samvdb
+[Tadas Juozapaitis]: https://github.com/kasp3r
+[Yoshiaki Yoshida]: https://github.com/kakakakakku
+
\ No newline at end of file
diff --git a/vendor/phpcompatibility/php-compatibility/LICENSE b/vendor/phpcompatibility/php-compatibility/LICENSE
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCSAliases.php b/vendor/phpcompatibility/php-compatibility/PHPCSAliases.php
new file mode 100644
index 0000000..7da17d6
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCSAliases.php
@@ -0,0 +1,67 @@
+
+ */
+
+
+/*
+ * Alias a number of PHPCS 3.x classes to their PHPCS 2.x equivalents.
+ *
+ * This file is auto-loaded by PHPCS 3.x before any sniffs are loaded
+ * through the PHPCS 3.x `` ruleset directive.
+ *
+ * {@internal The PHPCS file have been reorganized in PHPCS 3.x, quite
+ * a few "old" classes have been split and spread out over several "new"
+ * classes. In other words, this will only work for a limited number
+ * of classes.}}
+ *
+ * {@internal The `class_exists` wrappers are needed to play nice with other
+ * external PHPCS standards creating cross-version compatibility in the same
+ * manner.}}
+ */
+if (defined('PHPCOMPATIBILITY_PHPCS_ALIASES_SET') === false) {
+ if (interface_exists('\PHP_CodeSniffer_Sniff') === false) {
+ class_alias('PHP_CodeSniffer\Sniffs\Sniff', '\PHP_CodeSniffer_Sniff');
+ }
+ if (class_exists('\PHP_CodeSniffer_File') === false) {
+ class_alias('PHP_CodeSniffer\Files\File', '\PHP_CodeSniffer_File');
+ }
+ if (class_exists('\PHP_CodeSniffer_Tokens') === false) {
+ class_alias('PHP_CodeSniffer\Util\Tokens', '\PHP_CodeSniffer_Tokens');
+ }
+ if (class_exists('\PHP_CodeSniffer_Exception') === false) {
+ class_alias('PHP_CodeSniffer\Exceptions\RuntimeException', '\PHP_CodeSniffer_Exception');
+ }
+ if (class_exists('\PHP_CodeSniffer_Standards_AbstractScopeSniff') === false) {
+ class_alias('PHP_CodeSniffer\Sniffs\AbstractScopeSniff', '\PHP_CodeSniffer_Standards_AbstractScopeSniff');
+ }
+ if (class_exists('\Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff') === false) {
+ class_alias('PHP_CodeSniffer\Standards\Generic\Sniffs\NamingConventions\CamelCapsFunctionNameSniff', '\Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff');
+ }
+
+ define('PHPCOMPATIBILITY_PHPCS_ALIASES_SET', true);
+
+ /*
+ * Register an autoloader.
+ *
+ * {@internal When `installed_paths` is set via the ruleset, this autoloader
+ * is needed to run the sniffs.
+ * Upstream issue: {@link https://github.com/squizlabs/PHP_CodeSniffer/issues/1591} }}
+ */
+ spl_autoload_register(function ($class) {
+ // Only try & load our own classes.
+ if (stripos($class, 'PHPCompatibility') !== 0) {
+ return;
+ }
+
+ $file = realpath(__DIR__) . DIRECTORY_SEPARATOR . strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
+
+ if (file_exists($file)) {
+ include_once $file;
+ }
+ });
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractComplexVersionSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractComplexVersionSniff.php
new file mode 100644
index 0000000..d5fd60a
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractComplexVersionSniff.php
@@ -0,0 +1,132 @@
+
+ */
+
+namespace PHPCompatibility;
+
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\AbstractComplexVersionSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+abstract class AbstractComplexVersionSniff extends Sniff implements ComplexVersionInterface
+{
+
+
+ /**
+ * Handle the retrieval of relevant information and - if necessary - throwing of an
+ * error/warning for an item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return void
+ */
+ public function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo)
+ {
+ $itemArray = $this->getItemArray($itemInfo);
+ $errorInfo = $this->getErrorInfo($itemArray, $itemInfo);
+
+ if ($this->shouldThrowError($errorInfo) === true) {
+ $this->addError($phpcsFile, $stackPtr, $itemInfo, $errorInfo);
+ }
+ }
+
+
+ /**
+ * Determine whether an error/warning should be thrown for an item based on collected information.
+ *
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return bool
+ */
+ abstract protected function shouldThrowError(array $errorInfo);
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array();
+ }
+
+
+ /**
+ * Retrieve a subset of an item array containing only the array keys which
+ * contain PHP version information.
+ *
+ * @param array $itemArray Version and other information about an item.
+ *
+ * @return array Array with only the version information.
+ */
+ protected function getVersionArray(array $itemArray)
+ {
+ return array_diff_key($itemArray, array_flip($this->getNonVersionArrayKeys()));
+ }
+
+
+ /**
+ * Get the item name to be used for the creation of the error code and in the error message.
+ *
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return string
+ */
+ protected function getItemName(array $itemInfo, array $errorInfo)
+ {
+ return $itemInfo['name'];
+ }
+
+
+ /**
+ * Get the error message template for a specific sniff.
+ *
+ * @return string
+ */
+ abstract protected function getErrorMsgTemplate();
+
+
+ /**
+ * Allow for concrete child classes to filter the error message before it's passed to PHPCS.
+ *
+ * @param string $error The error message which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return string
+ */
+ protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
+ {
+ return $error;
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractFunctionCallParameterSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractFunctionCallParameterSniff.php
new file mode 100644
index 0000000..1a1678d
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractFunctionCallParameterSniff.php
@@ -0,0 +1,179 @@
+
+ */
+
+namespace PHPCompatibility;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\AbstractFunctionCallParameterSniff.
+ *
+ * Abstract class to use as a base for examining the parameter values passed to function calls.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+abstract class AbstractFunctionCallParameterSniff extends Sniff
+{
+ /**
+ * Is the sniff looking for a function call or a method call ?
+ *
+ * Note: the child class may need to do additional checks to make sure that
+ * the method called is of the right class/object.
+ * Checking that is outside of the scope of this abstract sniff.
+ *
+ * @var bool False (default) if the sniff is looking for function calls.
+ * True if the sniff is looking for method calls.
+ */
+ protected $isMethod = false;
+
+ /**
+ * Functions the sniff is looking for. Should be defined in the child class.
+ *
+ * @var array The only requirement for this array is that the top level
+ * array keys are the names of the functions you're looking for.
+ * Other than that, the array can have arbitrary content
+ * depending on your needs.
+ */
+ protected $targetFunctions = array();
+
+ /**
+ * List of tokens which when they preceed the $stackPtr indicate that this
+ * is not a function call.
+ *
+ * @var array
+ */
+ private $ignoreTokens = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_NEW => true,
+ T_CONST => true,
+ T_USE => true,
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->targetFunctions = $this->arrayKeysToLowercase($this->targetFunctions);
+
+ return array(T_STRING);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->bowOutEarly() === true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if (isset($this->targetFunctions[$functionLc]) === false) {
+ return;
+ }
+
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+
+ if ($this->isMethod === true) {
+ if ($tokens[$prevNonEmpty]['code'] !== T_DOUBLE_COLON
+ && $tokens[$prevNonEmpty]['code'] !== T_OBJECT_OPERATOR
+ ) {
+ // Not a call to a PHP method.
+ return;
+ }
+ } else {
+ if (isset($this->ignoreTokens[$tokens[$prevNonEmpty]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ if ($tokens[$prevNonEmpty]['code'] === T_NS_SEPARATOR
+ && $tokens[$prevNonEmpty - 1]['code'] === T_STRING
+ ) {
+ // Namespaced function.
+ return;
+ }
+ }
+
+ $parameters = $this->getFunctionCallParameters($phpcsFile, $stackPtr);
+
+ if (empty($parameters)) {
+ return $this->processNoParameters($phpcsFile, $stackPtr, $function);
+ } else {
+ return $this->processParameters($phpcsFile, $stackPtr, $function, $parameters);
+ }
+ }
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * If the check done in a child class is not specific to one PHP version,
+ * this function should return `false`.
+ *
+ * @return bool
+ */
+ abstract protected function bowOutEarly();
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * This method has to be made concrete in child classes.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ abstract public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters);
+
+
+ /**
+ * Process the function if no parameters were found.
+ *
+ * Defaults to doing nothing. Can be overloaded in child classes to handle functions
+ * were parameters are expected, but none found.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processNoParameters(File $phpcsFile, $stackPtr, $functionName)
+ {
+ return;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractNewFeatureSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractNewFeatureSniff.php
new file mode 100644
index 0000000..ac6c258
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractNewFeatureSniff.php
@@ -0,0 +1,108 @@
+
+ */
+
+namespace PHPCompatibility;
+
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\AbstractNewFeatureSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+abstract class AbstractNewFeatureSniff extends AbstractComplexVersionSniff
+{
+
+
+ /**
+ * Determine whether an error/warning should be thrown for an item based on collected information.
+ *
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return bool
+ */
+ protected function shouldThrowError(array $errorInfo)
+ {
+ return ($errorInfo['not_in_version'] !== '');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = array(
+ 'not_in_version' => '',
+ 'error' => true,
+ );
+
+ $versionArray = $this->getVersionArray($itemArray);
+
+ if (empty($versionArray) === false) {
+ foreach ($versionArray as $version => $present) {
+ if ($errorInfo['not_in_version'] === '' && $present === false
+ && $this->supportsBelow($version) === true
+ ) {
+ $errorInfo['not_in_version'] = $version;
+ }
+ }
+ }
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return '%s is not present in PHP version %s or earlier';
+ }
+
+
+ /**
+ * Generates the error or warning for this item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Array with detail (version) information
+ * relevant to the item.
+ *
+ * @return void
+ */
+ public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
+ {
+ $itemName = $this->getItemName($itemInfo, $errorInfo);
+ $error = $this->getErrorMsgTemplate();
+
+ $errorCode = $this->stringToErrorCode($itemName) . 'Found';
+ $data = array(
+ $itemName,
+ $errorInfo['not_in_version'],
+ );
+
+ $error = $this->filterErrorMsg($error, $itemInfo, $errorInfo);
+ $data = $this->filterErrorData($data, $itemInfo, $errorInfo);
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $errorInfo['error'], $errorCode, $data);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractRemovedFeatureSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractRemovedFeatureSniff.php
new file mode 100644
index 0000000..3254ebb
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/AbstractRemovedFeatureSniff.php
@@ -0,0 +1,147 @@
+
+ */
+
+namespace PHPCompatibility;
+
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\AbstractRemovedFeatureSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+abstract class AbstractRemovedFeatureSniff extends AbstractComplexVersionSniff
+{
+
+
+ /**
+ * Determine whether an error/warning should be thrown for an item based on collected information.
+ *
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return bool
+ */
+ protected function shouldThrowError(array $errorInfo)
+ {
+ return ($errorInfo['deprecated'] !== '' || $errorInfo['removed'] !== '');
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * By default, removed feature version arrays, contain an additional 'alternative' array key.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('alternative');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = array(
+ 'deprecated' => '',
+ 'removed' => '',
+ 'alternative' => '',
+ 'error' => false,
+ );
+
+ $versionArray = $this->getVersionArray($itemArray);
+
+ if (empty($versionArray) === false) {
+ foreach ($versionArray as $version => $removed) {
+ if ($this->supportsAbove($version) === true) {
+ if ($removed === true && $errorInfo['removed'] === '') {
+ $errorInfo['removed'] = $version;
+ $errorInfo['error'] = true;
+ } elseif ($errorInfo['deprecated'] === '') {
+ $errorInfo['deprecated'] = $version;
+ }
+ }
+ }
+ }
+
+ if (isset($itemArray['alternative']) === true) {
+ $errorInfo['alternative'] = $itemArray['alternative'];
+ }
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for suggesting an alternative for a specific sniff.
+ *
+ * @return string
+ */
+ protected function getAlternativeOptionTemplate()
+ {
+ return '; Use %s instead';
+ }
+
+
+ /**
+ * Generates the error or warning for this item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Array with detail (version) information
+ * relevant to the item.
+ *
+ * @return void
+ */
+ public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
+ {
+ $itemName = $this->getItemName($itemInfo, $errorInfo);
+ $error = $this->getErrorMsgTemplate();
+
+ $errorCode = $this->stringToErrorCode($itemName);
+ $data = array($itemName);
+
+ if ($errorInfo['deprecated'] !== '') {
+ $error .= 'deprecated since PHP %s and ';
+ $errorCode .= 'Deprecated';
+ $data[] = $errorInfo['deprecated'];
+ }
+
+ if ($errorInfo['removed'] !== '') {
+ $error .= 'removed since PHP %s and ';
+ $errorCode .= 'Removed';
+ $data[] = $errorInfo['removed'];
+ }
+
+ // Remove the last 'and' from the message.
+ $error = substr($error, 0, (strlen($error) - 5));
+
+ if ($errorInfo['alternative'] !== '') {
+ $error .= $this->getAlternativeOptionTemplate();
+ $data[] = $errorInfo['alternative'];
+ }
+
+ $error = $this->filterErrorMsg($error, $itemInfo, $errorInfo);
+ $data = $this->filterErrorData($data, $itemInfo, $errorInfo);
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $errorInfo['error'], $errorCode, $data);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/ComplexVersionInterface.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/ComplexVersionInterface.php
new file mode 100644
index 0000000..43c5754
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/ComplexVersionInterface.php
@@ -0,0 +1,77 @@
+
+ */
+
+namespace PHPCompatibility;
+
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\ComplexVersionInterface.
+ *
+ * Interface to be implemented by sniffs using a multi-dimensional array of
+ * PHP features (functions, classes etc) being sniffed for with version
+ * information in sub-arrays.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+interface ComplexVersionInterface
+{
+
+
+ /**
+ * Handle the retrieval of relevant information and - if necessary - throwing of an
+ * error/warning for an item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return void
+ */
+ public function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo);
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo);
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo);
+
+
+ /**
+ * Generates the error or warning for this item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Array with detail (version) information
+ * relevant to the item.
+ *
+ * @return void
+ */
+ public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo);
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/PHPCSHelper.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/PHPCSHelper.php
new file mode 100644
index 0000000..2c5131c
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/PHPCSHelper.php
@@ -0,0 +1,652 @@
+
+ */
+
+namespace PHPCompatibility;
+
+use PHP_CodeSniffer_Exception as PHPCS_Exception;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\PHPCSHelper
+ *
+ * PHPCS cross-version compatibility helper class.
+ *
+ * A number of PHPCS classes were split up into several classes in PHPCS 3.x
+ * Those classes cannot be aliased as they don't represent the same object.
+ * This class provides helper methods for functions which were contained in
+ * one of these classes and which are used within the PHPCompatibility library.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class PHPCSHelper
+{
+
+ /**
+ * Get the PHPCS version number.
+ *
+ * @return string
+ */
+ public static function getVersion()
+ {
+ if (defined('\PHP_CodeSniffer\Config::VERSION')) {
+ // PHPCS 3.x.
+ return \PHP_CodeSniffer\Config::VERSION;
+ } else {
+ // PHPCS 2.x.
+ return \PHP_CodeSniffer::VERSION;
+ }
+ }
+
+
+ /**
+ * Pass config data to PHPCS.
+ *
+ * PHPCS cross-version compatibility helper.
+ *
+ * @param string $key The name of the config value.
+ * @param string|null $value The value to set. If null, the config entry
+ * is deleted, reverting it to the default value.
+ * @param boolean $temp Set this config data temporarily for this script run.
+ * This will not write the config data to the config file.
+ *
+ * @return void
+ */
+ public static function setConfigData($key, $value, $temp = false)
+ {
+ if (method_exists('\PHP_CodeSniffer\Config', 'setConfigData')) {
+ // PHPCS 3.x.
+ \PHP_CodeSniffer\Config::setConfigData($key, $value, $temp);
+ } else {
+ // PHPCS 2.x.
+ \PHP_CodeSniffer::setConfigData($key, $value, $temp);
+ }
+ }
+
+
+ /**
+ * Get the value of a single PHPCS config key.
+ *
+ * @param string $key The name of the config value.
+ *
+ * @return string|null
+ */
+ public static function getConfigData($key)
+ {
+ if (method_exists('\PHP_CodeSniffer\Config', 'getConfigData')) {
+ // PHPCS 3.x.
+ return \PHP_CodeSniffer\Config::getConfigData($key);
+ } else {
+ // PHPCS 2.x.
+ return \PHP_CodeSniffer::getConfigData($key);
+ }
+ }
+
+
+ /**
+ * Get the value of a single PHPCS config key.
+ *
+ * This config key can be set in the `CodeSniffer.conf` file, on the
+ * command-line or in a ruleset.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param string $key The name of the config value.
+ *
+ * @return string|null
+ */
+ public static function getCommandLineData(File $phpcsFile, $key)
+ {
+ if (class_exists('\PHP_CodeSniffer\Config')) {
+ // PHPCS 3.x.
+ $config = $phpcsFile->config;
+ if (isset($config->{$key})) {
+ return $config->{$key};
+ }
+ } else {
+ // PHPCS 2.x.
+ $config = $phpcsFile->phpcs->cli->getCommandLineValues();
+ if (isset($config[$key])) {
+ return $config[$key];
+ }
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Returns the position of the first non-whitespace token in a statement.
+ *
+ * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
+ * class and introduced in PHPCS 2.1.0 and improved in PHPCS 2.7.1.
+ *
+ * Once the minimum supported PHPCS version for this standard goes beyond
+ * that, this method can be removed and calls to it replaced with
+ * `$phpcsFile->findStartOfStatement($start, $ignore)` calls.
+ *
+ * Last synced with PHPCS version: PHPCS 3.3.2 at commit 6ad28354c04b364c3c71a34e4a18b629cc3b231e}}
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $start The position to start searching from in the token stack.
+ * @param int|array $ignore Token types that should not be considered stop points.
+ *
+ * @return int
+ */
+ public static function findStartOfStatement(File $phpcsFile, $start, $ignore = null)
+ {
+ if (version_compare(self::getVersion(), '2.7.1', '>=') === true) {
+ return $phpcsFile->findStartOfStatement($start, $ignore);
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $endTokens = Tokens::$blockOpeners;
+
+ $endTokens[T_COLON] = true;
+ $endTokens[T_COMMA] = true;
+ $endTokens[T_DOUBLE_ARROW] = true;
+ $endTokens[T_SEMICOLON] = true;
+ $endTokens[T_OPEN_TAG] = true;
+ $endTokens[T_CLOSE_TAG] = true;
+ $endTokens[T_OPEN_SHORT_ARRAY] = true;
+
+ if ($ignore !== null) {
+ $ignore = (array) $ignore;
+ foreach ($ignore as $code) {
+ if (isset($endTokens[$code]) === true) {
+ unset($endTokens[$code]);
+ }
+ }
+ }
+
+ $lastNotEmpty = $start;
+
+ for ($i = $start; $i >= 0; $i--) {
+ if (isset($endTokens[$tokens[$i]['code']]) === true) {
+ // Found the end of the previous statement.
+ return $lastNotEmpty;
+ }
+
+ if (isset($tokens[$i]['scope_opener']) === true
+ && $i === $tokens[$i]['scope_closer']
+ ) {
+ // Found the end of the previous scope block.
+ return $lastNotEmpty;
+ }
+
+ // Skip nested statements.
+ if (isset($tokens[$i]['bracket_opener']) === true
+ && $i === $tokens[$i]['bracket_closer']
+ ) {
+ $i = $tokens[$i]['bracket_opener'];
+ } elseif (isset($tokens[$i]['parenthesis_opener']) === true
+ && $i === $tokens[$i]['parenthesis_closer']
+ ) {
+ $i = $tokens[$i]['parenthesis_opener'];
+ }
+
+ if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === false) {
+ $lastNotEmpty = $i;
+ }
+ }//end for
+
+ return 0;
+ }
+
+
+ /**
+ * Returns the position of the last non-whitespace token in a statement.
+ *
+ * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
+ * class and introduced in PHPCS 2.1.0 and improved in PHPCS 2.7.1 and 3.3.0.
+ *
+ * Once the minimum supported PHPCS version for this standard goes beyond
+ * that, this method can be removed and calls to it replaced with
+ * `$phpcsFile->findEndOfStatement($start, $ignore)` calls.
+ *
+ * Last synced with PHPCS version: PHPCS 3.3.0-alpha at commit f5d899dcb5c534a1c3cca34668624517856ba823}}
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $start The position to start searching from in the token stack.
+ * @param int|array $ignore Token types that should not be considered stop points.
+ *
+ * @return int
+ */
+ public static function findEndOfStatement(File $phpcsFile, $start, $ignore = null)
+ {
+ if (version_compare(self::getVersion(), '3.3.0', '>=') === true) {
+ return $phpcsFile->findEndOfStatement($start, $ignore);
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $endTokens = array(
+ T_COLON => true,
+ T_COMMA => true,
+ T_DOUBLE_ARROW => true,
+ T_SEMICOLON => true,
+ T_CLOSE_PARENTHESIS => true,
+ T_CLOSE_SQUARE_BRACKET => true,
+ T_CLOSE_CURLY_BRACKET => true,
+ T_CLOSE_SHORT_ARRAY => true,
+ T_OPEN_TAG => true,
+ T_CLOSE_TAG => true,
+ );
+
+ if ($ignore !== null) {
+ $ignore = (array) $ignore;
+ foreach ($ignore as $code) {
+ if (isset($endTokens[$code]) === true) {
+ unset($endTokens[$code]);
+ }
+ }
+ }
+
+ $lastNotEmpty = $start;
+
+ for ($i = $start; $i < $phpcsFile->numTokens; $i++) {
+ if ($i !== $start && isset($endTokens[$tokens[$i]['code']]) === true) {
+ // Found the end of the statement.
+ if ($tokens[$i]['code'] === T_CLOSE_PARENTHESIS
+ || $tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET
+ || $tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET
+ || $tokens[$i]['code'] === T_CLOSE_SHORT_ARRAY
+ || $tokens[$i]['code'] === T_OPEN_TAG
+ || $tokens[$i]['code'] === T_CLOSE_TAG
+ ) {
+ return $lastNotEmpty;
+ }
+
+ return $i;
+ }
+
+ // Skip nested statements.
+ if (isset($tokens[$i]['scope_closer']) === true
+ && ($i === $tokens[$i]['scope_opener']
+ || $i === $tokens[$i]['scope_condition'])
+ ) {
+ if ($i === $start && isset(Tokens::$scopeOpeners[$tokens[$i]['code']]) === true) {
+ return $tokens[$i]['scope_closer'];
+ }
+
+ $i = $tokens[$i]['scope_closer'];
+ } elseif (isset($tokens[$i]['bracket_closer']) === true
+ && $i === $tokens[$i]['bracket_opener']
+ ) {
+ $i = $tokens[$i]['bracket_closer'];
+ } elseif (isset($tokens[$i]['parenthesis_closer']) === true
+ && $i === $tokens[$i]['parenthesis_opener']
+ ) {
+ $i = $tokens[$i]['parenthesis_closer'];
+ }
+
+ if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === false) {
+ $lastNotEmpty = $i;
+ }
+ }//end for
+
+ return ($phpcsFile->numTokens - 1);
+ }
+
+
+ /**
+ * Returns the name of the class that the specified class extends
+ * (works for classes, anonymous classes and interfaces).
+ *
+ * Returns FALSE on error or if there is no extended class name.
+ *
+ * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
+ * class, but with some improvements which have been introduced in
+ * PHPCS 2.8.0.
+ * {@link https://github.com/squizlabs/PHP_CodeSniffer/commit/0011d448119d4c568e3ac1f825ae78815bf2cc34}.
+ *
+ * Once the minimum supported PHPCS version for this standard goes beyond
+ * that, this method can be removed and calls to it replaced with
+ * `$phpcsFile->findExtendedClassName($stackPtr)` calls.
+ *
+ * Last synced with PHPCS version: PHPCS 3.1.0-alpha at commit a9efcc9b0703f3f9f4a900623d4e97128a6aafc6}}
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The position of the class token in the stack.
+ *
+ * @return string|false
+ */
+ public static function findExtendedClassName(File $phpcsFile, $stackPtr)
+ {
+ if (version_compare(self::getVersion(), '3.1.0', '>=') === true) {
+ return $phpcsFile->findExtendedClassName($stackPtr);
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_CLASS
+ && $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
+ && $tokens[$stackPtr]['type'] !== 'T_INTERFACE'
+ ) {
+ return false;
+ }
+
+ if (isset($tokens[$stackPtr]['scope_closer']) === false) {
+ return false;
+ }
+
+ $classCloserIndex = $tokens[$stackPtr]['scope_closer'];
+ $extendsIndex = $phpcsFile->findNext(T_EXTENDS, $stackPtr, $classCloserIndex);
+ if ($extendsIndex === false) {
+ return false;
+ }
+
+ $find = array(
+ T_NS_SEPARATOR,
+ T_STRING,
+ T_WHITESPACE,
+ );
+
+ $end = $phpcsFile->findNext($find, ($extendsIndex + 1), $classCloserIndex, true);
+ $name = $phpcsFile->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1));
+ $name = trim($name);
+
+ if ($name === '') {
+ return false;
+ }
+
+ return $name;
+ }
+
+
+ /**
+ * Returns the name(s) of the interface(s) that the specified class implements.
+ *
+ * Returns FALSE on error or if there are no implemented interface names.
+ *
+ * {@internal Duplicate of same method as introduced in PHPCS 2.7.
+ * This method also includes an improvement we use which was only introduced
+ * in PHPCS 2.8.0, so only defer to upstream for higher versions.
+ * Once the minimum supported PHPCS version for this sniff library goes beyond
+ * that, this method can be removed and calls to it replaced with
+ * `$phpcsFile->findImplementedInterfaceNames($stackPtr)` calls.}}
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the class token.
+ *
+ * @return array|false
+ */
+ public static function findImplementedInterfaceNames(File $phpcsFile, $stackPtr)
+ {
+ if (version_compare(self::getVersion(), '2.7.1', '>') === true) {
+ return $phpcsFile->findImplementedInterfaceNames($stackPtr);
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_CLASS
+ && $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
+ ) {
+ return false;
+ }
+
+ if (isset($tokens[$stackPtr]['scope_closer']) === false) {
+ return false;
+ }
+
+ $classOpenerIndex = $tokens[$stackPtr]['scope_opener'];
+ $implementsIndex = $phpcsFile->findNext(T_IMPLEMENTS, $stackPtr, $classOpenerIndex);
+ if ($implementsIndex === false) {
+ return false;
+ }
+
+ $find = array(
+ T_NS_SEPARATOR,
+ T_STRING,
+ T_WHITESPACE,
+ T_COMMA,
+ );
+
+ $end = $phpcsFile->findNext($find, ($implementsIndex + 1), ($classOpenerIndex + 1), true);
+ $name = $phpcsFile->getTokensAsString(($implementsIndex + 1), ($end - $implementsIndex - 1));
+ $name = trim($name);
+
+ if ($name === '') {
+ return false;
+ } else {
+ $names = explode(',', $name);
+ $names = array_map('trim', $names);
+ return $names;
+ }
+ }
+
+
+ /**
+ * Returns the method parameters for the specified function token.
+ *
+ * Each parameter is in the following format:
+ *
+ *
+ * 0 => array(
+ * 'name' => '$var', // The variable name.
+ * 'token' => integer, // The stack pointer to the variable name.
+ * 'content' => string, // The full content of the variable definition.
+ * 'pass_by_reference' => boolean, // Is the variable passed by reference?
+ * 'variable_length' => boolean, // Is the param of variable length through use of `...` ?
+ * 'type_hint' => string, // The type hint for the variable.
+ * 'type_hint_token' => integer, // The stack pointer to the type hint
+ * // or false if there is no type hint.
+ * 'nullable_type' => boolean, // Is the variable using a nullable type?
+ * )
+ *
+ *
+ * Parameters with default values have an additional array index of
+ * 'default' with the value of the default as a string.
+ *
+ * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
+ * class.
+ *
+ * Last synced with PHPCS version: PHPCS 3.3.0-alpha at commit 53a28408d345044c0360c2c1b4a2aaebf4a3b8c9}}
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The position in the stack of the
+ * function token to acquire the
+ * parameters for.
+ *
+ * @return array|false
+ * @throws \PHP_CodeSniffer_Exception If the specified $stackPtr is not of
+ * type T_FUNCTION or T_CLOSURE.
+ */
+ public static function getMethodParameters(File $phpcsFile, $stackPtr)
+ {
+ if (version_compare(self::getVersion(), '3.3.0', '>=') === true) {
+ return $phpcsFile->getMethodParameters($stackPtr);
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_FUNCTION
+ && $tokens[$stackPtr]['code'] !== T_CLOSURE
+ ) {
+ throw new PHPCS_Exception('$stackPtr must be of type T_FUNCTION or T_CLOSURE');
+ }
+
+ $opener = $tokens[$stackPtr]['parenthesis_opener'];
+ $closer = $tokens[$stackPtr]['parenthesis_closer'];
+
+ $vars = array();
+ $currVar = null;
+ $paramStart = ($opener + 1);
+ $defaultStart = null;
+ $paramCount = 0;
+ $passByReference = false;
+ $variableLength = false;
+ $typeHint = '';
+ $typeHintToken = false;
+ $nullableType = false;
+
+ for ($i = $paramStart; $i <= $closer; $i++) {
+ // Check to see if this token has a parenthesis or bracket opener. If it does
+ // it's likely to be an array which might have arguments in it. This
+ // could cause problems in our parsing below, so lets just skip to the
+ // end of it.
+ if (isset($tokens[$i]['parenthesis_opener']) === true) {
+ // Don't do this if it's the close parenthesis for the method.
+ if ($i !== $tokens[$i]['parenthesis_closer']) {
+ $i = ($tokens[$i]['parenthesis_closer'] + 1);
+ }
+ }
+
+ if (isset($tokens[$i]['bracket_opener']) === true) {
+ // Don't do this if it's the close parenthesis for the method.
+ if ($i !== $tokens[$i]['bracket_closer']) {
+ $i = ($tokens[$i]['bracket_closer'] + 1);
+ }
+ }
+
+ switch ($tokens[$i]['type']) {
+ case 'T_BITWISE_AND':
+ if ($defaultStart === null) {
+ $passByReference = true;
+ }
+ break;
+ case 'T_VARIABLE':
+ $currVar = $i;
+ break;
+ case 'T_ELLIPSIS':
+ $variableLength = true;
+ break;
+ case 'T_ARRAY_HINT': // Pre-PHPCS 3.3.0.
+ case 'T_CALLABLE':
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $tokens[$i]['content'];
+ break;
+ case 'T_SELF':
+ case 'T_PARENT':
+ case 'T_STATIC':
+ // Self and parent are valid, static invalid, but was probably intended as type hint.
+ if (isset($defaultStart) === false) {
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $tokens[$i]['content'];
+ }
+ break;
+ case 'T_STRING':
+ // This is a string, so it may be a type hint, but it could
+ // also be a constant used as a default value.
+ $prevComma = false;
+ for ($t = $i; $t >= $opener; $t--) {
+ if ($tokens[$t]['code'] === T_COMMA) {
+ $prevComma = $t;
+ break;
+ }
+ }
+
+ if ($prevComma !== false) {
+ $nextEquals = false;
+ for ($t = $prevComma; $t < $i; $t++) {
+ if ($tokens[$t]['code'] === T_EQUAL) {
+ $nextEquals = $t;
+ break;
+ }
+ }
+
+ if ($nextEquals !== false) {
+ break;
+ }
+ }
+
+ if ($defaultStart === null) {
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $tokens[$i]['content'];
+ }
+ break;
+ case 'T_NS_SEPARATOR':
+ // Part of a type hint or default value.
+ if ($defaultStart === null) {
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $tokens[$i]['content'];
+ }
+ break;
+ case 'T_NULLABLE':
+ case 'T_INLINE_THEN': // Pre-PHPCS 2.8.0.
+ if ($defaultStart === null) {
+ $nullableType = true;
+ $typeHint .= $tokens[$i]['content'];
+ }
+ break;
+ case 'T_CLOSE_PARENTHESIS':
+ case 'T_COMMA':
+ // If it's null, then there must be no parameters for this
+ // method.
+ if ($currVar === null) {
+ break;
+ }
+
+ $vars[$paramCount] = array();
+ $vars[$paramCount]['token'] = $currVar;
+ $vars[$paramCount]['name'] = $tokens[$currVar]['content'];
+ $vars[$paramCount]['content'] = trim($phpcsFile->getTokensAsString($paramStart, ($i - $paramStart)));
+
+ if ($defaultStart !== null) {
+ $vars[$paramCount]['default'] = trim(
+ $phpcsFile->getTokensAsString(
+ $defaultStart,
+ ($i - $defaultStart)
+ )
+ );
+ }
+
+ $vars[$paramCount]['pass_by_reference'] = $passByReference;
+ $vars[$paramCount]['variable_length'] = $variableLength;
+ $vars[$paramCount]['type_hint'] = $typeHint;
+ $vars[$paramCount]['type_hint_token'] = $typeHintToken;
+ $vars[$paramCount]['nullable_type'] = $nullableType;
+
+ // Reset the vars, as we are about to process the next parameter.
+ $defaultStart = null;
+ $paramStart = ($i + 1);
+ $passByReference = false;
+ $variableLength = false;
+ $typeHint = '';
+ $typeHintToken = false;
+ $nullableType = false;
+
+ $paramCount++;
+ break;
+ case 'T_EQUAL':
+ $defaultStart = ($i + 1);
+ break;
+ }//end switch
+ }//end for
+
+ return $vars;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniff.php
new file mode 100644
index 0000000..a036328
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniff.php
@@ -0,0 +1,1960 @@
+
+ * @copyright 2014 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility;
+
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_Exception as PHPCS_Exception;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Sniff as PHPCS_Sniff;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2014 Cu.be Solutions bvba
+ */
+abstract class Sniff implements PHPCS_Sniff
+{
+
+ const REGEX_COMPLEX_VARS = '`(?:(\{)?(?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(?:->\$?(?P>varname)|\[[^\]]+\]|::\$?(?P>varname)|\([^\)]*\))*(?(3)\}|)(?(2)\}|)(?(1)\}|)`';
+
+ /**
+ * List of superglobals as an array of strings.
+ *
+ * Used by the ParameterShadowSuperGlobals and ForbiddenClosureUseVariableNames sniffs.
+ *
+ * @var array
+ */
+ protected $superglobals = array(
+ '$GLOBALS' => true,
+ '$_SERVER' => true,
+ '$_GET' => true,
+ '$_POST' => true,
+ '$_FILES' => true,
+ '$_COOKIE' => true,
+ '$_SESSION' => true,
+ '$_REQUEST' => true,
+ '$_ENV' => true,
+ );
+
+ /**
+ * List of functions using hash algorithm as parameter (always the first parameter).
+ *
+ * Used by the new/removed hash algorithm sniffs.
+ * Key is the function name, value is the 1-based parameter position in the function call.
+ *
+ * @var array
+ */
+ protected $hashAlgoFunctions = array(
+ 'hash_file' => 1,
+ 'hash_hmac_file' => 1,
+ 'hash_hmac' => 1,
+ 'hash_init' => 1,
+ 'hash_pbkdf2' => 1,
+ 'hash' => 1,
+ );
+
+
+ /**
+ * List of functions which take an ini directive as parameter (always the first parameter).
+ *
+ * Used by the new/removed ini directives sniffs.
+ * Key is the function name, value is the 1-based parameter position in the function call.
+ *
+ * @var array
+ */
+ protected $iniFunctions = array(
+ 'ini_get' => 1,
+ 'ini_set' => 1,
+ );
+
+
+ /**
+ * Get the testVersion configuration variable.
+ *
+ * The testVersion configuration variable may be in any of the following formats:
+ * 1) Omitted/empty, in which case no version is specified. This effectively
+ * disables all the checks for new PHP features provided by this standard.
+ * 2) A single PHP version number, e.g. "5.4" in which case the standard checks that
+ * the code will run on that version of PHP (no deprecated features or newer
+ * features being used).
+ * 3) A range, e.g. "5.0-5.5", in which case the standard checks the code will run
+ * on all PHP versions in that range, and that it doesn't use any features that
+ * were deprecated by the final version in the list, or which were not available
+ * for the first version in the list.
+ * We accept ranges where one of the components is missing, e.g. "-5.6" means
+ * all versions up to PHP 5.6, and "7.0-" means all versions above PHP 7.0.
+ * PHP version numbers should always be in Major.Minor format. Both "5", "5.3.2"
+ * would be treated as invalid, and ignored.
+ *
+ * @return array $arrTestVersions will hold an array containing min/max version
+ * of PHP that we are checking against (see above). If only a
+ * single version number is specified, then this is used as
+ * both the min and max.
+ *
+ * @throws \PHP_CodeSniffer_Exception If testVersion is invalid.
+ */
+ private function getTestVersion()
+ {
+ static $arrTestVersions = array();
+
+ $default = array(null, null);
+ $testVersion = trim(PHPCSHelper::getConfigData('testVersion'));
+
+ if (empty($testVersion) === false && isset($arrTestVersions[$testVersion]) === false) {
+
+ $arrTestVersions[$testVersion] = $default;
+
+ if (preg_match('`^\d+\.\d+$`', $testVersion)) {
+ $arrTestVersions[$testVersion] = array($testVersion, $testVersion);
+ return $arrTestVersions[$testVersion];
+ }
+
+ if (preg_match('`^(\d+\.\d+)?\s*-\s*(\d+\.\d+)?$`', $testVersion, $matches)) {
+ if (empty($matches[1]) === false || empty($matches[2]) === false) {
+ // If no lower-limit is set, we set the min version to 4.0.
+ // Whilst development focuses on PHP 5 and above, we also accept
+ // sniffs for PHP 4, so we include that as the minimum.
+ // (It makes no sense to support PHP 3 as this was effectively a
+ // different language).
+ $min = empty($matches[1]) ? '4.0' : $matches[1];
+
+ // If no upper-limit is set, we set the max version to 99.9.
+ $max = empty($matches[2]) ? '99.9' : $matches[2];
+
+ if (version_compare($min, $max, '>')) {
+ trigger_error(
+ "Invalid range in testVersion setting: '" . $testVersion . "'",
+ E_USER_WARNING
+ );
+ return $default;
+ } else {
+ $arrTestVersions[$testVersion] = array($min, $max);
+ return $arrTestVersions[$testVersion];
+ }
+ }
+ }
+
+ trigger_error(
+ "Invalid testVersion setting: '" . $testVersion . "'",
+ E_USER_WARNING
+ );
+ return $default;
+ }
+
+ if (isset($arrTestVersions[$testVersion])) {
+ return $arrTestVersions[$testVersion];
+ }
+
+ return $default;
+ }
+
+
+ /**
+ * Check whether a specific PHP version is equal to or higher than the maximum
+ * supported PHP version as provided by the user in `testVersion`.
+ *
+ * Should be used when sniffing for *old* PHP features (deprecated/removed).
+ *
+ * @param string $phpVersion A PHP version number in 'major.minor' format.
+ *
+ * @return bool True if testVersion has not been provided or if the PHP version
+ * is equal to or higher than the highest supported PHP version
+ * in testVersion. False otherwise.
+ */
+ public function supportsAbove($phpVersion)
+ {
+ $testVersion = $this->getTestVersion();
+ $testVersion = $testVersion[1];
+
+ if (is_null($testVersion)
+ || version_compare($testVersion, $phpVersion) >= 0
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Check whether a specific PHP version is equal to or lower than the minimum
+ * supported PHP version as provided by the user in `testVersion`.
+ *
+ * Should be used when sniffing for *new* PHP features.
+ *
+ * @param string $phpVersion A PHP version number in 'major.minor' format.
+ *
+ * @return bool True if the PHP version is equal to or lower than the lowest
+ * supported PHP version in testVersion.
+ * False otherwise or if no testVersion is provided.
+ */
+ public function supportsBelow($phpVersion)
+ {
+ $testVersion = $this->getTestVersion();
+ $testVersion = $testVersion[0];
+
+ if (is_null($testVersion) === false
+ && version_compare($testVersion, $phpVersion) <= 0
+ ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ /**
+ * Add a PHPCS message to the output stack as either a warning or an error.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file the message applies to.
+ * @param string $message The message.
+ * @param int $stackPtr The position of the token
+ * the message relates to.
+ * @param bool $isError Whether to report the message as an
+ * 'error' or 'warning'.
+ * Defaults to true (error).
+ * @param string $code The error code for the message.
+ * Defaults to 'Found'.
+ * @param array $data Optional input for the data replacements.
+ *
+ * @return void
+ */
+ public function addMessage(File $phpcsFile, $message, $stackPtr, $isError, $code = 'Found', $data = array())
+ {
+ if ($isError === true) {
+ $phpcsFile->addError($message, $stackPtr, $code, $data);
+ } else {
+ $phpcsFile->addWarning($message, $stackPtr, $code, $data);
+ }
+ }
+
+
+ /**
+ * Convert an arbitrary string to an alphanumeric string with underscores.
+ *
+ * Pre-empt issues with arbitrary strings being used as error codes in XML and PHP.
+ *
+ * @param string $baseString Arbitrary string.
+ *
+ * @return string
+ */
+ public function stringToErrorCode($baseString)
+ {
+ return preg_replace('`[^a-z0-9_]`i', '_', strtolower($baseString));
+ }
+
+
+ /**
+ * Strip quotes surrounding an arbitrary string.
+ *
+ * Intended for use with the contents of a T_CONSTANT_ENCAPSED_STRING / T_DOUBLE_QUOTED_STRING.
+ *
+ * @param string $string The raw string.
+ *
+ * @return string String without quotes around it.
+ */
+ public function stripQuotes($string)
+ {
+ return preg_replace('`^([\'"])(.*)\1$`Ds', '$2', $string);
+ }
+
+
+ /**
+ * Strip variables from an arbitrary double quoted string.
+ *
+ * Intended for use with the contents of a T_DOUBLE_QUOTED_STRING.
+ *
+ * @param string $string The raw string.
+ *
+ * @return string String without variables in it.
+ */
+ public function stripVariables($string)
+ {
+ if (strpos($string, '$') === false) {
+ return $string;
+ }
+
+ return preg_replace(self::REGEX_COMPLEX_VARS, '', $string);
+ }
+
+
+ /**
+ * Make all top level array keys in an array lowercase.
+ *
+ * @param array $array Initial array.
+ *
+ * @return array Same array, but with all lowercase top level keys.
+ */
+ public function arrayKeysToLowercase($array)
+ {
+ $keys = array_keys($array);
+ $keys = array_map('strtolower', $keys);
+ return array_combine($keys, $array);
+ }
+
+
+ /**
+ * Checks if a function call has parameters.
+ *
+ * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
+ * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
+ *
+ * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer, it
+ * will detect whether the array has values or is empty.
+ *
+ * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/120
+ * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/152
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function call token.
+ *
+ * @return bool
+ */
+ public function doesFunctionCallHaveParameters(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ // Is this one of the tokens this function handles ?
+ if (in_array($tokens[$stackPtr]['code'], array(T_STRING, T_ARRAY, T_OPEN_SHORT_ARRAY, T_VARIABLE), true) === false) {
+ return false;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+
+ // Deal with short array syntax.
+ if ($tokens[$stackPtr]['code'] === T_OPEN_SHORT_ARRAY) {
+ if (isset($tokens[$stackPtr]['bracket_closer']) === false) {
+ return false;
+ }
+
+ if ($nextNonEmpty === $tokens[$stackPtr]['bracket_closer']) {
+ // No parameters.
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // Deal with function calls & long arrays.
+ // Next non-empty token should be the open parenthesis.
+ if ($nextNonEmpty === false && $tokens[$nextNonEmpty]['code'] !== T_OPEN_PARENTHESIS) {
+ return false;
+ }
+
+ if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) {
+ return false;
+ }
+
+ $closeParenthesis = $tokens[$nextNonEmpty]['parenthesis_closer'];
+ $nextNextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $nextNonEmpty + 1, $closeParenthesis + 1, true);
+
+ if ($nextNextNonEmpty === $closeParenthesis) {
+ // No parameters.
+ return false;
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Count the number of parameters a function call has been passed.
+ *
+ * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
+ * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
+ *
+ * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer,
+ * it will return the number of values in the array.
+ *
+ * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/111
+ * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/114
+ * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/151
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function call token.
+ *
+ * @return int
+ */
+ public function getFunctionCallParameterCount(File $phpcsFile, $stackPtr)
+ {
+ if ($this->doesFunctionCallHaveParameters($phpcsFile, $stackPtr) === false) {
+ return 0;
+ }
+
+ return count($this->getFunctionCallParameters($phpcsFile, $stackPtr));
+ }
+
+
+ /**
+ * Get information on all parameters passed to a function call.
+ *
+ * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
+ * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
+ *
+ * Will return an multi-dimentional array with the start token pointer, end token
+ * pointer and raw parameter value for all parameters. Index will be 1-based.
+ * If no parameters are found, will return an empty array.
+ *
+ * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer,
+ * it will tokenize the values / key/value pairs contained in the array call.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function call token.
+ *
+ * @return array
+ */
+ public function getFunctionCallParameters(File $phpcsFile, $stackPtr)
+ {
+ if ($this->doesFunctionCallHaveParameters($phpcsFile, $stackPtr) === false) {
+ return array();
+ }
+
+ // Ok, we know we have a T_STRING, T_VARIABLE, T_ARRAY or T_OPEN_SHORT_ARRAY with parameters
+ // and valid open & close brackets/parenthesis.
+ $tokens = $phpcsFile->getTokens();
+
+ // Mark the beginning and end tokens.
+ if ($tokens[$stackPtr]['code'] === T_OPEN_SHORT_ARRAY) {
+ $opener = $stackPtr;
+ $closer = $tokens[$stackPtr]['bracket_closer'];
+
+ $nestedParenthesisCount = 0;
+
+ } else {
+ $opener = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+ $closer = $tokens[$opener]['parenthesis_closer'];
+
+ $nestedParenthesisCount = 1;
+ }
+
+ // Which nesting level is the one we are interested in ?
+ if (isset($tokens[$opener]['nested_parenthesis'])) {
+ $nestedParenthesisCount += count($tokens[$opener]['nested_parenthesis']);
+ }
+
+ $parameters = array();
+ $nextComma = $opener;
+ $paramStart = $opener + 1;
+ $cnt = 1;
+ while (($nextComma = $phpcsFile->findNext(array(T_COMMA, $tokens[$closer]['code'], T_OPEN_SHORT_ARRAY, T_CLOSURE), $nextComma + 1, $closer + 1)) !== false) {
+ // Ignore anything within short array definition brackets.
+ if ($tokens[$nextComma]['type'] === 'T_OPEN_SHORT_ARRAY'
+ && (isset($tokens[$nextComma]['bracket_opener'])
+ && $tokens[$nextComma]['bracket_opener'] === $nextComma)
+ && isset($tokens[$nextComma]['bracket_closer'])
+ ) {
+ // Skip forward to the end of the short array definition.
+ $nextComma = $tokens[$nextComma]['bracket_closer'];
+ continue;
+ }
+
+ // Skip past closures passed as function parameters.
+ if ($tokens[$nextComma]['type'] === 'T_CLOSURE'
+ && (isset($tokens[$nextComma]['scope_condition'])
+ && $tokens[$nextComma]['scope_condition'] === $nextComma)
+ && isset($tokens[$nextComma]['scope_closer'])
+ ) {
+ // Skip forward to the end of the closure declaration.
+ $nextComma = $tokens[$nextComma]['scope_closer'];
+ continue;
+ }
+
+ // Ignore comma's at a lower nesting level.
+ if ($tokens[$nextComma]['type'] === 'T_COMMA'
+ && isset($tokens[$nextComma]['nested_parenthesis'])
+ && count($tokens[$nextComma]['nested_parenthesis']) !== $nestedParenthesisCount
+ ) {
+ continue;
+ }
+
+ // Ignore closing parenthesis/bracket if not 'ours'.
+ if ($tokens[$nextComma]['type'] === $tokens[$closer]['type'] && $nextComma !== $closer) {
+ continue;
+ }
+
+ // Ok, we've reached the end of the parameter.
+ $parameters[$cnt]['start'] = $paramStart;
+ $parameters[$cnt]['end'] = $nextComma - 1;
+ $parameters[$cnt]['raw'] = trim($phpcsFile->getTokensAsString($paramStart, ($nextComma - $paramStart)));
+
+ // Check if there are more tokens before the closing parenthesis.
+ // Prevents code like the following from setting a third parameter:
+ // functionCall( $param1, $param2, );
+ $hasNextParam = $phpcsFile->findNext(Tokens::$emptyTokens, $nextComma + 1, $closer, true, null, true);
+ if ($hasNextParam === false) {
+ break;
+ }
+
+ // Prepare for the next parameter.
+ $paramStart = $nextComma + 1;
+ $cnt++;
+ }
+
+ return $parameters;
+ }
+
+
+ /**
+ * Get information on a specific parameter passed to a function call.
+ *
+ * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
+ * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
+ *
+ * Will return a array with the start token pointer, end token pointer and the raw value
+ * of the parameter at a specific offset.
+ * If the specified parameter is not found, will return false.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function call token.
+ * @param int $paramOffset The 1-based index position of the parameter to retrieve.
+ *
+ * @return array|false
+ */
+ public function getFunctionCallParameter(File $phpcsFile, $stackPtr, $paramOffset)
+ {
+ $parameters = $this->getFunctionCallParameters($phpcsFile, $stackPtr);
+
+ if (isset($parameters[$paramOffset]) === false) {
+ return false;
+ } else {
+ return $parameters[$paramOffset];
+ }
+ }
+
+
+ /**
+ * Verify whether a token is within a scoped condition.
+ *
+ * If the optional $validScopes parameter has been passed, the function
+ * will check that the token has at least one condition which is of a
+ * type defined in $validScopes.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the token.
+ * @param array|int $validScopes Optional. Array of valid scopes
+ * or int value of a valid scope.
+ * Pass the T_.. constant(s) for the
+ * desired scope to this parameter.
+ *
+ * @return bool Without the optional $scopeTypes: True if within a scope, false otherwise.
+ * If the $scopeTypes are set: True if *one* of the conditions is a
+ * valid scope, false otherwise.
+ */
+ public function tokenHasScope(File $phpcsFile, $stackPtr, $validScopes = null)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ // No conditions = no scope.
+ if (empty($tokens[$stackPtr]['conditions'])) {
+ return false;
+ }
+
+ // Ok, there are conditions, do we have to check for specific ones ?
+ if (isset($validScopes) === false) {
+ return true;
+ }
+
+ return $phpcsFile->hasCondition($stackPtr, $validScopes);
+ }
+
+
+ /**
+ * Verify whether a token is within a class scope.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the token.
+ * @param bool $strict Whether to strictly check for the T_CLASS
+ * scope or also accept interfaces and traits
+ * as scope.
+ *
+ * @return bool True if within class scope, false otherwise.
+ */
+ public function inClassScope(File $phpcsFile, $stackPtr, $strict = true)
+ {
+ $validScopes = array(T_CLASS);
+ if (defined('T_ANON_CLASS') === true) {
+ $validScopes[] = T_ANON_CLASS;
+ }
+
+ if ($strict === false) {
+ $validScopes[] = T_INTERFACE;
+ $validScopes[] = T_TRAIT;
+ }
+
+ return $phpcsFile->hasCondition($stackPtr, $validScopes);
+ }
+
+
+ /**
+ * Returns the fully qualified class name for a new class instantiation.
+ *
+ * Returns an empty string if the class name could not be reliably inferred.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of a T_NEW token.
+ *
+ * @return string
+ */
+ public function getFQClassNameFromNewToken(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return '';
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_NEW) {
+ return '';
+ }
+
+ $start = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+ if ($start === false) {
+ return '';
+ }
+
+ // Bow out if the next token is a variable as we don't know where it was defined.
+ if ($tokens[$start]['code'] === T_VARIABLE) {
+ return '';
+ }
+
+ // Bow out if the next token is the class keyword.
+ if ($tokens[$start]['type'] === 'T_ANON_CLASS' || $tokens[$start]['code'] === T_CLASS) {
+ return '';
+ }
+
+ $find = array(
+ T_NS_SEPARATOR,
+ T_STRING,
+ T_NAMESPACE,
+ T_WHITESPACE,
+ );
+
+ $end = $phpcsFile->findNext($find, ($start + 1), null, true, null, true);
+ $className = $phpcsFile->getTokensAsString($start, ($end - $start));
+ $className = trim($className);
+
+ return $this->getFQName($phpcsFile, $stackPtr, $className);
+ }
+
+
+ /**
+ * Returns the fully qualified name of the class that the specified class extends.
+ *
+ * Returns an empty string if the class does not extend another class or if
+ * the class name could not be reliably inferred.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of a T_CLASS token.
+ *
+ * @return string
+ */
+ public function getFQExtendedClassName(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return '';
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_CLASS
+ && $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
+ && $tokens[$stackPtr]['type'] !== 'T_INTERFACE'
+ ) {
+ return '';
+ }
+
+ $extends = PHPCSHelper::findExtendedClassName($phpcsFile, $stackPtr);
+ if (empty($extends) || is_string($extends) === false) {
+ return '';
+ }
+
+ return $this->getFQName($phpcsFile, $stackPtr, $extends);
+ }
+
+
+ /**
+ * Returns the class name for the static usage of a class.
+ * This can be a call to a method, the use of a property or constant.
+ *
+ * Returns an empty string if the class name could not be reliably inferred.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of a T_NEW token.
+ *
+ * @return string
+ */
+ public function getFQClassNameFromDoubleColonToken(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return '';
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_DOUBLE_COLON) {
+ return '';
+ }
+
+ // Nothing to do if previous token is a variable as we don't know where it was defined.
+ if ($tokens[$stackPtr - 1]['code'] === T_VARIABLE) {
+ return '';
+ }
+
+ // Nothing to do if 'parent' or 'static' as we don't know how far the class tree extends.
+ if (in_array($tokens[$stackPtr - 1]['code'], array(T_PARENT, T_STATIC), true)) {
+ return '';
+ }
+
+ // Get the classname from the class declaration if self is used.
+ if ($tokens[$stackPtr - 1]['code'] === T_SELF) {
+ $classDeclarationPtr = $phpcsFile->findPrevious(T_CLASS, $stackPtr - 1);
+ if ($classDeclarationPtr === false) {
+ return '';
+ }
+ $className = $phpcsFile->getDeclarationName($classDeclarationPtr);
+ return $this->getFQName($phpcsFile, $classDeclarationPtr, $className);
+ }
+
+ $find = array(
+ T_NS_SEPARATOR,
+ T_STRING,
+ T_NAMESPACE,
+ T_WHITESPACE,
+ );
+
+ $start = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true, null, true);
+ if ($start === false || isset($tokens[($start + 1)]) === false) {
+ return '';
+ }
+
+ $start = ($start + 1);
+ $className = $phpcsFile->getTokensAsString($start, ($stackPtr - $start));
+ $className = trim($className);
+
+ return $this->getFQName($phpcsFile, $stackPtr, $className);
+ }
+
+
+ /**
+ * Get the Fully Qualified name for a class/function/constant etc.
+ *
+ * Checks if a class/function/constant name is already fully qualified and
+ * if not, enrich it with the relevant namespace information.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the token.
+ * @param string $name The class / function / constant name.
+ *
+ * @return string
+ */
+ public function getFQName(File $phpcsFile, $stackPtr, $name)
+ {
+ if (strpos($name, '\\') === 0) {
+ // Already fully qualified.
+ return $name;
+ }
+
+ // Remove the namespace keyword if used.
+ if (strpos($name, 'namespace\\') === 0) {
+ $name = substr($name, 10);
+ }
+
+ $namespace = $this->determineNamespace($phpcsFile, $stackPtr);
+
+ if ($namespace === '') {
+ return '\\' . $name;
+ } else {
+ return '\\' . $namespace . '\\' . $name;
+ }
+ }
+
+
+ /**
+ * Is the class/function/constant name namespaced or global ?
+ *
+ * @param string $FQName Fully Qualified name of a class, function etc.
+ * I.e. should always start with a `\`.
+ *
+ * @return bool True if namespaced, false if global.
+ */
+ public function isNamespaced($FQName)
+ {
+ if (strpos($FQName, '\\') !== 0) {
+ throw new PHPCS_Exception('$FQName must be a fully qualified name');
+ }
+
+ return (strpos(substr($FQName, 1), '\\') !== false);
+ }
+
+
+ /**
+ * Determine the namespace name an arbitrary token lives in.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The token position for which to determine the namespace.
+ *
+ * @return string Namespace name or empty string if it couldn't be determined or no namespace applies.
+ */
+ public function determineNamespace(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return '';
+ }
+
+ // Check for scoped namespace {}.
+ if (empty($tokens[$stackPtr]['conditions']) === false) {
+ $namespacePtr = $phpcsFile->getCondition($stackPtr, T_NAMESPACE);
+ if ($namespacePtr !== false) {
+ $namespace = $this->getDeclaredNamespaceName($phpcsFile, $namespacePtr);
+ if ($namespace !== false) {
+ return $namespace;
+ }
+
+ // We are in a scoped namespace, but couldn't determine the name. Searching for a global namespace is futile.
+ return '';
+ }
+ }
+
+ /*
+ * Not in a scoped namespace, so let's see if we can find a non-scoped namespace instead.
+ * Keeping in mind that:
+ * - there can be multiple non-scoped namespaces in a file (bad practice, but it happens).
+ * - the namespace keyword can also be used as part of a function/method call and such.
+ * - that a non-named namespace resolves to the global namespace.
+ */
+ $previousNSToken = $stackPtr;
+ $namespace = false;
+ do {
+ $previousNSToken = $phpcsFile->findPrevious(T_NAMESPACE, ($previousNSToken - 1));
+
+ // Stop if we encounter a scoped namespace declaration as we already know we're not in one.
+ if (empty($tokens[$previousNSToken]['scope_condition']) === false && $tokens[$previousNSToken]['scope_condition'] === $previousNSToken) {
+ break;
+ }
+
+ $namespace = $this->getDeclaredNamespaceName($phpcsFile, $previousNSToken);
+
+ } while ($namespace === false && $previousNSToken !== false);
+
+ // If we still haven't got a namespace, return an empty string.
+ if ($namespace === false) {
+ return '';
+ } else {
+ return $namespace;
+ }
+ }
+
+ /**
+ * Get the complete namespace name for a namespace declaration.
+ *
+ * For hierarchical namespaces, the name will be composed of several tokens,
+ * i.e. MyProject\Sub\Level which will be returned together as one string.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int|bool $stackPtr The position of a T_NAMESPACE token.
+ *
+ * @return string|false Namespace name or false if not a namespace declaration.
+ * Namespace name can be an empty string for global namespace declaration.
+ */
+ public function getDeclaredNamespaceName(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if ($stackPtr === false || isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_NAMESPACE) {
+ return false;
+ }
+
+ if ($tokens[($stackPtr + 1)]['code'] === T_NS_SEPARATOR) {
+ // Not a namespace declaration, but use of, i.e. namespace\someFunction();
+ return false;
+ }
+
+ $nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+ if ($tokens[$nextToken]['code'] === T_OPEN_CURLY_BRACKET) {
+ // Declaration for global namespace when using multiple namespaces in a file.
+ // I.e.: namespace {}
+ return '';
+ }
+
+ // Ok, this should be a namespace declaration, so get all the parts together.
+ $validTokens = array(
+ T_STRING => true,
+ T_NS_SEPARATOR => true,
+ T_WHITESPACE => true,
+ );
+
+ $namespaceName = '';
+ while (isset($validTokens[$tokens[$nextToken]['code']]) === true) {
+ $namespaceName .= trim($tokens[$nextToken]['content']);
+ $nextToken++;
+ }
+
+ return $namespaceName;
+ }
+
+
+ /**
+ * Get the stack pointer for a return type token for a given function.
+ *
+ * Compatible layer for older PHPCS versions which don't recognize
+ * return type hints correctly.
+ *
+ * Expects to be passed T_RETURN_TYPE, T_FUNCTION or T_CLOSURE token.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the token.
+ *
+ * @return int|false Stack pointer to the return type token or false if
+ * no return type was found or the passed token was
+ * not of the correct type.
+ */
+ public function getReturnTypeHintToken(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (defined('T_RETURN_TYPE') && $tokens[$stackPtr]['code'] === T_RETURN_TYPE) {
+ return $stackPtr;
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_FUNCTION && $tokens[$stackPtr]['code'] !== T_CLOSURE) {
+ return false;
+ }
+
+ if (isset($tokens[$stackPtr]['parenthesis_closer']) === false) {
+ return false;
+ }
+
+ // Allow for interface and abstract method declarations.
+ $endOfFunctionDeclaration = null;
+ if (isset($tokens[$stackPtr]['scope_opener'])) {
+ $endOfFunctionDeclaration = $tokens[$stackPtr]['scope_opener'];
+ } else {
+ $nextSemiColon = $phpcsFile->findNext(T_SEMICOLON, ($tokens[$stackPtr]['parenthesis_closer'] + 1), null, false, null, true);
+ if ($nextSemiColon !== false) {
+ $endOfFunctionDeclaration = $nextSemiColon;
+ }
+ }
+
+ if (isset($endOfFunctionDeclaration) === false) {
+ return false;
+ }
+
+ $hasColon = $phpcsFile->findNext(
+ array(T_COLON, T_INLINE_ELSE),
+ ($tokens[$stackPtr]['parenthesis_closer'] + 1),
+ $endOfFunctionDeclaration
+ );
+ if ($hasColon === false) {
+ return false;
+ }
+
+ /*
+ * - `self`, `parent` and `callable` are not being recognized as return types in PHPCS < 2.6.0.
+ * - Return types are not recognized at all in PHPCS < 2.4.0.
+ * - The T_RETURN_TYPE token is defined, but no longer in use since PHPCS 3.3.0+.
+ * The token will now be tokenized as T_STRING.
+ * - An `array` (return) type declaration was tokenized as `T_ARRAY_HINT` in PHPCS 2.3.3 - 3.2.3
+ * to prevent confusing sniffs looking for array declarations.
+ * As of PHPCS 3.3.0 `array` as a type declaration will be tokenized as `T_STRING`.
+ */
+ $unrecognizedTypes = array(
+ T_CALLABLE,
+ T_SELF,
+ T_PARENT,
+ T_ARRAY, // PHPCS < 2.4.0.
+ T_STRING,
+ );
+
+ return $phpcsFile->findPrevious($unrecognizedTypes, ($endOfFunctionDeclaration - 1), $hasColon);
+ }
+
+
+ /**
+ * Get the complete return type declaration for a given function.
+ *
+ * Cross-version compatible way to retrieve the complete return type declaration.
+ *
+ * For a classname-based return type, PHPCS, as well as the Sniff::getReturnTypeHintToken()
+ * method will mark the classname as the return type token.
+ * This method will find preceeding namespaces and namespace separators and will return a
+ * string containing the qualified return type declaration.
+ *
+ * Expects to be passed a T_RETURN_TYPE token or the return value from a call to
+ * the Sniff::getReturnTypeHintToken() method.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the return type token.
+ *
+ * @return string|false The name of the return type token.
+ */
+ public function getReturnTypeHintName(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // In older PHPCS versions, the nullable indicator will turn a return type colon into a T_INLINE_ELSE.
+ $colon = $phpcsFile->findPrevious(array(T_COLON, T_INLINE_ELSE, T_FUNCTION, T_CLOSE_PARENTHESIS), ($stackPtr - 1));
+ if ($colon === false
+ || ($tokens[$colon]['code'] !== T_COLON && $tokens[$colon]['code'] !== T_INLINE_ELSE)
+ ) {
+ // Shouldn't happen, just in case.
+ return;
+ }
+
+ $returnTypeHint = '';
+ for ($i = ($colon + 1); $i <= $stackPtr; $i++) {
+ // As of PHPCS 3.3.0+, all tokens are tokenized as "normal", so T_CALLABLE, T_SELF etc are
+ // all possible, just exclude anything that's regarded as empty and the nullable indicator.
+ if (isset(Tokens::$emptyTokens[$tokens[$i]['code']])) {
+ continue;
+ }
+
+ if ($tokens[$i]['type'] === 'T_NULLABLE') {
+ continue;
+ }
+
+ if (defined('T_NULLABLE') === false && $tokens[$i]['code'] === T_INLINE_THEN) {
+ // Old PHPCS.
+ continue;
+ }
+
+ $returnTypeHint .= $tokens[$i]['content'];
+ }
+
+ return $returnTypeHint;
+ }
+
+
+ /**
+ * Check whether a T_VARIABLE token is a class property declaration.
+ *
+ * Compatibility layer for PHPCS cross-version compatibility
+ * as PHPCS 2.4.0 - 2.7.1 does not have good enough support for
+ * anonymous classes. Along the same lines, the`getMemberProperties()`
+ * method does not support the `var` prefix.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The position in the stack of the
+ * T_VARIABLE token to verify.
+ *
+ * @return bool
+ */
+ public function isClassProperty(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== T_VARIABLE) {
+ return false;
+ }
+
+ // Note: interfaces can not declare properties.
+ $validScopes = array(
+ 'T_CLASS' => true,
+ 'T_ANON_CLASS' => true,
+ 'T_TRAIT' => true,
+ );
+
+ $scopePtr = $this->validDirectScope($phpcsFile, $stackPtr, $validScopes);
+ if ($scopePtr !== false) {
+ // Make sure it's not a method parameter.
+ if (empty($tokens[$stackPtr]['nested_parenthesis']) === true) {
+ return true;
+ } else {
+ $parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
+ $deepestOpen = array_pop($parenthesis);
+ if ($deepestOpen < $scopePtr
+ || isset($tokens[$deepestOpen]['parenthesis_owner']) === false
+ || $tokens[$tokens[$deepestOpen]['parenthesis_owner']]['code'] !== T_FUNCTION
+ ) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Check whether a T_CONST token is a class constant declaration.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The position in the stack of the
+ * T_CONST token to verify.
+ *
+ * @return bool
+ */
+ public function isClassConstant(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== T_CONST) {
+ return false;
+ }
+
+ // Note: traits can not declare constants.
+ $validScopes = array(
+ 'T_CLASS' => true,
+ 'T_ANON_CLASS' => true,
+ 'T_INTERFACE' => true,
+ );
+ if ($this->validDirectScope($phpcsFile, $stackPtr, $validScopes) !== false) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Check whether the direct wrapping scope of a token is within a limited set of
+ * acceptable tokens.
+ *
+ * Used to check, for instance, if a T_CONST is a class constant.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The position in the stack of the
+ * T_CONST token to verify.
+ * @param array $validScopes Array of token types.
+ * Keys should be the token types in string
+ * format to allow for newer token types.
+ * Value is irrelevant.
+ *
+ * @return int|bool StackPtr to the scope if valid, false otherwise.
+ */
+ protected function validDirectScope(File $phpcsFile, $stackPtr, $validScopes)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (empty($tokens[$stackPtr]['conditions']) === true) {
+ return false;
+ }
+
+ /*
+ * Check only the direct wrapping scope of the token.
+ */
+ $conditions = array_keys($tokens[$stackPtr]['conditions']);
+ $ptr = array_pop($conditions);
+
+ if (isset($tokens[$ptr]) === false) {
+ return false;
+ }
+
+ if (isset($validScopes[$tokens[$ptr]['type']]) === true) {
+ return $ptr;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Get an array of just the type hints from a function declaration.
+ *
+ * Expects to be passed T_FUNCTION or T_CLOSURE token.
+ *
+ * Strips potential nullable indicator and potential global namespace
+ * indicator from the type hints before returning them.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the token.
+ *
+ * @return array Array with type hints or an empty array if
+ * - the function does not have any parameters
+ * - no type hints were found
+ * - or the passed token was not of the correct type.
+ */
+ public function getTypeHintsFromFunctionDeclaration(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] !== T_FUNCTION && $tokens[$stackPtr]['code'] !== T_CLOSURE) {
+ return array();
+ }
+
+ $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($parameters) || is_array($parameters) === false) {
+ return array();
+ }
+
+ $typeHints = array();
+
+ foreach ($parameters as $param) {
+ if ($param['type_hint'] === '') {
+ continue;
+ }
+
+ // Strip off potential nullable indication.
+ $typeHint = ltrim($param['type_hint'], '?');
+
+ // Strip off potential (global) namespace indication.
+ $typeHint = ltrim($typeHint, '\\');
+
+ if ($typeHint !== '') {
+ $typeHints[] = $typeHint;
+ }
+ }
+
+ return $typeHints;
+ }
+
+
+ /**
+ * Get the hash algorithm name from the parameter in a hash function call.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
+ * @param int $stackPtr The position of the T_STRING function token.
+ *
+ * @return string|false The algorithm name without quotes if this was a relevant hash
+ * function call or false if it was not.
+ */
+ public function getHashAlgorithmParameter(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($tokens[$stackPtr]['code'] !== T_STRING) {
+ return false;
+ }
+
+ $functionName = $tokens[$stackPtr]['content'];
+ $functionNameLc = strtolower($functionName);
+
+ // Bow out if not one of the functions we're targetting.
+ if (isset($this->hashAlgoFunctions[$functionNameLc]) === false) {
+ return false;
+ }
+
+ // Get the parameter from the function call which should contain the algorithm name.
+ $algoParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, $this->hashAlgoFunctions[$functionNameLc]);
+ if ($algoParam === false) {
+ return false;
+ }
+
+ // Algorithm is a text string, so we need to remove the quotes.
+ $algo = strtolower(trim($algoParam['raw']));
+ $algo = $this->stripQuotes($algo);
+
+ return $algo;
+ }
+
+
+ /**
+ * Determine whether an arbitrary T_STRING token is the use of a global constant.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function call token.
+ *
+ * @return bool
+ */
+ public function isUseOfGlobalConstant(File $phpcsFile, $stackPtr)
+ {
+ static $isLowPHPCS, $isLowPHP;
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ // Is this one of the tokens this function handles ?
+ if ($tokens[$stackPtr]['code'] !== T_STRING) {
+ return false;
+ }
+
+ // Check for older PHP, PHPCS version so we can compensate for misidentified tokens.
+ if (isset($isLowPHPCS, $isLowPHP) === false) {
+ $isLowPHP = false;
+ $isLowPHPCS = false;
+ if (version_compare(PHP_VERSION_ID, '50400', '<')) {
+ $isLowPHP = true;
+ $isLowPHPCS = version_compare(PHPCSHelper::getVersion(), '2.4.0', '<');
+ }
+ }
+
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($next !== false
+ && ($tokens[$next]['code'] === T_OPEN_PARENTHESIS
+ || $tokens[$next]['code'] === T_DOUBLE_COLON)
+ ) {
+ // Function call or declaration.
+ return false;
+ }
+
+ // Array of tokens which if found preceding the $stackPtr indicate that a T_STRING is not a global constant.
+ $tokensToIgnore = array(
+ 'T_NAMESPACE' => true,
+ 'T_USE' => true,
+ 'T_CLASS' => true,
+ 'T_TRAIT' => true,
+ 'T_INTERFACE' => true,
+ 'T_EXTENDS' => true,
+ 'T_IMPLEMENTS' => true,
+ 'T_NEW' => true,
+ 'T_FUNCTION' => true,
+ 'T_DOUBLE_COLON' => true,
+ 'T_OBJECT_OPERATOR' => true,
+ 'T_INSTANCEOF' => true,
+ 'T_INSTEADOF' => true,
+ 'T_GOTO' => true,
+ 'T_AS' => true,
+ 'T_PUBLIC' => true,
+ 'T_PROTECTED' => true,
+ 'T_PRIVATE' => true,
+ );
+
+ $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if ($prev !== false
+ && (isset($tokensToIgnore[$tokens[$prev]['type']]) === true
+ || ($tokens[$prev]['code'] === T_STRING
+ && (($isLowPHPCS === true
+ && $tokens[$prev]['content'] === 'trait')
+ || ($isLowPHP === true
+ && $tokens[$prev]['content'] === 'insteadof'))))
+ ) {
+ // Not the use of a constant.
+ return false;
+ }
+
+ if ($prev !== false
+ && $tokens[$prev]['code'] === T_NS_SEPARATOR
+ && $tokens[($prev - 1)]['code'] === T_STRING
+ ) {
+ // Namespaced constant of the same name.
+ return false;
+ }
+
+ if ($prev !== false
+ && $tokens[$prev]['code'] === T_CONST
+ && $this->isClassConstant($phpcsFile, $prev) === true
+ ) {
+ // Class constant declaration of the same name.
+ return false;
+ }
+
+ /*
+ * Deal with a number of variations of use statements.
+ */
+ for ($i = $stackPtr; $i > 0; $i--) {
+ if ($tokens[$i]['line'] !== $tokens[$stackPtr]['line']) {
+ break;
+ }
+ }
+
+ $firstOnLine = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
+ if ($firstOnLine !== false && $tokens[$firstOnLine]['code'] === T_USE) {
+ $nextOnLine = $phpcsFile->findNext(Tokens::$emptyTokens, ($firstOnLine + 1), null, true);
+ if ($nextOnLine !== false) {
+ if (($tokens[$nextOnLine]['code'] === T_STRING && $tokens[$nextOnLine]['content'] === 'const')
+ || $tokens[$nextOnLine]['code'] === T_CONST // Happens in some PHPCS versions.
+ ) {
+ $hasNsSep = $phpcsFile->findNext(T_NS_SEPARATOR, ($nextOnLine + 1), $stackPtr);
+ if ($hasNsSep !== false) {
+ // Namespaced const (group) use statement.
+ return false;
+ }
+ } else {
+ // Not a const use statement.
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Determine whether the tokens between $start and $end together form a positive number
+ * as recognized by PHP.
+ *
+ * The outcome of this function is reliable for `true`, `false` should be regarded as
+ * "undetermined".
+ *
+ * Note: Zero is *not* regarded as a positive number.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $start Start of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param int $end End of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param bool $allowFloats Whether to only consider integers, or also floats.
+ *
+ * @return bool True if PHP would evaluate the snippet as a positive number.
+ * False if not or if it could not be reliably determined
+ * (variable or calculations and such).
+ */
+ public function isPositiveNumber(File $phpcsFile, $start, $end, $allowFloats = false)
+ {
+ $number = $this->isNumber($phpcsFile, $start, $end, $allowFloats);
+
+ if ($number === false) {
+ return false;
+ }
+
+ return ($number > 0);
+ }
+
+
+ /**
+ * Determine whether the tokens between $start and $end together form a negative number
+ * as recognized by PHP.
+ *
+ * The outcome of this function is reliable for `true`, `false` should be regarded as
+ * "undetermined".
+ *
+ * Note: Zero is *not* regarded as a negative number.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $start Start of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param int $end End of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param bool $allowFloats Whether to only consider integers, or also floats.
+ *
+ * @return bool True if PHP would evaluate the snippet as a negative number.
+ * False if not or if it could not be reliably determined
+ * (variable or calculations and such).
+ */
+ public function isNegativeNumber(File $phpcsFile, $start, $end, $allowFloats = false)
+ {
+ $number = $this->isNumber($phpcsFile, $start, $end, $allowFloats);
+
+ if ($number === false) {
+ return false;
+ }
+
+ return ($number < 0);
+ }
+
+ /**
+ * Determine whether the tokens between $start and $end together form a number
+ * as recognized by PHP.
+ *
+ * The outcome of this function is reliable for "true-ish" values, `false` should
+ * be regarded as "undetermined".
+ *
+ * @link https://3v4l.org/npTeM
+ *
+ * Mainly intended for examining variable assignments, function call parameters, array values
+ * where the start and end of the snippet to examine is very clear.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $start Start of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param int $end End of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param bool $allowFloats Whether to only consider integers, or also floats.
+ *
+ * @return int|float|bool The number found if PHP would evaluate the snippet as a number.
+ * The return type will be int if $allowFloats is false, if
+ * $allowFloats is true, the return type will be float.
+ * False will be returned when the snippet does not evaluate to a
+ * number or if it could not be reliably determined
+ * (variable or calculations and such).
+ */
+ protected function isNumber(File $phpcsFile, $start, $end, $allowFloats = false)
+ {
+ $stringTokens = Tokens::$heredocTokens + Tokens::$stringTokens;
+
+ $validTokens = array();
+ $validTokens[T_LNUMBER] = true;
+ $validTokens[T_TRUE] = true; // Evaluates to int 1.
+ $validTokens[T_FALSE] = true; // Evaluates to int 0.
+ $validTokens[T_NULL] = true; // Evaluates to int 0.
+
+ if ($allowFloats === true) {
+ $validTokens[T_DNUMBER] = true;
+ }
+
+ $maybeValidTokens = $stringTokens + $validTokens;
+
+ $tokens = $phpcsFile->getTokens();
+ $searchEnd = ($end + 1);
+ $negativeNumber = false;
+
+ if (isset($tokens[$start], $tokens[$searchEnd]) === false) {
+ return false;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $start, $searchEnd, true);
+ while ($nextNonEmpty !== false
+ && ($tokens[$nextNonEmpty]['code'] === T_PLUS
+ || $tokens[$nextNonEmpty]['code'] === T_MINUS)
+ ) {
+
+ if ($tokens[$nextNonEmpty]['code'] === T_MINUS) {
+ $negativeNumber = ($negativeNumber === false) ? true : false;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $searchEnd, true);
+ }
+
+ if ($nextNonEmpty === false || isset($maybeValidTokens[$tokens[$nextNonEmpty]['code']]) === false) {
+ return false;
+ }
+
+ $content = false;
+ if ($tokens[$nextNonEmpty]['code'] === T_LNUMBER
+ || $tokens[$nextNonEmpty]['code'] === T_DNUMBER
+ ) {
+ $content = (float) $tokens[$nextNonEmpty]['content'];
+ } elseif ($tokens[$nextNonEmpty]['code'] === T_TRUE) {
+ $content = 1.0;
+ } elseif ($tokens[$nextNonEmpty]['code'] === T_FALSE
+ || $tokens[$nextNonEmpty]['code'] === T_NULL
+ ) {
+ $content = 0.0;
+ } elseif (isset($stringTokens[$tokens[$nextNonEmpty]['code']]) === true) {
+
+ if ($tokens[$nextNonEmpty]['code'] === T_START_HEREDOC
+ || $tokens[$nextNonEmpty]['code'] === T_START_NOWDOC
+ ) {
+ // Skip past heredoc/nowdoc opener to the first content.
+ $firstDocToken = $phpcsFile->findNext(array(T_HEREDOC, T_NOWDOC), ($nextNonEmpty + 1), $searchEnd);
+ if ($firstDocToken === false) {
+ // Live coding or parse error.
+ return false;
+ }
+
+ $stringContent = $content = $tokens[$firstDocToken]['content'];
+
+ // Skip forward to the end in preparation for the next part of the examination.
+ $nextNonEmpty = $phpcsFile->findNext(array(T_END_HEREDOC, T_END_NOWDOC), ($nextNonEmpty + 1), $searchEnd);
+ if ($nextNonEmpty === false) {
+ // Live coding or parse error.
+ return false;
+ }
+ } else {
+ // Gather subsequent lines for a multi-line string.
+ for ($i = $nextNonEmpty; $i < $searchEnd; $i++) {
+ if ($tokens[$i]['code'] !== $tokens[$nextNonEmpty]['code']) {
+ break;
+ }
+ $content .= $tokens[$i]['content'];
+ }
+
+ $nextNonEmpty = --$i;
+ $content = $this->stripQuotes($content);
+ $stringContent = $content;
+ }
+
+ /*
+ * Regexes based on the formats outlined in the manual, created by JRF.
+ * @link http://php.net/manual/en/language.types.float.php
+ */
+ $regexInt = '`^\s*[0-9]+`';
+ $regexFloat = '`^\s*(?:[+-]?(?:(?:(?P[0-9]+)|(?P([0-9]*\.(?P>LNUM)|(?P>LNUM)\.[0-9]*)))[eE][+-]?(?P>LNUM))|(?P>DNUM))`';
+
+ $intString = preg_match($regexInt, $content, $intMatch);
+ $floatString = preg_match($regexFloat, $content, $floatMatch);
+
+ // Does the text string start with a number ? If so, PHP would juggle it and use it as a number.
+ if ($allowFloats === false) {
+ if ($intString !== 1 || $floatString === 1) {
+ if ($floatString === 1) {
+ // Found float. Only integers targetted.
+ return false;
+ }
+
+ $content = 0.0;
+ } else {
+ $content = (float) trim($intMatch[0]);
+ }
+ } else {
+ if ($intString !== 1 && $floatString !== 1) {
+ $content = 0.0;
+ } else {
+ $content = ($floatString === 1) ? (float) trim($floatMatch[0]) : (float) trim($intMatch[0]);
+ }
+ }
+
+ // Allow for different behaviour for hex numeric strings between PHP 5 vs PHP 7.
+ if ($intString === 1 && trim($intMatch[0]) === '0'
+ && preg_match('`^\s*(0x[A-Fa-f0-9]+)`', $stringContent, $hexNumberString) === 1
+ && $this->supportsBelow('5.6') === true
+ ) {
+ // The filter extension still allows for hex numeric strings in PHP 7, so
+ // use that to get the numeric value if possible.
+ // If the filter extension is not available, the value will be zero, but so be it.
+ if (function_exists('filter_var')) {
+ $filtered = filter_var($hexNumberString[1], FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
+ if ($filtered !== false) {
+ $content = $filtered;
+ }
+ }
+ }
+ }
+
+ // OK, so we have a number, now is there still more code after it ?
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $searchEnd, true);
+ if ($nextNonEmpty !== false) {
+ return false;
+ }
+
+ if ($negativeNumber === true) {
+ $content = -$content;
+ }
+
+ if ($allowFloats === false) {
+ return (int) $content;
+ }
+
+ return $content;
+ }
+
+
+ /**
+ * Determine whether the tokens between $start and $end together form a numberic calculation
+ * as recognized by PHP.
+ *
+ * The outcome of this function is reliable for `true`, `false` should be regarded as "undetermined".
+ *
+ * Mainly intended for examining variable assignments, function call parameters, array values
+ * where the start and end of the snippet to examine is very clear.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $start Start of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ * @param int $end End of the snippet (inclusive), i.e. this
+ * token will be examined as part of the snippet.
+ *
+ * @return bool
+ */
+ protected function isNumericCalculation(File $phpcsFile, $start, $end)
+ {
+ $arithmeticTokens = Tokens::$arithmeticTokens;
+
+ // phpcs:disable PHPCompatibility.Constants.NewConstants.t_powFound
+ if (defined('T_POW') && isset($arithmeticTokens[T_POW]) === false) {
+ // T_POW was not added to the arithmetic array until PHPCS 2.9.0.
+ $arithmeticTokens[T_POW] = T_POW;
+ }
+ // phpcs:enable
+
+ $skipTokens = Tokens::$emptyTokens;
+ $skipTokens[] = T_MINUS;
+ $skipTokens[] = T_PLUS;
+
+ // Find the first arithmetic operator, but skip past +/- signs before numbers.
+ $nextNonEmpty = ($start - 1);
+ do {
+ $nextNonEmpty = $phpcsFile->findNext($skipTokens, ($nextNonEmpty + 1), ($end + 1), true);
+ $arithmeticOperator = $phpcsFile->findNext($arithmeticTokens, ($nextNonEmpty + 1), ($end + 1));
+ } while ($nextNonEmpty !== false && $arithmeticOperator !== false && $nextNonEmpty === $arithmeticOperator);
+
+ if ($arithmeticOperator === false) {
+ return false;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $subsetStart = $start;
+ $subsetEnd = ($arithmeticOperator - 1);
+
+ while ($this->isNumber($phpcsFile, $subsetStart, $subsetEnd, true) !== false
+ && isset($tokens[($arithmeticOperator + 1)]) === true
+ ) {
+ // Recognize T_POW for PHPCS < 2.4.0 on low PHP versions.
+ if (defined('T_POW') === false
+ && $tokens[$arithmeticOperator]['code'] === T_MULTIPLY
+ && $tokens[($arithmeticOperator + 1)]['code'] === T_MULTIPLY
+ && isset($tokens[$arithmeticOperator + 2]) === true
+ ) {
+ // Move operator one forward to the second * in T_POW.
+ ++$arithmeticOperator;
+ }
+
+ $subsetStart = ($arithmeticOperator + 1);
+ $nextNonEmpty = $arithmeticOperator;
+ do {
+ $nextNonEmpty = $phpcsFile->findNext($skipTokens, ($nextNonEmpty + 1), ($end + 1), true);
+ $arithmeticOperator = $phpcsFile->findNext($arithmeticTokens, ($nextNonEmpty + 1), ($end + 1));
+ } while ($nextNonEmpty !== false && $arithmeticOperator !== false && $nextNonEmpty === $arithmeticOperator);
+
+ if ($arithmeticOperator === false) {
+ // Last calculation operator already reached.
+ if ($this->isNumber($phpcsFile, $subsetStart, $end, true) !== false) {
+ return true;
+ }
+
+ return false;
+ }
+
+ $subsetEnd = ($arithmeticOperator - 1);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Determine whether a T_OPEN/CLOSE_SHORT_ARRAY token is a list() construct.
+ *
+ * Note: A variety of PHPCS versions have bugs in the tokenizing of short arrays.
+ * In that case, the tokens are identified as T_OPEN/CLOSE_SQUARE_BRACKET.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function call token.
+ *
+ * @return bool
+ */
+ public function isShortList(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Check for the existence of the token.
+ if (isset($tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ // Is this one of the tokens this function handles ?
+ if ($tokens[$stackPtr]['code'] !== T_OPEN_SHORT_ARRAY
+ && $tokens[$stackPtr]['code'] !== T_CLOSE_SHORT_ARRAY
+ ) {
+ return false;
+ }
+
+ switch ($tokens[$stackPtr]['code']) {
+ case T_OPEN_SHORT_ARRAY:
+ if (isset($tokens[$stackPtr]['bracket_closer']) === true) {
+ $opener = $stackPtr;
+ $closer = $tokens[$stackPtr]['bracket_closer'];
+ }
+ break;
+
+ case T_CLOSE_SHORT_ARRAY:
+ if (isset($tokens[$stackPtr]['bracket_opener']) === true) {
+ $opener = $tokens[$stackPtr]['bracket_opener'];
+ $closer = $stackPtr;
+ }
+ break;
+ }
+
+ if (isset($opener, $closer) === false) {
+ // Parse error, live coding or real square bracket.
+ return false;
+ }
+
+ /*
+ * PHPCS cross-version compatibility: work around for square brackets misidentified
+ * as short array when preceded by a variable variable in older PHPCS versions.
+ */
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($opener - 1), null, true, null, true);
+
+ if ($prevNonEmpty !== false
+ && $tokens[$prevNonEmpty]['code'] === T_CLOSE_CURLY_BRACKET
+ && isset($tokens[$prevNonEmpty]['bracket_opener']) === true
+ ) {
+ $maybeVariableVariable = $phpcsFile->findPrevious(
+ Tokens::$emptyTokens,
+ ($tokens[$prevNonEmpty]['bracket_opener'] - 1),
+ null,
+ true,
+ null,
+ true
+ );
+
+ if ($tokens[$maybeVariableVariable]['code'] === T_VARIABLE
+ || $tokens[$maybeVariableVariable]['code'] === T_DOLLAR
+ ) {
+ return false;
+ }
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($closer + 1), null, true, null, true);
+
+ if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === T_EQUAL) {
+ return true;
+ }
+
+ if ($prevNonEmpty !== false
+ && $tokens[$prevNonEmpty]['code'] === T_AS
+ && isset($tokens[$prevNonEmpty]['nested_parenthesis']) === true
+ ) {
+ $parentheses = array_reverse($tokens[$prevNonEmpty]['nested_parenthesis'], true);
+ foreach ($parentheses as $open => $close) {
+ if (isset($tokens[$open]['parenthesis_owner'])
+ && $tokens[$tokens[$open]['parenthesis_owner']]['code'] === T_FOREACH
+ ) {
+ return true;
+ }
+ }
+ }
+
+ // Maybe this is a short list syntax nested inside another short list syntax ?
+ $parentOpener = $opener;
+ do {
+ $parentOpener = $phpcsFile->findPrevious(
+ array(T_OPEN_SHORT_ARRAY, T_OPEN_SQUARE_BRACKET),
+ ($parentOpener - 1),
+ null,
+ false,
+ null,
+ true
+ );
+
+ if ($parentOpener === false) {
+ return false;
+ }
+
+ } while (isset($tokens[$parentOpener]['bracket_closer']) === true
+ && $tokens[$parentOpener]['bracket_closer'] < $opener
+ );
+
+ if (isset($tokens[$parentOpener]['bracket_closer']) === true
+ && $tokens[$parentOpener]['bracket_closer'] > $closer
+ ) {
+ // Work around tokenizer issue in PHPCS 2.0 - 2.7.
+ $phpcsVersion = PHPCSHelper::getVersion();
+ if ((version_compare($phpcsVersion, '2.0', '>') === true
+ && version_compare($phpcsVersion, '2.8', '<') === true)
+ && $tokens[$parentOpener]['code'] === T_OPEN_SQUARE_BRACKET
+ ) {
+ $nextNonEmpty = $phpcsFile->findNext(
+ Tokens::$emptyTokens,
+ ($tokens[$parentOpener]['bracket_closer'] + 1),
+ null,
+ true,
+ null,
+ true
+ );
+
+ if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === T_EQUAL) {
+ return true;
+ }
+
+ return false;
+ }
+
+ return $this->isShortList($phpcsFile, $parentOpener);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Determine whether the tokens between $start and $end could together represent a variable.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $start Starting point stack pointer. Inclusive.
+ * I.e. this token should be taken into account.
+ * @param int $end End point stack pointer. Exclusive.
+ * I.e. this token should not be taken into account.
+ * @param int $targetNestingLevel The nesting level the variable should be at.
+ *
+ * @return bool
+ */
+ public function isVariable(File $phpcsFile, $start, $end, $targetNestingLevel)
+ {
+ static $tokenBlackList, $bracketTokens;
+
+ // Create the token arrays only once.
+ if (isset($tokenBlackList, $bracketTokens) === false) {
+
+ $tokenBlackList = array(
+ T_OPEN_PARENTHESIS => T_OPEN_PARENTHESIS,
+ T_STRING_CONCAT => T_STRING_CONCAT,
+ );
+ $tokenBlackList += Tokens::$assignmentTokens;
+ $tokenBlackList += Tokens::$equalityTokens;
+ $tokenBlackList += Tokens::$comparisonTokens;
+ $tokenBlackList += Tokens::$operators;
+ $tokenBlackList += Tokens::$booleanOperators;
+ $tokenBlackList += Tokens::$castTokens;
+
+ /*
+ * List of brackets which can be part of a variable variable.
+ *
+ * Key is the open bracket token, value the close bracket token.
+ */
+ $bracketTokens = array(
+ T_OPEN_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
+ T_OPEN_SQUARE_BRACKET => T_CLOSE_SQUARE_BRACKET,
+ );
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // If no variable at all was found, then it's definitely a no-no.
+ $hasVariable = $phpcsFile->findNext(T_VARIABLE, $start, $end);
+ if ($hasVariable === false) {
+ return false;
+ }
+
+ // Check if the variable found is at the right level. Deeper levels are always an error.
+ if (isset($tokens[$hasVariable]['nested_parenthesis'])
+ && count($tokens[$hasVariable]['nested_parenthesis']) !== $targetNestingLevel
+ ) {
+ return false;
+ }
+
+ // Ok, so the first variable is at the right level, now are there any
+ // blacklisted tokens within the empty() ?
+ $hasBadToken = $phpcsFile->findNext($tokenBlackList, $start, $end);
+ if ($hasBadToken === false) {
+ return true;
+ }
+
+ // If there are also bracket tokens, the blacklisted token might be part of a variable
+ // variable, but if there are no bracket tokens, we know we have an error.
+ $hasBrackets = $phpcsFile->findNext($bracketTokens, $start, $end);
+ if ($hasBrackets === false) {
+ return false;
+ }
+
+ // Ok, we have both a blacklisted token as well as brackets, so we need to walk
+ // the tokens of the variable variable.
+ for ($i = $start; $i < $end; $i++) {
+ // If this is a bracket token, skip to the end of the bracketed expression.
+ if (isset($bracketTokens[$tokens[$i]['code']], $tokens[$i]['bracket_closer'])) {
+ $i = $tokens[$i]['bracket_closer'];
+ continue;
+ }
+
+ // If it's a blacklisted token, not within brackets, we have an error.
+ if (isset($tokenBlackList[$tokens[$i]['code']])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewAnonymousClassesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewAnonymousClassesSniff.php
new file mode 100644
index 0000000..09cd440
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewAnonymousClassesSniff.php
@@ -0,0 +1,87 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Classes;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Classes\NewAnonymousClasses.
+ *
+ * Anonymous classes are supported in PHP 7.0
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewAnonymousClassesSniff extends Sniff
+{
+
+ /**
+ * Tokens which in various PHP versions indicate the `class` keyword.
+ *
+ * The dedicated anonymous class token is added from the `register()`
+ * method if the token is available.
+ *
+ * @var array
+ */
+ private $indicators = array(
+ T_CLASS => T_CLASS,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ if (defined('T_ANON_CLASS')) {
+ $this->indicators[T_ANON_CLASS] = T_ANON_CLASS;
+ }
+
+ return array(T_NEW);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.6') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+ if ($nextNonEmpty === false || isset($this->indicators[$tokens[$nextNonEmpty]['code']]) === false) {
+ return;
+ }
+
+ // Still here ? In that case, it is an anonymous class.
+ $phpcsFile->addError(
+ 'Anonymous classes are not supported in PHP 5.6 or earlier',
+ $stackPtr,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewClassesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewClassesSniff.php
new file mode 100644
index 0000000..1060870
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewClassesSniff.php
@@ -0,0 +1,842 @@
+
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Classes;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Classes\NewClassesSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+class NewClassesSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new classes, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the class appears.
+ *
+ * @var array(string => array(string => bool))
+ */
+ protected $newClasses = array(
+ 'ArrayObject' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'ArrayIterator' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CachingIterator' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'DirectoryIterator' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'RecursiveDirectoryIterator' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'RecursiveIteratorIterator' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'php_user_filter' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'tidy' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+
+ 'SimpleXMLElement' => array(
+ '5.0.0' => false,
+ '5.0.1' => true,
+ ),
+ 'tidyNode' => array(
+ '5.0.0' => false,
+ '5.0.1' => true,
+ ),
+
+ 'libXMLError' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'PDO' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'PDOStatement' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'AppendIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'EmptyIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'FilterIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'InfiniteIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'IteratorIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'LimitIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'NoRewindIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'ParentIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'RecursiveArrayIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'RecursiveCachingIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'RecursiveFilterIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'SimpleXMLIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'SplFileObject' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'XMLReader' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+
+ 'SplFileInfo' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'SplTempFileObject' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'XMLWriter' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+
+ 'DateTime' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'DateTimeZone' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'RegexIterator' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'RecursiveRegexIterator' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'ReflectionFunctionAbstract' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'ZipArchive' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+
+ 'Closure' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'DateInterval' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'DatePeriod' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'finfo' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'Collator' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'NumberFormatter' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'Locale' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'Normalizer' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'MessageFormatter' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'IntlDateFormatter' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'Phar' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PharData' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PharFileInfo' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FilesystemIterator' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'GlobIterator' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'MultipleIterator' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'RecursiveTreeIterator' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplDoublyLinkedList' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplFixedArray' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplHeap' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplMaxHeap' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplMinHeap' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplObjectStorage' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplPriorityQueue' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplQueue' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SplStack' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+
+ 'ResourceBundle' => array(
+ '5.3.1' => false,
+ '5.3.2' => true,
+ ),
+
+ 'CallbackFilterIterator' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'RecursiveCallbackFilterIterator' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ReflectionZendExtension' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SessionHandler' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SNMP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'Transliterator' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'Spoofchecker' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ 'Generator' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLFile' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'DateTimeImmutable' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IntlCalendar' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IntlGregorianCalendar' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IntlTimeZone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IntlBreakIterator' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IntlRuleBasedBreakIterator' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IntlCodePointBreakIterator' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'UConverter' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+
+ 'GMP' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+
+ 'IntlChar' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ReflectionType' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ReflectionGenerator' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ 'ReflectionClassConstant' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+
+ );
+
+ /**
+ * A list of new Exception classes, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the class appears.
+ *
+ * {@internal Classes listed here do not need to be added to the $newClasses
+ * property as well.
+ * This list is automatically added to the $newClasses property
+ * in the `register()` method.}}
+ *
+ * {@internal Helper to update this list: https://3v4l.org/MhlUp}}
+ *
+ * @var array(string => array(string => bool))
+ */
+ protected $newExceptions = array(
+ 'com_exception' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'DOMException' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'Exception' => array(
+ // According to the docs introduced in PHP 5.1, but this appears to be.
+ // an error. Class was introduced with try/catch keywords in PHP 5.0.
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'ReflectionException' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'SoapFault' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'SQLiteException' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+
+ 'ErrorException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'BadFunctionCallException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'BadMethodCallException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'DomainException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'InvalidArgumentException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'LengthException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'LogicException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'mysqli_sql_exception' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'OutOfBoundsException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'OutOfRangeException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'OverflowException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'PDOException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'RangeException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'RuntimeException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'UnderflowException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'UnexpectedValueException' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+
+ 'PharException' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+
+ 'SNMPException' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ 'IntlException' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+
+ 'Error' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ArithmeticError' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'AssertionError' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'DivisionByZeroError' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ParseError' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'TypeError' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ClosedGeneratorException' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'UI\Exception\InvalidArgumentException' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'UI\Exception\RuntimeException' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ 'ArgumentCountError' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+
+ 'SodiumException' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ 'CompileError' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'JsonException' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of class names.
+ $this->newClasses = $this->arrayKeysToLowercase($this->newClasses);
+ $this->newExceptions = $this->arrayKeysToLowercase($this->newExceptions);
+
+ // Add the Exception classes to the Classes list.
+ $this->newClasses = array_merge($this->newClasses, $this->newExceptions);
+
+ $targets = array(
+ T_NEW,
+ T_CLASS,
+ T_DOUBLE_COLON,
+ T_FUNCTION,
+ T_CLOSURE,
+ T_CATCH,
+ );
+
+ if (defined('T_ANON_CLASS')) {
+ $targets[] = T_ANON_CLASS;
+ }
+
+ if (defined('T_RETURN_TYPE')) {
+ $targets[] = T_RETURN_TYPE;
+ }
+
+ return $targets;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ switch ($tokens[$stackPtr]['type']) {
+ case 'T_FUNCTION':
+ case 'T_CLOSURE':
+ $this->processFunctionToken($phpcsFile, $stackPtr);
+
+ // Deal with older PHPCS version which don't recognize return type hints
+ // as well as newer PHPCS versions (3.3.0+) where the tokenization has changed.
+ $returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
+ if ($returnTypeHint !== false) {
+ $this->processReturnTypeToken($phpcsFile, $returnTypeHint);
+ }
+ break;
+
+ case 'T_CATCH':
+ $this->processCatchToken($phpcsFile, $stackPtr);
+ break;
+
+ case 'T_RETURN_TYPE':
+ $this->processReturnTypeToken($phpcsFile, $stackPtr);
+ break;
+
+ default:
+ $this->processSingularToken($phpcsFile, $stackPtr);
+ break;
+ }
+ }
+
+
+ /**
+ * Processes this test for when a token resulting in a singular class name is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processSingularToken(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $FQClassName = '';
+
+ if ($tokens[$stackPtr]['type'] === 'T_NEW') {
+ $FQClassName = $this->getFQClassNameFromNewToken($phpcsFile, $stackPtr);
+
+ } elseif ($tokens[$stackPtr]['type'] === 'T_CLASS' || $tokens[$stackPtr]['type'] === 'T_ANON_CLASS') {
+ $FQClassName = $this->getFQExtendedClassName($phpcsFile, $stackPtr);
+
+ } elseif ($tokens[$stackPtr]['type'] === 'T_DOUBLE_COLON') {
+ $FQClassName = $this->getFQClassNameFromDoubleColonToken($phpcsFile, $stackPtr);
+ }
+
+ if ($FQClassName === '') {
+ return;
+ }
+
+ $className = substr($FQClassName, 1); // Remove global namespace indicator.
+ $classNameLc = strtolower($className);
+
+ if (isset($this->newClasses[$classNameLc]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $className,
+ 'nameLc' => $classNameLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Processes this test for when a function token is encountered.
+ *
+ * - Detect new classes when used as a type hint.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processFunctionToken(File $phpcsFile, $stackPtr)
+ {
+ // Retrieve typehints stripped of global NS indicator and/or nullable indicator.
+ $typeHints = $this->getTypeHintsFromFunctionDeclaration($phpcsFile, $stackPtr);
+ if (empty($typeHints) || is_array($typeHints) === false) {
+ return;
+ }
+
+ foreach ($typeHints as $hint) {
+
+ $typeHintLc = strtolower($hint);
+
+ if (isset($this->newClasses[$typeHintLc]) === true) {
+ $itemInfo = array(
+ 'name' => $hint,
+ 'nameLc' => $typeHintLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+ }
+ }
+
+
+ /**
+ * Processes this test for when a catch token is encountered.
+ *
+ * - Detect exceptions when used in a catch statement.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processCatchToken(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Bow out during live coding.
+ if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $opener = $tokens[$stackPtr]['parenthesis_opener'];
+ $closer = ($tokens[$stackPtr]['parenthesis_closer'] + 1);
+ $name = '';
+ $listen = array(
+ // Parts of a (namespaced) class name.
+ T_STRING => true,
+ T_NS_SEPARATOR => true,
+ // End/split tokens.
+ T_VARIABLE => false,
+ T_BITWISE_OR => false,
+ T_CLOSE_CURLY_BRACKET => false, // Shouldn't be needed as we expect a var before this.
+ );
+
+ for ($i = ($opener + 1); $i < $closer; $i++) {
+ if (isset($listen[$tokens[$i]['code']]) === false) {
+ continue;
+ }
+
+ if ($listen[$tokens[$i]['code']] === true) {
+ $name .= $tokens[$i]['content'];
+ continue;
+ } else {
+ if (empty($name) === true) {
+ // Weird, we should have a name by the time we encounter a variable or |.
+ // So this may be the closer.
+ continue;
+ }
+
+ $name = ltrim($name, '\\');
+ $nameLC = strtolower($name);
+
+ if (isset($this->newExceptions[$nameLC]) === true) {
+ $itemInfo = array(
+ 'name' => $name,
+ 'nameLc' => $nameLC,
+ );
+ $this->handleFeature($phpcsFile, $i, $itemInfo);
+ }
+
+ // Reset for a potential multi-catch.
+ $name = '';
+ }
+ }
+ }
+
+
+ /**
+ * Processes this test for when a return type token is encountered.
+ *
+ * - Detect new classes when used as a return type declaration.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processReturnTypeToken(File $phpcsFile, $stackPtr)
+ {
+ $returnTypeHint = $this->getReturnTypeHintName($phpcsFile, $stackPtr);
+ $returnTypeHint = ltrim($returnTypeHint, '\\');
+ $returnTypeHintLc = strtolower($returnTypeHint);
+
+ if (isset($this->newClasses[$returnTypeHintLc]) === false) {
+ return;
+ }
+
+ // Still here ? Then this is a return type declaration using a new class.
+ $itemInfo = array(
+ 'name' => $returnTypeHint,
+ 'nameLc' => $returnTypeHintLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newClasses[$itemInfo['nameLc']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The built-in class ' . parent::getErrorMsgTemplate();
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewConstVisibilitySniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewConstVisibilitySniff.php
new file mode 100644
index 0000000..7cc27f3
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewConstVisibilitySniff.php
@@ -0,0 +1,78 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Classes;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Classes\NewConstVisibility.
+ *
+ * Visibility for class constants is available since PHP 7.1.
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewConstVisibilitySniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_CONST);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
+
+ // Is the previous token a visibility indicator ?
+ if ($prevToken === false || isset(Tokens::$scopeModifiers[$tokens[$prevToken]['code']]) === false) {
+ return;
+ }
+
+ // Is this a class constant ?
+ if ($this->isClassConstant($phpcsFile, $stackPtr) === false) {
+ // This may be a constant declaration in the global namespace with visibility,
+ // but that would throw a parse error, i.e. not our concern.
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Visibility indicators for class constants are not supported in PHP 7.0 or earlier. Found "%s const"',
+ $stackPtr,
+ 'Found',
+ array($tokens[$prevToken]['content'])
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewLateStaticBindingSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewLateStaticBindingSniff.php
new file mode 100644
index 0000000..affcb23
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Classes/NewLateStaticBindingSniff.php
@@ -0,0 +1,79 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Classes;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Classes\NewLateStaticBindingSniff.
+ *
+ * PHP version 5.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewLateStaticBindingSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STATIC);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+ if ($nextNonEmpty === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ if ($tokens[$nextNonEmpty]['code'] !== T_DOUBLE_COLON) {
+ return;
+ }
+
+ $inClass = $this->inClassScope($phpcsFile, $stackPtr, false);
+
+ if ($inClass === true && $this->supportsBelow('5.2') === true) {
+ $phpcsFile->addError(
+ 'Late static binding is not supported in PHP 5.2 or earlier.',
+ $stackPtr,
+ 'Found'
+ );
+ }
+
+ if ($inClass === false) {
+ $phpcsFile->addError(
+ 'Late static binding is not supported outside of class scope.',
+ $stackPtr,
+ 'OutsideClassScope'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/NewConstantsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/NewConstantsSniff.php
new file mode 100644
index 0000000..faa5e26
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/NewConstantsSniff.php
@@ -0,0 +1,3511 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Constants;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Constants\NewConstantsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewConstantsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new PHP Constants, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the constant appears.
+ *
+ * Note: PHP Constants are case-sensitive!
+ *
+ * @var array(string => array(string => bool|string|null))
+ */
+ protected $newConstants = array(
+ 'E_STRICT' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ // Curl:
+ 'CURLOPT_FTP_USE_EPRT' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_NOSIGNAL' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_UNRESTRICTED_AUTH' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_BUFFERSIZE' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_HTTPAUTH' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_PROXYPORT' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_PROXYTYPE' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_SSLCERTTYPE' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'CURLOPT_HTTP200ALIASES' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ // OpenSSL:
+ 'OPENSSL_ALGO_MD2' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'OPENSSL_ALGO_MD4' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'OPENSSL_ALGO_MD5' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'OPENSSL_ALGO_SHA1' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'OPENSSL_ALGO_DSS1' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ // Tokenizer:
+ 'T_ABSTRACT' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'T_CATCH' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+
+ 'SORT_LOCALE_STRING' => array(
+ '5.0.1' => false,
+ '5.0.2' => true,
+ ),
+ 'PHP_EOL' => array(
+ '5.0.1' => false,
+ '5.0.2' => true,
+ ),
+
+ 'PHP_INT_MAX' => array(
+ '5.0.4' => false,
+ '5.0.5' => true,
+ ),
+ 'PHP_INT_SIZE' => array(
+ '5.0.4' => false,
+ '5.0.5' => true,
+ ),
+
+ '__COMPILER_HALT_OFFSET__' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'GLOB_ERR' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ // Curl:
+ 'CURLOPT_AUTOREFERER' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'CURLOPT_BINARYTRANSFER' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'CURLOPT_COOKIESESSION' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'CURLOPT_FTPSSLAUTH' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'CURLOPT_PROXYAUTH' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'CURLOPT_TIMECONDITION' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ // POSIX:
+ 'POSIX_F_OK' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_R_OK' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_W_OK' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_X_OK' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_S_IFBLK' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_S_IFCHR' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_S_IFIFO' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_S_IFREG' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'POSIX_S_IFSOCK' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ // Streams:
+ 'STREAM_IPPROTO_ICMP' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_IPPROTO_IP' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_IPPROTO_RAW' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_IPPROTO_TCP' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_IPPROTO_UDP' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_PF_INET' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_PF_INET6' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_PF_UNIX' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_SOCK_DGRAM' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_SOCK_RAW' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_SOCK_RDM' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_SOCK_SEQPACKET' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'STREAM_SOCK_STREAM' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ // Tokenizer:
+ 'T_HALT_COMPILER' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+
+ // Date/Time:
+ 'DATE_ATOM' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_COOKIE' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_ISO8601' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RFC822' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RFC850' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RFC1036' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RFC1123' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RFC2822' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RFC3339' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_RSS' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+ 'DATE_W3C' => array(
+ '5.1.0' => false,
+ '5.1.1' => true,
+ ),
+
+ // Date/Time:
+ 'SUNFUNCS_RET_TIMESTAMP' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'SUNFUNCS_RET_STRING' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'SUNFUNCS_RET_DOUBLE' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ // XSL:
+ 'LIBXSLT_VERSION' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'LIBXSLT_DOTTED_VERSION' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'LIBEXSLT_VERSION' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'LIBEXSLT_DOTTED_VERSION' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ // URL:
+ 'PHP_URL_SCHEME' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_HOST' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_PORT' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_USER' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_PASS' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_PATH' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_QUERY' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_URL_FRAGMENT' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_QUERY_RFC1738' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'PHP_QUERY_RFC3986' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+
+ // Curl:
+ 'CURLINFO_HEADER_OUT' => array(
+ '5.1.2' => false,
+ '5.1.3' => true,
+ ),
+
+ // Core:
+ 'E_RECOVERABLE_ERROR' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // Math:
+ 'M_EULER' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'M_LNPI' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'M_SQRT3' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'M_SQRTPI' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'PATHINFO_FILENAME' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'UPLOAD_ERR_EXTENSION' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // Curl:
+ 'CURLE_FILESIZE_EXCEEDED' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLE_FTP_SSL_FAILED' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLE_LDAP_INVALID_URL' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPAUTH_DEFAULT' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPAUTH_SSL' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPAUTH_TLS' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPSSL_ALL' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPSSL_CONTROL' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPSSL_NONE' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLFTPSSL_TRY' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'CURLOPT_FTP_SSL' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // Ming:
+ 'SWFTEXTFIELD_USEFONT' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWFTEXTFIELD_AUTOSIZE' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_NOT_COMPRESSED' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_ADPCM_COMPRESSED' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_MP3_COMPRESSED' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_NOT_COMPRESSED_LE' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_NELLY_COMPRESSED' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_5KHZ' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_11KHZ' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_22KHZ' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_44KHZ' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_8BITS' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_16BITS' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_MONO' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SWF_SOUND_STEREO' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // OpenSSL:
+ 'OPENSSL_KEYTYPE_EC' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'OPENSSL_VERSION_NUMBER' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'OPENSSL_VERSION_TEXT' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // PCRE:
+ 'PREG_BACKTRACK_LIMIT_ERROR' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'PREG_BAD_UTF8_ERROR' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'PREG_INTERNAL_ERROR' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'PREG_NO_ERROR' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'PREG_RECURSION_LIMIT_ERROR' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // Snmp:
+ 'SNMP_OID_OUTPUT_FULL' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'SNMP_OID_OUTPUT_NUMERIC' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ // Semaphore:
+ 'MSG_EAGAIN' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'MSG_ENOMSG' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+
+ // Curl:
+ 'CURLOPT_TCP_NODELAY' => array(
+ '5.2.0' => false,
+ '5.2.1' => true,
+ ),
+
+ // Stream:
+ 'STREAM_SHUT_RD' => array(
+ '5.2.0' => false,
+ '5.2.1' => true,
+ ),
+ 'STREAM_SHUT_WR' => array(
+ '5.2.0' => false,
+ '5.2.1' => true,
+ ),
+ 'STREAM_SHUT_RDWR' => array(
+ '5.2.0' => false,
+ '5.2.1' => true,
+ ),
+
+ 'GMP_VERSION' => array(
+ '5.2.1' => false,
+ '5.2.2' => true,
+ ),
+
+ // Curl:
+ 'CURLOPT_TIMEOUT_MS' => array(
+ '5.2.2' => false,
+ '5.2.3' => true,
+ ),
+ 'CURLOPT_CONNECTTIMEOUT_MS' => array(
+ '5.2.2' => false,
+ '5.2.3' => true,
+ ),
+
+ // Curl:
+ 'CURLOPT_PRIVATE' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ 'CURLINFO_PRIVATE' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ // GD:
+ 'GD_VERSION' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ 'GD_MAJOR_VERSION' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ 'GD_MINOR_VERSION' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ 'GD_RELEASE_VERSION' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ 'GD_EXTRA_VERSION' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ // PCRE:
+ 'PCRE_VERSION' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+
+ 'PHP_MAJOR_VERSION' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'PHP_MINOR_VERSION' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'PHP_RELEASE_VERSION' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'PHP_VERSION_ID' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'PHP_EXTRA_VERSION' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'PHP_ZTS' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'PHP_DEBUG' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'FILE_BINARY' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ 'FILE_TEXT' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+ // Sockets:
+ 'TCP_NODELAY' => array(
+ '5.2.6' => false,
+ '5.2.7' => true,
+ ),
+
+ // Curl:
+ 'CURLOPT_PROTOCOLS' => array(
+ '5.2.9' => false,
+ '5.2.10' => true,
+ ),
+ 'CURLOPT_REDIR_PROTOCOLS' => array(
+ '5.2.9' => false,
+ '5.2.10' => true,
+ ),
+ 'CURLPROXY_SOCKS4' => array(
+ '5.2.9' => false,
+ '5.2.10' => true,
+ ),
+
+ // Libxml:
+ 'LIBXML_PARSEHUGE' => array(
+ '5.2.11' => false,
+ '5.2.12' => true,
+ ),
+
+ // Core:
+ 'ENT_IGNORE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'E_DEPRECATED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'E_USER_DEPRECATED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'INI_SCANNER_NORMAL' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'INI_SCANNER_RAW' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_MAXPATHLEN' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_NT_DOMAIN_CONTROLLER' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_NT_SERVER' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_NT_WORKSTATION' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_BUILD' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_MAJOR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_MINOR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_PLATFORM' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_PRODUCTTYPE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_SP_MAJOR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_SP_MINOR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_WINDOWS_VERSION_SUITEMASK' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // Curl:
+ 'CURLINFO_CERTINFO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CURLOPT_PROGRESSFUNCTION' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CURLE_SSH' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // GD:
+ 'IMG_FILTER_PIXELATE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'IMAGETYPE_ICO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // Fileinfo:
+ 'FILEINFO_MIME_TYPE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FILEINFO_MIME_ENCODING' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // JSON:
+ 'JSON_ERROR_CTRL_CHAR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_ERROR_DEPTH' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_ERROR_NONE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_ERROR_STATE_MISMATCH' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_ERROR_SYNTAX' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_FORCE_OBJECT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_HEX_TAG' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_HEX_AMP' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_HEX_APOS' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'JSON_HEX_QUOT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // LDAP:
+ 'LDAP_OPT_NETWORK_TIMEOUT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // Libxml:
+ 'LIBXML_LOADED_VERSION' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // Math:
+ 'PHP_ROUND_HALF_UP' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_ROUND_HALF_DOWN' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_ROUND_HALF_EVEN' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'PHP_ROUND_HALF_ODD' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // Mysqli
+ 'MYSQLI_OPT_INT_AND_FLOAT_NATIVE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'MYSQLI_OPT_NET_CMD_BUFFER_SIZE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'MYSQLI_OPT_NET_READ_BUFFER_SIZE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'MYSQLI_OPT_SSL_VERIFY_SERVER_CERT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // OCI8:
+ 'OCI_CRED_EXT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // PCRE:
+ 'PREG_BAD_UTF8_OFFSET_ERROR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // PCNTL:
+ 'BUS_ADRALN' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'BUS_ADRERR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'BUS_OBJERR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CLD_CONTIUNED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CLD_DUMPED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CLD_EXITED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CLD_KILLED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CLD_STOPPED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'CLD_TRAPPED' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_FLTDIV' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_FLTINV' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_FLTOVF' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_FLTRES' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_FLTSUB' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_FLTUND' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_INTDIV' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'FPE_INTOVF' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_BADSTK' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_COPROC' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_ILLADR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_ILLOPC' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_ILLOPN' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_ILLTRP' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_PRVOPC' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ILL_PRVREG' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'POLL_ERR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'POLL_HUP' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'POLL_IN' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'POLL_MSG' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'POLL_OUT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'POLL_PRI' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SEGV_ACCERR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SEGV_MAPERR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_ASYNCIO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_KERNEL' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_MSGGQ' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_NOINFO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_QUEUE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_SIGIO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_TIMER' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_TKILL' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SI_USER' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SIG_BLOCK' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SIG_SETMASK' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'SIG_UNBLOCK' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'TRAP_BRKPT' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'TRAP_TRACE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ // Tokenizer:
+ 'T_DIR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'T_GOTO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'T_NAMESPACE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'T_NS_C' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'T_NS_SEPARATOR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'T_USE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+
+ // OCI8:
+ 'OCI_NO_AUTO_COMMIT' => array(
+ '5.3.1' => false,
+ '5.3.2' => true,
+ ),
+ // OpenSSL:
+ 'OPENSSL_TLSEXT_SERVER_NAME' => array(
+ '5.3.1' => false,
+ '5.3.2' => true,
+ ),
+
+ // JSON:
+ 'JSON_ERROR_UTF8' => array(
+ '5.3.2' => false,
+ '5.3.3' => true,
+ ),
+ 'JSON_NUMERIC_CHECK' => array(
+ '5.3.2' => false,
+ '5.3.3' => true,
+ ),
+
+ 'DEBUG_BACKTRACE_IGNORE_ARGS' => array(
+ '5.3.5' => false,
+ '5.3.6' => true,
+ ),
+
+ 'CURLINFO_REDIRECT_URL' => array(
+ '5.3.6' => false,
+ '5.3.7' => true,
+ ),
+ 'PHP_MANDIR' => array(
+ '5.3.6' => false,
+ '5.3.7' => true,
+ ),
+
+ 'PHP_BINARY' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SORT_NATURAL' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SORT_FLAG_CASE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ENT_HTML401' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ENT_XML1' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ENT_XHTML' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ENT_HTML5' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ENT_SUBSTITUTE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ENT_DISALLOWED' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IPPROTO_IP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IPPROTO_IPV6' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IPV6_MULTICAST_HOPS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IPV6_MULTICAST_IF' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IPV6_MULTICAST_LOOP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IP_MULTICAST_IF' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IP_MULTICAST_LOOP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IP_MULTICAST_TTL' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'MCAST_JOIN_GROUP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'MCAST_LEAVE_GROUP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'MCAST_BLOCK_SOURCE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'MCAST_UNBLOCK_SOURCE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'MCAST_JOIN_SOURCE_GROUP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'MCAST_LEAVE_SOURCE_GROUP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Curl:
+ 'CURLOPT_MAX_RECV_SPEED_LARGE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'CURLOPT_MAX_SEND_SPEED_LARGE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Directories:
+ 'SCANDIR_SORT_ASCENDING' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SCANDIR_SORT_DESCENDING' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SCANDIR_SORT_NONE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // LibXML:
+ 'LIBXML_HTML_NODEFDTD' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'LIBXML_HTML_NOIMPLIED' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'LIBXML_PEDANTIC' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // OpenSSL:
+ 'OPENSSL_CIPHER_AES_128_CBC' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'OPENSSL_CIPHER_AES_192_CBC' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'OPENSSL_CIPHER_AES_256_CBC' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'OPENSSL_RAW_DATA' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'OPENSSL_ZERO_PADDING' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Output buffering:
+ 'PHP_OUTPUT_HANDLER_CLEAN' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_CLEANABLE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_DISABLED' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_FINAL' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_FLUSH' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_FLUSHABLE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_REMOVABLE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_STARTED' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_STDFLAGS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_OUTPUT_HANDLER_WRITE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Sessions:
+ 'PHP_SESSION_ACTIVE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_SESSION_DISABLED' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'PHP_SESSION_NONE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Streams:
+ 'STREAM_META_ACCESS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'STREAM_META_GROUP' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'STREAM_META_GROUP_NAME' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'STREAM_META_OWNER' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'STREAM_META_OWNER_NAME' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'STREAM_META_TOUCH' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Intl:
+ 'U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_CHECK_BIDI' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_CHECK_CONTEXTJ' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_NONTRANSITIONAL_TO_ASCII' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_NONTRANSITIONAL_TO_UNICODE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'INTL_IDNA_VARIANT_2003' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'INTL_IDNA_VARIANT_UTS46' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_EMPTY_LABEL' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_LABEL_TOO_LONG' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_DOMAIN_NAME_TOO_LONG' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_LEADING_HYPHEN' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_TRAILING_HYPHEN' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_HYPHEN_3_4' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_LEADING_COMBINING_MARK' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_DISALLOWED' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_PUNYCODE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_LABEL_HAS_DOT' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_INVALID_ACE_LABEL' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_BIDI' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'IDNA_ERROR_CONTEXTJ' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Json:
+ 'JSON_PRETTY_PRINT' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'JSON_UNESCAPED_SLASHES' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'JSON_UNESCAPED_UNICODE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'JSON_BIGINT_AS_STRING' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'JSON_OBJECT_AS_ARRAY' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Snmp:
+ 'SNMP_OID_OUTPUT_SUFFIX' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SNMP_OID_OUTPUT_MODULE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SNMP_OID_OUTPUT_UCD' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SNMP_OID_OUTPUT_NONE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ // Tokenizer:
+ 'T_INSTEADOF' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'T_TRAIT' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'T_TRAIT_C' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ // Curl:
+ 'CURLINFO_PRIMARY_IP' => array(
+ '5.4.6' => false,
+ '5.4.7' => true,
+ ),
+ 'CURLINFO_PRIMARY_PORT' => array(
+ '5.4.6' => false,
+ '5.4.7' => true,
+ ),
+ 'CURLINFO_LOCAL_IP' => array(
+ '5.4.6' => false,
+ '5.4.7' => true,
+ ),
+ 'CURLINFO_LOCAL_PORT' => array(
+ '5.4.6' => false,
+ '5.4.7' => true,
+ ),
+
+ // OpenSSL:
+ 'OPENSSL_ALGO_RMD160' => array(
+ '5.4.7' => false,
+ '5.4.8' => true,
+ ),
+ 'OPENSSL_ALGO_SHA224' => array(
+ '5.4.7' => false,
+ '5.4.8' => true,
+ ),
+ 'OPENSSL_ALGO_SHA256' => array(
+ '5.4.7' => false,
+ '5.4.8' => true,
+ ),
+ 'OPENSSL_ALGO_SHA384' => array(
+ '5.4.7' => false,
+ '5.4.8' => true,
+ ),
+ 'OPENSSL_ALGO_SHA512' => array(
+ '5.4.7' => false,
+ '5.4.8' => true,
+ ),
+
+ // Filter:
+ 'FILTER_VALIDATE_MAC' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // GD
+ 'IMG_AFFINE_TRANSLATE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_AFFINE_SCALE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_AFFINE_ROTATE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_AFFINE_SHEAR_HORIZONTAL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_AFFINE_SHEAR_VERTICAL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_CROP_DEFAULT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_CROP_TRANSPARENT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_CROP_BLACK' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_CROP_WHITE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_CROP_SIDES' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_FLIP_BOTH' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_FLIP_HORIZONTAL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_FLIP_VERTICAL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BELL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BESSEL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BILINEAR_FIXED' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BICUBIC' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BICUBIC_FIXED' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BLACKMAN' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BOX' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_BSPLINE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_CATMULLROM' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_GAUSSIAN' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_GENERALIZED_CUBIC' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_HERMITE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_HAMMING' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_HANNING' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_MITCHELL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_POWER' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_QUADRATIC' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_SINC' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_NEAREST_NEIGHBOUR' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_WEIGHTED4' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'IMG_TRIANGLE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // JSON:
+ 'JSON_ERROR_RECURSION' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'JSON_ERROR_INF_OR_NAN' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'JSON_ERROR_UNSUPPORTED_TYPE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'JSON_PARTIAL_OUTPUT_ON_ERROR' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // MySQLi
+ 'MYSQLI_SERVER_PUBLIC_KEY' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // Curl:
+ 'CURLOPT_SHARE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLOPT_SSL_OPTIONS' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLSSLOPT_ALLOW_BEAST' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLOPT_USERNAME' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_RESPONSE_CODE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_HTTP_CONNECTCODE' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_HTTPAUTH_AVAIL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_PROXYAUTH_AVAIL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_OS_ERRNO' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_NUM_CONNECTS' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_SSL_ENGINES' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_COOKIELIST' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_FTP_ENTRY_PATH' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_APPCONNECT_TIME' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_CONDITION_UNMET' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_RTSP_CLIENT_CSEQ' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_RTSP_CSEQ_RECV' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_RTSP_SERVER_CSEQ' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLINFO_RTSP_SESSION_ID' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLMOPT_PIPELINING' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLMOPT_MAXCONNECTS' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLPAUSE_ALL' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLPAUSE_CONT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLPAUSE_RECV' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLPAUSE_RECV_CONT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLPAUSE_SEND' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'CURLPAUSE_SEND_CONT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // Soap:
+ 'SOAP_SSL_METHOD_TLS' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'SOAP_SSL_METHOD_SSLv2' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'SOAP_SSL_METHOD_SSLv3' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'SOAP_SSL_METHOD_SSLv23' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // Tokenizer:
+ 'T_FINALLY' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'T_YIELD' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ // Core/Password Hashing:
+ 'PASSWORD_BCRYPT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'PASSWORD_DEFAULT' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'PASSWORD_BCRYPT_DEFAULT_COST' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+
+
+ // Libxml:
+ 'LIBXML_SCHEMA_CREATE' => array(
+ '5.5.1' => false,
+ '5.5.2' => true,
+ ),
+
+ // Curl:
+ 'CURL_SSLVERSION_TLSv1_0' => array(
+ '5.5.18' => false,
+ '5.5.19' => true,
+ ),
+ 'CURL_SSLVERSION_TLSv1_1' => array(
+ '5.5.18' => false,
+ '5.5.19' => true,
+ ),
+ 'CURL_SSLVERSION_TLSv1_2' => array(
+ '5.5.18' => false,
+ '5.5.19' => true,
+ ),
+
+ 'CURLPROXY_SOCKS4A' => array(
+ '5.5.22' => false,
+ '5.5.23' => true,
+ ),
+ 'CURLPROXY_SOCKS5_HOSTNAME' => array(
+ '5.5.22' => false,
+ '5.5.23' => true,
+ ),
+
+ 'CURL_VERSION_HTTP2' => array(
+ '5.5.23' => false,
+ '5.5.24' => true,
+ ),
+
+ 'ARRAY_FILTER_USE_KEY' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'ARRAY_FILTER_USE_BOTH' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ // LDAP:
+ 'LDAP_ESCAPE_DN' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'LDAP_ESCAPE_FILTER' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ // OpenSSL:
+ 'OPENSSL_DEFAULT_STREAM_CIPHERS' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_ANY_CLIENT' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_ANY_SERVER' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_TLSv1_0_SERVER' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_TLSv1_1_SERVER' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'STREAM_CRYPTO_METHOD_TLSv1_2_SERVER' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ // PostgreSQL:
+ 'PGSQL_CONNECT_ASYNC' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_CONNECTION_AUTH_OK' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_CONNECTION_AWAITING_RESPONSE' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_CONNECTION_MADE' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_CONNECTION_SETENV' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_CONNECTION_SSL_STARTUP' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_CONNECTION_STARTED' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_DML_ESCAPE' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_POLLING_ACTIVE' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_POLLING_FAILED' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_POLLING_OK' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_POLLING_READING' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'PGSQL_POLLING_WRITING' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ // Tokenizer:
+ 'T_ELLIPSIS' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'T_POW' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'T_POW_EQUAL' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+
+ 'INI_SCANNER_TYPED' => array(
+ '5.6.0' => false,
+ '5.6.1' => true,
+ ),
+
+ 'JSON_PRESERVE_ZERO_FRACTION' => array(
+ '5.6.5' => false,
+ '5.6.6' => true,
+ ),
+
+ 'MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' => array(
+ '5.6.15' => false,
+ '5.6.16' => true,
+ ),
+
+ // GD:
+ // Also introduced in 7.0.10.
+ 'IMG_WEBP' => array(
+ '5.6.24' => false,
+ '5.6.25' => true,
+ ),
+
+
+ 'TOKEN_PARSE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'FILTER_VALIDATE_DOMAIN' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'PHP_INT_MIN' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ // Curl:
+ 'CURLPIPE_NOTHING' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'CURLPIPE_HTTP1' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'CURLPIPE_MULTIPLEX' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ // JSON:
+ 'JSON_ERROR_INVALID_PROPERTY_NAME' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'JSON_ERROR_UTF16' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ // LibXML:
+ 'LIBXML_BIGLINES' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ // PCRE:
+ 'PREG_JIT_STACKLIMIT_ERROR' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ // POSIX:
+ 'POSIX_RLIMIT_AS' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_CORE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_CPU' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_DATA' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_FSIZE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_LOCKS' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_MEMLOCK' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_MSGQUEUE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_NICE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_NOFILE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_NPROC' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_RSS' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_RTPRIO' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_RTTIME' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_SIGPENDING' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_STACK' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'POSIX_RLIMIT_INFINITY' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ // Tokenizer:
+ 'T_COALESCE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'T_SPACESHIP' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'T_YIELD_FROM' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ // Zlib:
+ // The first three are in the PHP 5.4 changelog, but the Extension constant page says 7.0.
+ 'ZLIB_ENCODING_RAW' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_ENCODING_DEFLATE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_ENCODING_GZIP' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_FILTERED' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_HUFFMAN_ONLY' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_FIXED' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_RLE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_DEFAULT_STRATEGY' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_BLOCK' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_FINISH' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_FULL_FLUSH' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_NO_FLUSH' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_PARTIAL_FLUSH' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'ZLIB_SYNC_FLUSH' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ 'CURL_HTTP_VERSION_2' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_HTTP_VERSION_2TLS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_REDIR_POST_301' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_REDIR_POST_302' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_REDIR_POST_303' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_REDIR_POST_ALL' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_VERSION_KERBEROS5' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_VERSION_PSL' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURL_VERSION_UNIX_SOCKETS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLAUTH_NEGOTIATE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLAUTH_NTLM_WB' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLFTP_CREATE_DIR' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLFTP_CREATE_DIR_NONE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLFTP_CREATE_DIR_RETRY' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLHEADER_SEPARATE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLHEADER_UNIFIED' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLMOPT_MAX_HOST_CONNECTIONS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLMOPT_MAX_PIPELINE_LENGTH' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLMOPT_MAX_TOTAL_CONNECTIONS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_CONNECT_TO' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_DEFAULT_PROTOCOL' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_DNS_INTERFACE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_DNS_LOCAL_IP4' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_DNS_LOCAL_IP6' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_EXPECT_100_TIMEOUT_MS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_HEADEROPT' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_LOGIN_OPTIONS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_PATH_AS_IS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_PINNEDPUBLICKEY' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_PIPEWAIT' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_PROXY_SERVICE_NAME' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_PROXYHEADER' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_SASL_IR' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_SERVICE_NAME' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_SSL_ENABLE_ALPN' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_SSL_ENABLE_NPN' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_SSL_FALSESTART' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_SSL_VERIFYSTATUS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_STREAM_WEIGHT' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_TCP_FASTOPEN' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_TFTP_NO_OPTIONS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_UNIX_SOCKET_PATH' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLOPT_XOAUTH2_BEARER' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLPROTO_SMB' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLPROTO_SMBS' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLPROXY_HTTP_1_0' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLSSH_AUTH_AGENT' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+ 'CURLSSLOPT_NO_REVOKE' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+
+ 'PHP_FD_SETSIZE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // Curl:
+ 'CURLMOPT_PUSHFUNCTION' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'CURL_PUSH_OK' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'CURL_PUSH_DENY' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // Filter:
+ 'FILTER_FLAG_EMAIL_UNICODE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // GD:
+ 'IMAGETYPE_WEBP' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // Json:
+ 'JSON_UNESCAPED_LINE_TERMINATORS' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // LDAP:
+ 'LDAP_OPT_X_SASL_NOCANON' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_SASL_USERNAME' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CACERTDIR' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CACERTFILE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CERTFILE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CIPHER_SUITE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_KEYFILE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_RANDOM_FILE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CRLCHECK' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CRL_NONE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CRL_PEER' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CRL_ALL' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_DHFILE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_CRLFILE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PROTOCOL_MIN' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PROTOCOL_SSL2' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PROTOCOL_SSL3' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_0' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_1' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PROTOCOL_TLS1_2' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_TLS_PACKAGE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_KEEPALIVE_IDLE' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_KEEPALIVE_PROBES' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'LDAP_OPT_X_KEEPALIVE_INTERVAL' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // PostgreSQL:
+ 'PGSQL_NOTICE_LAST' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'PGSQL_NOTICE_ALL' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'PGSQL_NOTICE_CLEAR' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ // SPL:
+ 'MT_RAND_PHP' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+
+ // SQLite3:
+ 'SQLITE3_DETERMINISTIC' => array(
+ '7.1.3' => false,
+ '7.1.4' => true,
+ ),
+
+ // Core:
+ 'PHP_OS_FAMILY' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PHP_FLOAT_DIG' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PHP_FLOAT_EPSILON' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PHP_FLOAT_MIN' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PHP_FLOAT_MAX' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // Core/Password Hashing:
+ 'PASSWORD_ARGON2I' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PASSWORD_ARGON2_DEFAULT_MEMORY_COST' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PASSWORD_ARGON2_DEFAULT_TIME_COST' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'PASSWORD_ARGON2_DEFAULT_THREADS' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // Fileinfo:
+ 'FILEINFO_EXTENSION' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // GD:
+ 'IMG_EFFECT_MULTIPLY' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'IMG_BMP' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // JSON:
+ 'JSON_INVALID_UTF8_IGNORE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'JSON_INVALID_UTF8_SUBSTITUTE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // LDAP:
+ 'LDAP_EXOP_START_TLS' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'LDAP_EXOP_MODIFY_PASSWD' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'LDAP_EXOP_REFRESH' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'LDAP_EXOP_WHO_AM_I' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'LDAP_EXOP_TURN' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // PCRE:
+ 'PREG_UNMATCHED_AS_NULL' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ // Sodium:
+ 'SODIUM_LIBRARY_VERSION' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_LIBRARY_MAJOR_VERSION' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_LIBRARY_MINOR_VERSION' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_AES256GCM_NSECBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_AES256GCM_ABYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NSECBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_ABYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NSECBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_ABYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AUTH_BYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_AUTH_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_SEALBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_SECRETKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_PUBLICKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_KEYPAIRBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_MACBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_NONCEBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_BOX_SEEDBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KDF_BYTES_MIN' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KDF_BYTES_MAX' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KDF_CONTEXTBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KDF_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KX_SEEDBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KX_SESSIONKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KX_PUBLICKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KX_SECRETKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_KX_KEYPAIRBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_GENERICHASH_BYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_GENERICHASH_BYTES_MIN' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_GENERICHASH_BYTES_MAX' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_GENERICHASH_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MIN' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_GENERICHASH_KEYBYTES_MAX' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_ALG_DEFAULT' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SALTBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_STRPREFIX' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_SENSITIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_SENSITIVE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SCALARMULT_BYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SCALARMULT_SCALARBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SHORTHASH_BYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SHORTHASH_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SECRETBOX_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SECRETBOX_MACBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SECRETBOX_NONCEBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SIGN_BYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SIGN_SEEDBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SIGN_SECRETKEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_SIGN_KEYPAIRBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_STREAM_NONCEBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'SODIUM_CRYPTO_STREAM_KEYBYTES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ 'CURLAUTH_BEARER' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLAUTH_GSSAPI' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLE_WEIRD_SERVER_REPLY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_APPCONNECT_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_CONNECT_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_CONTENT_LENGTH_DOWNLOAD_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_CONTENT_LENGTH_UPLOAD_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_FILETIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_HTTP_VERSION' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_NAMELOOKUP_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_PRETRANSFER_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_PROTOCOL' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_PROXY_SSL_VERIFYRESULT' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_REDIRECT_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_SCHEME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_SIZE_DOWNLOAD_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_SIZE_UPLOAD_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_SPEED_DOWNLOAD_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_SPEED_UPLOAD_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_STARTTRANSFER_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLINFO_TOTAL_TIME_T' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_LOCK_DATA_CONNECT' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_LOCK_DATA_PSL' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_MAX_READ_SIZE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_ABSTRACT_UNIX_SOCKET' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_DISALLOW_USERNAME_IN_URL' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_DNS_SHUFFLE_ADDRESSES' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_HAPROXYPROTOCOL' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_KEEP_SENDING_ON_ERROR' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PRE_PROXY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_CAINFO' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_CAPATH' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_CRLFILE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_KEYPASSWD' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_PINNEDPUBLICKEY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSLCERT' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSLCERTTYPE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSL_CIPHER_LIST' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSLKEY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSLKEYTYPE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSL_OPTIONS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSL_VERIFYHOST' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSL_VERIFYPEER' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_SSLVERSION' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_TLS13_CIPHERS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_TLSAUTH_PASSWORD' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_TLSAUTH_TYPE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_PROXY_TLSAUTH_USERNAME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_REQUEST_TARGET' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_SOCKS5_AUTH' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_SSH_COMPRESSION' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_SUPPRESS_CONNECT_HEADERS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_TIMEVALUE_LARGE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLOPT_TLS13_CIPHERS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLPROXY_HTTPS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURLSSH_AUTH_GSSAPI' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_MAX_DEFAULT' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_MAX_NONE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_MAX_TLSv1_0' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_MAX_TLSv1_1' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_MAX_TLSv1_2' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_MAX_TLSv1_3' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_SSLVERSION_TLSv1_3' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_ASYNCHDNS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_BROTLI' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_CONV' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_DEBUG' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_GSSAPI' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_GSSNEGOTIATE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_HTTPS_PROXY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_IDN' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_LARGEFILE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_MULTI_SSL' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_NTLM' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_NTLM_WB' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_SPNEGO' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_SSPI' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'CURL_VERSION_TLSAUTH_SRP' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'FILTER_SANITIZE_ADD_SLASHES' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'JSON_THROW_ON_ERROR' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_MANAGEDSAIT' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_PROXY_AUTHZ' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_SUBENTRIES' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_VALUESRETURNFILTER' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_ASSERT' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_PRE_READ' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_POST_READ' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_SORTREQUEST' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_SORTRESPONSE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_PAGEDRESULTS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_AUTHZID_REQUEST' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_AUTHZID_RESPONSE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_SYNC' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_SYNC_STATE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_SYNC_DONE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_DONTUSECOPY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_PASSWORDPOLICYREQUEST' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_PASSWORDPOLICYRESPONSE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_X_INCREMENTAL_VALUES' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_X_DOMAIN_SCOPE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_X_PERMISSIVE_MODIFY' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_X_SEARCH_OPTIONS' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_X_TREE_DELETE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_X_EXTENDED_DN' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_VLVREQUEST' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'LDAP_CONTROL_VLVRESPONSE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'MB_CASE_FOLD' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'MB_CASE_UPPER_SIMPLE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'MB_CASE_LOWER_SIMPLE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'MB_CASE_TITLE_SIMPLE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'MB_CASE_FOLD_SIMPLE' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PGSQL_DIAG_SCHEMA_NAME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PGSQL_DIAG_TABLE_NAME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PGSQL_DIAG_COLUMN_NAME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PGSQL_DIAG_DATATYPE_NAME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PGSQL_DIAG_CONSTRAINT_NAME' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PGSQL_DIAG_SEVERITY_NONLOCALIZED' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'PASSWORD_ARGON2ID' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'STREAM_CRYPTO_PROTO_SSLv3' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'STREAM_CRYPTO_PROTO_TLSv1_0' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'STREAM_CRYPTO_PROTO_TLSv1_1' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'STREAM_CRYPTO_PROTO_TLSv1_2' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $constantName = $tokens[$stackPtr]['content'];
+
+ if (isset($this->newConstants[$constantName]) === false) {
+ return;
+ }
+
+ if ($this->isUseOfGlobalConstant($phpcsFile, $stackPtr) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $constantName,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newConstants[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The constant "%s" is not present in PHP version %s or earlier';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/NewMagicClassConstantSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/NewMagicClassConstantSniff.php
new file mode 100644
index 0000000..2f46fda
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/NewMagicClassConstantSniff.php
@@ -0,0 +1,75 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Constants;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Constants\NewMagicClassConstantSniff.
+ *
+ * The special ClassName::class constant is available as of PHP 5.5.0, and allows for
+ * fully qualified class name resolution at compile.
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewMagicClassConstantSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (strtolower($tokens[$stackPtr]['content']) !== 'class') {
+ return;
+ }
+
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
+ if ($prevToken === false || $tokens[$prevToken]['code'] !== T_DOUBLE_COLON) {
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'The magic class constant ClassName::class was not available in PHP 5.4 or earlier',
+ $stackPtr,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/RemovedConstantsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/RemovedConstantsSniff.php
new file mode 100644
index 0000000..49a8d87
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Constants/RemovedConstantsSniff.php
@@ -0,0 +1,360 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Constants;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Constants\RemovedConstantsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedConstantsSniff extends AbstractRemovedFeatureSniff
+{
+
+ /**
+ * A list of removed PHP Constants.
+ *
+ * The array lists : version number with false (deprecated) or true (removed).
+ * If's sufficient to list the first version where the constant was deprecated/removed.
+ *
+ * Note: PHP Constants are case-sensitive!
+ *
+ * @var array(string => array(string => bool|string|null))
+ */
+ protected $removedConstants = array(
+ // Disabled since PHP 5.3.0 due to thread safety issues.
+ 'FILEINFO_COMPRESS' => array(
+ '5.3' => true,
+ ),
+
+ 'CURLOPT_CLOSEPOLICY' => array(
+ '5.6' => true,
+ ),
+ 'CURLCLOSEPOLICY_LEAST_RECENTLY_USED' => array(
+ '5.6' => true,
+ ),
+ 'CURLCLOSEPOLICY_LEAST_TRAFFIC' => array(
+ '5.6' => true,
+ ),
+ 'CURLCLOSEPOLICY_SLOWEST' => array(
+ '5.6' => true,
+ ),
+ 'CURLCLOSEPOLICY_CALLBACK' => array(
+ '5.6' => true,
+ ),
+ 'CURLCLOSEPOLICY_OLDEST' => array(
+ '5.6' => true,
+ ),
+
+ 'PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT' => array(
+ '7.0' => true,
+ ),
+
+ 'INTL_IDNA_VARIANT_2003' => array(
+ '7.2' => false,
+ ),
+
+ 'MCRYPT_MODE_ECB' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_MODE_CBC' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_MODE_CFB' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_MODE_OFB' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_MODE_NOFB' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_MODE_STREAM' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_ENCRYPT' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_DECRYPT' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_DEV_RANDOM' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_DEV_URANDOM' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RAND' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_3DES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_ARCFOUR_IV' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_ARCFOUR' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_BLOWFISH' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_CAST_128' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_CAST_256' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_CRYPT' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_DES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_DES_COMPAT' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_ENIGMA' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_GOST' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_IDEA' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_LOKI97' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_MARS' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_PANAMA' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RIJNDAEL_128' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RIJNDAEL_192' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RIJNDAEL_256' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RC2' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RC4' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RC6' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RC6_128' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RC6_192' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_RC6_256' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SAFER64' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SAFER128' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SAFERPLUS' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SERPENT' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SERPENT_128' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SERPENT_192' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SERPENT_256' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_SKIPJACK' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_TEAN' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_THREEWAY' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_TRIPLEDES' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_TWOFISH' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_TWOFISH128' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_TWOFISH192' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_TWOFISH256' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_WAKE' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'MCRYPT_XTEA' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ 'PHPDBG_FILE' => array(
+ '7.3' => true,
+ ),
+ 'PHPDBG_METHOD' => array(
+ '7.3' => true,
+ ),
+ 'PHPDBG_LINENO' => array(
+ '7.3' => true,
+ ),
+ 'PHPDBG_FUNC' => array(
+ '7.3' => true,
+ ),
+ 'FILTER_FLAG_SCHEME_REQUIRED' => array(
+ '7.3' => false,
+ ),
+ 'FILTER_FLAG_HOST_REQUIRED' => array(
+ '7.3' => false,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $constantName = $tokens[$stackPtr]['content'];
+
+ if (isset($this->removedConstants[$constantName]) === false) {
+ return;
+ }
+
+ if ($this->isUseOfGlobalConstant($phpcsFile, $stackPtr) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $constantName,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->removedConstants[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The constant "%s" is ';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/DiscouragedSwitchContinueSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/DiscouragedSwitchContinueSniff.php
new file mode 100644
index 0000000..23f0f5c
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/DiscouragedSwitchContinueSniff.php
@@ -0,0 +1,223 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\ControlStructures\DiscouragedSwitchContinue.
+ *
+ * PHP 7.3 will throw a warning when continue is used to target a switch control structure.
+ *
+ * PHP version 7.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class DiscouragedSwitchContinueSniff extends Sniff
+{
+
+ /**
+ * Token codes of control structures which can be targeted using continue.
+ *
+ * @var array
+ */
+ protected $loopStructures = array(
+ \T_FOR => \T_FOR,
+ \T_FOREACH => \T_FOREACH,
+ \T_WHILE => \T_WHILE,
+ \T_DO => \T_DO,
+ \T_SWITCH => \T_SWITCH,
+ );
+
+ /**
+ * Tokens which start a new case within a switch.
+ *
+ * @var array
+ */
+ protected $caseTokens = array(
+ \T_CASE => \T_CASE,
+ \T_DEFAULT => \T_DEFAULT,
+ );
+
+ /**
+ * Token codes which are accepted to determine the level for the continue.
+ *
+ * This array is enriched with the arithmetic operators in the register() method.
+ *
+ * @var array
+ */
+ protected $acceptedLevelTokens = array(
+ \T_LNUMBER => \T_LNUMBER,
+ \T_OPEN_PARENTHESIS => \T_OPEN_PARENTHESIS,
+ \T_CLOSE_PARENTHESIS => \T_CLOSE_PARENTHESIS,
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $this->acceptedLevelTokens += Tokens::$arithmeticTokens;
+ $this->acceptedLevelTokens += Tokens::$emptyTokens;
+
+ return array(\T_SWITCH);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
+ return;
+ }
+
+ $switchOpener = $tokens[$stackPtr]['scope_opener'];
+ $switchCloser = $tokens[$stackPtr]['scope_closer'];
+
+ // Quick check whether we need to bother with the more complex logic.
+ $hasContinue = $phpcsFile->findNext(\T_CONTINUE, ($switchOpener + 1), $switchCloser);
+ if ($hasContinue === false) {
+ return;
+ }
+
+ $caseDefault = $switchOpener;
+
+ do {
+ $caseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
+ if ($caseDefault === false) {
+ break;
+ }
+
+ if (isset($tokens[$caseDefault]['scope_opener']) === false) {
+ // Unknown start of the case, skip.
+ continue;
+ }
+
+ $caseOpener = $tokens[$caseDefault]['scope_opener'];
+ $nextCaseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
+ if ($nextCaseDefault === false) {
+ $caseCloser = $switchCloser;
+ } else {
+ $caseCloser = $nextCaseDefault;
+ }
+
+ // Check for unscoped control structures within the case.
+ $controlStructure = $caseOpener;
+ $doCount = 0;
+ while (($controlStructure = $phpcsFile->findNext($this->loopStructures, ($controlStructure + 1), $caseCloser)) !== false) {
+ if ($tokens[$controlStructure]['code'] === \T_DO) {
+ $doCount++;
+ }
+
+ if (isset($tokens[$controlStructure]['scope_opener'], $tokens[$controlStructure]['scope_closer']) === false) {
+ if ($tokens[$controlStructure]['code'] === \T_WHILE && $doCount > 0) {
+ // While in a do-while construct.
+ $doCount--;
+ continue;
+ }
+
+ // Control structure without braces found within the case, ignore this case.
+ continue 2;
+ }
+ }
+
+ // Examine the contents of the case.
+ $continue = $caseOpener;
+
+ do {
+ $continue = $phpcsFile->findNext(\T_CONTINUE, ($continue + 1), $caseCloser);
+ if ($continue === false) {
+ break;
+ }
+
+ $nextSemicolon = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($continue + 1), $caseCloser);
+ $codeString = '';
+ for ($i = ($continue + 1); $i < $nextSemicolon; $i++) {
+ if (isset($this->acceptedLevelTokens[$tokens[$i]['code']]) === false) {
+ // Function call/variable or other token which make numeric level impossible to determine.
+ continue 2;
+ }
+
+ if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
+ continue;
+ }
+
+ $codeString .= $tokens[$i]['content'];
+ }
+
+ $level = null;
+ if ($codeString !== '') {
+ if (is_numeric($codeString)) {
+ $level = (int) $codeString;
+ } else {
+ // With the above logic, the string can only contain digits and operators, eval!
+ $level = eval("return ( $codeString );");
+ }
+ }
+
+ if (isset($level) === false || $level === 0) {
+ $level = 1;
+ }
+
+ // Examine which control structure is being targeted by the continue statement.
+ if (isset($tokens[$continue]['conditions']) === false) {
+ continue;
+ }
+
+ $conditions = array_reverse($tokens[$continue]['conditions'], true);
+ // PHPCS adds more structures to the conditions array than we want to take into
+ // consideration, so clean up the array.
+ foreach ($conditions as $tokenPtr => $tokenCode) {
+ if (isset($this->loopStructures[$tokenCode]) === false) {
+ unset($conditions[$tokenPtr]);
+ }
+ }
+
+ $targetCondition = \array_slice($conditions, ($level - 1), 1, true);
+ if (empty($targetCondition)) {
+ continue;
+ }
+
+ $conditionToken = key($targetCondition);
+ if ($conditionToken === $stackPtr) {
+ $phpcsFile->addWarning(
+ "Targeting a 'switch' control structure with a 'continue' statement is strongly discouraged and will throw a warning as of PHP 7.3.",
+ $continue,
+ 'Found'
+ );
+ }
+
+ } while ($continue < $caseCloser);
+
+ } while ($caseDefault < $switchCloser);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenBreakContinueOutsideLoopSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenBreakContinueOutsideLoopSniff.php
new file mode 100644
index 0000000..1d64636
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenBreakContinueOutsideLoopSniff.php
@@ -0,0 +1,109 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ControlStructures\ForbiddenBreakContinueOutsideLoop.
+ *
+ * Forbids use of break or continue statements outside of looping structures.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ForbiddenBreakContinueOutsideLoopSniff extends Sniff
+{
+
+ /**
+ * Token codes of control structure in which usage of break/continue is valid.
+ *
+ * @var array
+ */
+ protected $validLoopStructures = array(
+ T_FOR => true,
+ T_FOREACH => true,
+ T_WHILE => true,
+ T_DO => true,
+ T_SWITCH => true,
+ );
+
+ /**
+ * Token codes which did not correctly get a condition assigned in older PHPCS versions.
+ *
+ * @var array
+ */
+ protected $backCompat = array(
+ T_CASE => true,
+ T_DEFAULT => true,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_BREAK,
+ T_CONTINUE,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $token = $tokens[$stackPtr];
+
+ // Check if the break/continue is within a valid loop structure.
+ if (empty($token['conditions']) === false) {
+ foreach ($token['conditions'] as $tokenCode) {
+ if (isset($this->validLoopStructures[$tokenCode]) === true) {
+ return;
+ }
+ }
+ } else {
+ // Deal with older PHPCS versions.
+ if (isset($token['scope_condition']) === true && isset($this->backCompat[$tokens[$token['scope_condition']]['code']]) === true) {
+ return;
+ }
+ }
+
+ // If we're still here, no valid loop structure container has been found, so throw an error.
+ $error = "Using '%s' outside of a loop or switch structure is invalid";
+ $isError = false;
+ $errorCode = 'Found';
+ $data = array($token['content']);
+
+ if ($this->supportsAbove('7.0')) {
+ $error .= ' and will throw a fatal error since PHP 7.0';
+ $isError = true;
+ $errorCode = 'FatalError';
+ }
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode, $data);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenBreakContinueVariableArgumentsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenBreakContinueVariableArgumentsSniff.php
new file mode 100644
index 0000000..b93c7c3
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenBreakContinueVariableArgumentsSniff.php
@@ -0,0 +1,101 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\ControlStructures\ForbiddenBreakContinueVariableArguments.
+ *
+ * Forbids variable arguments on break or continue statements.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class ForbiddenBreakContinueVariableArgumentsSniff extends Sniff
+{
+ /**
+ * Error types this sniff handles for forbidden break/continue arguments.
+ *
+ * Array key is the error code. Array value will be used as part of the error message.
+ *
+ * @var array
+ */
+ private $errorTypes = array(
+ 'variableArgument' => 'a variable argument',
+ 'zeroArgument' => '0 as an argument',
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_BREAK, T_CONTINUE);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $nextSemicolonToken = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), ($stackPtr), null, false);
+ $errorType = '';
+ for ($curToken = $stackPtr + 1; $curToken < $nextSemicolonToken; $curToken++) {
+ if ($tokens[$curToken]['type'] === 'T_STRING') {
+ // If the next non-whitespace token after the string
+ // is an opening parenthesis then it's a function call.
+ $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, $curToken + 1, null, true);
+ if ($tokens[$openBracket]['code'] === T_OPEN_PARENTHESIS) {
+ $errorType = 'variableArgument';
+ break;
+ }
+
+ } elseif (in_array($tokens[$curToken]['type'], array('T_VARIABLE', 'T_FUNCTION', 'T_CLOSURE'), true)) {
+ $errorType = 'variableArgument';
+ break;
+
+ } elseif ($tokens[$curToken]['type'] === 'T_LNUMBER' && $tokens[$curToken]['content'] === '0') {
+ $errorType = 'zeroArgument';
+ break;
+ }
+ }
+
+ if ($errorType !== '') {
+ $error = 'Using %s on break or continue is forbidden since PHP 5.4';
+ $errorCode = $errorType . 'Found';
+ $data = array($this->errorTypes[$errorType]);
+
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenSwitchWithMultipleDefaultBlocksSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenSwitchWithMultipleDefaultBlocksSniff.php
new file mode 100644
index 0000000..f537de8
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/ForbiddenSwitchWithMultipleDefaultBlocksSniff.php
@@ -0,0 +1,79 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ControlStructures\ForbiddenSwitchWithMultipleDefaultBlocksSniff.
+ *
+ * Switch statements can not have multiple default blocks since PHP 7.0
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class ForbiddenSwitchWithMultipleDefaultBlocksSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_SWITCH);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ if (isset($tokens[$stackPtr]['scope_closer']) === false) {
+ return;
+ }
+
+ $defaultToken = $stackPtr;
+ $defaultCount = 0;
+ $targetLevel = $tokens[$stackPtr]['level'] + 1;
+ while ($defaultCount < 2 && ($defaultToken = $phpcsFile->findNext(array(T_DEFAULT), $defaultToken + 1, $tokens[$stackPtr]['scope_closer'])) !== false) {
+ // Same level or one below (= two default cases after each other).
+ if ($tokens[$defaultToken]['level'] === $targetLevel || $tokens[$defaultToken]['level'] === ($targetLevel + 1)) {
+ $defaultCount++;
+ }
+ }
+
+ if ($defaultCount > 1) {
+ $phpcsFile->addError(
+ 'Switch statements can not have multiple default blocks since PHP 7.0',
+ $stackPtr,
+ 'Found'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewExecutionDirectivesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewExecutionDirectivesSniff.php
new file mode 100644
index 0000000..c65906b
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewExecutionDirectivesSniff.php
@@ -0,0 +1,334 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\ControlStructures\NewExecutionDirectivesSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewExecutionDirectivesSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new execution directives
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If the execution order is conditional, add the condition as a string to the version nr.
+ * If's sufficient to list the first version where the execution directive appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newDirectives = array(
+ 'ticks' => array(
+ '3.1' => false,
+ '4.0' => true,
+ 'valid_value_callback' => 'isNumeric',
+ ),
+ 'encoding' => array(
+ '5.2' => false,
+ '5.3' => '--enable-zend-multibyte', // Directive ignored unless.
+ '5.4' => true,
+ 'valid_value_callback' => 'validEncoding',
+ ),
+ 'strict_types' => array(
+ '5.6' => false,
+ '7.0' => true,
+ 'valid_values' => array(1),
+ ),
+ );
+
+
+ /**
+ * Tokens to ignore when trying to find the value for the directive.
+ *
+ * @var array
+ */
+ protected $ignoreTokens = array();
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $this->ignoreTokens = Tokens::$emptyTokens;
+ $this->ignoreTokens[T_EQUAL] = T_EQUAL;
+
+ return array(T_DECLARE);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === true) {
+ $openParenthesis = $tokens[$stackPtr]['parenthesis_opener'];
+ $closeParenthesis = $tokens[$stackPtr]['parenthesis_closer'];
+ } else {
+ if (version_compare(PHPCSHelper::getVersion(), '2.3.4', '>=')) {
+ return;
+ }
+
+ // Deal with PHPCS 2.3.0-2.3.3 which do not yet set the parenthesis properly for declare statements.
+ $openParenthesis = $phpcsFile->findNext(T_OPEN_PARENTHESIS, ($stackPtr + 1), null, false, null, true);
+ if ($openParenthesis === false || isset($tokens[$openParenthesis]['parenthesis_closer']) === false) {
+ return;
+ }
+ $closeParenthesis = $tokens[$openParenthesis]['parenthesis_closer'];
+ }
+
+ $directivePtr = $phpcsFile->findNext(T_STRING, ($openParenthesis + 1), $closeParenthesis, false);
+ if ($directivePtr === false) {
+ return;
+ }
+
+ $directiveContent = $tokens[$directivePtr]['content'];
+
+ if (isset($this->newDirectives[$directiveContent]) === false) {
+ $error = 'Declare can only be used with the directives %s. Found: %s';
+ $data = array(
+ implode(', ', array_keys($this->newDirectives)),
+ $directiveContent,
+ );
+
+ $phpcsFile->addError($error, $stackPtr, 'InvalidDirectiveFound', $data);
+
+ } else {
+ // Check for valid directive for version.
+ $itemInfo = array(
+ 'name' => $directiveContent,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+
+ // Check for valid directive value.
+ $valuePtr = $phpcsFile->findNext($this->ignoreTokens, $directivePtr + 1, $closeParenthesis, true);
+ if ($valuePtr === false) {
+ return;
+ }
+
+ $this->addWarningOnInvalidValue($phpcsFile, $valuePtr, $directiveContent);
+ }
+ }
+
+
+ /**
+ * Determine whether an error/warning should be thrown for an item based on collected information.
+ *
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return bool
+ */
+ protected function shouldThrowError(array $errorInfo)
+ {
+ return ($errorInfo['not_in_version'] !== '' || $errorInfo['conditional_version'] !== '');
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newDirectives[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array(
+ 'valid_value_callback',
+ 'valid_values',
+ );
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['conditional_version'] = '';
+ $errorInfo['condition'] = '';
+
+ $versionArray = $this->getVersionArray($itemArray);
+
+ if (empty($versionArray) === false) {
+ foreach ($versionArray as $version => $present) {
+ if (is_string($present) === true && $this->supportsBelow($version) === true) {
+ // We cannot test for compilation option (ok, except by scraping the output of phpinfo...).
+ $errorInfo['conditional_version'] = $version;
+ $errorInfo['condition'] = $present;
+ }
+ }
+ }
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'Directive ' . parent::getErrorMsgTemplate();
+ }
+
+
+ /**
+ * Generates the error or warning for this item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Array with detail (version) information
+ * relevant to the item.
+ *
+ * @return void
+ */
+ public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
+ {
+ if ($errorInfo['not_in_version'] !== '') {
+ parent::addError($phpcsFile, $stackPtr, $itemInfo, $errorInfo);
+ } elseif ($errorInfo['conditional_version'] !== '') {
+ $error = 'Directive %s is present in PHP version %s but will be disregarded unless PHP is compiled with %s';
+ $errorCode = $this->stringToErrorCode($itemInfo['name']) . 'WithConditionFound';
+ $data = array(
+ $itemInfo['name'],
+ $errorInfo['conditional_version'],
+ $errorInfo['condition'],
+ );
+
+ $phpcsFile->addWarning($error, $stackPtr, $errorCode, $data);
+ }
+ }
+
+
+ /**
+ * Generates a error or warning for this sniff.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the execution directive value
+ * in the token array.
+ * @param string $directive The directive.
+ *
+ * @return void
+ */
+ protected function addWarningOnInvalidValue(File $phpcsFile, $stackPtr, $directive)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $value = $tokens[$stackPtr]['content'];
+ if (isset(Tokens::$stringTokens[$tokens[$stackPtr]['code']]) === true) {
+ $value = $this->stripQuotes($value);
+ }
+
+ $isError = false;
+ if (isset($this->newDirectives[$directive]['valid_values'])) {
+ if (in_array($value, $this->newDirectives[$directive]['valid_values']) === false) {
+ $isError = true;
+ }
+ } elseif (isset($this->newDirectives[$directive]['valid_value_callback'])) {
+ $valid = call_user_func(array($this, $this->newDirectives[$directive]['valid_value_callback']), $value);
+ if ($valid === false) {
+ $isError = true;
+ }
+ }
+
+ if ($isError === true) {
+ $error = 'The execution directive %s does not seem to have a valid value. Please review. Found: %s';
+ $errorCode = $this->stringToErrorCode($directive) . 'InvalidValueFound';
+ $data = array(
+ $directive,
+ $value,
+ );
+
+ $phpcsFile->addWarning($error, $stackPtr, $errorCode, $data);
+ }
+ }
+
+
+ /**
+ * Check whether a value is numeric.
+ *
+ * Callback function to test whether the value for an execution directive is valid.
+ *
+ * @param mixed $value The value to test.
+ *
+ * @return bool
+ */
+ protected function isNumeric($value)
+ {
+ return is_numeric($value);
+ }
+
+
+ /**
+ * Check whether a value is a valid encoding.
+ *
+ * Callback function to test whether the value for an execution directive is valid.
+ *
+ * @param mixed $value The value to test.
+ *
+ * @return bool
+ */
+ protected function validEncoding($value)
+ {
+ static $encodings;
+ if (isset($encodings) === false && function_exists('mb_list_encodings')) {
+ $encodings = mb_list_encodings();
+ }
+
+ if (empty($encodings) || is_array($encodings) === false) {
+ // If we can't test the encoding, let it pass through.
+ return true;
+ }
+
+ return in_array($value, $encodings, true);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewForeachExpressionReferencingSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewForeachExpressionReferencingSniff.php
new file mode 100644
index 0000000..88b6ae1
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewForeachExpressionReferencingSniff.php
@@ -0,0 +1,96 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * New `foreach` Expression Referencing.
+ *
+ * Before PHP 5.5.0, referencing $value is only possible if the iterated array
+ * can be referenced (i.e. if it is a variable).
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewForeachExpressionReferencingSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_FOREACH);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $opener = $tokens[$stackPtr]['parenthesis_opener'];
+ $closer = $tokens[$stackPtr]['parenthesis_closer'];
+
+ $asToken = $phpcsFile->findNext(T_AS, ($opener + 1), $closer);
+ if ($asToken === false) {
+ return;
+ }
+
+ /*
+ * Note: referencing $key is not allowed in any version, so this should only find referenced $values.
+ * If it does find a referenced key, it would be a parse error anyway.
+ */
+ $hasReference = $phpcsFile->findNext(T_BITWISE_AND, ($asToken + 1), $closer);
+ if ($hasReference === false) {
+ return;
+ }
+
+ $nestingLevel = 0;
+ if ($asToken !== ($opener + 1) && isset($tokens[$opener + 1]['nested_parenthesis'])) {
+ $nestingLevel = count($tokens[$opener + 1]['nested_parenthesis']);
+ }
+
+ if ($this->isVariable($phpcsFile, ($opener + 1), $asToken, $nestingLevel) === true) {
+ return;
+ }
+
+ // Non-variable detected before the `as` keyword.
+ $phpcsFile->addError(
+ 'Referencing $value is only possible if the iterated array is a variable in PHP 5.4 or earlier.',
+ $hasReference,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewListInForeachSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewListInForeachSniff.php
new file mode 100644
index 0000000..f964279
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewListInForeachSniff.php
@@ -0,0 +1,79 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * Detect unpacking nested arrays with list() in a foreach().
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewListInForeachSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_FOREACH);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $opener = $tokens[$stackPtr]['parenthesis_opener'];
+ $closer = $tokens[$stackPtr]['parenthesis_closer'];
+
+ $asToken = $phpcsFile->findNext(T_AS, ($opener + 1), $closer);
+ if ($asToken === false) {
+ return;
+ }
+
+ $hasList = $phpcsFile->findNext(array(T_LIST, T_OPEN_SHORT_ARRAY), ($asToken + 1), $closer);
+ if ($hasList === false) {
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Unpacking nested arrays with list() in a foreach is not supported in PHP 5.4 or earlier.',
+ $hasList,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewMultiCatchSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewMultiCatchSniff.php
new file mode 100644
index 0000000..5fc03ff
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ControlStructures/NewMultiCatchSniff.php
@@ -0,0 +1,75 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ControlStructures;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ControlStructures\NewMultiCatch.
+ *
+ * Catching multiple exception types in one statement is available since PHP 7.1.
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewMultiCatchSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_CATCH);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $token = $tokens[$stackPtr];
+
+ // Bow out during live coding.
+ if (isset($token['parenthesis_opener'], $token['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $hasBitwiseOr = $phpcsFile->findNext(T_BITWISE_OR, $token['parenthesis_opener'], $token['parenthesis_closer']);
+
+ if ($hasBitwiseOr === false) {
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Catching multiple exceptions within one statement is not supported in PHP 7.0 or earlier.',
+ $hasBitwiseOr,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Extensions/RemovedExtensionsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Extensions/RemovedExtensionsSniff.php
new file mode 100644
index 0000000..f8bf06d
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Extensions/RemovedExtensionsSniff.php
@@ -0,0 +1,309 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Extensions;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Extensions\RemovedExtensionsSniff.
+ *
+ * Discourages the use of removed extensions. Suggests alternative extensions if available
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class RemovedExtensionsSniff extends AbstractRemovedFeatureSniff
+{
+ /**
+ * A list of functions to whitelist, if any.
+ *
+ * This is intended for projects using functions which start with the same
+ * prefix as one of the removed extensions.
+ *
+ * This property can be set from the ruleset, like so:
+ *
+ *
+ *
+ *
+ *
+ *
+ * @var array
+ */
+ public $functionWhitelist;
+
+ /**
+ * A list of removed extensions with their alternative, if any
+ *
+ * The array lists : version number with false (deprecated) and true (removed).
+ * If's sufficient to list the first version where the extension was deprecated/removed.
+ *
+ * @var array(string|null)
+ */
+ protected $removedExtensions = array(
+ 'activescript' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/activescript',
+ ),
+ 'cpdf' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/pdflib',
+ ),
+ 'dbase' => array(
+ '5.3' => true,
+ 'alternative' => null,
+ ),
+ 'dbx' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/dbx',
+ ),
+ 'dio' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/dio',
+ ),
+ 'ereg' => array(
+ '5.3' => false,
+ '7.0' => true,
+ 'alternative' => 'pcre',
+ ),
+ 'fam' => array(
+ '5.1' => true,
+ 'alternative' => null,
+ ),
+ 'fbsql' => array(
+ '5.3' => true,
+ 'alternative' => null,
+ ),
+ 'fdf' => array(
+ '5.3' => true,
+ 'alternative' => 'pecl/fdf',
+ ),
+ 'filepro' => array(
+ '5.2' => true,
+ 'alternative' => null,
+ ),
+ 'hw_api' => array(
+ '5.2' => true,
+ 'alternative' => null,
+ ),
+ 'ingres' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/ingres',
+ ),
+ 'ircg' => array(
+ '5.1' => true,
+ 'alternative' => null,
+ ),
+ 'mcrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'openssl (preferred) or pecl/mcrypt once available',
+ ),
+ 'mcve' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/mvce',
+ ),
+ 'ming' => array(
+ '5.3' => true,
+ 'alternative' => 'pecl/ming',
+ ),
+ 'mnogosearch' => array(
+ '5.1' => true,
+ 'alternative' => null,
+ ),
+ 'msql' => array(
+ '5.3' => true,
+ 'alternative' => null,
+ ),
+ 'mssql' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'mysql_' => array(
+ '5.5' => false,
+ '7.0' => true,
+ 'alternative' => 'mysqli',
+ ),
+ 'ncurses' => array(
+ '5.3' => true,
+ 'alternative' => 'pecl/ncurses',
+ ),
+ 'oracle' => array(
+ '5.1' => true,
+ 'alternative' => 'oci8 or pdo_oci',
+ ),
+ 'ovrimos' => array(
+ '5.1' => true,
+ 'alternative' => null,
+ ),
+ 'pfpro' => array(
+ '5.3' => true,
+ 'alternative' => null,
+ ),
+ 'sqlite' => array(
+ '5.4' => true,
+ 'alternative' => null,
+ ),
+ // Has to be before `sybase` as otherwise it will never match.
+ 'sybase_ct' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'sybase' => array(
+ '5.3' => true,
+ 'alternative' => 'sybase_ct',
+ ),
+ 'w32api' => array(
+ '5.1' => true,
+ 'alternative' => 'pecl/ffi',
+ ),
+ 'yp' => array(
+ '5.1' => true,
+ 'alternative' => null,
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->removedExtensions = $this->arrayKeysToLowercase($this->removedExtensions);
+
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Find the next non-empty token.
+ $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+
+ if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) {
+ // Not a function call.
+ return;
+ }
+
+ if (isset($tokens[$openBracket]['parenthesis_closer']) === false) {
+ // Not a function call.
+ return;
+ }
+
+ // Find the previous non-empty token.
+ $search = Tokens::$emptyTokens;
+ $search[] = T_BITWISE_AND;
+ $previous = $phpcsFile->findPrevious($search, ($stackPtr - 1), null, true);
+ if ($tokens[$previous]['code'] === T_FUNCTION) {
+ // It's a function definition, not a function call.
+ return;
+ }
+
+ if ($tokens[$previous]['code'] === T_NEW) {
+ // We are creating an object, not calling a function.
+ return;
+ }
+
+ if ($tokens[$previous]['code'] === T_OBJECT_OPERATOR) {
+ // We are calling a method of an object.
+ return;
+ }
+
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if ($this->isWhiteListed($functionLc) === true) {
+ // Function is whitelisted.
+ return;
+ }
+
+ foreach ($this->removedExtensions as $extension => $versionList) {
+ if (strpos($functionLc, $extension) === 0) {
+ $itemInfo = array(
+ 'name' => $extension,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ break;
+ }
+ }
+ }
+
+
+ /**
+ * Is the current function being checked whitelisted ?
+ *
+ * Parsing the list late as it may be provided as a property, but also inline.
+ *
+ * @param string $content Content of the current token.
+ *
+ * @return bool
+ */
+ protected function isWhiteListed($content)
+ {
+ if (isset($this->functionWhitelist) === false) {
+ return false;
+ }
+
+ if (is_string($this->functionWhitelist) === true) {
+ if (strpos($this->functionWhitelist, ',') !== false) {
+ $this->functionWhitelist = explode(',', $this->functionWhitelist);
+ } else {
+ $this->functionWhitelist = (array) $this->functionWhitelist;
+ }
+ }
+
+ if (is_array($this->functionWhitelist) === true) {
+ $this->functionWhitelist = array_map('strtolower', $this->functionWhitelist);
+ return in_array($content, $this->functionWhitelist, true);
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->removedExtensions[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return "Extension '%s' is ";
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenParameterShadowSuperGlobalsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenParameterShadowSuperGlobalsSniff.php
new file mode 100644
index 0000000..b3037fc
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenParameterShadowSuperGlobalsSniff.php
@@ -0,0 +1,79 @@
+
+ * @copyright 2015 Declan Kelly
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\ForbiddenParameterShadowSuperGlobalsSniff
+ *
+ * Discourages use of superglobals as parameters for functions.
+ *
+ * {@internal List of superglobals is maintained in the parent class.}}
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Declan Kelly
+ * @copyright 2015 Declan Kelly
+ */
+class ForbiddenParameterShadowSuperGlobalsSniff extends Sniff
+{
+
+ /**
+ * Register the tokens to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+ }
+
+ /**
+ * Processes the test.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('5.4') === false) {
+ return;
+ }
+
+ // Get all parameters from function signature.
+ $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($parameters) || is_array($parameters) === false) {
+ return;
+ }
+
+ foreach ($parameters as $param) {
+ if (isset($this->superglobals[$param['name']]) === true) {
+ $error = 'Parameter shadowing super global (%s) causes fatal error since PHP 5.4';
+ $errorCode = $this->stringToErrorCode(substr($param['name'], 1)) . 'Found';
+ $data = array($param['name']);
+
+ $phpcsFile->addError($error, $param['token'], $errorCode, $data);
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenParametersWithSameNameSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenParametersWithSameNameSniff.php
new file mode 100644
index 0000000..abbf0ac
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenParametersWithSameNameSniff.php
@@ -0,0 +1,86 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\ForbiddenParametersWithSameName.
+ *
+ * Functions can not have multiple parameters with the same name since PHP 7.0
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class ForbiddenParametersWithSameNameSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $token = $tokens[$stackPtr];
+ // Skip function without body.
+ if (isset($token['scope_opener']) === false) {
+ return;
+ }
+
+ // Get all parameters from method signature.
+ $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($parameters) || is_array($parameters) === false) {
+ return;
+ }
+
+ $paramNames = array();
+ foreach ($parameters as $param) {
+ $paramNames[] = strtolower($param['name']);
+ }
+
+ if (count($paramNames) !== count(array_unique($paramNames))) {
+ $phpcsFile->addError(
+ 'Functions can not have multiple parameters with the same name since PHP 7.0',
+ $stackPtr,
+ 'Found'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenVariableNamesInClosureUseSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenVariableNamesInClosureUseSniff.php
new file mode 100644
index 0000000..928938a
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/ForbiddenVariableNamesInClosureUseSniff.php
@@ -0,0 +1,118 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * PHP 7.1 Forbidden variable names in closure use statements.
+ *
+ * Variables bound to a closure via the use construct cannot use the same name
+ * as any superglobals, $this, or any parameter since PHP 7.1.
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ForbiddenVariableNamesInClosureUseSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_USE);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.1') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Verify this use statement is used with a closure - if so, it has to have parenthesis before it.
+ $previousNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
+ if ($previousNonEmpty === false || $tokens[$previousNonEmpty]['code'] !== T_CLOSE_PARENTHESIS
+ || isset($tokens[$previousNonEmpty]['parenthesis_opener']) === false
+ ) {
+ return;
+ }
+
+ // ... and (a variable within) parenthesis after it.
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_OPEN_PARENTHESIS) {
+ return;
+ }
+
+ if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) {
+ // Live coding.
+ return;
+ }
+
+ $closurePtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($tokens[$previousNonEmpty]['parenthesis_opener'] - 1), null, true);
+ if ($closurePtr === false || $tokens[$closurePtr]['code'] !== T_CLOSURE) {
+ return;
+ }
+
+ // Get the parameters declared by the closure.
+ $closureParams = PHPCSHelper::getMethodParameters($phpcsFile, $closurePtr);
+
+ $errorMsg = 'Variables bound to a closure via the use construct cannot use the same name as superglobals, $this, or a declared parameter since PHP 7.1. Found: %s';
+
+ for ($i = ($nextNonEmpty + 1); $i < $tokens[$nextNonEmpty]['parenthesis_closer']; $i++) {
+ if ($tokens[$i]['code'] !== T_VARIABLE) {
+ continue;
+ }
+
+ $variableName = $tokens[$i]['content'];
+
+ if ($variableName === '$this') {
+ $phpcsFile->addError($errorMsg, $i, 'FoundThis', array($variableName));
+ continue;
+ }
+
+ if (isset($this->superglobals[$variableName]) === true) {
+ $phpcsFile->addError($errorMsg, $i, 'FoundSuperglobal', array($variableName));
+ continue;
+ }
+
+ // Check whether it is one of the parameters declared by the closure.
+ if (empty($closureParams) === false) {
+ foreach ($closureParams as $param) {
+ if ($param['name'] === $variableName) {
+ $phpcsFile->addError($errorMsg, $i, 'FoundShadowParam', array($variableName));
+ continue 2;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewClosureSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewClosureSniff.php
new file mode 100644
index 0000000..219832b
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewClosureSniff.php
@@ -0,0 +1,237 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\NewClosure.
+ *
+ * Closures are available since PHP 5.3
+ *
+ * PHP version 5.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewClosureSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_CLOSURE);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.2')) {
+ $phpcsFile->addError(
+ 'Closures / anonymous functions are not available in PHP 5.2 or earlier',
+ $stackPtr,
+ 'Found'
+ );
+ }
+
+ /*
+ * Closures can only be declared as static since PHP 5.4.
+ */
+ $isStatic = $this->isClosureStatic($phpcsFile, $stackPtr);
+ if ($this->supportsBelow('5.3') && $isStatic === true) {
+ $phpcsFile->addError(
+ 'Closures / anonymous functions could not be declared as static in PHP 5.3 or earlier',
+ $stackPtr,
+ 'StaticFound'
+ );
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
+ // Live coding or parse error.
+ return;
+ }
+
+ $scopeStart = ($tokens[$stackPtr]['scope_opener'] + 1);
+ $scopeEnd = $tokens[$stackPtr]['scope_closer'];
+ $usesThis = $this->findThisUsageInClosure($phpcsFile, $scopeStart, $scopeEnd);
+
+ if ($this->supportsBelow('5.3')) {
+ /*
+ * Closures declared within classes only have access to $this since PHP 5.4.
+ */
+ if ($usesThis !== false) {
+ $thisFound = $usesThis;
+ do {
+ $phpcsFile->addError(
+ 'Closures / anonymous functions did not have access to $this in PHP 5.3 or earlier',
+ $thisFound,
+ 'ThisFound'
+ );
+
+ $thisFound = $this->findThisUsageInClosure($phpcsFile, ($thisFound + 1), $scopeEnd);
+
+ } while ($thisFound !== false);
+ }
+
+ /*
+ * Closures declared within classes only have access to self/parent/static since PHP 5.4.
+ */
+ $usesClassRef = $this->findClassRefUsageInClosure($phpcsFile, $scopeStart, $scopeEnd);
+
+ if ($usesClassRef !== false) {
+ do {
+ $phpcsFile->addError(
+ 'Closures / anonymous functions could not use "%s::" in PHP 5.3 or earlier',
+ $usesClassRef,
+ 'ClassRefFound',
+ array(strtolower($tokens[$usesClassRef]['content']))
+ );
+
+ $usesClassRef = $this->findClassRefUsageInClosure($phpcsFile, ($usesClassRef + 1), $scopeEnd);
+
+ } while ($usesClassRef !== false);
+ }
+ }
+
+ /*
+ * Check for correct usage.
+ */
+ if ($this->supportsAbove('5.4') && $usesThis !== false) {
+
+ $thisFound = $usesThis;
+
+ do {
+ /*
+ * Closures only have access to $this if not declared as static.
+ */
+ if ($isStatic === true) {
+ $phpcsFile->addError(
+ 'Closures / anonymous functions declared as static do not have access to $this',
+ $thisFound,
+ 'ThisFoundInStatic'
+ );
+ }
+
+ /*
+ * Closures only have access to $this if used within a class context.
+ */
+ elseif ($this->inClassScope($phpcsFile, $stackPtr, false) === false) {
+ $phpcsFile->addWarning(
+ 'Closures / anonymous functions only have access to $this if used within a class or when bound to an object using bindTo(). Please verify.',
+ $thisFound,
+ 'ThisFoundOutsideClass'
+ );
+ }
+
+ $thisFound = $this->findThisUsageInClosure($phpcsFile, ($thisFound + 1), $scopeEnd);
+
+ } while ($thisFound !== false);
+ }
+
+ // Prevent double reporting for nested closures.
+ return $scopeEnd;
+ }
+
+
+ /**
+ * Check whether the closure is declared as static.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return bool
+ */
+ protected function isClosureStatic(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
+
+ return ($prevToken !== false && $tokens[$prevToken]['code'] === T_STATIC);
+ }
+
+
+ /**
+ * Check if the code within a closure uses the $this variable.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $startToken The position within the closure to continue searching from.
+ * @param int $endToken The closure scope closer to stop searching at.
+ *
+ * @return int|false The stackPtr to the first $this usage if found or false if
+ * $this is not used.
+ */
+ protected function findThisUsageInClosure(File $phpcsFile, $startToken, $endToken)
+ {
+ // Make sure the $startToken is valid.
+ if ($startToken >= $endToken) {
+ return false;
+ }
+
+ return $phpcsFile->findNext(
+ T_VARIABLE,
+ $startToken,
+ $endToken,
+ false,
+ '$this'
+ );
+ }
+
+ /**
+ * Check if the code within a closure uses "self/parent/static".
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $startToken The position within the closure to continue searching from.
+ * @param int $endToken The closure scope closer to stop searching at.
+ *
+ * @return int|false The stackPtr to the first classRef usage if found or false if
+ * they are not used.
+ */
+ protected function findClassRefUsageInClosure(File $phpcsFile, $startToken, $endToken)
+ {
+ // Make sure the $startToken is valid.
+ if ($startToken >= $endToken) {
+ return false;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $classRef = $phpcsFile->findNext(array(T_SELF, T_PARENT, T_STATIC), $startToken, $endToken);
+
+ if ($classRef === false || $tokens[$classRef]['code'] !== T_STATIC) {
+ return $classRef;
+ }
+
+ // T_STATIC, make sure it is used as a class reference.
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($classRef + 1), $endToken, true);
+ if ($next === false || $tokens[$next]['code'] !== T_DOUBLE_COLON) {
+ return false;
+ }
+
+ return $classRef;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewNullableTypesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewNullableTypesSniff.php
new file mode 100644
index 0000000..51f56df
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewNullableTypesSniff.php
@@ -0,0 +1,162 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\NewNullableTypes.
+ *
+ * Nullable type hints and return types are available since PHP 7.1.
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewNullableTypesSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * {@internal Not sniffing for T_NULLABLE which was introduced in PHPCS 2.7.2
+ * as in that case we can't distinguish between parameter type hints and
+ * return type hints for the error message.}}
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array(
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+
+ if (defined('T_RETURN_TYPE')) {
+ $tokens[] = T_RETURN_TYPE;
+ }
+
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $tokenCode = $tokens[$stackPtr]['code'];
+
+ if ($tokenCode === T_FUNCTION || $tokenCode === T_CLOSURE) {
+ $this->processFunctionDeclaration($phpcsFile, $stackPtr);
+
+ // Deal with older PHPCS version which don't recognize return type hints
+ // as well as newer PHPCS versions (3.3.0+) where the tokenization has changed.
+ $returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
+ if ($returnTypeHint !== false) {
+ $this->processReturnType($phpcsFile, $returnTypeHint);
+ }
+ } else {
+ $this->processReturnType($phpcsFile, $stackPtr);
+ }
+ }
+
+
+ /**
+ * Process this test for function tokens.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ protected function processFunctionDeclaration(File $phpcsFile, $stackPtr)
+ {
+ $params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+
+ if (empty($params) === false && is_array($params)) {
+ foreach ($params as $param) {
+ if ($param['nullable_type'] === true) {
+ $phpcsFile->addError(
+ 'Nullable type declarations are not supported in PHP 7.0 or earlier. Found: %s',
+ $param['token'],
+ 'typeDeclarationFound',
+ array($param['type_hint'])
+ );
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Process this test for return type tokens.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ protected function processReturnType(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[($stackPtr - 1)]['code']) === false) {
+ return;
+ }
+
+ $previous = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+
+ // Deal with namespaced class names.
+ if ($tokens[$previous]['code'] === T_NS_SEPARATOR) {
+ $validTokens = Tokens::$emptyTokens;
+ $validTokens[T_STRING] = true;
+ $validTokens[T_NS_SEPARATOR] = true;
+
+ $stackPtr--;
+
+ while (isset($validTokens[$tokens[($stackPtr - 1)]['code']]) === true) {
+ $stackPtr--;
+ }
+
+ $previous = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ }
+
+ // T_NULLABLE token was introduced in PHPCS 2.7.2. Before that it identified as T_INLINE_THEN.
+ if ((defined('T_NULLABLE') === true && $tokens[$previous]['type'] === 'T_NULLABLE')
+ || (defined('T_NULLABLE') === false && $tokens[$previous]['code'] === T_INLINE_THEN)
+ ) {
+ $phpcsFile->addError(
+ 'Nullable return types are not supported in PHP 7.0 or earlier.',
+ $stackPtr,
+ 'returnTypeFound'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewParamTypeDeclarationsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewParamTypeDeclarationsSniff.php
new file mode 100644
index 0000000..2012f16
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewParamTypeDeclarationsSniff.php
@@ -0,0 +1,195 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\NewParamTypeDeclarationsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewParamTypeDeclarationsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new types.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the keyword appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newTypes = array(
+ 'array' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'self' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'parent' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'callable' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'int' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'float' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'bool' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'string' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'iterable' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'object' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ );
+
+
+ /**
+ * Invalid types
+ *
+ * The array lists : the invalid type hint => what was probably intended/alternative.
+ *
+ * @var array(string => string)
+ */
+ protected $invalidTypes = array(
+ 'static' => 'self',
+ 'boolean' => 'bool',
+ 'integer' => 'int',
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ // Get all parameters from method signature.
+ $paramNames = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($paramNames)) {
+ return;
+ }
+
+ $supportsPHP4 = $this->supportsBelow('4.4');
+
+ foreach ($paramNames as $param) {
+ if ($param['type_hint'] === '') {
+ continue;
+ }
+
+ // Strip off potential nullable indication.
+ $typeHint = ltrim($param['type_hint'], '?');
+
+ if ($supportsPHP4 === true) {
+ $phpcsFile->addError(
+ 'Type declarations were not present in PHP 4.4 or earlier.',
+ $param['token'],
+ 'TypeHintFound'
+ );
+
+ } elseif (isset($this->newTypes[$typeHint])) {
+ $itemInfo = array(
+ 'name' => $typeHint,
+ );
+ $this->handleFeature($phpcsFile, $param['token'], $itemInfo);
+
+ // As of PHP 7.0, using `self` or `parent` outside class scope throws a fatal error.
+ // Only throw this error for PHP 5.2+ as before that the "type hint not supported" error
+ // will be thrown.
+ if (($typeHint === 'self' || $typeHint === 'parent')
+ && $this->inClassScope($phpcsFile, $stackPtr, false) === false
+ && $this->supportsAbove('5.2') !== false
+ ) {
+ $phpcsFile->addError(
+ "'%s' type cannot be used outside of class scope",
+ $param['token'],
+ ucfirst($typeHint) . 'OutsideClassScopeFound',
+ array($typeHint)
+ );
+ }
+ } elseif (isset($this->invalidTypes[$typeHint])) {
+ $error = "'%s' is not a valid type declaration. Did you mean %s ?";
+ $data = array(
+ $typeHint,
+ $this->invalidTypes[$typeHint],
+ );
+
+ $phpcsFile->addError($error, $param['token'], 'InvalidTypeHintFound', $data);
+ }
+ }
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newTypes[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return "'%s' type declaration is not present in PHP version %s or earlier";
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewReturnTypeDeclarationsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewReturnTypeDeclarationsSniff.php
new file mode 100644
index 0000000..0a6f8bd
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NewReturnTypeDeclarationsSniff.php
@@ -0,0 +1,173 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\NewReturnTypeDeclarationsSniff.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewReturnTypeDeclarationsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new types
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the keyword appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newTypes = array(
+ 'int' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'float' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'bool' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'string' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'array' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'callable' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'parent' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'self' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'Class name' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ 'iterable' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'void' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+
+ 'object' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array(
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+
+ if (defined('T_RETURN_TYPE')) {
+ $tokens[] = T_RETURN_TYPE;
+ }
+
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ // Deal with older PHPCS version which don't recognize return type hints
+ // as well as newer PHPCS versions (3.3.0+) where the tokenization has changed.
+ if ($tokens[$stackPtr]['code'] === T_FUNCTION || $tokens[$stackPtr]['code'] === T_CLOSURE) {
+ $returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
+ if ($returnTypeHint !== false) {
+ $stackPtr = $returnTypeHint;
+ }
+ }
+
+ if (isset($this->newTypes[$tokens[$stackPtr]['content']]) === true) {
+ $itemInfo = array(
+ 'name' => $tokens[$stackPtr]['content'],
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+ // Handle class name based return types.
+ elseif ($tokens[$stackPtr]['code'] === T_STRING
+ || (defined('T_RETURN_TYPE') && $tokens[$stackPtr]['code'] === T_RETURN_TYPE)
+ ) {
+ $itemInfo = array(
+ 'name' => 'Class name',
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newTypes[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return '%s return type is not present in PHP version %s or earlier';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NonStaticMagicMethodsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NonStaticMagicMethodsSniff.php
new file mode 100644
index 0000000..4bff99d
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionDeclarations/NonStaticMagicMethodsSniff.php
@@ -0,0 +1,178 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionDeclarations\NonStaticMagicMethodsSniff.
+ *
+ * Verifies the use of the correct visibility and static properties of magic methods.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class NonStaticMagicMethodsSniff extends Sniff
+{
+
+ /**
+ * A list of PHP magic methods and their visibility and static requirements.
+ *
+ * Method names in the array should be all *lowercase*.
+ * Visibility can be either 'public', 'protected' or 'private'.
+ * Static can be either 'true' - *must* be static, or 'false' - *must* be non-static.
+ * When a method does not have a specific requirement for either visibility or static,
+ * do *not* add the key.
+ *
+ * @var array(string)
+ */
+ protected $magicMethods = array(
+ '__get' => array(
+ 'visibility' => 'public',
+ 'static' => false,
+ ),
+ '__set' => array(
+ 'visibility' => 'public',
+ 'static' => false,
+ ),
+ '__isset' => array(
+ 'visibility' => 'public',
+ 'static' => false,
+ ),
+ '__unset' => array(
+ 'visibility' => 'public',
+ 'static' => false,
+ ),
+ '__call' => array(
+ 'visibility' => 'public',
+ 'static' => false,
+ ),
+ '__callstatic' => array(
+ 'visibility' => 'public',
+ 'static' => true,
+ ),
+ '__sleep' => array(
+ 'visibility' => 'public',
+ ),
+ '__tostring' => array(
+ 'visibility' => 'public',
+ ),
+ '__set_state' => array(
+ 'static' => true,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $targets = array(
+ T_CLASS,
+ T_INTERFACE,
+ T_TRAIT,
+ );
+
+ if (defined('T_ANON_CLASS')) {
+ $targets[] = T_ANON_CLASS;
+ }
+
+ return $targets;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ // Should be removed, the requirement was previously also there, 5.3 just started throwing a warning about it.
+ if ($this->supportsAbove('5.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['scope_closer']) === false) {
+ return;
+ }
+
+ $classScopeCloser = $tokens[$stackPtr]['scope_closer'];
+ $functionPtr = $stackPtr;
+
+ // Find all the functions in this class or interface.
+ while (($functionToken = $phpcsFile->findNext(T_FUNCTION, $functionPtr, $classScopeCloser)) !== false) {
+ /*
+ * Get the scope closer for this function in order to know how
+ * to advance to the next function.
+ * If no body of function (e.g. for interfaces), there is
+ * no closing curly brace; advance the pointer differently.
+ */
+ if (isset($tokens[$functionToken]['scope_closer'])) {
+ $scopeCloser = $tokens[$functionToken]['scope_closer'];
+ } else {
+ $scopeCloser = ($functionToken + 1);
+ }
+
+ $methodName = $phpcsFile->getDeclarationName($functionToken);
+ $methodNameLc = strtolower($methodName);
+ if (isset($this->magicMethods[$methodNameLc]) === false) {
+ $functionPtr = $scopeCloser;
+ continue;
+ }
+
+ $methodProperties = $phpcsFile->getMethodProperties($functionToken);
+ $errorCodeBase = $this->stringToErrorCode($methodNameLc);
+
+ if (isset($this->magicMethods[$methodNameLc]['visibility']) && $this->magicMethods[$methodNameLc]['visibility'] !== $methodProperties['scope']) {
+ $error = 'Visibility for magic method %s must be %s. Found: %s';
+ $errorCode = $errorCodeBase . 'MethodVisibility';
+ $data = array(
+ $methodName,
+ $this->magicMethods[$methodNameLc]['visibility'],
+ $methodProperties['scope'],
+ );
+
+ $phpcsFile->addError($error, $functionToken, $errorCode, $data);
+ }
+
+ if (isset($this->magicMethods[$methodNameLc]['static']) && $this->magicMethods[$methodNameLc]['static'] !== $methodProperties['is_static']) {
+ $error = 'Magic method %s cannot be defined as static.';
+ $errorCode = $errorCodeBase . 'MethodStatic';
+ $data = array($methodName);
+
+ if ($this->magicMethods[$methodNameLc]['static'] === true) {
+ $error = 'Magic method %s must be defined as static.';
+ $errorCode = $errorCodeBase . 'MethodNonStatic';
+ }
+
+ $phpcsFile->addError($error, $functionToken, $errorCode, $data);
+ }
+
+ // Advance to next function.
+ $functionPtr = $scopeCloser;
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/NewMagicMethodsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/NewMagicMethodsSniff.php
new file mode 100644
index 0000000..10f018a
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/NewMagicMethodsSniff.php
@@ -0,0 +1,194 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionNameRestrictions;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionNameRestrictions\NewMagicMethodsSniff.
+ *
+ * Warns for non-magic behaviour of magic methods prior to becoming magic.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewMagicMethodsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new magic methods, not considered magic in older versions.
+ *
+ * Method names in the array should be all *lowercase*.
+ * The array lists : version number with false (not magic) or true (magic).
+ * If's sufficient to list the first version where the method became magic.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newMagicMethods = array(
+ '__get' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+
+ '__isset' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ '__unset' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ '__set_state' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+
+ '__callstatic' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ '__invoke' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+
+ '__debuginfo' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+
+ // Special case - only became properly magical in 5.2.0,
+ // before that it was only called for echo and print.
+ '__tostring' => array(
+ '5.1' => false,
+ '5.2' => true,
+ 'message' => 'The method %s() was not truly magical in PHP version %s and earlier. The associated magic functionality will only be called when directly combined with echo or print.',
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_FUNCTION);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $functionName = $phpcsFile->getDeclarationName($stackPtr);
+ $functionNameLc = strtolower($functionName);
+
+ if (isset($this->newMagicMethods[$functionNameLc]) === false) {
+ return;
+ }
+
+ if ($this->inClassScope($phpcsFile, $stackPtr, false) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $functionName,
+ 'nameLc' => $functionNameLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newMagicMethods[$itemInfo['nameLc']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('message');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['error'] = false; // Warning, not error.
+ $errorInfo['message'] = '';
+
+ if (empty($itemArray['message']) === false) {
+ $errorInfo['message'] = $itemArray['message'];
+ }
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The method %s() was not magical in PHP version %s and earlier. The associated magic functionality will not be invoked.';
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error message before it's passed to PHPCS.
+ *
+ * @param string $error The error message which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return string
+ */
+ protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
+ {
+ if ($errorInfo['message'] !== '') {
+ $error = $errorInfo['message'];
+ }
+
+ return $error;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedMagicAutoloadSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedMagicAutoloadSniff.php
new file mode 100644
index 0000000..9da3e1b
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedMagicAutoloadSniff.php
@@ -0,0 +1,80 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionNameRestrictions;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionNameRestrictions\RemovedMagicAutoloadSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class RemovedMagicAutoloadSniff extends Sniff
+{
+ /**
+ * Scopes to look for when testing using validDirectScope
+ *
+ * @var array
+ */
+ private $checkForScopes = array(
+ 'T_CLASS' => true,
+ 'T_ANON_CLASS' => true,
+ 'T_INTERFACE' => true,
+ 'T_TRAIT' => true,
+ 'T_NAMESPACE' => true,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_FUNCTION);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.2') === false) {
+ return;
+ }
+
+ $funcName = $phpcsFile->getDeclarationName($stackPtr);
+
+ if (strtolower($funcName) !== '__autoload') {
+ return;
+ }
+
+ if ($this->validDirectScope($phpcsFile, $stackPtr, $this->checkForScopes) !== false) {
+ return;
+ }
+
+ if ($this->determineNamespace($phpcsFile, $stackPtr) !== '') {
+ return;
+ }
+
+ $phpcsFile->addWarning('Use of __autoload() function is deprecated since PHP 7.2', $stackPtr, 'Found');
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertSniff.php
new file mode 100644
index 0000000..14f4514
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedNamespacedAssertSniff.php
@@ -0,0 +1,92 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionNameRestrictions;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * Removed Namespaced Assert.
+ *
+ * As of PHP 7.3, a compile-time deprecation warning will be thrown when a function
+ * called `assert()` is declared. In PHP 8 this will become a compile-error.
+ *
+ * Methods are unaffected.
+ * Global, non-namespaced, assert() function declarations were always a fatal
+ * "function already declared" error, so not the concern of this sniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedNamespacedAssertSniff extends Sniff
+{
+ /**
+ * Scopes in which an `assert` function can be declared without issue.
+ *
+ * @var array
+ */
+ private $scopes = array(
+ T_CLASS,
+ T_INTERFACE,
+ T_TRAIT,
+ T_CLOSURE,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Enrich the scopes list.
+ if (defined('T_ANON_CLASS')) {
+ $this->scopes[] = T_ANON_CLASS;
+ }
+
+ return array(T_FUNCTION);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.3') === false) {
+ return;
+ }
+
+ $funcName = $phpcsFile->getDeclarationName($stackPtr);
+
+ if (strtolower($funcName) !== 'assert') {
+ return;
+ }
+
+ if ($phpcsFile->hasCondition($stackPtr, $this->scopes) === true) {
+ return;
+ }
+
+ if ($this->determineNamespace($phpcsFile, $stackPtr) === '') {
+ // Not a namespaced function declaration. Parse error, but not our concern.
+ return;
+ }
+
+ $phpcsFile->addWarning('Declaring a free-standing function called assert() is deprecated since PHP 7.3.', $stackPtr, 'Found');
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedPHP4StyleConstructorsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedPHP4StyleConstructorsSniff.php
new file mode 100644
index 0000000..7fc42d5
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/RemovedPHP4StyleConstructorsSniff.php
@@ -0,0 +1,135 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionNameRestrictions;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionNameRestrictions\RemovedPHP4StyleConstructorsSniff.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Koen Eelen
+ */
+class RemovedPHP4StyleConstructorsSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_CLASS,
+ T_INTERFACE,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ if ($this->determineNamespace($phpcsFile, $stackPtr) !== '') {
+ /*
+ * Namespaced methods with the same name as the class are treated as
+ * regular methods, so we can bow out if we're in a namespace.
+ *
+ * Note: the exception to this is PHP 5.3.0-5.3.2. This is currently
+ * not dealt with.
+ */
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ $class = $tokens[$stackPtr];
+
+ if (isset($class['scope_closer']) === false) {
+ return;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_STRING) {
+ // Anonymous class in combination with PHPCS 2.3.x.
+ return;
+ }
+
+ $scopeCloser = $class['scope_closer'];
+ $className = $tokens[$nextNonEmpty]['content'];
+
+ if (empty($className) || is_string($className) === false) {
+ return;
+ }
+
+ $nextFunc = $stackPtr;
+ $classNameLc = strtolower($className);
+ $newConstructorFound = false;
+ $oldConstructorFound = false;
+ $oldConstructorPos = -1;
+ while (($nextFunc = $phpcsFile->findNext(T_FUNCTION, ($nextFunc + 1), $scopeCloser)) !== false) {
+ $functionScopeCloser = $nextFunc;
+ if (isset($tokens[$nextFunc]['scope_closer'])) {
+ // Normal (non-interface, non-abstract) method.
+ $functionScopeCloser = $tokens[$nextFunc]['scope_closer'];
+ }
+
+ $funcName = $phpcsFile->getDeclarationName($nextFunc);
+ if (empty($funcName) || is_string($funcName) === false) {
+ $nextFunc = $functionScopeCloser;
+ continue;
+ }
+
+ $funcNameLc = strtolower($funcName);
+
+ if ($funcNameLc === '__construct') {
+ $newConstructorFound = true;
+ }
+
+ if ($funcNameLc === $classNameLc) {
+ $oldConstructorFound = true;
+ $oldConstructorPos = $nextFunc;
+ }
+
+ // If both have been found, no need to continue looping through the functions.
+ if ($newConstructorFound === true && $oldConstructorFound === true) {
+ break;
+ }
+
+ $nextFunc = $functionScopeCloser;
+ }
+
+ if ($newConstructorFound === false && $oldConstructorFound === true) {
+ $phpcsFile->addWarning(
+ 'Use of deprecated PHP4 style class constructor is not supported since PHP 7.',
+ $oldConstructorPos,
+ 'Found'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/ReservedFunctionNamesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/ReservedFunctionNamesSniff.php
new file mode 100644
index 0000000..a63413e
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionNameRestrictions/ReservedFunctionNamesSniff.php
@@ -0,0 +1,144 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionNameRestrictions;
+
+use Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff as PHPCS_CamelCapsFunctionNameSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Standards_AbstractScopeSniff as PHPCS_AbstractScopeSniff;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionNameRestrictions\ReservedFunctionNamesSniff.
+ *
+ * All function and method names starting with double underscore are reserved by PHP.
+ *
+ * {@internal Extends an upstream sniff to benefit from the properties contained therein.
+ * The properties are lists of valid PHP magic function and method names, which
+ * should be ignored for the purposes of this sniff.
+ * As this sniff is not PHP version specific, we don't need access to the utility
+ * methods in the PHPCompatibility\Sniff, so extending the upstream sniff is fine.
+ * As the upstream sniff checks the same (and more, but we don't need the rest),
+ * the logic in this sniff is largely the same as used upstream.
+ * Extending the upstream sniff instead of including it via the ruleset, however,
+ * prevents hard to debug issues of errors not being reported from the upstream sniff
+ * if this library is used in combination with other rulesets.}}
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ReservedFunctionNamesSniff extends PHPCS_CamelCapsFunctionNameSniff
+{
+
+ /**
+ * Overload the constructor to work round various PHPCS cross-version compatibility issues.
+ */
+ public function __construct()
+ {
+ $scopeTokens = array(T_CLASS, T_INTERFACE, T_TRAIT);
+ if (defined('T_ANON_CLASS')) {
+ $scopeTokens[] = T_ANON_CLASS;
+ }
+
+ // Call the grand-parent constructor directly.
+ PHPCS_AbstractScopeSniff::__construct($scopeTokens, array(T_FUNCTION), true);
+
+ // Make sure debuginfo is included in the array. Upstream only includes it since 2.5.1.
+ $this->magicMethods['debuginfo'] = true;
+ }
+
+
+ /**
+ * Processes the tokens within the scope.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being processed.
+ * @param int $stackPtr The position where this token was
+ * found.
+ * @param int $currScope The position of the current scope.
+ *
+ * @return void
+ */
+ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ /*
+ * Determine if this is a function which needs to be examined.
+ * The `processTokenWithinScope()` is called for each valid scope a method is in,
+ * so for nested classes, we need to make sure we only examine the token for
+ * the lowest level valid scope.
+ */
+ $conditions = $tokens[$stackPtr]['conditions'];
+ end($conditions);
+ $deepestScope = key($conditions);
+ if ($deepestScope !== $currScope) {
+ return;
+ }
+
+ $methodName = $phpcsFile->getDeclarationName($stackPtr);
+ if ($methodName === null) {
+ // Ignore closures.
+ return;
+ }
+
+ // Is this a magic method. i.e., is prefixed with "__" ?
+ if (preg_match('|^__[^_]|', $methodName) > 0) {
+ $magicPart = strtolower(substr($methodName, 2));
+ if (isset($this->magicMethods[$magicPart]) === false
+ && isset($this->methodsDoubleUnderscore[$magicPart]) === false
+ ) {
+ $className = '[anonymous class]';
+ $scopeNextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($currScope + 1), null, true);
+ if ($scopeNextNonEmpty !== false && $tokens[$scopeNextNonEmpty]['code'] === T_STRING) {
+ $className = $tokens[$scopeNextNonEmpty]['content'];
+ }
+
+ $phpcsFile->addWarning(
+ 'Method name "%s" is discouraged; PHP has reserved all method names with a double underscore prefix for future use.',
+ $stackPtr,
+ 'MethodDoubleUnderscore',
+ array($className . '::' . $methodName)
+ );
+ }
+ }
+ }
+
+
+ /**
+ * Processes the tokens outside the scope.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being processed.
+ * @param int $stackPtr The position where this token was
+ * found.
+ *
+ * @return void
+ */
+ protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
+ {
+ $functionName = $phpcsFile->getDeclarationName($stackPtr);
+ if ($functionName === null) {
+ // Ignore closures.
+ return;
+ }
+
+ // Is this a magic function. i.e., it is prefixed with "__".
+ if (preg_match('|^__[^_]|', $functionName) > 0) {
+ $magicPart = strtolower(substr($functionName, 2));
+ if (isset($this->magicFunctions[$magicPart]) === false) {
+ $phpcsFile->addWarning(
+ 'Function name "%s" is discouraged; PHP has reserved all method names with a double underscore prefix for future use.',
+ $stackPtr,
+ 'FunctionDoubleUnderscore',
+ array($functionName)
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/ArgumentFunctionsReportCurrentValueSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/ArgumentFunctionsReportCurrentValueSniff.php
new file mode 100644
index 0000000..a8989dc
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/ArgumentFunctionsReportCurrentValueSniff.php
@@ -0,0 +1,439 @@
+ true,
+ 'func_get_args' => true,
+ 'debug_backtrace' => true,
+ 'debug_print_backtrace' => true,
+ );
+
+ /**
+ * Tokens to look out for to allow us to skip past nested scoped structures.
+ *
+ * @var array
+ */
+ private $skipPastNested = array(
+ 'T_CLASS' => true,
+ 'T_ANON_CLASS' => true,
+ 'T_INTERFACE' => true,
+ 'T_TRAIT' => true,
+ 'T_FUNCTION' => true,
+ 'T_CLOSURE' => true,
+ );
+
+ /**
+ * List of tokens which when they preceed a T_STRING *within a function* indicate
+ * this is not a call to a PHP native function.
+ *
+ * This list already takes into account that nested scoped structures are being
+ * skipped over, so doesn't check for those again.
+ * Similarly, as constants won't have parentheses, those don't need to be checked
+ * for either.
+ *
+ * @var array
+ */
+ private $noneFunctionCallIndicators = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ );
+
+ /**
+ * The tokens for variable incrementing/decrementing.
+ *
+ * @var array
+ */
+ private $plusPlusMinusMinus = array(
+ T_DEC => true,
+ T_INC => true,
+ );
+
+ /**
+ * Tokens to ignore when determining the start of a statement.
+ *
+ * @var array
+ */
+ private $ignoreForStartOfStatement = array(
+ T_COMMA,
+ T_DOUBLE_ARROW,
+ T_OPEN_SQUARE_BRACKET,
+ T_OPEN_PARENTHESIS,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
+ // Abstract function, interface function, live coding or parse error.
+ return;
+ }
+
+ $scopeOpener = $tokens[$stackPtr]['scope_opener'];
+ $scopeCloser = $tokens[$stackPtr]['scope_closer'];
+
+ // Does the function declaration have parameters ?
+ $params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($params)) {
+ // No named arguments found, so no risk of them being changed.
+ return;
+ }
+
+ $paramNames = array();
+ foreach ($params as $param) {
+ $paramNames[] = $param['name'];
+ }
+
+ for ($i = ($scopeOpener + 1); $i < $scopeCloser; $i++) {
+ if (isset($this->skipPastNested[$tokens[$i]['type']]) && isset($tokens[$i]['scope_closer'])) {
+ // Skip past nested structures.
+ $i = $tokens[$i]['scope_closer'];
+ continue;
+ }
+
+ if ($tokens[$i]['code'] !== T_STRING) {
+ continue;
+ }
+
+ $foundFunctionName = strtolower($tokens[$i]['content']);
+
+ if (isset($this->changedFunctions[$foundFunctionName]) === false) {
+ // Not one of the target functions.
+ continue;
+ }
+
+ /*
+ * Ok, so is this really a function call to one of the PHP native functions ?
+ */
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
+ if ($next === false || $tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
+ // Live coding, parse error or not a function call.
+ continue;
+ }
+
+ $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($i - 1), null, true);
+ if ($prev !== false) {
+ if (isset($this->noneFunctionCallIndicators[$tokens[$prev]['code']])) {
+ continue;
+ }
+
+ // Check for namespaced functions, ie: \foo\bar() not \bar().
+ if ($tokens[ $prev ]['code'] === T_NS_SEPARATOR) {
+ $pprev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prev - 1), null, true);
+ if ($pprev !== false && $tokens[ $pprev ]['code'] === T_STRING) {
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Address some special cases.
+ */
+ if ($foundFunctionName !== 'func_get_args') {
+ $paramOne = $this->getFunctionCallParameter($phpcsFile, $i, 1);
+ if ($paramOne !== false) {
+ switch ($foundFunctionName) {
+ /*
+ * Check if `debug_(print_)backtrace()` is called with the
+ * `DEBUG_BACKTRACE_IGNORE_ARGS` option.
+ */
+ case 'debug_backtrace':
+ case 'debug_print_backtrace':
+ $hasIgnoreArgs = $phpcsFile->findNext(
+ T_STRING,
+ $paramOne['start'],
+ ($paramOne['end'] + 1),
+ false,
+ 'DEBUG_BACKTRACE_IGNORE_ARGS'
+ );
+
+ if ($hasIgnoreArgs !== false) {
+ // Debug_backtrace() called with ignore args option.
+ continue 2;
+ }
+ break;
+
+ /*
+ * Collect the necessary information to only throw a notice if the argument
+ * touched/changed is in line with the passed $arg_num.
+ *
+ * Also, we can ignore `func_get_arg()` if the argument offset passed is
+ * higher than the number of named parameters.
+ *
+ * {@internal Note: This does not take calculations into account!
+ * Should be exceptionally rare and can - if needs be - be addressed at a later stage.}}
+ */
+ case 'func_get_arg':
+ $number = $phpcsFile->findNext(T_LNUMBER, $paramOne['start'], ($paramOne['end'] + 1));
+ if ($number !== false) {
+ $argNumber = $tokens[$number]['content'];
+
+ if (isset($paramNames[$argNumber]) === false) {
+ // Requesting a non-named additional parameter. Ignore.
+ continue 2;
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ /*
+ * Check if the call to func_get_args() happens to be in an array_slice() or
+ * array_splice() with an $offset higher than the number of named parameters.
+ * In that case, we can ignore it.
+ *
+ * {@internal Note: This does not take offset calculations into account!
+ * Should be exceptionally rare and can - if needs be - be addressed at a later stage.}}
+ */
+ if ($prev !== false && $tokens[$prev]['code'] === T_OPEN_PARENTHESIS) {
+
+ $maybeFunctionCall = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prev - 1), null, true);
+ if ($maybeFunctionCall !== false
+ && $tokens[$maybeFunctionCall]['code'] === T_STRING
+ && ($tokens[$maybeFunctionCall]['content'] === 'array_slice'
+ || $tokens[$maybeFunctionCall]['content'] === 'array_splice')
+ ) {
+ $parentFuncParamTwo = $this->getFunctionCallParameter($phpcsFile, $maybeFunctionCall, 2);
+ $number = $phpcsFile->findNext(
+ T_LNUMBER,
+ $parentFuncParamTwo['start'],
+ ($parentFuncParamTwo['end'] + 1)
+ );
+
+ if ($number !== false && isset($paramNames[$tokens[$number]['content']]) === false) {
+ // Requesting non-named additional parameters. Ignore.
+ continue ;
+ }
+
+ // Slice starts at a named argument, but we know which params are being accessed.
+ $paramNamesSubset = array_slice($paramNames, $tokens[$number]['content']);
+ }
+ }
+ }
+
+ /*
+ * For debug_backtrace(), check if the result is being dereferenced and if so,
+ * whether the `args` index is used.
+ * I.e. whether `$index` in `debug_backtrace()[$stackFrame][$index]` is a string
+ * with the content `args`.
+ *
+ * Note: We already know that $next is the open parenthesis of the function call.
+ */
+ if ($foundFunctionName === 'debug_backtrace' && isset($tokens[$next]['parenthesis_closer'])) {
+ $afterParenthesis = $phpcsFile->findNext(
+ Tokens::$emptyTokens,
+ ($tokens[$next]['parenthesis_closer'] + 1),
+ null,
+ true
+ );
+
+ if ($tokens[$afterParenthesis]['code'] === T_OPEN_SQUARE_BRACKET
+ && isset($tokens[$afterParenthesis]['bracket_closer'])
+ ) {
+ $afterStackFrame = $phpcsFile->findNext(
+ Tokens::$emptyTokens,
+ ($tokens[$afterParenthesis]['bracket_closer'] + 1),
+ null,
+ true
+ );
+
+ if ($tokens[$afterStackFrame]['code'] === T_OPEN_SQUARE_BRACKET
+ && isset($tokens[$afterStackFrame]['bracket_closer'])
+ ) {
+ $arrayIndex = $phpcsFile->findNext(
+ T_CONSTANT_ENCAPSED_STRING,
+ ($afterStackFrame + 1),
+ $tokens[$afterStackFrame]['bracket_closer']
+ );
+
+ if ($arrayIndex !== false && $this->stripQuotes($tokens[$arrayIndex]['content']) !== 'args') {
+ continue;
+ }
+ }
+ }
+ }
+
+ /*
+ * Only check for variables before the start of the statement to
+ * prevent false positives on the return value of the function call
+ * being assigned to one of the parameters, i.e.:
+ * `$param = func_get_args();`.
+ */
+ $startOfStatement = PHPCSHelper::findStartOfStatement($phpcsFile, $i, $this->ignoreForStartOfStatement);
+
+ /*
+ * Ok, so we've found one of the target functions in the right scope.
+ * Now, let's check if any of the passed parameters were touched.
+ */
+ $scanResult = 'clean';
+ for ($j = ($scopeOpener + 1); $j < $startOfStatement; $j++) {
+ if (isset($this->skipPastNested[$tokens[$j]['type']])
+ && isset($tokens[$j]['scope_closer'])
+ ) {
+ // Skip past nested structures.
+ $j = $tokens[$j]['scope_closer'];
+ continue;
+ }
+
+ if ($tokens[$j]['code'] !== T_VARIABLE) {
+ continue;
+ }
+
+ if ($foundFunctionName === 'func_get_arg' && isset($argNumber)) {
+ if (isset($paramNames[$argNumber])
+ && $tokens[$j]['content'] !== $paramNames[$argNumber]
+ ) {
+ // Different param than the one requested by func_get_arg().
+ continue;
+ }
+ } elseif ($foundFunctionName === 'func_get_args' && isset($paramNamesSubset)) {
+ if (in_array($tokens[$j]['content'], $paramNamesSubset, true) === false) {
+ // Different param than the ones requested by func_get_args().
+ continue;
+ }
+ } elseif (in_array($tokens[$j]['content'], $paramNames, true) === false) {
+ // Variable is not one of the function parameters.
+ continue;
+ }
+
+ /*
+ * Ok, so we've found a variable which was passed as one of the parameters.
+ * Now, is this variable being changed, i.e. incremented, decremented or
+ * assigned something ?
+ */
+ $scanResult = 'warning';
+ if (isset($variableToken) === false) {
+ $variableToken = $j;
+ }
+
+ $beforeVar = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($j - 1), null, true);
+ if ($beforeVar !== false && isset($this->plusPlusMinusMinus[$tokens[$beforeVar]['code']])) {
+ // Variable is being (pre-)incremented/decremented.
+ $scanResult = 'error';
+ $variableToken = $j;
+ break;
+ }
+
+ $afterVar = $phpcsFile->findNext(Tokens::$emptyTokens, ($j + 1), null, true);
+ if ($afterVar === false) {
+ // Shouldn't be possible, but just in case.
+ continue;
+ }
+
+ if (isset($this->plusPlusMinusMinus[$tokens[$afterVar]['code']])) {
+ // Variable is being (post-)incremented/decremented.
+ $scanResult = 'error';
+ $variableToken = $j;
+ break;
+ }
+
+ if ($tokens[$afterVar]['code'] === T_OPEN_SQUARE_BRACKET
+ && isset($tokens[$afterVar]['bracket_closer'])
+ ) {
+ // Skip past array access on the variable.
+ while (($afterVar = $phpcsFile->findNext(Tokens::$emptyTokens, ($tokens[$afterVar]['bracket_closer'] + 1), null, true)) !== false) {
+ if ($tokens[$afterVar]['code'] !== T_OPEN_SQUARE_BRACKET
+ || isset($tokens[$afterVar]['bracket_closer']) === false
+ ) {
+ break;
+ }
+ }
+ }
+
+ if ($afterVar !== false
+ && isset(Tokens::$assignmentTokens[$tokens[$afterVar]['code']])
+ ) {
+ // Variable is being assigned something.
+ $scanResult = 'error';
+ $variableToken = $j;
+ break;
+ }
+ }
+
+ unset($argNumber, $paramNamesSubset);
+
+ if ($scanResult === 'clean') {
+ continue;
+ }
+
+ $error = 'Since PHP 7.0, functions inspecting arguments, like %1$s(), no longer report the original value as passed to a parameter, but will instead provide the current value. The parameter "%2$s" was %4$s on line %3$s.';
+ $data = array(
+ $foundFunctionName,
+ $tokens[$variableToken]['content'],
+ $tokens[$variableToken]['line'],
+ );
+
+ if ($scanResult === 'error') {
+ $data[] = 'changed';
+ $phpcsFile->addError($error, $i, 'Changed', $data);
+
+ } elseif ($scanResult === 'warning') {
+ $data[] = 'used, and possibly changed (by reference),';
+ $phpcsFile->addWarning($error, $i, 'NeedsInspection', $data);
+ }
+
+ unset($variableToken);
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/ArgumentFunctionsUsageSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/ArgumentFunctionsUsageSniff.php
new file mode 100644
index 0000000..89ea8d8
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/ArgumentFunctionsUsageSniff.php
@@ -0,0 +1,164 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\ArgumentFunctionsUsageSniff.
+ *
+ * - Prior to PHP 5.3, these functions could not be used as a function call parameter.
+ *
+ * - Calling these functions from the outermost scope of a file which has been included by
+ * calling `include` or `require` from within a function in the calling file, worked
+ * prior to PHP 5.3. As of PHP 5.3, this will generate a warning and will always return false/-1.
+ * If the file was called directly or included in the global scope, calls to these
+ * functions would already generate a warning prior to PHP 5.3.
+ *
+ * PHP version 5.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ArgumentFunctionsUsageSniff extends Sniff
+{
+
+ /**
+ * The target functions for this sniff.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'func_get_args' => true,
+ 'func_get_arg' => true,
+ 'func_num_args' => true,
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $functionLc = strtolower($tokens[$stackPtr]['content']);
+ if (isset($this->targetFunctions[$functionLc]) === false) {
+ return;
+ }
+
+ // Next non-empty token should be the open parenthesis.
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_OPEN_PARENTHESIS) {
+ return;
+ }
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_NEW => true,
+ );
+
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevNonEmpty]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ } elseif ($tokens[$prevNonEmpty]['code'] === T_NS_SEPARATOR && $tokens[$prevNonEmpty - 1]['code'] === T_STRING) {
+ // Namespaced function.
+ return;
+ }
+
+ $data = $tokens[$stackPtr]['content'];
+
+ /*
+ * Check for usage of the functions in the global scope.
+ *
+ * As PHPCS can not determine whether a file is included from within a function in
+ * another file, so always throw a warning/error.
+ */
+ if ($phpcsFile->hasCondition($stackPtr, array(T_FUNCTION, T_CLOSURE)) === false) {
+ $isError = false;
+ $message = 'Use of %s() outside of a user-defined function is only supported if the file is included from within a user-defined function in another file prior to PHP 5.3.';
+
+ if ($this->supportsAbove('5.3') === true) {
+ $isError = true;
+ $message .= ' As of PHP 5.3, it is no longer supported at all.';
+ }
+
+ $this->addMessage($phpcsFile, $message, $stackPtr, $isError, 'OutsideFunctionScope', $data);
+ }
+
+ /*
+ * Check for usage of the functions as a parameter in a function call.
+ */
+ if ($this->supportsBelow('5.2') === false) {
+ return;
+ }
+
+ if (isset($tokens[$stackPtr]['nested_parenthesis']) === false) {
+ return;
+ }
+
+ $throwError = false;
+
+ $closer = end($tokens[$stackPtr]['nested_parenthesis']);
+ if (isset($tokens[$closer]['parenthesis_owner'])
+ && $tokens[$tokens[$closer]['parenthesis_owner']]['type'] === 'T_CLOSURE'
+ ) {
+ $throwError = true;
+ } else {
+ $opener = key($tokens[$stackPtr]['nested_parenthesis']);
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($opener - 1), null, true);
+ if ($tokens[$prevNonEmpty]['code'] !== T_STRING) {
+ return;
+ }
+
+ $prevPrevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prevNonEmpty - 1), null, true);
+ if ($tokens[$prevPrevNonEmpty]['code'] === T_FUNCTION) {
+ return;
+ }
+
+ $throwError = true;
+ }
+
+ if ($throwError === false) {
+ return;
+ }
+
+ $phpcsFile->addError(
+ '%s() could not be used in parameter lists prior to PHP 5.3.',
+ $stackPtr,
+ 'InParameterList',
+ $data
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/NewFunctionParametersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/NewFunctionParametersSniff.php
new file mode 100644
index 0000000..4dcff8e
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/NewFunctionParametersSniff.php
@@ -0,0 +1,1074 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\newFunctionParametersSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewFunctionParametersSniff extends AbstractNewFeatureSniff
+{
+ /**
+ * A list of new functions, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * The index is the location of the parameter in the parameter list, starting at 0 !
+ * If's sufficient to list the first version where the function appears.
+ *
+ * @var array
+ */
+ protected $newFunctionParameters = array(
+ 'array_filter' => array(
+ 2 => array(
+ 'name' => 'flag',
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ ),
+ 'array_slice' => array(
+ 1 => array(
+ 'name' => 'preserve_keys',
+ '5.0.1' => false,
+ '5.0.2' => true,
+ ),
+ ),
+ 'array_unique' => array(
+ 1 => array(
+ 'name' => 'sort_flags',
+ '5.2.8' => false,
+ '5.2.9' => true,
+ ),
+ ),
+ 'assert' => array(
+ 1 => array(
+ 'name' => 'description',
+ '5.4.7' => false,
+ '5.4.8' => true,
+ ),
+ ),
+ 'base64_decode' => array(
+ 1 => array(
+ 'name' => 'strict',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'bcmod' => array(
+ 2 => array(
+ 'name' => 'scale',
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ ),
+ 'class_implements' => array(
+ 1 => array(
+ 'name' => 'autoload',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'class_parents' => array(
+ 1 => array(
+ 'name' => 'autoload',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'clearstatcache' => array(
+ 0 => array(
+ 'name' => 'clear_realpath_cache',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 1 => array(
+ 'name' => 'filename',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'copy' => array(
+ 2 => array(
+ 'name' => 'context',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'curl_multi_info_read' => array(
+ 1 => array(
+ 'name' => 'msgs_in_queue',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'debug_backtrace' => array(
+ 0 => array(
+ 'name' => 'options',
+ '5.2.4' => false,
+ '5.2.5' => true,
+ ),
+ 1 => array(
+ 'name' => 'limit',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'debug_print_backtrace' => array(
+ 0 => array(
+ 'name' => 'options',
+ '5.3.5' => false,
+ '5.3.6' => true,
+ ),
+ 1 => array(
+ 'name' => 'limit',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'dirname' => array(
+ 1 => array(
+ 'name' => 'levels',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'dns_get_record' => array(
+ 4 => array(
+ 'name' => 'raw',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'fgetcsv' => array(
+ 4 => array(
+ 'name' => 'escape',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'fputcsv' => array(
+ 4 => array(
+ 'name' => 'escape_char',
+ '5.5.3' => false,
+ '5.5.4' => true,
+ ),
+ ),
+ 'file_get_contents' => array(
+ 3 => array(
+ 'name' => 'offset',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 4 => array(
+ 'name' => 'maxlen',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'filter_input_array' => array(
+ 2 => array(
+ 'name' => 'add_empty',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'filter_var_array' => array(
+ 2 => array(
+ 'name' => 'add_empty',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'getenv' => array(
+ 1 => array(
+ 'name' => 'local_only',
+ '5.5.37' => false,
+ '5.5.38' => true, // Also introduced in PHP 5.6.24 and 7.0.9.
+ ),
+ ),
+ 'getopt' => array(
+ 2 => array(
+ 'name' => 'optind',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'gettimeofday' => array(
+ 0 => array(
+ 'name' => 'return_float',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'get_defined_functions' => array(
+ 0 => array(
+ 'name' => 'exclude_disabled',
+ '7.0.14' => false,
+ '7.0.15' => true,
+ ),
+ ),
+ 'get_headers' => array(
+ 2 => array(
+ 'name' => 'context',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'get_html_translation_table' => array(
+ 2 => array(
+ 'name' => 'encoding',
+ '5.3.3' => false,
+ '5.3.4' => true,
+ ),
+ ),
+ 'get_loaded_extensions' => array(
+ 0 => array(
+ 'name' => 'zend_extensions',
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ ),
+ 'gzcompress' => array(
+ 2 => array(
+ 'name' => 'encoding',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'gzdeflate' => array(
+ 2 => array(
+ 'name' => 'encoding',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'htmlentities' => array(
+ 3 => array(
+ 'name' => 'double_encode',
+ '5.2.2' => false,
+ '5.2.3' => true,
+ ),
+ ),
+ 'htmlspecialchars' => array(
+ 3 => array(
+ 'name' => 'double_encode',
+ '5.2.2' => false,
+ '5.2.3' => true,
+ ),
+ ),
+ 'http_build_query' => array(
+ 2 => array(
+ 'name' => 'arg_separator',
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 3 => array(
+ 'name' => 'enc_type',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'idn_to_ascii' => array(
+ 2 => array(
+ 'name' => 'variant',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 3 => array(
+ 'name' => 'idna_info',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'idn_to_utf8' => array(
+ 2 => array(
+ 'name' => 'variant',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 3 => array(
+ 'name' => 'idna_info',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'imagecolorset' => array(
+ 5 => array(
+ 'name' => 'alpha',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'imagepng' => array(
+ 2 => array(
+ 'name' => 'quality',
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 3 => array(
+ 'name' => 'filters',
+ '5.1.2' => false,
+ '5.1.3' => true,
+ ),
+ ),
+ 'imagerotate' => array(
+ 3 => array(
+ 'name' => 'ignore_transparent',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'imap_open' => array(
+ 4 => array(
+ 'name' => 'n_retries',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 5 => array(
+ 'name' => 'params',
+ '5.3.1' => false,
+ '5.3.2' => true,
+ ),
+ ),
+ 'imap_reopen' => array(
+ 3 => array(
+ 'name' => 'n_retries',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'ini_get_all' => array(
+ 1 => array(
+ 'name' => 'details',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'is_a' => array(
+ 2 => array(
+ 'name' => 'allow_string',
+ '5.3.8' => false,
+ '5.3.9' => true,
+ ),
+ ),
+ 'is_subclass_of' => array(
+ 2 => array(
+ 'name' => 'allow_string',
+ '5.3.8' => false,
+ '5.3.9' => true,
+ ),
+ ),
+ 'iterator_to_array' => array(
+ 1 => array(
+ 'name' => 'use_keys',
+ '5.2.0' => false,
+ '5.2.1' => true,
+ ),
+ ),
+ 'json_decode' => array(
+ 2 => array(
+ 'name' => 'depth',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 3 => array(
+ 'name' => 'options',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'json_encode' => array(
+ 1 => array(
+ 'name' => 'options',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 2 => array(
+ 'name' => 'depth',
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ ),
+ 'ldap_add' => array(
+ 3 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_compare' => array(
+ 4 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_delete' => array(
+ 2 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_list' => array(
+ 8 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_mod_add' => array(
+ 3 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_mod_del' => array(
+ 3 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_mod_replace' => array(
+ 3 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_modify_batch' => array(
+ 3 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_parse_result' => array(
+ 6 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_read' => array(
+ 8 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_rename' => array(
+ 5 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'ldap_search' => array(
+ 8 => array(
+ 'name' => 'serverctrls',
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ ),
+ 'memory_get_peak_usage' => array(
+ 0 => array(
+ 'name' => 'real_usage',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'memory_get_usage' => array(
+ 0 => array(
+ 'name' => 'real_usage',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'mb_encode_numericentity' => array(
+ 3 => array(
+ 'name' => 'is_hex',
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ ),
+ 'mb_strrpos' => array(
+ /*
+ * Note: the actual position is 2, but the original 3rd
+ * parameter 'encoding' was moved to the 4th position.
+ * So the only way to detect if offset is used is when
+ * both offset and encoding are set.
+ */
+ 3 => array(
+ 'name' => 'offset',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'mssql_connect' => array(
+ 3 => array(
+ 'name' => 'new_link',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'mysqli_commit' => array(
+ 1 => array(
+ 'name' => 'flags',
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 2 => array(
+ 'name' => 'name',
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ ),
+ 'mysqli_rollback' => array(
+ 1 => array(
+ 'name' => 'flags',
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 2 => array(
+ 'name' => 'name',
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ ),
+ 'nl2br' => array(
+ 1 => array(
+ 'name' => 'is_xhtml',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'openssl_decrypt' => array(
+ 4 => array(
+ 'name' => 'iv',
+ '5.3.2' => false,
+ '5.3.3' => true,
+ ),
+ 5 => array(
+ 'name' => 'tag',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 6 => array(
+ 'name' => 'aad',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'openssl_encrypt' => array(
+ 4 => array(
+ 'name' => 'iv',
+ '5.3.2' => false,
+ '5.3.3' => true,
+ ),
+ 5 => array(
+ 'name' => 'tag',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 6 => array(
+ 'name' => 'aad',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 7 => array(
+ 'name' => 'tag_length',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'openssl_open' => array(
+ 4 => array(
+ 'name' => 'method',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 5 => array(
+ 'name' => 'iv',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'openssl_pkcs7_verify' => array(
+ 5 => array(
+ 'name' => 'content',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 6 => array(
+ 'name' => 'p7bfilename',
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ ),
+ 'openssl_seal' => array(
+ 4 => array(
+ 'name' => 'method',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 5 => array(
+ 'name' => 'iv',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'openssl_verify' => array(
+ 3 => array(
+ 'name' => 'signature_alg',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'parse_ini_file' => array(
+ 2 => array(
+ 'name' => 'scanner_mode',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'parse_url' => array(
+ 1 => array(
+ 'name' => 'component',
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ ),
+ 'pg_fetch_all' => array(
+ 1 => array(
+ 'name' => 'result_type',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'pg_last_notice' => array(
+ 1 => array(
+ 'name' => 'option',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'pg_lo_create' => array(
+ 1 => array(
+ 'name' => 'object_id',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'pg_lo_import' => array(
+ 2 => array(
+ 'name' => 'object_id',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'pg_select' => array(
+ 4 => array(
+ 'name' => 'result_type',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'php_uname' => array(
+ 0 => array(
+ 'name' => 'mode',
+ '4.2' => false,
+ '4.3' => true,
+ ),
+ ),
+ 'preg_replace' => array(
+ 4 => array(
+ 'name' => 'count',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'preg_replace_callback' => array(
+ 4 => array(
+ 'name' => 'count',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'round' => array(
+ 2 => array(
+ 'name' => 'mode',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'sem_acquire' => array(
+ 1 => array(
+ 'name' => 'nowait',
+ '5.6' => false,
+ '5.6.1' => true,
+ ),
+ ),
+ 'session_regenerate_id' => array(
+ 0 => array(
+ 'name' => 'delete_old_session',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'session_set_cookie_params' => array(
+ 4 => array(
+ 'name' => 'httponly',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'session_set_save_handler' => array(
+ 6 => array(
+ 'name' => 'create_sid',
+ '5.5.0' => false,
+ '5.5.1' => true,
+ ),
+ 7 => array(
+ 'name' => 'validate_sid',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 8 => array(
+ 'name' => 'update_timestamp',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'session_start' => array(
+ 0 => array(
+ 'name' => 'options',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'setcookie' => array(
+ 6 => array(
+ 'name' => 'httponly',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'setrawcookie' => array(
+ 6 => array(
+ 'name' => 'httponly',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'simplexml_load_file' => array(
+ 4 => array(
+ 'name' => 'is_prefix',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'simplexml_load_string' => array(
+ 4 => array(
+ 'name' => 'is_prefix',
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ ),
+ 'spl_autoload_register' => array(
+ 2 => array(
+ 'name' => 'prepend',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'stream_context_create' => array(
+ 1 => array(
+ 'name' => 'params',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'stream_copy_to_stream' => array(
+ 3 => array(
+ 'name' => 'offset',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'stream_get_contents' => array(
+ 2 => array(
+ 'name' => 'offset',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'stream_wrapper_register' => array(
+ 2 => array(
+ 'name' => 'flags',
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+ ),
+ 'stristr' => array(
+ 2 => array(
+ 'name' => 'before_needle',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'strstr' => array(
+ 2 => array(
+ 'name' => 'before_needle',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'str_word_count' => array(
+ 2 => array(
+ 'name' => 'charlist',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'substr_count' => array(
+ 2 => array(
+ 'name' => 'offset',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 3 => array(
+ 'name' => 'length',
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ ),
+ 'sybase_connect' => array(
+ 5 => array(
+ 'name' => 'new',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'timezone_transitions_get' => array(
+ 1 => array(
+ 'name' => 'timestamp_begin',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 2 => array(
+ 'name' => 'timestamp_end',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'timezone_identifiers_list' => array(
+ 0 => array(
+ 'name' => 'what',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 1 => array(
+ 'name' => 'country',
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ ),
+ 'token_get_all' => array(
+ 1 => array(
+ 'name' => 'flags',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'ucwords' => array(
+ 1 => array(
+ 'name' => 'delimiters',
+ '5.4.31' => false,
+ '5.5.15' => false,
+ '5.4.32' => true,
+ '5.5.16' => true,
+ ),
+ ),
+ 'unpack' => array(
+ 2 => array(
+ 'name' => 'offset',
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ ),
+ 'unserialize' => array(
+ 1 => array(
+ 'name' => 'options',
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->newFunctionParameters = $this->arrayKeysToLowercase($this->newFunctionParameters);
+
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if (isset($this->newFunctionParameters[$functionLc]) === false) {
+ return;
+ }
+
+ $parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr);
+ if ($parameterCount === 0) {
+ return;
+ }
+
+ // If the parameter count returned > 0, we know there will be valid open parenthesis.
+ $openParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+ $parameterOffsetFound = $parameterCount - 1;
+
+ foreach ($this->newFunctionParameters[$functionLc] as $offset => $parameterDetails) {
+ if ($offset <= $parameterOffsetFound) {
+ $itemInfo = array(
+ 'name' => $function,
+ 'nameLc' => $functionLc,
+ 'offset' => $offset,
+ );
+ $this->handleFeature($phpcsFile, $openParenthesis, $itemInfo);
+ }
+ }
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newFunctionParameters[$itemInfo['nameLc']][$itemInfo['offset']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('name');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['paramName'] = $itemArray['name'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the item name to be used for the creation of the error code.
+ *
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return string
+ */
+ protected function getItemName(array $itemInfo, array $errorInfo)
+ {
+ return $itemInfo['name'] . '_' . $errorInfo['paramName'];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The function %s() does not have a parameter "%s" in PHP version %s or earlier';
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ array_shift($data);
+ array_unshift($data, $itemInfo['name'], $errorInfo['paramName']);
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/NewFunctionsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/NewFunctionsSniff.php
new file mode 100644
index 0000000..b8269de
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/NewFunctionsSniff.php
@@ -0,0 +1,1925 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\newFunctionsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewFunctionsSniff extends AbstractNewFeatureSniff
+{
+ /**
+ * A list of new functions, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the function appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newFunctions = array(
+ 'iterator_count' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'iterator_to_array' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'spl_autoload_call' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'spl_autoload_extensions' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'spl_autoload_functions' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'spl_autoload_register' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'spl_autoload_unregister' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'spl_autoload' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'hash_hmac' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'array_fill_keys' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'error_get_last' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'image_type_to_extension' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'memory_get_peak_usage' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'sys_get_temp_dir' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'timezone_abbreviations_list' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'timezone_identifiers_list' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'timezone_name_from_abbr' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'stream_socket_shutdown' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'imagegrabscreen' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'imagegrabwindow' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'libxml_disable_entity_loader' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'mb_stripos' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'mb_stristr' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'mb_strrchr' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'mb_strrichr' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'mb_strripos' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'ming_setSWFCompression' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'openssl_csr_get_public_key' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'openssl_csr_get_subject' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'openssl_pkey_get_details' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'spl_object_hash' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'iterator_apply' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'preg_last_error' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'pg_field_table' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'posix_initgroups' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'gmp_nextprime' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'xmlwriter_full_end_element' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'xmlwriter_write_raw' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'xmlwriter_start_dtd_entity' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'xmlwriter_end_dtd_entity' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'xmlwriter_write_dtd_entity' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_has_var' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_id' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_input_array' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_input' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_list' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_var_array' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter_var' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'json_decode' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'json_encode' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_close' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_close' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_compressedsize' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_compressionmethod' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_filesize' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_name' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_open' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_entry_read' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_open' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'zip_read' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+
+ 'array_replace' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'array_replace_recursive' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'class_alias' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'forward_static_call' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'forward_static_call_array' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'gc_collect_cycles' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'gc_disable' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'gc_enable' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'gc_enabled' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'get_called_class' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'gethostname' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'header_remove' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'lcfirst' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'parse_ini_string' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'quoted_printable_encode' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'str_getcsv' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'stream_context_set_default' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'stream_supports_lock' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'stream_context_get_params' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'date_add' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'date_create_from_format' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'date_diff' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'date_get_last_errors' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'date_parse_from_format' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'date_sub' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'timezone_version_get' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'gmp_testbit' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'hash_copy' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'imap_gc' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'imap_utf8_to_mutf7' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'imap_mutf7_to_utf8' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'json_last_error' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli_get_cache_stats' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli_fetch_all' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli_get_connection_status' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli_poll' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli_read_async_query' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'openssl_random_pseudo_bytes' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'pcntl_signal_dispatch' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'pcntl_sigprocmask' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'pcntl_sigtimedwait' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'pcntl_sigwaitinfo' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'preg_filter' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'msg_queue_exists' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'shm_has_vars' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'acosh' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'asinh' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'atanh' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'expm1' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'log1p' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_describe' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_dict_exists' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_free_dict' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_free' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_get_error' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_init' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_list_dicts' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_request_dict' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_request_pwl_dict' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_broker_set_ordering' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_add_to_personal' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_add_to_session' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_check' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_describe' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_get_error' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_is_in_session' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_quick_check' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_store_replacement' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'enchant_dict_suggest' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'finfo_buffer' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'finfo_close' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'finfo_file' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'finfo_open' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'finfo_set_flags' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'intl_error_name' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'intl_get_error_code' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'intl_get_error_message' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'intl_is_failure' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+
+ 'hex2bin' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'http_response_code' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'get_declared_traits' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'getimagesizefromstring' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'stream_set_chunk_size' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'socket_import_stream' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'trait_exists' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'header_register_callback' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'class_uses' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session_status' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session_register_shutdown' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mysqli_error_list' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mysqli_stmt_error_list' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'libxml_set_external_entity_loader' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ldap_control_paged_result' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'ldap_control_paged_result_response' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_create' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_create_from_rules' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_create_inverse' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_get_error_code' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_get_error_message' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_list_ids' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'transliteral_transliterate' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'zlib_decode' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'zlib_encode' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ 'array_column' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'boolval' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'json_last_error_msg' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'password_get_info' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'password_hash' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'password_needs_rehash' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'password_verify' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'hash_pbkdf2' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'openssl_pbkdf2' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_escape' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_file_create' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_multi_setopt' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_multi_strerror' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_pause' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_reset' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_share_close' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_share_init' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_share_setopt' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_strerror' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'curl_unescape' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imageaffinematrixconcat' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imageaffinematrixget' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imagecrop' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imagecropauto' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imageflip' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imagepalettetotruecolor' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'imagescale' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'mysqli_begin_transaction' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'mysqli_release_savepoint' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'mysqli_savepoint' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'pg_escape_literal' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'pg_escape_identifier' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'socket_sendmsg' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'socket_recvmsg' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'socket_cmsg_space' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'cli_get_process_title' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'cli_set_process_title' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'datefmt_format_object' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'datefmt_get_calendar_object' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'datefmt_get_timezone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'datefmt_set_timezone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'datefmt_get_calendar_object' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_create_instance' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_keyword_values_for_locale' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_now' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_available_locales' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_time' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_set_time' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_add' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_set_time_zone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_after' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_before' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_set' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_roll' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_clear' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_field_difference' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_actual_maximum' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_actual_minumum' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_day_of_week_type' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_first_day_of_week' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_greatest_minimum' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_least_maximum' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_locale' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_maximum' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_minimal_days_in_first_week' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_minimum' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_time_zone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_type' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_weekend_transition' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_in_daylight_time' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_is_equivalent_to' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_is_lenient' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_equals' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_repeated_wall_time_option' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_skipped_wall_time_option' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_set_repeated_wall_time_option' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_set_skipped_wall_time_option' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_from_date_time' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_to_date_time' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_error_code' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlcal_get_error_message' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlgregcal_create_instance' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlgregcal_set_gregorian_change' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlgregcal_get_gregorian_change' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlgregcal_is_leap_year' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_create_time_zone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_create_default' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_id' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_gmt' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_unknown' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_create_enumeration' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_count_equivalent_ids' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_create_time_zone_id_enumeration' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_canonical_id' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_region' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_tz_data_version' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_equivalent_id' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_use_daylight_time' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_offset' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_raw_offset' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_has_same_rules' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_display_name' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_dst_savings' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_from_date_time_zone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_to_date_time_zone' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_error_code' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'intlz_get_error_message' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+
+ 'gmp_root' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'gmp_rootrem' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'hash_equals' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'ldap_escape' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'ldap_modify_batch' => array(
+ '5.4.25' => false,
+ '5.5.9' => false,
+ '5.4.26' => true,
+ '5.5.10' => true,
+ '5.6.0' => true,
+ ),
+ 'mysqli_get_links_stats' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'openssl_get_cert_locations' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'openssl_x509_fingerprint' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'openssl_spki_new' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'openssl_spki_verify' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'openssl_spki_export_challenge' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'openssl_spki_export' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'pg_connect_poll' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'pg_consume_input' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'pg_flush' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'pg_lo_truncate' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'pg_socket' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'session_abort' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+ 'session_reset' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+
+ 'random_bytes' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'random_int' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'error_clear_last' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'gmp_random_seed' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'intdiv' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'preg_replace_callback_array' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'gc_mem_caches' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'get_resources' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'posix_setrlimit' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'inflate_add' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'deflate_add' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'inflate_init' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'deflate_init' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ 'socket_export_stream' => array(
+ '7.0.6' => false,
+ '7.0.7' => true,
+ ),
+
+ 'curl_multi_errno' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'curl_share_errno' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'curl_share_strerror' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'is_iterable' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'pcntl_async_signals' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'pcntl_signal_get_handler' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'session_create_id' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'session_gc' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sapi_windows_cp_set' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sapi_windows_cp_get' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sapi_windows_cp_is_utf8' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sapi_windows_cp_conv' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+
+ 'hash_hkdf' => array(
+ '7.1.1' => false,
+ '7.1.2' => true,
+ ),
+ 'oci_register_taf_callback' => array(
+ '7.1.6' => false,
+ '7.1.7' => true,
+ ),
+ 'oci_unregister_taf_callback' => array(
+ '7.1.8' => false,
+ '7.1.9' => true,
+ ),
+
+ 'stream_isatty' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sapi_windows_vt100_support' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'ftp_append' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'hash_hmac_algos' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'imagebmp' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'imagecreatefrombmp' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'imagegetclip' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'imageopenpolygon' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'imageresolution' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'imagesetclip' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'ldap_exop' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'ldap_exop_passwd' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'ldap_exop_whoami' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'ldap_parse_exop' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'mb_chr' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'mb_ord' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'mb_scrub' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'socket_addrinfo_lookup' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'socket_addrinfo_connect' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'socket_addrinfo_bind' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'socket_addrinfo_explain' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'spl_object_id' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_add' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_base642bin' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_bin2base64' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_bin2hex' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_compare' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_aes256gcm_decrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_aes256gcm_encrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_aes256gcm_is_available' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_aes256gcm_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_chacha20poly1305_decrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_chacha20poly1305_encrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_chacha20poly1305_ietf_encrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_chacha20poly1305_ietf_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_chacha20poly1305_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_xchacha20poly1305_ietf_decrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_xchacha20poly1305_ietf_encrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_aead_xchacha20poly1305_ietf_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_auth_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_auth_verify' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_auth' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_keypair_from_secretkey_and_publickey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_keypair' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_open' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_publickey_from_secretkey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_publickey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_seal_open' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_seal' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_secretkey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box_seed_keypair' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_box' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_generichash_final' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_generichash_init' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_generichash_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_generichash_update' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_generichash' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kdf_derive_from_key' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kdf_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kx_client_session_keys' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kx_keypair' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kx_publickey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kx_secretkey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kx_seed_keypair' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_kx_server_session_keys' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash_scryptsalsa208sha256_str_verify' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash_scryptsalsa208sha256_str' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash_scryptsalsa208sha256' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash_str_needs_rehash' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash_str_verify' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash_str' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_pwhash' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_scalarmult_base' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_scalarmult' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretbox_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretbox_open' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretbox' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretstream_xchacha20poly1305_init_pull' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretstream_xchacha20poly1305_init_push' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretstream_xchacha20poly1305_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretstream_xchacha20poly1305_pull' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretstream_xchacha20poly1305_push' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_secretstream_xchacha20poly1305_rekey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_shorthash_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_shorthash' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_detached' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_ed25519_pk_to_curve25519' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_ed25519_sk_to_curve25519' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_keypair_from_secretkey_and_publickey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_keypair' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_open' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_publickey_from_secretkey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_publickey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_secretkey' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_seed_keypair' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign_verify_detached' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_sign' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_stream_keygen' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_stream_xor' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_crypto_stream' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_hex2bin' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_increment' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_memcmp' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_memzero' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_pad' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'sodium_unpad' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+
+ 'hrtime' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'is_countable' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'array_key_first' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'array_key_last' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'fpm_get_status' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'net_get_interfaces' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'gmp_binomial' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'gmp_lcm' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'gmp_perfect_power' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'gmp_kronecker' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_add_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_bind_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_delete_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_exop_refresh' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_mod_add_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_mod_replace_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_mod_del_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'ldap_rename_ext' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'normalizer_get_raw_decomposition' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'openssl_pkey_derive' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'socket_wsaprotocol_info_export' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'socket_wsaprotocol_info_import' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'socket_wsaprotocol_info_release' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->newFunctions = $this->arrayKeysToLowercase($this->newFunctions);
+
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+
+ } elseif ($tokens[$prevToken]['code'] === T_NS_SEPARATOR && $tokens[$prevToken - 1]['code'] === T_STRING) {
+ // Namespaced function.
+ return;
+ }
+
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if (isset($this->newFunctions[$functionLc]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $function,
+ 'nameLc' => $functionLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newFunctions[$itemInfo['nameLc']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The function %s() is not present in PHP version %s or earlier';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/OptionalToRequiredFunctionParametersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/OptionalToRequiredFunctionParametersSniff.php
new file mode 100644
index 0000000..d884d98
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/OptionalToRequiredFunctionParametersSniff.php
@@ -0,0 +1,159 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\Sniffs\FunctionUse\RequiredToOptionalFunctionParametersSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\OptionalToRequiredFunctionParametersSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class OptionalToRequiredFunctionParametersSniff extends RequiredToOptionalFunctionParametersSniff
+{
+
+ /**
+ * A list of function parameters, which were optional in older versions and became required later on.
+ *
+ * The array lists : version number with true (required) and false (optional use deprecated).
+ *
+ * The index is the location of the parameter in the parameter list, starting at 0 !
+ * If's sufficient to list the last version in which the parameter was not yet required.
+ *
+ * @var array
+ */
+ protected $functionParameters = array(
+ // Special case, the optional nature is not deprecated, but usage is recommended
+ // and leaving the parameter out will throw an E_NOTICE.
+ 'crypt' => array(
+ 1 => array(
+ 'name' => 'salt',
+ '5.6' => 'recommended',
+ ),
+ ),
+ 'parse_str' => array(
+ 1 => array(
+ 'name' => 'result',
+ '7.2' => false,
+ ),
+ ),
+ );
+
+
+ /**
+ * Determine whether an error/warning should be thrown for an item based on collected information.
+ *
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return bool
+ */
+ protected function shouldThrowError(array $errorInfo)
+ {
+ return ($errorInfo['optionalDeprecated'] !== ''
+ || $errorInfo['optionalRemoved'] !== ''
+ || $errorInfo['optionalRecommended'] !== '');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = array(
+ 'paramName' => '',
+ 'optionalRecommended' => '',
+ 'optionalDeprecated' => '',
+ 'optionalRemoved' => '',
+ 'error' => false,
+ );
+
+ $versionArray = $this->getVersionArray($itemArray);
+
+ if (empty($versionArray) === false) {
+ foreach ($versionArray as $version => $required) {
+ if ($this->supportsAbove($version) === true) {
+ if ($required === true && $errorInfo['optionalRemoved'] === '') {
+ $errorInfo['optionalRemoved'] = $version;
+ $errorInfo['error'] = true;
+ } elseif ($required === 'recommended' && $errorInfo['optionalRecommended'] === '') {
+ $errorInfo['optionalRecommended'] = $version;
+ } elseif ($errorInfo['optionalDeprecated'] === '') {
+ $errorInfo['optionalDeprecated'] = $version;
+ }
+ }
+ }
+ }
+
+ $errorInfo['paramName'] = $itemArray['name'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Generates the error or warning for this item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Array with detail (version) information
+ * relevant to the item.
+ *
+ * @return void
+ */
+ public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
+ {
+ $error = 'The "%s" parameter for function %s() is missing. Passing this parameter is ';
+ if ($errorInfo['optionalRecommended'] === '') {
+ $error .= 'no longer optional. The optional nature of the parameter is ';
+ } else {
+ $error .= 'strongly recommended ';
+ }
+
+ $errorCode = $this->stringToErrorCode($itemInfo['name'] . '_' . $errorInfo['paramName']);
+ $data = array(
+ $errorInfo['paramName'],
+ $itemInfo['name'],
+ );
+
+ if ($errorInfo['optionalRecommended'] !== '') {
+ $error .= 'since PHP %s ';
+ $errorCode .= 'SoftRecommended';
+ $data[] = $errorInfo['optionalRecommended'];
+ } else {
+ if ($errorInfo['optionalDeprecated'] !== '') {
+ $error .= 'deprecated since PHP %s and ';
+ $errorCode .= 'SoftRequired';
+ $data[] = $errorInfo['optionalDeprecated'];
+ }
+
+ if ($errorInfo['optionalRemoved'] !== '') {
+ $error .= 'removed since PHP %s and ';
+ $errorCode .= 'HardRequired';
+ $data[] = $errorInfo['optionalRemoved'];
+ }
+
+ // Remove the last 'and' from the message.
+ $error = substr($error, 0, (strlen($error) - 5));
+ }
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $errorInfo['error'], $errorCode, $data);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RemovedFunctionParametersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RemovedFunctionParametersSniff.php
new file mode 100644
index 0000000..b2f42b3
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RemovedFunctionParametersSniff.php
@@ -0,0 +1,219 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\RemovedFunctionParametersSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class RemovedFunctionParametersSniff extends AbstractRemovedFeatureSniff
+{
+ /**
+ * A list of removed function parameters, which were present in older versions.
+ *
+ * The array lists : version number with false (deprecated) and true (removed).
+ * The index is the location of the parameter in the parameter list, starting at 0 !
+ * If's sufficient to list the first version where the function parameter was deprecated/removed.
+ *
+ * @var array
+ */
+ protected $removedFunctionParameters = array(
+ 'define' => array(
+ 2 => array(
+ 'name' => 'case_insensitive',
+ '7.3' => false, // Slated for removal in PHP 8.0.0.
+ ),
+ ),
+ 'gmmktime' => array(
+ 6 => array(
+ 'name' => 'is_dst',
+ '5.1' => false,
+ '7.0' => true,
+ ),
+ ),
+ 'ldap_first_attribute' => array(
+ 2 => array(
+ 'name' => 'ber_identifier',
+ '5.2.4' => true,
+ ),
+ ),
+ 'ldap_next_attribute' => array(
+ 2 => array(
+ 'name' => 'ber_identifier',
+ '5.2.4' => true,
+ ),
+ ),
+ 'mktime' => array(
+ 6 => array(
+ 'name' => 'is_dst',
+ '5.1' => false,
+ '7.0' => true,
+ ),
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->removedFunctionParameters = $this->arrayKeysToLowercase($this->removedFunctionParameters);
+
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if (isset($this->removedFunctionParameters[$functionLc]) === false) {
+ return;
+ }
+
+ $parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr);
+ if ($parameterCount === 0) {
+ return;
+ }
+
+ // If the parameter count returned > 0, we know there will be valid open parenthesis.
+ $openParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+ $parameterOffsetFound = $parameterCount - 1;
+
+ foreach ($this->removedFunctionParameters[$functionLc] as $offset => $parameterDetails) {
+ if ($offset <= $parameterOffsetFound) {
+ $itemInfo = array(
+ 'name' => $function,
+ 'nameLc' => $functionLc,
+ 'offset' => $offset,
+ );
+ $this->handleFeature($phpcsFile, $openParenthesis, $itemInfo);
+ }
+ }
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->removedFunctionParameters[$itemInfo['nameLc']][$itemInfo['offset']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('name');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['paramName'] = $itemArray['name'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the item name to be used for the creation of the error code.
+ *
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return string
+ */
+ protected function getItemName(array $itemInfo, array $errorInfo)
+ {
+ return $itemInfo['name'] . '_' . $errorInfo['paramName'];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The "%s" parameter for function %s() is ';
+ }
+
+
+ /**
+ * Filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ array_shift($data);
+ array_unshift($data, $errorInfo['paramName'], $itemInfo['name']);
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RemovedFunctionsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RemovedFunctionsSniff.php
new file mode 100644
index 0000000..df2aaa0
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RemovedFunctionsSniff.php
@@ -0,0 +1,970 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\RemovedFunctionsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class RemovedFunctionsSniff extends AbstractRemovedFeatureSniff
+{
+ /**
+ * A list of deprecated and removed functions with their alternatives.
+ *
+ * The array lists : version number with false (deprecated) or true (removed) and an alternative function.
+ * If no alternative exists, it is NULL, i.e, the function should just not be used.
+ *
+ * @var array(string => array(string => bool|string|null))
+ */
+ protected $removedFunctions = array(
+ 'php_check_syntax' => array(
+ '5.0.5' => true,
+ 'alternative' => null,
+ ),
+ 'call_user_method' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'call_user_func()',
+ ),
+ 'call_user_method_array' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'call_user_func_array()',
+ ),
+ 'define_syslog_variables' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => null,
+ ),
+ 'dl' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => null,
+ ),
+ 'ereg' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'preg_match()',
+ ),
+ 'ereg_replace' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'preg_replace()',
+ ),
+ 'eregi' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'preg_match()',
+ ),
+ 'eregi_replace' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'preg_replace()',
+ ),
+ 'imagepsbbox' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'imagepsencodefont' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'imagepsextendfont' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'imagepsfreefont' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'imagepsloadfont' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'imagepsslantfont' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'imagepstext' => array(
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'import_request_variables' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => null,
+ ),
+ 'ldap_sort' => array(
+ '7.0' => false,
+ 'alternative' => null,
+ ),
+ 'mcrypt_generic_end' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'mcrypt_generic_deinit()',
+ ),
+ 'mysql_db_query' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'mysqli::select_db() and mysqli::query()',
+ ),
+ 'mysql_escape_string' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'mysqli::real_escape_string()',
+ ),
+ 'mysql_list_dbs' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'mysqli_bind_param' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli_stmt::bind_param()',
+ ),
+ 'mysqli_bind_result' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli_stmt::bind_result()',
+ ),
+ 'mysqli_client_encoding' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli::character_set_name()',
+ ),
+ 'mysqli_fetch' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli_stmt::fetch()',
+ ),
+ 'mysqli_param_count' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli_stmt_param_count()',
+ ),
+ 'mysqli_get_metadata' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli_stmt::result_metadata()',
+ ),
+ 'mysqli_send_long_data' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => 'mysqli_stmt::send_long_data()',
+ ),
+ 'magic_quotes_runtime' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'session_register' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => '$_SESSION',
+ ),
+ 'session_unregister' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => '$_SESSION',
+ ),
+ 'session_is_registered' => array(
+ '5.3' => false,
+ '5.4' => true,
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => '$_SESSION',
+ ),
+ 'set_magic_quotes_runtime' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'set_socket_blocking' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'stream_set_blocking()',
+ ),
+ 'split' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'preg_split()',
+ ),
+ 'spliti' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'preg_split()',
+ ),
+ 'sql_regcase' => array(
+ '5.3' => false,
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'php_logo_guid' => array(
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => null,
+ ),
+ 'php_egg_logo_guid' => array(
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => null,
+ ),
+ 'php_real_logo_guid' => array(
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => null,
+ ),
+ 'zend_logo_guid' => array(
+ '5.5' => true,
+ '5.6' => true,
+ 'alternative' => null,
+ ),
+ 'datefmt_set_timezone_id' => array(
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'IntlDateFormatter::setTimeZone()',
+ ),
+ 'mcrypt_ecb' => array(
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'mcrypt_cbc' => array(
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'mcrypt_cfb' => array(
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'mcrypt_ofb' => array(
+ '5.5' => false,
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => null,
+ ),
+ 'ocibindbyname' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_bind_by_name()',
+ ),
+ 'ocicancel' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_cancel()',
+ ),
+ 'ocicloselob' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::close()',
+ ),
+ 'ocicollappend' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::append()',
+ ),
+ 'ocicollassign' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::assign()',
+ ),
+ 'ocicollassignelem' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::assignElem()',
+ ),
+ 'ocicollgetelem' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::getElem()',
+ ),
+ 'ocicollmax' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::max()',
+ ),
+ 'ocicollsize' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::size()',
+ ),
+ 'ocicolltrim' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::trim()',
+ ),
+ 'ocicolumnisnull' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_is_null()',
+ ),
+ 'ocicolumnname' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_name()',
+ ),
+ 'ocicolumnprecision' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_precision()',
+ ),
+ 'ocicolumnscale' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_scale()',
+ ),
+ 'ocicolumnsize' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_size()',
+ ),
+ 'ocicolumntype' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_type()',
+ ),
+ 'ocicolumntyperaw' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_field_type_raw()',
+ ),
+ 'ocicommit' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_commit()',
+ ),
+ 'ocidefinebyname' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_define_by_name()',
+ ),
+ 'ocierror' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_error()',
+ ),
+ 'ociexecute' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_execute()',
+ ),
+ 'ocifetch' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_fetch()',
+ ),
+ 'ocifetchinto' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => null,
+ ),
+ 'ocifetchstatement' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_fetch_all()',
+ ),
+ 'ocifreecollection' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Collection::free()',
+ ),
+ 'ocifreecursor' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_free_statement()',
+ ),
+ 'ocifreedesc' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::free()',
+ ),
+ 'ocifreestatement' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_free_statement()',
+ ),
+ 'ociinternaldebug' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_internal_debug()',
+ ),
+ 'ociloadlob' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::load()',
+ ),
+ 'ocilogoff' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_close()',
+ ),
+ 'ocilogon' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_connect()',
+ ),
+ 'ocinewcollection' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_new_collection()',
+ ),
+ 'ocinewcursor' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_new_cursor()',
+ ),
+ 'ocinewdescriptor' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_new_descriptor()',
+ ),
+ 'ocinlogon' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_new_connect()',
+ ),
+ 'ocinumcols' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_num_fields()',
+ ),
+ 'ociparse' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_parse()',
+ ),
+ 'ociplogon' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_pconnect()',
+ ),
+ 'ociresult' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_result()',
+ ),
+ 'ocirollback' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_rollback()',
+ ),
+ 'ocirowcount' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_num_rows()',
+ ),
+ 'ocisavelob' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::save()',
+ ),
+ 'ocisavelobfile' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::import()',
+ ),
+ 'ociserverversion' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_server_version()',
+ ),
+ 'ocisetprefetch' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_set_prefetch()',
+ ),
+ 'ocistatementtype' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'oci_statement_type()',
+ ),
+ 'ociwritelobtofile' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::export()',
+ ),
+ 'ociwritetemporarylob' => array(
+ '5.4' => false,
+ '5.5' => false,
+ '5.6' => false,
+ 'alternative' => 'OCI-Lob::writeTemporary()',
+ ),
+ 'mysqli_get_cache_stats' => array(
+ '5.4' => true,
+ 'alternative' => null,
+ ),
+
+ 'mcrypt_create_iv' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'random_bytes() or OpenSSL',
+ ),
+ 'mcrypt_decrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_get_algorithms_name' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_get_block_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_get_iv_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_get_key_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_get_modes_name' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_get_supported_key_sizes' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_is_block_algorithm_mode' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_is_block_algorithm' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_is_block_mode' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_enc_self_test' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_encrypt' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_generic_deinit' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_generic_init' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_generic' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_get_block_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_get_cipher_name' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_get_iv_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_get_key_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_list_algorithms' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_list_modes' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_close' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_get_algo_block_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_get_algo_key_size' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_get_supported_key_sizes' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_is_block_algorithm_mode' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_is_block_algorithm' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_is_block_mode' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_open' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mcrypt_module_self_test' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'mdecrypt_generic' => array(
+ '7.1' => false,
+ '7.2' => true,
+ 'alternative' => 'OpenSSL',
+ ),
+ 'jpeg2wbmp' => array(
+ '7.2' => false,
+ 'alternative' => 'imagecreatefromjpeg() and imagewbmp()',
+ ),
+ 'png2wbmp' => array(
+ '7.2' => false,
+ 'alternative' => 'imagecreatefrompng() or imagewbmp()',
+ ),
+ 'create_function' => array(
+ '7.2' => false,
+ 'alternative' => 'an anonymous function',
+ ),
+ 'each' => array(
+ '7.2' => false,
+ 'alternative' => 'a foreach loop',
+ ),
+ 'gmp_random' => array(
+ '7.2' => false,
+ 'alternative' => 'gmp_random_bits() or gmp_random_range()',
+ ),
+ 'read_exif_data' => array(
+ '7.2' => false,
+ 'alternative' => 'exif_read_data()',
+ ),
+
+ 'image2wbmp' => array(
+ '7.3' => false,
+ 'alternative' => 'imagewbmp()',
+ ),
+ 'mbregex_encoding' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_regex_encoding()',
+ ),
+ 'mbereg' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg()',
+ ),
+ 'mberegi' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_eregi()',
+ ),
+ 'mbereg_replace' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_replace()',
+ ),
+ 'mberegi_replace' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_eregi_replace()',
+ ),
+ 'mbsplit' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_split()',
+ ),
+ 'mbereg_match' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_match()',
+ ),
+ 'mbereg_search' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search()',
+ ),
+ 'mbereg_search_pos' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search_pos()',
+ ),
+ 'mbereg_search_regs' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search_regs()',
+ ),
+ 'mbereg_search_init' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search_init()',
+ ),
+ 'mbereg_search_getregs' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search_getregs()',
+ ),
+ 'mbereg_search_getpos' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search_getpos()',
+ ),
+ 'mbereg_search_setpos' => array(
+ '7.3' => false,
+ 'alternative' => 'mb_ereg_search_setpos()',
+ ),
+ 'fgetss' => array(
+ '7.3' => false,
+ 'alternative' => null,
+ ),
+ 'gzgetss' => array(
+ '7.3' => false,
+ 'alternative' => null,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->removedFunctions = $this->arrayKeysToLowercase($this->removedFunctions);
+
+ return array(T_STRING);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CLASS => true,
+ T_CONST => true,
+ T_USE => true,
+ T_NS_SEPARATOR => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if (isset($this->removedFunctions[$functionLc]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $function,
+ 'nameLc' => $functionLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->removedFunctions[$itemInfo['nameLc']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'Function %s() is ';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RequiredToOptionalFunctionParametersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RequiredToOptionalFunctionParametersSniff.php
new file mode 100644
index 0000000..8c61013
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/FunctionUse/RequiredToOptionalFunctionParametersSniff.php
@@ -0,0 +1,310 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\FunctionUse;
+
+use PHPCompatibility\AbstractComplexVersionSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\FunctionUse\RequiredToOptionalFunctionParametersSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RequiredToOptionalFunctionParametersSniff extends AbstractComplexVersionSniff
+{
+
+ /**
+ * A list of function parameters, which were required in older versions and became optional later on.
+ *
+ * The array lists : version number with true (required) and false (optional).
+ *
+ * The index is the location of the parameter in the parameter list, starting at 0 !
+ * If's sufficient to list the last version in which the parameter was still required.
+ *
+ * @var array
+ */
+ protected $functionParameters = array(
+ 'array_push' => array(
+ 1 => array(
+ 'name' => 'element to push',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'array_unshift' => array(
+ 1 => array(
+ 'name' => 'element to prepend',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'bcscale' => array(
+ 0 => array(
+ 'name' => 'scale',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_fget' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_fput' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_get' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_nb_fget' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_nb_fput' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_nb_get' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_nb_put' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'ftp_put' => array(
+ 3 => array(
+ 'name' => 'mode',
+ '7.2' => true,
+ '7.3' => false,
+ ),
+ ),
+ 'getenv' => array(
+ 0 => array(
+ 'name' => 'varname',
+ '7.0' => true,
+ '7.1' => false,
+ ),
+ ),
+ 'preg_match_all' => array(
+ 2 => array(
+ 'name' => 'matches',
+ '5.3' => true,
+ '5.4' => false,
+ ),
+ ),
+ 'stream_socket_enable_crypto' => array(
+ 2 => array(
+ 'name' => 'crypto_type',
+ '5.5' => true,
+ '5.6' => false,
+ ),
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of function names.
+ $this->functionParameters = $this->arrayKeysToLowercase($this->functionParameters);
+
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $function = $tokens[$stackPtr]['content'];
+ $functionLc = strtolower($function);
+
+ if (isset($this->functionParameters[$functionLc]) === false) {
+ return;
+ }
+
+ $parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr);
+ $openParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
+
+ // If the parameter count returned > 0, we know there will be valid open parenthesis.
+ if ($parameterCount === 0 && $tokens[$openParenthesis]['code'] !== T_OPEN_PARENTHESIS) {
+ return;
+ }
+
+ $parameterOffsetFound = $parameterCount - 1;
+
+ foreach ($this->functionParameters[$functionLc] as $offset => $parameterDetails) {
+ if ($offset > $parameterOffsetFound) {
+ $itemInfo = array(
+ 'name' => $function,
+ 'nameLc' => $functionLc,
+ 'offset' => $offset,
+ );
+ $this->handleFeature($phpcsFile, $openParenthesis, $itemInfo);
+ }
+ }
+ }
+
+
+ /**
+ * Determine whether an error/warning should be thrown for an item based on collected information.
+ *
+ * @param array $errorInfo Detail information about an item.
+ *
+ * @return bool
+ */
+ protected function shouldThrowError(array $errorInfo)
+ {
+ return ($errorInfo['requiredVersion'] !== '');
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->functionParameters[$itemInfo['nameLc']][$itemInfo['offset']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('name');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = array(
+ 'paramName' => '',
+ 'requiredVersion' => '',
+ );
+
+ $versionArray = $this->getVersionArray($itemArray);
+
+ if (empty($versionArray) === false) {
+ foreach ($versionArray as $version => $required) {
+ if ($required === true && $this->supportsBelow($version) === true) {
+ $errorInfo['requiredVersion'] = $version;
+ }
+ }
+ }
+
+ $errorInfo['paramName'] = $itemArray['name'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The "%s" parameter for function %s() is missing, but was required for PHP version %s and lower';
+ }
+
+
+ /**
+ * Generates the error or warning for this item.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the relevant token in
+ * the stack.
+ * @param array $itemInfo Base information about the item.
+ * @param array $errorInfo Array with detail (version) information
+ * relevant to the item.
+ *
+ * @return void
+ */
+ public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
+ {
+ $error = $this->getErrorMsgTemplate();
+ $errorCode = $this->stringToErrorCode($itemInfo['name'] . '_' . $errorInfo['paramName']) . 'Missing';
+ $data = array(
+ $errorInfo['paramName'],
+ $itemInfo['name'],
+ $errorInfo['requiredVersion'],
+ );
+
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Generators/NewGeneratorReturnSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Generators/NewGeneratorReturnSniff.php
new file mode 100644
index 0000000..8b20fa4
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Generators/NewGeneratorReturnSniff.php
@@ -0,0 +1,153 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Generators;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Generators\NewGeneratorReturnSniff.
+ *
+ * As of PHP 7.0, a return statement can be used within a generator for a final expression to be returned.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewGeneratorReturnSniff extends Sniff
+{
+ /**
+ * Scope conditions within which a yield can exist.
+ *
+ * @var array
+ */
+ private $validConditions = array(
+ T_FUNCTION => T_FUNCTION,
+ T_CLOSURE => T_CLOSURE,
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $targets = array(
+ T_YIELD,
+ );
+
+ /*
+ * The `yield` keyword was introduced in PHP 5.5 with the token T_YIELD.
+ * The `yield from` keyword was introduced in PHP 7.0 and tokenizes as
+ * "T_YIELD T_WHITESPACE T_STRING".
+ *
+ * Pre-PHPCS 3.1.0, the T_YIELD token was not correctly back-filled for PHP < 5.5.
+ * Also, as of PHPCS 3.1.0, the PHPCS tokenizer adds a new T_YIELD_FROM
+ * token.
+ *
+ * So for PHP 5.3-5.4 icw PHPCS < 3.1.0, we need to look for T_STRING with content "yield".
+ * For PHP 5.5+ we need to look for T_YIELD.
+ * For PHPCS 3.1.0+, we also need to look for T_YIELD_FROM.
+ */
+ if (version_compare(PHP_VERSION_ID, '50500', '<') === true
+ && version_compare(PHPCSHelper::getVersion(), '3.1.0', '<') === true
+ ) {
+ $targets[] = T_STRING;
+ }
+
+ if (defined('T_YIELD_FROM')) {
+ $targets[] = T_YIELD_FROM;
+ }
+
+ return $targets;
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void|int Void or a stack pointer to skip forward.
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.6') !== true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] === T_STRING
+ && $tokens[$stackPtr]['content'] !== 'yield'
+ ) {
+ return;
+ }
+
+ if (empty($tokens[$stackPtr]['conditions']) === true) {
+ return;
+ }
+
+ // Walk the condition from inner to outer to see if we can find a valid function/closure scope.
+ $conditions = array_reverse($tokens[$stackPtr]['conditions'], true);
+ foreach ($conditions as $ptr => $type) {
+ if (isset($this->validConditions[$type]) === true) {
+ $function = $ptr;
+ break;
+ }
+ }
+
+ if (isset($function) === false) {
+ // Yield outside function scope, fatal error, but not our concern.
+ return;
+ }
+
+ if (isset($tokens[$function]['scope_opener'], $tokens[$function]['scope_closer']) === false) {
+ // Can't reliably determine start/end of function scope.
+ return;
+ }
+
+ $targets = array(T_RETURN, T_CLOSURE, T_FUNCTION, T_CLASS);
+ if (defined('T_ANON_CLASS')) {
+ $targets[] = T_ANON_CLASS;
+ }
+
+ $current = $tokens[$function]['scope_opener'];
+
+ while (($current = $phpcsFile->findNext($targets, ($current + 1), $tokens[$function]['scope_closer'])) !== false) {
+ if ($tokens[$current]['code'] === T_RETURN) {
+ $phpcsFile->addError(
+ 'Returning a final expression from a generator was not supported in PHP 5.6 or earlier',
+ $current,
+ 'ReturnFound'
+ );
+
+ return $tokens[$function]['scope_closer'];
+ }
+
+ // Found a nested scope in which return can exist without problems.
+ if (isset($tokens[$current]['scope_closer'])) {
+ // Skip past the nested scope.
+ $current = $tokens[$current]['scope_closer'];
+ }
+ }
+
+ // Don't examine this function again.
+ return $tokens[$function]['scope_closer'];
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/IniDirectives/NewIniDirectivesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/IniDirectives/NewIniDirectivesSniff.php
new file mode 100644
index 0000000..6d32b02
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/IniDirectives/NewIniDirectivesSniff.php
@@ -0,0 +1,663 @@
+
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\IniDirectives;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\IniDirectives\NewIniDirectivesSniff.
+ *
+ * Discourages the use of new INI directives through ini_set() or ini_get().
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+class NewIniDirectivesSniff extends AbstractNewFeatureSniff
+{
+ /**
+ * A list of new INI directives
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the ini directive appears.
+ *
+ * @var array(string)
+ */
+ protected $newIniDirectives = array(
+ 'auto_globals_jit' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'com.code_page' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'date.default_latitude' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'date.default_longitude' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'date.sunrise_zenith' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'date.sunset_zenith' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'ibase.default_charset' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'ibase.default_db' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mail.force_extra_parameters' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mime_magic.debug' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mysqli.max_links' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mysqli.default_port' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mysqli.default_socket' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mysqli.default_host' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mysqli.default_user' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'mysqli.default_pw' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'report_zend_debug' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'session.hash_bits_per_character' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'session.hash_function' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'soap.wsdl_cache_dir' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'soap.wsdl_cache_enabled' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'soap.wsdl_cache_ttl' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'sqlite.assoc_case' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'tidy.clean_output' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'tidy.default_config' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'zend.ze1_compatibility_mode' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+
+ 'date.timezone' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'detect_unicode' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'fbsql.batchsize' => array(
+ '5.0' => false,
+ '5.1' => true,
+ 'alternative' => 'fbsql.batchSize',
+ ),
+ 'realpath_cache_size' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'realpath_cache_ttl' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+
+ 'mbstring.strict_detection' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+ 'mssql.charset' => array(
+ '5.1.1' => false,
+ '5.1.2' => true,
+ ),
+
+ 'gd.jpeg_ignore_warning' => array(
+ '5.1.2' => false,
+ '5.1.3' => true,
+ ),
+
+ 'fbsql.show_timestamp_decimals' => array(
+ '5.1.4' => false,
+ '5.1.5' => true,
+ ),
+ 'soap.wsdl_cache' => array(
+ '5.1.4' => false,
+ '5.1.5' => true,
+ ),
+ 'soap.wsdl_cache_limit' => array(
+ '5.1.4' => false,
+ '5.1.5' => true,
+ ),
+
+ 'allow_url_include' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter.default' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'filter.default_flags' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'pcre.backtrack_limit' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'pcre.recursion_limit' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+ 'session.cookie_httponly' => array(
+ '5.1' => false,
+ '5.2' => true,
+ ),
+
+ 'cgi.check_shebang_line' => array(
+ '5.2.0' => false,
+ '5.2.1' => true,
+ ),
+
+ 'max_input_nesting_level' => array(
+ '5.2.2' => false,
+ '5.2.3' => true,
+ ),
+
+ 'mysqli.allow_local_infile' => array(
+ '5.2.3' => false,
+ '5.2.4' => true,
+ ),
+
+ 'max_file_uploads' => array(
+ '5.2.11' => false,
+ '5.2.12' => true,
+ ),
+
+ 'cgi.discard_path' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'exit_on_timeout' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'intl.default_locale' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'intl.error_level' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mail.add_x_header' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mail.log' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mbstring.http_output_conv_mimetype' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli.allow_persistent' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli.cache_size' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqli.max_persistent' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqlnd.collect_memory_statistics' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqlnd.collect_statistics' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqlnd.debug' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'mysqlnd.net_read_buffer_size' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'odbc.default_cursortype' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'request_order' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'user_ini.cache_ttl' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'user_ini.filename' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'zend.enable_gc' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+
+ 'curl.cainfo' => array(
+ '5.3.6' => false,
+ '5.3.7' => true,
+ ),
+
+ 'max_input_vars' => array(
+ '5.3.8' => false,
+ '5.3.9' => true,
+ ),
+
+ 'sqlite3.extension_dir' => array(
+ '5.3.10' => false,
+ '5.3.11' => true,
+ ),
+
+ 'cli.pager' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'cli.prompt' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'cli_server.color' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'enable_post_data_reading' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mysqlnd.mempool_default_size' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mysqlnd.net_cmd_buffer_size' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mysqlnd.net_read_timeout' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'phar.cache_list' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.upload_progress.enabled' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.upload_progress.cleanup' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.upload_progress.name' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.upload_progress.freq' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.upload_progress.min_freq' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.upload_progress.prefix' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'windows_show_crt_warning' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'zend.detect_unicode' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => 'detect_unicode',
+ ),
+ 'zend.multibyte' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'zend.script_encoding' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'zend.signal_check' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mysqlnd.log_mask' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ 'intl.use_exceptions' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'mysqlnd.sha256_server_public_key' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'mysqlnd.trace_alloc' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'sys_temp_dir' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ 'xsl.security_prefs' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+
+ 'session.use_strict_mode' => array(
+ '5.5.1' => false,
+ '5.5.2' => true,
+ ),
+
+ 'mysqli.rollback_on_cached_plink' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+
+ 'assert.exception' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'pcre.jit' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'session.lazy_write' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'zend.assertions' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+
+ 'hard_timeout' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'session.sid_length' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'session.sid_bits_per_character' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'session.trans_sid_hosts' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'session.trans_sid_tags' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'url_rewriter.hosts' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+
+ // Introduced in PHP 7.1.25, 7.2.13, 7.3.0.
+ 'imap.enable_insecure_rsh' => array(
+ '7.1.24' => false,
+ '7.1.25' => true,
+ ),
+
+ 'syslog.facility' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'syslog.filter' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'syslog.ident' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ 'session.cookie_samesite' => array(
+ '7.2' => false,
+ '7.3' => true,
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $functionLc = strtolower($tokens[$stackPtr]['content']);
+ if (isset($this->iniFunctions[$functionLc]) === false) {
+ return;
+ }
+
+ $iniToken = $this->getFunctionCallParameter($phpcsFile, $stackPtr, $this->iniFunctions[$functionLc]);
+ if ($iniToken === false) {
+ return;
+ }
+
+ $filteredToken = $this->stripQuotes($iniToken['raw']);
+ if (isset($this->newIniDirectives[$filteredToken]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $filteredToken,
+ 'functionLc' => $functionLc,
+ );
+ $this->handleFeature($phpcsFile, $iniToken['end'], $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newIniDirectives[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('alternative');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['alternative'] = '';
+
+ if (isset($itemArray['alternative']) === true) {
+ $errorInfo['alternative'] = $itemArray['alternative'];
+ }
+
+ // Lower error level to warning if the function used was ini_get.
+ if ($errorInfo['error'] === true && $itemInfo['functionLc'] === 'ini_get') {
+ $errorInfo['error'] = false;
+ }
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return "INI directive '%s' is not present in PHP version %s or earlier";
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error message before it's passed to PHPCS.
+ *
+ * @param string $error The error message which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return string
+ */
+ protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
+ {
+ if ($errorInfo['alternative'] !== '') {
+ $error .= ". This directive was previously called '%s'.";
+ }
+
+ return $error;
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ if ($errorInfo['alternative'] !== '') {
+ $data[] = $errorInfo['alternative'];
+ }
+
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/IniDirectives/RemovedIniDirectivesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/IniDirectives/RemovedIniDirectivesSniff.php
new file mode 100644
index 0000000..3979269
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/IniDirectives/RemovedIniDirectivesSniff.php
@@ -0,0 +1,346 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\IniDirectives;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\IniDirectives\RemovedIniDirectivesSniff.
+ *
+ * Discourages the use of deprecated and removed INI directives through ini_set() or ini_get().
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class RemovedIniDirectivesSniff extends AbstractRemovedFeatureSniff
+{
+ /**
+ * A list of deprecated INI directives.
+ *
+ * The array lists : version number with false (deprecated) and true (removed).
+ * If's sufficient to list the first version where the ini directive was deprecated/removed.
+ *
+ * @var array(string)
+ */
+ protected $deprecatedIniDirectives = array(
+ 'fbsql.batchSize' => array(
+ '5.1' => true,
+ 'alternative' => 'fbsql.batchsize',
+ ),
+
+ 'ifx.allow_persistent' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.blobinfile' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.byteasvarchar' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.charasvarchar' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.default_host' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.default_password' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.default_user' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.max_links' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.max_persistent' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.nullformat' => array(
+ '5.2.1' => true,
+ ),
+ 'ifx.textasvarchar' => array(
+ '5.2.1' => true,
+ ),
+
+ 'zend.ze1_compatibility_mode' => array(
+ '5.3' => true,
+ ),
+
+ 'allow_call_time_pass_reference' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'define_syslog_variables' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'detect_unicode' => array(
+ '5.4' => true,
+ 'alternative' => 'zend.detect_unicode',
+ ),
+ 'highlight.bg' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'magic_quotes_gpc' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'magic_quotes_runtime' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'magic_quotes_sybase' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'mbstring.script_encoding' => array(
+ '5.4' => true,
+ 'alternative' => 'zend.script_encoding',
+ ),
+ 'register_globals' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'register_long_arrays' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'safe_mode' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'safe_mode_allowed_env_vars' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'safe_mode_exec_dir' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'safe_mode_gid' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'safe_mode_include_dir' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'safe_mode_protected_env_vars' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.bug_compat_42' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'session.bug_compat_warn' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'y2k_compliance' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ 'always_populate_raw_post_data' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'iconv.input_encoding' => array(
+ '5.6' => false,
+ ),
+ 'iconv.output_encoding' => array(
+ '5.6' => false,
+ ),
+ 'iconv.internal_encoding' => array(
+ '5.6' => false,
+ ),
+ 'mbstring.http_input' => array(
+ '5.6' => false,
+ ),
+ 'mbstring.http_output' => array(
+ '5.6' => false,
+ ),
+ 'mbstring.internal_encoding' => array(
+ '5.6' => false,
+ ),
+
+ 'asp_tags' => array(
+ '7.0' => true,
+ ),
+ 'xsl.security_prefs' => array(
+ '7.0' => true,
+ ),
+
+ 'mcrypt.algorithms_dir' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'mcrypt.modes_dir' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ 'session.entropy_file' => array(
+ '7.1' => true,
+ ),
+ 'session.entropy_length' => array(
+ '7.1' => true,
+ ),
+ 'session.hash_function' => array(
+ '7.1' => true,
+ ),
+ 'session.hash_bits_per_character' => array(
+ '7.1' => true,
+ ),
+
+ 'mbstring.func_overload' => array(
+ '7.2' => false,
+ ),
+ 'sql.safe_mode' => array(
+ '7.2' => true,
+ ),
+ 'track_errors' => array(
+ '7.2' => false,
+ ),
+ 'opcache.fast_shutdown' => array(
+ '7.2' => true,
+ ),
+
+ 'birdstep.max_links' => array(
+ '7.3' => true,
+ ),
+ 'opcache.inherited_hack' => array(
+ '5.3' => false, // Soft deprecated, i.e. ignored.
+ '7.3' => true,
+ ),
+ 'pdo_odbc.db2_instance_name' => array(
+ '7.3' => false, // Has been marked as deprecated in the manual from before this time. Now hard-deprecated.
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $functionLc = strtolower($tokens[$stackPtr]['content']);
+ if (isset($this->iniFunctions[$functionLc]) === false) {
+ return;
+ }
+
+ $iniToken = $this->getFunctionCallParameter($phpcsFile, $stackPtr, $this->iniFunctions[$functionLc]);
+ if ($iniToken === false) {
+ return;
+ }
+
+ $filteredToken = $this->stripQuotes($iniToken['raw']);
+ if (isset($this->deprecatedIniDirectives[$filteredToken]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $filteredToken,
+ 'functionLc' => $functionLc,
+ );
+ $this->handleFeature($phpcsFile, $iniToken['end'], $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->deprecatedIniDirectives[$itemInfo['name']];
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+
+ // Lower error level to warning if the function used was ini_get.
+ if ($errorInfo['error'] === true && $itemInfo['functionLc'] === 'ini_get') {
+ $errorInfo['error'] = false;
+ }
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return "INI directive '%s' is ";
+ }
+
+
+ /**
+ * Get the error message template for suggesting an alternative for a specific sniff.
+ *
+ * @return string
+ */
+ protected function getAlternativeOptionTemplate()
+ {
+ return str_replace("%s", "'%s'", parent::getAlternativeOptionTemplate());
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingConstSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingConstSniff.php
new file mode 100644
index 0000000..57689c2
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingConstSniff.php
@@ -0,0 +1,78 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\InitialValue;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\InitialValue\NewConstantArraysUsingConstSniff.
+ *
+ * Constant arrays using the const keyword in PHP 5.6
+ *
+ * PHP version 5.6
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewConstantArraysUsingConstSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_CONST);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.5') !== true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $find = array(
+ T_ARRAY => T_ARRAY,
+ T_OPEN_SHORT_ARRAY => T_OPEN_SHORT_ARRAY,
+ );
+
+ while (($hasArray = $phpcsFile->findNext($find, ($stackPtr + 1), null, false, null, true)) !== false) {
+ $phpcsFile->addError(
+ 'Constant arrays using the "const" keyword are not allowed in PHP 5.5 or earlier',
+ $hasArray,
+ 'Found'
+ );
+
+ // Skip past the content of the array.
+ $stackPtr = $hasArray;
+ if ($tokens[$hasArray]['code'] === T_OPEN_SHORT_ARRAY && isset($tokens[$hasArray]['bracket_closer'])) {
+ $stackPtr = $tokens[$hasArray]['bracket_closer'];
+ } elseif ($tokens[$hasArray]['code'] === T_ARRAY && isset($tokens[$hasArray]['parenthesis_closer'])) {
+ $stackPtr = $tokens[$hasArray]['parenthesis_closer'];
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingDefineSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingDefineSniff.php
new file mode 100644
index 0000000..6bace76
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingDefineSniff.php
@@ -0,0 +1,97 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\InitialValue;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\InitialValue\NewConstantArraysUsingDefineSniff.
+ *
+ * Constant arrays using define in PHP 7.0
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewConstantArraysUsingDefineSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.6') !== true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ $ignore = array(
+ T_DOUBLE_COLON => true,
+ T_OBJECT_OPERATOR => true,
+ T_FUNCTION => true,
+ T_CONST => true,
+ );
+
+ $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function.
+ return;
+ }
+
+ $functionLc = strtolower($tokens[$stackPtr]['content']);
+ if ($functionLc !== 'define') {
+ return;
+ }
+
+ $secondParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 2);
+ if (isset($secondParam['start'], $secondParam['end']) === false) {
+ return;
+ }
+
+ $targetNestingLevel = 0;
+ if (isset($tokens[$secondParam['start']]['nested_parenthesis'])) {
+ $targetNestingLevel = count($tokens[$secondParam['start']]['nested_parenthesis']);
+ }
+
+ $array = $phpcsFile->findNext(array(T_ARRAY, T_OPEN_SHORT_ARRAY), $secondParam['start'], ($secondParam['end'] + 1));
+ if ($array !== false) {
+ if ((isset($tokens[$array]['nested_parenthesis']) === false && $targetNestingLevel === 0) || count($tokens[$array]['nested_parenthesis']) === $targetNestingLevel) {
+ $phpcsFile->addError(
+ 'Constant arrays using define are not allowed in PHP 5.6 or earlier',
+ $array,
+ 'Found'
+ );
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantScalarExpressionsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantScalarExpressionsSniff.php
new file mode 100644
index 0000000..83b1374
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewConstantScalarExpressionsSniff.php
@@ -0,0 +1,534 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\InitialValue;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\InitialValue\NewConstantScalarExpressionsSniff.
+ *
+ * Since PHP 5.6, it is now possible to provide a scalar expression involving
+ * numeric and string literals and/or constants in contexts where PHP previously
+ * expected a static value, such as constant and property declarations and
+ * default function arguments.
+ *
+ * PHP version 5.6
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewConstantScalarExpressionsSniff extends Sniff
+{
+
+ /**
+ * Error message.
+ *
+ * @var string
+ */
+ const ERROR_PHRASE = 'Constant scalar expressions are not allowed %s in PHP 5.5 or earlier.';
+
+ /**
+ * Partial error phrases to be used in combination with the error message constant.
+ *
+ * @var array
+ */
+ protected $errorPhrases = array(
+ 'const' => 'when defining constants using the const keyword',
+ 'property' => 'in property declarations',
+ 'staticvar' => 'in static variable declarations',
+ 'default' => 'in default function arguments',
+ );
+
+ /**
+ * Tokens which were allowed to be used in these declarations prior to PHP 5.6.
+ *
+ * This list will be enriched in the setProperties() method.
+ *
+ * @var array
+ */
+ protected $safeOperands = array(
+ T_LNUMBER => T_LNUMBER,
+ T_DNUMBER => T_DNUMBER,
+ T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
+ T_TRUE => T_TRUE,
+ T_FALSE => T_FALSE,
+ T_NULL => T_NULL,
+
+ T_LINE => T_LINE,
+ T_FILE => T_FILE,
+ T_DIR => T_DIR,
+ T_FUNC_C => T_FUNC_C,
+ T_CLASS_C => T_CLASS_C,
+ T_TRAIT_C => T_TRAIT_C,
+ T_METHOD_C => T_METHOD_C,
+ T_NS_C => T_NS_C,
+
+ // Special cases:
+ T_NS_SEPARATOR => T_NS_SEPARATOR,
+ /*
+ * This can be neigh anything, but for any usage except constants,
+ * the T_STRING will be combined with non-allowed tokens, so we should be good.
+ */
+ T_STRING => T_STRING,
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Set the properties up only once.
+ $this->setProperties();
+
+ return array(
+ T_CONST,
+ T_VARIABLE,
+ T_FUNCTION,
+ T_CLOSURE,
+ T_STATIC,
+ );
+ }
+
+
+ /**
+ * Make some adjustments to the $safeOperands property.
+ *
+ * @return void
+ */
+ public function setProperties()
+ {
+ $this->safeOperands += Tokens::$heredocTokens;
+ $this->safeOperands += Tokens::$emptyTokens;
+ }
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('5.5') !== true);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void|int Null or integer stack pointer to skip forward.
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->bowOutEarly() === true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ switch ($tokens[$stackPtr]['type']) {
+ case 'T_FUNCTION':
+ case 'T_CLOSURE':
+ $params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($params)) {
+ // No parameters.
+ return;
+ }
+
+ $funcToken = $tokens[$stackPtr];
+
+ if (isset($funcToken['parenthesis_owner'], $funcToken['parenthesis_opener'], $funcToken['parenthesis_closer']) === false
+ || $funcToken['parenthesis_owner'] !== $stackPtr
+ || isset($tokens[$funcToken['parenthesis_opener']], $tokens[$funcToken['parenthesis_closer']]) === false
+ ) {
+ // Hmm.. something is going wrong as these should all be available & valid.
+ return;
+ }
+
+ $opener = $funcToken['parenthesis_opener'];
+ $closer = $funcToken['parenthesis_closer'];
+
+ // Which nesting level is the one we are interested in ?
+ $nestedParenthesisCount = 1;
+ if (isset($tokens[$opener]['nested_parenthesis'])) {
+ $nestedParenthesisCount += count($tokens[$opener]['nested_parenthesis']);
+ }
+
+ foreach ($params as $param) {
+ if (isset($param['default']) === false) {
+ continue;
+ }
+
+ $end = $param['token'];
+ while (($end = $phpcsFile->findNext(array(T_COMMA, T_CLOSE_PARENTHESIS), ($end + 1), ($closer + 1))) !== false) {
+ $maybeSkipTo = $this->isRealEndOfDeclaration($tokens, $end, $nestedParenthesisCount);
+ if ($maybeSkipTo !== true) {
+ $end = $maybeSkipTo;
+ continue;
+ }
+
+ // Ignore closing parenthesis/bracket if not 'ours'.
+ if ($tokens[$end]['code'] === T_CLOSE_PARENTHESIS && $end !== $closer) {
+ continue;
+ }
+
+ // Ok, we've found the end of the param default value declaration.
+ break;
+ }
+
+ if ($this->isValidAssignment($phpcsFile, $param['token'], $end) === false) {
+ $this->throwError($phpcsFile, $param['token'], 'default', $param['content']);
+ }
+ }
+
+ /*
+ * No need for the sniff to be triggered by the T_VARIABLEs in the function
+ * definition as we've already examined them above, so let's skip over them.
+ */
+ return $closer;
+
+ case 'T_VARIABLE':
+ case 'T_STATIC':
+ case 'T_CONST':
+ $type = 'const';
+
+ // Filter out non-property declarations.
+ if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
+ if ($this->isClassProperty($phpcsFile, $stackPtr) === false) {
+ return;
+ }
+
+ $type = 'property';
+
+ // Move back one token to have the same starting point as the others.
+ $stackPtr = ($stackPtr - 1);
+ }
+
+ // Filter out late static binding and class properties.
+ if ($tokens[$stackPtr]['code'] === T_STATIC) {
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+ if ($next === false || $tokens[$next]['code'] !== T_VARIABLE) {
+ // Late static binding.
+ return;
+ }
+
+ if ($this->isClassProperty($phpcsFile, $next) === true) {
+ // Class properties are examined based on the T_VARIABLE token.
+ return;
+ }
+ unset($next);
+
+ $type = 'staticvar';
+ }
+
+ $endOfStatement = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), ($stackPtr + 1));
+ if ($endOfStatement === false) {
+ // No semi-colon - live coding.
+ return;
+ }
+
+ $targetNestingLevel = 0;
+ if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
+ $targetNestingLevel = count($tokens[$stackPtr]['nested_parenthesis']);
+ }
+
+ // Examine each variable/constant in multi-declarations.
+ $start = $stackPtr;
+ $end = $stackPtr;
+ while (($end = $phpcsFile->findNext(array(T_COMMA, T_SEMICOLON, T_OPEN_SHORT_ARRAY, T_CLOSE_TAG), ($end + 1), ($endOfStatement + 1))) !== false) {
+
+ $maybeSkipTo = $this->isRealEndOfDeclaration($tokens, $end, $targetNestingLevel);
+ if ($maybeSkipTo !== true) {
+ $end = $maybeSkipTo;
+ continue;
+ }
+
+ $start = $phpcsFile->findNext(Tokens::$emptyTokens, ($start + 1), $end, true);
+ if ($start === false
+ || ($tokens[$stackPtr]['code'] === T_CONST && $tokens[$start]['code'] !== T_STRING)
+ || ($tokens[$stackPtr]['code'] !== T_CONST && $tokens[$start]['code'] !== T_VARIABLE)
+ ) {
+ // Shouldn't be possible.
+ continue;
+ }
+
+ if ($this->isValidAssignment($phpcsFile, $start, $end) === false) {
+ // Create the "found" snippet.
+ $content = '';
+ $tokenCount = ($end - $start);
+ if ($tokenCount < 20) {
+ // Prevent large arrays from being added to the error message.
+ $content = $phpcsFile->getTokensAsString($start, ($tokenCount + 1));
+ }
+
+ $this->throwError($phpcsFile, $start, $type, $content);
+ }
+
+ $start = $end;
+ }
+
+ // Skip to the end of the statement to prevent duplicate messages for multi-declarations.
+ return $endOfStatement;
+ }
+ }
+
+
+ /**
+ * Is a value declared and is the value declared valid pre-PHP 5.6 ?
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param int $end The end of the value definition.
+ * This will normally be a comma or semi-colon.
+ *
+ * @return bool
+ */
+ protected function isValidAssignment(File $phpcsFile, $stackPtr, $end)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), $end, true);
+ if ($next === false || $tokens[$next]['code'] !== T_EQUAL) {
+ // No value assigned.
+ return true;
+ }
+
+ return $this->isStaticValue($phpcsFile, $tokens, ($next + 1), ($end - 1));
+ }
+
+
+ /**
+ * Is a value declared and is the value declared constant as accepted in PHP 5.5 and lower ?
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param array $tokens The token stack of the current file.
+ * @param int $start The stackPtr from which to start examining.
+ * @param int $end The end of the value definition (inclusive),
+ * i.e. this token will be examined as part of
+ * the snippet.
+ * @param bool $nestedArrays Optional. Array nesting level when examining
+ * the content of an array.
+ *
+ * @return bool
+ */
+ protected function isStaticValue(File $phpcsFile, $tokens, $start, $end, $nestedArrays = 0)
+ {
+ $nextNonSimple = $phpcsFile->findNext($this->safeOperands, $start, ($end + 1), true);
+ if ($nextNonSimple === false) {
+ return true;
+ }
+
+ /*
+ * OK, so we have at least one token which needs extra examination.
+ */
+ switch ($tokens[$nextNonSimple]['code']) {
+ case T_MINUS:
+ case T_PLUS:
+ if ($this->isNumber($phpcsFile, $start, $end, true) !== false) {
+ // Int or float with sign.
+ return true;
+ }
+
+ return false;
+
+ case T_NAMESPACE:
+ case T_PARENT:
+ case T_SELF:
+ case T_DOUBLE_COLON:
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonSimple + 1), ($end + 1), true);
+
+ if ($tokens[$nextNonSimple]['code'] === T_NAMESPACE) {
+ // Allow only `namespace\...`.
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_NS_SEPARATOR) {
+ return false;
+ }
+ } elseif ($tokens[$nextNonSimple]['code'] === T_PARENT
+ || $tokens[$nextNonSimple]['code'] === T_SELF
+ ) {
+ // Allow only `parent::` and `self::`.
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_DOUBLE_COLON) {
+ return false;
+ }
+ } elseif ($tokens[$nextNonSimple]['code'] === T_DOUBLE_COLON) {
+ // Allow only `T_STRING::T_STRING`.
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_STRING) {
+ return false;
+ }
+
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($nextNonSimple - 1), null, true);
+ // No need to worry about parent/self, that's handled above and
+ // the double colon is skipped over in that case.
+ if ($prevNonEmpty === false || $tokens[$prevNonEmpty]['code'] !== T_STRING) {
+ return false;
+ }
+ }
+
+ // Examine what comes after the namespace/parent/self/double colon, if anything.
+ return $this->isStaticValue($phpcsFile, $tokens, ($nextNonEmpty + 1), $end, $nestedArrays);
+
+ case T_ARRAY:
+ case T_OPEN_SHORT_ARRAY:
+ ++$nestedArrays;
+
+ $arrayItems = $this->getFunctionCallParameters($phpcsFile, $nextNonSimple);
+ if (empty($arrayItems) === false) {
+ foreach ($arrayItems as $item) {
+ // Check for a double arrow, but only if it's for this array item, not for a nested array.
+ $doubleArrow = false;
+
+ $maybeDoubleArrow = $phpcsFile->findNext(
+ array(T_DOUBLE_ARROW, T_ARRAY, T_OPEN_SHORT_ARRAY),
+ $item['start'],
+ ($item['end'] + 1)
+ );
+ if ($maybeDoubleArrow !== false && $tokens[$maybeDoubleArrow]['code'] === T_DOUBLE_ARROW) {
+ // Double arrow is for this nesting level.
+ $doubleArrow = $maybeDoubleArrow;
+ }
+
+ if ($doubleArrow === false) {
+ if ($this->isStaticValue($phpcsFile, $tokens, $item['start'], $item['end'], $nestedArrays) === false) {
+ return false;
+ }
+
+ } else {
+ // Examine array key.
+ if ($this->isStaticValue($phpcsFile, $tokens, $item['start'], ($doubleArrow - 1), $nestedArrays) === false) {
+ return false;
+ }
+
+ // Examine array value.
+ if ($this->isStaticValue($phpcsFile, $tokens, ($doubleArrow + 1), $item['end'], $nestedArrays) === false) {
+ return false;
+ }
+ }
+ }
+ }
+
+ --$nestedArrays;
+
+ /*
+ * Find the end of the array.
+ * We already know we will have a valid closer as otherwise we wouldn't have been
+ * able to get the array items.
+ */
+ $closer = ($nextNonSimple + 1);
+ if ($tokens[$nextNonSimple]['code'] === T_OPEN_SHORT_ARRAY
+ && isset($tokens[$nextNonSimple]['bracket_closer']) === true
+ ) {
+ $closer = $tokens[$nextNonSimple]['bracket_closer'];
+ } else {
+ $maybeOpener = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonSimple + 1), ($end + 1), true);
+ if ($tokens[$maybeOpener]['code'] === T_OPEN_PARENTHESIS) {
+ $opener = $maybeOpener;
+ if (isset($tokens[$opener]['parenthesis_closer']) === true) {
+ $closer = $tokens[$opener]['parenthesis_closer'];
+ }
+ }
+ }
+
+ if ($closer === $end) {
+ return true;
+ }
+
+ // Examine what comes after the array, if anything.
+ return $this->isStaticValue($phpcsFile, $tokens, ($closer + 1), $end, $nestedArrays);
+
+ }
+
+ // Ok, so this unsafe token was not one of the exceptions, i.e. this is a PHP 5.6+ syntax.
+ return false;
+ }
+
+
+ /**
+ * Throw an error if a scalar expression is found.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the token to link the error to.
+ * @param string $type Type of usage found.
+ * @param string $content Optional. The value for the declaration as found.
+ *
+ * @return void
+ */
+ protected function throwError(File $phpcsFile, $stackPtr, $type, $content = '')
+ {
+ $error = static::ERROR_PHRASE;
+ $phrase = '';
+ $errorCode = 'Found';
+
+ if (isset($this->errorPhrases[$type]) === true) {
+ $errorCode = $this->stringToErrorCode($type) . 'Found';
+ $phrase = $this->errorPhrases[$type];
+ }
+
+ $data = array($phrase);
+
+ if (empty($content) === false) {
+ $error .= ' Found: %s';
+ $data[] = $content;
+ }
+
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+
+
+ /**
+ * Helper function to find the end of multi variable/constant declarations.
+ *
+ * Checks whether a certain part of a declaration needs to be skipped over or
+ * if it is the real end of the declaration.
+ *
+ * @param array $tokens Token stack of the current file.
+ * @param int $endPtr The token to examine as a candidate end pointer.
+ * @param int $targetLevel Target nesting level.
+ *
+ * @return bool|int True if this is the real end. Int stackPtr to skip to if not.
+ */
+ private function isRealEndOfDeclaration($tokens, $endPtr, $targetLevel)
+ {
+ // Ignore anything within short array definition brackets for now.
+ if ($tokens[$endPtr]['code'] === T_OPEN_SHORT_ARRAY
+ && (isset($tokens[$endPtr]['bracket_opener'])
+ && $tokens[$endPtr]['bracket_opener'] === $endPtr)
+ && isset($tokens[$endPtr]['bracket_closer'])
+ ) {
+ // Skip forward to the end of the short array definition.
+ return $tokens[$endPtr]['bracket_closer'];
+ }
+
+ // Skip past comma's at a lower nesting level.
+ if ($tokens[$endPtr]['code'] === T_COMMA) {
+ // Check if a comma is at the nesting level we're targetting.
+ $nestingLevel = 0;
+ if (isset($tokens[$endPtr]['nested_parenthesis']) === true) {
+ $nestingLevel = count($tokens[$endPtr]['nested_parenthesis']);
+ }
+ if ($nestingLevel > $targetLevel) {
+ return $endPtr;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewHeredocSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewHeredocSniff.php
new file mode 100644
index 0000000..3126efe
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/InitialValue/NewHeredocSniff.php
@@ -0,0 +1,90 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\InitialValue;
+
+use PHPCompatibility\Sniffs\InitialValue\NewConstantScalarExpressionsSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\InitialValue\NewHeredocSniff.
+ *
+ * As of PHP 5.3.0, it's possible to initialize static variables, class properties
+ * and constants declared using the `const` keyword, using the Heredoc syntax.
+ * And while not documented, heredoc initialization can now also be used for function param defaults.
+ * See: https://3v4l.org/JVH8W
+ *
+ * These heredocs (still) cannot contain variables. That's, however, outside the scope of the
+ * PHPCompatibility library until such time as there is a PHP version in which this would be accepted.
+ *
+ * PHP version 5.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewHeredocSniff extends NewConstantScalarExpressionsSniff
+{
+
+ /**
+ * Error message.
+ *
+ * @var string
+ */
+ const ERROR_PHRASE = 'Initializing %s using the Heredoc syntax was not supported in PHP 5.2 or earlier';
+
+ /**
+ * Partial error phrases to be used in combination with the error message constant.
+ *
+ * @var array
+ */
+ protected $errorPhrases = array(
+ 'const' => 'constants',
+ 'property' => 'class properties',
+ 'staticvar' => 'static variables',
+ 'default' => 'default parameter values',
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('5.2') !== true);
+ }
+
+
+ /**
+ * Is a value declared and does the declared value not contain an heredoc ?
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param int $end The end of the value definition.
+ *
+ * @return bool True if no heredoc (or assignment) is found, false otherwise.
+ */
+ protected function isValidAssignment(File $phpcsFile, $stackPtr, $end)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), $end, true);
+ if ($next === false || $tokens[$next]['code'] !== T_EQUAL) {
+ // No value assigned.
+ return true;
+ }
+
+ return ($phpcsFile->findNext(T_START_HEREDOC, ($next + 1), $end, false, null, true) === false);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Interfaces/InternalInterfacesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Interfaces/InternalInterfacesSniff.php
new file mode 100644
index 0000000..64a4167
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Interfaces/InternalInterfacesSniff.php
@@ -0,0 +1,92 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Interfaces;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Interfaces\InternalInterfacesSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class InternalInterfacesSniff extends Sniff
+{
+
+ /**
+ * A list of PHP internal interfaces, not intended to be implemented by userland classes.
+ *
+ * The array lists : the error message to use.
+ *
+ * @var array(string => string)
+ */
+ protected $internalInterfaces = array(
+ 'Traversable' => 'shouldn\'t be implemented directly, implement the Iterator or IteratorAggregate interface instead.',
+ 'DateTimeInterface' => 'is intended for type hints only and is not implementable.',
+ 'Throwable' => 'cannot be implemented directly, extend the Exception class instead.',
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of interface names.
+ $this->internalInterfaces = $this->arrayKeysToLowercase($this->internalInterfaces);
+
+ $targets = array(T_CLASS);
+
+ if (defined('T_ANON_CLASS')) {
+ $targets[] = T_ANON_CLASS;
+ }
+
+ return $targets;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $interfaces = PHPCSHelper::findImplementedInterfaceNames($phpcsFile, $stackPtr);
+
+ if (is_array($interfaces) === false || $interfaces === array()) {
+ return;
+ }
+
+ foreach ($interfaces as $interface) {
+ $interface = ltrim($interface, '\\');
+ $interfaceLc = strtolower($interface);
+ if (isset($this->internalInterfaces[$interfaceLc]) === true) {
+ $error = 'The interface %s %s';
+ $errorCode = $this->stringToErrorCode($interfaceLc) . 'Found';
+ $data = array(
+ $interface,
+ $this->internalInterfaces[$interfaceLc],
+ );
+
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Interfaces/NewInterfacesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Interfaces/NewInterfacesSniff.php
new file mode 100644
index 0000000..15e70aa
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Interfaces/NewInterfacesSniff.php
@@ -0,0 +1,336 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Interfaces;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Interfaces\NewInterfacesSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewInterfacesSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new interfaces, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the interface appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newInterfaces = array(
+ 'Traversable' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+ 'Reflector' => array(
+ '4.4' => false,
+ '5.0' => true,
+ ),
+
+ 'Countable' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'OuterIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'RecursiveIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'SeekableIterator' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'Serializable' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'SplObserver' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+ 'SplSubject' => array(
+ '5.0' => false,
+ '5.1' => true,
+ ),
+
+ 'JsonSerializable' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'SessionHandlerInterface' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+
+ 'DateTimeInterface' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+
+ 'SessionIdInterface' => array(
+ '5.5.0' => false,
+ '5.5.1' => true,
+ ),
+
+ 'Throwable' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ 'SessionUpdateTimestampHandlerInterface' => array(
+ '5.6' => false,
+ '7.0' => true,
+ ),
+ );
+
+ /**
+ * A list of methods which cannot be used in combination with particular interfaces.
+ *
+ * @var array(string => array(string => string))
+ */
+ protected $unsupportedMethods = array(
+ 'Serializable' => array(
+ '__sleep' => 'http://php.net/serializable',
+ '__wakeup' => 'http://php.net/serializable',
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Handle case-insensitivity of interface names.
+ $this->newInterfaces = $this->arrayKeysToLowercase($this->newInterfaces);
+ $this->unsupportedMethods = $this->arrayKeysToLowercase($this->unsupportedMethods);
+
+ $targets = array(
+ T_CLASS,
+ T_FUNCTION,
+ T_CLOSURE,
+ );
+
+ if (defined('T_ANON_CLASS')) {
+ $targets[] = T_ANON_CLASS;
+ }
+
+ if (defined('T_RETURN_TYPE')) {
+ $targets[] = T_RETURN_TYPE;
+ }
+
+ return $targets;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ switch ($tokens[$stackPtr]['type']) {
+ case 'T_CLASS':
+ case 'T_ANON_CLASS':
+ $this->processClassToken($phpcsFile, $stackPtr);
+ break;
+
+ case 'T_FUNCTION':
+ case 'T_CLOSURE':
+ $this->processFunctionToken($phpcsFile, $stackPtr);
+
+ // Deal with older PHPCS versions which don't recognize return type hints
+ // as well as newer PHPCS versions (3.3.0+) where the tokenization has changed.
+ $returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
+ if ($returnTypeHint !== false) {
+ $this->processReturnTypeToken($phpcsFile, $returnTypeHint);
+ }
+ break;
+
+ case 'T_RETURN_TYPE':
+ $this->processReturnTypeToken($phpcsFile, $stackPtr);
+ break;
+
+ default:
+ // Deliberately left empty.
+ break;
+ }
+ }
+
+
+ /**
+ * Processes this test for when a class token is encountered.
+ *
+ * - Detect classes implementing the new interfaces.
+ * - Detect classes implementing the new interfaces with unsupported functions.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processClassToken(File $phpcsFile, $stackPtr)
+ {
+ $interfaces = PHPCSHelper::findImplementedInterfaceNames($phpcsFile, $stackPtr);
+
+ if (is_array($interfaces) === false || $interfaces === array()) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $checkMethods = false;
+
+ if (isset($tokens[$stackPtr]['scope_closer'])) {
+ $checkMethods = true;
+ $scopeCloser = $tokens[$stackPtr]['scope_closer'];
+ }
+
+ foreach ($interfaces as $interface) {
+ $interface = ltrim($interface, '\\');
+ $interfaceLc = strtolower($interface);
+
+ if (isset($this->newInterfaces[$interfaceLc]) === true) {
+ $itemInfo = array(
+ 'name' => $interface,
+ 'nameLc' => $interfaceLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+ if ($checkMethods === true && isset($this->unsupportedMethods[$interfaceLc]) === true) {
+ $nextFunc = $stackPtr;
+ while (($nextFunc = $phpcsFile->findNext(T_FUNCTION, ($nextFunc + 1), $scopeCloser)) !== false) {
+ $funcName = $phpcsFile->getDeclarationName($nextFunc);
+ $funcNameLc = strtolower($funcName);
+ if ($funcNameLc === '') {
+ continue;
+ }
+
+ if (isset($this->unsupportedMethods[$interfaceLc][$funcNameLc]) === true) {
+ $error = 'Classes that implement interface %s do not support the method %s(). See %s';
+ $errorCode = $this->stringToErrorCode($interface) . 'UnsupportedMethod';
+ $data = array(
+ $interface,
+ $funcName,
+ $this->unsupportedMethods[$interfaceLc][$funcNameLc],
+ );
+
+ $phpcsFile->addError($error, $nextFunc, $errorCode, $data);
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Processes this test for when a function token is encountered.
+ *
+ * - Detect new interfaces when used as a type hint.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processFunctionToken(File $phpcsFile, $stackPtr)
+ {
+ $typeHints = $this->getTypeHintsFromFunctionDeclaration($phpcsFile, $stackPtr);
+ if (empty($typeHints) || is_array($typeHints) === false) {
+ return;
+ }
+
+ foreach ($typeHints as $hint) {
+
+ $typeHintLc = strtolower($hint);
+
+ if (isset($this->newInterfaces[$typeHintLc]) === true) {
+ $itemInfo = array(
+ 'name' => $hint,
+ 'nameLc' => $typeHintLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+ }
+ }
+
+
+ /**
+ * Processes this test for when a return type token is encountered.
+ *
+ * - Detect new interfaces when used as a return type declaration.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ private function processReturnTypeToken(File $phpcsFile, $stackPtr)
+ {
+ $returnTypeHint = $this->getReturnTypeHintName($phpcsFile, $stackPtr);
+ $returnTypeHint = ltrim($returnTypeHint, '\\');
+ $returnTypeHintLc = strtolower($returnTypeHint);
+
+ if (isset($this->newInterfaces[$returnTypeHintLc]) === false) {
+ return;
+ }
+
+ // Still here ? Then this is a return type declaration using a new interface.
+ $itemInfo = array(
+ 'name' => $returnTypeHint,
+ 'nameLc' => $returnTypeHintLc,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newInterfaces[$itemInfo['nameLc']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The built-in interface ' . parent::getErrorMsgTemplate();
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/CaseSensitiveKeywordsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/CaseSensitiveKeywordsSniff.php
new file mode 100644
index 0000000..9c6a103
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/CaseSensitiveKeywordsSniff.php
@@ -0,0 +1,73 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Keywords;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Keywords\CaseSensitiveKeywordsSniff.
+ *
+ * Prior to PHP 5.5, cases existed where the self, parent, and static keywords
+ * were treated in a case sensitive fashion.
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class CaseSensitiveKeywordsSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_SELF,
+ T_STATIC,
+ T_PARENT,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $tokenContentLC = strtolower($tokens[$stackPtr]['content']);
+
+ if ($tokenContentLC !== $tokens[$stackPtr]['content']) {
+ $phpcsFile->addError(
+ 'The keyword \'%s\' was treated in a case-sensitive fashion in certain cases in PHP 5.4 or earlier. Use the lowercase version for consistent support.',
+ $stackPtr,
+ 'NonLowercaseFound',
+ array($tokenContentLC)
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsDeclaredSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsDeclaredSniff.php
new file mode 100644
index 0000000..21c5cdb
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsDeclaredSniff.php
@@ -0,0 +1,248 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Keywords;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Keywords\ForbiddenNamesAsDeclaredClassSniff.
+ *
+ * Prohibits the use of some reserved keywords to name a class, interface, trait or namespace.
+ * Emits errors for reserved words and warnings for soft-reserved words.
+ *
+ * @see http://php.net/manual/en/reserved.other-reserved-words.php
+ *
+ * PHP version 7.0+
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ForbiddenNamesAsDeclaredSniff extends Sniff
+{
+
+ /**
+ * List of tokens which can not be used as class, interface, trait names or as part of a namespace.
+ *
+ * @var array
+ */
+ protected $forbiddenTokens = array(
+ T_NULL => '7.0',
+ T_TRUE => '7.0',
+ T_FALSE => '7.0',
+ );
+
+ /**
+ * T_STRING keywords to recognize as forbidden names.
+ *
+ * @var array
+ */
+ protected $forbiddenNames = array(
+ 'null' => '7.0',
+ 'true' => '7.0',
+ 'false' => '7.0',
+ 'bool' => '7.0',
+ 'int' => '7.0',
+ 'float' => '7.0',
+ 'string' => '7.0',
+ 'iterable' => '7.1',
+ 'void' => '7.1',
+ 'object' => '7.2',
+ );
+
+ /**
+ * T_STRING keywords to recognize as soft reserved names.
+ *
+ * Using any of these keywords to name a class, interface, trait or namespace
+ * is highly discouraged since they may be used in future versions of PHP.
+ *
+ * @var array
+ */
+ protected $softReservedNames = array(
+ 'resource' => '7.0',
+ 'object' => '7.0',
+ 'mixed' => '7.0',
+ 'numeric' => '7.0',
+ );
+
+ /**
+ * Combined list of the two lists above.
+ *
+ * Used for quick check whether or not something is a reserved
+ * word.
+ * Set from the `register()` method.
+ *
+ * @var array
+ */
+ private $allForbiddenNames = array();
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Do the list merge only once.
+ $this->allForbiddenNames = array_merge($this->forbiddenNames, $this->softReservedNames);
+
+ $targets = array(
+ T_CLASS,
+ T_INTERFACE,
+ T_TRAIT,
+ T_NAMESPACE,
+ T_STRING, // Compat for PHPCS < 2.4.0 and PHP < 5.3.
+ );
+
+ return $targets;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $tokenCode = $tokens[$stackPtr]['code'];
+ $tokenType = $tokens[$stackPtr]['type'];
+ $tokenContentLc = strtolower($tokens[$stackPtr]['content']);
+
+ // For string tokens we only care about 'trait' as that is the only one
+ // which may not be correctly recognized as it's own token.
+ // This only happens in older versions of PHP where the token doesn't exist yet as a keyword.
+ if ($tokenCode === T_STRING && $tokenContentLc !== 'trait') {
+ return;
+ }
+
+ if (in_array($tokenType, array('T_CLASS', 'T_INTERFACE', 'T_TRAIT'), true)) {
+ // Check for the declared name being a name which is not tokenized as T_STRING.
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty !== false && isset($this->forbiddenTokens[$tokens[$nextNonEmpty]['code']]) === true) {
+ $name = $tokens[$nextNonEmpty]['content'];
+ } else {
+ // Get the declared name if it's a T_STRING.
+ $name = $phpcsFile->getDeclarationName($stackPtr);
+ }
+ unset($nextNonEmpty);
+
+ if (isset($name) === false || is_string($name) === false || $name === '') {
+ return;
+ }
+
+ $nameLc = strtolower($name);
+ if (isset($this->allForbiddenNames[$nameLc]) === false) {
+ return;
+ }
+
+ } elseif ($tokenCode === T_NAMESPACE) {
+ $namespaceName = $this->getDeclaredNamespaceName($phpcsFile, $stackPtr);
+
+ if ($namespaceName === false || $namespaceName === '') {
+ return;
+ }
+
+ $namespaceParts = explode('\\', $namespaceName);
+ foreach ($namespaceParts as $namespacePart) {
+ $partLc = strtolower($namespacePart);
+ if (isset($this->allForbiddenNames[$partLc]) === true) {
+ $name = $namespacePart;
+ $nameLc = $partLc;
+ break;
+ }
+ }
+ } elseif ($tokenCode === T_STRING) {
+ // Traits which are not yet tokenized as T_TRAIT.
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false) {
+ return;
+ }
+
+ $nextNonEmptyCode = $tokens[$nextNonEmpty]['code'];
+
+ if ($nextNonEmptyCode !== T_STRING && isset($this->forbiddenTokens[$nextNonEmptyCode]) === true) {
+ $name = $tokens[$nextNonEmpty]['content'];
+ $nameLc = strtolower($tokens[$nextNonEmpty]['content']);
+ } elseif ($nextNonEmptyCode === T_STRING) {
+ $endOfStatement = $phpcsFile->findNext(array(T_SEMICOLON, T_OPEN_CURLY_BRACKET), ($stackPtr + 1));
+ if ($endOfStatement === false) {
+ return;
+ }
+
+ do {
+ $nextNonEmptyLc = strtolower($tokens[$nextNonEmpty]['content']);
+
+ if (isset($this->allForbiddenNames[$nextNonEmptyLc]) === true) {
+ $name = $tokens[$nextNonEmpty]['content'];
+ $nameLc = $nextNonEmptyLc;
+ break;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $endOfStatement, true);
+ } while ($nextNonEmpty !== false);
+ }
+ unset($nextNonEmptyCode, $nextNonEmptyLc, $endOfStatement);
+ }
+
+ if (isset($name, $nameLc) === false) {
+ return;
+ }
+
+ // Still here, so this is one of the reserved words.
+ // Build up the error message.
+ $error = "'%s' is a";
+ $isError = null;
+ $errorCode = $this->stringToErrorCode($nameLc) . 'Found';
+ $data = array(
+ $nameLc,
+ );
+
+ if (isset($this->softReservedNames[$nameLc]) === true
+ && $this->supportsAbove($this->softReservedNames[$nameLc]) === true
+ ) {
+ $error .= ' soft reserved keyword as of PHP version %s';
+ $isError = false;
+ $data[] = $this->softReservedNames[$nameLc];
+ }
+
+ if (isset($this->forbiddenNames[$nameLc]) === true
+ && $this->supportsAbove($this->forbiddenNames[$nameLc]) === true
+ ) {
+ if (isset($isError) === true) {
+ $error .= ' and a';
+ }
+ $error .= ' reserved keyword as of PHP version %s';
+ $isError = true;
+ $data[] = $this->forbiddenNames[$nameLc];
+ }
+
+ if (isset($isError) === true) {
+ $error .= ' and should not be used to name a class, interface or trait or as part of a namespace (%s)';
+ $data[] = $tokens[$stackPtr]['type'];
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode, $data);
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsInvokedFunctionsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsInvokedFunctionsSniff.php
new file mode 100644
index 0000000..01db961
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsInvokedFunctionsSniff.php
@@ -0,0 +1,180 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Keywords;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Keywords\ForbiddenNamesAsInvokedFunctionsSniff.
+ *
+ * Prohibits the use of reserved keywords invoked as functions.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Jansen Price
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class ForbiddenNamesAsInvokedFunctionsSniff extends Sniff
+{
+
+ /**
+ * List of tokens to register.
+ *
+ * @var array
+ */
+ protected $targetedTokens = array(
+ T_ABSTRACT => '5.0',
+ T_CALLABLE => '5.4',
+ T_CATCH => '5.0',
+ T_FINAL => '5.0',
+ T_FINALLY => '5.5',
+ T_GOTO => '5.3',
+ T_IMPLEMENTS => '5.0',
+ T_INTERFACE => '5.0',
+ T_INSTANCEOF => '5.0',
+ T_INSTEADOF => '5.4',
+ T_NAMESPACE => '5.3',
+ T_PRIVATE => '5.0',
+ T_PROTECTED => '5.0',
+ T_PUBLIC => '5.0',
+ T_TRAIT => '5.4',
+ T_TRY => '5.0',
+ );
+
+ /**
+ * T_STRING keywords to recognize as targetted tokens.
+ *
+ * Compatibility for PHP versions where the keyword is not yet recognized
+ * as its own token and for PHPCS versions which change the token to
+ * T_STRING when used in a method call.
+ *
+ * @var array
+ */
+ protected $targetedStringTokens = array(
+ 'abstract' => '5.0',
+ 'callable' => '5.4',
+ 'catch' => '5.0',
+ 'final' => '5.0',
+ 'finally' => '5.5',
+ 'goto' => '5.3',
+ 'implements' => '5.0',
+ 'interface' => '5.0',
+ 'instanceof' => '5.0',
+ 'insteadof' => '5.4',
+ 'namespace' => '5.3',
+ 'private' => '5.0',
+ 'protected' => '5.0',
+ 'public' => '5.0',
+ 'trait' => '5.4',
+ 'try' => '5.0',
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array_keys($this->targetedTokens);
+ $tokens[] = T_STRING;
+
+ return $tokens;
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $tokenCode = $tokens[$stackPtr]['code'];
+ $tokenContentLc = strtolower($tokens[$stackPtr]['content']);
+ $isString = false;
+
+ /*
+ * For string tokens we only care if the string is a reserved word used
+ * as a function. This only happens in older versions of PHP where the
+ * token doesn't exist yet for that keyword or in later versions when the
+ * token is used in a method invocation.
+ */
+ if ($tokenCode === T_STRING
+ && (isset($this->targetedStringTokens[$tokenContentLc]) === false)
+ ) {
+ return;
+ }
+
+ if ($tokenCode === T_STRING) {
+ $isString = true;
+ }
+
+ // Make sure this is a function call.
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($next === false || $tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
+ // Not a function call.
+ return;
+ }
+
+ // This sniff isn't concerned about function declarations.
+ $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if ($prev !== false && $tokens[$prev]['code'] === T_FUNCTION) {
+ return;
+ }
+
+ /*
+ * Deal with PHP 7 relaxing the rules.
+ * "As of PHP 7.0.0 these keywords are allowed as property, constant, and method names
+ * of classes, interfaces and traits...", i.e. they can be invoked as a method call.
+ *
+ * Only needed for those keywords which we sniff out via T_STRING.
+ */
+ if (($tokens[$prev]['code'] === T_OBJECT_OPERATOR || $tokens[$prev]['code'] === T_DOUBLE_COLON)
+ && $this->supportsBelow('5.6') === false
+ ) {
+ return;
+ }
+
+ // For the word catch, it is valid to have an open parenthesis
+ // after it, but only if it is preceded by a right curly brace.
+ if ($tokenCode === T_CATCH) {
+ if ($prev !== false && $tokens[$prev]['code'] === T_CLOSE_CURLY_BRACKET) {
+ // Ok, it's fine.
+ return;
+ }
+ }
+
+ if ($isString === true) {
+ $version = $this->targetedStringTokens[$tokenContentLc];
+ } else {
+ $version = $this->targetedTokens[$tokenCode];
+ }
+
+ if ($this->supportsAbove($version)) {
+ $error = "'%s' is a reserved keyword introduced in PHP version %s and cannot be invoked as a function (%s)";
+ $errorCode = $this->stringToErrorCode($tokenContentLc) . 'Found';
+ $data = array(
+ $tokenContentLc,
+ $version,
+ $tokens[$stackPtr]['type'],
+ );
+
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesSniff.php
new file mode 100644
index 0000000..0d1456c
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesSniff.php
@@ -0,0 +1,391 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Keywords;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Keywords\ForbiddenNamesSniff.
+ *
+ * Prohibits the use of reserved keywords as class, function, namespace or constant names.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class ForbiddenNamesSniff extends Sniff
+{
+
+ /**
+ * A list of keywords that can not be used as function, class and namespace name or constant name.
+ * Mentions since which version it's not allowed.
+ *
+ * @var array(string => string)
+ */
+ protected $invalidNames = array(
+ 'abstract' => '5.0',
+ 'and' => 'all',
+ 'array' => 'all',
+ 'as' => 'all',
+ 'break' => 'all',
+ 'callable' => '5.4',
+ 'case' => 'all',
+ 'catch' => '5.0',
+ 'class' => 'all',
+ 'clone' => '5.0',
+ 'const' => 'all',
+ 'continue' => 'all',
+ 'declare' => 'all',
+ 'default' => 'all',
+ 'do' => 'all',
+ 'else' => 'all',
+ 'elseif' => 'all',
+ 'enddeclare' => 'all',
+ 'endfor' => 'all',
+ 'endforeach' => 'all',
+ 'endif' => 'all',
+ 'endswitch' => 'all',
+ 'endwhile' => 'all',
+ 'extends' => 'all',
+ 'final' => '5.0',
+ 'finally' => '5.5',
+ 'for' => 'all',
+ 'foreach' => 'all',
+ 'function' => 'all',
+ 'global' => 'all',
+ 'goto' => '5.3',
+ 'if' => 'all',
+ 'implements' => '5.0',
+ 'interface' => '5.0',
+ 'instanceof' => '5.0',
+ 'insteadof' => '5.4',
+ 'namespace' => '5.3',
+ 'new' => 'all',
+ 'or' => 'all',
+ 'private' => '5.0',
+ 'protected' => '5.0',
+ 'public' => '5.0',
+ 'static' => 'all',
+ 'switch' => 'all',
+ 'throw' => '5.0',
+ 'trait' => '5.4',
+ 'try' => '5.0',
+ 'use' => 'all',
+ 'var' => 'all',
+ 'while' => 'all',
+ 'xor' => 'all',
+ '__class__' => 'all',
+ '__dir__' => '5.3',
+ '__file__' => 'all',
+ '__function__' => 'all',
+ '__method__' => 'all',
+ '__namespace__' => '5.3',
+ );
+
+ /**
+ * A list of keywords that can follow use statements.
+ *
+ * @var array(string => string)
+ */
+ protected $validUseNames = array(
+ 'const' => true,
+ 'function' => true,
+ );
+
+ /**
+ * Scope modifiers and other keywords allowed in trait use statements.
+ *
+ * @var array
+ */
+ private $allowedModifiers = array();
+
+ /**
+ * Targeted tokens.
+ *
+ * @var array
+ */
+ protected $targetedTokens = array(
+ T_CLASS,
+ T_FUNCTION,
+ T_NAMESPACE,
+ T_STRING,
+ T_CONST,
+ T_USE,
+ T_AS,
+ T_EXTENDS,
+ T_INTERFACE,
+ T_TRAIT,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $this->allowedModifiers = Tokens::$scopeModifiers;
+ $this->allowedModifiers[T_FINAL] = T_FINAL;
+
+ $tokens = $this->targetedTokens;
+
+ if (defined('T_ANON_CLASS')) {
+ $tokens[] = T_ANON_CLASS;
+ }
+
+ return $tokens;
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ /*
+ * We distinguish between the class, function and namespace names vs the define statements.
+ */
+ if ($tokens[$stackPtr]['type'] === 'T_STRING') {
+ $this->processString($phpcsFile, $stackPtr, $tokens);
+ } else {
+ $this->processNonString($phpcsFile, $stackPtr, $tokens);
+ }
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param array $tokens The stack of tokens that make up
+ * the file.
+ *
+ * @return void
+ */
+ public function processNonString(File $phpcsFile, $stackPtr, $tokens)
+ {
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false) {
+ return;
+ }
+
+ /*
+ * Deal with anonymous classes - `class` before a reserved keyword is sometimes
+ * misidentified as `T_ANON_CLASS`.
+ * In PHPCS < 2.3.4 these were tokenized as T_CLASS no matter what.
+ */
+ if ($tokens[$stackPtr]['type'] === 'T_ANON_CLASS' || $tokens[$stackPtr]['type'] === 'T_CLASS') {
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if ($prevNonEmpty !== false && $tokens[$prevNonEmpty]['type'] === 'T_NEW') {
+ return;
+ }
+ }
+
+ /*
+ * PHP 5.6 allows for use const and use function, but only if followed by the function/constant name.
+ * - `use function HelloWorld` => move to the next token (HelloWorld) to verify.
+ * - `use const HelloWorld` => move to the next token (HelloWorld) to verify.
+ */
+ elseif ($tokens[$stackPtr]['type'] === 'T_USE'
+ && isset($this->validUseNames[strtolower($tokens[$nextNonEmpty]['content'])]) === true
+ ) {
+ $maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
+ if ($maybeUseNext !== false && $this->isEndOfUseStatement($tokens[$maybeUseNext]) === false) {
+ $nextNonEmpty = $maybeUseNext;
+ }
+ }
+
+ /*
+ * Deal with visibility modifiers.
+ * - `use HelloWorld { sayHello as protected; }` => valid, bow out.
+ * - `use HelloWorld { sayHello as private myPrivateHello; }` => move to the next token to verify.
+ */
+ elseif ($tokens[$stackPtr]['type'] === 'T_AS'
+ && isset($this->allowedModifiers[$tokens[$nextNonEmpty]['code']]) === true
+ && $phpcsFile->hasCondition($stackPtr, T_USE) === true
+ ) {
+ $maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
+ if ($maybeUseNext === false || $this->isEndOfUseStatement($tokens[$maybeUseNext]) === true) {
+ return;
+ }
+
+ $nextNonEmpty = $maybeUseNext;
+ }
+
+ /*
+ * Deal with functions declared to return by reference.
+ */
+ elseif ($tokens[$stackPtr]['type'] === 'T_FUNCTION'
+ && $tokens[$nextNonEmpty]['type'] === 'T_BITWISE_AND'
+ ) {
+ $maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
+ if ($maybeUseNext === false) {
+ // Live coding.
+ return;
+ }
+
+ $nextNonEmpty = $maybeUseNext;
+ }
+
+ /*
+ * Deal with nested namespaces.
+ */
+ elseif ($tokens[$stackPtr]['type'] === 'T_NAMESPACE') {
+ if ($tokens[$stackPtr + 1]['code'] === T_NS_SEPARATOR) {
+ // Not a namespace declaration, but use of, i.e. namespace\someFunction();
+ return;
+ }
+
+ $endToken = $phpcsFile->findNext(array(T_SEMICOLON, T_OPEN_CURLY_BRACKET), ($stackPtr + 1), null, false, null, true);
+ $namespaceName = trim($phpcsFile->getTokensAsString(($stackPtr + 1), ($endToken - $stackPtr - 1)));
+ if (empty($namespaceName) === true) {
+ return;
+ }
+
+ $namespaceParts = explode('\\', $namespaceName);
+ foreach ($namespaceParts as $namespacePart) {
+ $partLc = strtolower($namespacePart);
+ if (isset($this->invalidNames[$partLc]) === false) {
+ continue;
+ }
+
+ // Find the token position of the part which matched.
+ for ($i = ($stackPtr + 1); $i < $endToken; $i++) {
+ if ($tokens[$i]['content'] === $namespacePart) {
+ $nextNonEmpty = $i;
+ break;
+ }
+ }
+ }
+ unset($i, $namespacePart, $partLc);
+ }
+
+ $nextContentLc = strtolower($tokens[$nextNonEmpty]['content']);
+ if (isset($this->invalidNames[$nextContentLc]) === false) {
+ return;
+ }
+
+ /*
+ * Deal with PHP 7 relaxing the rules.
+ * "As of PHP 7.0.0 these keywords are allowed as property, constant, and method names
+ * of classes, interfaces and traits, except that class may not be used as constant name."
+ */
+ if ((($tokens[$stackPtr]['type'] === 'T_FUNCTION'
+ && $this->inClassScope($phpcsFile, $stackPtr, false) === true)
+ || ($tokens[$stackPtr]['type'] === 'T_CONST'
+ && $this->isClassConstant($phpcsFile, $stackPtr) === true
+ && $nextContentLc !== 'class'))
+ && $this->supportsBelow('5.6') === false
+ ) {
+ return;
+ }
+
+ if ($this->supportsAbove($this->invalidNames[$nextContentLc])) {
+ $data = array(
+ $tokens[$nextNonEmpty]['content'],
+ $this->invalidNames[$nextContentLc],
+ );
+ $this->addError($phpcsFile, $stackPtr, $tokens[$nextNonEmpty]['content'], $data);
+ }
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param array $tokens The stack of tokens that make up
+ * the file.
+ *
+ * @return void
+ */
+ public function processString(File $phpcsFile, $stackPtr, $tokens)
+ {
+ $tokenContentLc = strtolower($tokens[$stackPtr]['content']);
+
+ /*
+ * Special case for PHP versions where the target is not yet identified as
+ * its own token, but presents as T_STRING.
+ * - trait keyword in PHP < 5.4
+ */
+ if (version_compare(PHP_VERSION_ID, '50400', '<') && $tokenContentLc === 'trait') {
+ $this->processNonString($phpcsFile, $stackPtr, $tokens);
+ return;
+ }
+
+ // Look for any define/defined tokens (both T_STRING ones, blame Tokenizer).
+ if ($tokenContentLc !== 'define' && $tokenContentLc !== 'defined') {
+ return;
+ }
+
+ // Retrieve the define(d) constant name.
+ $firstParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 1);
+ if ($firstParam === false) {
+ return;
+ }
+
+ $defineName = $this->stripQuotes($firstParam['raw']);
+ $defineNameLc = strtolower($defineName);
+
+ if (isset($this->invalidNames[$defineNameLc]) && $this->supportsAbove($this->invalidNames[$defineNameLc])) {
+ $data = array(
+ $defineName,
+ $this->invalidNames[$defineNameLc],
+ );
+ $this->addError($phpcsFile, $stackPtr, $defineNameLc, $data);
+ }
+ }
+
+
+ /**
+ * Add the error message.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param string $content The token content found.
+ * @param array $data The data to pass into the error message.
+ *
+ * @return void
+ */
+ protected function addError(File $phpcsFile, $stackPtr, $content, $data)
+ {
+ $error = "Function name, class name, namespace name or constant name can not be reserved keyword '%s' (since version %s)";
+ $errorCode = $this->stringToErrorCode($content) . 'Found';
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+
+
+ /**
+ * Check if the current token code is for a token which can be considered
+ * the end of a (partial) use statement.
+ *
+ * @param int $token The current token information.
+ *
+ * @return bool
+ */
+ protected function isEndOfUseStatement($token)
+ {
+ return in_array($token['code'], array(T_CLOSE_CURLY_BRACKET, T_SEMICOLON, T_COMMA), true);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/NewKeywordsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/NewKeywordsSniff.php
new file mode 100644
index 0000000..b2bd330
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/NewKeywordsSniff.php
@@ -0,0 +1,366 @@
+
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Keywords;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Keywords\NewKeywordsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+class NewKeywordsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new keywords, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the last version which did not contain the keyword.
+ *
+ * Description will be used as part of the error message.
+ * Condition is the name of a callback method within this class or the parent class
+ * which checks whether the token complies with a certain condition.
+ * The callback function will be passed the $phpcsFile and the $stackPtr.
+ * The callback function should return `true` if the condition is met and the
+ * error should *not* be thrown.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newKeywords = array(
+ 'T_HALT_COMPILER' => array(
+ '5.0' => false,
+ '5.1' => true,
+ 'description' => '"__halt_compiler" keyword',
+ ),
+ 'T_CONST' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '"const" keyword',
+ 'condition' => 'isClassConstant', // Keyword is only new when not in class context.
+ ),
+ 'T_CALLABLE' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'description' => '"callable" keyword',
+ 'content' => 'callable',
+ ),
+ 'T_DIR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '__DIR__ magic constant',
+ 'content' => '__DIR__',
+ ),
+ 'T_GOTO' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '"goto" keyword',
+ 'content' => 'goto',
+ ),
+ 'T_INSTEADOF' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'description' => '"insteadof" keyword (for traits)',
+ 'content' => 'insteadof',
+ ),
+ 'T_NAMESPACE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '"namespace" keyword',
+ 'content' => 'namespace',
+ ),
+ 'T_NS_C' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '__NAMESPACE__ magic constant',
+ 'content' => '__NAMESPACE__',
+ ),
+ 'T_USE' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '"use" keyword (for traits/namespaces/anonymous functions)',
+ ),
+ 'T_START_NOWDOC' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => 'nowdoc functionality',
+ ),
+ 'T_END_NOWDOC' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => 'nowdoc functionality',
+ ),
+ 'T_START_HEREDOC' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => '(Double) quoted Heredoc identifier',
+ 'condition' => 'isNotQuoted', // Heredoc is only new with quoted identifier.
+ ),
+ 'T_TRAIT' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'description' => '"trait" keyword',
+ 'content' => 'trait',
+ ),
+ 'T_TRAIT_C' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'description' => '__TRAIT__ magic constant',
+ 'content' => '__TRAIT__',
+ ),
+ // The specifics for distinguishing between 'yield' and 'yield from' are dealt
+ // with in the translation logic.
+ // This token has to be placed above the `T_YIELD` token in this array to allow for this.
+ 'T_YIELD_FROM' => array(
+ '5.6' => false,
+ '7.0' => true,
+ 'description' => '"yield from" keyword (for generators)',
+ 'content' => 'yield',
+ ),
+ 'T_YIELD' => array(
+ '5.4' => false,
+ '5.5' => true,
+ 'description' => '"yield" keyword (for generators)',
+ 'content' => 'yield',
+ ),
+ 'T_FINALLY' => array(
+ '5.4' => false,
+ '5.5' => true,
+ 'description' => '"finally" keyword (in exception handling)',
+ 'content' => 'finally',
+ ),
+ );
+
+ /**
+ * Translation table for T_STRING tokens.
+ *
+ * Will be set up from the register() method.
+ *
+ * @var array(string => string)
+ */
+ protected $translateContentToToken = array();
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array();
+ $translate = array();
+ foreach ($this->newKeywords as $token => $versions) {
+ if (defined($token)) {
+ $tokens[] = constant($token);
+ }
+ if (isset($versions['content'])) {
+ $translate[strtolower($versions['content'])] = $token;
+ }
+ }
+
+ /*
+ * Deal with tokens not recognized by the PHP version the sniffer is run
+ * under and (not correctly) compensated for by PHPCS.
+ */
+ if (empty($translate) === false) {
+ $this->translateContentToToken = $translate;
+ $tokens[] = T_STRING;
+ }
+
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $tokenType = $tokens[$stackPtr]['type'];
+
+ // Allow for dealing with multi-token keywords, like "yield from".
+ $end = $stackPtr;
+
+ // Translate T_STRING token if necessary.
+ if ($tokens[$stackPtr]['type'] === 'T_STRING') {
+ $content = strtolower($tokens[$stackPtr]['content']);
+
+ if (isset($this->translateContentToToken[$content]) === false) {
+ // Not one of the tokens we're looking for.
+ return;
+ }
+
+ $tokenType = $this->translateContentToToken[$content];
+ }
+
+ /*
+ * Special case: distinguish between `yield` and `yield from`.
+ *
+ * PHPCS currently (at least up to v 3.0.1) does not backfill for the
+ * `yield` nor the `yield from` keywords.
+ * See: https://github.com/squizlabs/PHP_CodeSniffer/issues/1524
+ *
+ * In PHP < 5.5, both `yield` as well as `from` are tokenized as T_STRING.
+ * In PHP 5.5 - 5.6, `yield` is tokenized as T_YIELD and `from` as T_STRING,
+ * but the `T_YIELD_FROM` token *is* defined in PHP.
+ * In PHP 7.0+ both are tokenized as their respective token, however,
+ * a multi-line "yield from" is tokenized as two tokens.
+ */
+ if ($tokenType === 'T_YIELD') {
+ $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($end + 1), null, true);
+ if ($tokens[$nextToken]['code'] === T_STRING
+ && $tokens[$nextToken]['content'] === 'from'
+ ) {
+ $tokenType = 'T_YIELD_FROM';
+ $end = $nextToken;
+ }
+ unset($nextToken);
+ }
+
+ if ($tokenType === 'T_YIELD_FROM' && $tokens[($stackPtr - 1)]['type'] === 'T_YIELD_FROM') {
+ // Multi-line "yield from", no need to report it twice.
+ return;
+ }
+
+ if (isset($this->newKeywords[$tokenType]) === false) {
+ return;
+ }
+
+ $nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true);
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+
+ if ($prevToken !== false
+ && ($tokens[$prevToken]['code'] === T_DOUBLE_COLON
+ || $tokens[$prevToken]['code'] === T_OBJECT_OPERATOR)
+ ) {
+ // Class property of the same name as one of the keywords. Ignore.
+ return;
+ }
+
+ // Skip attempts to use keywords as functions or class names - the former
+ // will be reported by ForbiddenNamesAsInvokedFunctionsSniff, whilst the
+ // latter will be (partially) reported by the ForbiddenNames sniff.
+ // Either type will result in false-positives when targetting lower versions
+ // of PHP where the name was not reserved, unless we explicitly check for
+ // them.
+ if (($nextToken === false
+ || $tokens[$nextToken]['type'] !== 'T_OPEN_PARENTHESIS')
+ && ($prevToken === false
+ || $tokens[$prevToken]['type'] !== 'T_CLASS'
+ || $tokens[$prevToken]['type'] !== 'T_INTERFACE')
+ ) {
+ // Skip based on token scope condition.
+ if (isset($this->newKeywords[$tokenType]['condition'])
+ && call_user_func(array($this, $this->newKeywords[$tokenType]['condition']), $phpcsFile, $stackPtr) === true
+ ) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $tokenType,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newKeywords[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array(
+ 'description',
+ 'condition',
+ 'content',
+ );
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['description'] = $itemArray['description'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ $data[0] = $errorInfo['description'];
+ return $data;
+ }
+
+
+ /**
+ * Callback for the quoted heredoc identifier condition.
+ *
+ * A double quoted identifier will have the opening quote on position 3
+ * in the string: `<<<"ID"`.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return bool
+ */
+ public function isNotQuoted(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ return ($tokens[$stackPtr]['content'][3] !== '"');
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/LanguageConstructs/NewEmptyNonVariableSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/LanguageConstructs/NewEmptyNonVariableSniff.php
new file mode 100644
index 0000000..0f2e160
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/LanguageConstructs/NewEmptyNonVariableSniff.php
@@ -0,0 +1,84 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\LanguageConstructs;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\LanguageConstructs\NewEmptyNonVariableSniff.
+ *
+ * Verify that nothing but variables are passed to empty().
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewEmptyNonVariableSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_EMPTY);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ $open = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+ if ($open === false
+ || $tokens[$open]['code'] !== T_OPEN_PARENTHESIS
+ || isset($tokens[$open]['parenthesis_closer']) === false
+ ) {
+ return;
+ }
+
+ $close = $tokens[$open]['parenthesis_closer'];
+
+ $nestingLevel = 0;
+ if ($close !== ($open + 1) && isset($tokens[$open + 1]['nested_parenthesis'])) {
+ $nestingLevel = count($tokens[$open + 1]['nested_parenthesis']);
+ }
+
+ if ($this->isVariable($phpcsFile, ($open + 1), $close, $nestingLevel) === true) {
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Only variables can be passed to empty() prior to PHP 5.5.',
+ $stackPtr,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/LanguageConstructs/NewLanguageConstructsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/LanguageConstructs/NewLanguageConstructsSniff.php
new file mode 100644
index 0000000..5997b25
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/LanguageConstructs/NewLanguageConstructsSniff.php
@@ -0,0 +1,140 @@
+
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\LanguageConstructs;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\LanguageConstructs\NewLanguageConstructsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+class NewLanguageConstructsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new language constructs, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the keyword appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newConstructs = array(
+ 'T_NS_SEPARATOR' => array(
+ '5.2' => false,
+ '5.3' => true,
+ 'description' => 'the \ operator (for namespaces)',
+ ),
+ 'T_ELLIPSIS' => array(
+ '5.5' => false,
+ '5.6' => true,
+ 'description' => 'variadic functions using ...',
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array();
+ foreach ($this->newConstructs as $token => $versions) {
+ $tokens[] = constant($token);
+ }
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $tokenType = $tokens[$stackPtr]['type'];
+
+ $itemInfo = array(
+ 'name' => $tokenType,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newConstructs[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('description');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['description'] = $itemArray['description'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ $data[0] = $errorInfo['description'];
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/AssignmentOrderSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/AssignmentOrderSniff.php
new file mode 100644
index 0000000..d330d53
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/AssignmentOrderSniff.php
@@ -0,0 +1,183 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Lists;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * List assignment order.
+ *
+ * The list() construct no longer assigns variables in reverse order.
+ * This affects all list constructs where non-unique variables are used.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class AssignmentOrderSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_LIST,
+ T_OPEN_SHORT_ARRAY,
+ );
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void|int Void if not a valid list. If a list construct has been
+ * examined, the stack pointer to the list closer to skip
+ * passed any nested lists which don't need to be examined again.
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] === T_OPEN_SHORT_ARRAY
+ && $this->isShortList($phpcsFile, $stackPtr) === false
+ ) {
+ // Short array, not short list.
+ return;
+ }
+
+ if ($tokens[$stackPtr]['code'] === T_LIST) {
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false
+ || $tokens[$nextNonEmpty]['code'] !== T_OPEN_PARENTHESIS
+ || isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false
+ ) {
+ // Parse error or live coding.
+ return;
+ }
+
+ $opener = $nextNonEmpty;
+ $closer = $tokens[$nextNonEmpty]['parenthesis_closer'];
+ } else {
+ // Short list syntax.
+ $opener = $stackPtr;
+
+ if (isset($tokens[$stackPtr]['bracket_closer'])) {
+ $closer = $tokens[$stackPtr]['bracket_closer'];
+ }
+ }
+
+ if (isset($opener, $closer) === false) {
+ return;
+ }
+
+ /*
+ * OK, so we have the opener & closer, now we need to check all the variables in the
+ * list() to see if there are duplicates as that's the problem.
+ */
+ $hasVars = $phpcsFile->findNext(array(T_VARIABLE, T_DOLLAR), ($opener + 1), $closer);
+ if ($hasVars === false) {
+ // Empty list, not our concern.
+ return ($closer + 1);
+ }
+
+ // Set the variable delimiters based on the list type being examined.
+ $stopPoints = array(T_COMMA);
+ if ($tokens[$stackPtr]['code'] === T_OPEN_SHORT_ARRAY) {
+ $stopPoints[] = T_CLOSE_SHORT_ARRAY;
+ } else {
+ $stopPoints[] = T_CLOSE_PARENTHESIS;
+ }
+
+ $listVars = array();
+ $lastStopPoint = $opener;
+
+ /*
+ * Create a list of all variables used within the `list()` construct.
+ * We're not concerned with whether these are nested or not, as any duplicate
+ * variable name used will be problematic, independent of nesting.
+ */
+ do {
+ $nextStopPoint = $phpcsFile->findNext($stopPoints, ($lastStopPoint + 1), $closer);
+ if ($nextStopPoint === false) {
+ $nextStopPoint = $closer;
+ }
+
+ // Also detect this in PHP 7.1 keyed lists.
+ $hasDoubleArrow = $phpcsFile->findNext(T_DOUBLE_ARROW, ($lastStopPoint + 1), $nextStopPoint);
+ if ($hasDoubleArrow !== false) {
+ $lastStopPoint = $hasDoubleArrow;
+ }
+
+ // Find the start of the variable, allowing for variable variables.
+ $nextStartPoint = $phpcsFile->findNext(array(T_VARIABLE, T_DOLLAR), ($lastStopPoint + 1), $nextStopPoint);
+ if ($nextStartPoint === false) {
+ // Skip past empty bits in the list, i.e. `list( $a, , ,)`.
+ $lastStopPoint = $nextStopPoint;
+ continue;
+ }
+
+ /*
+ * Gather the content of all non-empty tokens to determine the "variable name".
+ * Variable name in this context includes array or object property syntaxes, such
+ * as `$a['name']` and `$b->property`.
+ */
+ $varContent = '';
+
+ for ($i = $nextStartPoint; $i < $nextStopPoint; $i++) {
+ if (isset(Tokens::$emptyTokens[$tokens[$i]['code']])) {
+ continue;
+ }
+
+ $varContent .= $tokens[$i]['content'];
+ }
+
+ if ($varContent !== '') {
+ $listVars[] = $varContent;
+ }
+
+ $lastStopPoint = $nextStopPoint;
+
+ } while ($lastStopPoint < $closer);
+
+ if (empty($listVars)) {
+ // Shouldn't be possible, but just in case.
+ return ($closer + 1);
+ }
+
+ // Verify that all variables used in the list() construct are unique.
+ if (count($listVars) !== count(array_unique($listVars))) {
+ $phpcsFile->addError(
+ 'list() will assign variable from left-to-right since PHP 7.0. Ensure all variables in list() are unique to prevent unexpected results.',
+ $stackPtr,
+ 'Affected'
+ );
+ }
+
+ return ($closer + 1);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/ForbiddenEmptyListAssignmentSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/ForbiddenEmptyListAssignmentSniff.php
new file mode 100644
index 0000000..5fa4dad
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/ForbiddenEmptyListAssignmentSniff.php
@@ -0,0 +1,111 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Lists;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Lists\ForbiddenEmptyListAssignmentSniff.
+ *
+ * Empty list() assignments have been removed in PHP 7.0
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class ForbiddenEmptyListAssignmentSniff extends Sniff
+{
+
+ /**
+ * List of tokens to disregard when determining whether the list() is empty.
+ *
+ * @var array
+ */
+ protected $ignoreTokens = array();
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ // Set up a list of tokens to disregard when determining whether the list() is empty.
+ // Only needs to be set up once.
+ $this->ignoreTokens = Tokens::$emptyTokens;
+ $this->ignoreTokens[T_COMMA] = T_COMMA;
+ $this->ignoreTokens[T_OPEN_PARENTHESIS] = T_OPEN_PARENTHESIS;
+ $this->ignoreTokens[T_CLOSE_PARENTHESIS] = T_CLOSE_PARENTHESIS;
+
+ return array(
+ T_LIST,
+ T_OPEN_SHORT_ARRAY,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] === T_OPEN_SHORT_ARRAY) {
+ if ($this->isShortList($phpcsFile, $stackPtr) === false) {
+ return;
+ }
+
+ $open = $stackPtr;
+ $close = $tokens[$stackPtr]['bracket_closer'];
+ } else {
+ // T_LIST.
+ $open = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr, null, false, null, true);
+ if ($open === false || isset($tokens[$open]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $close = $tokens[$open]['parenthesis_closer'];
+ }
+
+ $error = true;
+ if (($close - $open) > 1) {
+ for ($cnt = $open + 1; $cnt < $close; $cnt++) {
+ if (isset($this->ignoreTokens[$tokens[$cnt]['code']]) === false) {
+ $error = false;
+ break;
+ }
+ }
+ }
+
+ if ($error === true) {
+ $phpcsFile->addError(
+ 'Empty list() assignments are not allowed since PHP 7.0',
+ $stackPtr,
+ 'Found'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewKeyedListSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewKeyedListSniff.php
new file mode 100644
index 0000000..6cd4f73
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewKeyedListSniff.php
@@ -0,0 +1,211 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Lists;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Lists\NewKeyedListSniff.
+ *
+ * "You can now specify keys in list(), or its new shorthand [] syntax. "
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewKeyedListSniff extends Sniff
+{
+ /**
+ * Tokens which represent the start of a list construct.
+ *
+ * @var array
+ */
+ protected $sniffTargets = array(
+ T_LIST => T_LIST,
+ T_OPEN_SHORT_ARRAY => T_OPEN_SHORT_ARRAY,
+ );
+
+ /**
+ * The token(s) within the list construct which is being targeted.
+ *
+ * @var array
+ */
+ protected $targetsInList = array(
+ T_DOUBLE_ARROW => T_DOUBLE_ARROW,
+ );
+
+ /**
+ * All tokens needed to walk through the list construct and
+ * determine whether the target token is contained within.
+ *
+ * Set by the setUpAllTargets() method which is called from within register().
+ *
+ * @var array
+ */
+ protected $allTargets;
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $this->setUpAllTargets();
+
+ return $this->sniffTargets;
+ }
+
+ /**
+ * Prepare the $allTargets array only once.
+ *
+ * @return array
+ */
+ public function setUpAllTargets()
+ {
+ $this->allTargets = $this->sniffTargets + $this->targetsInList;
+ }
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('7.0') === false);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->bowOutEarly() === true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] === T_OPEN_SHORT_ARRAY
+ && $this->isShortList($phpcsFile, $stackPtr) === false
+ ) {
+ // Short array, not short list.
+ return;
+ }
+
+ if ($tokens[$stackPtr]['code'] === T_LIST) {
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false
+ || $tokens[$nextNonEmpty]['code'] !== T_OPEN_PARENTHESIS
+ || isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false
+ ) {
+ // Parse error or live coding.
+ return;
+ }
+
+ $opener = $nextNonEmpty;
+ $closer = $tokens[$nextNonEmpty]['parenthesis_closer'];
+ } else {
+ // Short list syntax.
+ $opener = $stackPtr;
+
+ if (isset($tokens[$stackPtr]['bracket_closer'])) {
+ $closer = $tokens[$stackPtr]['bracket_closer'];
+ }
+ }
+
+ if (isset($opener, $closer) === false) {
+ return;
+ }
+
+ $this->examineList($phpcsFile, $opener, $closer);
+ }
+
+
+ /**
+ * Examine the contents of a list construct to determine whether an error needs to be thrown.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $opener The position of the list open token.
+ * @param int $closer The position of the list close token.
+ *
+ * @return void
+ */
+ protected function examineList(File $phpcsFile, $opener, $closer)
+ {
+ $start = $opener;
+ while (($start = $this->hasTargetInList($phpcsFile, $start, $closer)) !== false) {
+ $phpcsFile->addError(
+ 'Specifying keys in list constructs is not supported in PHP 7.0 or earlier.',
+ $start,
+ 'Found'
+ );
+ }
+ }
+
+
+ /**
+ * Check whether a certain target token exists within a list construct.
+ *
+ * Skips past nested list constructs, so these can be examined based on their own token.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $start The position of the list open token or a token
+ * within the list to start (resume) the examination from.
+ * @param int $closer The position of the list close token.
+ *
+ * @return int|bool Stack pointer to the target token if encountered. False otherwise.
+ */
+ protected function hasTargetInList(File $phpcsFile, $start, $closer)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ for ($i = ($start + 1); $i < $closer; $i++) {
+ if (isset($this->allTargets[$tokens[$i]['code']]) === false) {
+ continue;
+ }
+
+ if (isset($this->targetsInList[$tokens[$i]['code']]) === true) {
+ return $i;
+ }
+
+ // Skip past nested list constructs.
+ if ($tokens[$i]['code'] === T_LIST) {
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
+ if ($nextNonEmpty !== false
+ && $tokens[$nextNonEmpty]['code'] === T_OPEN_PARENTHESIS
+ && isset($tokens[$nextNonEmpty]['parenthesis_closer']) === true
+ ) {
+ $i = $tokens[$nextNonEmpty]['parenthesis_closer'];
+ }
+ } elseif ($tokens[$i]['code'] === T_OPEN_SHORT_ARRAY
+ && isset($tokens[$i]['bracket_closer'])
+ ) {
+ $i = $tokens[$i]['bracket_closer'];
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewListReferenceAssignmentSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewListReferenceAssignmentSniff.php
new file mode 100644
index 0000000..45815ef
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewListReferenceAssignmentSniff.php
@@ -0,0 +1,67 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Lists;
+
+use PHPCompatibility\Sniffs\Lists\NewKeyedListSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * Detect reference assignments in array destructuring using (short) list.
+ *
+ * PHP version 7.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewListReferenceAssignmentSniff extends NewKeyedListSniff
+{
+ /**
+ * The token(s) within the list construct which is being targeted.
+ *
+ * @var array
+ */
+ protected $targetsInList = array(
+ T_BITWISE_AND => T_BITWISE_AND,
+ );
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('7.2') === false);
+ }
+
+ /**
+ * Examine the contents of a list construct to determine whether an error needs to be thrown.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $opener The position of the list open token.
+ * @param int $closer The position of the list close token.
+ *
+ * @return void
+ */
+ protected function examineList(File $phpcsFile, $opener, $closer)
+ {
+ $start = $opener;
+ while (($start = $this->hasTargetInList($phpcsFile, $start, $closer)) !== false) {
+ $phpcsFile->addError(
+ 'Reference assignments within list constructs are not supported in PHP 7.2 or earlier.',
+ $start,
+ 'Found'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewShortListSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewShortListSniff.php
new file mode 100644
index 0000000..91ce212
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Lists/NewShortListSniff.php
@@ -0,0 +1,79 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Lists;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Lists\NewShortListSniff.
+ *
+ * "The shorthand array syntax ([]) may now be used to destructure arrays for
+ * assignments (including within foreach), as an alternative to the existing
+ * list() syntax, which is still supported."
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewShortListSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_OPEN_SHORT_ARRAY);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('7.0') === false) {
+ return;
+ }
+
+ if ($this->isShortList($phpcsFile, $stackPtr) === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $closer = $tokens[$stackPtr]['bracket_closer'];
+
+ $hasVariable = $phpcsFile->findNext(T_VARIABLE, ($stackPtr + 1), $closer);
+ if ($hasVariable === false) {
+ // List syntax is only valid if there are variables in it.
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'The shorthand list syntax "[]" to destructure arrays is not available in PHP 7.0 or earlier.',
+ $stackPtr,
+ 'Found'
+ );
+
+ return ($closer + 1);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/MethodUse/NewDirectCallsToCloneSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/MethodUse/NewDirectCallsToCloneSniff.php
new file mode 100644
index 0000000..c2a8992
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/MethodUse/NewDirectCallsToCloneSniff.php
@@ -0,0 +1,97 @@
+__clone() is now allowed. This was the only magic method
+ * that had a compile-time check preventing some calls to it, which doesn't make sense.
+ * If we allow all other magic methods to be called, there's no reason to forbid this one."
+ *
+ * PHP version 7.0
+ *
+ * @link https://wiki.php.net/rfc/abstract_syntax_tree#directly_calling_clone_is_allowed
+ *
+ * @since 9.1.0
+ */
+class NewDirectCallsToCloneSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @since 9.1.0
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_DOUBLE_COLON,
+ T_OBJECT_OPERATOR,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @since 9.1.0
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.6') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== T_STRING) {
+ /*
+ * Not a method call.
+ *
+ * Note: This disregards method calls with the method name in a variable, like:
+ * $method = '__clone';
+ * $obj->$method();
+ * However, that would be very hard to examine reliably anyway.
+ */
+ return;
+ }
+
+ if (strtolower($tokens[$nextNonEmpty]['content']) !== '__clone') {
+ // Not a call to the __clone() method.
+ return;
+ }
+
+ $nextNextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true);
+ if ($nextNextNonEmpty === false || $tokens[$nextNextNonEmpty]['code'] !== T_OPEN_PARENTHESIS) {
+ // Not a method call.
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Direct calls to the __clone() magic method are not allowed in PHP 5.6 or earlier.',
+ $nextNonEmpty,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Miscellaneous/RemovedAlternativePHPTagsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Miscellaneous/RemovedAlternativePHPTagsSniff.php
new file mode 100644
index 0000000..3e68aaf
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Miscellaneous/RemovedAlternativePHPTagsSniff.php
@@ -0,0 +1,166 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Miscellaneous;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Miscellaneous\RemovedAlternativePHPTags.
+ *
+ * Check for usage of alternative PHP tags - removed in PHP 7.0.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ *
+ * Based on `Generic_Sniffs_PHP_DisallowAlternativePHPTags` by Juliette Reinders Folmer
+ * which was merged into PHPCS 2.7.0.
+ */
+class RemovedAlternativePHPTagsSniff extends Sniff
+{
+
+ /**
+ * Whether ASP tags are enabled or not.
+ *
+ * @var bool
+ */
+ private $aspTags = false;
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ if (version_compare(PHP_VERSION_ID, '70000', '<') === true) {
+ // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.asp_tagsRemoved
+ $this->aspTags = (bool) ini_get('asp_tags');
+ }
+
+ return array(
+ T_OPEN_TAG,
+ T_OPEN_TAG_WITH_ECHO,
+ T_INLINE_HTML,
+ );
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $openTag = $tokens[$stackPtr];
+ $content = trim($openTag['content']);
+
+ if ($content === '' || $content === ']+)?language=[\'"]?php[\'"]?(?:[^>]+)?>)`i', $content, $match) === 1
+ ) {
+ $found = $match[1];
+ $data = array(
+ 'Script',
+ $found,
+ );
+ $errorCode = 'ScriptOpenTagFound';
+ }
+
+ if (isset($errorCode, $data)) {
+ $phpcsFile->addError(
+ '%s style opening tags have been removed in PHP 7.0. Found "%s"',
+ $stackPtr,
+ $errorCode,
+ $data
+ );
+ return;
+ }
+
+ // If we're still here, we can't be sure if what we find was really intended as ASP open tags.
+ if ($openTag['code'] === T_INLINE_HTML && $this->aspTags === false) {
+ if (strpos($content, '<%') !== false) {
+ $error = 'Possible use of ASP style opening tags detected. ASP style opening tags have been removed in PHP 7.0. Found: %s';
+ $snippet = $this->getSnippet($content, '<%');
+ $data = array('<%' . $snippet);
+
+ $phpcsFile->addWarning($error, $stackPtr, 'MaybeASPOpenTagFound', $data);
+ }
+ }
+ }
+
+
+ /**
+ * Get a snippet from a HTML token.
+ *
+ * @param string $content The content of the HTML token.
+ * @param string $startAt Partial string to use as a starting point for the snippet.
+ * @param int $length The target length of the snippet to get. Defaults to 25.
+ *
+ * @return string
+ */
+ protected function getSnippet($content, $startAt = '', $length = 25)
+ {
+ $startPos = 0;
+
+ if ($startAt !== '') {
+ $startPos = strpos($content, $startAt);
+ if ($startPos !== false) {
+ $startPos += strlen($startAt);
+ }
+ }
+
+ $snippet = substr($content, $startPos, $length);
+ if ((strlen($content) - $startPos) > $length) {
+ $snippet .= '...';
+ }
+
+ return $snippet;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Miscellaneous/ValidIntegersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Miscellaneous/ValidIntegersSniff.php
new file mode 100644
index 0000000..998240f
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Miscellaneous/ValidIntegersSniff.php
@@ -0,0 +1,220 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Miscellaneous;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Miscellaneous\ValidIntegersSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ValidIntegersSniff extends Sniff
+{
+
+ /**
+ * Whether PHPCS is run on a PHP < 5.4.
+ *
+ * @var bool
+ */
+ protected $isLowPHPVersion = false;
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $this->isLowPHPVersion = version_compare(PHP_VERSION_ID, '50400', '<');
+
+ return array(
+ T_LNUMBER, // Binary, octal integers.
+ T_CONSTANT_ENCAPSED_STRING, // Hex numeric string.
+ );
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $token = $tokens[$stackPtr];
+
+ if ($this->couldBeBinaryInteger($tokens, $stackPtr) === true) {
+ if ($this->supportsBelow('5.3')) {
+ $error = 'Binary integer literals were not present in PHP version 5.3 or earlier. Found: %s';
+ if ($this->isLowPHPVersion === false) {
+ $data = array($token['content']);
+ } else {
+ $data = array($this->getBinaryInteger($phpcsFile, $tokens, $stackPtr));
+ }
+ $phpcsFile->addError($error, $stackPtr, 'BinaryIntegerFound', $data);
+ }
+
+ if ($this->isInvalidBinaryInteger($tokens, $stackPtr) === true) {
+ $error = 'Invalid binary integer detected. Found: %s';
+ $data = array($this->getBinaryInteger($phpcsFile, $tokens, $stackPtr));
+ $phpcsFile->addWarning($error, $stackPtr, 'InvalidBinaryIntegerFound', $data);
+ }
+ return;
+ }
+
+ $isError = $this->supportsAbove('7.0');
+ $data = array( $token['content'] );
+
+ if ($this->isInvalidOctalInteger($tokens, $stackPtr) === true) {
+ $this->addMessage(
+ $phpcsFile,
+ 'Invalid octal integer detected. Prior to PHP 7 this would lead to a truncated number. From PHP 7 onwards this causes a parse error. Found: %s',
+ $stackPtr,
+ $isError,
+ 'InvalidOctalIntegerFound',
+ $data
+ );
+ return;
+ }
+
+ if ($this->isHexidecimalNumericString($tokens, $stackPtr) === true) {
+ $this->addMessage(
+ $phpcsFile,
+ 'The behaviour of hexadecimal numeric strings was inconsistent prior to PHP 7 and support has been removed in PHP 7. Found: %s',
+ $stackPtr,
+ $isError,
+ 'HexNumericStringFound',
+ $data
+ );
+ return;
+ }
+ }
+
+
+ /**
+ * Could the current token an potentially be a binary integer ?
+ *
+ * @param array $tokens Token stack.
+ * @param int $stackPtr The current position in the token stack.
+ *
+ * @return bool
+ */
+ private function couldBeBinaryInteger($tokens, $stackPtr)
+ {
+ $token = $tokens[$stackPtr];
+
+ if ($token['code'] !== T_LNUMBER) {
+ return false;
+ }
+
+ if ($this->isLowPHPVersion === false) {
+ return (preg_match('`^0b[0-1]+$`D', $token['content']) === 1);
+ }
+ // Pre-5.4, binary strings are tokenized as T_LNUMBER (0) + T_STRING ("b01010101").
+ // At this point, we don't yet care whether it's a valid binary int, that's a separate check.
+ else {
+ return($token['content'] === '0' && $tokens[$stackPtr + 1]['code'] === T_STRING && preg_match('`^b[0-9]+$`D', $tokens[$stackPtr + 1]['content']) === 1);
+ }
+ }
+
+ /**
+ * Is the current token an invalid binary integer ?
+ *
+ * @param array $tokens Token stack.
+ * @param int $stackPtr The current position in the token stack.
+ *
+ * @return bool
+ */
+ private function isInvalidBinaryInteger($tokens, $stackPtr)
+ {
+ if ($this->couldBeBinaryInteger($tokens, $stackPtr) === false) {
+ return false;
+ }
+
+ if ($this->isLowPHPVersion === false) {
+ // If it's an invalid binary int, the token will be split into two T_LNUMBER tokens.
+ return ($tokens[$stackPtr + 1]['code'] === T_LNUMBER);
+ } else {
+ return (preg_match('`^b[0-1]+$`D', $tokens[$stackPtr + 1]['content']) === 0);
+ }
+ }
+
+ /**
+ * Retrieve the content of the tokens which together look like a binary integer.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param array $tokens Token stack.
+ * @param int $stackPtr The position of the current token in
+ * the stack.
+ *
+ * @return string
+ */
+ private function getBinaryInteger(File $phpcsFile, $tokens, $stackPtr)
+ {
+ $length = 2; // PHP < 5.4 T_LNUMBER + T_STRING.
+
+ if ($this->isLowPHPVersion === false) {
+ $i = $stackPtr;
+ while ($tokens[$i]['code'] === T_LNUMBER) {
+ $i++;
+ }
+ $length = ($i - $stackPtr);
+ }
+
+ return $phpcsFile->getTokensAsString($stackPtr, $length);
+ }
+
+ /**
+ * Is the current token an invalid octal integer ?
+ *
+ * @param array $tokens Token stack.
+ * @param int $stackPtr The current position in the token stack.
+ *
+ * @return bool
+ */
+ private function isInvalidOctalInteger($tokens, $stackPtr)
+ {
+ $token = $tokens[$stackPtr];
+
+ if ($token['code'] === T_LNUMBER && preg_match('`^0[0-7]*[8-9]+[0-9]*$`D', $token['content']) === 1) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Is the current token a hexidecimal numeric string ?
+ *
+ * @param array $tokens Token stack.
+ * @param int $stackPtr The current position in the token stack.
+ *
+ * @return bool
+ */
+ private function isHexidecimalNumericString($tokens, $stackPtr)
+ {
+ $token = $tokens[$stackPtr];
+
+ if ($token['code'] === T_CONSTANT_ENCAPSED_STRING && preg_match('`^0x[a-f0-9]+$`iD', $this->stripQuotes($token['content'])) === 1) {
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/ForbiddenNegativeBitshiftSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/ForbiddenNegativeBitshiftSniff.php
new file mode 100644
index 0000000..683bb4d
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/ForbiddenNegativeBitshiftSniff.php
@@ -0,0 +1,104 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Operators;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Operators\ForbiddenNegativeBitshift.
+ *
+ * Bitwise shifts by negative number will throw an ArithmeticError in PHP 7.0.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class ForbiddenNegativeBitshiftSniff extends Sniff
+{
+ /**
+ * Potential end tokens for which the end pointer has to be set back by one.
+ *
+ * {@internal The PHPCS `findEndOfStatement()` method is not completely consistent
+ * in how it returns the statement end. This is just a simple way to bypass
+ * the inconsistency for our purposes.}}
+ *
+ * @var array
+ */
+ private $inclusiveStopPoints = array(
+ T_COLON => true,
+ T_COMMA => true,
+ T_DOUBLE_ARROW => true,
+ T_SEMICOLON => true,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_SL,
+ T_SL_EQUAL,
+ T_SR,
+ T_SR_EQUAL,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Determine the start and end of the part of the statement we need to examine.
+ $start = ($stackPtr + 1);
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, $start, null, true);
+ if ($next !== false && $tokens[$next]['code'] === T_OPEN_PARENTHESIS) {
+ $start = ($next + 1);
+ }
+
+ $end = PHPCSHelper::findEndOfStatement($phpcsFile, $start);
+ if (isset($this->inclusiveStopPoints[$tokens[$end]['code']]) === true) {
+ --$end;
+ }
+
+ if ($this->isNegativeNumber($phpcsFile, $start, $end, true) !== true) {
+ // Not a negative number or undetermined.
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Bitwise shifts by negative number will throw an ArithmeticError in PHP 7.0. Found: %s',
+ $stackPtr,
+ 'Found',
+ array($phpcsFile->getTokensAsString($start, ($end - $start + 1)))
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/NewOperatorsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/NewOperatorsSniff.php
new file mode 100644
index 0000000..637c649
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/NewOperatorsSniff.php
@@ -0,0 +1,294 @@
+
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Operators;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Operators\NewOperatorsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2013 Cu.be Solutions bvba
+ */
+class NewOperatorsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new operators, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the keyword appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newOperators = array(
+ 'T_POW' => array(
+ '5.5' => false,
+ '5.6' => true,
+ 'description' => 'power operator (**)',
+ ), // Identified in PHP < 5.6 icw PHPCS < 2.4.0 as T_MULTIPLY + T_MULTIPLY.
+ 'T_POW_EQUAL' => array(
+ '5.5' => false,
+ '5.6' => true,
+ 'description' => 'power assignment operator (**=)',
+ ), // Identified in PHP < 5.6 icw PHPCS < 2.6.0 as T_MULTIPLY + T_MUL_EQUAL.
+ 'T_SPACESHIP' => array(
+ '5.6' => false,
+ '7.0' => true,
+ 'description' => 'spaceship operator (<=>)',
+ ), // Identified in PHP < 7.0 icw PHPCS < 2.5.1 as T_IS_SMALLER_OR_EQUAL + T_GREATER_THAN.
+ 'T_COALESCE' => array(
+ '5.6' => false,
+ '7.0' => true,
+ 'description' => 'null coalescing operator (??)',
+ ), // Identified in PHP < 7.0 icw PHPCS < 2.6.2 as T_INLINE_THEN + T_INLINE_THEN.
+ /*
+ * Was slated for 7.2, but still not implemented. PHPCS however does already tokenize it.
+ * @link https://wiki.php.net/rfc/null_coalesce_equal_operator
+ */
+ 'T_COALESCE_EQUAL' => array(
+ '7.3' => false,
+ '7.4' => true,
+ 'description' => 'null coalesce equal operator (??=)',
+ ), // Identified in PHP < 7.0 icw PHPCS < 2.6.2 as T_INLINE_THEN + T_INLINE_THEN + T_EQUAL and between PHPCS 2.6.2 and PHPCS 2.8.1 as T_COALESCE + T_EQUAL.
+ );
+
+
+ /**
+ * A list of new operators which are not recognized in older PHPCS versions.
+ *
+ * The array lists an alternative token to listen for.
+ *
+ * @var array(string => int)
+ */
+ protected $newOperatorsPHPCSCompat = array(
+ 'T_POW' => T_MULTIPLY,
+ 'T_POW_EQUAL' => T_MUL_EQUAL,
+ 'T_SPACESHIP' => T_GREATER_THAN,
+ 'T_COALESCE' => T_INLINE_THEN,
+ 'T_COALESCE_EQUAL' => T_EQUAL,
+ );
+
+ /**
+ * Token translation table for older PHPCS versions.
+ *
+ * The 'before' index lists the token which would have to be directly before the
+ * token found for it to be one of the new operators.
+ * The 'real_token' index indicates which operator was found in that case.
+ *
+ * If the token combination has multi-layer complexity, such as is the case
+ * with T_COALESCE(_EQUAL), a 'callback' index is added instead pointing to a
+ * separate function which can determine whether this is the targetted token across
+ * PHP and PHPCS versions.
+ *
+ * {@internal 'before' was chosen rather than 'after' as that allowed for a 1-on-1
+ * translation list with the current tokens.}}
+ *
+ * @var array(string => array(string => string))
+ */
+ protected $PHPCSCompatTranslate = array(
+ 'T_MULTIPLY' => array(
+ 'before' => 'T_MULTIPLY',
+ 'real_token' => 'T_POW',
+ ),
+ 'T_MUL_EQUAL' => array(
+ 'before' => 'T_MULTIPLY',
+ 'real_token' => 'T_POW_EQUAL',
+ ),
+ 'T_GREATER_THAN' => array(
+ 'before' => 'T_IS_SMALLER_OR_EQUAL',
+ 'real_token' => 'T_SPACESHIP',
+ ),
+ 'T_INLINE_THEN' => array(
+ 'callback' => 'isTCoalesce',
+ 'real_token' => 'T_COALESCE',
+ ),
+ 'T_EQUAL' => array(
+ 'callback' => 'isTCoalesceEqual',
+ 'real_token' => 'T_COALESCE_EQUAL',
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array();
+ foreach ($this->newOperators as $token => $versions) {
+ if (defined($token)) {
+ $tokens[] = constant($token);
+ } elseif (isset($this->newOperatorsPHPCSCompat[$token])) {
+ $tokens[] = $this->newOperatorsPHPCSCompat[$token];
+ }
+ }
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $tokenType = $tokens[$stackPtr]['type'];
+
+ // Translate older PHPCS token combis for new operators to the actual operator.
+ if (isset($this->newOperators[$tokenType]) === false) {
+ if (isset($this->PHPCSCompatTranslate[$tokenType])
+ && ((isset($this->PHPCSCompatTranslate[$tokenType]['before'], $tokens[$stackPtr - 1]) === true
+ && $tokens[$stackPtr - 1]['type'] === $this->PHPCSCompatTranslate[$tokenType]['before'])
+ || (isset($this->PHPCSCompatTranslate[$tokenType]['callback']) === true
+ && call_user_func(array($this, $this->PHPCSCompatTranslate[$tokenType]['callback']), $tokens, $stackPtr) === true))
+ ) {
+ $tokenType = $this->PHPCSCompatTranslate[$tokenType]['real_token'];
+ }
+ } elseif ($tokenType === 'T_COALESCE') {
+ // Make sure that T_COALESCE is not confused with T_COALESCE_EQUAL.
+ if (isset($tokens[($stackPtr + 1)]) !== false && $tokens[($stackPtr + 1)]['code'] === T_EQUAL) {
+ // Ignore as will be dealt with via the T_EQUAL token.
+ return;
+ }
+ }
+
+ // If the translation did not yield one of the tokens we are looking for, bow out.
+ if (isset($this->newOperators[$tokenType]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $tokenType,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newOperators[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('description');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['description'] = $itemArray['description'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ $data[0] = $errorInfo['description'];
+ return $data;
+ }
+
+
+ /**
+ * Callback function to determine whether a T_EQUAL token is really a T_COALESCE_EQUAL token.
+ *
+ * @param array $tokens The token stack.
+ * @param int $stackPtr The current position in the token stack.
+ *
+ * @return bool
+ */
+ private function isTCoalesceEqual($tokens, $stackPtr)
+ {
+ if ($tokens[$stackPtr]['code'] !== T_EQUAL || isset($tokens[($stackPtr - 1)]) === false) {
+ // Function called for wrong token or token has no predecesor.
+ return false;
+ }
+
+ if ($tokens[($stackPtr - 1)]['type'] === 'T_COALESCE') {
+ return true;
+ }
+ if ($tokens[($stackPtr - 1)]['type'] === 'T_INLINE_THEN'
+ && (isset($tokens[($stackPtr - 2)]) && $tokens[($stackPtr - 2)]['type'] === 'T_INLINE_THEN')
+ ) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Callback function to determine whether a T_INLINE_THEN token is really a T_COALESCE token.
+ *
+ * @param array $tokens The token stack.
+ * @param int $stackPtr The current position in the token stack.
+ *
+ * @return bool
+ */
+ private function isTCoalesce($tokens, $stackPtr)
+ {
+ if ($tokens[$stackPtr]['code'] !== T_INLINE_THEN || isset($tokens[($stackPtr - 1)]) === false) {
+ // Function called for wrong token or token has no predecesor.
+ return false;
+ }
+
+ if ($tokens[($stackPtr - 1)]['code'] === T_INLINE_THEN) {
+ // Make sure not to confuse it with the T_COALESCE_EQUAL token.
+ if (isset($tokens[($stackPtr + 1)]) === false || $tokens[($stackPtr + 1)]['code'] !== T_EQUAL) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/NewShortTernarySniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/NewShortTernarySniff.php
new file mode 100644
index 0000000..1a5a753
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Operators/NewShortTernarySniff.php
@@ -0,0 +1,74 @@
+
+ * @copyright 2012 Ben Selby
+ */
+
+namespace PHPCompatibility\Sniffs\Operators;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Operators\NewShortTernarySniff.
+ *
+ * Performs checks on ternary operators, specifically that the middle expression
+ * is not omitted for versions that don't support this.
+ *
+ * PHP version 5.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Ben Selby
+ * @copyright 2012 Ben Selby
+ */
+class NewShortTernarySniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_INLINE_THEN);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.2') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Get next non-whitespace token, and check it isn't the related inline else
+ // symbol, which is not allowed prior to PHP 5.3.
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+
+ if ($next !== false && $tokens[$next]['code'] === T_INLINE_ELSE) {
+ $phpcsFile->addError(
+ 'Middle may not be omitted from ternary operators in PHP < 5.3',
+ $stackPtr,
+ 'MiddleMissing'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/ForbiddenGetClassNullSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/ForbiddenGetClassNullSniff.php
new file mode 100644
index 0000000..7e3f930
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/ForbiddenGetClassNullSniff.php
@@ -0,0 +1,80 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\ForbiddenGetClassNullSniff.
+ *
+ * Detect: Passing `null` to get_class() is no longer allowed as of PHP 7.2.
+ * This will now result in an E_WARNING being thrown.
+ *
+ * PHP version 7.2
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class ForbiddenGetClassNullSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'get_class' => true,
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsAbove('7.2') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[1]) === false) {
+ return;
+ }
+
+ if ($parameters[1]['raw'] !== 'null') {
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Passing "null" as the $object to get_class() is not allowed since PHP 7.2.',
+ $parameters[1]['start'],
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewArrayReduceInitialTypeSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewArrayReduceInitialTypeSniff.php
new file mode 100644
index 0000000..e4c8ab6
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewArrayReduceInitialTypeSniff.php
@@ -0,0 +1,106 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\NewArrayReduceInitialTypeSniff.
+ *
+ * Detect: In PHP 5.2 and lower, the $initial parameter had to be an integer.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewArrayReduceInitialTypeSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'array_reduce' => true,
+ );
+
+ /**
+ * Tokens which, for the purposes of this sniff, indicate that there is
+ * a variable element to the value passed.
+ *
+ * @var array
+ */
+ private $variableValueTokens = array(
+ T_VARIABLE,
+ T_STRING,
+ T_SELF,
+ T_PARENT,
+ T_STATIC,
+ T_DOUBLE_QUOTED_STRING,
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('5.2') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[3]) === false) {
+ return;
+ }
+
+ $targetParam = $parameters[3];
+ if ($this->isNumber($phpcsFile, $targetParam['start'], $targetParam['end'], true) !== false) {
+ return;
+ }
+
+ if ($this->isNumericCalculation($phpcsFile, $targetParam['start'], $targetParam['end']) === true) {
+ return;
+ }
+
+ $error = 'Passing a non-integer as the value for $initial to array_reduce() is not supported in PHP 5.2 or lower.';
+ if ($phpcsFile->findNext($this->variableValueTokens, $targetParam['start'], ($targetParam['end'] + 1)) === false) {
+ $phpcsFile->addError(
+ $error . ' Found %s',
+ $targetParam['start'],
+ 'InvalidTypeFound',
+ array($targetParam['raw'])
+ );
+ } else {
+ $phpcsFile->addWarning(
+ $error . ' Variable value found. Found %s',
+ $targetParam['start'],
+ 'VariableFound',
+ array($targetParam['raw'])
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewFopenModesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewFopenModesSniff.php
new file mode 100644
index 0000000..07245d4
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewFopenModesSniff.php
@@ -0,0 +1,112 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\NewFopenModesSniff.
+ *
+ * Detect: Changes in allowed values for the fopen() $mode parameter.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewFopenModesSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'fopen' => true,
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ // Version used here should be (above) the highest version from the `newModes` control,
+ // structure below, i.e. the last PHP version in which a new mode was introduced.
+ return ($this->supportsBelow('7.1') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[2]) === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $targetParam = $parameters[2];
+ $errors = array();
+
+ for ($i = $targetParam['start']; $i <= $targetParam['end']; $i++) {
+ if ($tokens[$i]['code'] !== T_CONSTANT_ENCAPSED_STRING) {
+ continue;
+ }
+
+ if (strpos($tokens[$i]['content'], 'c+') !== false && $this->supportsBelow('5.2.5')) {
+ $errors['cplusFound'] = array(
+ 'c+',
+ '5.2.5',
+ $targetParam['raw'],
+ );
+ } elseif (strpos($tokens[$i]['content'], 'c') !== false && $this->supportsBelow('5.2.5')) {
+ $errors['cFound'] = array(
+ 'c',
+ '5.2.5',
+ $targetParam['raw'],
+ );
+ }
+
+ if (strpos($tokens[$i]['content'], 'e') !== false && $this->supportsBelow('7.0.15')) {
+ $errors['eFound'] = array(
+ 'e',
+ '7.0.15',
+ $targetParam['raw'],
+ );
+ }
+ }
+
+ if (empty($errors) === true) {
+ return;
+ }
+
+ foreach ($errors as $errorCode => $errorData) {
+ $phpcsFile->addError(
+ 'Passing "%s" as the $mode to fopen() is not supported in PHP %s or lower. Found %s',
+ $targetParam['start'],
+ $errorCode,
+ $errorData
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewHashAlgorithmsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewHashAlgorithmsSniff.php
new file mode 100644
index 0000000..4e60bfb
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewHashAlgorithmsSniff.php
@@ -0,0 +1,167 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\NewHashAlgorithmsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewHashAlgorithmsSniff extends AbstractNewFeatureSniff
+{
+ /**
+ * A list of new hash algorithms, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the hash algorithm appears.
+ *
+ * @var array(string => array(string => bool))
+ */
+ protected $newAlgorithms = array(
+ 'md2' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ripemd256' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'ripemd320' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'salsa10' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'salsa20' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'snefru256' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'sha224' => array(
+ '5.2' => false,
+ '5.3' => true,
+ ),
+ 'joaat' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'fnv132' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'fnv164' => array(
+ '5.3' => false,
+ '5.4' => true,
+ ),
+ 'gost-crypto' => array(
+ '5.5' => false,
+ '5.6' => true,
+ ),
+
+ 'sha512/224' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sha512/256' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sha3-224' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sha3-256' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sha3-384' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ 'sha3-512' => array(
+ '7.0' => false,
+ '7.1' => true,
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $algo = $this->getHashAlgorithmParameter($phpcsFile, $stackPtr);
+ if (empty($algo) || is_string($algo) === false) {
+ return;
+ }
+
+ // Bow out if not one of the algorithms we're targetting.
+ if (isset($this->newAlgorithms[$algo]) === false) {
+ return;
+ }
+
+ // Check if the algorithm used is new.
+ $itemInfo = array(
+ 'name' => $algo,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newAlgorithms[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The %s hash algorithm is not present in PHP version %s or earlier';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewNegativeStringOffsetSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewNegativeStringOffsetSniff.php
new file mode 100644
index 0000000..8ef932a
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewNegativeStringOffsetSniff.php
@@ -0,0 +1,126 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\NewNegativeStringOffsetSniff.
+ *
+ * Detect: negative string offsets as parameters passed to functions where this
+ * was not allowed prior to PHP 7.1.
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewNegativeStringOffsetSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array Function name => 1-based parameter offset of the affected parameters => parameter name.
+ */
+ protected $targetFunctions = array(
+ 'file_get_contents' => array(
+ 4 => 'offset',
+ ),
+ 'grapheme_extract' => array(
+ 4 => 'start',
+ ),
+ 'grapheme_stripos' => array(
+ 3 => 'offset',
+ ),
+ 'grapheme_strpos' => array(
+ 3 => 'offset',
+ ),
+ 'iconv_strpos' => array(
+ 3 => 'offset',
+ ),
+ 'mb_ereg_search_setpos' => array(
+ 1 => 'position',
+ ),
+ 'mb_strimwidth' => array(
+ 2 => 'start',
+ 3 => 'width',
+ ),
+ 'mb_stripos' => array(
+ 3 => 'offset',
+ ),
+ 'mb_strpos' => array(
+ 3 => 'offset',
+ ),
+ 'stripos' => array(
+ 3 => 'offset',
+ ),
+ 'strpos' => array(
+ 3 => 'offset',
+ ),
+ 'substr_count' => array(
+ 3 => 'offset',
+ 4 => 'length',
+ ),
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('7.0') === false);
+ }
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ $functionLC = strtolower($functionName);
+ foreach ($this->targetFunctions[$functionLC] as $pos => $name) {
+ if (isset($parameters[$pos]) === false) {
+ continue;
+ }
+
+ $targetParam = $parameters[$pos];
+
+ if ($this->isNegativeNumber($phpcsFile, $targetParam['start'], $targetParam['end']) === false) {
+ continue;
+ }
+
+ $phpcsFile->addError(
+ 'Negative string offsets were not supported for the $%s parameter in %s() in PHP 7.0 or lower. Found %s',
+ $targetParam['start'],
+ 'Found',
+ array(
+ $name,
+ $functionName,
+ $targetParam['raw'],
+ )
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewPCREModifiersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewPCREModifiersSniff.php
new file mode 100644
index 0000000..242286a
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewPCREModifiersSniff.php
@@ -0,0 +1,115 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\Sniffs\ParameterValues\RemovedPCREModifiersSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\NewPCREModifiers.
+ *
+ * Check for usage of newly added regex modifiers for PCRE functions.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewPCREModifiersSniff extends RemovedPCREModifiersSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'preg_replace' => true,
+ 'preg_filter' => true,
+ 'preg_grep' => true,
+ 'preg_match_all' => true,
+ 'preg_match' => true,
+ 'preg_replace_callback_array' => true,
+ 'preg_replace_callback' => true,
+ 'preg_replace' => true,
+ 'preg_split' => true,
+ );
+
+ /**
+ * Array listing newly introduced regex modifiers.
+ *
+ * The key should be the modifier (case-sensitive!).
+ * The value should be the PHP version in which the modifier was introduced.
+ *
+ * @var array
+ */
+ protected $newModifiers = array(
+ 'J' => array(
+ '7.1' => false,
+ '7.2' => true,
+ ),
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ // Version used here should be the highest version from the `$newModifiers` array,
+ // i.e. the last PHP version in which a new modifier was introduced.
+ return ($this->supportsBelow('7.2') === false);
+ }
+
+
+ /**
+ * Examine the regex modifier string.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param string $functionName The function which contained the pattern.
+ * @param string $modifiers The regex modifiers found.
+ *
+ * @return void
+ */
+ protected function examineModifiers(File $phpcsFile, $stackPtr, $functionName, $modifiers)
+ {
+ $error = 'The PCRE regex modifier "%s" is not present in PHP version %s or earlier';
+
+ foreach ($this->newModifiers as $modifier => $versionArray) {
+ if (strpos($modifiers, $modifier) === false) {
+ continue;
+ }
+
+ $notInVersion = '';
+ foreach ($versionArray as $version => $present) {
+ if ($notInVersion === '' && $present === false
+ && $this->supportsBelow($version) === true
+ ) {
+ $notInVersion = $version;
+ }
+ }
+
+ if ($notInVersion === '') {
+ continue;
+ }
+
+ $errorCode = $modifier . 'ModifierFound';
+ $data = array(
+ $modifier,
+ $notInVersion,
+ );
+
+ $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewPackFormatSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewPackFormatSniff.php
new file mode 100644
index 0000000..5af6c24
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/NewPackFormatSniff.php
@@ -0,0 +1,123 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\NewPackFormatSniff.
+ *
+ * Detect: Changes in the allowed values for $format passed to pack().
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewPackFormatSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'pack' => true,
+ );
+
+ /**
+ * List of new format character codes added to pack().
+ *
+ * @var array Regex pattern => Version array.
+ */
+ protected $newFormats = array(
+ '`([Z])`' => array(
+ '5.4' => false,
+ '5.5' => true,
+ ),
+ '`([qQJP])`' => array(
+ '5.6.2' => false,
+ '5.6.3' => true,
+ ),
+ '`([eEgG])`' => array(
+ '7.0.14' => false,
+ '7.0.15' => true, // And 7.1.1.
+ ),
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsBelow('7.1') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[1]) === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $targetParam = $parameters[1];
+
+ for ($i = $targetParam['start']; $i <= $targetParam['end']; $i++) {
+ if ($tokens[$i]['code'] !== T_CONSTANT_ENCAPSED_STRING
+ && $tokens[$i]['code'] !== T_DOUBLE_QUOTED_STRING
+ ) {
+ continue;
+ }
+
+ $content = $tokens[$i]['content'];
+ if ($tokens[$i]['code'] === T_DOUBLE_QUOTED_STRING) {
+ $content = $this->stripVariables($content);
+ }
+
+ foreach ($this->newFormats as $pattern => $versionArray) {
+ if (preg_match($pattern, $content, $matches) !== 1) {
+ continue;
+ }
+
+ foreach ($versionArray as $version => $present) {
+ if ($present === false && $this->supportsBelow($version) === true) {
+ $phpcsFile->addError(
+ 'Passing the $format(s) "%s" to pack() is not supported in PHP %s or lower. Found %s',
+ $targetParam['start'],
+ 'NewFormatFound',
+ array(
+ $matches[1],
+ $version,
+ $targetParam['raw'],
+ )
+ );
+ continue 2;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedHashAlgorithmsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedHashAlgorithmsSniff.php
new file mode 100644
index 0000000..8e48d40
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedHashAlgorithmsSniff.php
@@ -0,0 +1,111 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\RemovedHashAlgorithmsSniff.
+ *
+ * Discourages the use of deprecated and removed hash algorithms.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class RemovedHashAlgorithmsSniff extends AbstractRemovedFeatureSniff
+{
+
+ /**
+ * A list of removed hash algorithms, which were present in older versions.
+ *
+ * The array lists : version number with false (deprecated) and true (removed).
+ * If's sufficient to list the first version where the hash algorithm was deprecated/removed.
+ *
+ * @var array(string => array(string => bool))
+ */
+ protected $removedAlgorithms = array(
+ 'salsa10' => array(
+ '5.4' => true,
+ ),
+ 'salsa20' => array(
+ '5.4' => true,
+ ),
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $algo = $this->getHashAlgorithmParameter($phpcsFile, $stackPtr);
+ if (empty($algo) || is_string($algo) === false) {
+ return;
+ }
+
+ // Bow out if not one of the algorithms we're targetting.
+ if (isset($this->removedAlgorithms[$algo]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $algo,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->removedAlgorithms[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The %s hash algorithm is ';
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedIconvEncodingSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedIconvEncodingSniff.php
new file mode 100644
index 0000000..f4df0ef
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedIconvEncodingSniff.php
@@ -0,0 +1,80 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\RemovedIconvEncodingSniff.
+ *
+ * Detect: "The iconv and mbstring configuration options related to encoding
+ * have been deprecated in favour of default_charset."
+ *
+ * {@internal It is unclear which mbstring functions should be targetted, so for now,
+ * only the iconv function is handled.}}
+ *
+ * PHP version 5.6
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedIconvEncodingSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'iconv_set_encoding' => true,
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsAbove('5.6') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[1]) === false) {
+ return;
+ }
+
+ $phpcsFile->addWarning(
+ 'All previously accepted values for the $type parameter of iconv_set_encoding() have been deprecated since PHP 5.6. Found %s',
+ $parameters[1]['start'],
+ 'DeprecatedValueFound',
+ $parameters[1]['raw']
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedMbstringModifiersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedMbstringModifiersSniff.php
new file mode 100644
index 0000000..3257699
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedMbstringModifiersSniff.php
@@ -0,0 +1,122 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\RemovedMbstringModifiersSniff.
+ *
+ * PHP version 7.1
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedMbstringModifiersSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * Key is the function name, value the parameter position of the options parameter.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'mb_ereg_replace' => 4,
+ 'mb_eregi_replace' => 4,
+ 'mb_regex_set_options' => 1,
+ 'mbereg_replace' => 4, // Undocumented, but valid function alias.
+ 'mberegi_replace' => 4, // Undocumented, but valid function alias.
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ // Version used here should be the highest version from the `$newModifiers` array,
+ // i.e. the last PHP version in which a new modifier was introduced.
+ return ($this->supportsAbove('7.1') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * This method has to be made concrete in child classes.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $functionNameLc = strtolower($functionName);
+
+ // Check whether the options parameter in the function call is passed.
+ if (isset($parameters[$this->targetFunctions[$functionNameLc]]) === false) {
+ return;
+ }
+
+ $optionsParam = $parameters[$this->targetFunctions[$functionNameLc]];
+
+ $stringToken = $phpcsFile->findNext(Tokens::$stringTokens, $optionsParam['start'], $optionsParam['end'] + 1);
+ if ($stringToken === false) {
+ // No string token found in the options parameter, so skip it (e.g. variable passed in).
+ return;
+ }
+
+ $options = '';
+
+ /*
+ * Get the content of any string tokens in the options parameter and remove the quotes and variables.
+ */
+ for ($i = $stringToken; $i <= $optionsParam['end']; $i++) {
+ if (isset(Tokens::$stringTokens[$tokens[$i]['code']]) === false) {
+ continue;
+ }
+
+ $content = $this->stripQuotes($tokens[$i]['content']);
+ if ($tokens[$i]['code'] === T_DOUBLE_QUOTED_STRING) {
+ $content = $this->stripVariables($content);
+ }
+ $content = trim($content);
+
+ if (empty($content) === false) {
+ $options .= $content;
+ }
+ }
+
+ if (strpos($options, 'e') !== false) {
+ $error = 'The Mbstring regex "e" modifier is deprecated since PHP 7.1.';
+
+ // The alternative mb_ereg_replace_callback() function is only available since 5.4.1.
+ if ($this->supportsBelow('5.4.1') === false) {
+ $error .= ' Use mb_ereg_replace_callback() instead (PHP 5.4.1+).';
+ }
+
+ $phpcsFile->addWarning($error, $stackPtr, 'Deprecated');
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedNonCryptoHashSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedNonCryptoHashSniff.php
new file mode 100644
index 0000000..9a19680
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedNonCryptoHashSniff.php
@@ -0,0 +1,114 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\RemovedNonCryptoHashSniff.
+ *
+ * Detect: "The hash_hmac(), hash_hmac_file(), hash_pbkdf2(), and hash_init()
+ * (with HASH_HMAC) functions no longer accept non-cryptographic hashes."
+ *
+ * PHP version 7.2
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedNonCryptoHashSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'hash_hmac' => true,
+ 'hash_hmac_file' => true,
+ 'hash_init' => true,
+ 'hash_pbkdf2' => true,
+ );
+
+ /**
+ * List of the non-cryptographic hashes.
+ *
+ * @var array
+ */
+ protected $disabledCryptos = array(
+ 'adler32' => true,
+ 'crc32' => true,
+ 'crc32b' => true,
+ 'fnv132' => true,
+ 'fnv1a32' => true,
+ 'fnv164' => true,
+ 'fnv1a64' => true,
+ 'joaat' => true,
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsAbove('7.2') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[1]) === false) {
+ return;
+ }
+
+ $targetParam = $parameters[1];
+
+ if (isset($this->disabledCryptos[$this->stripQuotes($targetParam['raw'])]) === false) {
+ return;
+ }
+
+ if (strtolower($functionName) === 'hash_init'
+ && (isset($parameters[2]) === false
+ || ($parameters[2]['raw'] !== 'HASH_HMAC'
+ && $parameters[2]['raw'] !== (string) HASH_HMAC))
+ ) {
+ // For hash_init(), these hashes are only disabled with HASH_HMAC set.
+ return;
+ }
+
+ $phpcsFile->addError(
+ 'Non-cryptographic hashes are no longer accepted by function %s() since PHP 7.2. Found: %s',
+ $targetParam['start'],
+ $this->stringToErrorCode($functionName),
+ array(
+ $functionName,
+ $targetParam['raw'],
+ )
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedPCREModifiersSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedPCREModifiersSniff.php
new file mode 100644
index 0000000..a4b81db
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedPCREModifiersSniff.php
@@ -0,0 +1,219 @@
+
+ * @copyright 2014 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\RemovedPCREModifiersSniff.
+ *
+ * Check for usage of the `e` modifier with PCRE functions which is deprecated since PHP 5.5
+ * and removed as of PHP 7.0.
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2014 Cu.be Solutions bvba
+ */
+class RemovedPCREModifiersSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'preg_replace' => true,
+ 'preg_filter' => true,
+ );
+
+ /**
+ * Regex bracket delimiters.
+ *
+ * @var array
+ */
+ protected $doublesSeparators = array(
+ '{' => '}',
+ '[' => ']',
+ '(' => ')',
+ '<' => '>',
+ );
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ // Check the first parameter in the function call as that should contain the regex(es).
+ if (isset($parameters[1]) === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $functionNameLc = strtolower($functionName);
+ $firstParam = $parameters[1];
+
+ // Differentiate between an array of patterns passed and a single pattern.
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $firstParam['start'], ($firstParam['end'] + 1), true);
+ if ($nextNonEmpty !== false && ($tokens[$nextNonEmpty]['code'] === T_ARRAY || $tokens[$nextNonEmpty]['code'] === T_OPEN_SHORT_ARRAY)) {
+ $arrayValues = $this->getFunctionCallParameters($phpcsFile, $nextNonEmpty);
+ if ($functionNameLc === 'preg_replace_callback_array') {
+ // For preg_replace_callback_array(), the patterns will be in the array keys.
+ foreach ($arrayValues as $value) {
+ $hasKey = $phpcsFile->findNext(T_DOUBLE_ARROW, $value['start'], ($value['end'] + 1));
+ if ($hasKey === false) {
+ continue;
+ }
+
+ $value['end'] = ($hasKey - 1);
+ $value['raw'] = trim($phpcsFile->getTokensAsString($value['start'], ($hasKey - $value['start'])));
+ $this->processRegexPattern($value, $phpcsFile, $value['end'], $functionName);
+ }
+
+ } else {
+ // Otherwise, the patterns will be in the array values.
+ foreach ($arrayValues as $value) {
+ $hasKey = $phpcsFile->findNext(T_DOUBLE_ARROW, $value['start'], ($value['end'] + 1));
+ if ($hasKey !== false) {
+ $value['start'] = ($hasKey + 1);
+ $value['raw'] = trim($phpcsFile->getTokensAsString($value['start'], (($value['end'] + 1) - $value['start'])));
+ }
+
+ $this->processRegexPattern($value, $phpcsFile, $value['end'], $functionName);
+ }
+ }
+
+ } else {
+ $this->processRegexPattern($firstParam, $phpcsFile, $stackPtr, $functionName);
+ }
+ }
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsAbove('5.5') === false);
+ }
+
+
+ /**
+ * Analyse a potential regex pattern for usage of the /e modifier.
+ *
+ * @param array $pattern Array containing the start and end token
+ * pointer of the potential regex pattern and
+ * the raw string value of the pattern.
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param string $functionName The function which contained the pattern.
+ *
+ * @return void
+ */
+ protected function processRegexPattern($pattern, File $phpcsFile, $stackPtr, $functionName)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ /*
+ * The pattern might be build up of a combination of strings, variables
+ * and function calls. We are only concerned with the strings.
+ */
+ $regex = '';
+ for ($i = $pattern['start']; $i <= $pattern['end']; $i++) {
+ if (isset(Tokens::$stringTokens[$tokens[$i]['code']]) === true) {
+ $content = $this->stripQuotes($tokens[$i]['content']);
+ if ($tokens[$i]['code'] === T_DOUBLE_QUOTED_STRING) {
+ $content = $this->stripVariables($content);
+ }
+
+ $regex .= trim($content);
+ }
+ }
+
+ // Deal with multi-line regexes which were broken up in several string tokens.
+ if ($tokens[$pattern['start']]['line'] !== $tokens[$pattern['end']]['line']) {
+ $regex = $this->stripQuotes($regex);
+ }
+
+ if ($regex === '') {
+ // No string token found in the first parameter, so skip it (e.g. if variable passed in).
+ return;
+ }
+
+ $regexFirstChar = substr($regex, 0, 1);
+
+ // Make sure that the character identified as the delimiter is valid.
+ // Otherwise, it is a false positive caused by the string concatenation.
+ if (preg_match('`[a-z0-9\\\\ ]`i', $regexFirstChar) === 1) {
+ return;
+ }
+
+ if (isset($this->doublesSeparators[$regexFirstChar])) {
+ $regexEndPos = strrpos($regex, $this->doublesSeparators[$regexFirstChar]);
+ } else {
+ $regexEndPos = strrpos($regex, $regexFirstChar);
+ }
+
+ if ($regexEndPos !== false) {
+ $modifiers = substr($regex, $regexEndPos + 1);
+ $this->examineModifiers($phpcsFile, $stackPtr, $functionName, $modifiers);
+ }
+ }
+
+
+ /**
+ * Examine the regex modifier string.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param string $functionName The function which contained the pattern.
+ * @param string $modifiers The regex modifiers found.
+ *
+ * @return void
+ */
+ protected function examineModifiers(File $phpcsFile, $stackPtr, $functionName, $modifiers)
+ {
+ if (strpos($modifiers, 'e') !== false) {
+ $error = '%s() - /e modifier is deprecated since PHP 5.5';
+ $isError = false;
+ $errorCode = 'Deprecated';
+ $data = array($functionName);
+
+ if ($this->supportsAbove('7.0')) {
+ $error .= ' and removed since PHP 7.0';
+ $isError = true;
+ $errorCode = 'Removed';
+ }
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode, $data);
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedSetlocaleStringSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedSetlocaleStringSniff.php
new file mode 100644
index 0000000..0ddd64c
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/ParameterValues/RemovedSetlocaleStringSniff.php
@@ -0,0 +1,99 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\ParameterValues;
+
+use PHPCompatibility\AbstractFunctionCallParameterSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\ParameterValues\RemovedSetlocaleStringSniff.
+ *
+ * Detect: Support for the category parameter passed as a string has been removed.
+ * Only LC_* constants can be used as of this version [7.0.0].
+ *
+ * PHP version 4.2
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedSetlocaleStringSniff extends AbstractFunctionCallParameterSniff
+{
+
+ /**
+ * Functions to check for.
+ *
+ * @var array
+ */
+ protected $targetFunctions = array(
+ 'setlocale' => true,
+ );
+
+
+ /**
+ * Do a version check to determine if this sniff needs to run at all.
+ *
+ * @return bool
+ */
+ protected function bowOutEarly()
+ {
+ return ($this->supportsAbove('4.2') === false);
+ }
+
+
+ /**
+ * Process the parameters of a matched function.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param string $functionName The token content (function name) which was matched.
+ * @param array $parameters Array with information about the parameters.
+ *
+ * @return int|void Integer stack pointer to skip forward or void to continue
+ * normal file processing.
+ */
+ public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
+ {
+ if (isset($parameters[1]) === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $targetParam = $parameters[1];
+
+ for ($i = $targetParam['start']; $i <= $targetParam['end']; $i++) {
+ if ($tokens[$i]['code'] !== T_CONSTANT_ENCAPSED_STRING
+ && $tokens[$i]['code'] !== T_DOUBLE_QUOTED_STRING
+ ) {
+ continue;
+ }
+
+ $message = 'Passing the $category as a string to setlocale() has been deprecated since PHP 4.2';
+ $isError = false;
+ $errorCode = 'Deprecated';
+ $data = array($targetParam['raw']);
+
+ if ($this->supportsAbove('7.0') === true) {
+ $message .= ' and is removed since PHP 7.0';
+ $isError = true;
+ $errorCode = 'Removed';
+ }
+
+ $message .= '; Pass one of the LC_* constants instead. Found: %s';
+
+ $this->addMessage($phpcsFile, $message, $i, $isError, $errorCode, $data);
+ break;
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/ForbiddenCallTimePassByReferenceSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/ForbiddenCallTimePassByReferenceSniff.php
new file mode 100644
index 0000000..4febe5f
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/ForbiddenCallTimePassByReferenceSniff.php
@@ -0,0 +1,253 @@
+
+ * @author Florian Grandel
+ * @copyright 2009 Florian Grandel
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\ForbiddenCallTimePassByReference.
+ *
+ * Discourages the use of call time pass by references
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Gary Rogers
+ * @author Florian Grandel
+ * @copyright 2009 Florian Grandel
+ */
+class ForbiddenCallTimePassByReferenceSniff extends Sniff
+{
+
+ /**
+ * Tokens that represent assignments or equality comparisons.
+ *
+ * Near duplicate of Tokens::$assignmentTokens + Tokens::$equalityTokens.
+ * Copied in for PHPCS cross-version compatibility.
+ *
+ * @var array
+ */
+ private $assignOrCompare = array(
+ // Equality tokens.
+ 'T_IS_EQUAL' => true,
+ 'T_IS_NOT_EQUAL' => true,
+ 'T_IS_IDENTICAL' => true,
+ 'T_IS_NOT_IDENTICAL' => true,
+ 'T_IS_SMALLER_OR_EQUAL' => true,
+ 'T_IS_GREATER_OR_EQUAL' => true,
+
+ // Assignment tokens.
+ 'T_EQUAL' => true,
+ 'T_AND_EQUAL' => true,
+ 'T_OR_EQUAL' => true,
+ 'T_CONCAT_EQUAL' => true,
+ 'T_DIV_EQUAL' => true,
+ 'T_MINUS_EQUAL' => true,
+ 'T_POW_EQUAL' => true,
+ 'T_MOD_EQUAL' => true,
+ 'T_MUL_EQUAL' => true,
+ 'T_PLUS_EQUAL' => true,
+ 'T_XOR_EQUAL' => true,
+ 'T_DOUBLE_ARROW' => true,
+ 'T_SL_EQUAL' => true,
+ 'T_SR_EQUAL' => true,
+ 'T_COALESCE_EQUAL' => true,
+ 'T_ZSR_EQUAL' => true,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_STRING,
+ T_VARIABLE,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('5.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Skip tokens that are the names of functions or classes
+ // within their definitions. For example: function myFunction...
+ // "myFunction" is T_STRING but we should skip because it is not a
+ // function or method *call*.
+ $findTokens = Tokens::$emptyTokens;
+ $findTokens[] = T_BITWISE_AND;
+
+ $prevNonEmpty = $phpcsFile->findPrevious(
+ $findTokens,
+ ($stackPtr - 1),
+ null,
+ true
+ );
+
+ if ($prevNonEmpty !== false && in_array($tokens[$prevNonEmpty]['type'], array('T_FUNCTION', 'T_CLASS', 'T_INTERFACE', 'T_TRAIT'), true)) {
+ return;
+ }
+
+ // If the next non-whitespace token after the function or method call
+ // is not an opening parenthesis then it can't really be a *call*.
+ $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+
+ if ($openBracket === false || $tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS
+ || isset($tokens[$openBracket]['parenthesis_closer']) === false
+ ) {
+ return;
+ }
+
+ // Get the function call parameters.
+ $parameters = $this->getFunctionCallParameters($phpcsFile, $stackPtr);
+ if (count($parameters) === 0) {
+ return;
+ }
+
+ // Which nesting level is the one we are interested in ?
+ $nestedParenthesisCount = 1;
+ if (isset($tokens[$openBracket]['nested_parenthesis'])) {
+ $nestedParenthesisCount = count($tokens[$openBracket]['nested_parenthesis']) + 1;
+ }
+
+ foreach ($parameters as $parameter) {
+ if ($this->isCallTimePassByReferenceParam($phpcsFile, $parameter, $nestedParenthesisCount) === true) {
+ // T_BITWISE_AND represents a pass-by-reference.
+ $error = 'Using a call-time pass-by-reference is deprecated since PHP 5.3';
+ $isError = false;
+ $errorCode = 'Deprecated';
+
+ if ($this->supportsAbove('5.4')) {
+ $error .= ' and prohibited since PHP 5.4';
+ $isError = true;
+ $errorCode = 'NotAllowed';
+ }
+
+ $this->addMessage($phpcsFile, $error, $parameter['start'], $isError, $errorCode);
+ }
+ }
+ }
+
+
+ /**
+ * Determine whether a parameter is passed by reference.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param array $parameter Information on the current parameter
+ * to be examined.
+ * @param int $nestingLevel Target nesting level.
+ *
+ * @return bool
+ */
+ protected function isCallTimePassByReferenceParam(File $phpcsFile, $parameter, $nestingLevel)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $searchStartToken = $parameter['start'] - 1;
+ $searchEndToken = $parameter['end'] + 1;
+ $nextVariable = $searchStartToken;
+ do {
+ $nextVariable = $phpcsFile->findNext(array(T_VARIABLE, T_OPEN_SHORT_ARRAY, T_CLOSURE), ($nextVariable + 1), $searchEndToken);
+ if ($nextVariable === false) {
+ return false;
+ }
+
+ // Ignore anything within short array definition brackets.
+ if ($tokens[$nextVariable]['type'] === 'T_OPEN_SHORT_ARRAY'
+ && (isset($tokens[$nextVariable]['bracket_opener'])
+ && $tokens[$nextVariable]['bracket_opener'] === $nextVariable)
+ && isset($tokens[$nextVariable]['bracket_closer'])
+ ) {
+ // Skip forward to the end of the short array definition.
+ $nextVariable = $tokens[$nextVariable]['bracket_closer'];
+ continue;
+ }
+
+ // Skip past closures passed as function parameters.
+ if ($tokens[$nextVariable]['type'] === 'T_CLOSURE'
+ && (isset($tokens[$nextVariable]['scope_condition'])
+ && $tokens[$nextVariable]['scope_condition'] === $nextVariable)
+ && isset($tokens[$nextVariable]['scope_closer'])
+ ) {
+ // Skip forward to the end of the closure declaration.
+ $nextVariable = $tokens[$nextVariable]['scope_closer'];
+ continue;
+ }
+
+ // Make sure the variable belongs directly to this function call
+ // and is not inside a nested function call or array.
+ if (isset($tokens[$nextVariable]['nested_parenthesis']) === false
+ || (count($tokens[$nextVariable]['nested_parenthesis']) !== $nestingLevel)
+ ) {
+ continue;
+ }
+
+ // Checking this: $value = my_function(...[*]$arg...).
+ $tokenBefore = $phpcsFile->findPrevious(
+ Tokens::$emptyTokens,
+ ($nextVariable - 1),
+ $searchStartToken,
+ true
+ );
+
+ if ($tokenBefore === false || $tokens[$tokenBefore]['code'] !== T_BITWISE_AND) {
+ // Nothing before the token or no &.
+ continue;
+ }
+
+ if ($phpcsFile->isReference($tokenBefore) === false) {
+ continue;
+ }
+
+ // Checking this: $value = my_function(...[*]&$arg...).
+ $tokenBefore = $phpcsFile->findPrevious(
+ Tokens::$emptyTokens,
+ ($tokenBefore - 1),
+ $searchStartToken,
+ true
+ );
+
+ // Prevent false positive on assign by reference and compare with reference
+ // within function call parameters.
+ if (isset($this->assignOrCompare[$tokens[$tokenBefore]['type']])) {
+ continue;
+ }
+
+ // The found T_BITWISE_AND represents a pass-by-reference.
+ return true;
+
+ } while ($nextVariable < $searchEndToken);
+
+ // This code should never be reached, but here in case of weird bugs.
+ return false;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewArrayStringDereferencingSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewArrayStringDereferencingSniff.php
new file mode 100644
index 0000000..2805c84
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewArrayStringDereferencingSniff.php
@@ -0,0 +1,108 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\NewArrayStringDereferencingSniff.
+ *
+ * Array and string literals can now be dereferenced directly to access individual elements and characters.
+ *
+ * PHP version 5.5
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewArrayStringDereferencingSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_ARRAY,
+ T_OPEN_SHORT_ARRAY,
+ T_CONSTANT_ENCAPSED_STRING,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.4') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ switch ($tokens[$stackPtr]['code']) {
+ case T_CONSTANT_ENCAPSED_STRING:
+ $type = 'string literals';
+ $end = $stackPtr;
+ break;
+
+ case T_ARRAY:
+ if (isset($tokens[$stackPtr]['parenthesis_closer']) === false) {
+ // Live coding.
+ return;
+ } else {
+ $type = 'arrays';
+ $end = $tokens[$stackPtr]['parenthesis_closer'];
+ }
+ break;
+
+ case T_OPEN_SHORT_ARRAY:
+ if (isset($tokens[$stackPtr]['bracket_closer']) === false) {
+ // Live coding.
+ return;
+ } else {
+ $type = 'arrays';
+ $end = $tokens[$stackPtr]['bracket_closer'];
+ }
+ break;
+ }
+
+ if (isset($type, $end) === false) {
+ // Shouldn't happen, but for some reason did.
+ return;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true, null, true);
+
+ if ($nextNonEmpty !== false
+ && ($tokens[$nextNonEmpty]['type'] === 'T_OPEN_SQUARE_BRACKET'
+ || $tokens[$nextNonEmpty]['type'] === 'T_OPEN_SHORT_ARRAY') // Work around bug #1381 in PHPCS 2.8.1 and lower.
+ ) {
+ $phpcsFile->addError(
+ 'Direct array dereferencing of %s is not present in PHP version 5.4 or earlier',
+ $nextNonEmpty,
+ 'Found',
+ array($type)
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewClassMemberAccessSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewClassMemberAccessSniff.php
new file mode 100644
index 0000000..6a0c37e
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewClassMemberAccessSniff.php
@@ -0,0 +1,113 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\NewClassMemberAccessSniff.
+ *
+ * PHP 5.4: Class member access on instantiation has been added, e.g. (new Foo)->bar().
+ * PHP 7.0: Class member access on cloning has been added, e.g. (clone $foo)->bar().
+ *
+ * PHP version 5.4
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewClassMemberAccessSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_NEW,
+ T_CLONE,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if ($tokens[$stackPtr]['code'] === T_NEW && $this->supportsBelow('5.3') !== true) {
+ return;
+ } elseif ($tokens[$stackPtr]['code'] === T_CLONE && $this->supportsBelow('5.6') !== true) {
+ return;
+ }
+
+ if (isset($tokens[$stackPtr]['nested_parenthesis']) === false) {
+ // The `new className/clone $a` has to be in parentheses, without is not supported.
+ return;
+ }
+
+ $parenthesisCloser = end($tokens[$stackPtr]['nested_parenthesis']);
+ $parenthesisOpener = key($tokens[$stackPtr]['nested_parenthesis']);
+
+ if (isset($tokens[$parenthesisOpener]['parenthesis_owner']) === true) {
+ // If there is an owner, these parentheses are for a different purpose.
+ return;
+ }
+
+ $prevBeforeParenthesis = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($parenthesisOpener - 1), null, true);
+ if ($prevBeforeParenthesis !== false && $tokens[$prevBeforeParenthesis]['code'] === T_STRING) {
+ // This is most likely a function call with the new/cloned object as a parameter.
+ return;
+ }
+
+ $nextAfterParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, ($parenthesisCloser + 1), null, true);
+ if ($nextAfterParenthesis === false) {
+ // Live coding.
+ return;
+ }
+
+ if ($tokens[$nextAfterParenthesis]['code'] !== T_OBJECT_OPERATOR
+ && $tokens[$nextAfterParenthesis]['code'] !== T_OPEN_SQUARE_BRACKET
+ ) {
+ return;
+ }
+
+ $data = array('instantiation', '5.3');
+ $errorCode = 'OnNewFound';
+
+ if ($tokens[$stackPtr]['code'] === T_CLONE) {
+ $data = array('cloning', '5.6');
+ $errorCode = 'OnCloneFound';
+ }
+
+ $phpcsFile->addError(
+ 'Class member access on object %s was not supported in PHP %s or earlier',
+ $parenthesisCloser,
+ $errorCode,
+ $data
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewDynamicAccessToStaticSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewDynamicAccessToStaticSniff.php
new file mode 100644
index 0000000..3ab76a3
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewDynamicAccessToStaticSniff.php
@@ -0,0 +1,85 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\NewDynamicAccessToStaticSniff.
+ *
+ * As of PHP 5.3, static properties and methods as well as class constants
+ * can be accessed using a dynamic (variable) class name.
+ *
+ * PHP version 5.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewDynamicAccessToStaticSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_DOUBLE_COLON,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.2') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+
+ // Disregard `static::` as well. Late static binding is reported by another sniff.
+ if ($tokens[$prevNonEmpty]['code'] === T_SELF
+ || $tokens[$prevNonEmpty]['code'] === T_PARENT
+ || $tokens[$prevNonEmpty]['code'] === T_STATIC
+ ) {
+ return;
+ }
+
+ if ($tokens[$prevNonEmpty]['code'] === T_STRING) {
+ $prevPrevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prevNonEmpty - 1), null, true);
+
+ if ($tokens[$prevPrevNonEmpty]['code'] !== T_OBJECT_OPERATOR) {
+ return;
+ }
+ }
+
+ $phpcsFile->addError(
+ 'Static class properties and methods, as well as class constants, could not be accessed using a dynamic (variable) classname in PHP 5.2 or earlier.',
+ $stackPtr,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFlexibleHeredocNowdocSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFlexibleHeredocNowdocSniff.php
new file mode 100644
index 0000000..e9b3748
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFlexibleHeredocNowdocSniff.php
@@ -0,0 +1,247 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * New Flexible Heredoc Nowdoc.
+ *
+ * As of PHP 7.3:
+ * - The body and the closing marker of a Heredoc/nowdoc can be indented;
+ * - The closing marker no longer needs to be on a line by itself;
+ * - The heredoc/nowdoc body may no longer contain the closing marker at the
+ * start of any of its lines.
+ *
+ * PHP version 7.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewFlexibleHeredocNowdocSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $targets = array(
+ T_END_HEREDOC,
+ T_END_NOWDOC,
+ );
+
+ if (version_compare(PHP_VERSION_ID, '70299', '>') === false) {
+ // Start identifier of a PHP 7.3 flexible heredoc/nowdoc.
+ $targets[] = T_STRING;
+ }
+
+ return $targets;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ /*
+ * Due to a tokenizer bug which gets hit when the PHP 7.3 heredoc/nowdoc syntax
+ * is used, this part of the sniff cannot possibly work on PHPCS < 2.6.0.
+ * See upstream issue #928.
+ */
+ if ($this->supportsBelow('7.2') === true && version_compare(PHPCSHelper::getVersion(), '2.6.0', '>=')) {
+ $this->detectIndentedNonStandAloneClosingMarker($phpcsFile, $stackPtr);
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ if ($this->supportsAbove('7.3') === true && $tokens[$stackPtr]['code'] !== T_STRING) {
+ $this->detectClosingMarkerInBody($phpcsFile, $stackPtr);
+ }
+ }
+
+
+ /**
+ * Detect indented and/or non-stand alone closing markers.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ protected function detectIndentedNonStandAloneClosingMarker(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $indentError = 'Heredoc/nowdoc with an indented closing marker is not supported in PHP 7.2 or earlier.';
+ $indentErrorCode = 'IndentedClosingMarker';
+ $trailingError = 'Having code - other than a semi-colon or new line - after the closing marker of a heredoc/nowdoc is not supported in PHP 7.2 or earlier.';
+ $trailingErrorCode = 'ClosingMarkerNoNewLine';
+
+ if (version_compare(PHP_VERSION_ID, '70299', '>') === true) {
+
+ /*
+ * Check for indented closing marker.
+ */
+ if (ltrim($tokens[$stackPtr]['content']) !== $tokens[$stackPtr]['content']) {
+ $phpcsFile->addError($indentError, $stackPtr, $indentErrorCode);
+ }
+
+ /*
+ * Check for tokens after the closing marker.
+ */
+ $nextNonWhitespace = $phpcsFile->findNext(array(T_WHITESPACE, T_SEMICOLON), ($stackPtr + 1), null, true);
+ if ($tokens[$stackPtr]['line'] === $tokens[$nextNonWhitespace]['line']) {
+ $phpcsFile->addError($trailingError, $stackPtr, $trailingErrorCode);
+ }
+ } else {
+ // For PHP < 7.3, we're only interested in T_STRING tokens.
+ if ($tokens[$stackPtr]['code'] !== T_STRING) {
+ return;
+ }
+
+ if (preg_match('`^<<<([\'"]?)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\1[\r\n]+`', $tokens[$stackPtr]['content'], $matches) !== 1) {
+ // Not the start of a PHP 7.3 flexible heredoc/nowdoc.
+ return;
+ }
+
+ $identifier = $matches[2];
+
+ for ($i = ($stackPtr + 1); $i <= $phpcsFile->numTokens; $i++) {
+ if ($tokens[$i]['code'] !== T_ENCAPSED_AND_WHITESPACE) {
+ continue;
+ }
+
+ $trimmed = ltrim($tokens[$i]['content']);
+
+ if (strpos($trimmed, $identifier) !== 0) {
+ continue;
+ }
+
+ // OK, we've found the PHP 7.3 flexible heredoc/nowdoc closing marker.
+
+ /*
+ * Check for indented closing marker.
+ */
+ if ($trimmed !== $tokens[$i]['content']) {
+ // Indent found before closing marker.
+ $phpcsFile->addError($indentError, $i, $indentErrorCode);
+ }
+
+ /*
+ * Check for tokens after the closing marker.
+ */
+ // Remove the identifier.
+ $afterMarker = substr($trimmed, strlen($identifier));
+ // Remove a potential semi-colon at the beginning of what's left of the string.
+ $afterMarker = ltrim($afterMarker, ';');
+ // Remove new line characters at the end of the string.
+ $afterMarker = rtrim($afterMarker, "\r\n");
+
+ if ($afterMarker !== '') {
+ $phpcsFile->addError($trailingError, $i, $trailingErrorCode);
+ }
+
+ break;
+ }
+ }
+ }
+
+
+ /**
+ * Detect heredoc/nowdoc identifiers at the start of lines in the heredoc/nowdoc body.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ protected function detectClosingMarkerInBody(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $error = 'The body of a heredoc/nowdoc can not contain the heredoc/nowdoc closing marker as text at the start of a line since PHP 7.3.';
+ $errorCode = 'ClosingMarkerNoNewLine';
+
+ if (version_compare(PHP_VERSION_ID, '70299', '>') === true) {
+ $nextNonWhitespace = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true, null, true);
+ if ($nextNonWhitespace === false
+ || $tokens[$nextNonWhitespace]['code'] === T_SEMICOLON
+ || (($tokens[$nextNonWhitespace]['code'] === T_COMMA
+ || $tokens[$nextNonWhitespace]['code'] === T_STRING_CONCAT)
+ && $tokens[$nextNonWhitespace]['line'] !== $tokens[$stackPtr]['line'])
+ ) {
+ // This is most likely a correctly identified closing marker.
+ return;
+ }
+
+ // The real closing tag has to be before the next heredoc/nowdoc.
+ $nextHereNowDoc = $phpcsFile->findNext(array(T_START_HEREDOC, T_START_NOWDOC), ($stackPtr + 1));
+ if ($nextHereNowDoc === false) {
+ $nextHereNowDoc = null;
+ }
+
+ $identifier = trim($tokens[$stackPtr]['content']);
+ $realClosingMarker = $stackPtr;
+
+ while (($realClosingMarker = $phpcsFile->findNext(T_STRING, ($realClosingMarker + 1), $nextHereNowDoc, false, $identifier)) !== false) {
+
+ $prevNonWhitespace = $phpcsFile->findPrevious(T_WHITESPACE, ($realClosingMarker - 1), null, true);
+ if ($prevNonWhitespace === false
+ || $tokens[$prevNonWhitespace]['line'] === $tokens[$realClosingMarker]['line']
+ ) {
+ // Marker text found, but not at the start of the line.
+ continue;
+ }
+
+ // The original T_END_HEREDOC/T_END_NOWDOC was most likely incorrect as we've found
+ // a possible alternative closing marker.
+ $phpcsFile->addError($error, $stackPtr, $errorCode);
+
+ break;
+ }
+
+ } else {
+ if (isset($tokens[$stackPtr]['scope_closer'], $tokens[$stackPtr]['scope_opener']) === true
+ && $tokens[$stackPtr]['scope_closer'] === $stackPtr
+ ) {
+ $opener = $tokens[$stackPtr]['scope_opener'];
+ } else {
+ // PHPCS < 3.0.2 did not add scope_* values for Nowdocs.
+ $opener = $phpcsFile->findPrevious(T_START_NOWDOC, ($stackPtr - 1));
+ if ($opener === false) {
+ return;
+ }
+ }
+
+ $quotedIdentifier = preg_quote($tokens[$stackPtr]['content'], '`');
+
+ // Throw an error for each line in the body which starts with the identifier.
+ for ($i = ($opener + 1); $i < $stackPtr; $i++) {
+ if (preg_match('`^[ \t]*' . $quotedIdentifier . '\b`', $tokens[$i]['content']) === 1) {
+ $phpcsFile->addError($error, $i, $errorCode);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFunctionArrayDereferencingSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFunctionArrayDereferencingSniff.php
new file mode 100644
index 0000000..87c5397
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFunctionArrayDereferencingSniff.php
@@ -0,0 +1,95 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\NewFunctionArrayDereferencingSniff.
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewFunctionArrayDereferencingSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_STRING);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Next non-empty token should be the open parenthesis.
+ $openParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+ if ($openParenthesis === false || $tokens[$openParenthesis]['code'] !== T_OPEN_PARENTHESIS) {
+ return;
+ }
+
+ // Don't throw errors during live coding.
+ if (isset($tokens[$openParenthesis]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ // Is this T_STRING really a function or method call ?
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if ($prevToken !== false && in_array($tokens[$prevToken]['code'], array(T_DOUBLE_COLON, T_OBJECT_OPERATOR), true) === false) {
+ $ignore = array(
+ T_FUNCTION => true,
+ T_CONST => true,
+ T_USE => true,
+ T_NEW => true,
+ T_CLASS => true,
+ T_INTERFACE => true,
+ );
+
+ if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
+ // Not a call to a PHP function or method.
+ return;
+ }
+ }
+
+ $closeParenthesis = $tokens[$openParenthesis]['parenthesis_closer'];
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($closeParenthesis + 1), null, true, null, true);
+ if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['type'] === 'T_OPEN_SQUARE_BRACKET') {
+ $phpcsFile->addError(
+ 'Function array dereferencing is not present in PHP version 5.3 or earlier',
+ $nextNonEmpty,
+ 'Found'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFunctionCallTrailingCommaSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFunctionCallTrailingCommaSniff.php
new file mode 100644
index 0000000..9d8b139
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewFunctionCallTrailingCommaSniff.php
@@ -0,0 +1,115 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\NewFunctionCallTrailingCommaSniff.
+ *
+ * PHP version 7.3
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewFunctionCallTrailingCommaSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_STRING,
+ T_VARIABLE,
+ T_ISSET,
+ T_UNSET,
+ );
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('7.2') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($tokens[$nextNonEmpty]['code'] !== T_OPEN_PARENTHESIS
+ || isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false
+ ) {
+ return;
+ }
+
+ if ($tokens[$stackPtr]['code'] === T_STRING) {
+ $ignore = array(
+ T_FUNCTION => true,
+ T_CONST => true,
+ T_USE => true,
+ );
+
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if (isset($ignore[$tokens[$prevNonEmpty]['code']]) === true) {
+ // Not a function call.
+ return;
+ }
+ }
+
+ $closer = $tokens[$nextNonEmpty]['parenthesis_closer'];
+ $lastInParenthesis = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($closer - 1), $nextNonEmpty, true);
+
+ if ($tokens[$lastInParenthesis]['code'] !== T_COMMA) {
+ return;
+ }
+
+ $data = array();
+ switch ($tokens[$stackPtr]['code']) {
+ case T_ISSET:
+ $data[] = 'calls to isset()';
+ $errorCode = 'FoundInIsset';
+ break;
+
+ case T_UNSET:
+ $data[] = 'calls to unset()';
+ $errorCode = 'FoundInUnset';
+ break;
+
+ default:
+ $data[] = 'function calls';
+ $errorCode = 'FoundInFunctionCall';
+ break;
+ }
+
+ $phpcsFile->addError(
+ 'Trailing comma\'s are not allowed in %s in PHP 7.2 or earlier',
+ $lastInParenthesis,
+ $errorCode,
+ $data
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewShortArraySniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewShortArraySniff.php
new file mode 100644
index 0000000..84c1e30
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/NewShortArraySniff.php
@@ -0,0 +1,74 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\NewShortArray.
+ *
+ * Short array syntax is available since PHP 5.4
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Alex Miroshnikov
+ */
+class NewShortArraySniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_OPEN_SHORT_ARRAY,
+ T_CLOSE_SHORT_ARRAY,
+ );
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $token = $tokens[$stackPtr];
+
+ $error = '%s is available since 5.4';
+ $data = array();
+
+ if ($token['type'] === 'T_OPEN_SHORT_ARRAY') {
+ $data[] = 'Short array syntax (open)';
+ } elseif ($token['type'] === 'T_CLOSE_SHORT_ARRAY') {
+ $data[] = 'Short array syntax (close)';
+ }
+
+ $phpcsFile->addError($error, $stackPtr, 'Found', $data);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/RemovedNewReferenceSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/RemovedNewReferenceSniff.php
new file mode 100644
index 0000000..f0f9604
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Syntax/RemovedNewReferenceSniff.php
@@ -0,0 +1,77 @@
+
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+
+namespace PHPCompatibility\Sniffs\Syntax;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Syntax\RemovedNewReferenceSniff.
+ *
+ * Discourages the use of assigning the return value of new by reference
+ *
+ * PHP version 5.4
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ * @copyright 2012 Cu.be Solutions bvba
+ */
+class RemovedNewReferenceSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_NEW);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('5.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
+ if ($prevNonEmpty === false || $tokens[$prevNonEmpty]['type'] !== 'T_BITWISE_AND') {
+ return;
+ }
+
+ $error = 'Assigning the return value of new by reference is deprecated in PHP 5.3';
+ $isError = false;
+ $errorCode = 'Deprecated';
+
+ if ($this->supportsAbove('7.0') === true) {
+ $error .= ' and has been removed in PHP 7.0';
+ $isError = true;
+ $errorCode = 'Removed';
+ }
+
+ $this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode);
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/TypeCasts/NewTypeCastsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/TypeCasts/NewTypeCastsSniff.php
new file mode 100644
index 0000000..6b0127d
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/TypeCasts/NewTypeCastsSniff.php
@@ -0,0 +1,203 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\TypeCasts;
+
+use PHPCompatibility\AbstractNewFeatureSniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\TypeCasts\NewTypeCastsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewTypeCastsSniff extends AbstractNewFeatureSniff
+{
+
+ /**
+ * A list of new type casts, not present in older versions.
+ *
+ * The array lists : version number with false (not present) or true (present).
+ * If's sufficient to list the first version where the keyword appears.
+ *
+ * @var array(string => array(string => int|string|null))
+ */
+ protected $newTypeCasts = array(
+ 'T_UNSET_CAST' => array(
+ '4.4' => false,
+ '5.0' => true,
+ 'description' => 'The unset cast',
+ ),
+ 'T_BINARY_CAST' => array(
+ '5.2.0' => false,
+ '5.2.1' => true,
+ 'description' => 'The binary cast',
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array();
+ foreach ($this->newTypeCasts as $token => $versions) {
+ if (defined($token)) {
+ $tokens[] = constant($token);
+ }
+ }
+
+ /*
+ * Work around tokenizer issues.
+ *
+ * - (binary) cast is incorrectly tokenized as T_STRING_CAST by PHP and PHPCS.
+ * - b"something" binary cast is incorrectly tokenized as T_CONSTANT_ENCAPSED_STRING by PHP and PHPCS.
+ * - Since PHPCS 3.4.0, PHPCS *will* tokenize these correctly.
+ *
+ * @link https://github.com/squizlabs/PHP_CodeSniffer/issues/1574
+ */
+ if (version_compare(PHPCSHelper::getVersion(), '3.4.0', '<') === true) {
+ $tokens[] = T_STRING_CAST;
+ $tokens[] = T_CONSTANT_ENCAPSED_STRING;
+ }
+
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $tokenType = $tokens[$stackPtr]['type'];
+
+ // Detect incorrectly tokenized binary casts.
+ if (isset($this->newTypeCasts[$tokenType]) === false) {
+ $tokenContent = $tokens[$stackPtr]['content'];
+ switch ($tokenType) {
+ case 'T_STRING_CAST':
+ if (preg_match('`^\(\s*binary\s*\)$`i', $tokenContent) !== 1) {
+ return;
+ }
+
+ $tokenType = 'T_BINARY_CAST';
+ break;
+
+ case 'T_CONSTANT_ENCAPSED_STRING':
+ if ((strpos($tokenContent, 'b"') === 0 && substr($tokenContent, -1) === '"')
+ || (strpos($tokenContent, "b'") === 0 && substr($tokenContent, -1) === "'")
+ ) {
+ $tokenType = 'T_BINARY_CAST';
+ } else {
+ return;
+ }
+ break;
+
+ }
+ }
+
+ // If the translation did not yield one of the tokens we are looking for, bow out.
+ if (isset($this->newTypeCasts[$tokenType]) === false) {
+ return;
+ }
+
+ $itemInfo = array(
+ 'name' => $tokenType,
+ 'content' => $tokens[$stackPtr]['content'],
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->newTypeCasts[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('description');
+ }
+
+
+ /**
+ * Retrieve the relevant detail (version) information for use in an error message.
+ *
+ * @param array $itemArray Version and other information about the item.
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array
+ */
+ public function getErrorInfo(array $itemArray, array $itemInfo)
+ {
+ $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
+ $errorInfo['description'] = $itemArray['description'];
+
+ return $errorInfo;
+ }
+
+
+ /**
+ * Filter the error message before it's passed to PHPCS.
+ *
+ * @param string $error The error message which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return string
+ */
+ protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
+ {
+ return $error . '. Found: %s';
+ }
+
+
+ /**
+ * Filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ $data[0] = $errorInfo['description'];
+ $data[] = $itemInfo['content'];
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/TypeCasts/RemovedTypeCastsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/TypeCasts/RemovedTypeCastsSniff.php
new file mode 100644
index 0000000..07e74bf
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/TypeCasts/RemovedTypeCastsSniff.php
@@ -0,0 +1,127 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\TypeCasts;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\TypeCasts\RemovedTypeCastsSniff.
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class RemovedTypeCastsSniff extends AbstractRemovedFeatureSniff
+{
+ /**
+ * A list of deprecated and removed type casts with their alternatives.
+ *
+ * The array lists : version number with false (deprecated) or true (removed) and an alternative function.
+ * If no alternative exists, it is NULL, i.e, the function should just not be used.
+ *
+ * @var array(string => array(string => bool|string|null))
+ */
+ protected $deprecatedTypeCasts = array(
+ 'T_UNSET_CAST' => array(
+ '7.2' => false,
+ 'alternative' => 'unset()',
+ 'description' => 'unset',
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ $tokens = array();
+ foreach ($this->deprecatedTypeCasts as $token => $versions) {
+ $tokens[] = constant($token);
+ }
+
+ return $tokens;
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+ $tokenType = $tokens[$stackPtr]['type'];
+
+ $itemInfo = array(
+ 'name' => $tokenType,
+ 'description' => $this->deprecatedTypeCasts[$tokenType]['description'],
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get an array of the non-PHP-version array keys used in a sub-array.
+ *
+ * @return array
+ */
+ protected function getNonVersionArrayKeys()
+ {
+ return array('description', 'alternative');
+ }
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->deprecatedTypeCasts[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return 'The %s cast is ';
+ }
+
+
+ /**
+ * Filter the error data before it's passed to PHPCS.
+ *
+ * @param array $data The error data array which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return array
+ */
+ protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
+ {
+ $data[0] = $itemInfo['description'];
+ return $data;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Upgrade/LowPHPCSSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Upgrade/LowPHPCSSniff.php
new file mode 100644
index 0000000..770dd46
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Upgrade/LowPHPCSSniff.php
@@ -0,0 +1,171 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Upgrade;
+
+use PHPCompatibility\Sniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+
+/**
+ * \PHPCompatibility\Sniffs\Upgrade\LowPHPCSSniff.
+ *
+ * Add a notification for users of low PHPCS versions.
+ *
+ * Originally PHPCompatibility supported PHPCS 1.5.x, 2.x and since PHPCompatibility 8.0.0, 3.x.
+ * Support for PHPCS < 2.3.0 has been dropped in PHPCompatibility 9.0.0.
+ *
+ * The standard will - up to a point - still work for users of lower
+ * PHPCS versions, but will give less accurate results and may throw
+ * notices and warnings (or even fatal out).
+ *
+ * This sniff adds an explicit error/warning for users of the standard
+ * using a PHPCS version below the recommended version.
+ *
+ * @category Upgrade
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class LowPHPCSSniff extends Sniff
+{
+ /**
+ * The minimum supported PHPCS version.
+ *
+ * Users on PHPCS versions below this will see an ERROR message.
+ *
+ * @var string
+ */
+ protected $minSupportedVersion = '2.3.0';
+
+ /**
+ * The minimum recommended PHPCS version.
+ *
+ * Users on PHPCS versions below this will see a WARNING.
+ *
+ * @var string
+ */
+ protected $minRecommendedVersion = '2.6.0';
+
+ /**
+ * Keep track of whether this sniff needs to actually run.
+ *
+ * This will be set to `false` when either a high enough PHPCS
+ * version is detected or once the error/warning has been thrown,
+ * to make sure that the notice will only be thrown once per run.
+ *
+ * @var bool
+ */
+ private $examine = true;
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(
+ T_OPEN_TAG,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ // Don't do anything if the warning has already been thrown or is not necessary.
+ if ($this->examine === false) {
+ return ($phpcsFile->numTokens + 1);
+ }
+
+ $phpcsVersion = PHPCSHelper::getVersion();
+
+ // Don't do anything if the PHPCS version used is above the minimum recommended version.
+ if (version_compare($phpcsVersion, $this->minRecommendedVersion, '>=')) {
+ $this->examine = false;
+ return ($phpcsFile->numTokens + 1);
+ }
+
+ if (version_compare($phpcsVersion, $this->minSupportedVersion, '<')) {
+ $isError = true;
+ $message = "IMPORTANT: Please be advised that the minimum PHP_CodeSniffer version the PHPCompatibility standard supports is %s. You are currently using PHP_CodeSniffer %s. Please upgrade your PHP_CodeSniffer installation. The recommended version of PHP_CodeSniffer for PHPCompatibility is %s or higher.";
+ $errorCode = 'Unsupported_' . $this->stringToErrorCode($this->minSupportedVersion);
+ $replacements = array(
+ $this->minSupportedVersion,
+ $phpcsVersion,
+ $this->minRecommendedVersion,
+ $errorCode,
+ );
+ } else {
+ $isError = false;
+ $message = "IMPORTANT: Please be advised that for the most reliable PHPCompatibility results, PHP_CodeSniffer %s or higher should be used. Support for lower versions will be dropped in the foreseeable future. You are currently using PHP_CodeSniffer %s. Please upgrade your PHP_CodeSniffer installation to version %s or higher.";
+ $errorCode = 'BelowRecommended_' . $this->stringToErrorCode($this->minRecommendedVersion);
+ $replacements = array(
+ $this->minRecommendedVersion,
+ $phpcsVersion,
+ $this->minRecommendedVersion,
+ $errorCode,
+ );
+ }
+
+ /*
+ * Figure out the report width to determine how long the delimiter lines should be.
+ *
+ * This is not an exact calculation as there are a number of unknowns at the time the
+ * notice is thrown (whether there are other notices for the file, whether those are
+ * warnings or errors, whether there are auto-fixable issues etc).
+ *
+ * In other words, this is just an approximation to get a reasonably stable and
+ * readable message layout format.
+ *
+ * {@internal
+ * PHPCS has had some changes as to how the messages display over the years.
+ * Most significantly in 2.4.0 it was attempted to solve an issue with messages
+ * containing new lines. Unfortunately, that solution is buggy.
+ * An improved version has been pulled upstream and will hopefully make it
+ * into PHPCS 3.3.1/3.4.0.
+ *
+ * Anyway, this means that instead of new lines, delimiter lines will be used to improved
+ * the readability of the (long) message.
+ *
+ * Also, as of PHPCS 2.2.0, the report width when using the `-s` option is 8 wider than
+ * it should be. A patch for that is included in the same upstream PR.
+ *
+ * If/when the upstream PR has been merged and the minimum supported/recommended version
+ * of PHPCompatibility would go beyond that, the below code should be adjusted.}}
+ */
+ $reportWidth = PHPCSHelper::getCommandLineData($phpcsFile, 'reportWidth');
+ $showSources = PHPCSHelper::getCommandLineData($phpcsFile, 'showSources');
+ if ($showSources === true && version_compare($phpcsVersion, '2.3.0', '>=')) {
+ $reportWidth += 6;
+ }
+
+ $messageWidth = ($reportWidth - 15); // 15 is length of " # | WARNING | ".
+ $delimiterLine = str_repeat('-', ($messageWidth));
+ $disableNotice = 'To disable this notice, add --exclude=PHPCompatibility.Upgrade.LowPHPCS to your command or add to your custom ruleset. ';
+ $thankYou = 'Thank you for using PHPCompatibility!';
+
+ $message .= ' ' . $delimiterLine;
+ $message .= ' ' . $disableNotice;
+ $message .= ' ' . $delimiterLine;
+ $message .= ' ' . $thankYou;
+
+ $this->addMessage($phpcsFile, $message, 0, $isError, $errorCode, $replacements);
+
+ $this->examine = false;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/UseDeclarations/NewGroupUseDeclarationsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/UseDeclarations/NewGroupUseDeclarationsSniff.php
new file mode 100644
index 0000000..85aba0e
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/UseDeclarations/NewGroupUseDeclarationsSniff.php
@@ -0,0 +1,105 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\UseDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\UseDeclarations\NewGroupUseDeclarationsSniff.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class NewGroupUseDeclarationsSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ if (defined('T_OPEN_USE_GROUP')) {
+ return array(T_OPEN_USE_GROUP);
+ } else {
+ return array(T_USE);
+ }
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('7.1') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $token = $tokens[$stackPtr];
+
+ // Deal with PHPCS pre-2.6.0.
+ if ($token['code'] === T_USE) {
+ $hasCurlyBrace = $phpcsFile->findNext(T_OPEN_CURLY_BRACKET, ($stackPtr + 1), null, false, null, true);
+ if ($hasCurlyBrace === false) {
+ return;
+ }
+
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($hasCurlyBrace - 1), null, true);
+ if ($prevToken === false || $tokens[$prevToken]['code'] !== T_NS_SEPARATOR) {
+ return;
+ }
+
+ $stackPtr = $hasCurlyBrace;
+ }
+
+ // Still here ? In that case, it is a group use statement.
+ if ($this->supportsBelow('5.6') === true) {
+ $phpcsFile->addError(
+ 'Group use declarations are not allowed in PHP 5.6 or earlier',
+ $stackPtr,
+ 'Found'
+ );
+ }
+
+ $closers = array(T_CLOSE_CURLY_BRACKET);
+ if (defined('T_CLOSE_USE_GROUP')) {
+ $closers[] = T_CLOSE_USE_GROUP;
+ }
+
+ $closeCurly = $phpcsFile->findNext($closers, ($stackPtr + 1), null, false, null, true);
+ if ($closeCurly === false) {
+ return;
+ }
+
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($closeCurly - 1), null, true);
+ if ($tokens[$prevToken]['code'] === T_COMMA) {
+ $phpcsFile->addError(
+ 'Trailing comma\'s are not allowed in group use statements in PHP 7.1 or earlier',
+ $prevToken,
+ 'TrailingCommaFound'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/UseDeclarations/NewUseConstFunctionSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/UseDeclarations/NewUseConstFunctionSniff.php
new file mode 100644
index 0000000..60d233c
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/UseDeclarations/NewUseConstFunctionSniff.php
@@ -0,0 +1,102 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\UseDeclarations;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\UseDeclarations\NewUseConstFunctionSniff.
+ *
+ * The use operator has been extended to support importing functions and
+ * constants in addition to classes. This is achieved via the use function
+ * and use const constructs, respectively.
+ *
+ * PHP version 5.6
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewUseConstFunctionSniff extends Sniff
+{
+
+ /**
+ * A list of keywords that can follow use statements.
+ *
+ * @var array(string => string)
+ */
+ protected $validUseNames = array(
+ 'const' => true,
+ 'function' => true,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_USE);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsBelow('5.5') !== true) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($nextNonEmpty === false) {
+ // Live coding.
+ return;
+ }
+
+ if (isset($this->validUseNames[strtolower($tokens[$nextNonEmpty]['content'])]) === false) {
+ // Not a `use const` or `use function` statement.
+ return;
+ }
+
+ // `use const` and `use function` have to be followed by the function/constant name.
+ $functionOrConstName = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true);
+ if ($functionOrConstName === false
+ // Identifies as T_AS or T_STRING, this covers both.
+ || ($tokens[$functionOrConstName]['content'] === 'as'
+ || $tokens[$functionOrConstName]['code'] === T_COMMA)
+ ) {
+ // Live coding or incorrect use of reserved keyword, but that is
+ // covered by the ForbiddenNames sniff.
+ return;
+ }
+
+ // Still here ? In that case we have encountered a `use const` or `use function` statement.
+ $phpcsFile->addError(
+ 'Importing functions and constants through a "use" statement is not supported in PHP 5.5 or lower.',
+ $nextNonEmpty,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/ForbiddenGlobalVariableVariableSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/ForbiddenGlobalVariableVariableSniff.php
new file mode 100644
index 0000000..0654f29
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/ForbiddenGlobalVariableVariableSniff.php
@@ -0,0 +1,124 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Variables;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Variables\ForbiddenGlobalVariableVariableSniff.
+ *
+ * Variable variables are forbidden with global
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class ForbiddenGlobalVariableVariableSniff extends Sniff
+{
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_GLOBAL);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $endOfStatement = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), ($stackPtr + 1));
+ if ($endOfStatement === false) {
+ // No semi-colon - live coding.
+ return;
+ }
+
+ for ($ptr = ($stackPtr + 1); $ptr <= $endOfStatement; $ptr++) {
+ $errorThrown = false;
+ $nextComma = $phpcsFile->findNext(T_COMMA, $ptr, $endOfStatement, false, null, true);
+ $varEnd = ($nextComma === false) ? $endOfStatement : $nextComma;
+ $variable = $phpcsFile->findNext(T_VARIABLE, $ptr, $varEnd);
+ $varString = trim($phpcsFile->getTokensAsString($ptr, ($varEnd - $ptr)));
+ $data = array($varString);
+
+ if ($variable !== false) {
+
+ $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($variable - 1), $ptr, true);
+
+ if ($prev !== false && $tokens[$prev]['type'] === 'T_DOLLAR') {
+
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($variable + 1), $varEnd, true);
+
+ if ($next !== false
+ && in_array($tokens[$next]['code'], array(T_OPEN_SQUARE_BRACKET, T_OBJECT_OPERATOR, T_DOUBLE_COLON), true) === true
+ ) {
+ $phpcsFile->addError(
+ 'Global with variable variables is not allowed since PHP 7.0. Found %s',
+ $variable,
+ 'Found',
+ $data
+ );
+ $errorThrown = true;
+ } else {
+ $phpcsFile->addWarning(
+ 'Global with anything other than bare variables is discouraged since PHP 7.0. Found %s',
+ $variable,
+ 'NonBareVariableFound',
+ $data
+ );
+ $errorThrown = true;
+ }
+ }
+ }
+
+ if ($errorThrown === false) {
+ $dollar = $phpcsFile->findNext(T_DOLLAR, $ptr, $varEnd);
+ if ($dollar !== false) {
+ $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($dollar + 1), $varEnd, true);
+ if ($tokens[$next]['code'] === T_OPEN_CURLY_BRACKET) {
+ $phpcsFile->addWarning(
+ 'Global with anything other than bare variables is discouraged since PHP 7.0. Found %s',
+ $dollar,
+ 'NonBareVariableFound',
+ $data
+ );
+ }
+ }
+ }
+
+ // Move the stack pointer forward to the next variable for multi-variable statements.
+ if ($nextComma === false) {
+ break;
+ }
+ $ptr = $nextComma;
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/ForbiddenThisUseContextsSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/ForbiddenThisUseContextsSniff.php
new file mode 100644
index 0000000..13f04e1
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/ForbiddenThisUseContextsSniff.php
@@ -0,0 +1,424 @@
+ T_CLASS,
+ 'T_INTERFACE' => T_INTERFACE,
+ 'T_TRAIT' => T_TRAIT,
+ );
+
+ /**
+ * Scopes to skip over when examining the contents of functions.
+ *
+ * @since 9.1.0
+ *
+ * @var array
+ */
+ private $skipOverScopes = array(
+ 'T_FUNCTION' => true,
+ 'T_CLOSURE' => true,
+ );
+
+ /**
+ * Valid uses of $this in plain functions or methods outside object context.
+ *
+ * @since 9.1.0
+ *
+ * @var array
+ */
+ private $validUseOutsideObject = array(
+ T_ISSET => true,
+ T_EMPTY => true,
+ );
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @since 9.1.0
+ *
+ * @return array
+ */
+ public function register()
+ {
+ if (defined('T_ANON_CLASS')) {
+ $this->ooScopeTokens['T_ANON_CLASS'] = T_ANON_CLASS;
+ }
+
+ $this->skipOverScopes += $this->ooScopeTokens;
+
+ return array(
+ T_FUNCTION,
+ T_CLOSURE,
+ T_GLOBAL,
+ T_CATCH,
+ T_FOREACH,
+ T_UNSET,
+ );
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @since 9.1.0
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.1') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ switch ($tokens[$stackPtr]['code']) {
+ case T_FUNCTION:
+ $this->isThisUsedAsParameter($phpcsFile, $stackPtr);
+ $this->isThisUsedOutsideObjectContext($phpcsFile, $stackPtr);
+ break;
+
+ case T_CLOSURE:
+ $this->isThisUsedAsParameter($phpcsFile, $stackPtr);
+ break;
+
+ case T_GLOBAL:
+ /*
+ * $this can no longer be imported using the `global` keyword.
+ * This worked in PHP 7.0, though in PHP 5.x, it would throw a
+ * fatal "Cannot re-assign $this" error.
+ */
+ $endOfStatement = $phpcsFile->findNext(array(T_SEMICOLON, T_CLOSE_TAG), ($stackPtr + 1));
+ if ($endOfStatement === false) {
+ // No semi-colon - live coding.
+ return;
+ }
+
+ for ($i = ($stackPtr + 1); $i < $endOfStatement; $i++) {
+ if ($tokens[$i]['code'] !== T_VARIABLE || $tokens[$i]['content'] !== '$this') {
+ continue;
+ }
+
+ $phpcsFile->addError(
+ '"$this" can no longer be used with the "global" keyword since PHP 7.1.',
+ $i,
+ 'Global'
+ );
+ }
+
+ break;
+
+ case T_CATCH:
+ /*
+ * $this can no longer be used as a catch variable.
+ */
+ if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $varPtr = $phpcsFile->findNext(
+ T_VARIABLE,
+ ($tokens[$stackPtr]['parenthesis_opener'] + 1),
+ $tokens[$stackPtr]['parenthesis_closer']
+ );
+
+ if ($varPtr === false || $tokens[$varPtr]['content'] !== '$this') {
+ return;
+ }
+
+ $phpcsFile->addError(
+ '"$this" can no longer be used as a catch variable since PHP 7.1.',
+ $varPtr,
+ 'Catch'
+ );
+
+ break;
+
+ case T_FOREACH:
+ /*
+ * $this can no longer be used as a foreach *value* variable.
+ * This worked in PHP 7.0, though in PHP 5.x, it would throw a
+ * fatal "Cannot re-assign $this" error.
+ */
+ if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
+ return;
+ }
+
+ $stopPtr = $phpcsFile->findPrevious(
+ array(T_AS, T_DOUBLE_ARROW),
+ ($tokens[$stackPtr]['parenthesis_closer'] - 1),
+ $tokens[$stackPtr]['parenthesis_opener']
+ );
+ if ($stopPtr === false) {
+ return;
+ }
+
+ $valueVarPtr = $phpcsFile->findNext(
+ T_VARIABLE,
+ ($stopPtr + 1),
+ $tokens[$stackPtr]['parenthesis_closer']
+ );
+ if ($valueVarPtr === false || $tokens[$valueVarPtr]['content'] !== '$this') {
+ return;
+ }
+
+ $afterThis = $phpcsFile->findNext(
+ Tokens::$emptyTokens,
+ ($valueVarPtr + 1),
+ $tokens[$stackPtr]['parenthesis_closer'],
+ true
+ );
+
+ if ($afterThis !== false
+ && ($tokens[$afterThis]['code'] === T_OBJECT_OPERATOR
+ || $tokens[$afterThis]['code'] === T_DOUBLE_COLON)
+ ) {
+ return;
+ }
+
+ $phpcsFile->addError(
+ '"$this" can no longer be used as value variable in a foreach control structure since PHP 7.1.',
+ $valueVarPtr,
+ 'ForeachValueVar'
+ );
+
+ break;
+
+ case T_UNSET:
+ /*
+ * $this can no longer be unset.
+ */
+ $openParenthesis = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+ if ($openParenthesis === false
+ || $tokens[$openParenthesis]['code'] !== T_OPEN_PARENTHESIS
+ || isset($tokens[$openParenthesis]['parenthesis_closer']) === false
+ ) {
+ return;
+ }
+
+ for ($i = ($openParenthesis + 1); $i < $tokens[$openParenthesis]['parenthesis_closer']; $i++) {
+ if ($tokens[$i]['code'] !== T_VARIABLE || $tokens[$i]['content'] !== '$this') {
+ continue;
+ }
+
+ $afterThis = $phpcsFile->findNext(
+ Tokens::$emptyTokens,
+ ($i + 1),
+ $tokens[$openParenthesis]['parenthesis_closer'],
+ true
+ );
+
+ if ($afterThis !== false
+ && ($tokens[$afterThis]['code'] === T_OBJECT_OPERATOR
+ || $tokens[$afterThis]['code'] === T_DOUBLE_COLON
+ || $tokens[$afterThis]['code'] === T_OPEN_SQUARE_BRACKET)
+ ) {
+ $i = $afterThis;
+ continue;
+ }
+
+ $phpcsFile->addError(
+ '"$this" can no longer be unset since PHP 7.1.',
+ $i,
+ 'Unset'
+ );
+ }
+
+ break;
+ }
+ }
+
+ /**
+ * Check if $this is used as a parameter in a function declaration.
+ *
+ * $this can no longer be used as a parameter in a *global* function.
+ * Use as a parameter in a method was already an error prior to PHP 7.1.
+ *
+ * @since 9.1.0
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ protected function isThisUsedAsParameter(File $phpcsFile, $stackPtr)
+ {
+ if ($this->validDirectScope($phpcsFile, $stackPtr, $this->ooScopeTokens) !== false) {
+ return;
+ }
+
+ $params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
+ if (empty($params)) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ foreach ($params as $param) {
+ if ($param['name'] !== '$this') {
+ continue;
+ }
+
+ if ($tokens[$stackPtr]['code'] === T_FUNCTION) {
+ $phpcsFile->addError(
+ '"$this" can no longer be used as a parameter since PHP 7.1.',
+ $param['token'],
+ 'FunctionParam'
+ );
+ } else {
+ $phpcsFile->addError(
+ '"$this" can no longer be used as a closure parameter since PHP 7.0.7.',
+ $param['token'],
+ 'ClosureParam'
+ );
+ }
+ }
+ }
+
+ /**
+ * Check if $this is used in a plain function or method.
+ *
+ * Prior to PHP 7.1, this would result in an "undefined variable" notice
+ * and execution would continue with $this regarded as `null`.
+ * As of PHP 7.1, this throws an exception.
+ *
+ * Note: use within isset() and empty() to check object context is still allowed.
+ * Note: $this can still be used within a closure.
+ *
+ * @since 9.1.0
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in
+ * the stack passed in $tokens.
+ *
+ * @return void
+ */
+ protected function isThisUsedOutsideObjectContext(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
+ return;
+ }
+
+ if ($this->validDirectScope($phpcsFile, $stackPtr, $this->ooScopeTokens) !== false) {
+ $methodProps = $phpcsFile->getMethodProperties($stackPtr);
+ if ($methodProps['is_static'] === false) {
+ return;
+ } else {
+ $methodName = $phpcsFile->getDeclarationName($stackPtr);
+ if ($methodName === '__call') {
+ /*
+ * This is an exception.
+ * @link https://wiki.php.net/rfc/this_var#always_show_true_this_value_in_magic_method_call
+ */
+ return;
+ }
+ }
+ }
+
+ for ($i = ($tokens[$stackPtr]['scope_opener'] + 1); $i < $tokens[$stackPtr]['scope_closer']; $i++) {
+ if (isset($this->skipOverScopes[$tokens[$i]['type']])) {
+ if (isset($tokens[$i]['scope_closer']) === false) {
+ // Live coding or parse error, will only lead to inaccurate results.
+ return;
+ }
+
+ // Skip over nested structures.
+ $i = $tokens[$i]['scope_closer'];
+ continue;
+ }
+
+ if ($tokens[$i]['code'] !== T_VARIABLE || $tokens[$i]['content'] !== '$this') {
+ continue;
+ }
+
+ if (isset($tokens[$i]['nested_parenthesis']) === true) {
+ $nestedParenthesis = $tokens[$i]['nested_parenthesis'];
+ $nestedOpenParenthesis = array_keys($nestedParenthesis);
+ $lastOpenParenthesis = array_pop($nestedOpenParenthesis);
+
+ $previousNonEmpty = $phpcsFile->findPrevious(
+ Tokens::$emptyTokens,
+ ($lastOpenParenthesis - 1),
+ null,
+ true,
+ null,
+ true
+ );
+
+ if (isset($this->validUseOutsideObject[$tokens[$previousNonEmpty]['code']])) {
+ continue;
+ }
+ }
+
+ $phpcsFile->addError(
+ '"$this" can no longer be used in a plain function or method since PHP 7.1.',
+ $i,
+ 'OutsideObjectContext'
+ );
+ }
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/NewUniformVariableSyntaxSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/NewUniformVariableSyntaxSniff.php
new file mode 100644
index 0000000..2750b0f
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/NewUniformVariableSyntaxSniff.php
@@ -0,0 +1,111 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Variables;
+
+use PHPCompatibility\Sniff;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Variables\NewUniformVariableSyntax.
+ *
+ * The interpretation of variable variables has changed in PHP 7.0.
+ *
+ * PHP version 7.0
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Juliette Reinders Folmer
+ */
+class NewUniformVariableSyntaxSniff extends Sniff
+{
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_VARIABLE);
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('7.0') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ // Verify that the next token is a square open bracket. If not, bow out.
+ $nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
+
+ if ($nextToken === false || $tokens[$nextToken]['code'] !== T_OPEN_SQUARE_BRACKET || isset($tokens[$nextToken]['bracket_closer']) === false) {
+ return;
+ }
+
+ // The previous non-empty token has to be a $, -> or ::.
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
+ if ($prevToken === false || in_array($tokens[$prevToken]['code'], array(T_DOLLAR, T_OBJECT_OPERATOR, T_DOUBLE_COLON), true) === false) {
+ return;
+ }
+
+ // For static object calls, it only applies when this is a function call.
+ if ($tokens[$prevToken]['code'] === T_DOUBLE_COLON) {
+ $hasBrackets = $tokens[$nextToken]['bracket_closer'];
+ while (($hasBrackets = $phpcsFile->findNext(Tokens::$emptyTokens, ($hasBrackets + 1), null, true, null, true)) !== false) {
+ if ($tokens[$hasBrackets]['code'] === T_OPEN_SQUARE_BRACKET) {
+ if (isset($tokens[$hasBrackets]['bracket_closer'])) {
+ $hasBrackets = $tokens[$hasBrackets]['bracket_closer'];
+ continue;
+ } else {
+ // Live coding.
+ return;
+ }
+
+ } elseif ($tokens[$hasBrackets]['code'] === T_OPEN_PARENTHESIS) {
+ // Caught!
+ break;
+
+ } else {
+ // Not a function call, so bow out.
+ return;
+ }
+ }
+
+ // Now let's also prevent false positives when used with self and static which still work fine.
+ $classToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prevToken - 1), null, true, null, true);
+ if ($classToken !== false) {
+ if ($tokens[$classToken]['code'] === T_STATIC || $tokens[$classToken]['code'] === T_SELF) {
+ return;
+ } elseif ($tokens[$classToken]['code'] === T_STRING && $tokens[$classToken]['content'] === 'self') {
+ return;
+ }
+ }
+ }
+
+ $phpcsFile->addError(
+ 'Indirect access to variables, properties and methods will be evaluated strictly in left-to-right order since PHP 7.0. Use curly braces to remove ambiguity.',
+ $stackPtr,
+ 'Found'
+ );
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/RemovedPredefinedGlobalVariablesSniff.php b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/RemovedPredefinedGlobalVariablesSniff.php
new file mode 100644
index 0000000..bfd23a9
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Variables/RemovedPredefinedGlobalVariablesSniff.php
@@ -0,0 +1,293 @@
+
+ */
+
+namespace PHPCompatibility\Sniffs\Variables;
+
+use PHPCompatibility\AbstractRemovedFeatureSniff;
+use PHPCompatibility\PHPCSHelper;
+use PHP_CodeSniffer_File as File;
+use PHP_CodeSniffer_Tokens as Tokens;
+
+/**
+ * \PHPCompatibility\Sniffs\Variables\RemovedPredefinedGlobalVariablesSniff.
+ *
+ * Discourages the use of removed global variables. Suggests alternative extensions if available
+ *
+ * @category PHP
+ * @package PHPCompatibility
+ * @author Wim Godden
+ */
+class RemovedPredefinedGlobalVariablesSniff extends AbstractRemovedFeatureSniff
+{
+
+ /**
+ * A list of removed global variables with their alternative, if any.
+ *
+ * The array lists : version number with false (deprecated) and true (removed).
+ * If's sufficient to list the first version where the variable was deprecated/removed.
+ *
+ * @var array(string|null)
+ */
+ protected $removedGlobalVariables = array(
+ 'HTTP_POST_VARS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_POST',
+ ),
+ 'HTTP_GET_VARS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_GET',
+ ),
+ 'HTTP_ENV_VARS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_ENV',
+ ),
+ 'HTTP_SERVER_VARS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_SERVER',
+ ),
+ 'HTTP_COOKIE_VARS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_COOKIE',
+ ),
+ 'HTTP_SESSION_VARS' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_SESSION',
+ ),
+ 'HTTP_POST_FILES' => array(
+ '5.3' => false,
+ '5.4' => true,
+ 'alternative' => '$_FILES',
+ ),
+
+ 'HTTP_RAW_POST_DATA' => array(
+ '5.6' => false,
+ '7.0' => true,
+ 'alternative' => 'php://input',
+ ),
+
+ 'php_errormsg' => array(
+ '7.2' => false,
+ 'alternative' => 'error_get_last()',
+ ),
+ );
+
+
+ /**
+ * Returns an array of tokens this test wants to listen for.
+ *
+ * @return array
+ */
+ public function register()
+ {
+ return array(T_VARIABLE);
+ }
+
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ *
+ * @return void
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ if ($this->supportsAbove('5.3') === false) {
+ return;
+ }
+
+ $tokens = $phpcsFile->getTokens();
+ $varName = substr($tokens[$stackPtr]['content'], 1);
+
+ if (isset($this->removedGlobalVariables[$varName]) === false) {
+ return;
+ }
+
+ if ($this->isClassProperty($phpcsFile, $stackPtr) === true) {
+ // Ok, so this was a class property declaration, not our concern.
+ return;
+ }
+
+ // Check for static usage of class properties shadowing the removed global variables.
+ if ($this->inClassScope($phpcsFile, $stackPtr, false) === true) {
+ $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true, null, true);
+ if ($prevToken !== false && $tokens[$prevToken]['code'] === T_DOUBLE_COLON) {
+ return;
+ }
+ }
+
+ // Do some additional checks for the $php_errormsg variable.
+ if ($varName === 'php_errormsg'
+ && $this->isTargetPHPErrormsgVar($phpcsFile, $stackPtr, $tokens) === false
+ ) {
+ return;
+ }
+
+ // Still here, so throw an error/warning.
+ $itemInfo = array(
+ 'name' => $varName,
+ );
+ $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
+ }
+
+
+ /**
+ * Get the relevant sub-array for a specific item from a multi-dimensional array.
+ *
+ * @param array $itemInfo Base information about the item.
+ *
+ * @return array Version and other information about the item.
+ */
+ public function getItemArray(array $itemInfo)
+ {
+ return $this->removedGlobalVariables[$itemInfo['name']];
+ }
+
+
+ /**
+ * Get the error message template for this sniff.
+ *
+ * @return string
+ */
+ protected function getErrorMsgTemplate()
+ {
+ return "Global variable '\$%s' is ";
+ }
+
+
+ /**
+ * Filter the error message before it's passed to PHPCS.
+ *
+ * @param string $error The error message which was created.
+ * @param array $itemInfo Base information about the item this error message applies to.
+ * @param array $errorInfo Detail information about an item this error message applies to.
+ *
+ * @return string
+ */
+ protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
+ {
+ if ($itemInfo['name'] === 'php_errormsg') {
+ $error = str_replace('Global', 'The', $error);
+ }
+ return $error;
+ }
+
+ /**
+ * Run some additional checks for the `$php_errormsg` variable.
+ *
+ * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ * @param array $tokens Token array of the current file.
+ *
+ * @return bool
+ */
+ private function isTargetPHPErrormsgVar(File $phpcsFile, $stackPtr, array $tokens)
+ {
+ $scopeStart = 0;
+
+ /*
+ * If the variable is detected within the scope of a function/closure, limit the checking.
+ */
+ $function = $phpcsFile->getCondition($stackPtr, T_CLOSURE);
+ if ($function === false) {
+ $function = $phpcsFile->getCondition($stackPtr, T_FUNCTION);
+ }
+
+ // It could also be a function param, which is not in the function scope.
+ if ($function === false && isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
+ $nestedParentheses = $tokens[$stackPtr]['nested_parenthesis'];
+ $parenthesisCloser = end($nestedParentheses);
+ if (isset($tokens[$parenthesisCloser]['parenthesis_owner'])
+ && ($tokens[$tokens[$parenthesisCloser]['parenthesis_owner']]['code'] === T_FUNCTION
+ || $tokens[$tokens[$parenthesisCloser]['parenthesis_owner']]['code'] === T_CLOSURE)
+ ) {
+ $function = $tokens[$parenthesisCloser]['parenthesis_owner'];
+ }
+ }
+
+ if ($function !== false) {
+ $scopeStart = $tokens[$function]['scope_opener'];
+ }
+
+ /*
+ * Now, let's do some additional checks.
+ */
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
+
+ // Is the variable being used as an array ?
+ if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === T_OPEN_SQUARE_BRACKET) {
+ // The PHP native variable is a string, so this is probably not it
+ // (except for array access to string, but why would you in this case ?).
+ return false;
+ }
+
+ // Is this a variable assignment ?
+ if ($nextNonEmpty !== false
+ && isset(Tokens::$assignmentTokens[$tokens[$nextNonEmpty]['code']]) === true
+ ) {
+ return false;
+ }
+
+ // Is this a function param shadowing the PHP native one ?
+ if ($function !== false) {
+ $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $function);
+ if (is_array($parameters) === true && empty($parameters) === false) {
+ foreach ($parameters as $param) {
+ if ($param['name'] === '$php_errormsg') {
+ return false;
+ }
+ }
+ }
+ }
+
+ $skipPast = array(
+ 'T_CLASS' => true,
+ 'T_ANON_CLASS' => true,
+ 'T_INTERFACE' => true,
+ 'T_TRAIT' => true,
+ 'T_FUNCTION' => true,
+ 'T_CLOSURE' => true,
+ );
+
+ // Walk back and see if there is an assignment to the variable within the same scope.
+ for ($i = ($stackPtr - 1); $i >= $scopeStart; $i--) {
+ if ($tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET
+ && isset($tokens[$i]['scope_condition'])
+ && isset($skipPast[$tokens[$tokens[$i]['scope_condition']]['type']])
+ ) {
+ // Skip past functions, classes etc.
+ $i = $tokens[$i]['scope_condition'];
+ continue;
+ }
+
+ if ($tokens[$i]['code'] !== T_VARIABLE || $tokens[$i]['content'] !== '$php_errormsg') {
+ continue;
+ }
+
+ $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
+
+ if ($nextNonEmpty !== false
+ && isset(Tokens::$assignmentTokens[$tokens[$nextNonEmpty]['code']]) === true
+ ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/PHPCompatibility/ruleset.xml b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/ruleset.xml
new file mode 100644
index 0000000..3eb0b67
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/PHPCompatibility/ruleset.xml
@@ -0,0 +1,7 @@
+
+
+ Coding Standard that checks for PHP version compatibility.
+
+ ./../PHPCSAliases.php
+
+
diff --git a/vendor/phpcompatibility/php-compatibility/README.md b/vendor/phpcompatibility/php-compatibility/README.md
new file mode 100644
index 0000000..0326b46
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/README.md
@@ -0,0 +1,223 @@
+PHP Compatibility Coding Standard for PHP CodeSniffer
+=====================================================
+[](https://packagist.org/packages/phpcompatibility/php-compatibility)
+[](https://packagist.org/packages/phpcompatibility/php-compatibility)
+
+[](https://github.com/PHPCompatibility/PHPCompatibility/blob/master/LICENSE)
+[](https://flattr.com/submit/auto?user_id=wimg&url=https://github.com/PHPCompatibility/PHPCompatibility&title=PHPCompatibility&language=&tags=github&category=software)
+
+[](https://travis-ci.org/PHPCompatibility/PHPCompatibility)
+[](https://scrutinizer-ci.com/g/PHPCompatibility/PHPCompatibility/)
+[](https://coveralls.io/github/PHPCompatibility/PHPCompatibility?branch=master)
+
+[](https://packagist.org/packages/phpcompatibility/php-compatibility)
+[](https://travis-ci.org/PHPCompatibility/PHPCompatibility)
+
+
+This is a set of sniffs for [PHP CodeSniffer](http://pear.php.net/PHP_CodeSniffer) that checks for PHP cross-version compatibility.
+It will allow you to analyse your code for compatibility with higher and lower versions of PHP.
+
+
+PHP Version Support
+-------
+
+The project aims to cover all PHP compatibility changes introduced since PHP 5.0 up to the latest PHP release. This is an ongoing process and coverage is not yet 100% (if, indeed, it ever could be). Progress is tracked on [our Github issue tracker](https://github.com/PHPCompatibility/PHPCompatibility/issues).
+
+Pull requests that check for compatibility issues in PHP 4 code - in particular between PHP 4 and PHP 5.0 - are very welcome as there are still situations where people need help upgrading legacy systems. However, coverage for changes introduced before PHP 5.1 will remain patchy as sniffs for this are not actively being developed at this time.
+
+Requirements
+-------
+
+* PHP 5.3+ for use with PHP CodeSniffer 2.x.
+* PHP 5.4+ for use with PHP CodeSniffer 3.x.
+
+PHP CodeSniffer: 2.3.0+ or 3.0.2+.
+
+The sniffs are designed to give the same results regardless of which PHP version you are using to run PHP CodeSniffer. You should get reasonably consistent results independently of the PHP version used in your test environment, though for the best results it is recommended to run the sniffs on PHP 5.4 or higher.
+
+PHP CodeSniffer 2.3.0 is required for 90% of the sniffs, PHP CodeSniffer 2.6.0 or later is required for full support, notices may be thrown on older versions.
+
+For running the sniffs on PHP 7.3, it is recommended to use PHP_CodeSniffer 3.3.1+, or, if needs be, PHP_CodeSniffer 2.9.2.
+PHP_CodeSniffer < 2.9.2/3.3.1 is not fully compatible with PHP 7.3, which effectively means that PHPCompatibility can't be either.
+While the sniffs will still work in _most_ cases, you can expect PHP warnings to be thrown.
+
+As of version 8.0.0, the PHPCompatibility standard can also be used with PHP CodeSniffer 3.x.
+
+As of version 9.0.0, support for PHP CodeSniffer 1.5.x and low 2.x versions < 2.3.0 has been dropped.
+
+
+Thank you
+---------
+Thanks to all [contributors](https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors) for their valuable contributions.
+
+[](https://wpengine.com)
+
+Thanks to [WP Engine](https://wpengine.com) for their support on the PHP 7.0 sniffs.
+
+
+:warning: Upgrading to PHPCompatibility 9.0.0 :warning:
+--------
+This library has been reorganized. All sniffs have been placed in categories and a significant number of sniffs have been renamed.
+
+If you use the complete `PHPCompatibility` standard without `exclude` directives in a custom ruleset and do not (yet) use the new-style PHP_CodeSniffer annotation as introduced in [PHP_CodeSniffer 3.2.0](https://github.com/squizlabs/PHP_CodeSniffer/releases/tag/3.2.0), this will have no noticeable effect and everything should work as before.
+
+However, if you do use `exclude` directives for PHPCompatibility sniffs in a custom ruleset or if you use the [new-style PHP_CodeSniffer inline annotations](https://github.com/squizlabs/PHP_CodeSniffer/releases/3.2.0), you will need to update these when upgrading. This should be a one-time only change.
+The changelog contains detailed information about all the sniff renames.
+
+Please read the changelog for version [9.0.0](https://github.com/PHPCompatibility/PHPCompatibility/releases/tag/9.0.0) carefully before upgrading.
+
+
+Installation in a Composer project (method 1)
+-------------------------------------------
+
+* Add the following lines to the `require-dev` section of your `composer.json` file.
+ ```json
+ "require-dev": {
+ "phpcompatibility/php-compatibility": "*"
+ },
+ "prefer-stable" : true
+ ```
+* Next, PHP CodeSniffer has to be informed of the location of the standard.
+ - If PHPCompatibility is the **_only_** external PHP CodeSniffer standard you use, you can add the following to your `composer.json` file to automatically run the necessary command:
+ ```json
+ "scripts": {
+ "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility",
+ "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths vendor/phpcompatibility/php-compatibility"
+ }
+ ```
+ - Alternatively - and **_strongly recommended_** if you use more than one external PHP CodeSniffer standard - you can use any of the following Composer plugins to handle this for you.
+
+ Just add the Composer plugin you prefer to the `require-dev` section of your `composer.json` file.
+
+ * [DealerDirect/phpcodesniffer-composer-installer](https://github.com/DealerDirect/phpcodesniffer-composer-installer):"^0.4.3"
+ * [higidi/composer-phpcodesniffer-standards-plugin](https://github.com/higidi/composer-phpcodesniffer-standards-plugin)
+ * [SimplyAdmire/ComposerPlugins](https://github.com/SimplyAdmire/ComposerPlugins). This plugin *might* still work, but appears to be abandoned.
+ - As a last alternative in case you use a custom ruleset, _and only if you use PHP CodeSniffer version 2.6.0 or higher_, you can tell PHP CodeSniffer the path to the PHPCompatibility standard by adding the following snippet to your custom ruleset:
+ ```xml
+
+ ```
+* Run `composer update --lock` to install both PHP CodeSniffer, the PHPCompatibility coding standard and - optionally - the Composer plugin.
+* Verify that the PHPCompatibility standard is registered correctly by running `./vendor/bin/phpcs -i` on the command line. PHPCompatibility should be listed as one of the available standards.
+* Now you can use the following command to inspect your code:
+ ```bash
+ ./vendor/bin/phpcs -p . --standard=PHPCompatibility
+ ```
+
+Installation via a git check-out to an arbitrary directory (method 2)
+-----------------------
+
+* Install [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) via [your preferred method](https://github.com/squizlabs/PHP_CodeSniffer#installation).
+
+ PHP CodeSniffer offers a variety of installation methods to suit your work-flow: Composer, [PEAR](http://pear.php.net/PHP_CodeSniffer), a Phar file, zipped/tarred release archives or checking the repository out using Git.
+
+ **Pro-tip:** Register the path to PHPCS in your system `$PATH` environment variable to make the `phpcs` command available from anywhere in your file system.
+* Download the [latest PHPCompatibility release](https://github.com/PHPCompatibility/PHPCompatibility/releases) and unzip/untar it into an arbitrary directory.
+
+ You can also choose to clone the repository using git to easily update your install regularly.
+* Add the path to the directory in which you placed your copy of the PHPCompatibility repo to the PHP CodeSniffer configuration using the below command from the command line:
+ ```bash
+ phpcs --config-set installed_paths /path/to/PHPCompatibility
+ ```
+ I.e. if you placed the `PHPCompatibility` repository in the `/my/custom/standards/PHPCompatibility` directory, you will need to add that directory to the PHP CodeSniffer [`installed_paths` configuration variable](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options#setting-the-installed-standard-paths).
+
+ **Warning**: :warning: The `installed_paths` command overwrites any previously set `installed_paths`. If you have previously set `installed_paths` for other external standards, run `phpcs --config-show` first and then run the `installed_paths` command with all the paths you need separated by comma's, i.e.:
+ ```bash
+ phpcs --config-set installed_paths /path/1,/path/2,/path/3
+ ```
+
+ **Pro-tip:** Alternatively, in case you use a custom ruleset _and only if you use PHP CodeSniffer version 2.6.0 or higher_, you can tell PHP CodeSniffer the path to the PHPCompatibility standard(s) by adding the following snippet to your custom ruleset:
+ ```xml
+
+ ```
+* Verify that the PHPCompatibility standard is registered correctly by running `phpcs -i` on the command line. PHPCompatibility should be listed as one of the available standards.
+* Now you can use the following command to inspect your code:
+ ```bash
+ phpcs -p . --standard=PHPCompatibility
+ ```
+
+Sniffing your code for compatibility with specific PHP version(s)
+------------------------------
+* Run the coding standard from the command-line with `phpcs -p . --standard=PHPCompatibility`.
+* By default, you will only receive notifications about deprecated and/or removed PHP features.
+* To get the most out of the PHPCompatibility standard, you should specify a `testVersion` to check against. That will enable the checks for both deprecated/removed PHP features as well as the detection of code using new PHP features.
+ - You can run the checks for just one specific PHP version by adding `--runtime-set testVersion 5.5` to your command line command.
+ - You can also specify a range of PHP versions that your code needs to support. In this situation, compatibility issues that affect any of the PHP versions in that range will be reported: `--runtime-set testVersion 5.3-5.5`.
+ - As of PHPCompatibility 7.1.3, you can omit one part of the range if you want to support everything above or below a particular version, i.e. use `--runtime-set testVersion 7.0-` to run all the checks for PHP 7.0 and above.
+* By default the report will be sent to the console, if you want to save the report to a file, add the following to the command line command: `--report-full=path/to/report-file`.
+ For more information and other reporting options, check the [PHP CodeSniffer wiki](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Reporting).
+
+
+### Using a framework/CMS/polyfill specific ruleset
+
+As of mid 2018, a limited set of framework/CMS specific rulesets is available. These rulesets are hosted in their own repositories.
+* `PHPCompatibilityJoomla` [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityJoomla) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-joomla)
+* `PHPCompatibilityWP` [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityWP) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-wp)
+
+Since the autumn of 2018, there are also a number of PHP polyfill specific rulesets available:
+* `PHPCompatibilityPasswordCompat` [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityPasswordCompat) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-passwordcompat): accounts for @ircmaxell's [`password_compat`](https://github.com/ircmaxell/password_compat) polyfill library.
+* `PHPCompatibilityParagonie` [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityParagonie) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-paragonie): contains two rulesets which account for the Paragonie [`random_compat`](https://github.com/paragonie/random_compat) and [`sodium_compat`](https://github.com/paragonie/sodium_compat) polyfill libraries respectively.
+* `PHPCompatibilitySymfony` [GitHub](https://github.com/PHPCompatibility/PHPCompatibilitySymfony) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-symfony): contains a number of rulesets which account for various PHP polyfill libraries offered by the Symfony project. For more details about the available rulesets, please check out the [README of the PHPCompatibilitySymfony](https://github.com/PHPCompatibility/PHPCompatibilitySymfony/blob/master/README.md) repository.
+
+If you want to make sure you have all PHPCompatibility rulesets available at any time, you can use the `PHPCompatibilityAll` package [GitHub](https://github.com/PHPCompatibility/PHPCompatibilityAll) | [Packagist](https://packagist.org/packages/phpcompatibility/phpcompatibility-all).
+
+**IMPORTANT:** Framework/CMS/Polyfill specific rulesets do not set the minimum PHP version for your project, so you will still need to pass a `testVersion` to get the most accurate results.
+
+
+Using a custom ruleset
+------------------------------
+Like with any PHP CodeSniffer standard, you can add PHPCompatibility to a custom PHP CodeSniffer ruleset.
+
+```xml
+
+
+ My rules for PHP CodeSniffer
+
+
+
+
+
+
+
+
+```
+
+You can also set the `testVersion` from within the ruleset:
+```xml
+
+
+```
+
+Other advanced options, such as changing the message type or severity of select sniffs, as described in the [PHPCS Annotated ruleset](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Annotated-ruleset.xml) wiki page are, of course, also supported.
+
+#### `testVersion` in the ruleset versus command-line
+
+In PHPCS 3.2.0 and lower, once you set the `testVersion` in the ruleset, you could not overrule it from the command-line anymore.
+Starting with PHPCS 3.3.0, a `testVersion` set via the command-line will overrule the `testVersion` in the ruleset.
+
+This allows for more flexibility when, for instance, your project needs to comply with PHP `5.5-`, but you have a bootstrap file which needs to be compatible with PHP `5.2-`.
+
+
+#### PHPCompatibility specific options
+
+At this moment, there is one sniff which has a property which can be set via the ruleset. More custom properties may become available in the future.
+
+The `PHPCompatibility.Extensions.RemovedExtensions` sniff checks for removed extensions based on the function prefix used for these extensions.
+This might clash with userland functions using the same function prefix.
+
+To whitelist userland functions, you can pass a comma-delimited list of function names to the sniff.
+```xml
+
+
+
+
+
+
+```
+
+This property was added in PHPCompatibility version 7.0.1.
+As of PHPCompatibility version 8.0.0, this custom property is only supported in combination with PHP CodeSniffer > 2.6.0 due to an upstream bug (which was fixed in PHPCS 2.6.0).
+
+
+License
+-------
+This code is released under the GNU Lesser General Public License (LGPL). For more information, visit http://www.gnu.org/copyleft/lesser.html
diff --git a/vendor/phpcompatibility/php-compatibility/composer.json b/vendor/phpcompatibility/php-compatibility/composer.json
new file mode 100644
index 0000000..5a0384a
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/composer.json
@@ -0,0 +1,44 @@
+{
+ "name" : "phpcompatibility/php-compatibility",
+ "description" : "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
+ "type" : "phpcodesniffer-standard",
+ "keywords" : [ "compatibility", "phpcs", "standards" ],
+ "homepage" : "http://techblog.wimgodden.be/tag/codesniffer/",
+ "license" : "LGPL-3.0-or-later",
+ "authors" : [ {
+ "name" : "Wim Godden",
+ "role" : "lead",
+ "homepage" : "https://github.com/wimg"
+ },
+ {
+ "name" : "Juliette Reinders Folmer",
+ "role" : "lead",
+ "homepage" : "https://github.com/jrfnl"
+ },
+ {
+ "name" : "Contributors",
+ "homepage" : "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
+ } ],
+ "support" : {
+ "issues" : "https://github.com/PHPCompatibility/PHPCompatibility/issues",
+ "source" : "https://github.com/PHPCompatibility/PHPCompatibility"
+ },
+ "require" : {
+ "php" : ">=5.3",
+ "squizlabs/php_codesniffer" : "^2.3 || ^3.0.2"
+ },
+ "require-dev" : {
+ "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "conflict": {
+ "squizlabs/php_codesniffer": "2.6.2"
+ },
+ "suggest" : {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "scripts" : {
+ "post-install-cmd": "\"vendor/bin/phpcs\" --config-set installed_paths ../../..",
+ "post-update-cmd" : "\"vendor/bin/phpcs\" --config-set installed_paths ../../.."
+ }
+}
diff --git a/vendor/phpcompatibility/php-compatibility/phpunit-bootstrap.php b/vendor/phpcompatibility/php-compatibility/phpunit-bootstrap.php
new file mode 100644
index 0000000..f5d728b
--- /dev/null
+++ b/vendor/phpcompatibility/php-compatibility/phpunit-bootstrap.php
@@ -0,0 +1,79 @@
+=')
+ && class_exists('PHPUnit_Framework_TestCase') === false
+) {
+ class_alias('PHPUnit\Framework\TestCase', 'PHPUnit_Framework_TestCase');
+}
+
+require_once __DIR__ . $ds . 'PHPCompatibility' . $ds . 'Tests' . $ds . 'BaseSniffTest.php';
+require_once __DIR__ . $ds . 'PHPCompatibility' . $ds . 'Util' . $ds . 'Tests' . $ds . 'CoreMethodTestFrame.php';
+unset($ds, $phpcsDir, $vendorDir);
diff --git a/vendor/phpcompatibility/phpcompatibility-paragonie/LICENSE b/vendor/phpcompatibility/phpcompatibility-paragonie/LICENSE
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-paragonie/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vendor/phpcompatibility/phpcompatibility-paragonie/PHPCompatibilityParagonieRandomCompat/ruleset.xml b/vendor/phpcompatibility/phpcompatibility-paragonie/PHPCompatibilityParagonieRandomCompat/ruleset.xml
new file mode 100644
index 0000000..e67a12e
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-paragonie/PHPCompatibilityParagonieRandomCompat/ruleset.xml
@@ -0,0 +1,40 @@
+
+
+ PHPCompatibility ruleset for PHP_CodeSniffer which accounts for polyfills provided by the Paragonie random_compat library.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /random_compat/lib/byte_safe_strings\.php$
+
+
+ /random_compat/lib/random_bytes_dev_urandom\.php$
+
+
+ /random_compat/lib/random_bytes_mcrypt\.php$
+
+
+ /random_compat/lib/random_bytes_mcrypt\.php$
+
+
+ /random_compat/lib/random_bytes_mcrypt\.php$
+
+
+ /random_compat/lib/random_bytes_libsodium\.php$
+
+
+
diff --git a/vendor/phpcompatibility/phpcompatibility-paragonie/PHPCompatibilityParagonieSodiumCompat/ruleset.xml b/vendor/phpcompatibility/phpcompatibility-paragonie/PHPCompatibilityParagonieSodiumCompat/ruleset.xml
new file mode 100644
index 0000000..a0b189b
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-paragonie/PHPCompatibilityParagonieSodiumCompat/ruleset.xml
@@ -0,0 +1,148 @@
+
+
+ PHPCompatibility ruleset for PHP_CodeSniffer which accounts for polyfills provided by the Paragonie sodium_compat library.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phpcompatibility/phpcompatibility-paragonie/README.md b/vendor/phpcompatibility/phpcompatibility-paragonie/README.md
new file mode 100644
index 0000000..e2c2b73
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-paragonie/README.md
@@ -0,0 +1,109 @@
+[](https://packagist.org/packages/phpcompatibility/phpcompatibility-paragonie)
+[](https://packagist.org/packages/phpcompatibility/phpcompatibility-paragonie)
+[](https://github.com/PHPCompatibility/PHPCompatibilityParagonie/blob/master/LICENSE)
+[](https://travis-ci.org/PHPCompatibility/PHPCompatibilityParagonie)
+
+# PHPCompatibilityParagonie
+
+Using PHPCompatibilityParagonie, you can analyse the codebase of a project using either of the Paragonie polyfills, for PHP cross-version compatibility.
+
+
+## What's in this repo ?
+
+Two rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.
+
+These rulesets prevent false positives from the [PHPCompatibility standard](https://github.com/PHPCompatibility/PHPCompatibility) by excluding back-fills and poly-fills which are provided by those libraries.
+
+Paragonie Polyfill Library | Corresponding PHPCompatibility Ruleset | Includes
+--- | --- | ---
+[`random_compat`](https://github.com/paragonie/random_compat) | `PHPCompatibilityParagonieRandomCompat`
+[`sodium_compat`](https://github.com/paragonie/sodium_compat) | `PHPCompatibilityParagonieSodiumCompat` | `PHPCompatibilityParagonieRandomCompat`
+
+> Note:
+> As the `sodium_compat` library has `random_compat` [as a dependency](https://github.com/paragonie/sodium_compat/blob/master/composer.json), the `PHPCompatibilityParagonieSodiumCompat` ruleset includes the `PHPCompatibilityParagonieRandomCompat` ruleset.
+>
+> In practice, this means that if your project uses both libraries, you just need to use the `PHPCompatibilityParagonieSodiumCompat` ruleset to prevent false positives from both.
+
+
+## Requirements
+
+* [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer).
+ * PHP 5.3+ for use with [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) 2.3.0+.
+ * PHP 5.4+ for use with [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) 3.0.2+.
+
+ Use the latest stable release of PHP_CodeSniffer for the best results.
+ The minimum _recommended_ version of PHP_CodeSniffer is version 2.6.0.
+* [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) 9.0.0+.
+
+
+## Installation instructions
+
+The only supported installation method is via [Composer](https://getcomposer.org/).
+
+If you don't have a Composer plugin installed to manage the `installed_paths` setting for PHP_CodeSniffer, run the following from the command-line:
+```bash
+composer require --dev dealerdirect/phpcodesniffer-composer-installer:^0.4.4 phpcompatibility/phpcompatibility-paragonie:*
+composer install
+```
+
+If you already have a Composer PHP_CodeSniffer plugin installed, run:
+```bash
+composer require --dev phpcompatibility/phpcompatibility-paragonie:*
+composer install
+```
+
+Next, run:
+```bash
+vendor/bin/phpcs -i
+```
+If all went well, you will now see that the `PHPCompatibility`, `PHPCompatibilityParagonieRandomCompat` and `PHPCompatibilityParagonieSodiumCompat` standards are installed for PHP_CodeSniffer.
+
+
+## How to use
+
+Now you can use the following commands to inspect the code in your project for PHP cross-version compatibility:
+```bash
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityParagonieRandomCompat
+
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityParagonieSodiumCompat
+```
+
+By default, you will only receive notifications about deprecated and/or removed PHP features.
+
+To get the most out of the PHPCompatibilityParagonie rulesets, you should specify a `testVersion` to check against. That will enable the checks for both deprecated/removed PHP features as well as the detection of code using new PHP features.
+
+For example:
+```bash
+# For a project which should be compatible with PHP 5.3 up to and including PHP 7.0:
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityParagonieRandomCompat --runtime-set testVersion 5.3-7.0
+
+# For a project which should be compatible with PHP 5.4 and higher:
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityParagonieSodiumCompat --runtime-set testVersion 5.4-
+```
+
+For more detailed information about setting the `testVersion`, see the README of the generic [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions) standard.
+
+
+### Testing PHP files only
+
+By default PHP_CodeSniffer will analyse PHP, JavaScript and CSS files. As the PHPCompatibility sniffs only target PHP code, you can make the run slightly faster by telling PHP_CodeSniffer to only check PHP files, like so:
+```bash
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityParagonieRandomCompat --extensions=php --runtime-set testVersion 5.3-
+```
+
+## License
+
+All code within the PHPCompatibility organisation is released under the GNU Lesser General Public License (LGPL). For more information, visit https://www.gnu.org/copyleft/lesser.html
+
+
+## Changelog
+
+### 1.0.1 - 2018-12-16
+
+* Prevent false positives when the ruleset is run over the code of the `RandomCompat` polyfill itself.
+* The rulesets are now also tested against PHP 7.3.
+ Note: full PHP 7.3 support is only available in combination with PHP_CodeSniffer 2.9.2 or 3.3.1+ due to an incompatibility within PHP_CodeSniffer itself.
+
+### 1.0.0 - 2018-10-07
+
+Initial release of PHPCompatibilityParagonie containing rulesets covering the `random_compat` and `sodium_compat` polyfill libraries.
diff --git a/vendor/phpcompatibility/phpcompatibility-paragonie/composer.json b/vendor/phpcompatibility/phpcompatibility-paragonie/composer.json
new file mode 100644
index 0000000..996b51c
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-paragonie/composer.json
@@ -0,0 +1,31 @@
+{
+ "name" : "phpcompatibility/phpcompatibility-paragonie",
+ "description" : "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.",
+ "type" : "phpcodesniffer-standard",
+ "keywords" : [ "compatibility", "phpcs", "standards", "paragonie", "polyfill" ],
+ "homepage" : "http://phpcompatibility.com/",
+ "license" : "LGPL-3.0-or-later",
+ "authors" : [ {
+ "name" : "Wim Godden",
+ "role" : "lead"
+ },
+ {
+ "name" : "Juliette Reinders Folmer",
+ "role" : "lead"
+ } ],
+ "support" : {
+ "issues" : "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues",
+ "source" : "https://github.com/PHPCompatibility/PHPCompatibilityParagonie"
+ },
+ "require" : {
+ "phpcompatibility/php-compatibility" : "^9.0"
+ },
+ "require-dev" : {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4"
+ },
+ "suggest" : {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "prefer-stable" : true
+}
diff --git a/vendor/phpcompatibility/phpcompatibility-wp/LICENSE b/vendor/phpcompatibility/phpcompatibility-wp/LICENSE
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-wp/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/vendor/phpcompatibility/phpcompatibility-wp/PHPCompatibilityWP/ruleset.xml b/vendor/phpcompatibility/phpcompatibility-wp/PHPCompatibilityWP/ruleset.xml
new file mode 100644
index 0000000..a47477a
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-wp/PHPCompatibilityWP/ruleset.xml
@@ -0,0 +1,44 @@
+
+
+ WordPress specific ruleset which checks for PHP cross version compatibility.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/phpcompatibility/phpcompatibility-wp/README.md b/vendor/phpcompatibility/phpcompatibility-wp/README.md
new file mode 100644
index 0000000..279c044
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-wp/README.md
@@ -0,0 +1,98 @@
+[](https://packagist.org/packages/phpcompatibility/phpcompatibility-wp)
+[](https://packagist.org/packages/phpcompatibility/phpcompatibility-wp)
+[](https://github.com/PHPCompatibility/PHPCompatibilityWP/blob/master/LICENSE)
+[](https://travis-ci.org/PHPCompatibility/PHPCompatibilityWP)
+
+# PHPCompatibilityWP
+
+Using PHPCompatibilityWP, you can analyse the codebase of a WordPress-based project for PHP cross-version compatibility.
+
+
+## What's in this repo ?
+
+A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects based on the WordPress CMS.
+
+This WordPress specific ruleset prevents false positives from the [PHPCompatibility standard](https://github.com/PHPCompatibility/PHPCompatibility) by excluding back-fills and poly-fills which are provided by WordPress.
+
+
+## Requirements
+
+* [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer).
+ * PHP 5.3+ for use with [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) 2.3.0+.
+ * PHP 5.4+ for use with [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) 3.0.2+.
+
+ Use the latest stable release of PHP_CodeSniffer for the best results.
+ The minimum _recommended_ version of PHP_CodeSniffer is version 2.6.0.
+* [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility) 9.0.0+.
+* [PHPCompatibilityParagonie](https://github.com/PHPCompatibility/PHPCompatibilityParagonie) 1.0.0+.
+
+
+## Installation instructions
+
+The only supported installation method is via [Composer](https://getcomposer.org/).
+
+If you don't have a Composer plugin installed to manage the `installed_paths` setting for PHP_CodeSniffer, run the following from the command-line:
+```bash
+composer require --dev dealerdirect/phpcodesniffer-composer-installer:^0.4.3 phpcompatibility/phpcompatibility-wp:*
+composer install
+```
+
+If you already have a Composer PHP_CodeSniffer plugin installed, run:
+```bash
+composer require --dev phpcompatibility/phpcompatibility-wp:*
+composer install
+```
+
+Next, run:
+```bash
+vendor/bin/phpcs -i
+```
+If all went well, you will now see that the `PHPCompatibility`, `PHPCompatibilityWP` and some more PHPCompatibility standards are installed for PHP_CodeSniffer.
+
+
+## How to use
+
+Now you can use the following command to inspect your code:
+```bash
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityWP
+```
+
+By default, you will only receive notifications about deprecated and/or removed PHP features.
+
+To get the most out of the PHPCompatibilityWP standard, you should specify a `testVersion` to check against. That will enable the checks for both deprecated/removed PHP features as well as the detection of code using new PHP features.
+
+The minimum PHP requirement of the WordPress project at this time is PHP 5.2.4. If you want to enforce this, either add `--runtime-set testVersion 5.2-` to your command-line command or add `` to your [custom ruleset](https://github.com/PHPCompatibility/PHPCompatibility#using-a-custom-ruleset).
+
+For example:
+```bash
+# For a project which should be compatible with PHP 5.2 and higher:
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityWP --runtime-set testVersion 5.2-
+```
+
+For more detailed information about setting the `testVersion`, see the README of the generic [PHPCompatibility](https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions) standard.
+
+
+### Testing PHP files only
+
+By default PHP_CodeSniffer will analyse PHP, JavaScript and CSS files. As the PHPCompatibility sniffs only target PHP code, you can make the run slightly faster by telling PHP_CodeSniffer to only check PHP files, like so:
+```bash
+./vendor/bin/phpcs -p . --standard=PHPCompatibilityWP --extensions=php --runtime-set testVersion 5.2-
+```
+
+## License
+
+All code within the PHPCompatibility organisation is released under the GNU Lesser General Public License (LGPL). For more information, visit https://www.gnu.org/copyleft/lesser.html
+
+
+## Changelog
+
+### 2.0.0 - 2018-10-07
+
+- Ruleset: Updated for compatibility with PHPCompatibility 9.0+.
+- Composer: Added dependency for a dedicated polyfill-based PHPCompatibility ruleset.
+- CI: Added a test for the ruleset.
+- Readme: Removed the installation instructions for a non-Composer based install.
+
+### 1.0.0 - 2018-07-17
+
+Initial release of the PHPCompatibilityWP ruleset.
diff --git a/vendor/phpcompatibility/phpcompatibility-wp/composer.json b/vendor/phpcompatibility/phpcompatibility-wp/composer.json
new file mode 100644
index 0000000..5c1cd1a
--- /dev/null
+++ b/vendor/phpcompatibility/phpcompatibility-wp/composer.json
@@ -0,0 +1,32 @@
+{
+ "name" : "phpcompatibility/phpcompatibility-wp",
+ "description" : "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.",
+ "type" : "phpcodesniffer-standard",
+ "keywords" : [ "compatibility", "phpcs", "standards", "wordpress" ],
+ "homepage" : "http://phpcompatibility.com/",
+ "license" : "LGPL-3.0-or-later",
+ "authors" : [ {
+ "name" : "Wim Godden",
+ "role" : "lead"
+ },
+ {
+ "name" : "Juliette Reinders Folmer",
+ "role" : "lead"
+ } ],
+ "support" : {
+ "issues" : "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues",
+ "source" : "https://github.com/PHPCompatibility/PHPCompatibilityWP"
+ },
+ "require" : {
+ "phpcompatibility/php-compatibility" : "^9.0",
+ "phpcompatibility/phpcompatibility-paragonie" : "^1.0"
+ },
+ "require-dev" : {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
+ },
+ "suggest" : {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.",
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "prefer-stable" : true
+}
diff --git a/vendor/squizlabs/php_codesniffer/.gitattributes b/vendor/squizlabs/php_codesniffer/.gitattributes
new file mode 100644
index 0000000..56dcc5d
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/.gitattributes
@@ -0,0 +1,5 @@
+.travis.yml export-ignore
+package.xml export-ignore
+phpunit.xml.dist export-ignore
+php5-testingConfig.ini export-ignore
+php7-testingConfig.ini export-ignore
diff --git a/vendor/squizlabs/php_codesniffer/.gitignore b/vendor/squizlabs/php_codesniffer/.gitignore
new file mode 100644
index 0000000..9965895
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/.gitignore
@@ -0,0 +1,6 @@
+/CodeSniffer.conf
+/phpcs.xml
+/phpunit.xml
+.idea/*
+/vendor/
+composer.lock
diff --git a/vendor/squizlabs/php_codesniffer/CONTRIBUTING.md b/vendor/squizlabs/php_codesniffer/CONTRIBUTING.md
new file mode 100644
index 0000000..5cc7363
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/CONTRIBUTING.md
@@ -0,0 +1,13 @@
+Contributing
+-------------
+
+Before you contribute code to PHP\_CodeSniffer, please make sure it conforms to the PHPCS coding standard and that the PHP\_CodeSniffer unit tests still pass. The easiest way to contribute is to work on a checkout of the repository, or your own fork, rather than an installed PEAR version. If you do this, you can run the following commands to check if everything is ready to submit:
+
+ cd PHP_CodeSniffer
+ php bin/phpcs
+
+Which should display no coding standard errors. And then:
+
+ phpunit
+
+Which should give you no failures or errors. You can ignore any skipped tests as these are for external tools.
diff --git a/vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist b/vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist
new file mode 100644
index 0000000..62dc395
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist
@@ -0,0 +1,9 @@
+ 'PSR2',
+ 'report_format' => 'summary',
+ 'show_warnings' => '0',
+ 'show_progress' => '1',
+ 'report_width' => '120',
+)
+?>
diff --git a/vendor/squizlabs/php_codesniffer/README.md b/vendor/squizlabs/php_codesniffer/README.md
new file mode 100644
index 0000000..3fcbbb6
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/README.md
@@ -0,0 +1,110 @@
+## About
+
+PHP\_CodeSniffer is a set of two PHP scripts; the main `phpcs` script that tokenizes PHP, JavaScript and CSS files to detect violations of a defined coding standard, and a second `phpcbf` script to automatically correct coding standard violations. PHP\_CodeSniffer is an essential development tool that ensures your code remains clean and consistent.
+
+[](https://travis-ci.org/squizlabs/PHP_CodeSniffer) [](http://squizlabs.github.io/PHP_CodeSniffer/analysis/squizlabs/PHP_CodeSniffer) [](https://gitter.im/squizlabs/PHP_CodeSniffer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+## Requirements
+
+PHP\_CodeSniffer requires PHP version 5.4.0 or greater, although individual sniffs may have additional requirements such as external applications and scripts. See the [Configuration Options manual page](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Configuration-Options) for a list of these requirements.
+
+If you're using PHP_CodeSniffer as part of a team, or you're running it on a [CI](https://en.wikipedia.org/wiki/Continuous_integration) server, you may want to configure your project's settings [using a configuration file](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage#using-a-default-configuration-file).
+
+
+## Installation
+
+The easiest way to get started with PHP\_CodeSniffer is to download the Phar files for each of the commands:
+```
+# Download using curl
+curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
+curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
+
+# Or download using wget
+wget https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar
+wget https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar
+
+# Then test the downloaded PHARs
+php phpcs.phar -h
+php phpcbf.phar -h
+```
+
+### Composer
+If you use Composer, you can install PHP_CodeSniffer system-wide with the following command:
+
+ composer global require "squizlabs/php_codesniffer=*"
+
+Make sure you have the composer bin dir in your PATH. The default value is `~/.composer/vendor/bin/`, but you can check the value that you need to use by running `composer global config bin-dir --absolute`.
+
+Or alternatively, include a dependency for `squizlabs/php_codesniffer` in your `composer.json` file. For example:
+
+```json
+{
+ "require-dev": {
+ "squizlabs/php_codesniffer": "3.*"
+ }
+}
+```
+
+You will then be able to run PHP_CodeSniffer from the vendor bin directory:
+
+ ./vendor/bin/phpcs -h
+ ./vendor/bin/phpcbf -h
+
+### Phive
+If you use Phive, you can install PHP_CodeSniffer as a project tool using the following commands:
+
+ phive install phpcs
+ phive install phpcbf
+
+You will then be able to run PHP_CodeSniffer from the tools directory:
+
+ ./tools/phpcs -h
+ ./tools/phpcbf -h
+
+### PEAR
+If you use PEAR, you can install PHP\_CodeSniffer using the PEAR installer. This will make the `phpcs` and `phpcbf` commands immediately available for use. To install PHP\_CodeSniffer using the PEAR installer, first ensure you have [installed PEAR](http://pear.php.net/manual/en/installation.getting.php) and then run the following command:
+
+ pear install PHP_CodeSniffer
+
+### Git Clone
+You can also download the PHP\_CodeSniffer source and run the `phpcs` and `phpcbf` commands directly from the Git clone:
+
+ git clone https://github.com/squizlabs/PHP_CodeSniffer.git
+ cd PHP_CodeSniffer
+ php bin/phpcs -h
+ php bin/phpcbf -h
+
+## Documentation
+
+The documentation for PHP\_CodeSniffer is available on the [Github wiki](https://github.com/squizlabs/PHP_CodeSniffer/wiki).
+
+## Issues
+
+Bug reports and feature requests can be submitted on the [Github Issue Tracker](https://github.com/squizlabs/PHP_CodeSniffer/issues).
+
+## Contributing
+
+See [CONTRIBUTING.md](CONTRIBUTING.md) for information.
+
+## Versioning
+
+PHP_CodeSniffer uses a `MAJOR.MINOR.PATCH` version number format.
+
+The `MAJOR` version is incremented when:
+- backwards-incompatible changes are made to how the `phpcs` or `phpcbf` commands are used, or
+- backwards-incompatible changes are made to the `ruleset.xml` format, or
+- backwards-incompatible changes are made to the API used by sniff developers, or
+- custom PHP_CodeSniffer token types are removed
+
+The `MINOR` version is incremented when:
+- new backwards-compatible features are added to the `phpcs` and `phpcbf` commands, or
+- backwards-compatible changes are made to the `ruleset.xml` format, or
+- backwards-compatible changes are made to the API used by sniff developers, or
+- new sniffs are added to an included standard
+
+> NOTE: Backwards-compatible changes to the API used by sniff developers will allow an existing sniff to continue running without producing fatal errors but may not result in the sniff reporting the same errors as it did previously without changes being required.
+
+The `PATCH` version is incremented when:
+- backwards-compatible bug fixes are made
+
+> NOTE: As PHP_CodeSniffer exists to report and fix issues, most bugs are the result of coding standard errors being incorrectly reported or coding standard errors not being reported when they should be. This means that the messages produced by PHP_CodeSniffer, and the fixes it makes, are likely to be different between PATCH versions.
diff --git a/vendor/squizlabs/php_codesniffer/autoload.php b/vendor/squizlabs/php_codesniffer/autoload.php
new file mode 100644
index 0000000..8067521
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/autoload.php
@@ -0,0 +1,300 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer;
+
+if (class_exists('PHP_CodeSniffer\Autoload', false) === false) {
+ class Autoload
+ {
+
+ /**
+ * The composer autoloader.
+ *
+ * @var \Composer\Autoload\ClassLoader
+ */
+ private static $composerAutoloader = null;
+
+ /**
+ * A mapping of file names to class names.
+ *
+ * @var array
+ */
+ private static $loadedClasses = [];
+
+ /**
+ * A mapping of class names to file names.
+ *
+ * @var array
+ */
+ private static $loadedFiles = [];
+
+ /**
+ * A list of additional directories to search during autoloading.
+ *
+ * This is typically a list of coding standard directories.
+ *
+ * @var string[]
+ */
+ private static $searchPaths = [];
+
+
+ /**
+ * Loads a class.
+ *
+ * This method only loads classes that exist in the PHP_CodeSniffer namespace.
+ * All other classes are ignored and loaded by subsequent autoloaders.
+ *
+ * @param string $class The name of the class to load.
+ *
+ * @return bool
+ */
+ public static function load($class)
+ {
+ // Include the composer autoloader if there is one, but re-register it
+ // so this autoloader runs before the composer one as we need to include
+ // all files so we can figure out what the class/interface/trait name is.
+ if (self::$composerAutoloader === null) {
+ // Make sure we don't try to load any of Composer's classes
+ // while the autoloader is being setup.
+ if (strpos($class, 'Composer\\') === 0) {
+ return;
+ }
+
+ if (strpos(__DIR__, 'phar://') !== 0
+ && file_exists(__DIR__.'/../../autoload.php') === true
+ ) {
+ self::$composerAutoloader = include __DIR__.'/../../autoload.php';
+ if (self::$composerAutoloader instanceof \Composer\Autoload\ClassLoader) {
+ self::$composerAutoloader->unregister();
+ self::$composerAutoloader->register();
+ } else {
+ // Something went wrong, so keep going without the autoloader
+ // although namespaced sniffs might error.
+ self::$composerAutoloader = false;
+ }
+ } else {
+ self::$composerAutoloader = false;
+ }
+ }//end if
+
+ $ds = DIRECTORY_SEPARATOR;
+ $path = false;
+
+ if (substr($class, 0, 16) === 'PHP_CodeSniffer\\') {
+ if (substr($class, 0, 22) === 'PHP_CodeSniffer\Tests\\') {
+ $isInstalled = !is_dir(__DIR__.$ds.'tests');
+ if ($isInstalled === false) {
+ $path = __DIR__.$ds.'tests';
+ } else {
+ $path = '@test_dir@'.$ds.'PHP_CodeSniffer'.$ds.'CodeSniffer';
+ }
+
+ $path .= $ds.substr(str_replace('\\', $ds, $class), 22).'.php';
+ } else {
+ $path = __DIR__.$ds.'src'.$ds.substr(str_replace('\\', $ds, $class), 16).'.php';
+ }
+ }
+
+ // See if the composer autoloader knows where the class is.
+ if ($path === false && self::$composerAutoloader !== false) {
+ $path = self::$composerAutoloader->findFile($class);
+ }
+
+ // See if the class is inside one of our alternate search paths.
+ if ($path === false) {
+ foreach (self::$searchPaths as $searchPath => $nsPrefix) {
+ $className = $class;
+ if ($nsPrefix !== '' && substr($class, 0, strlen($nsPrefix)) === $nsPrefix) {
+ $className = substr($class, (strlen($nsPrefix) + 1));
+ }
+
+ $path = $searchPath.$ds.str_replace('\\', $ds, $className).'.php';
+ if (is_file($path) === true) {
+ break;
+ }
+
+ $path = false;
+ }
+ }
+
+ if ($path !== false && is_file($path) === true) {
+ self::loadFile($path);
+ return true;
+ }
+
+ return false;
+
+ }//end load()
+
+
+ /**
+ * Includes a file and tracks what class or interface was loaded as a result.
+ *
+ * @param string $path The path of the file to load.
+ *
+ * @return string The fully qualified name of the class in the loaded file.
+ */
+ public static function loadFile($path)
+ {
+ if (strpos(__DIR__, 'phar://') !== 0) {
+ $path = realpath($path);
+ if ($path === false) {
+ return false;
+ }
+ }
+
+ if (isset(self::$loadedClasses[$path]) === true) {
+ return self::$loadedClasses[$path];
+ }
+
+ $classes = get_declared_classes();
+ $interfaces = get_declared_interfaces();
+ $traits = get_declared_traits();
+
+ include $path;
+
+ $className = null;
+ $newClasses = array_reverse(array_diff(get_declared_classes(), $classes));
+ foreach ($newClasses as $name) {
+ if (isset(self::$loadedFiles[$name]) === false) {
+ $className = $name;
+ break;
+ }
+ }
+
+ if ($className === null) {
+ $newClasses = array_reverse(array_diff(get_declared_interfaces(), $interfaces));
+ foreach ($newClasses as $name) {
+ if (isset(self::$loadedFiles[$name]) === false) {
+ $className = $name;
+ break;
+ }
+ }
+ }
+
+ if ($className === null) {
+ $newClasses = array_reverse(array_diff(get_declared_traits(), $traits));
+ foreach ($newClasses as $name) {
+ if (isset(self::$loadedFiles[$name]) === false) {
+ $className = $name;
+ break;
+ }
+ }
+ }
+
+ self::$loadedClasses[$path] = $className;
+ self::$loadedFiles[$className] = $path;
+ return self::$loadedClasses[$path];
+
+ }//end loadFile()
+
+
+ /**
+ * Adds a directory to search during autoloading.
+ *
+ * @param string $path The path to the directory to search.
+ * @param string $nsPrefix The namespace prefix used by files under this path.
+ *
+ * @return void
+ */
+ public static function addSearchPath($path, $nsPrefix='')
+ {
+ self::$searchPaths[$path] = rtrim(trim((string) $nsPrefix), '\\');
+
+ }//end addSearchPath()
+
+
+ /**
+ * Retrieve the namespaces and paths registered by external standards.
+ *
+ * @return array
+ */
+ public static function getSearchPaths()
+ {
+ return self::$searchPaths;
+
+ }//end getSearchPaths()
+
+
+ /**
+ * Gets the class name for the given file path.
+ *
+ * @param string $path The name of the file.
+ *
+ * @throws \Exception If the file path has not been loaded.
+ * @return string
+ */
+ public static function getLoadedClassName($path)
+ {
+ if (isset(self::$loadedClasses[$path]) === false) {
+ throw new \Exception("Cannot get class name for $path; file has not been included");
+ }
+
+ return self::$loadedClasses[$path];
+
+ }//end getLoadedClassName()
+
+
+ /**
+ * Gets the file path for the given class name.
+ *
+ * @param string $class The name of the class.
+ *
+ * @throws \Exception If the class name has not been loaded
+ * @return string
+ */
+ public static function getLoadedFileName($class)
+ {
+ if (isset(self::$loadedFiles[$class]) === false) {
+ throw new \Exception("Cannot get file name for $class; class has not been included");
+ }
+
+ return self::$loadedFiles[$class];
+
+ }//end getLoadedFileName()
+
+
+ /**
+ * Gets the mapping of file names to class names.
+ *
+ * @return array
+ */
+ public static function getLoadedClasses()
+ {
+ return self::$loadedClasses;
+
+ }//end getLoadedClasses()
+
+
+ /**
+ * Gets the mapping of class names to file names.
+ *
+ * @return array
+ */
+ public static function getLoadedFiles()
+ {
+ return self::$loadedFiles;
+
+ }//end getLoadedFiles()
+
+
+ }//end class
+
+ // Register the autoloader before any existing autoloaders to ensure
+ // it gets a chance to hear about every autoload request, and record
+ // the file and class name for it.
+ spl_autoload_register(__NAMESPACE__.'\Autoload::load', true, true);
+}//end if
diff --git a/vendor/squizlabs/php_codesniffer/bin/phpcbf b/vendor/squizlabs/php_codesniffer/bin/phpcbf
new file mode 100755
index 0000000..45b43f4
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/bin/phpcbf
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+if (is_file(__DIR__.'/../autoload.php') === true) {
+ include_once __DIR__.'/../autoload.php';
+} else {
+ include_once 'PHP/CodeSniffer/autoload.php';
+}
+
+$runner = new PHP_CodeSniffer\Runner();
+$exitCode = $runner->runPHPCBF();
+exit($exitCode);
diff --git a/vendor/squizlabs/php_codesniffer/bin/phpcbf.bat b/vendor/squizlabs/php_codesniffer/bin/phpcbf.bat
new file mode 100644
index 0000000..5b07a7d
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/bin/phpcbf.bat
@@ -0,0 +1,12 @@
+@echo off
+REM PHP Code Beautifier and Fixer fixes violations of a defined coding standard.
+REM
+REM @author Greg Sherwood
+REM @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+REM @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+
+if "%PHP_PEAR_PHP_BIN%" neq "" (
+ set PHPBIN=%PHP_PEAR_PHP_BIN%
+) else set PHPBIN=php
+
+"%PHPBIN%" "%~dp0\phpcbf" %*
diff --git a/vendor/squizlabs/php_codesniffer/bin/phpcs b/vendor/squizlabs/php_codesniffer/bin/phpcs
new file mode 100755
index 0000000..52d28cd
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/bin/phpcs
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+if (is_file(__DIR__.'/../autoload.php') === true) {
+ include_once __DIR__.'/../autoload.php';
+} else {
+ include_once 'PHP/CodeSniffer/autoload.php';
+}
+
+$runner = new PHP_CodeSniffer\Runner();
+$exitCode = $runner->runPHPCS();
+exit($exitCode);
diff --git a/vendor/squizlabs/php_codesniffer/bin/phpcs.bat b/vendor/squizlabs/php_codesniffer/bin/phpcs.bat
new file mode 100755
index 0000000..9f9be72
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/bin/phpcs.bat
@@ -0,0 +1,12 @@
+@echo off
+REM PHP_CodeSniffer detects violations of a defined coding standard.
+REM
+REM @author Greg Sherwood
+REM @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+REM @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+
+if "%PHP_PEAR_PHP_BIN%" neq "" (
+ set PHPBIN=%PHP_PEAR_PHP_BIN%
+) else set PHPBIN=php
+
+"%PHPBIN%" "%~dp0\phpcs" %*
diff --git a/vendor/squizlabs/php_codesniffer/composer.json b/vendor/squizlabs/php_codesniffer/composer.json
new file mode 100644
index 0000000..7605a5d
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "squizlabs/php_codesniffer",
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "type": "library",
+ "keywords": [
+ "phpcs",
+ "standards"
+ ],
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "license": "BSD-3-Clause",
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
+ "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki",
+ "source": "https://github.com/squizlabs/PHP_CodeSniffer"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "ext-simplexml": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "bin": [
+ "bin/phpcs",
+ "bin/phpcbf"
+ ]
+}
diff --git a/vendor/squizlabs/php_codesniffer/licence.txt b/vendor/squizlabs/php_codesniffer/licence.txt
new file mode 100644
index 0000000..f95432c
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/licence.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2012, Squiz Pty Ltd (ABN 77 084 670 600)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Squiz Pty Ltd nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/squizlabs/php_codesniffer/phpcs.xml.dist b/vendor/squizlabs/php_codesniffer/phpcs.xml.dist
new file mode 100644
index 0000000..72aa59a
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/phpcs.xml.dist
@@ -0,0 +1,146 @@
+
+
+ The coding standard for PHP_CodeSniffer itself.
+
+ autoload.php
+ bin
+ scripts
+ src
+ tests
+
+ */src/Standards/*/Tests/*\.(inc|css|js)$
+ */tests/Core/*/*Test\.(inc|css|js)$
+
+
+
+
+
+
+
+
+ error
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ error
+
+
+
+
+ error
+
+
+
+
+ tests/bootstrap.php
+
+
+
diff --git a/vendor/squizlabs/php_codesniffer/phpcs.xsd b/vendor/squizlabs/php_codesniffer/phpcs.xsd
new file mode 100644
index 0000000..d958c4f
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/phpcs.xsd
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/squizlabs/php_codesniffer/phpstan.neon b/vendor/squizlabs/php_codesniffer/phpstan.neon
new file mode 100644
index 0000000..f9075bd
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/phpstan.neon
@@ -0,0 +1,13 @@
+parameters:
+ ignoreErrors:
+ -
+ message: '~^Undefined variable: \$phpCodeSnifferConfig$~'
+ path: %currentWorkingDirectory%/src/Config.php
+
+ dynamicConstantNames:
+ - PHP_CODESNIFFER_IN_TESTS
+ - PHP_CODESNIFFER_CBF
+ - PHP_CODESNIFFER_VERBOSITY
+
+ excludes_analyse:
+ - */Tests/*
diff --git a/vendor/squizlabs/php_codesniffer/scripts/ValidatePEAR/FileList.php b/vendor/squizlabs/php_codesniffer/scripts/ValidatePEAR/FileList.php
new file mode 100644
index 0000000..171873d
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/scripts/ValidatePEAR/FileList.php
@@ -0,0 +1,99 @@
+
+ * @copyright 2019 Juliette Reinders Folmer. All rights reserved.
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+/**
+ * Class to create a file list with filtering.
+ */
+class FileList
+{
+
+ /**
+ * The path to the project root directory.
+ *
+ * @var string
+ */
+ protected $rootPath;
+
+ /**
+ * Recursive directory iterator.
+ *
+ * @var \DirectoryIterator
+ */
+ protected $fileIterator;
+
+ /**
+ * Base regex to use if no filter regex is provided.
+ *
+ * Matches based on:
+ * - File path starts with the project root (replacement done in constructor).
+ * - Don't match .git/ files.
+ * - Don't match dot files, i.e. "." or "..".
+ * - Don't match backup files.
+ * - Match everything else in a case-insensitive manner.
+ *
+ * @var string
+ */
+ private $baseRegex = '`^%s(?!\.git/)(?!(.*/)?\.+$)(?!.*\.(bak|orig)).*$`Dix';
+
+
+ /**
+ * Constructor.
+ *
+ * @param string $directory The directory to examine.
+ * @param string $rootPath Path to the project root.
+ * @param string $filter PCRE regular expression to filter the file list with.
+ */
+ public function __construct($directory, $rootPath='', $filter='')
+ {
+ $this->rootPath = $rootPath;
+
+ $directory = new \RecursiveDirectoryIterator(
+ $directory,
+ \RecursiveDirectoryIterator::UNIX_PATHS
+ );
+ $flattened = new \RecursiveIteratorIterator(
+ $directory,
+ \RecursiveIteratorIterator::LEAVES_ONLY,
+ \RecursiveIteratorIterator::CATCH_GET_CHILD
+ );
+
+ if ($filter === '') {
+ $filter = sprintf($this->baseRegex, preg_quote($this->rootPath));
+ }
+
+ $this->fileIterator = new \RegexIterator($flattened, $filter);
+
+ return $this;
+
+ }//end __construct()
+
+
+ /**
+ * Retrieve the filtered file list as an array.
+ *
+ * @return array
+ */
+ public function getList()
+ {
+ $fileList = [];
+
+ foreach ($this->fileIterator as $file) {
+ $fileList[] = str_replace($this->rootPath, '', $file);
+ }
+
+ return $fileList;
+
+ }//end getList()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/scripts/ValidatePEAR/ValidatePEARPackageXML.php b/vendor/squizlabs/php_codesniffer/scripts/ValidatePEAR/ValidatePEARPackageXML.php
new file mode 100644
index 0000000..266e836
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/scripts/ValidatePEAR/ValidatePEARPackageXML.php
@@ -0,0 +1,360 @@
+
+ * @copyright 2019 Juliette Reinders Folmer. All rights reserved.
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+/**
+ * Validate the PHP_CodeSniffer PEAR package.xml file.
+ */
+class ValidatePEARPackageXML
+{
+
+ /**
+ * The root directory of the project.
+ *
+ * @var string
+ */
+ protected $projectRoot = '';
+
+ /**
+ * The contents of the package.xml file.
+ *
+ * @var \SimpleXMLElement
+ */
+ protected $packageXML;
+
+ /**
+ * List of all files in the repo.
+ *
+ * @var array
+ */
+ protected $allFiles = [];
+
+ /**
+ * Valid file roles.
+ *
+ * @var array
+ *
+ * @link https://pear.php.net/manual/en/developers.packagedef.intro.php#developers.packagedef.roles
+ */
+ private $validRoles = [
+ 'data' => true,
+ 'doc' => true,
+ 'ext' => true,
+ 'extsrc' => true,
+ 'php' => true,
+ 'script' => true,
+ 'src' => true,
+ 'test' => true,
+ ];
+
+ /**
+ * Files encountered in the package.xml tag.
+ *
+ * @var array
+ */
+ private $listedContents = [];
+
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ $this->projectRoot = dirname(dirname(__DIR__)).'/';
+ $this->packageXML = simplexml_load_file($this->projectRoot.'package.xml');
+
+ $allFiles = (new FileList($this->projectRoot, $this->projectRoot))->getList();
+ $this->allFiles = array_flip($allFiles);
+
+ }//end __construct()
+
+
+ /**
+ * Validate the file listings in the package.xml file.
+ *
+ * @return void
+ */
+ public function validate()
+ {
+ $exitCode = 0;
+ if ($this->checkContents() !== true) {
+ $exitCode = 1;
+ }
+
+ if ($this->checkPHPRelease() !== true) {
+ $exitCode = 1;
+ }
+
+ exit($exitCode);
+
+ }//end validate()
+
+
+ /**
+ * Validate the file listings in the tag.
+ *
+ * @return bool
+ */
+ protected function checkContents()
+ {
+ echo PHP_EOL.'Checking Contents tag'.PHP_EOL;
+ echo '====================='.PHP_EOL;
+
+ $valid = true;
+
+ /*
+ * - Check that every file that is mentioned in the `` tag exists in the repo.
+ * - Check that the "role" value is valid.
+ * - Check that the "baseinstalldir" value is valid.
+ */
+
+ $valid = $this->walkDirTag($this->packageXML->contents);
+ if ($valid === true) {
+ echo "Existing listings in the Contents tag are valid.".PHP_EOL;
+ }
+
+ /*
+ * Verify that all files in the `src` and the `tests` directories are listed in the `` tag.
+ */
+
+ $srcFiles = (new FileList(
+ $this->projectRoot.'src/',
+ $this->projectRoot,
+ '`\.(css|fixed|inc|js|php|xml)$`Di'
+ ))->getList();
+ $testsFiles = (new FileList(
+ $this->projectRoot.'tests/',
+ $this->projectRoot,
+ '`\.(css|inc|js|php|xml)$`Di'
+ ))->getList();
+ $files = array_merge($srcFiles, $testsFiles);
+
+ foreach ($files as $file) {
+ if (isset($this->listedContents[$file]) === true) {
+ continue;
+ }
+
+ echo "- File '{$file}' is missing from Contents tag.".PHP_EOL;
+ $valid = false;
+ }
+
+ if ($valid === true) {
+ echo "No missing files in the Contents tag.".PHP_EOL;
+ }
+
+ return $valid;
+
+ }//end checkContents()
+
+
+ /**
+ * Validate all child tags within a tag.
+ *
+ * @param \SimpleXMLElement $tag The current XML tag to examine.
+ * @param string $currentDirectory The complete relative path to the
+ * directory being examined.
+ *
+ * @return bool
+ */
+ protected function walkDirTag($tag, $currentDirectory='')
+ {
+ $valid = true;
+ $name = (string) $tag['name'];
+ if ($name !== '/' && empty($name) === false) {
+ $currentDirectory .= $name.'/';
+ }
+
+ $children = $tag->children();
+ foreach ($children as $key => $value) {
+ if ($key === 'dir') {
+ if ($this->walkDirTag($value, $currentDirectory) === false) {
+ $valid = false;
+ }
+ }
+
+ if ($key === 'file') {
+ if ($this->checkFileTag($value, $currentDirectory) === false) {
+ $valid = false;
+ }
+ }
+ }
+
+ return $valid;
+
+ }//end walkDirTag()
+
+
+ /**
+ * Validate the information within a tag.
+ *
+ * @param \SimpleXMLElement $tag The current XML tag to examine.
+ * @param string $currentDirectory The complete relative path to the
+ * directory being examined.
+ *
+ * @return bool
+ */
+ protected function checkFileTag($tag, $currentDirectory='')
+ {
+ $valid = true;
+ $attributes = $tag->attributes();
+ $baseinstalldir = (string) $attributes['baseinstalldir'];
+ $name = $currentDirectory.(string) $attributes['name'];
+ $role = (string) $attributes['role'];
+
+ $this->listedContents[$name] = true;
+
+ if (empty($name) === true) {
+ echo "- Name attribute missing.".PHP_EOL;
+ $valid = false;
+ } else {
+ if (isset($this->allFiles[$name]) === false) {
+ echo "- File '{$name}' does not exist.".PHP_EOL;
+ $valid = false;
+ }
+
+ if (empty($role) === true) {
+ echo "- Role attribute missing for file '{$name}'.".PHP_EOL;
+ $valid = false;
+ } else {
+ if (isset($this->validRoles[$role]) === false) {
+ echo "- Role for file '{$name}' is invalid.".PHP_EOL;
+ $valid = false;
+ } else {
+ // Limited validation of the "role" tags.
+ if (strpos($name, 'Test.') !== false && $role !== 'test') {
+ echo "- Test files should have the role 'test'. Found: '$role' for file '{$name}'.".PHP_EOL;
+ $valid = false;
+ } else if ((strpos($name, 'Standard.xml') !== false || strpos($name, 'Sniff.php') !== false)
+ && $role !== 'php'
+ ) {
+ echo "- Sniff files, including sniff documentation files should have the role 'php'. Found: '$role' for file '{$name}'.".PHP_EOL;
+ $valid = false;
+ }
+ }
+
+ if (empty($baseinstalldir) === true) {
+ if ($role !== 'script' && strpos($name, 'tests/') !== 0) {
+ echo "- Baseinstalldir attribute missing for file '{$name}'.".PHP_EOL;
+ $valid = false;
+ }
+ } else {
+ if ($role === 'script' || strpos($name, 'tests/') === 0) {
+ echo "- Baseinstalldir for file '{$name}' should be empty.".PHP_EOL;
+ $valid = false;
+ }
+
+ if ($role !== 'script' && $baseinstalldir !== 'PHP/CodeSniffer') {
+ echo "- Baseinstalldir for file '{$name}' is invalid.".PHP_EOL;
+ $valid = false;
+ }
+ }
+ }//end if
+ }//end if
+
+ return $valid;
+
+ }//end checkFileTag()
+
+
+ /**
+ * Validate the file listings in the tags.
+ *
+ * @return bool True if the info in the "phprelease" tags is valid. False otherwise.
+ */
+ protected function checkPHPRelease()
+ {
+ echo PHP_EOL.'Checking PHPRelease tags'.PHP_EOL;
+ echo '========================'.PHP_EOL;
+
+ $valid = true;
+ $listedFiles = [];
+ $releaseTags = 1;
+
+ /*
+ * - Check that every file that is mentioned in the `` tags exists in the repo.
+ * - Check that the "as" value is valid.
+ */
+
+ foreach ($this->packageXML->phprelease as $release) {
+ foreach ($release->filelist->install as $install) {
+ $attributes = $install->attributes();
+ $name = (string) $attributes['name'];
+ $as = (string) $attributes['as'];
+
+ $listedFiles[$releaseTags][$name] = $as;
+
+ if (empty($as) === true || empty($name) === true) {
+ continue;
+ }
+
+ if (isset($this->allFiles[$name]) === false) {
+ echo "- File '{$name}' does not exist.".PHP_EOL;
+ $valid = false;
+ }
+
+ // Rest of the checks only apply to the test files.
+ if (strpos($name, 'tests/') !== 0) {
+ continue;
+ }
+
+ // Check validity of the tags for files in the tests root directory.
+ if (preg_match('`^tests/([^/]+\.php)$`', $name, $matches) === 1
+ && ($as === $name || $as === $matches[1])
+ ) {
+ continue;
+ }
+
+ // Check validity of the tags for files in the tests root subdirectories.
+ if (preg_match('`^tests/.+\.(php|inc|js|css|xml)$`', $name) === 1
+ && $as === str_replace('tests/', 'CodeSniffer/', $name)
+ ) {
+ continue;
+ }
+
+ echo "- Invalid 'as' attribute '{$as}' for test file '{$name}'.".PHP_EOL;
+ $valid = false;
+ }//end foreach
+
+ ++$releaseTags;
+ }//end foreach
+
+ if ($valid === true) {
+ echo "Existing PHPRelease tags are valid.".PHP_EOL;
+ }
+
+ /*
+ * Verify that all files in the `tests` directory are listed in both `` tags.
+ */
+
+ $testFiles = (new FileList($this->projectRoot.'tests/', $this->projectRoot, '`\.(inc|php|js|css|xml)$`Di'))->getList();
+
+ foreach ($testFiles as $file) {
+ foreach ($listedFiles as $key => $listed) {
+ if (isset($listed[$file]) === true) {
+ continue;
+ }
+
+ echo "- File '{$file}' is missing from PHPRelease tag [{$key}] .".PHP_EOL;
+ $valid = false;
+ }
+ }
+
+ if ($valid === true) {
+ echo "No missing PHPRelease tags.".PHP_EOL;
+ }
+
+ return $valid;
+
+ }//end checkPHPRelease()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/scripts/build-phar.php b/vendor/squizlabs/php_codesniffer/scripts/build-phar.php
new file mode 100644
index 0000000..6b2800c
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/scripts/build-phar.php
@@ -0,0 +1,96 @@
+#!/usr/bin/env php
+
+ * @author Greg Sherwood
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ * @link http://pear.php.net/package/PHP_CodeSniffer
+ */
+
+error_reporting(E_ALL | E_STRICT);
+
+if (ini_get('phar.readonly') === '1') {
+ echo 'Unable to build, phar.readonly in php.ini is set to read only.'.PHP_EOL;
+ exit(1);
+}
+
+$scripts = [
+ 'phpcs',
+ 'phpcbf',
+];
+
+foreach ($scripts as $script) {
+ echo "Building $script phar".PHP_EOL;
+
+ $pharName = $script.'.phar';
+ $pharFile = getcwd().'/'.$pharName;
+ echo "\t=> $pharFile".PHP_EOL;
+ if (file_exists($pharFile) === true) {
+ echo "\t** file exists, removing **".PHP_EOL;
+ unlink($pharFile);
+ }
+
+ $phar = new Phar($pharFile, 0, $pharName);
+
+ /*
+ Add the files.
+ */
+
+ echo "\t=> adding files... ";
+
+ $srcDir = realpath(__DIR__.'/../src');
+ $srcDirLen = strlen($srcDir);
+
+ $rdi = new \RecursiveDirectoryIterator($srcDir, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
+ $di = new \RecursiveIteratorIterator($rdi, 0, \RecursiveIteratorIterator::CATCH_GET_CHILD);
+
+ foreach ($di as $file) {
+ $filename = $file->getFilename();
+
+ // Skip hidden files.
+ if (substr($filename, 0, 1) === '.') {
+ continue;
+ }
+
+ $fullpath = $file->getPathname();
+ if (strpos($fullpath, '/Tests/') !== false) {
+ continue;
+ }
+
+ $path = 'src'.substr($fullpath, $srcDirLen);
+
+ $phar->addFromString($path, php_strip_whitespace($fullpath));
+ }
+
+ // Add autoloader.
+ $phar->addFromString('autoload.php', php_strip_whitespace(realpath(__DIR__.'/../autoload.php')));
+
+ // Add licence file.
+ $phar->addFromString('licence.txt', php_strip_whitespace(realpath(__DIR__.'/../licence.txt')));
+
+ echo 'done'.PHP_EOL;
+
+ /*
+ Add the stub.
+ */
+
+ echo "\t=> adding stub... ";
+ $stub = '#!/usr/bin/env php'."\n";
+ $stub .= 'run'.$script.'();'."\n";
+ $stub .= 'exit($exitCode);'."\n";
+ $stub .= '__HALT_COMPILER();';
+ $phar->setStub($stub);
+
+ echo 'done'.PHP_EOL;
+}//end foreach
diff --git a/vendor/squizlabs/php_codesniffer/scripts/validate-pear-package.php b/vendor/squizlabs/php_codesniffer/scripts/validate-pear-package.php
new file mode 100644
index 0000000..f40a2b5
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/scripts/validate-pear-package.php
@@ -0,0 +1,19 @@
+#!/usr/bin/env php
+
+ * @copyright 2019 Juliette Reinders Folmer. All rights reserved.
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+require_once __DIR__.'/ValidatePEAR/FileList.php';
+require_once __DIR__.'/ValidatePEAR/ValidatePEARPackageXML.php';
+
+$validate = new ValidatePEARPackageXML();
+$validate->validate();
diff --git a/vendor/squizlabs/php_codesniffer/src/Config.php b/vendor/squizlabs/php_codesniffer/src/Config.php
new file mode 100644
index 0000000..cba3f67
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Config.php
@@ -0,0 +1,1714 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer;
+
+use PHP_CodeSniffer\Exceptions\RuntimeException;
+use PHP_CodeSniffer\Exceptions\DeepExitException;
+
+class Config
+{
+
+ /**
+ * The current version.
+ *
+ * @var string
+ */
+ const VERSION = '3.4.2';
+
+ /**
+ * Package stability; either stable, beta or alpha.
+ *
+ * @var string
+ */
+ const STABILITY = 'stable';
+
+ /**
+ * An array of settings that PHPCS and PHPCBF accept.
+ *
+ * This array is not meant to be accessed directly. Instead, use the settings
+ * as if they are class member vars so the __get() and __set() magic methods
+ * can be used to validate the values. For example, to set the verbosity level to
+ * level 2, use $this->verbosity = 2; instead of accessing this property directly.
+ *
+ * The list of settings are:
+ *
+ * string[] files The files and directories to check.
+ * string[] standards The standards being used for checking.
+ * int verbosity How verbose the output should be.
+ * 0: no unnecessary output
+ * 1: basic output for files being checked
+ * 2: ruleset and file parsing output
+ * 3: sniff execution output
+ * bool interactive Enable interactive checking mode.
+ * bool parallel Check files in parallel.
+ * bool cache Enable the use of the file cache.
+ * bool cacheFile A file where the cache data should be written
+ * bool colors Display colours in output.
+ * bool explain Explain the coding standards.
+ * bool local Process local files in directories only (no recursion).
+ * bool showSources Show sniff source codes in report output.
+ * bool showProgress Show basic progress information while running.
+ * bool quiet Quiet mode; disables progress and verbose output.
+ * bool annotations Process phpcs: annotations.
+ * int tabWidth How many spaces each tab is worth.
+ * string encoding The encoding of the files being checked.
+ * string[] sniffs The sniffs that should be used for checking.
+ * If empty, all sniffs in the supplied standards will be used.
+ * string[] exclude The sniffs that should be excluded from checking.
+ * If empty, all sniffs in the supplied standards will be used.
+ * string[] ignored Regular expressions used to ignore files and folders during checking.
+ * string reportFile A file where the report output should be written.
+ * string generator The documentation generator to use.
+ * string filter The filter to use for the run.
+ * string[] bootstrap One of more files to include before the run begins.
+ * int reportWidth The maximum number of columns that reports should use for output.
+ * Set to "auto" for have this value changed to the width of the terminal.
+ * int errorSeverity The minimum severity an error must have to be displayed.
+ * int warningSeverity The minimum severity a warning must have to be displayed.
+ * bool recordErrors Record the content of error messages as well as error counts.
+ * string suffix A suffix to add to fixed files.
+ * string basepath A file system location to strip from the paths of files shown in reports.
+ * bool stdin Read content from STDIN instead of supplied files.
+ * string stdinContent Content passed directly to PHPCS on STDIN.
+ * string stdinPath The path to use for content passed on STDIN.
+ *
+ * array extensions File extensions that should be checked, and what tokenizer to use.
+ * E.g., array('inc' => 'PHP');
+ * array reports The reports to use for printing output after the run.
+ * The format of the array is:
+ * array(
+ * 'reportName1' => 'outputFile',
+ * 'reportName2' => null,
+ * );
+ * If the array value is NULL, the report will be written to the screen.
+ *
+ * string[] unknown Any arguments gathered on the command line that are unknown to us.
+ * E.g., using `phpcs -c` will give array('c');
+ *
+ * @var array
+ */
+ private $settings = [
+ 'files' => null,
+ 'standards' => null,
+ 'verbosity' => null,
+ 'interactive' => null,
+ 'parallel' => null,
+ 'cache' => null,
+ 'cacheFile' => null,
+ 'colors' => null,
+ 'explain' => null,
+ 'local' => null,
+ 'showSources' => null,
+ 'showProgress' => null,
+ 'quiet' => null,
+ 'annotations' => null,
+ 'tabWidth' => null,
+ 'encoding' => null,
+ 'extensions' => null,
+ 'sniffs' => null,
+ 'exclude' => null,
+ 'ignored' => null,
+ 'reportFile' => null,
+ 'generator' => null,
+ 'filter' => null,
+ 'bootstrap' => null,
+ 'reports' => null,
+ 'basepath' => null,
+ 'reportWidth' => null,
+ 'errorSeverity' => null,
+ 'warningSeverity' => null,
+ 'recordErrors' => null,
+ 'suffix' => null,
+ 'stdin' => null,
+ 'stdinContent' => null,
+ 'stdinPath' => null,
+ 'unknown' => null,
+ ];
+
+ /**
+ * Whether or not to kill the process when an unknown command line arg is found.
+ *
+ * If FALSE, arguments that are not command line options or file/directory paths
+ * will be ignored and execution will continue. These values will be stored in
+ * $this->unknown.
+ *
+ * @var boolean
+ */
+ public $dieOnUnknownArg;
+
+ /**
+ * The current command line arguments we are processing.
+ *
+ * @var string[]
+ */
+ private $cliArgs = [];
+
+ /**
+ * Command line values that the user has supplied directly.
+ *
+ * @var array
+ */
+ private static $overriddenDefaults = [];
+
+ /**
+ * Config file data that has been loaded for the run.
+ *
+ * @var array
+ */
+ private static $configData = null;
+
+ /**
+ * The full path to the config data file that has been loaded.
+ *
+ * @var string
+ */
+ private static $configDataFile = null;
+
+ /**
+ * Automatically discovered executable utility paths.
+ *
+ * @var array
+ */
+ private static $executablePaths = [];
+
+
+ /**
+ * Get the value of an inaccessible property.
+ *
+ * @param string $name The name of the property.
+ *
+ * @return mixed
+ * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the setting name is invalid.
+ */
+ public function __get($name)
+ {
+ if (array_key_exists($name, $this->settings) === false) {
+ throw new RuntimeException("ERROR: unable to get value of property \"$name\"");
+ }
+
+ return $this->settings[$name];
+
+ }//end __get()
+
+
+ /**
+ * Set the value of an inaccessible property.
+ *
+ * @param string $name The name of the property.
+ * @param mixed $value The value of the property.
+ *
+ * @return void
+ * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the setting name is invalid.
+ */
+ public function __set($name, $value)
+ {
+ if (array_key_exists($name, $this->settings) === false) {
+ throw new RuntimeException("Can't __set() $name; setting doesn't exist");
+ }
+
+ switch ($name) {
+ case 'reportWidth' :
+ // Support auto terminal width.
+ if ($value === 'auto' && preg_match('|\d+ (\d+)|', shell_exec('stty size 2>&1'), $matches) === 1) {
+ $value = (int) $matches[1];
+ } else {
+ $value = (int) $value;
+ }
+ break;
+ case 'standards' :
+ $cleaned = [];
+
+ // Check if the standard name is valid, or if the case is invalid.
+ $installedStandards = Util\Standards::getInstalledStandards();
+ foreach ($value as $standard) {
+ foreach ($installedStandards as $validStandard) {
+ if (strtolower($standard) === strtolower($validStandard)) {
+ $standard = $validStandard;
+ break;
+ }
+ }
+
+ $cleaned[] = $standard;
+ }
+
+ $value = $cleaned;
+ break;
+ default :
+ // No validation required.
+ break;
+ }//end switch
+
+ $this->settings[$name] = $value;
+
+ }//end __set()
+
+
+ /**
+ * Check if the value of an inaccessible property is set.
+ *
+ * @param string $name The name of the property.
+ *
+ * @return bool
+ */
+ public function __isset($name)
+ {
+ return isset($this->settings[$name]);
+
+ }//end __isset()
+
+
+ /**
+ * Unset the value of an inaccessible property.
+ *
+ * @param string $name The name of the property.
+ *
+ * @return void
+ */
+ public function __unset($name)
+ {
+ $this->settings[$name] = null;
+
+ }//end __unset()
+
+
+ /**
+ * Get the array of all config settings.
+ *
+ * @return array
+ */
+ public function getSettings()
+ {
+ return $this->settings;
+
+ }//end getSettings()
+
+
+ /**
+ * Set the array of all config settings.
+ *
+ * @param array $settings The array of config settings.
+ *
+ * @return void
+ */
+ public function setSettings($settings)
+ {
+ return $this->settings = $settings;
+
+ }//end setSettings()
+
+
+ /**
+ * Creates a Config object and populates it with command line values.
+ *
+ * @param array $cliArgs An array of values gathered from CLI args.
+ * @param bool $dieOnUnknownArg Whether or not to kill the process when an
+ * unknown command line arg is found.
+ *
+ * @return void
+ */
+ public function __construct(array $cliArgs=[], $dieOnUnknownArg=true)
+ {
+ if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
+ // Let everything through during testing so that we can
+ // make use of PHPUnit command line arguments as well.
+ $this->dieOnUnknownArg = false;
+ } else {
+ $this->dieOnUnknownArg = $dieOnUnknownArg;
+ }
+
+ if (empty($cliArgs) === true) {
+ $cliArgs = $_SERVER['argv'];
+ array_shift($cliArgs);
+ }
+
+ $this->restoreDefaults();
+ $this->setCommandLineValues($cliArgs);
+
+ if (isset(self::$overriddenDefaults['standards']) === false) {
+ // They did not supply a standard to use.
+ // Look for a default ruleset in the current directory or higher.
+ $currentDir = getcwd();
+
+ $defaultFiles = [
+ '.phpcs.xml',
+ 'phpcs.xml',
+ '.phpcs.xml.dist',
+ 'phpcs.xml.dist',
+ ];
+
+ do {
+ foreach ($defaultFiles as $defaultFilename) {
+ $default = $currentDir.DIRECTORY_SEPARATOR.$defaultFilename;
+ if (is_file($default) === true) {
+ $this->standards = [$default];
+ break(2);
+ }
+ }
+
+ $lastDir = $currentDir;
+ $currentDir = dirname($currentDir);
+ } while ($currentDir !== '.' && $currentDir !== $lastDir);
+ }//end if
+
+ if (defined('STDIN') === false
+ || strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'
+ ) {
+ return;
+ }
+
+ $handle = fopen('php://stdin', 'r');
+
+ // Check for content on STDIN.
+ if ($this->stdin === true
+ || (Util\Common::isStdinATTY() === false
+ && feof($handle) === false)
+ ) {
+ $readStreams = [$handle];
+ $writeSteams = null;
+
+ $fileContents = '';
+ while (is_resource($handle) === true && feof($handle) === false) {
+ // Set a timeout of 200ms.
+ if (stream_select($readStreams, $writeSteams, $writeSteams, 0, 200000) === 0) {
+ break;
+ }
+
+ $fileContents .= fgets($handle);
+ }
+
+ if (trim($fileContents) !== '') {
+ $this->stdin = true;
+ $this->stdinContent = $fileContents;
+ self::$overriddenDefaults['stdin'] = true;
+ self::$overriddenDefaults['stdinContent'] = true;
+ }
+ }//end if
+
+ fclose($handle);
+
+ }//end __construct()
+
+
+ /**
+ * Set the command line values.
+ *
+ * @param array $args An array of command line arguments to set.
+ *
+ * @return void
+ */
+ public function setCommandLineValues($args)
+ {
+ $this->cliArgs = $args;
+ $numArgs = count($args);
+
+ for ($i = 0; $i < $numArgs; $i++) {
+ $arg = $this->cliArgs[$i];
+ if ($arg === '') {
+ continue;
+ }
+
+ if ($arg{0} === '-') {
+ if ($arg === '-') {
+ // Asking to read from STDIN.
+ $this->stdin = true;
+ self::$overriddenDefaults['stdin'] = true;
+ continue;
+ }
+
+ if ($arg === '--') {
+ // Empty argument, ignore it.
+ continue;
+ }
+
+ if ($arg{1} === '-') {
+ $this->processLongArgument(substr($arg, 2), $i);
+ } else {
+ $switches = str_split($arg);
+ foreach ($switches as $switch) {
+ if ($switch === '-') {
+ continue;
+ }
+
+ $this->processShortArgument($switch, $i);
+ }
+ }
+ } else {
+ $this->processUnknownArgument($arg, $i);
+ }//end if
+ }//end for
+
+ }//end setCommandLineValues()
+
+
+ /**
+ * Restore default values for all possible command line arguments.
+ *
+ * @return array
+ */
+ public function restoreDefaults()
+ {
+ $this->files = [];
+ $this->standards = ['PEAR'];
+ $this->verbosity = 0;
+ $this->interactive = false;
+ $this->cache = false;
+ $this->cacheFile = null;
+ $this->colors = false;
+ $this->explain = false;
+ $this->local = false;
+ $this->showSources = false;
+ $this->showProgress = false;
+ $this->quiet = false;
+ $this->annotations = true;
+ $this->parallel = 1;
+ $this->tabWidth = 0;
+ $this->encoding = 'utf-8';
+ $this->extensions = [
+ 'php' => 'PHP',
+ 'inc' => 'PHP',
+ 'js' => 'JS',
+ 'css' => 'CSS',
+ ];
+ $this->sniffs = [];
+ $this->exclude = [];
+ $this->ignored = [];
+ $this->reportFile = null;
+ $this->generator = null;
+ $this->filter = null;
+ $this->bootstrap = [];
+ $this->basepath = null;
+ $this->reports = ['full' => null];
+ $this->reportWidth = 'auto';
+ $this->errorSeverity = 5;
+ $this->warningSeverity = 5;
+ $this->recordErrors = true;
+ $this->suffix = '';
+ $this->stdin = false;
+ $this->stdinContent = null;
+ $this->stdinPath = null;
+ $this->unknown = [];
+
+ $standard = self::getConfigData('default_standard');
+ if ($standard !== null) {
+ $this->standards = explode(',', $standard);
+ }
+
+ $reportFormat = self::getConfigData('report_format');
+ if ($reportFormat !== null) {
+ $this->reports = [$reportFormat => null];
+ }
+
+ $tabWidth = self::getConfigData('tab_width');
+ if ($tabWidth !== null) {
+ $this->tabWidth = (int) $tabWidth;
+ }
+
+ $encoding = self::getConfigData('encoding');
+ if ($encoding !== null) {
+ $this->encoding = strtolower($encoding);
+ }
+
+ $severity = self::getConfigData('severity');
+ if ($severity !== null) {
+ $this->errorSeverity = (int) $severity;
+ $this->warningSeverity = (int) $severity;
+ }
+
+ $severity = self::getConfigData('error_severity');
+ if ($severity !== null) {
+ $this->errorSeverity = (int) $severity;
+ }
+
+ $severity = self::getConfigData('warning_severity');
+ if ($severity !== null) {
+ $this->warningSeverity = (int) $severity;
+ }
+
+ $showWarnings = self::getConfigData('show_warnings');
+ if ($showWarnings !== null) {
+ $showWarnings = (bool) $showWarnings;
+ if ($showWarnings === false) {
+ $this->warningSeverity = 0;
+ }
+ }
+
+ $reportWidth = self::getConfigData('report_width');
+ if ($reportWidth !== null) {
+ $this->reportWidth = $reportWidth;
+ }
+
+ $showProgress = self::getConfigData('show_progress');
+ if ($showProgress !== null) {
+ $this->showProgress = (bool) $showProgress;
+ }
+
+ $quiet = self::getConfigData('quiet');
+ if ($quiet !== null) {
+ $this->quiet = (bool) $quiet;
+ }
+
+ $colors = self::getConfigData('colors');
+ if ($colors !== null) {
+ $this->colors = (bool) $colors;
+ }
+
+ if (defined('PHP_CODESNIFFER_IN_TESTS') === false) {
+ $cache = self::getConfigData('cache');
+ if ($cache !== null) {
+ $this->cache = (bool) $cache;
+ }
+
+ $parallel = self::getConfigData('parallel');
+ if ($parallel !== null) {
+ $this->parallel = max((int) $parallel, 1);
+ }
+ }
+
+ }//end restoreDefaults()
+
+
+ /**
+ * Processes a short (-e) command line argument.
+ *
+ * @param string $arg The command line argument.
+ * @param int $pos The position of the argument on the command line.
+ *
+ * @return void
+ */
+ public function processShortArgument($arg, $pos)
+ {
+ switch ($arg) {
+ case 'h':
+ case '?':
+ ob_start();
+ $this->printUsage();
+ $output = ob_get_contents();
+ ob_end_clean();
+ throw new DeepExitException($output, 0);
+ case 'i' :
+ ob_start();
+ Util\Standards::printInstalledStandards();
+ $output = ob_get_contents();
+ ob_end_clean();
+ throw new DeepExitException($output, 0);
+ case 'v' :
+ if ($this->quiet === true) {
+ // Ignore when quiet mode is enabled.
+ break;
+ }
+
+ $this->verbosity++;
+ self::$overriddenDefaults['verbosity'] = true;
+ break;
+ case 'l' :
+ $this->local = true;
+ self::$overriddenDefaults['local'] = true;
+ break;
+ case 's' :
+ $this->showSources = true;
+ self::$overriddenDefaults['showSources'] = true;
+ break;
+ case 'a' :
+ $this->interactive = true;
+ self::$overriddenDefaults['interactive'] = true;
+ break;
+ case 'e':
+ $this->explain = true;
+ self::$overriddenDefaults['explain'] = true;
+ break;
+ case 'p' :
+ if ($this->quiet === true) {
+ // Ignore when quiet mode is enabled.
+ break;
+ }
+
+ $this->showProgress = true;
+ self::$overriddenDefaults['showProgress'] = true;
+ break;
+ case 'q' :
+ // Quiet mode disables a few other settings as well.
+ $this->quiet = true;
+ $this->showProgress = false;
+ $this->verbosity = 0;
+
+ self::$overriddenDefaults['quiet'] = true;
+ break;
+ case 'm' :
+ $this->recordErrors = false;
+ self::$overriddenDefaults['recordErrors'] = true;
+ break;
+ case 'd' :
+ $ini = explode('=', $this->cliArgs[($pos + 1)]);
+ $this->cliArgs[($pos + 1)] = '';
+ if (isset($ini[1]) === true) {
+ ini_set($ini[0], $ini[1]);
+ } else {
+ ini_set($ini[0], true);
+ }
+ break;
+ case 'n' :
+ if (isset(self::$overriddenDefaults['warningSeverity']) === false) {
+ $this->warningSeverity = 0;
+ self::$overriddenDefaults['warningSeverity'] = true;
+ }
+ break;
+ case 'w' :
+ if (isset(self::$overriddenDefaults['warningSeverity']) === false) {
+ $this->warningSeverity = $this->errorSeverity;
+ self::$overriddenDefaults['warningSeverity'] = true;
+ }
+ break;
+ default:
+ if ($this->dieOnUnknownArg === false) {
+ $unknown = $this->unknown;
+ $unknown[] = $arg;
+ $this->unknown = $unknown;
+ } else {
+ $this->processUnknownArgument('-'.$arg, $pos);
+ }
+ }//end switch
+
+ }//end processShortArgument()
+
+
+ /**
+ * Processes a long (--example) command line argument.
+ *
+ * @param string $arg The command line argument.
+ * @param int $pos The position of the argument on the command line.
+ *
+ * @return void
+ */
+ public function processLongArgument($arg, $pos)
+ {
+ switch ($arg) {
+ case 'help':
+ ob_start();
+ $this->printUsage();
+ $output = ob_get_contents();
+ ob_end_clean();
+ throw new DeepExitException($output, 0);
+ case 'version':
+ $output = 'PHP_CodeSniffer version '.self::VERSION.' ('.self::STABILITY.') ';
+ $output .= 'by Squiz (http://www.squiz.net)'.PHP_EOL;
+ throw new DeepExitException($output, 0);
+ case 'colors':
+ if (isset(self::$overriddenDefaults['colors']) === true) {
+ break;
+ }
+
+ $this->colors = true;
+ self::$overriddenDefaults['colors'] = true;
+ break;
+ case 'no-colors':
+ if (isset(self::$overriddenDefaults['colors']) === true) {
+ break;
+ }
+
+ $this->colors = false;
+ self::$overriddenDefaults['colors'] = true;
+ break;
+ case 'cache':
+ if (isset(self::$overriddenDefaults['cache']) === true) {
+ break;
+ }
+
+ if (defined('PHP_CODESNIFFER_IN_TESTS') === false) {
+ $this->cache = true;
+ self::$overriddenDefaults['cache'] = true;
+ }
+ break;
+ case 'no-cache':
+ if (isset(self::$overriddenDefaults['cache']) === true) {
+ break;
+ }
+
+ $this->cache = false;
+ self::$overriddenDefaults['cache'] = true;
+ break;
+ case 'ignore-annotations':
+ if (isset(self::$overriddenDefaults['annotations']) === true) {
+ break;
+ }
+
+ $this->annotations = false;
+ self::$overriddenDefaults['annotations'] = true;
+ break;
+ case 'config-set':
+ if (isset($this->cliArgs[($pos + 1)]) === false
+ || isset($this->cliArgs[($pos + 2)]) === false
+ ) {
+ $error = 'ERROR: Setting a config option requires a name and value'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ $key = $this->cliArgs[($pos + 1)];
+ $value = $this->cliArgs[($pos + 2)];
+ $current = self::getConfigData($key);
+
+ try {
+ $this->setConfigData($key, $value);
+ } catch (\Exception $e) {
+ throw new DeepExitException($e->getMessage().PHP_EOL, 3);
+ }
+
+ $output = 'Using config file: '.self::$configDataFile.PHP_EOL.PHP_EOL;
+
+ if ($current === null) {
+ $output .= "Config value \"$key\" added successfully".PHP_EOL;
+ } else {
+ $output .= "Config value \"$key\" updated successfully; old value was \"$current\"".PHP_EOL;
+ }
+ throw new DeepExitException($output, 0);
+ case 'config-delete':
+ if (isset($this->cliArgs[($pos + 1)]) === false) {
+ $error = 'ERROR: Deleting a config option requires the name of the option'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ $output = 'Using config file: '.self::$configDataFile.PHP_EOL.PHP_EOL;
+
+ $key = $this->cliArgs[($pos + 1)];
+ $current = self::getConfigData($key);
+ if ($current === null) {
+ $output .= "Config value \"$key\" has not been set".PHP_EOL;
+ } else {
+ try {
+ $this->setConfigData($key, null);
+ } catch (\Exception $e) {
+ throw new DeepExitException($e->getMessage().PHP_EOL, 3);
+ }
+
+ $output .= "Config value \"$key\" removed successfully; old value was \"$current\"".PHP_EOL;
+ }
+ throw new DeepExitException($output, 0);
+ case 'config-show':
+ ob_start();
+ $data = self::getAllConfigData();
+ echo 'Using config file: '.self::$configDataFile.PHP_EOL.PHP_EOL;
+ $this->printConfigData($data);
+ $output = ob_get_contents();
+ ob_end_clean();
+ throw new DeepExitException($output, 0);
+ case 'runtime-set':
+ if (isset($this->cliArgs[($pos + 1)]) === false
+ || isset($this->cliArgs[($pos + 2)]) === false
+ ) {
+ $error = 'ERROR: Setting a runtime config option requires a name and value'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ $key = $this->cliArgs[($pos + 1)];
+ $value = $this->cliArgs[($pos + 2)];
+ $this->cliArgs[($pos + 1)] = '';
+ $this->cliArgs[($pos + 2)] = '';
+ self::setConfigData($key, $value, true);
+ if (isset(self::$overriddenDefaults['runtime-set']) === false) {
+ self::$overriddenDefaults['runtime-set'] = [];
+ }
+
+ self::$overriddenDefaults['runtime-set'][$key] = true;
+ break;
+ default:
+ if (substr($arg, 0, 7) === 'sniffs=') {
+ if (isset(self::$overriddenDefaults['sniffs']) === true) {
+ break;
+ }
+
+ $sniffs = explode(',', substr($arg, 7));
+ foreach ($sniffs as $sniff) {
+ if (substr_count($sniff, '.') !== 2) {
+ $error = 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+ }
+
+ $this->sniffs = $sniffs;
+ self::$overriddenDefaults['sniffs'] = true;
+ } else if (substr($arg, 0, 8) === 'exclude=') {
+ if (isset(self::$overriddenDefaults['exclude']) === true) {
+ break;
+ }
+
+ $sniffs = explode(',', substr($arg, 8));
+ foreach ($sniffs as $sniff) {
+ if (substr_count($sniff, '.') !== 2) {
+ $error = 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+ }
+
+ $this->exclude = $sniffs;
+ self::$overriddenDefaults['exclude'] = true;
+ } else if (defined('PHP_CODESNIFFER_IN_TESTS') === false
+ && substr($arg, 0, 6) === 'cache='
+ ) {
+ if ((isset(self::$overriddenDefaults['cache']) === true
+ && $this->cache === false)
+ || isset(self::$overriddenDefaults['cacheFile']) === true
+ ) {
+ break;
+ }
+
+ // Turn caching on.
+ $this->cache = true;
+ self::$overriddenDefaults['cache'] = true;
+
+ $this->cacheFile = Util\Common::realpath(substr($arg, 6));
+
+ // It may not exist and return false instead.
+ if ($this->cacheFile === false) {
+ $this->cacheFile = substr($arg, 6);
+
+ $dir = dirname($this->cacheFile);
+ if (is_dir($dir) === false) {
+ $error = 'ERROR: The specified cache file path "'.$this->cacheFile.'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ if ($dir === '.') {
+ // Passed cache file is a file in the current directory.
+ $this->cacheFile = getcwd().'/'.basename($this->cacheFile);
+ } else {
+ if ($dir{0} === '/') {
+ // An absolute path.
+ $dir = Util\Common::realpath($dir);
+ } else {
+ $dir = Util\Common::realpath(getcwd().'/'.$dir);
+ }
+
+ if ($dir !== false) {
+ // Cache file path is relative.
+ $this->cacheFile = $dir.'/'.basename($this->cacheFile);
+ }
+ }
+ }//end if
+
+ self::$overriddenDefaults['cacheFile'] = true;
+
+ if (is_dir($this->cacheFile) === true) {
+ $error = 'ERROR: The specified cache file path "'.$this->cacheFile.'" is a directory'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+ } else if (substr($arg, 0, 10) === 'bootstrap=') {
+ $files = explode(',', substr($arg, 10));
+ $bootstrap = [];
+ foreach ($files as $file) {
+ $path = Util\Common::realpath($file);
+ if ($path === false) {
+ $error = 'ERROR: The specified bootstrap file "'.$file.'" does not exist'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ $bootstrap[] = $path;
+ }
+
+ $this->bootstrap = array_merge($this->bootstrap, $bootstrap);
+ self::$overriddenDefaults['bootstrap'] = true;
+ } else if (substr($arg, 0, 10) === 'file-list=') {
+ $fileList = substr($arg, 10);
+ $path = Util\Common::realpath($fileList);
+ if ($path === false) {
+ $error = 'ERROR: The specified file list "'.$fileList.'" does not exist'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ $files = file($path);
+ foreach ($files as $inputFile) {
+ $inputFile = trim($inputFile);
+
+ // Skip empty lines.
+ if ($inputFile === '') {
+ continue;
+ }
+
+ $this->processFilePath($inputFile);
+ }
+ } else if (substr($arg, 0, 11) === 'stdin-path=') {
+ if (isset(self::$overriddenDefaults['stdinPath']) === true) {
+ break;
+ }
+
+ $this->stdinPath = Util\Common::realpath(substr($arg, 11));
+
+ // It may not exist and return false instead, so use whatever they gave us.
+ if ($this->stdinPath === false) {
+ $this->stdinPath = trim(substr($arg, 11));
+ }
+
+ self::$overriddenDefaults['stdinPath'] = true;
+ } else if (PHP_CODESNIFFER_CBF === false && substr($arg, 0, 12) === 'report-file=') {
+ if (isset(self::$overriddenDefaults['reportFile']) === true) {
+ break;
+ }
+
+ $this->reportFile = Util\Common::realpath(substr($arg, 12));
+
+ // It may not exist and return false instead.
+ if ($this->reportFile === false) {
+ $this->reportFile = substr($arg, 12);
+
+ $dir = dirname($this->reportFile);
+ if (is_dir($dir) === false) {
+ $error = 'ERROR: The specified report file path "'.$this->reportFile.'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ if ($dir === '.') {
+ // Passed report file is a file in the current directory.
+ $this->reportFile = getcwd().'/'.basename($this->reportFile);
+ } else {
+ if ($dir{0} === '/') {
+ // An absolute path.
+ $dir = Util\Common::realpath($dir);
+ } else {
+ $dir = Util\Common::realpath(getcwd().'/'.$dir);
+ }
+
+ if ($dir !== false) {
+ // Report file path is relative.
+ $this->reportFile = $dir.'/'.basename($this->reportFile);
+ }
+ }
+ }//end if
+
+ self::$overriddenDefaults['reportFile'] = true;
+
+ if (is_dir($this->reportFile) === true) {
+ $error = 'ERROR: The specified report file path "'.$this->reportFile.'" is a directory'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+ } else if (substr($arg, 0, 13) === 'report-width=') {
+ if (isset(self::$overriddenDefaults['reportWidth']) === true) {
+ break;
+ }
+
+ $this->reportWidth = substr($arg, 13);
+ self::$overriddenDefaults['reportWidth'] = true;
+ } else if (substr($arg, 0, 9) === 'basepath=') {
+ if (isset(self::$overriddenDefaults['basepath']) === true) {
+ break;
+ }
+
+ self::$overriddenDefaults['basepath'] = true;
+
+ if (substr($arg, 9) === '') {
+ $this->basepath = null;
+ break;
+ }
+
+ $this->basepath = Util\Common::realpath(substr($arg, 9));
+
+ // It may not exist and return false instead.
+ if ($this->basepath === false) {
+ $this->basepath = substr($arg, 9);
+ }
+
+ if (is_dir($this->basepath) === false) {
+ $error = 'ERROR: The specified basepath "'.$this->basepath.'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+ } else if ((substr($arg, 0, 7) === 'report=' || substr($arg, 0, 7) === 'report-')) {
+ $reports = [];
+
+ if ($arg[6] === '-') {
+ // This is a report with file output.
+ $split = strpos($arg, '=');
+ if ($split === false) {
+ $report = substr($arg, 7);
+ $output = null;
+ } else {
+ $report = substr($arg, 7, ($split - 7));
+ $output = substr($arg, ($split + 1));
+ if ($output === false) {
+ $output = null;
+ } else {
+ $dir = dirname($output);
+ if (is_dir($dir) === false) {
+ $error = 'ERROR: The specified '.$report.' report file path "'.$output.'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ if ($dir === '.') {
+ // Passed report file is a filename in the current directory.
+ $output = getcwd().'/'.basename($output);
+ } else {
+ if ($dir{0} === '/') {
+ // An absolute path.
+ $dir = Util\Common::realpath($dir);
+ } else {
+ $dir = Util\Common::realpath(getcwd().'/'.$dir);
+ }
+
+ if ($dir !== false) {
+ // Report file path is relative.
+ $output = $dir.'/'.basename($output);
+ }
+ }
+ }//end if
+ }//end if
+
+ $reports[$report] = $output;
+ } else {
+ // This is a single report.
+ if (isset(self::$overriddenDefaults['reports']) === true) {
+ break;
+ }
+
+ $reportNames = explode(',', substr($arg, 7));
+ foreach ($reportNames as $report) {
+ $reports[$report] = null;
+ }
+ }//end if
+
+ // Remove the default value so the CLI value overrides it.
+ if (isset(self::$overriddenDefaults['reports']) === false) {
+ $this->reports = $reports;
+ } else {
+ $this->reports = array_merge($this->reports, $reports);
+ }
+
+ self::$overriddenDefaults['reports'] = true;
+ } else if (substr($arg, 0, 7) === 'filter=') {
+ if (isset(self::$overriddenDefaults['filter']) === true) {
+ break;
+ }
+
+ $this->filter = substr($arg, 7);
+ self::$overriddenDefaults['filter'] = true;
+ } else if (substr($arg, 0, 9) === 'standard=') {
+ $standards = trim(substr($arg, 9));
+ if ($standards !== '') {
+ $this->standards = explode(',', $standards);
+ }
+
+ self::$overriddenDefaults['standards'] = true;
+ } else if (substr($arg, 0, 11) === 'extensions=') {
+ if (isset(self::$overriddenDefaults['extensions']) === true) {
+ break;
+ }
+
+ $extensions = explode(',', substr($arg, 11));
+ $newExtensions = [];
+ foreach ($extensions as $ext) {
+ $slash = strpos($ext, '/');
+ if ($slash !== false) {
+ // They specified the tokenizer too.
+ list($ext, $tokenizer) = explode('/', $ext);
+ $newExtensions[$ext] = strtoupper($tokenizer);
+ continue;
+ }
+
+ if (isset($this->extensions[$ext]) === true) {
+ $newExtensions[$ext] = $this->extensions[$ext];
+ } else {
+ $newExtensions[$ext] = 'PHP';
+ }
+ }
+
+ $this->extensions = $newExtensions;
+ self::$overriddenDefaults['extensions'] = true;
+ } else if (substr($arg, 0, 7) === 'suffix=') {
+ if (isset(self::$overriddenDefaults['suffix']) === true) {
+ break;
+ }
+
+ $this->suffix = substr($arg, 7);
+ self::$overriddenDefaults['suffix'] = true;
+ } else if (substr($arg, 0, 9) === 'parallel=') {
+ if (isset(self::$overriddenDefaults['parallel']) === true) {
+ break;
+ }
+
+ $this->parallel = max((int) substr($arg, 9), 1);
+ self::$overriddenDefaults['parallel'] = true;
+ } else if (substr($arg, 0, 9) === 'severity=') {
+ $this->errorSeverity = (int) substr($arg, 9);
+ $this->warningSeverity = $this->errorSeverity;
+ if (isset(self::$overriddenDefaults['errorSeverity']) === false) {
+ self::$overriddenDefaults['errorSeverity'] = true;
+ }
+
+ if (isset(self::$overriddenDefaults['warningSeverity']) === false) {
+ self::$overriddenDefaults['warningSeverity'] = true;
+ }
+ } else if (substr($arg, 0, 15) === 'error-severity=') {
+ if (isset(self::$overriddenDefaults['errorSeverity']) === true) {
+ break;
+ }
+
+ $this->errorSeverity = (int) substr($arg, 15);
+ self::$overriddenDefaults['errorSeverity'] = true;
+ } else if (substr($arg, 0, 17) === 'warning-severity=') {
+ if (isset(self::$overriddenDefaults['warningSeverity']) === true) {
+ break;
+ }
+
+ $this->warningSeverity = (int) substr($arg, 17);
+ self::$overriddenDefaults['warningSeverity'] = true;
+ } else if (substr($arg, 0, 7) === 'ignore=') {
+ if (isset(self::$overriddenDefaults['ignored']) === true) {
+ break;
+ }
+
+ // Split the ignore string on commas, unless the comma is escaped
+ // using 1 or 3 slashes (\, or \\\,).
+ $patterns = preg_split(
+ '/(?<=(?ignored = $ignored;
+ self::$overriddenDefaults['ignored'] = true;
+ } else if (substr($arg, 0, 10) === 'generator='
+ && PHP_CODESNIFFER_CBF === false
+ ) {
+ if (isset(self::$overriddenDefaults['generator']) === true) {
+ break;
+ }
+
+ $this->generator = substr($arg, 10);
+ self::$overriddenDefaults['generator'] = true;
+ } else if (substr($arg, 0, 9) === 'encoding=') {
+ if (isset(self::$overriddenDefaults['encoding']) === true) {
+ break;
+ }
+
+ $this->encoding = strtolower(substr($arg, 9));
+ self::$overriddenDefaults['encoding'] = true;
+ } else if (substr($arg, 0, 10) === 'tab-width=') {
+ if (isset(self::$overriddenDefaults['tabWidth']) === true) {
+ break;
+ }
+
+ $this->tabWidth = (int) substr($arg, 10);
+ self::$overriddenDefaults['tabWidth'] = true;
+ } else {
+ if ($this->dieOnUnknownArg === false) {
+ $eqPos = strpos($arg, '=');
+ try {
+ if ($eqPos === false) {
+ $this->values[$arg] = $arg;
+ } else {
+ $value = substr($arg, ($eqPos + 1));
+ $arg = substr($arg, 0, $eqPos);
+ $this->values[$arg] = $value;
+ }
+ } catch (RuntimeException $e) {
+ // Value is not valid, so just ignore it.
+ }
+ } else {
+ $this->processUnknownArgument('--'.$arg, $pos);
+ }
+ }//end if
+ break;
+ }//end switch
+
+ }//end processLongArgument()
+
+
+ /**
+ * Processes an unknown command line argument.
+ *
+ * Assumes all unknown arguments are files and folders to check.
+ *
+ * @param string $arg The command line argument.
+ * @param int $pos The position of the argument on the command line.
+ *
+ * @return void
+ */
+ public function processUnknownArgument($arg, $pos)
+ {
+ // We don't know about any additional switches; just files.
+ if ($arg{0} === '-') {
+ if ($this->dieOnUnknownArg === false) {
+ return;
+ }
+
+ $error = "ERROR: option \"$arg\" not known".PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ }
+
+ $this->processFilePath($arg);
+
+ }//end processUnknownArgument()
+
+
+ /**
+ * Processes a file path and add it to the file list.
+ *
+ * @param string $path The path to the file to add.
+ *
+ * @return void
+ */
+ public function processFilePath($path)
+ {
+ // If we are processing STDIN, don't record any files to check.
+ if ($this->stdin === true) {
+ return;
+ }
+
+ $file = Util\Common::realpath($path);
+ if (file_exists($file) === false) {
+ if ($this->dieOnUnknownArg === false) {
+ return;
+ }
+
+ $error = 'ERROR: The file "'.$path.'" does not exist.'.PHP_EOL.PHP_EOL;
+ $error .= $this->printShortUsage(true);
+ throw new DeepExitException($error, 3);
+ } else {
+ // Can't modify the files array directly because it's not a real
+ // class member, so need to use this little get/modify/set trick.
+ $files = $this->files;
+ $files[] = $file;
+ $this->files = $files;
+ self::$overriddenDefaults['files'] = true;
+ }
+
+ }//end processFilePath()
+
+
+ /**
+ * Prints out the usage information for this script.
+ *
+ * @return void
+ */
+ public function printUsage()
+ {
+ echo PHP_EOL;
+
+ if (PHP_CODESNIFFER_CBF === true) {
+ $this->printPHPCBFUsage();
+ } else {
+ $this->printPHPCSUsage();
+ }
+
+ echo PHP_EOL;
+
+ }//end printUsage()
+
+
+ /**
+ * Prints out the short usage information for this script.
+ *
+ * @param bool $return If TRUE, the usage string is returned
+ * instead of output to screen.
+ *
+ * @return string|void
+ */
+ public function printShortUsage($return=false)
+ {
+ if (PHP_CODESNIFFER_CBF === true) {
+ $usage = 'Run "phpcbf --help" for usage information';
+ } else {
+ $usage = 'Run "phpcs --help" for usage information';
+ }
+
+ $usage .= PHP_EOL.PHP_EOL;
+
+ if ($return === true) {
+ return $usage;
+ }
+
+ echo $usage;
+
+ }//end printShortUsage()
+
+
+ /**
+ * Prints out the usage information for PHPCS.
+ *
+ * @return void
+ */
+ public function printPHPCSUsage()
+ {
+ echo 'Usage: phpcs [-nwlsaepqvi] [-d key[=value]] [--colors] [--no-colors]'.PHP_EOL;
+ echo ' [--cache[=]] [--no-cache] [--tab-width=]'.PHP_EOL;
+ echo ' [--report=] [--report-file=] [--report-=]'.PHP_EOL;
+ echo ' [--report-width=] [--basepath=] [--bootstrap=]'.PHP_EOL;
+ echo ' [--severity=] [--error-severity=] [--warning-severity=]'.PHP_EOL;
+ echo ' [--runtime-set key value] [--config-set key value] [--config-delete key] [--config-show]'.PHP_EOL;
+ echo ' [--standard=] [--sniffs=] [--exclude=]'.PHP_EOL;
+ echo ' [--encoding=] [--parallel=] [--generator=]'.PHP_EOL;
+ echo ' [--extensions=] [--ignore=] [--ignore-annotations]'.PHP_EOL;
+ echo ' [--stdin-path=] [--file-list=] [--filter=] - ...'.PHP_EOL;
+ echo PHP_EOL;
+ echo ' - Check STDIN instead of local files and directories'.PHP_EOL;
+ echo ' -n Do not print warnings (shortcut for --warning-severity=0)'.PHP_EOL;
+ echo ' -w Print both warnings and errors (this is the default)'.PHP_EOL;
+ echo ' -l Local directory only, no recursion'.PHP_EOL;
+ echo ' -s Show sniff codes in all reports'.PHP_EOL;
+ echo ' -a Run interactively'.PHP_EOL;
+ echo ' -e Explain a standard by showing the sniffs it includes'.PHP_EOL;
+ echo ' -p Show progress of the run'.PHP_EOL;
+ echo ' -q Quiet mode; disables progress and verbose output'.PHP_EOL;
+ echo ' -m Stop error messages from being recorded'.PHP_EOL;
+ echo ' (saves a lot of memory, but stops many reports from being used)'.PHP_EOL;
+ echo ' -v Print processed files'.PHP_EOL;
+ echo ' -vv Print ruleset and token output'.PHP_EOL;
+ echo ' -vvv Print sniff processing information'.PHP_EOL;
+ echo ' -i Show a list of installed coding standards'.PHP_EOL;
+ echo ' -d Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
+ echo PHP_EOL;
+ echo ' --help Print this help message'.PHP_EOL;
+ echo ' --version Print version information'.PHP_EOL;
+ echo ' --colors Use colors in output'.PHP_EOL;
+ echo ' --no-colors Do not use colors in output (this is the default)'.PHP_EOL;
+ echo ' --cache Cache results between runs'.PHP_EOL;
+ echo ' --no-cache Do not cache results between runs (this is the default)'.PHP_EOL;
+ echo ' --ignore-annotations Ignore all phpcs: annotations in code comments'.PHP_EOL;
+ echo PHP_EOL;
+ echo ' Use a specific file for caching (uses a temporary file by default)'.PHP_EOL;
+ echo ' A path to strip from the front of file paths inside reports'.PHP_EOL;
+ echo ' A comma separated list of files to run before processing begins'.PHP_EOL;
+ echo ' The encoding of the files being checked (default is utf-8)'.PHP_EOL;
+ echo ' A comma separated list of file extensions to check'.PHP_EOL;
+ echo ' The type of the file can be specified using: ext/type'.PHP_EOL;
+ echo ' e.g., module/php,es/js'.PHP_EOL;
+ echo ' One or more files and/or directories to check'.PHP_EOL;
+ echo ' A file containing a list of files and/or directories to check (one per line)'.PHP_EOL;
+ echo ' Use the "gitmodified" filter, or specify the path to a custom filter class'.PHP_EOL;
+ echo ' Uses either the "HTML", "Markdown" or "Text" generator'.PHP_EOL;
+ echo ' (forces documentation generation instead of checking)'.PHP_EOL;
+ echo ' A comma separated list of patterns to ignore files and directories'.PHP_EOL;
+ echo ' How many files should be checked simultaneously (default is 1)'.PHP_EOL;
+ echo ' Print either the "full", "xml", "checkstyle", "csv"'.PHP_EOL;
+ echo ' "json", "junit", "emacs", "source", "summary", "diff"'.PHP_EOL;
+ echo ' "svnblame", "gitblame", "hgblame" or "notifysend" report,'.PHP_EOL;
+ echo ' or specify the path to a custom report class'.PHP_EOL;
+ echo ' (the "full" report is printed by default)'.PHP_EOL;
+ echo ' Write the report to the specified file path'.PHP_EOL;
+ echo ' How many columns wide screen reports should be printed'.PHP_EOL;
+ echo ' or set to "auto" to use current screen width, where supported'.PHP_EOL;
+ echo ' The minimum severity required to display an error or warning'.PHP_EOL;
+ echo ' A comma separated list of sniff codes to include or exclude from checking'.PHP_EOL;
+ echo ' (all sniffs must be part of the specified standard)'.PHP_EOL;
+ echo ' The name or path of the coding standard to use'.PHP_EOL;
+ echo ' If processing STDIN, the file path that STDIN will be processed as'.PHP_EOL;
+ echo ' The number of spaces each tab represents'.PHP_EOL;
+
+ }//end printPHPCSUsage()
+
+
+ /**
+ * Prints out the usage information for PHPCBF.
+ *
+ * @return void
+ */
+ public function printPHPCBFUsage()
+ {
+ echo 'Usage: phpcbf [-nwli] [-d key[=value]] [--ignore-annotations] [--bootstrap=]'.PHP_EOL;
+ echo ' [--standard=] [--sniffs=] [--exclude=] [--suffix=]'.PHP_EOL;
+ echo ' [--severity=] [--error-severity=] [--warning-severity=]'.PHP_EOL;
+ echo ' [--tab-width=] [--encoding=] [--parallel=]'.PHP_EOL;
+ echo ' [--basepath=] [--extensions=] [--ignore=]'.PHP_EOL;
+ echo ' [--stdin-path=] [--file-list=] [--filter=] - ...'.PHP_EOL;
+ echo PHP_EOL;
+ echo ' - Fix STDIN instead of local files and directories'.PHP_EOL;
+ echo ' -n Do not fix warnings (shortcut for --warning-severity=0)'.PHP_EOL;
+ echo ' -w Fix both warnings and errors (on by default)'.PHP_EOL;
+ echo ' -l Local directory only, no recursion'.PHP_EOL;
+ echo ' -p Show progress of the run'.PHP_EOL;
+ echo ' -q Quiet mode; disables progress and verbose output'.PHP_EOL;
+ echo ' -v Print processed files'.PHP_EOL;
+ echo ' -vv Print ruleset and token output'.PHP_EOL;
+ echo ' -vvv Print sniff processing information'.PHP_EOL;
+ echo ' -i Show a list of installed coding standards'.PHP_EOL;
+ echo ' -d Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
+ echo PHP_EOL;
+ echo ' --help Print this help message'.PHP_EOL;
+ echo ' --version Print version information'.PHP_EOL;
+ echo ' --ignore-annotations Ignore all phpcs: annotations in code comments'.PHP_EOL;
+ echo PHP_EOL;
+ echo ' A path to strip from the front of file paths inside reports'.PHP_EOL;
+ echo ' A comma separated list of files to run before processing begins'.PHP_EOL;
+ echo ' The encoding of the files being fixed (default is utf-8)'.PHP_EOL;
+ echo ' A comma separated list of file extensions to fix'.PHP_EOL;
+ echo ' The type of the file can be specified using: ext/type'.PHP_EOL;
+ echo ' e.g., module/php,es/js'.PHP_EOL;
+ echo ' One or more files and/or directories to fix'.PHP_EOL;
+ echo ' A file containing a list of files and/or directories to fix (one per line)'.PHP_EOL;
+ echo ' Use the "gitmodified" filter, or specify the path to a custom filter class'.PHP_EOL;
+ echo ' A comma separated list of patterns to ignore files and directories'.PHP_EOL;
+ echo ' How many files should be fixed simultaneously (default is 1)'.PHP_EOL;
+ echo ' The minimum severity required to fix an error or warning'.PHP_EOL;
+ echo ' A comma separated list of sniff codes to include or exclude from fixing'.PHP_EOL;
+ echo ' (all sniffs must be part of the specified standard)'.PHP_EOL;
+ echo ' The name or path of the coding standard to use'.PHP_EOL;
+ echo ' If processing STDIN, the file path that STDIN will be processed as'.PHP_EOL;
+ echo ' Write modified files to a filename using this suffix'.PHP_EOL;
+ echo ' ("diff" and "patch" are not used in this mode)'.PHP_EOL;
+ echo ' The number of spaces each tab represents'.PHP_EOL;
+
+ }//end printPHPCBFUsage()
+
+
+ /**
+ * Get a single config value.
+ *
+ * @param string $key The name of the config value.
+ *
+ * @return string|null
+ * @see setConfigData()
+ * @see getAllConfigData()
+ */
+ public static function getConfigData($key)
+ {
+ $phpCodeSnifferConfig = self::getAllConfigData();
+
+ if ($phpCodeSnifferConfig === null) {
+ return null;
+ }
+
+ if (isset($phpCodeSnifferConfig[$key]) === false) {
+ return null;
+ }
+
+ return $phpCodeSnifferConfig[$key];
+
+ }//end getConfigData()
+
+
+ /**
+ * Get the path to an executable utility.
+ *
+ * @param string $name The name of the executable utility.
+ *
+ * @return string|null
+ * @see getConfigData()
+ */
+ public static function getExecutablePath($name)
+ {
+ $data = self::getConfigData($name.'_path');
+ if ($data !== null) {
+ return $data;
+ }
+
+ if ($name === "php") {
+ // For php, we know the executable path. There's no need to look it up.
+ return PHP_BINARY;
+ }
+
+ if (array_key_exists($name, self::$executablePaths) === true) {
+ return self::$executablePaths[$name];
+ }
+
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ $cmd = 'where '.escapeshellarg($name).' 2> nul';
+ } else {
+ $cmd = 'which '.escapeshellarg($name).' 2> /dev/null';
+ }
+
+ $result = exec($cmd, $output, $retVal);
+ if ($retVal !== 0) {
+ $result = null;
+ }
+
+ self::$executablePaths[$name] = $result;
+ return $result;
+
+ }//end getExecutablePath()
+
+
+ /**
+ * Set a single config value.
+ *
+ * @param string $key The name of the config value.
+ * @param string|null $value The value to set. If null, the config
+ * entry is deleted, reverting it to the
+ * default value.
+ * @param boolean $temp Set this config data temporarily for this
+ * script run. This will not write the config
+ * data to the config file.
+ *
+ * @return bool
+ * @see getConfigData()
+ * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the config file can not be written.
+ */
+ public static function setConfigData($key, $value, $temp=false)
+ {
+ if (isset(self::$overriddenDefaults['runtime-set']) === true
+ && isset(self::$overriddenDefaults['runtime-set'][$key]) === true
+ ) {
+ return false;
+ }
+
+ if ($temp === false) {
+ $path = '';
+ if (is_callable('\Phar::running') === true) {
+ $path = \Phar::running(false);
+ }
+
+ if ($path !== '') {
+ $configFile = dirname($path).DIRECTORY_SEPARATOR.'CodeSniffer.conf';
+ } else {
+ $configFile = dirname(__DIR__).DIRECTORY_SEPARATOR.'CodeSniffer.conf';
+ if (is_file($configFile) === false
+ && strpos('@data_dir@', '@data_dir') === false
+ ) {
+ // If data_dir was replaced, this is a PEAR install and we can
+ // use the PEAR data dir to store the conf file.
+ $configFile = '@data_dir@/PHP_CodeSniffer/CodeSniffer.conf';
+ }
+ }
+
+ if (is_file($configFile) === true
+ && is_writable($configFile) === false
+ ) {
+ $error = 'ERROR: Config file '.$configFile.' is not writable'.PHP_EOL.PHP_EOL;
+ throw new DeepExitException($error, 3);
+ }
+ }//end if
+
+ $phpCodeSnifferConfig = self::getAllConfigData();
+
+ if ($value === null) {
+ if (isset($phpCodeSnifferConfig[$key]) === true) {
+ unset($phpCodeSnifferConfig[$key]);
+ }
+ } else {
+ $phpCodeSnifferConfig[$key] = $value;
+ }
+
+ if ($temp === false) {
+ $output = '<'.'?php'."\n".' $phpCodeSnifferConfig = ';
+ $output .= var_export($phpCodeSnifferConfig, true);
+ $output .= "\n?".'>';
+
+ if (file_put_contents($configFile, $output) === false) {
+ $error = 'ERROR: Config file '.$configFile.' could not be written'.PHP_EOL.PHP_EOL;
+ throw new DeepExitException($error, 3);
+ }
+
+ self::$configDataFile = $configFile;
+ }
+
+ self::$configData = $phpCodeSnifferConfig;
+
+ // If the installed paths are being set, make sure all known
+ // standards paths are added to the autoloader.
+ if ($key === 'installed_paths') {
+ $installedStandards = Util\Standards::getInstalledStandardDetails();
+ foreach ($installedStandards as $name => $details) {
+ Autoload::addSearchPath($details['path'], $details['namespace']);
+ }
+ }
+
+ return true;
+
+ }//end setConfigData()
+
+
+ /**
+ * Get all config data.
+ *
+ * @return array
+ * @see getConfigData()
+ */
+ public static function getAllConfigData()
+ {
+ if (self::$configData !== null) {
+ return self::$configData;
+ }
+
+ $path = '';
+ if (is_callable('\Phar::running') === true) {
+ $path = \Phar::running(false);
+ }
+
+ if ($path !== '') {
+ $configFile = dirname($path).DIRECTORY_SEPARATOR.'CodeSniffer.conf';
+ } else {
+ $configFile = dirname(__DIR__).DIRECTORY_SEPARATOR.'CodeSniffer.conf';
+ if (is_file($configFile) === false
+ && strpos('@data_dir@', '@data_dir') === false
+ ) {
+ $configFile = '@data_dir@/PHP_CodeSniffer/CodeSniffer.conf';
+ }
+ }
+
+ if (is_file($configFile) === false) {
+ self::$configData = [];
+ return [];
+ }
+
+ if (is_readable($configFile) === false) {
+ $error = 'ERROR: Config file '.$configFile.' is not readable'.PHP_EOL.PHP_EOL;
+ throw new DeepExitException($error, 3);
+ }
+
+ include $configFile;
+ self::$configDataFile = $configFile;
+ self::$configData = $phpCodeSnifferConfig;
+ return self::$configData;
+
+ }//end getAllConfigData()
+
+
+ /**
+ * Prints out the gathered config data.
+ *
+ * @param array $data The config data to print.
+ *
+ * @return void
+ */
+ public function printConfigData($data)
+ {
+ $max = 0;
+ $keys = array_keys($data);
+ foreach ($keys as $key) {
+ $len = strlen($key);
+ if (strlen($key) > $max) {
+ $max = $len;
+ }
+ }
+
+ if ($max === 0) {
+ return;
+ }
+
+ $max += 2;
+ ksort($data);
+ foreach ($data as $name => $value) {
+ echo str_pad($name.': ', $max).$value.PHP_EOL;
+ }
+
+ }//end printConfigData()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Exceptions/DeepExitException.php b/vendor/squizlabs/php_codesniffer/src/Exceptions/DeepExitException.php
new file mode 100644
index 0000000..b144094
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Exceptions/DeepExitException.php
@@ -0,0 +1,18 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Exceptions;
+
+class DeepExitException extends \Exception
+{
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Exceptions/RuntimeException.php b/vendor/squizlabs/php_codesniffer/src/Exceptions/RuntimeException.php
new file mode 100644
index 0000000..093bf13
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Exceptions/RuntimeException.php
@@ -0,0 +1,15 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Exceptions;
+
+class RuntimeException extends \RuntimeException
+{
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Exceptions/TokenizerException.php b/vendor/squizlabs/php_codesniffer/src/Exceptions/TokenizerException.php
new file mode 100644
index 0000000..ceba00c
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Exceptions/TokenizerException.php
@@ -0,0 +1,15 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Exceptions;
+
+class TokenizerException extends \Exception
+{
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Files/DummyFile.php b/vendor/squizlabs/php_codesniffer/src/Files/DummyFile.php
new file mode 100644
index 0000000..3275bf0
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Files/DummyFile.php
@@ -0,0 +1,82 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Files;
+
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Config;
+
+class DummyFile extends File
+{
+
+
+ /**
+ * Creates a DummyFile object and sets the content.
+ *
+ * @param string $content The content of the file.
+ * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
+ * @param \PHP_CodeSniffer\Config $config The config data for the run.
+ *
+ * @return void
+ */
+ public function __construct($content, Ruleset $ruleset, Config $config)
+ {
+ $this->setContent($content);
+
+ // See if a filename was defined in the content.
+ // This is done by including: phpcs_input_file: [file path]
+ // as the first line of content.
+ $path = 'STDIN';
+ if ($content !== null) {
+ if (substr($content, 0, 17) === 'phpcs_input_file:') {
+ $eolPos = strpos($content, $this->eolChar);
+ $filename = trim(substr($content, 17, ($eolPos - 17)));
+ $content = substr($content, ($eolPos + strlen($this->eolChar)));
+ $path = $filename;
+
+ $this->setContent($content);
+ }
+ }
+
+ // The CLI arg overrides anything passed in the content.
+ if ($config->stdinPath !== null) {
+ $path = $config->stdinPath;
+ }
+
+ parent::__construct($path, $ruleset, $config);
+
+ }//end __construct()
+
+
+ /**
+ * Set the error, warning, and fixable counts for the file.
+ *
+ * @param int $errorCount The number of errors found.
+ * @param int $warningCount The number of warnings found.
+ * @param int $fixableCount The number of fixable errors found.
+ * @param int $fixedCount The number of errors that were fixed.
+ *
+ * @return void
+ */
+ public function setErrorCounts($errorCount, $warningCount, $fixableCount, $fixedCount)
+ {
+ $this->errorCount = $errorCount;
+ $this->warningCount = $warningCount;
+ $this->fixableCount = $fixableCount;
+ $this->fixedCount = $fixedCount;
+
+ }//end setErrorCounts()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Files/File.php b/vendor/squizlabs/php_codesniffer/src/Files/File.php
new file mode 100644
index 0000000..05fa345
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Files/File.php
@@ -0,0 +1,2485 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Files;
+
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Config;
+use PHP_CodeSniffer\Fixer;
+use PHP_CodeSniffer\Util;
+use PHP_CodeSniffer\Exceptions\RuntimeException;
+use PHP_CodeSniffer\Exceptions\TokenizerException;
+
+class File
+{
+
+ /**
+ * The absolute path to the file associated with this object.
+ *
+ * @var string
+ */
+ public $path = '';
+
+ /**
+ * The content of the file.
+ *
+ * @var string
+ */
+ protected $content = '';
+
+ /**
+ * The config data for the run.
+ *
+ * @var \PHP_CodeSniffer\Config
+ */
+ public $config = null;
+
+ /**
+ * The ruleset used for the run.
+ *
+ * @var \PHP_CodeSniffer\Ruleset
+ */
+ public $ruleset = null;
+
+ /**
+ * If TRUE, the entire file is being ignored.
+ *
+ * @var boolean
+ */
+ public $ignored = false;
+
+ /**
+ * The EOL character this file uses.
+ *
+ * @var string
+ */
+ public $eolChar = '';
+
+ /**
+ * The Fixer object to control fixing errors.
+ *
+ * @var \PHP_CodeSniffer\Fixer
+ */
+ public $fixer = null;
+
+ /**
+ * The tokenizer being used for this file.
+ *
+ * @var \PHP_CodeSniffer\Tokenizers\Tokenizer
+ */
+ public $tokenizer = null;
+
+ /**
+ * The name of the tokenizer being used for this file.
+ *
+ * @var string
+ */
+ public $tokenizerType = 'PHP';
+
+ /**
+ * Was the file loaded from cache?
+ *
+ * If TRUE, the file was loaded from a local cache.
+ * If FALSE, the file was tokenized and processed fully.
+ *
+ * @var boolean
+ */
+ public $fromCache = false;
+
+ /**
+ * The number of tokens in this file.
+ *
+ * Stored here to save calling count() everywhere.
+ *
+ * @var integer
+ */
+ public $numTokens = 0;
+
+ /**
+ * The tokens stack map.
+ *
+ * @var array
+ */
+ protected $tokens = [];
+
+ /**
+ * The errors raised from sniffs.
+ *
+ * @var array
+ * @see getErrors()
+ */
+ protected $errors = [];
+
+ /**
+ * The warnings raised from sniffs.
+ *
+ * @var array
+ * @see getWarnings()
+ */
+ protected $warnings = [];
+
+ /**
+ * The metrics recorded by sniffs.
+ *
+ * @var array
+ * @see getMetrics()
+ */
+ protected $metrics = [];
+
+ /**
+ * The metrics recorded for each token.
+ *
+ * Stops the same metric being recorded for the same token twice.
+ *
+ * @var array
+ * @see getMetrics()
+ */
+ private $metricTokens = [];
+
+ /**
+ * The total number of errors raised.
+ *
+ * @var integer
+ */
+ protected $errorCount = 0;
+
+ /**
+ * The total number of warnings raised.
+ *
+ * @var integer
+ */
+ protected $warningCount = 0;
+
+ /**
+ * The total number of errors and warnings that can be fixed.
+ *
+ * @var integer
+ */
+ protected $fixableCount = 0;
+
+ /**
+ * The total number of errors and warnings that were fixed.
+ *
+ * @var integer
+ */
+ protected $fixedCount = 0;
+
+ /**
+ * An array of sniffs that are being ignored.
+ *
+ * @var array
+ */
+ protected $ignoredListeners = [];
+
+ /**
+ * An array of message codes that are being ignored.
+ *
+ * @var array
+ */
+ protected $ignoredCodes = [];
+
+ /**
+ * An array of sniffs listening to this file's processing.
+ *
+ * @var \PHP_CodeSniffer\Sniffs\Sniff[]
+ */
+ protected $listeners = [];
+
+ /**
+ * The class name of the sniff currently processing the file.
+ *
+ * @var string
+ */
+ protected $activeListener = '';
+
+ /**
+ * An array of sniffs being processed and how long they took.
+ *
+ * @var array
+ */
+ protected $listenerTimes = [];
+
+ /**
+ * A cache of often used config settings to improve performance.
+ *
+ * Storing them here saves 10k+ calls to __get() in the Config class.
+ *
+ * @var array
+ */
+ protected $configCache = [];
+
+
+ /**
+ * Constructs a file.
+ *
+ * @param string $path The absolute path to the file to process.
+ * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
+ * @param \PHP_CodeSniffer\Config $config The config data for the run.
+ *
+ * @return void
+ */
+ public function __construct($path, Ruleset $ruleset, Config $config)
+ {
+ $this->path = $path;
+ $this->ruleset = $ruleset;
+ $this->config = $config;
+ $this->fixer = new Fixer();
+
+ $parts = explode('.', $path);
+ $extension = array_pop($parts);
+ if (isset($config->extensions[$extension]) === true) {
+ $this->tokenizerType = $config->extensions[$extension];
+ } else {
+ // Revert to default.
+ $this->tokenizerType = 'PHP';
+ }
+
+ $this->configCache['cache'] = $this->config->cache;
+ $this->configCache['sniffs'] = array_map('strtolower', $this->config->sniffs);
+ $this->configCache['exclude'] = array_map('strtolower', $this->config->exclude);
+ $this->configCache['errorSeverity'] = $this->config->errorSeverity;
+ $this->configCache['warningSeverity'] = $this->config->warningSeverity;
+ $this->configCache['recordErrors'] = $this->config->recordErrors;
+ $this->configCache['ignorePatterns'] = $this->ruleset->ignorePatterns;
+ $this->configCache['includePatterns'] = $this->ruleset->includePatterns;
+
+ }//end __construct()
+
+
+ /**
+ * Set the content of the file.
+ *
+ * Setting the content also calculates the EOL char being used.
+ *
+ * @param string $content The file content.
+ *
+ * @return void
+ */
+ public function setContent($content)
+ {
+ $this->content = $content;
+ $this->tokens = [];
+
+ try {
+ $this->eolChar = Util\Common::detectLineEndings($content);
+ } catch (RuntimeException $e) {
+ $this->addWarningOnLine($e->getMessage(), 1, 'Internal.DetectLineEndings');
+ return;
+ }
+
+ }//end setContent()
+
+
+ /**
+ * Reloads the content of the file.
+ *
+ * By default, we have no idea where our content comes from,
+ * so we can't do anything.
+ *
+ * @return void
+ */
+ public function reloadContent()
+ {
+
+ }//end reloadContent()
+
+
+ /**
+ * Disables caching of this file.
+ *
+ * @return void
+ */
+ public function disableCaching()
+ {
+ $this->configCache['cache'] = false;
+
+ }//end disableCaching()
+
+
+ /**
+ * Starts the stack traversal and tells listeners when tokens are found.
+ *
+ * @return void
+ */
+ public function process()
+ {
+ if ($this->ignored === true) {
+ return;
+ }
+
+ $this->errors = [];
+ $this->warnings = [];
+ $this->errorCount = 0;
+ $this->warningCount = 0;
+ $this->fixableCount = 0;
+
+ $this->parse();
+
+ // Check if tokenizer errors cause this file to be ignored.
+ if ($this->ignored === true) {
+ return;
+ }
+
+ $this->fixer->startFile($this);
+
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
+ echo "\t*** START TOKEN PROCESSING ***".PHP_EOL;
+ }
+
+ $foundCode = false;
+ $listenerIgnoreTo = [];
+ $inTests = defined('PHP_CODESNIFFER_IN_TESTS');
+ $checkAnnotations = $this->config->annotations;
+
+ // Foreach of the listeners that have registered to listen for this
+ // token, get them to process it.
+ foreach ($this->tokens as $stackPtr => $token) {
+ // Check for ignored lines.
+ if ($checkAnnotations === true
+ && ($token['code'] === T_COMMENT
+ || $token['code'] === T_PHPCS_IGNORE_FILE
+ || $token['code'] === T_PHPCS_SET
+ || $token['code'] === T_DOC_COMMENT_STRING
+ || $token['code'] === T_DOC_COMMENT_TAG
+ || ($inTests === true && $token['code'] === T_INLINE_HTML))
+ ) {
+ $commentText = ltrim($this->tokens[$stackPtr]['content'], ' /*');
+ $commentTextLower = strtolower($commentText);
+ if (strpos($commentText, '@codingStandards') !== false) {
+ if (strpos($commentText, '@codingStandardsIgnoreFile') !== false) {
+ // Ignoring the whole file, just a little late.
+ $this->errors = [];
+ $this->warnings = [];
+ $this->errorCount = 0;
+ $this->warningCount = 0;
+ $this->fixableCount = 0;
+ return;
+ } else if (strpos($commentText, '@codingStandardsChangeSetting') !== false) {
+ $start = strpos($commentText, '@codingStandardsChangeSetting');
+ $comment = substr($commentText, ($start + 30));
+ $parts = explode(' ', $comment);
+ if (count($parts) >= 2) {
+ $sniffParts = explode('.', $parts[0]);
+ if (count($sniffParts) >= 3) {
+ // If the sniff code is not known to us, it has not been registered in this run.
+ // But don't throw an error as it could be there for a different standard to use.
+ if (isset($this->ruleset->sniffCodes[$parts[0]]) === true) {
+ $listenerCode = array_shift($parts);
+ $propertyCode = array_shift($parts);
+ $propertyValue = rtrim(implode(' ', $parts), " */\r\n");
+ $listenerClass = $this->ruleset->sniffCodes[$listenerCode];
+ $this->ruleset->setSniffProperty($listenerClass, $propertyCode, $propertyValue);
+ }
+ }
+ }
+ }//end if
+ } else if (substr($commentTextLower, 0, 16) === 'phpcs:ignorefile'
+ || substr($commentTextLower, 0, 17) === '@phpcs:ignorefile'
+ ) {
+ // Ignoring the whole file, just a little late.
+ $this->errors = [];
+ $this->warnings = [];
+ $this->errorCount = 0;
+ $this->warningCount = 0;
+ $this->fixableCount = 0;
+ return;
+ } else if (substr($commentTextLower, 0, 9) === 'phpcs:set'
+ || substr($commentTextLower, 0, 10) === '@phpcs:set'
+ ) {
+ if (isset($token['sniffCode']) === true) {
+ $listenerCode = $token['sniffCode'];
+ if (isset($this->ruleset->sniffCodes[$listenerCode]) === true) {
+ $propertyCode = $token['sniffProperty'];
+ $propertyValue = $token['sniffPropertyValue'];
+ $listenerClass = $this->ruleset->sniffCodes[$listenerCode];
+ $this->ruleset->setSniffProperty($listenerClass, $propertyCode, $propertyValue);
+ }
+ }
+ }//end if
+ }//end if
+
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
+ $type = $token['type'];
+ $content = Util\Common::prepareForOutput($token['content']);
+ echo "\t\tProcess token $stackPtr: $type => $content".PHP_EOL;
+ }
+
+ if ($token['code'] !== T_INLINE_HTML) {
+ $foundCode = true;
+ }
+
+ if (isset($this->ruleset->tokenListeners[$token['code']]) === false) {
+ continue;
+ }
+
+ foreach ($this->ruleset->tokenListeners[$token['code']] as $listenerData) {
+ if (isset($this->ignoredListeners[$listenerData['class']]) === true
+ || (isset($listenerIgnoreTo[$listenerData['class']]) === true
+ && $listenerIgnoreTo[$listenerData['class']] > $stackPtr)
+ ) {
+ // This sniff is ignoring past this token, or the whole file.
+ continue;
+ }
+
+ // Make sure this sniff supports the tokenizer
+ // we are currently using.
+ $class = $listenerData['class'];
+
+ if (isset($listenerData['tokenizers'][$this->tokenizerType]) === false) {
+ continue;
+ }
+
+ // If the file path matches one of our ignore patterns, skip it.
+ // While there is support for a type of each pattern
+ // (absolute or relative) we don't actually support it here.
+ foreach ($listenerData['ignore'] as $pattern) {
+ // We assume a / directory separator, as do the exclude rules
+ // most developers write, so we need a special case for any system
+ // that is different.
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $pattern = str_replace('/', '\\\\', $pattern);
+ }
+
+ $pattern = '`'.$pattern.'`i';
+ if (preg_match($pattern, $this->path) === 1) {
+ $this->ignoredListeners[$class] = true;
+ continue(2);
+ }
+ }
+
+ // If the file path does not match one of our include patterns, skip it.
+ // While there is support for a type of each pattern
+ // (absolute or relative) we don't actually support it here.
+ if (empty($listenerData['include']) === false) {
+ $included = false;
+ foreach ($listenerData['include'] as $pattern) {
+ // We assume a / directory separator, as do the exclude rules
+ // most developers write, so we need a special case for any system
+ // that is different.
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $pattern = str_replace('/', '\\\\', $pattern);
+ }
+
+ $pattern = '`'.$pattern.'`i';
+ if (preg_match($pattern, $this->path) === 1) {
+ $included = true;
+ break;
+ }
+ }
+
+ if ($included === false) {
+ $this->ignoredListeners[$class] = true;
+ continue;
+ }
+ }//end if
+
+ $this->activeListener = $class;
+
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
+ $startTime = microtime(true);
+ echo "\t\t\tProcessing ".$this->activeListener.'... ';
+ }
+
+ $ignoreTo = $this->ruleset->sniffs[$class]->process($this, $stackPtr);
+ if ($ignoreTo !== null) {
+ $listenerIgnoreTo[$this->activeListener] = $ignoreTo;
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
+ $timeTaken = (microtime(true) - $startTime);
+ if (isset($this->listenerTimes[$this->activeListener]) === false) {
+ $this->listenerTimes[$this->activeListener] = 0;
+ }
+
+ $this->listenerTimes[$this->activeListener] += $timeTaken;
+
+ $timeTaken = round(($timeTaken), 4);
+ echo "DONE in $timeTaken seconds".PHP_EOL;
+ }
+
+ $this->activeListener = '';
+ }//end foreach
+ }//end foreach
+
+ // If short open tags are off but the file being checked uses
+ // short open tags, the whole content will be inline HTML
+ // and nothing will be checked. So try and handle this case.
+ // We don't show this error for STDIN because we can't be sure the content
+ // actually came directly from the user. It could be something like
+ // refs from a Git pre-push hook.
+ if ($foundCode === false && $this->tokenizerType === 'PHP' && $this->path !== 'STDIN') {
+ $shortTags = (bool) ini_get('short_open_tag');
+ if ($shortTags === false) {
+ $error = 'No PHP code was found in this file and short open tags are not allowed by this install of PHP. This file may be using short open tags but PHP does not allow them.';
+ $this->addWarning($error, null, 'Internal.NoCodeFound');
+ }
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
+ echo "\t*** END TOKEN PROCESSING ***".PHP_EOL;
+ echo "\t*** START SNIFF PROCESSING REPORT ***".PHP_EOL;
+
+ asort($this->listenerTimes, SORT_NUMERIC);
+ $this->listenerTimes = array_reverse($this->listenerTimes, true);
+ foreach ($this->listenerTimes as $listener => $timeTaken) {
+ echo "\t$listener: ".round(($timeTaken), 4).' secs'.PHP_EOL;
+ }
+
+ echo "\t*** END SNIFF PROCESSING REPORT ***".PHP_EOL;
+ }
+
+ $this->fixedCount += $this->fixer->getFixCount();
+
+ }//end process()
+
+
+ /**
+ * Tokenizes the file and prepares it for the test run.
+ *
+ * @return void
+ */
+ public function parse()
+ {
+ if (empty($this->tokens) === false) {
+ // File has already been parsed.
+ return;
+ }
+
+ try {
+ $tokenizerClass = 'PHP_CodeSniffer\Tokenizers\\'.$this->tokenizerType;
+ $this->tokenizer = new $tokenizerClass($this->content, $this->config, $this->eolChar);
+ $this->tokens = $this->tokenizer->getTokens();
+ } catch (TokenizerException $e) {
+ $this->ignored = true;
+ $this->addWarning($e->getMessage(), null, 'Internal.Tokenizer.Exception');
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
+ echo "[$this->tokenizerType => tokenizer error]... ";
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo PHP_EOL;
+ }
+ }
+
+ return;
+ }
+
+ $this->numTokens = count($this->tokens);
+
+ // Check for mixed line endings as these can cause tokenizer errors and we
+ // should let the user know that the results they get may be incorrect.
+ // This is done by removing all backslashes, removing the newline char we
+ // detected, then converting newlines chars into text. If any backslashes
+ // are left at the end, we have additional newline chars in use.
+ $contents = str_replace('\\', '', $this->content);
+ $contents = str_replace($this->eolChar, '', $contents);
+ $contents = str_replace("\n", '\n', $contents);
+ $contents = str_replace("\r", '\r', $contents);
+ if (strpos($contents, '\\') !== false) {
+ $error = 'File has mixed line endings; this may cause incorrect results';
+ $this->addWarningOnLine($error, 1, 'Internal.LineEndings.Mixed');
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
+ if ($this->numTokens === 0) {
+ $numLines = 0;
+ } else {
+ $numLines = $this->tokens[($this->numTokens - 1)]['line'];
+ }
+
+ echo "[$this->tokenizerType => $this->numTokens tokens in $numLines lines]... ";
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo PHP_EOL;
+ }
+ }
+
+ }//end parse()
+
+
+ /**
+ * Returns the token stack for this file.
+ *
+ * @return array
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+
+ }//end getTokens()
+
+
+ /**
+ * Remove vars stored in this file that are no longer required.
+ *
+ * @return void
+ */
+ public function cleanUp()
+ {
+ $this->listenerTimes = null;
+ $this->content = null;
+ $this->tokens = null;
+ $this->metricTokens = null;
+ $this->tokenizer = null;
+ $this->fixer = null;
+ $this->config = null;
+ $this->ruleset = null;
+
+ }//end cleanUp()
+
+
+ /**
+ * Records an error against a specific token in the file.
+ *
+ * @param string $error The error message.
+ * @param int $stackPtr The stack position where the error occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the error message.
+ * @param int $severity The severity level for this error. A value of 0
+ * will be converted into the default severity level.
+ * @param boolean $fixable Can the error be fixed by the sniff?
+ *
+ * @return boolean
+ */
+ public function addError(
+ $error,
+ $stackPtr,
+ $code,
+ $data=[],
+ $severity=0,
+ $fixable=false
+ ) {
+ if ($stackPtr === null) {
+ $line = 1;
+ $column = 1;
+ } else {
+ $line = $this->tokens[$stackPtr]['line'];
+ $column = $this->tokens[$stackPtr]['column'];
+ }
+
+ return $this->addMessage(true, $error, $line, $column, $code, $data, $severity, $fixable);
+
+ }//end addError()
+
+
+ /**
+ * Records a warning against a specific token in the file.
+ *
+ * @param string $warning The error message.
+ * @param int $stackPtr The stack position where the error occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the warning message.
+ * @param int $severity The severity level for this warning. A value of 0
+ * will be converted into the default severity level.
+ * @param boolean $fixable Can the warning be fixed by the sniff?
+ *
+ * @return boolean
+ */
+ public function addWarning(
+ $warning,
+ $stackPtr,
+ $code,
+ $data=[],
+ $severity=0,
+ $fixable=false
+ ) {
+ if ($stackPtr === null) {
+ $line = 1;
+ $column = 1;
+ } else {
+ $line = $this->tokens[$stackPtr]['line'];
+ $column = $this->tokens[$stackPtr]['column'];
+ }
+
+ return $this->addMessage(false, $warning, $line, $column, $code, $data, $severity, $fixable);
+
+ }//end addWarning()
+
+
+ /**
+ * Records an error against a specific line in the file.
+ *
+ * @param string $error The error message.
+ * @param int $line The line on which the error occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the error message.
+ * @param int $severity The severity level for this error. A value of 0
+ * will be converted into the default severity level.
+ *
+ * @return boolean
+ */
+ public function addErrorOnLine(
+ $error,
+ $line,
+ $code,
+ $data=[],
+ $severity=0
+ ) {
+ return $this->addMessage(true, $error, $line, 1, $code, $data, $severity, false);
+
+ }//end addErrorOnLine()
+
+
+ /**
+ * Records a warning against a specific token in the file.
+ *
+ * @param string $warning The error message.
+ * @param int $line The line on which the warning occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the warning message.
+ * @param int $severity The severity level for this warning. A value of 0 will
+ * will be converted into the default severity level.
+ *
+ * @return boolean
+ */
+ public function addWarningOnLine(
+ $warning,
+ $line,
+ $code,
+ $data=[],
+ $severity=0
+ ) {
+ return $this->addMessage(false, $warning, $line, 1, $code, $data, $severity, false);
+
+ }//end addWarningOnLine()
+
+
+ /**
+ * Records a fixable error against a specific token in the file.
+ *
+ * Returns true if the error was recorded and should be fixed.
+ *
+ * @param string $error The error message.
+ * @param int $stackPtr The stack position where the error occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the error message.
+ * @param int $severity The severity level for this error. A value of 0
+ * will be converted into the default severity level.
+ *
+ * @return boolean
+ */
+ public function addFixableError(
+ $error,
+ $stackPtr,
+ $code,
+ $data=[],
+ $severity=0
+ ) {
+ $recorded = $this->addError($error, $stackPtr, $code, $data, $severity, true);
+ if ($recorded === true && $this->fixer->enabled === true) {
+ return true;
+ }
+
+ return false;
+
+ }//end addFixableError()
+
+
+ /**
+ * Records a fixable warning against a specific token in the file.
+ *
+ * Returns true if the warning was recorded and should be fixed.
+ *
+ * @param string $warning The error message.
+ * @param int $stackPtr The stack position where the error occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the warning message.
+ * @param int $severity The severity level for this warning. A value of 0
+ * will be converted into the default severity level.
+ *
+ * @return boolean
+ */
+ public function addFixableWarning(
+ $warning,
+ $stackPtr,
+ $code,
+ $data=[],
+ $severity=0
+ ) {
+ $recorded = $this->addWarning($warning, $stackPtr, $code, $data, $severity, true);
+ if ($recorded === true && $this->fixer->enabled === true) {
+ return true;
+ }
+
+ return false;
+
+ }//end addFixableWarning()
+
+
+ /**
+ * Adds an error to the error stack.
+ *
+ * @param boolean $error Is this an error message?
+ * @param string $message The text of the message.
+ * @param int $line The line on which the message occurred.
+ * @param int $column The column at which the message occurred.
+ * @param string $code A violation code unique to the sniff message.
+ * @param array $data Replacements for the message.
+ * @param int $severity The severity level for this message. A value of 0
+ * will be converted into the default severity level.
+ * @param boolean $fixable Can the problem be fixed by the sniff?
+ *
+ * @return boolean
+ */
+ protected function addMessage($error, $message, $line, $column, $code, $data, $severity, $fixable)
+ {
+ // Check if this line is ignoring all message codes.
+ if (isset($this->tokenizer->ignoredLines[$line]['.all']) === true) {
+ return false;
+ }
+
+ // Work out which sniff generated the message.
+ $parts = explode('.', $code);
+ if ($parts[0] === 'Internal') {
+ // An internal message.
+ $listenerCode = Util\Common::getSniffCode($this->activeListener);
+ $sniffCode = $code;
+ $checkCodes = [$sniffCode];
+ } else {
+ if ($parts[0] !== $code) {
+ // The full message code has been passed in.
+ $sniffCode = $code;
+ $listenerCode = substr($sniffCode, 0, strrpos($sniffCode, '.'));
+ } else {
+ $listenerCode = Util\Common::getSniffCode($this->activeListener);
+ $sniffCode = $listenerCode.'.'.$code;
+ $parts = explode('.', $sniffCode);
+ }
+
+ $checkCodes = [
+ $sniffCode,
+ $parts[0].'.'.$parts[1].'.'.$parts[2],
+ $parts[0].'.'.$parts[1],
+ $parts[0],
+ ];
+ }//end if
+
+ if (isset($this->tokenizer->ignoredLines[$line]) === true) {
+ // Check if this line is ignoring this specific message.
+ $ignored = false;
+ foreach ($checkCodes as $checkCode) {
+ if (isset($this->tokenizer->ignoredLines[$line][$checkCode]) === true) {
+ $ignored = true;
+ break;
+ }
+ }
+
+ // If it is ignored, make sure it's not whitelisted.
+ if ($ignored === true
+ && isset($this->tokenizer->ignoredLines[$line]['.except']) === true
+ ) {
+ foreach ($checkCodes as $checkCode) {
+ if (isset($this->tokenizer->ignoredLines[$line]['.except'][$checkCode]) === true) {
+ $ignored = false;
+ break;
+ }
+ }
+ }
+
+ if ($ignored === true) {
+ return false;
+ }
+ }//end if
+
+ $includeAll = true;
+ if ($this->configCache['cache'] === false
+ || $this->configCache['recordErrors'] === false
+ ) {
+ $includeAll = false;
+ }
+
+ // Filter out any messages for sniffs that shouldn't have run
+ // due to the use of the --sniffs command line argument.
+ if ($includeAll === false
+ && ((empty($this->configCache['sniffs']) === false
+ && in_array(strtolower($listenerCode), $this->configCache['sniffs'], true) === false)
+ || (empty($this->configCache['exclude']) === false
+ && in_array(strtolower($listenerCode), $this->configCache['exclude'], true) === true))
+ ) {
+ return false;
+ }
+
+ // If we know this sniff code is being ignored for this file, return early.
+ foreach ($checkCodes as $checkCode) {
+ if (isset($this->ignoredCodes[$checkCode]) === true) {
+ return false;
+ }
+ }
+
+ $oppositeType = 'warning';
+ if ($error === false) {
+ $oppositeType = 'error';
+ }
+
+ foreach ($checkCodes as $checkCode) {
+ // Make sure this message type has not been set to the opposite message type.
+ if (isset($this->ruleset->ruleset[$checkCode]['type']) === true
+ && $this->ruleset->ruleset[$checkCode]['type'] === $oppositeType
+ ) {
+ $error = !$error;
+ break;
+ }
+ }
+
+ if ($error === true) {
+ $configSeverity = $this->configCache['errorSeverity'];
+ $messageCount = &$this->errorCount;
+ $messages = &$this->errors;
+ } else {
+ $configSeverity = $this->configCache['warningSeverity'];
+ $messageCount = &$this->warningCount;
+ $messages = &$this->warnings;
+ }
+
+ if ($includeAll === false && $configSeverity === 0) {
+ // Don't bother doing any processing as these messages are just going to
+ // be hidden in the reports anyway.
+ return false;
+ }
+
+ if ($severity === 0) {
+ $severity = 5;
+ }
+
+ foreach ($checkCodes as $checkCode) {
+ // Make sure we are interested in this severity level.
+ if (isset($this->ruleset->ruleset[$checkCode]['severity']) === true) {
+ $severity = $this->ruleset->ruleset[$checkCode]['severity'];
+ break;
+ }
+ }
+
+ if ($includeAll === false && $configSeverity > $severity) {
+ return false;
+ }
+
+ // Make sure we are not ignoring this file.
+ $included = null;
+ foreach ($checkCodes as $checkCode) {
+ $patterns = null;
+
+ if (isset($this->configCache['includePatterns'][$checkCode]) === true) {
+ $patterns = $this->configCache['includePatterns'][$checkCode];
+ $excluding = false;
+ } else if (isset($this->configCache['ignorePatterns'][$checkCode]) === true) {
+ $patterns = $this->configCache['ignorePatterns'][$checkCode];
+ $excluding = true;
+ }
+
+ if ($patterns === null) {
+ continue;
+ }
+
+ foreach ($patterns as $pattern => $type) {
+ // While there is support for a type of each pattern
+ // (absolute or relative) we don't actually support it here.
+ $replacements = [
+ '\\,' => ',',
+ '*' => '.*',
+ ];
+
+ // We assume a / directory separator, as do the exclude rules
+ // most developers write, so we need a special case for any system
+ // that is different.
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $replacements['/'] = '\\\\';
+ }
+
+ $pattern = '`'.strtr($pattern, $replacements).'`i';
+ $matched = preg_match($pattern, $this->path);
+
+ if ($matched === 0) {
+ if ($excluding === false && $included === null) {
+ // This file path is not being included.
+ $included = false;
+ }
+
+ continue;
+ }
+
+ if ($excluding === true) {
+ // This file path is being excluded.
+ $this->ignoredCodes[$checkCode] = true;
+ return false;
+ }
+
+ // This file path is being included.
+ $included = true;
+ break;
+ }//end foreach
+ }//end foreach
+
+ if ($included === false) {
+ // There were include rules set, but this file
+ // path didn't match any of them.
+ return false;
+ }
+
+ $messageCount++;
+ if ($fixable === true) {
+ $this->fixableCount++;
+ }
+
+ if ($this->configCache['recordErrors'] === false
+ && $includeAll === false
+ ) {
+ return true;
+ }
+
+ // Work out the error message.
+ if (isset($this->ruleset->ruleset[$sniffCode]['message']) === true) {
+ $message = $this->ruleset->ruleset[$sniffCode]['message'];
+ }
+
+ if (empty($data) === false) {
+ $message = vsprintf($message, $data);
+ }
+
+ if (isset($messages[$line]) === false) {
+ $messages[$line] = [];
+ }
+
+ if (isset($messages[$line][$column]) === false) {
+ $messages[$line][$column] = [];
+ }
+
+ $messages[$line][$column][] = [
+ 'message' => $message,
+ 'source' => $sniffCode,
+ 'listener' => $this->activeListener,
+ 'severity' => $severity,
+ 'fixable' => $fixable,
+ ];
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1
+ && $this->fixer->enabled === true
+ && $fixable === true
+ ) {
+ @ob_end_clean();
+ echo "\tE: [Line $line] $message ($sniffCode)".PHP_EOL;
+ ob_start();
+ }
+
+ return true;
+
+ }//end addMessage()
+
+
+ /**
+ * Record a metric about the file being examined.
+ *
+ * @param int $stackPtr The stack position where the metric was recorded.
+ * @param string $metric The name of the metric being recorded.
+ * @param string $value The value of the metric being recorded.
+ *
+ * @return boolean
+ */
+ public function recordMetric($stackPtr, $metric, $value)
+ {
+ if (isset($this->metrics[$metric]) === false) {
+ $this->metrics[$metric] = ['values' => [$value => 1]];
+ $this->metricTokens[$metric][$stackPtr] = true;
+ } else if (isset($this->metricTokens[$metric][$stackPtr]) === false) {
+ $this->metricTokens[$metric][$stackPtr] = true;
+ if (isset($this->metrics[$metric]['values'][$value]) === false) {
+ $this->metrics[$metric]['values'][$value] = 1;
+ } else {
+ $this->metrics[$metric]['values'][$value]++;
+ }
+ }
+
+ return true;
+
+ }//end recordMetric()
+
+
+ /**
+ * Returns the number of errors raised.
+ *
+ * @return int
+ */
+ public function getErrorCount()
+ {
+ return $this->errorCount;
+
+ }//end getErrorCount()
+
+
+ /**
+ * Returns the number of warnings raised.
+ *
+ * @return int
+ */
+ public function getWarningCount()
+ {
+ return $this->warningCount;
+
+ }//end getWarningCount()
+
+
+ /**
+ * Returns the number of fixable errors/warnings raised.
+ *
+ * @return int
+ */
+ public function getFixableCount()
+ {
+ return $this->fixableCount;
+
+ }//end getFixableCount()
+
+
+ /**
+ * Returns the number of fixed errors/warnings.
+ *
+ * @return int
+ */
+ public function getFixedCount()
+ {
+ return $this->fixedCount;
+
+ }//end getFixedCount()
+
+
+ /**
+ * Returns the list of ignored lines.
+ *
+ * @return array
+ */
+ public function getIgnoredLines()
+ {
+ return $this->tokenizer->ignoredLines;
+
+ }//end getIgnoredLines()
+
+
+ /**
+ * Returns the errors raised from processing this file.
+ *
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->errors;
+
+ }//end getErrors()
+
+
+ /**
+ * Returns the warnings raised from processing this file.
+ *
+ * @return array
+ */
+ public function getWarnings()
+ {
+ return $this->warnings;
+
+ }//end getWarnings()
+
+
+ /**
+ * Returns the metrics found while processing this file.
+ *
+ * @return array
+ */
+ public function getMetrics()
+ {
+ return $this->metrics;
+
+ }//end getMetrics()
+
+
+ /**
+ * Returns the absolute filename of this file.
+ *
+ * @return string
+ */
+ public function getFilename()
+ {
+ return $this->path;
+
+ }//end getFilename()
+
+
+ /**
+ * Returns the declaration names for classes, interfaces, traits, and functions.
+ *
+ * @param int $stackPtr The position of the declaration token which
+ * declared the class, interface, trait, or function.
+ *
+ * @return string|null The name of the class, interface, trait, or function;
+ * or NULL if the function or class is anonymous.
+ * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified token is not of type
+ * T_FUNCTION, T_CLASS, T_ANON_CLASS,
+ * T_CLOSURE, T_TRAIT, or T_INTERFACE.
+ */
+ public function getDeclarationName($stackPtr)
+ {
+ $tokenCode = $this->tokens[$stackPtr]['code'];
+
+ if ($tokenCode === T_ANON_CLASS || $tokenCode === T_CLOSURE) {
+ return null;
+ }
+
+ if ($tokenCode !== T_FUNCTION
+ && $tokenCode !== T_CLASS
+ && $tokenCode !== T_INTERFACE
+ && $tokenCode !== T_TRAIT
+ ) {
+ throw new RuntimeException('Token type "'.$this->tokens[$stackPtr]['type'].'" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT');
+ }
+
+ if ($tokenCode === T_FUNCTION
+ && strtolower($this->tokens[$stackPtr]['content']) !== 'function'
+ ) {
+ // This is a function declared without the "function" keyword.
+ // So this token is the function name.
+ return $this->tokens[$stackPtr]['content'];
+ }
+
+ $content = null;
+ for ($i = $stackPtr; $i < $this->numTokens; $i++) {
+ if ($this->tokens[$i]['code'] === T_STRING) {
+ $content = $this->tokens[$i]['content'];
+ break;
+ }
+ }
+
+ return $content;
+
+ }//end getDeclarationName()
+
+
+ /**
+ * Returns the method parameters for the specified function token.
+ *
+ * Each parameter is in the following format:
+ *
+ *
+ * 0 => array(
+ * 'name' => '$var', // The variable name.
+ * 'token' => integer, // The stack pointer to the variable name.
+ * 'content' => string, // The full content of the variable definition.
+ * 'pass_by_reference' => boolean, // Is the variable passed by reference?
+ * 'variable_length' => boolean, // Is the param of variable length through use of `...` ?
+ * 'type_hint' => string, // The type hint for the variable.
+ * 'type_hint_token' => integer, // The stack pointer to the type hint
+ * // or false if there is no type hint.
+ * 'nullable_type' => boolean, // Is the variable using a nullable type?
+ * )
+ *
+ *
+ * Parameters with default values have an additional array index of
+ * 'default' with the value of the default as a string.
+ *
+ * @param int $stackPtr The position in the stack of the function token
+ * to acquire the parameters for.
+ *
+ * @return array
+ * @throws \PHP_CodeSniffer\Exceptions\TokenizerException If the specified $stackPtr is not of
+ * type T_FUNCTION or T_CLOSURE.
+ */
+ public function getMethodParameters($stackPtr)
+ {
+ if ($this->tokens[$stackPtr]['code'] !== T_FUNCTION
+ && $this->tokens[$stackPtr]['code'] !== T_CLOSURE
+ ) {
+ throw new TokenizerException('$stackPtr must be of type T_FUNCTION or T_CLOSURE');
+ }
+
+ $opener = $this->tokens[$stackPtr]['parenthesis_opener'];
+ $closer = $this->tokens[$stackPtr]['parenthesis_closer'];
+
+ $vars = [];
+ $currVar = null;
+ $paramStart = ($opener + 1);
+ $defaultStart = null;
+ $paramCount = 0;
+ $passByReference = false;
+ $variableLength = false;
+ $typeHint = '';
+ $typeHintToken = false;
+ $nullableType = false;
+
+ for ($i = $paramStart; $i <= $closer; $i++) {
+ // Check to see if this token has a parenthesis or bracket opener. If it does
+ // it's likely to be an array which might have arguments in it. This
+ // could cause problems in our parsing below, so lets just skip to the
+ // end of it.
+ if (isset($this->tokens[$i]['parenthesis_opener']) === true) {
+ // Don't do this if it's the close parenthesis for the method.
+ if ($i !== $this->tokens[$i]['parenthesis_closer']) {
+ $i = ($this->tokens[$i]['parenthesis_closer'] + 1);
+ }
+ }
+
+ if (isset($this->tokens[$i]['bracket_opener']) === true) {
+ // Don't do this if it's the close parenthesis for the method.
+ if ($i !== $this->tokens[$i]['bracket_closer']) {
+ $i = ($this->tokens[$i]['bracket_closer'] + 1);
+ }
+ }
+
+ switch ($this->tokens[$i]['code']) {
+ case T_BITWISE_AND:
+ if ($defaultStart === null) {
+ $passByReference = true;
+ }
+ break;
+ case T_VARIABLE:
+ $currVar = $i;
+ break;
+ case T_ELLIPSIS:
+ $variableLength = true;
+ break;
+ case T_CALLABLE:
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $this->tokens[$i]['content'];
+ break;
+ case T_SELF:
+ case T_PARENT:
+ case T_STATIC:
+ // Self and parent are valid, static invalid, but was probably intended as type hint.
+ if (isset($defaultStart) === false) {
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $this->tokens[$i]['content'];
+ }
+ break;
+ case T_STRING:
+ // This is a string, so it may be a type hint, but it could
+ // also be a constant used as a default value.
+ $prevComma = false;
+ for ($t = $i; $t >= $opener; $t--) {
+ if ($this->tokens[$t]['code'] === T_COMMA) {
+ $prevComma = $t;
+ break;
+ }
+ }
+
+ if ($prevComma !== false) {
+ $nextEquals = false;
+ for ($t = $prevComma; $t < $i; $t++) {
+ if ($this->tokens[$t]['code'] === T_EQUAL) {
+ $nextEquals = $t;
+ break;
+ }
+ }
+
+ if ($nextEquals !== false) {
+ break;
+ }
+ }
+
+ if ($defaultStart === null) {
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $this->tokens[$i]['content'];
+ }
+ break;
+ case T_NS_SEPARATOR:
+ // Part of a type hint or default value.
+ if ($defaultStart === null) {
+ if ($typeHintToken === false) {
+ $typeHintToken = $i;
+ }
+
+ $typeHint .= $this->tokens[$i]['content'];
+ }
+ break;
+ case T_NULLABLE:
+ if ($defaultStart === null) {
+ $nullableType = true;
+ $typeHint .= $this->tokens[$i]['content'];
+ }
+ break;
+ case T_CLOSE_PARENTHESIS:
+ case T_COMMA:
+ // If it's null, then there must be no parameters for this
+ // method.
+ if ($currVar === null) {
+ continue 2;
+ }
+
+ $vars[$paramCount] = [];
+ $vars[$paramCount]['token'] = $currVar;
+ $vars[$paramCount]['name'] = $this->tokens[$currVar]['content'];
+ $vars[$paramCount]['content'] = trim($this->getTokensAsString($paramStart, ($i - $paramStart)));
+
+ if ($defaultStart !== null) {
+ $vars[$paramCount]['default'] = trim($this->getTokensAsString($defaultStart, ($i - $defaultStart)));
+ }
+
+ $vars[$paramCount]['pass_by_reference'] = $passByReference;
+ $vars[$paramCount]['variable_length'] = $variableLength;
+ $vars[$paramCount]['type_hint'] = $typeHint;
+ $vars[$paramCount]['type_hint_token'] = $typeHintToken;
+ $vars[$paramCount]['nullable_type'] = $nullableType;
+
+ // Reset the vars, as we are about to process the next parameter.
+ $defaultStart = null;
+ $paramStart = ($i + 1);
+ $passByReference = false;
+ $variableLength = false;
+ $typeHint = '';
+ $typeHintToken = false;
+ $nullableType = false;
+
+ $paramCount++;
+ break;
+ case T_EQUAL:
+ $defaultStart = ($i + 1);
+ break;
+ }//end switch
+ }//end for
+
+ return $vars;
+
+ }//end getMethodParameters()
+
+
+ /**
+ * Returns the visibility and implementation properties of a method.
+ *
+ * The format of the array is:
+ *
+ * array(
+ * 'scope' => 'public', // public protected or protected
+ * 'scope_specified' => true, // true is scope keyword was found.
+ * 'return_type' => '', // the return type of the method.
+ * 'return_type_token' => integer, // The stack pointer to the start of the return type
+ * // or false if there is no return type.
+ * 'nullable_return_type' => false, // true if the return type is nullable.
+ * 'is_abstract' => false, // true if the abstract keyword was found.
+ * 'is_final' => false, // true if the final keyword was found.
+ * 'is_static' => false, // true if the static keyword was found.
+ * 'has_body' => false, // true if the method has a body
+ * );
+ *
+ *
+ * @param int $stackPtr The position in the stack of the function token to
+ * acquire the properties for.
+ *
+ * @return array
+ * @throws \PHP_CodeSniffer\Exceptions\TokenizerException If the specified position is not a
+ * T_FUNCTION token.
+ */
+ public function getMethodProperties($stackPtr)
+ {
+ if ($this->tokens[$stackPtr]['code'] !== T_FUNCTION
+ && $this->tokens[$stackPtr]['code'] !== T_CLOSURE
+ ) {
+ throw new TokenizerException('$stackPtr must be of type T_FUNCTION or T_CLOSURE');
+ }
+
+ if ($this->tokens[$stackPtr]['code'] === T_FUNCTION) {
+ $valid = [
+ T_PUBLIC => T_PUBLIC,
+ T_PRIVATE => T_PRIVATE,
+ T_PROTECTED => T_PROTECTED,
+ T_STATIC => T_STATIC,
+ T_FINAL => T_FINAL,
+ T_ABSTRACT => T_ABSTRACT,
+ T_WHITESPACE => T_WHITESPACE,
+ T_COMMENT => T_COMMENT,
+ T_DOC_COMMENT => T_DOC_COMMENT,
+ ];
+ } else {
+ $valid = [
+ T_STATIC => T_STATIC,
+ T_WHITESPACE => T_WHITESPACE,
+ T_COMMENT => T_COMMENT,
+ T_DOC_COMMENT => T_DOC_COMMENT,
+ ];
+ }
+
+ $scope = 'public';
+ $scopeSpecified = false;
+ $isAbstract = false;
+ $isFinal = false;
+ $isStatic = false;
+
+ for ($i = ($stackPtr - 1); $i > 0; $i--) {
+ if (isset($valid[$this->tokens[$i]['code']]) === false) {
+ break;
+ }
+
+ switch ($this->tokens[$i]['code']) {
+ case T_PUBLIC:
+ $scope = 'public';
+ $scopeSpecified = true;
+ break;
+ case T_PRIVATE:
+ $scope = 'private';
+ $scopeSpecified = true;
+ break;
+ case T_PROTECTED:
+ $scope = 'protected';
+ $scopeSpecified = true;
+ break;
+ case T_ABSTRACT:
+ $isAbstract = true;
+ break;
+ case T_FINAL:
+ $isFinal = true;
+ break;
+ case T_STATIC:
+ $isStatic = true;
+ break;
+ }//end switch
+ }//end for
+
+ $returnType = '';
+ $returnTypeToken = false;
+ $nullableReturnType = false;
+ $hasBody = true;
+
+ if (isset($this->tokens[$stackPtr]['parenthesis_closer']) === true) {
+ $scopeOpener = null;
+ if (isset($this->tokens[$stackPtr]['scope_opener']) === true) {
+ $scopeOpener = $this->tokens[$stackPtr]['scope_opener'];
+ }
+
+ $valid = [
+ T_STRING => T_STRING,
+ T_CALLABLE => T_CALLABLE,
+ T_SELF => T_SELF,
+ T_PARENT => T_PARENT,
+ T_NS_SEPARATOR => T_NS_SEPARATOR,
+ ];
+
+ for ($i = $this->tokens[$stackPtr]['parenthesis_closer']; $i < $this->numTokens; $i++) {
+ if (($scopeOpener === null && $this->tokens[$i]['code'] === T_SEMICOLON)
+ || ($scopeOpener !== null && $i === $scopeOpener)
+ ) {
+ // End of function definition.
+ break;
+ }
+
+ if ($this->tokens[$i]['code'] === T_NULLABLE) {
+ $nullableReturnType = true;
+ }
+
+ if (isset($valid[$this->tokens[$i]['code']]) === true) {
+ if ($returnTypeToken === false) {
+ $returnTypeToken = $i;
+ }
+
+ $returnType .= $this->tokens[$i]['content'];
+ }
+ }
+
+ $end = $this->findNext([T_OPEN_CURLY_BRACKET, T_SEMICOLON], $this->tokens[$stackPtr]['parenthesis_closer']);
+ $hasBody = $this->tokens[$end]['code'] === T_OPEN_CURLY_BRACKET;
+ }//end if
+
+ if ($returnType !== '' && $nullableReturnType === true) {
+ $returnType = '?'.$returnType;
+ }
+
+ return [
+ 'scope' => $scope,
+ 'scope_specified' => $scopeSpecified,
+ 'return_type' => $returnType,
+ 'return_type_token' => $returnTypeToken,
+ 'nullable_return_type' => $nullableReturnType,
+ 'is_abstract' => $isAbstract,
+ 'is_final' => $isFinal,
+ 'is_static' => $isStatic,
+ 'has_body' => $hasBody,
+ ];
+
+ }//end getMethodProperties()
+
+
+ /**
+ * Returns the visibility and implementation properties of the class member
+ * variable found at the specified position in the stack.
+ *
+ * The format of the array is:
+ *
+ *
+ * array(
+ * 'scope' => 'public', // public protected or protected.
+ * 'scope_specified' => false, // true if the scope was explicitly specified.
+ * 'is_static' => false, // true if the static keyword was found.
+ * );
+ *
+ *
+ * @param int $stackPtr The position in the stack of the T_VARIABLE token to
+ * acquire the properties for.
+ *
+ * @return array
+ * @throws \PHP_CodeSniffer\Exceptions\TokenizerException If the specified position is not a
+ * T_VARIABLE token, or if the position is not
+ * a class member variable.
+ */
+ public function getMemberProperties($stackPtr)
+ {
+ if ($this->tokens[$stackPtr]['code'] !== T_VARIABLE) {
+ throw new TokenizerException('$stackPtr must be of type T_VARIABLE');
+ }
+
+ $conditions = array_keys($this->tokens[$stackPtr]['conditions']);
+ $ptr = array_pop($conditions);
+ if (isset($this->tokens[$ptr]) === false
+ || ($this->tokens[$ptr]['code'] !== T_CLASS
+ && $this->tokens[$ptr]['code'] !== T_ANON_CLASS
+ && $this->tokens[$ptr]['code'] !== T_TRAIT)
+ ) {
+ if (isset($this->tokens[$ptr]) === true
+ && $this->tokens[$ptr]['code'] === T_INTERFACE
+ ) {
+ // T_VARIABLEs in interfaces can actually be method arguments
+ // but they wont be seen as being inside the method because there
+ // are no scope openers and closers for abstract methods. If it is in
+ // parentheses, we can be pretty sure it is a method argument.
+ if (isset($this->tokens[$stackPtr]['nested_parenthesis']) === false
+ || empty($this->tokens[$stackPtr]['nested_parenthesis']) === true
+ ) {
+ $error = 'Possible parse error: interfaces may not include member vars';
+ $this->addWarning($error, $stackPtr, 'Internal.ParseError.InterfaceHasMemberVar');
+ return [];
+ }
+ } else {
+ throw new TokenizerException('$stackPtr is not a class member var');
+ }
+ }
+
+ // Make sure it's not a method parameter.
+ if (empty($this->tokens[$stackPtr]['nested_parenthesis']) === false) {
+ $parenthesis = array_keys($this->tokens[$stackPtr]['nested_parenthesis']);
+ $deepestOpen = array_pop($parenthesis);
+ if ($deepestOpen > $ptr
+ && isset($this->tokens[$deepestOpen]['parenthesis_owner']) === true
+ && $this->tokens[$this->tokens[$deepestOpen]['parenthesis_owner']]['code'] === T_FUNCTION
+ ) {
+ throw new TokenizerException('$stackPtr is not a class member var');
+ }
+ }
+
+ $valid = [
+ T_PUBLIC => T_PUBLIC,
+ T_PRIVATE => T_PRIVATE,
+ T_PROTECTED => T_PROTECTED,
+ T_STATIC => T_STATIC,
+ T_VAR => T_VAR,
+ ];
+
+ $valid += Util\Tokens::$emptyTokens;
+
+ $scope = 'public';
+ $scopeSpecified = false;
+ $isStatic = false;
+
+ $startOfStatement = $this->findPrevious(
+ [
+ T_SEMICOLON,
+ T_OPEN_CURLY_BRACKET,
+ T_CLOSE_CURLY_BRACKET,
+ ],
+ ($stackPtr - 1)
+ );
+
+ for ($i = ($startOfStatement + 1); $i < $stackPtr; $i++) {
+ if (isset($valid[$this->tokens[$i]['code']]) === false) {
+ break;
+ }
+
+ switch ($this->tokens[$i]['code']) {
+ case T_PUBLIC:
+ $scope = 'public';
+ $scopeSpecified = true;
+ break;
+ case T_PRIVATE:
+ $scope = 'private';
+ $scopeSpecified = true;
+ break;
+ case T_PROTECTED:
+ $scope = 'protected';
+ $scopeSpecified = true;
+ break;
+ case T_STATIC:
+ $isStatic = true;
+ break;
+ }
+ }//end for
+
+ return [
+ 'scope' => $scope,
+ 'scope_specified' => $scopeSpecified,
+ 'is_static' => $isStatic,
+ ];
+
+ }//end getMemberProperties()
+
+
+ /**
+ * Returns the visibility and implementation properties of a class.
+ *
+ * The format of the array is:
+ *
+ * array(
+ * 'is_abstract' => false, // true if the abstract keyword was found.
+ * 'is_final' => false, // true if the final keyword was found.
+ * );
+ *
+ *
+ * @param int $stackPtr The position in the stack of the T_CLASS token to
+ * acquire the properties for.
+ *
+ * @return array
+ * @throws \PHP_CodeSniffer\Exceptions\TokenizerException If the specified position is not a
+ * T_CLASS token.
+ */
+ public function getClassProperties($stackPtr)
+ {
+ if ($this->tokens[$stackPtr]['code'] !== T_CLASS) {
+ throw new TokenizerException('$stackPtr must be of type T_CLASS');
+ }
+
+ $valid = [
+ T_FINAL => T_FINAL,
+ T_ABSTRACT => T_ABSTRACT,
+ T_WHITESPACE => T_WHITESPACE,
+ T_COMMENT => T_COMMENT,
+ T_DOC_COMMENT => T_DOC_COMMENT,
+ ];
+
+ $isAbstract = false;
+ $isFinal = false;
+
+ for ($i = ($stackPtr - 1); $i > 0; $i--) {
+ if (isset($valid[$this->tokens[$i]['code']]) === false) {
+ break;
+ }
+
+ switch ($this->tokens[$i]['code']) {
+ case T_ABSTRACT:
+ $isAbstract = true;
+ break;
+
+ case T_FINAL:
+ $isFinal = true;
+ break;
+ }
+ }//end for
+
+ return [
+ 'is_abstract' => $isAbstract,
+ 'is_final' => $isFinal,
+ ];
+
+ }//end getClassProperties()
+
+
+ /**
+ * Determine if the passed token is a reference operator.
+ *
+ * Returns true if the specified token position represents a reference.
+ * Returns false if the token represents a bitwise operator.
+ *
+ * @param int $stackPtr The position of the T_BITWISE_AND token.
+ *
+ * @return boolean
+ */
+ public function isReference($stackPtr)
+ {
+ if ($this->tokens[$stackPtr]['code'] !== T_BITWISE_AND) {
+ return false;
+ }
+
+ $tokenBefore = $this->findPrevious(
+ Util\Tokens::$emptyTokens,
+ ($stackPtr - 1),
+ null,
+ true
+ );
+
+ if ($this->tokens[$tokenBefore]['code'] === T_FUNCTION) {
+ // Function returns a reference.
+ return true;
+ }
+
+ if ($this->tokens[$tokenBefore]['code'] === T_DOUBLE_ARROW) {
+ // Inside a foreach loop or array assignment, this is a reference.
+ return true;
+ }
+
+ if ($this->tokens[$tokenBefore]['code'] === T_AS) {
+ // Inside a foreach loop, this is a reference.
+ return true;
+ }
+
+ if (isset(Util\Tokens::$assignmentTokens[$this->tokens[$tokenBefore]['code']]) === true) {
+ // This is directly after an assignment. It's a reference. Even if
+ // it is part of an operation, the other tests will handle it.
+ return true;
+ }
+
+ $tokenAfter = $this->findNext(
+ Util\Tokens::$emptyTokens,
+ ($stackPtr + 1),
+ null,
+ true
+ );
+
+ if ($this->tokens[$tokenAfter]['code'] === T_NEW) {
+ return true;
+ }
+
+ if (isset($this->tokens[$stackPtr]['nested_parenthesis']) === true) {
+ $brackets = $this->tokens[$stackPtr]['nested_parenthesis'];
+ $lastBracket = array_pop($brackets);
+ if (isset($this->tokens[$lastBracket]['parenthesis_owner']) === true) {
+ $owner = $this->tokens[$this->tokens[$lastBracket]['parenthesis_owner']];
+ if ($owner['code'] === T_FUNCTION
+ || $owner['code'] === T_CLOSURE
+ ) {
+ $params = $this->getMethodParameters($this->tokens[$lastBracket]['parenthesis_owner']);
+ foreach ($params as $param) {
+ $varToken = $tokenAfter;
+ if ($param['variable_length'] === true) {
+ $varToken = $this->findNext(
+ (Util\Tokens::$emptyTokens + [T_ELLIPSIS]),
+ ($stackPtr + 1),
+ null,
+ true
+ );
+ }
+
+ if ($param['token'] === $varToken
+ && $param['pass_by_reference'] === true
+ ) {
+ // Function parameter declared to be passed by reference.
+ return true;
+ }
+ }
+ }//end if
+ } else {
+ $prev = false;
+ for ($t = ($this->tokens[$lastBracket]['parenthesis_opener'] - 1); $t >= 0; $t--) {
+ if ($this->tokens[$t]['code'] !== T_WHITESPACE) {
+ $prev = $t;
+ break;
+ }
+ }
+
+ if ($prev !== false && $this->tokens[$prev]['code'] === T_USE) {
+ // Closure use by reference.
+ return true;
+ }
+ }//end if
+ }//end if
+
+ // Pass by reference in function calls and assign by reference in arrays.
+ if ($this->tokens[$tokenBefore]['code'] === T_OPEN_PARENTHESIS
+ || $this->tokens[$tokenBefore]['code'] === T_COMMA
+ || $this->tokens[$tokenBefore]['code'] === T_OPEN_SHORT_ARRAY
+ ) {
+ if ($this->tokens[$tokenAfter]['code'] === T_VARIABLE) {
+ return true;
+ } else {
+ $skip = Util\Tokens::$emptyTokens;
+ $skip[] = T_NS_SEPARATOR;
+ $skip[] = T_SELF;
+ $skip[] = T_PARENT;
+ $skip[] = T_STATIC;
+ $skip[] = T_STRING;
+ $skip[] = T_NAMESPACE;
+ $skip[] = T_DOUBLE_COLON;
+
+ $nextSignificantAfter = $this->findNext(
+ $skip,
+ ($stackPtr + 1),
+ null,
+ true
+ );
+ if ($this->tokens[$nextSignificantAfter]['code'] === T_VARIABLE) {
+ return true;
+ }
+ }//end if
+ }//end if
+
+ return false;
+
+ }//end isReference()
+
+
+ /**
+ * Returns the content of the tokens from the specified start position in
+ * the token stack for the specified length.
+ *
+ * @param int $start The position to start from in the token stack.
+ * @param int $length The length of tokens to traverse from the start pos.
+ * @param bool $origContent Whether the original content or the tab replaced
+ * content should be used.
+ *
+ * @return string The token contents.
+ */
+ public function getTokensAsString($start, $length, $origContent=false)
+ {
+ if (is_int($start) === false || isset($this->tokens[$start]) === false) {
+ throw new RuntimeException('The $start position for getTokensAsString() must exist in the token stack');
+ }
+
+ if (is_int($length) === false || $length <= 0) {
+ return '';
+ }
+
+ $str = '';
+ $end = ($start + $length);
+ if ($end > $this->numTokens) {
+ $end = $this->numTokens;
+ }
+
+ for ($i = $start; $i < $end; $i++) {
+ // If tabs are being converted to spaces by the tokeniser, the
+ // original content should be used instead of the converted content.
+ if ($origContent === true && isset($this->tokens[$i]['orig_content']) === true) {
+ $str .= $this->tokens[$i]['orig_content'];
+ } else {
+ $str .= $this->tokens[$i]['content'];
+ }
+ }
+
+ return $str;
+
+ }//end getTokensAsString()
+
+
+ /**
+ * Returns the position of the previous specified token(s).
+ *
+ * If a value is specified, the previous token of the specified type(s)
+ * containing the specified value will be returned.
+ *
+ * Returns false if no token can be found.
+ *
+ * @param int|string|array $types The type(s) of tokens to search for.
+ * @param int $start The position to start searching from in the
+ * token stack.
+ * @param int $end The end position to fail if no token is found.
+ * if not specified or null, end will default to
+ * the start of the token stack.
+ * @param bool $exclude If true, find the previous token that is NOT of
+ * the types specified in $types.
+ * @param string $value The value that the token(s) must be equal to.
+ * If value is omitted, tokens with any value will
+ * be returned.
+ * @param bool $local If true, tokens outside the current statement
+ * will not be checked. IE. checking will stop
+ * at the previous semi-colon found.
+ *
+ * @return int|bool
+ * @see findNext()
+ */
+ public function findPrevious(
+ $types,
+ $start,
+ $end=null,
+ $exclude=false,
+ $value=null,
+ $local=false
+ ) {
+ $types = (array) $types;
+
+ if ($end === null) {
+ $end = 0;
+ }
+
+ for ($i = $start; $i >= $end; $i--) {
+ $found = (bool) $exclude;
+ foreach ($types as $type) {
+ if ($this->tokens[$i]['code'] === $type) {
+ $found = !$exclude;
+ break;
+ }
+ }
+
+ if ($found === true) {
+ if ($value === null) {
+ return $i;
+ } else if ($this->tokens[$i]['content'] === $value) {
+ return $i;
+ }
+ }
+
+ if ($local === true) {
+ if (isset($this->tokens[$i]['scope_opener']) === true
+ && $i === $this->tokens[$i]['scope_closer']
+ ) {
+ $i = $this->tokens[$i]['scope_opener'];
+ } else if (isset($this->tokens[$i]['bracket_opener']) === true
+ && $i === $this->tokens[$i]['bracket_closer']
+ ) {
+ $i = $this->tokens[$i]['bracket_opener'];
+ } else if (isset($this->tokens[$i]['parenthesis_opener']) === true
+ && $i === $this->tokens[$i]['parenthesis_closer']
+ ) {
+ $i = $this->tokens[$i]['parenthesis_opener'];
+ } else if ($this->tokens[$i]['code'] === T_SEMICOLON) {
+ break;
+ }
+ }
+ }//end for
+
+ return false;
+
+ }//end findPrevious()
+
+
+ /**
+ * Returns the position of the next specified token(s).
+ *
+ * If a value is specified, the next token of the specified type(s)
+ * containing the specified value will be returned.
+ *
+ * Returns false if no token can be found.
+ *
+ * @param int|string|array $types The type(s) of tokens to search for.
+ * @param int $start The position to start searching from in the
+ * token stack.
+ * @param int $end The end position to fail if no token is found.
+ * if not specified or null, end will default to
+ * the end of the token stack.
+ * @param bool $exclude If true, find the next token that is NOT of
+ * a type specified in $types.
+ * @param string $value The value that the token(s) must be equal to.
+ * If value is omitted, tokens with any value will
+ * be returned.
+ * @param bool $local If true, tokens outside the current statement
+ * will not be checked. i.e., checking will stop
+ * at the next semi-colon found.
+ *
+ * @return int|bool
+ * @see findPrevious()
+ */
+ public function findNext(
+ $types,
+ $start,
+ $end=null,
+ $exclude=false,
+ $value=null,
+ $local=false
+ ) {
+ $types = (array) $types;
+
+ if ($end === null || $end > $this->numTokens) {
+ $end = $this->numTokens;
+ }
+
+ for ($i = $start; $i < $end; $i++) {
+ $found = (bool) $exclude;
+ foreach ($types as $type) {
+ if ($this->tokens[$i]['code'] === $type) {
+ $found = !$exclude;
+ break;
+ }
+ }
+
+ if ($found === true) {
+ if ($value === null) {
+ return $i;
+ } else if ($this->tokens[$i]['content'] === $value) {
+ return $i;
+ }
+ }
+
+ if ($local === true && $this->tokens[$i]['code'] === T_SEMICOLON) {
+ break;
+ }
+ }//end for
+
+ return false;
+
+ }//end findNext()
+
+
+ /**
+ * Returns the position of the first non-whitespace token in a statement.
+ *
+ * @param int $start The position to start searching from in the token stack.
+ * @param int|array $ignore Token types that should not be considered stop points.
+ *
+ * @return int
+ */
+ public function findStartOfStatement($start, $ignore=null)
+ {
+ $endTokens = Util\Tokens::$blockOpeners;
+
+ $endTokens[T_COLON] = true;
+ $endTokens[T_COMMA] = true;
+ $endTokens[T_DOUBLE_ARROW] = true;
+ $endTokens[T_SEMICOLON] = true;
+ $endTokens[T_OPEN_TAG] = true;
+ $endTokens[T_CLOSE_TAG] = true;
+ $endTokens[T_OPEN_SHORT_ARRAY] = true;
+
+ if ($ignore !== null) {
+ $ignore = (array) $ignore;
+ foreach ($ignore as $code) {
+ unset($endTokens[$code]);
+ }
+ }
+
+ $lastNotEmpty = $start;
+
+ for ($i = $start; $i >= 0; $i--) {
+ if (isset($endTokens[$this->tokens[$i]['code']]) === true) {
+ // Found the end of the previous statement.
+ return $lastNotEmpty;
+ }
+
+ if (isset($this->tokens[$i]['scope_opener']) === true
+ && $i === $this->tokens[$i]['scope_closer']
+ ) {
+ // Found the end of the previous scope block.
+ return $lastNotEmpty;
+ }
+
+ // Skip nested statements.
+ if (isset($this->tokens[$i]['bracket_opener']) === true
+ && $i === $this->tokens[$i]['bracket_closer']
+ ) {
+ $i = $this->tokens[$i]['bracket_opener'];
+ } else if (isset($this->tokens[$i]['parenthesis_opener']) === true
+ && $i === $this->tokens[$i]['parenthesis_closer']
+ ) {
+ $i = $this->tokens[$i]['parenthesis_opener'];
+ }
+
+ if (isset(Util\Tokens::$emptyTokens[$this->tokens[$i]['code']]) === false) {
+ $lastNotEmpty = $i;
+ }
+ }//end for
+
+ return 0;
+
+ }//end findStartOfStatement()
+
+
+ /**
+ * Returns the position of the last non-whitespace token in a statement.
+ *
+ * @param int $start The position to start searching from in the token stack.
+ * @param int|array $ignore Token types that should not be considered stop points.
+ *
+ * @return int
+ */
+ public function findEndOfStatement($start, $ignore=null)
+ {
+ $endTokens = [
+ T_COLON => true,
+ T_COMMA => true,
+ T_DOUBLE_ARROW => true,
+ T_SEMICOLON => true,
+ T_CLOSE_PARENTHESIS => true,
+ T_CLOSE_SQUARE_BRACKET => true,
+ T_CLOSE_CURLY_BRACKET => true,
+ T_CLOSE_SHORT_ARRAY => true,
+ T_OPEN_TAG => true,
+ T_CLOSE_TAG => true,
+ ];
+
+ if ($ignore !== null) {
+ $ignore = (array) $ignore;
+ foreach ($ignore as $code) {
+ unset($endTokens[$code]);
+ }
+ }
+
+ $lastNotEmpty = $start;
+
+ for ($i = $start; $i < $this->numTokens; $i++) {
+ if ($i !== $start && isset($endTokens[$this->tokens[$i]['code']]) === true) {
+ // Found the end of the statement.
+ if ($this->tokens[$i]['code'] === T_CLOSE_PARENTHESIS
+ || $this->tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET
+ || $this->tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET
+ || $this->tokens[$i]['code'] === T_CLOSE_SHORT_ARRAY
+ || $this->tokens[$i]['code'] === T_OPEN_TAG
+ || $this->tokens[$i]['code'] === T_CLOSE_TAG
+ ) {
+ return $lastNotEmpty;
+ }
+
+ return $i;
+ }
+
+ // Skip nested statements.
+ if (isset($this->tokens[$i]['scope_closer']) === true
+ && ($i === $this->tokens[$i]['scope_opener']
+ || $i === $this->tokens[$i]['scope_condition'])
+ ) {
+ if ($i === $start && isset(Util\Tokens::$scopeOpeners[$this->tokens[$i]['code']]) === true) {
+ return $this->tokens[$i]['scope_closer'];
+ }
+
+ $i = $this->tokens[$i]['scope_closer'];
+ } else if (isset($this->tokens[$i]['bracket_closer']) === true
+ && $i === $this->tokens[$i]['bracket_opener']
+ ) {
+ $i = $this->tokens[$i]['bracket_closer'];
+ } else if (isset($this->tokens[$i]['parenthesis_closer']) === true
+ && $i === $this->tokens[$i]['parenthesis_opener']
+ ) {
+ $i = $this->tokens[$i]['parenthesis_closer'];
+ }
+
+ if (isset(Util\Tokens::$emptyTokens[$this->tokens[$i]['code']]) === false) {
+ $lastNotEmpty = $i;
+ }
+ }//end for
+
+ return ($this->numTokens - 1);
+
+ }//end findEndOfStatement()
+
+
+ /**
+ * Returns the position of the first token on a line, matching given type.
+ *
+ * Returns false if no token can be found.
+ *
+ * @param int|string|array $types The type(s) of tokens to search for.
+ * @param int $start The position to start searching from in the
+ * token stack. The first token matching on
+ * this line before this token will be returned.
+ * @param bool $exclude If true, find the token that is NOT of
+ * the types specified in $types.
+ * @param string $value The value that the token must be equal to.
+ * If value is omitted, tokens with any value will
+ * be returned.
+ *
+ * @return int | bool
+ */
+ public function findFirstOnLine($types, $start, $exclude=false, $value=null)
+ {
+ if (is_array($types) === false) {
+ $types = [$types];
+ }
+
+ $foundToken = false;
+
+ for ($i = $start; $i >= 0; $i--) {
+ if ($this->tokens[$i]['line'] < $this->tokens[$start]['line']) {
+ break;
+ }
+
+ $found = $exclude;
+ foreach ($types as $type) {
+ if ($exclude === false) {
+ if ($this->tokens[$i]['code'] === $type) {
+ $found = true;
+ break;
+ }
+ } else {
+ if ($this->tokens[$i]['code'] === $type) {
+ $found = false;
+ break;
+ }
+ }
+ }
+
+ if ($found === true) {
+ if ($value === null) {
+ $foundToken = $i;
+ } else if ($this->tokens[$i]['content'] === $value) {
+ $foundToken = $i;
+ }
+ }
+ }//end for
+
+ return $foundToken;
+
+ }//end findFirstOnLine()
+
+
+ /**
+ * Determine if the passed token has a condition of one of the passed types.
+ *
+ * @param int $stackPtr The position of the token we are checking.
+ * @param int|string|array $types The type(s) of tokens to search for.
+ *
+ * @return boolean
+ */
+ public function hasCondition($stackPtr, $types)
+ {
+ // Check for the existence of the token.
+ if (isset($this->tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ // Make sure the token has conditions.
+ if (isset($this->tokens[$stackPtr]['conditions']) === false) {
+ return false;
+ }
+
+ $types = (array) $types;
+ $conditions = $this->tokens[$stackPtr]['conditions'];
+
+ foreach ($types as $type) {
+ if (in_array($type, $conditions, true) === true) {
+ // We found a token with the required type.
+ return true;
+ }
+ }
+
+ return false;
+
+ }//end hasCondition()
+
+
+ /**
+ * Return the position of the condition for the passed token.
+ *
+ * Returns FALSE if the token does not have the condition.
+ *
+ * @param int $stackPtr The position of the token we are checking.
+ * @param int|string $type The type of token to search for.
+ *
+ * @return int
+ */
+ public function getCondition($stackPtr, $type)
+ {
+ // Check for the existence of the token.
+ if (isset($this->tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ // Make sure the token has conditions.
+ if (isset($this->tokens[$stackPtr]['conditions']) === false) {
+ return false;
+ }
+
+ $conditions = $this->tokens[$stackPtr]['conditions'];
+ foreach ($conditions as $token => $condition) {
+ if ($condition === $type) {
+ return $token;
+ }
+ }
+
+ return false;
+
+ }//end getCondition()
+
+
+ /**
+ * Returns the name of the class that the specified class extends.
+ * (works for classes, anonymous classes and interfaces)
+ *
+ * Returns FALSE on error or if there is no extended class name.
+ *
+ * @param int $stackPtr The stack position of the class.
+ *
+ * @return string|false
+ */
+ public function findExtendedClassName($stackPtr)
+ {
+ // Check for the existence of the token.
+ if (isset($this->tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($this->tokens[$stackPtr]['code'] !== T_CLASS
+ && $this->tokens[$stackPtr]['code'] !== T_ANON_CLASS
+ && $this->tokens[$stackPtr]['code'] !== T_INTERFACE
+ ) {
+ return false;
+ }
+
+ if (isset($this->tokens[$stackPtr]['scope_opener']) === false) {
+ return false;
+ }
+
+ $classOpenerIndex = $this->tokens[$stackPtr]['scope_opener'];
+ $extendsIndex = $this->findNext(T_EXTENDS, $stackPtr, $classOpenerIndex);
+ if (false === $extendsIndex) {
+ return false;
+ }
+
+ $find = [
+ T_NS_SEPARATOR,
+ T_STRING,
+ T_WHITESPACE,
+ ];
+
+ $end = $this->findNext($find, ($extendsIndex + 1), ($classOpenerIndex + 1), true);
+ $name = $this->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1));
+ $name = trim($name);
+
+ if ($name === '') {
+ return false;
+ }
+
+ return $name;
+
+ }//end findExtendedClassName()
+
+
+ /**
+ * Returns the names of the interfaces that the specified class implements.
+ *
+ * Returns FALSE on error or if there are no implemented interface names.
+ *
+ * @param int $stackPtr The stack position of the class.
+ *
+ * @return array|false
+ */
+ public function findImplementedInterfaceNames($stackPtr)
+ {
+ // Check for the existence of the token.
+ if (isset($this->tokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if ($this->tokens[$stackPtr]['code'] !== T_CLASS
+ && $this->tokens[$stackPtr]['code'] !== T_ANON_CLASS
+ ) {
+ return false;
+ }
+
+ if (isset($this->tokens[$stackPtr]['scope_closer']) === false) {
+ return false;
+ }
+
+ $classOpenerIndex = $this->tokens[$stackPtr]['scope_opener'];
+ $implementsIndex = $this->findNext(T_IMPLEMENTS, $stackPtr, $classOpenerIndex);
+ if ($implementsIndex === false) {
+ return false;
+ }
+
+ $find = [
+ T_NS_SEPARATOR,
+ T_STRING,
+ T_WHITESPACE,
+ T_COMMA,
+ ];
+
+ $end = $this->findNext($find, ($implementsIndex + 1), ($classOpenerIndex + 1), true);
+ $name = $this->getTokensAsString(($implementsIndex + 1), ($end - $implementsIndex - 1));
+ $name = trim($name);
+
+ if ($name === '') {
+ return false;
+ } else {
+ $names = explode(',', $name);
+ $names = array_map('trim', $names);
+ return $names;
+ }
+
+ }//end findImplementedInterfaceNames()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Files/FileList.php b/vendor/squizlabs/php_codesniffer/src/Files/FileList.php
new file mode 100644
index 0000000..ee65ccb
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Files/FileList.php
@@ -0,0 +1,247 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Files;
+
+use PHP_CodeSniffer\Autoload;
+use PHP_CodeSniffer\Util;
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Config;
+use PHP_CodeSniffer\Exceptions\DeepExitException;
+
+class FileList implements \Iterator, \Countable
+{
+
+ /**
+ * A list of file paths that are included in the list.
+ *
+ * @var array
+ */
+ private $files = [];
+
+ /**
+ * The number of files in the list.
+ *
+ * @var integer
+ */
+ private $numFiles = 0;
+
+ /**
+ * The config data for the run.
+ *
+ * @var \PHP_CodeSniffer\Config
+ */
+ public $config = null;
+
+ /**
+ * The ruleset used for the run.
+ *
+ * @var \PHP_CodeSniffer\Ruleset
+ */
+ public $ruleset = null;
+
+ /**
+ * An array of patterns to use for skipping files.
+ *
+ * @var array
+ */
+ protected $ignorePatterns = [];
+
+
+ /**
+ * Constructs a file list and loads in an array of file paths to process.
+ *
+ * @param \PHP_CodeSniffer\Config $config The config data for the run.
+ * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
+ *
+ * @return void
+ */
+ public function __construct(Config $config, Ruleset $ruleset)
+ {
+ $this->ruleset = $ruleset;
+ $this->config = $config;
+
+ $paths = $config->files;
+ foreach ($paths as $path) {
+ $isPharFile = Util\Common::isPharFile($path);
+ if (is_dir($path) === true || $isPharFile === true) {
+ if ($isPharFile === true) {
+ $path = 'phar://'.$path;
+ }
+
+ $filterClass = $this->getFilterClass();
+
+ $di = new \RecursiveDirectoryIterator($path, (\RecursiveDirectoryIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS));
+ $filter = new $filterClass($di, $path, $config, $ruleset);
+ $iterator = new \RecursiveIteratorIterator($filter);
+
+ foreach ($iterator as $file) {
+ $this->files[$file->getPathname()] = null;
+ $this->numFiles++;
+ }
+ } else {
+ $this->addFile($path);
+ }//end if
+ }//end foreach
+
+ reset($this->files);
+
+ }//end __construct()
+
+
+ /**
+ * Add a file to the list.
+ *
+ * If a file object has already been created, it can be passed here.
+ * If it is left NULL, it will be created when accessed.
+ *
+ * @param string $path The path to the file being added.
+ * @param \PHP_CodeSniffer\Files\File $file The file being added.
+ *
+ * @return void
+ */
+ public function addFile($path, $file=null)
+ {
+ // No filtering is done for STDIN when the filename
+ // has not been specified.
+ if ($path === 'STDIN') {
+ $this->files[$path] = $file;
+ $this->numFiles++;
+ return;
+ }
+
+ $filterClass = $this->getFilterClass();
+
+ $di = new \RecursiveArrayIterator([$path]);
+ $filter = new $filterClass($di, $path, $this->config, $this->ruleset);
+ $iterator = new \RecursiveIteratorIterator($filter);
+
+ foreach ($iterator as $path) {
+ $this->files[$path] = $file;
+ $this->numFiles++;
+ }
+
+ }//end addFile()
+
+
+ /**
+ * Get the class name of the filter being used for the run.
+ *
+ * @return string
+ */
+ private function getFilterClass()
+ {
+ $filterType = $this->config->filter;
+
+ if ($filterType === null) {
+ $filterClass = '\PHP_CodeSniffer\Filters\Filter';
+ } else {
+ if (strpos($filterType, '.') !== false) {
+ // This is a path to a custom filter class.
+ $filename = realpath($filterType);
+ if ($filename === false) {
+ $error = "ERROR: Custom filter \"$filterType\" not found".PHP_EOL;
+ throw new DeepExitException($error, 3);
+ }
+
+ $filterClass = Autoload::loadFile($filename);
+ } else {
+ $filterClass = '\PHP_CodeSniffer\Filters\\'.$filterType;
+ }
+ }
+
+ return $filterClass;
+
+ }//end getFilterClass()
+
+
+ /**
+ * Rewind the iterator to the first file.
+ *
+ * @return void
+ */
+ public function rewind()
+ {
+ reset($this->files);
+
+ }//end rewind()
+
+
+ /**
+ * Get the file that is currently being processed.
+ *
+ * @return \PHP_CodeSniffer\Files\File
+ */
+ public function current()
+ {
+ $path = key($this->files);
+ if ($this->files[$path] === null) {
+ $this->files[$path] = new LocalFile($path, $this->ruleset, $this->config);
+ }
+
+ return $this->files[$path];
+
+ }//end current()
+
+
+ /**
+ * Return the file path of the current file being processed.
+ *
+ * @return void
+ */
+ public function key()
+ {
+ return key($this->files);
+
+ }//end key()
+
+
+ /**
+ * Move forward to the next file.
+ *
+ * @return void
+ */
+ public function next()
+ {
+ next($this->files);
+
+ }//end next()
+
+
+ /**
+ * Checks if current position is valid.
+ *
+ * @return boolean
+ */
+ public function valid()
+ {
+ if (current($this->files) === false) {
+ return false;
+ }
+
+ return true;
+
+ }//end valid()
+
+
+ /**
+ * Return the number of files in the list.
+ *
+ * @return integer
+ */
+ public function count()
+ {
+ return $this->numFiles;
+
+ }//end count()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php b/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php
new file mode 100644
index 0000000..39b1073
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php
@@ -0,0 +1,213 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Files;
+
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Config;
+use PHP_CodeSniffer\Util\Cache;
+
+class LocalFile extends File
+{
+
+
+ /**
+ * Creates a LocalFile object and sets the content.
+ *
+ * @param string $path The absolute path to the file.
+ * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
+ * @param \PHP_CodeSniffer\Config $config The config data for the run.
+ *
+ * @return void
+ */
+ public function __construct($path, Ruleset $ruleset, Config $config)
+ {
+ $this->path = trim($path);
+ if (is_readable($this->path) === false) {
+ parent::__construct($this->path, $ruleset, $config);
+ $error = 'Error opening file; file no longer exists or you do not have access to read the file';
+ $this->addMessage(true, $error, 1, 1, 'Internal.LocalFile', [], 5, false);
+ $this->ignored = true;
+ return;
+ }
+
+ // Before we go and spend time tokenizing this file, just check
+ // to see if there is a tag up top to indicate that the whole
+ // file should be ignored. It must be on one of the first two lines.
+ if ($config->annotations === true) {
+ $handle = fopen($this->path, 'r');
+ if ($handle !== false) {
+ $firstContent = fgets($handle);
+ $firstContent .= fgets($handle);
+ fclose($handle);
+
+ if (strpos($firstContent, '@codingStandardsIgnoreFile') !== false
+ || stripos($firstContent, 'phpcs:ignorefile') !== false
+ ) {
+ // We are ignoring the whole file.
+ $this->ignored = true;
+ return;
+ }
+ }
+ }
+
+ $this->reloadContent();
+
+ parent::__construct($this->path, $ruleset, $config);
+
+ }//end __construct()
+
+
+ /**
+ * Loads the latest version of the file's content from the file system.
+ *
+ * @return void
+ */
+ public function reloadContent()
+ {
+ $this->setContent(file_get_contents($this->path));
+
+ }//end reloadContent()
+
+
+ /**
+ * Processes the file.
+ *
+ * @return void
+ */
+ public function process()
+ {
+ if ($this->ignored === true) {
+ return;
+ }
+
+ if ($this->configCache['cache'] === false) {
+ parent::process();
+ return;
+ }
+
+ $hash = md5_file($this->path);
+ $cache = Cache::get($this->path);
+ if ($cache !== false && $cache['hash'] === $hash) {
+ // We can't filter metrics, so just load all of them.
+ $this->metrics = $cache['metrics'];
+
+ if ($this->configCache['recordErrors'] === true) {
+ // Replay the cached errors and warnings to filter out the ones
+ // we don't need for this specific run.
+ $this->configCache['cache'] = false;
+ $this->replayErrors($cache['errors'], $cache['warnings']);
+ $this->configCache['cache'] = true;
+ } else {
+ $this->errorCount = $cache['errorCount'];
+ $this->warningCount = $cache['warningCount'];
+ $this->fixableCount = $cache['fixableCount'];
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 0
+ || (PHP_CODESNIFFER_CBF === true && empty($this->config->files) === false)
+ ) {
+ echo "[loaded from cache]... ";
+ }
+
+ $this->numTokens = $cache['numTokens'];
+ $this->fromCache = true;
+ return;
+ }//end if
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo PHP_EOL;
+ }
+
+ parent::process();
+
+ $cache = [
+ 'hash' => $hash,
+ 'errors' => $this->errors,
+ 'warnings' => $this->warnings,
+ 'metrics' => $this->metrics,
+ 'errorCount' => $this->errorCount,
+ 'warningCount' => $this->warningCount,
+ 'fixableCount' => $this->fixableCount,
+ 'numTokens' => $this->numTokens,
+ ];
+
+ Cache::set($this->path, $cache);
+
+ // During caching, we don't filter out errors in any way, so
+ // we need to do that manually now by replaying them.
+ if ($this->configCache['recordErrors'] === true) {
+ $this->configCache['cache'] = false;
+ $this->replayErrors($this->errors, $this->warnings);
+ $this->configCache['cache'] = true;
+ }
+
+ }//end process()
+
+
+ /**
+ * Clears and replays error and warnings for the file.
+ *
+ * Replaying errors and warnings allows for filtering rules to be changed
+ * and then errors and warnings to be reapplied with the new rules. This is
+ * particularly useful while caching.
+ *
+ * @param array $errors The list of errors to replay.
+ * @param array $warnings The list of warnings to replay.
+ *
+ * @return void
+ */
+ private function replayErrors($errors, $warnings)
+ {
+ $this->errors = [];
+ $this->warnings = [];
+ $this->errorCount = 0;
+ $this->warningCount = 0;
+ $this->fixableCount = 0;
+
+ foreach ($errors as $line => $lineErrors) {
+ foreach ($lineErrors as $column => $colErrors) {
+ foreach ($colErrors as $error) {
+ $this->activeListener = $error['listener'];
+ $this->addMessage(
+ true,
+ $error['message'],
+ $line,
+ $column,
+ $error['source'],
+ [],
+ $error['severity'],
+ $error['fixable']
+ );
+ }
+ }
+ }
+
+ foreach ($warnings as $line => $lineErrors) {
+ foreach ($lineErrors as $column => $colErrors) {
+ foreach ($colErrors as $error) {
+ $this->activeListener = $error['listener'];
+ $this->addMessage(
+ false,
+ $error['message'],
+ $line,
+ $column,
+ $error['source'],
+ [],
+ $error['severity'],
+ $error['fixable']
+ );
+ }
+ }
+ }
+
+ }//end replayErrors()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Filters/ExactMatch.php b/vendor/squizlabs/php_codesniffer/src/Filters/ExactMatch.php
new file mode 100644
index 0000000..13af8ff
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Filters/ExactMatch.php
@@ -0,0 +1,108 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Filters;
+
+use PHP_CodeSniffer\Util;
+
+abstract class ExactMatch extends Filter
+{
+
+ /**
+ * A list of files to exclude.
+ *
+ * @var array
+ */
+ private $blacklist = null;
+
+ /**
+ * A list of files to include.
+ *
+ * If the whitelist is empty, only files in the blacklist will be excluded.
+ *
+ * @var array
+ */
+ private $whitelist = null;
+
+
+ /**
+ * Check whether the current element of the iterator is acceptable.
+ *
+ * If a file is both blacklisted and whitelisted, it will be deemed unacceptable.
+ *
+ * @return bool
+ */
+ public function accept()
+ {
+ if (parent::accept() === false) {
+ return false;
+ }
+
+ if ($this->blacklist === null) {
+ $this->blacklist = $this->getblacklist();
+ }
+
+ if ($this->whitelist === null) {
+ $this->whitelist = $this->getwhitelist();
+ }
+
+ $filePath = Util\Common::realpath($this->current());
+
+ // If file is both blacklisted and whitelisted, the blacklist takes precedence.
+ if (isset($this->blacklist[$filePath]) === true) {
+ return false;
+ }
+
+ if (empty($this->whitelist) === true && empty($this->blacklist) === false) {
+ // We are only checking a blacklist, so everything else should be whitelisted.
+ return true;
+ }
+
+ return isset($this->whitelist[$filePath]);
+
+ }//end accept()
+
+
+ /**
+ * Returns an iterator for the current entry.
+ *
+ * Ensures that the blacklist and whitelist are preserved so they don't have
+ * to be generated each time.
+ *
+ * @return \RecursiveIterator
+ */
+ public function getChildren()
+ {
+ $children = parent::getChildren();
+ $children->blacklist = $this->blacklist;
+ $children->whitelist = $this->whitelist;
+ return $children;
+
+ }//end getChildren()
+
+
+ /**
+ * Get a list of blacklisted file paths.
+ *
+ * @return array
+ */
+ abstract protected function getBlacklist();
+
+
+ /**
+ * Get a list of whitelisted file paths.
+ *
+ * @return array
+ */
+ abstract protected function getWhitelist();
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php b/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php
new file mode 100644
index 0000000..04cc391
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php
@@ -0,0 +1,270 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Filters;
+
+use PHP_CodeSniffer\Util;
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Config;
+
+class Filter extends \RecursiveFilterIterator
+{
+ /**
+ * The top-level path we are filtering.
+ *
+ * @var string
+ */
+ protected $basedir = null;
+
+ /**
+ * The config data for the run.
+ *
+ * @var \PHP_CodeSniffer\Config
+ */
+ protected $config = null;
+
+ /**
+ * The ruleset used for the run.
+ *
+ * @var \PHP_CodeSniffer\Ruleset
+ */
+ protected $ruleset = null;
+
+ /**
+ * A list of ignore patterns that apply to directories only.
+ *
+ * @var array
+ */
+ protected $ignoreDirPatterns = null;
+
+ /**
+ * A list of ignore patterns that apply to files only.
+ *
+ * @var array
+ */
+ protected $ignoreFilePatterns = null;
+
+ /**
+ * A list of file paths we've already accepted.
+ *
+ * Used to ensure we aren't following circular symlinks.
+ *
+ * @var array
+ */
+ protected $acceptedPaths = [];
+
+
+ /**
+ * Constructs a filter.
+ *
+ * @param \RecursiveIterator $iterator The iterator we are using to get file paths.
+ * @param string $basedir The top-level path we are filtering.
+ * @param \PHP_CodeSniffer\Config $config The config data for the run.
+ * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
+ *
+ * @return void
+ */
+ public function __construct($iterator, $basedir, Config $config, Ruleset $ruleset)
+ {
+ parent::__construct($iterator);
+ $this->basedir = $basedir;
+ $this->config = $config;
+ $this->ruleset = $ruleset;
+
+ }//end __construct()
+
+
+ /**
+ * Check whether the current element of the iterator is acceptable.
+ *
+ * Files are checked for allowed extensions and ignore patterns.
+ * Directories are checked for ignore patterns only.
+ *
+ * @return bool
+ */
+ public function accept()
+ {
+ $filePath = $this->current();
+ $realPath = Util\Common::realpath($filePath);
+
+ if ($realPath !== false) {
+ // It's a real path somewhere, so record it
+ // to check for circular symlinks.
+ if (isset($this->acceptedPaths[$realPath]) === true) {
+ // We've been here before.
+ return false;
+ }
+ }
+
+ $filePath = $this->current();
+ if (is_dir($filePath) === true) {
+ if ($this->config->local === true) {
+ return false;
+ }
+ } else if ($this->shouldProcessFile($filePath) === false) {
+ return false;
+ }
+
+ if ($this->shouldIgnorePath($filePath) === true) {
+ return false;
+ }
+
+ $this->acceptedPaths[$realPath] = true;
+ return true;
+
+ }//end accept()
+
+
+ /**
+ * Returns an iterator for the current entry.
+ *
+ * Ensures that the ignore patterns are preserved so they don't have
+ * to be generated each time.
+ *
+ * @return \RecursiveIterator
+ */
+ public function getChildren()
+ {
+ $children = new static(
+ new \RecursiveDirectoryIterator($this->current(), (\RecursiveDirectoryIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS)),
+ $this->basedir,
+ $this->config,
+ $this->ruleset
+ );
+
+ // Set the ignore patterns so we don't have to generate them again.
+ $children->ignoreDirPatterns = $this->ignoreDirPatterns;
+ $children->ignoreFilePatterns = $this->ignoreFilePatterns;
+ $children->acceptedPaths = $this->acceptedPaths;
+ return $children;
+
+ }//end getChildren()
+
+
+ /**
+ * Checks filtering rules to see if a file should be checked.
+ *
+ * Checks both file extension filters and path ignore filters.
+ *
+ * @param string $path The path to the file being checked.
+ *
+ * @return bool
+ */
+ protected function shouldProcessFile($path)
+ {
+ // Check that the file's extension is one we are checking.
+ // We are strict about checking the extension and we don't
+ // let files through with no extension or that start with a dot.
+ $fileName = basename($path);
+ $fileParts = explode('.', $fileName);
+ if ($fileParts[0] === $fileName || $fileParts[0] === '') {
+ return false;
+ }
+
+ // Checking multi-part file extensions, so need to create a
+ // complete extension list and make sure one is allowed.
+ $extensions = [];
+ array_shift($fileParts);
+ foreach ($fileParts as $part) {
+ $extensions[implode('.', $fileParts)] = 1;
+ array_shift($fileParts);
+ }
+
+ $matches = array_intersect_key($extensions, $this->config->extensions);
+ if (empty($matches) === true) {
+ return false;
+ }
+
+ return true;
+
+ }//end shouldProcessFile()
+
+
+ /**
+ * Checks filtering rules to see if a path should be ignored.
+ *
+ * @param string $path The path to the file or directory being checked.
+ *
+ * @return bool
+ */
+ protected function shouldIgnorePath($path)
+ {
+ if ($this->ignoreFilePatterns === null) {
+ $this->ignoreDirPatterns = [];
+ $this->ignoreFilePatterns = [];
+
+ $ignorePatterns = array_merge($this->config->ignored, $this->ruleset->getIgnorePatterns());
+ foreach ($ignorePatterns as $pattern => $type) {
+ // If the ignore pattern ends with /* then it is ignoring an entire directory.
+ if (substr($pattern, -2) === '/*') {
+ // Need to check this pattern for dirs as well as individual file paths.
+ $this->ignoreFilePatterns[$pattern] = $type;
+
+ $pattern = substr($pattern, 0, -2);
+ $this->ignoreDirPatterns[$pattern] = $type;
+ } else {
+ // This is a file-specific pattern, so only need to check this
+ // for individual file paths.
+ $this->ignoreFilePatterns[$pattern] = $type;
+ }
+ }
+ }
+
+ $relativePath = $path;
+ if (strpos($path, $this->basedir) === 0) {
+ // The +1 cuts off the directory separator as well.
+ $relativePath = substr($path, (strlen($this->basedir) + 1));
+ }
+
+ if (is_dir($path) === true) {
+ $ignorePatterns = $this->ignoreDirPatterns;
+ } else {
+ $ignorePatterns = $this->ignoreFilePatterns;
+ }
+
+ foreach ($ignorePatterns as $pattern => $type) {
+ // Maintains backwards compatibility in case the ignore pattern does
+ // not have a relative/absolute value.
+ if (is_int($pattern) === true) {
+ $pattern = $type;
+ $type = 'absolute';
+ }
+
+ $replacements = [
+ '\\,' => ',',
+ '*' => '.*',
+ ];
+
+ // We assume a / directory separator, as do the exclude rules
+ // most developers write, so we need a special case for any system
+ // that is different.
+ if (DIRECTORY_SEPARATOR === '\\') {
+ $replacements['/'] = '\\\\';
+ }
+
+ $pattern = strtr($pattern, $replacements);
+
+ if ($type === 'relative') {
+ $testPath = $relativePath;
+ } else {
+ $testPath = $path;
+ }
+
+ $pattern = '`'.$pattern.'`i';
+ if (preg_match($pattern, $testPath) === 1) {
+ return true;
+ }
+ }//end foreach
+
+ return false;
+
+ }//end shouldIgnorePath()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Filters/GitModified.php b/vendor/squizlabs/php_codesniffer/src/Filters/GitModified.php
new file mode 100644
index 0000000..4b6ef3f
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Filters/GitModified.php
@@ -0,0 +1,66 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Filters;
+
+use PHP_CodeSniffer\Util;
+
+class GitModified extends ExactMatch
+{
+
+
+ /**
+ * Get a list of blacklisted file paths.
+ *
+ * @return array
+ */
+ protected function getBlacklist()
+ {
+ return [];
+
+ }//end getBlacklist()
+
+
+ /**
+ * Get a list of whitelisted file paths.
+ *
+ * @return array
+ */
+ protected function getWhitelist()
+ {
+ $modified = [];
+
+ $cmd = 'git ls-files -o -m --exclude-standard -- '.escapeshellarg($this->basedir);
+ $output = [];
+ exec($cmd, $output);
+
+ $basedir = $this->basedir;
+ if (is_dir($basedir) === false) {
+ $basedir = dirname($basedir);
+ }
+
+ foreach ($output as $path) {
+ $path = Util\Common::realpath($path);
+
+ if ($path === false) {
+ continue;
+ }
+
+ do {
+ $modified[$path] = true;
+ $path = dirname($path);
+ } while ($path !== $basedir);
+ }
+
+ return $modified;
+
+ }//end getWhitelist()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Fixer.php b/vendor/squizlabs/php_codesniffer/src/Fixer.php
new file mode 100644
index 0000000..943af2e
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Fixer.php
@@ -0,0 +1,723 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer;
+
+use PHP_CodeSniffer\Files\File;
+use PHP_CodeSniffer\Util\Common;
+
+class Fixer
+{
+
+ /**
+ * Is the fixer enabled and fixing a file?
+ *
+ * Sniffs should check this value to ensure they are not
+ * doing extra processing to prepare for a fix when fixing is
+ * not required.
+ *
+ * @var boolean
+ */
+ public $enabled = false;
+
+ /**
+ * The number of times we have looped over a file.
+ *
+ * @var integer
+ */
+ public $loops = 0;
+
+ /**
+ * The file being fixed.
+ *
+ * @var \PHP_CodeSniffer\Files\File
+ */
+ private $currentFile = null;
+
+ /**
+ * The list of tokens that make up the file contents.
+ *
+ * This is a simplified list which just contains the token content and nothing
+ * else. This is the array that is updated as fixes are made, not the file's
+ * token array. Imploding this array will give you the file content back.
+ *
+ * @var array
+ */
+ private $tokens = [];
+
+ /**
+ * A list of tokens that have already been fixed.
+ *
+ * We don't allow the same token to be fixed more than once each time
+ * through a file as this can easily cause conflicts between sniffs.
+ *
+ * @var int[]
+ */
+ private $fixedTokens = [];
+
+ /**
+ * The last value of each fixed token.
+ *
+ * If a token is being "fixed" back to its last value, the fix is
+ * probably conflicting with another.
+ *
+ * @var array
+ */
+ private $oldTokenValues = [];
+
+ /**
+ * A list of tokens that have been fixed during a changeset.
+ *
+ * All changes in changeset must be able to be applied, or else
+ * the entire changeset is rejected.
+ *
+ * @var array
+ */
+ private $changeset = [];
+
+ /**
+ * Is there an open changeset.
+ *
+ * @var boolean
+ */
+ private $inChangeset = false;
+
+ /**
+ * Is the current fixing loop in conflict?
+ *
+ * @var boolean
+ */
+ private $inConflict = false;
+
+ /**
+ * The number of fixes that have been performed.
+ *
+ * @var integer
+ */
+ private $numFixes = 0;
+
+
+ /**
+ * Starts fixing a new file.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being fixed.
+ *
+ * @return void
+ */
+ public function startFile(File $phpcsFile)
+ {
+ $this->currentFile = $phpcsFile;
+ $this->numFixes = 0;
+ $this->fixedTokens = [];
+
+ $tokens = $phpcsFile->getTokens();
+ $this->tokens = [];
+ foreach ($tokens as $index => $token) {
+ if (isset($token['orig_content']) === true) {
+ $this->tokens[$index] = $token['orig_content'];
+ } else {
+ $this->tokens[$index] = $token['content'];
+ }
+ }
+
+ }//end startFile()
+
+
+ /**
+ * Attempt to fix the file by processing it until no fixes are made.
+ *
+ * @return boolean
+ */
+ public function fixFile()
+ {
+ $fixable = $this->currentFile->getFixableCount();
+ if ($fixable === 0) {
+ // Nothing to fix.
+ return false;
+ }
+
+ $this->enabled = true;
+
+ $this->loops = 0;
+ while ($this->loops < 50) {
+ ob_start();
+
+ // Only needed once file content has changed.
+ $contents = $this->getContents();
+
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
+ @ob_end_clean();
+ echo '---START FILE CONTENT---'.PHP_EOL;
+ $lines = explode($this->currentFile->eolChar, $contents);
+ $max = strlen(count($lines));
+ foreach ($lines as $lineNum => $line) {
+ $lineNum++;
+ echo str_pad($lineNum, $max, ' ', STR_PAD_LEFT).'|'.$line.PHP_EOL;
+ }
+
+ echo '--- END FILE CONTENT ---'.PHP_EOL;
+ ob_start();
+ }
+
+ $this->inConflict = false;
+ $this->currentFile->ruleset->populateTokenListeners();
+ $this->currentFile->setContent($contents);
+ $this->currentFile->process();
+ ob_end_clean();
+
+ $this->loops++;
+
+ if (PHP_CODESNIFFER_CBF === true && PHP_CODESNIFFER_VERBOSITY > 0) {
+ echo "\r".str_repeat(' ', 80)."\r";
+ echo "\t=> Fixing file: $this->numFixes/$fixable violations remaining [made $this->loops pass";
+ if ($this->loops > 1) {
+ echo 'es';
+ }
+
+ echo ']... ';
+ }
+
+ if ($this->numFixes === 0 && $this->inConflict === false) {
+ // Nothing left to do.
+ break;
+ } else if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo "\t* fixed $this->numFixes violations, starting loop ".($this->loops + 1).' *'.PHP_EOL;
+ }
+ }//end while
+
+ $this->enabled = false;
+
+ if ($this->numFixes > 0) {
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ if (ob_get_level() > 0) {
+ ob_end_clean();
+ }
+
+ echo "\t*** Reached maximum number of loops with $this->numFixes violations left unfixed ***".PHP_EOL;
+ ob_start();
+ }
+
+ return false;
+ }
+
+ return true;
+
+ }//end fixFile()
+
+
+ /**
+ * Generates a text diff of the original file and the new content.
+ *
+ * @param string $filePath Optional file path to diff the file against.
+ * If not specified, the original version of the
+ * file will be used.
+ * @param boolean $colors Print colored output or not.
+ *
+ * @return string
+ */
+ public function generateDiff($filePath=null, $colors=true)
+ {
+ if ($filePath === null) {
+ $filePath = $this->currentFile->getFilename();
+ }
+
+ $cwd = getcwd().DIRECTORY_SEPARATOR;
+ if (strpos($filePath, $cwd) === 0) {
+ $filename = substr($filePath, strlen($cwd));
+ } else {
+ $filename = $filePath;
+ }
+
+ $contents = $this->getContents();
+
+ $tempName = tempnam(sys_get_temp_dir(), 'phpcs-fixer');
+ $fixedFile = fopen($tempName, 'w');
+ fwrite($fixedFile, $contents);
+
+ // We must use something like shell_exec() because whitespace at the end
+ // of lines is critical to diff files.
+ $filename = escapeshellarg($filename);
+ $cmd = "diff -u -L$filename -LPHP_CodeSniffer $filename \"$tempName\"";
+
+ $diff = shell_exec($cmd);
+
+ fclose($fixedFile);
+ if (is_file($tempName) === true) {
+ unlink($tempName);
+ }
+
+ if ($colors === false) {
+ return $diff;
+ }
+
+ $diffLines = explode(PHP_EOL, $diff);
+ if (count($diffLines) === 1) {
+ // Seems to be required for cygwin.
+ $diffLines = explode("\n", $diff);
+ }
+
+ $diff = [];
+ foreach ($diffLines as $line) {
+ if (isset($line[0]) === true) {
+ switch ($line[0]) {
+ case '-':
+ $diff[] = "\033[31m$line\033[0m";
+ break;
+ case '+':
+ $diff[] = "\033[32m$line\033[0m";
+ break;
+ default:
+ $diff[] = $line;
+ }
+ }
+ }
+
+ $diff = implode(PHP_EOL, $diff);
+
+ return $diff;
+
+ }//end generateDiff()
+
+
+ /**
+ * Get a count of fixes that have been performed on the file.
+ *
+ * This value is reset every time a new file is started, or an existing
+ * file is restarted.
+ *
+ * @return int
+ */
+ public function getFixCount()
+ {
+ return $this->numFixes;
+
+ }//end getFixCount()
+
+
+ /**
+ * Get the current content of the file, as a string.
+ *
+ * @return string
+ */
+ public function getContents()
+ {
+ $contents = implode($this->tokens);
+ return $contents;
+
+ }//end getContents()
+
+
+ /**
+ * Get the current fixed content of a token.
+ *
+ * This function takes changesets into account so should be used
+ * instead of directly accessing the token array.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ *
+ * @return string
+ */
+ public function getTokenContent($stackPtr)
+ {
+ if ($this->inChangeset === true
+ && isset($this->changeset[$stackPtr]) === true
+ ) {
+ return $this->changeset[$stackPtr];
+ } else {
+ return $this->tokens[$stackPtr];
+ }
+
+ }//end getTokenContent()
+
+
+ /**
+ * Start recording actions for a changeset.
+ *
+ * @return void
+ */
+ public function beginChangeset()
+ {
+ if ($this->inConflict === true) {
+ return false;
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ $sniff = $bt[1]['class'];
+ $line = $bt[0]['line'];
+
+ @ob_end_clean();
+ echo "\t=> Changeset started by $sniff (line $line)".PHP_EOL;
+ ob_start();
+ }
+
+ $this->changeset = [];
+ $this->inChangeset = true;
+
+ }//end beginChangeset()
+
+
+ /**
+ * Stop recording actions for a changeset, and apply logged changes.
+ *
+ * @return boolean
+ */
+ public function endChangeset()
+ {
+ if ($this->inConflict === true) {
+ return false;
+ }
+
+ $this->inChangeset = false;
+
+ $success = true;
+ $applied = [];
+ foreach ($this->changeset as $stackPtr => $content) {
+ $success = $this->replaceToken($stackPtr, $content);
+ if ($success === false) {
+ break;
+ } else {
+ $applied[] = $stackPtr;
+ }
+ }
+
+ if ($success === false) {
+ // Rolling back all changes.
+ foreach ($applied as $stackPtr) {
+ $this->revertToken($stackPtr);
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ @ob_end_clean();
+ echo "\t=> Changeset failed to apply".PHP_EOL;
+ ob_start();
+ }
+ } else if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $fixes = count($this->changeset);
+ @ob_end_clean();
+ echo "\t=> Changeset ended: $fixes changes applied".PHP_EOL;
+ ob_start();
+ }
+
+ $this->changeset = [];
+
+ }//end endChangeset()
+
+
+ /**
+ * Stop recording actions for a changeset, and discard logged changes.
+ *
+ * @return void
+ */
+ public function rollbackChangeset()
+ {
+ $this->inChangeset = false;
+ $this->inConflict = false;
+
+ if (empty($this->changeset) === false) {
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $bt = debug_backtrace();
+ if ($bt[1]['class'] === 'PHP_CodeSniffer\Fixer') {
+ $sniff = $bt[2]['class'];
+ $line = $bt[1]['line'];
+ } else {
+ $sniff = $bt[1]['class'];
+ $line = $bt[0]['line'];
+ }
+
+ $numChanges = count($this->changeset);
+
+ @ob_end_clean();
+ echo "\t\tR: $sniff (line $line) rolled back the changeset ($numChanges changes)".PHP_EOL;
+ echo "\t=> Changeset rolled back".PHP_EOL;
+ ob_start();
+ }
+
+ $this->changeset = [];
+ }//end if
+
+ }//end rollbackChangeset()
+
+
+ /**
+ * Replace the entire contents of a token.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ * @param string $content The new content of the token.
+ *
+ * @return bool If the change was accepted.
+ */
+ public function replaceToken($stackPtr, $content)
+ {
+ if ($this->inConflict === true) {
+ return false;
+ }
+
+ if ($this->inChangeset === false
+ && isset($this->fixedTokens[$stackPtr]) === true
+ ) {
+ $indent = "\t";
+ if (empty($this->changeset) === false) {
+ $indent .= "\t";
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ @ob_end_clean();
+ echo "$indent* token $stackPtr has already been modified, skipping *".PHP_EOL;
+ ob_start();
+ }
+
+ return false;
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ if ($bt[1]['class'] === 'PHP_CodeSniffer\Fixer') {
+ $sniff = $bt[2]['class'];
+ $line = $bt[1]['line'];
+ } else {
+ $sniff = $bt[1]['class'];
+ $line = $bt[0]['line'];
+ }
+
+ $tokens = $this->currentFile->getTokens();
+ $type = $tokens[$stackPtr]['type'];
+ $oldContent = Common::prepareForOutput($this->tokens[$stackPtr]);
+ $newContent = Common::prepareForOutput($content);
+ if (trim($this->tokens[$stackPtr]) === '' && isset($this->tokens[($stackPtr + 1)]) === true) {
+ // Add some context for whitespace only changes.
+ $append = Common::prepareForOutput($this->tokens[($stackPtr + 1)]);
+ $oldContent .= $append;
+ $newContent .= $append;
+ }
+ }//end if
+
+ if ($this->inChangeset === true) {
+ $this->changeset[$stackPtr] = $content;
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ @ob_end_clean();
+ echo "\t\tQ: $sniff (line $line) replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL;
+ ob_start();
+ }
+
+ return true;
+ }
+
+ if (isset($this->oldTokenValues[$stackPtr]) === false) {
+ $this->oldTokenValues[$stackPtr] = [
+ 'curr' => $content,
+ 'prev' => $this->tokens[$stackPtr],
+ 'loop' => $this->loops,
+ ];
+ } else {
+ if ($this->oldTokenValues[$stackPtr]['prev'] === $content
+ && $this->oldTokenValues[$stackPtr]['loop'] === ($this->loops - 1)
+ ) {
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $indent = "\t";
+ if (empty($this->changeset) === false) {
+ $indent .= "\t";
+ }
+
+ $loop = $this->oldTokenValues[$stackPtr]['loop'];
+
+ @ob_end_clean();
+ echo "$indent**** $sniff (line $line) has possible conflict with another sniff on loop $loop; caused by the following change ****".PHP_EOL;
+ echo "$indent**** replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\" ****".PHP_EOL;
+ }
+
+ if ($this->oldTokenValues[$stackPtr]['loop'] >= ($this->loops - 1)) {
+ $this->inConflict = true;
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ echo "$indent**** ignoring all changes until next loop ****".PHP_EOL;
+ }
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ ob_start();
+ }
+
+ return false;
+ }//end if
+
+ $this->oldTokenValues[$stackPtr]['prev'] = $this->oldTokenValues[$stackPtr]['curr'];
+ $this->oldTokenValues[$stackPtr]['curr'] = $content;
+ $this->oldTokenValues[$stackPtr]['loop'] = $this->loops;
+ }//end if
+
+ $this->fixedTokens[$stackPtr] = $this->tokens[$stackPtr];
+ $this->tokens[$stackPtr] = $content;
+ $this->numFixes++;
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $indent = "\t";
+ if (empty($this->changeset) === false) {
+ $indent .= "\tA: ";
+ }
+
+ if (ob_get_level() > 0) {
+ ob_end_clean();
+ }
+
+ echo "$indent$sniff (line $line) replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL;
+ ob_start();
+ }
+
+ return true;
+
+ }//end replaceToken()
+
+
+ /**
+ * Reverts the previous fix made to a token.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ *
+ * @return bool If a change was reverted.
+ */
+ public function revertToken($stackPtr)
+ {
+ if (isset($this->fixedTokens[$stackPtr]) === false) {
+ return false;
+ }
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ if ($bt[1]['class'] === 'PHP_CodeSniffer\Fixer') {
+ $sniff = $bt[2]['class'];
+ $line = $bt[1]['line'];
+ } else {
+ $sniff = $bt[1]['class'];
+ $line = $bt[0]['line'];
+ }
+
+ $tokens = $this->currentFile->getTokens();
+ $type = $tokens[$stackPtr]['type'];
+ $oldContent = Common::prepareForOutput($this->tokens[$stackPtr]);
+ $newContent = Common::prepareForOutput($this->fixedTokens[$stackPtr]);
+ if (trim($this->tokens[$stackPtr]) === '' && isset($tokens[($stackPtr + 1)]) === true) {
+ // Add some context for whitespace only changes.
+ $append = Common::prepareForOutput($this->tokens[($stackPtr + 1)]);
+ $oldContent .= $append;
+ $newContent .= $append;
+ }
+ }//end if
+
+ $this->tokens[$stackPtr] = $this->fixedTokens[$stackPtr];
+ unset($this->fixedTokens[$stackPtr]);
+ $this->numFixes--;
+
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
+ $indent = "\t";
+ if (empty($this->changeset) === false) {
+ $indent .= "\tR: ";
+ }
+
+ @ob_end_clean();
+ echo "$indent$sniff (line $line) reverted token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL;
+ ob_start();
+ }
+
+ return true;
+
+ }//end revertToken()
+
+
+ /**
+ * Replace the content of a token with a part of its current content.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ * @param int $start The first character to keep.
+ * @param int $length The number of characters to keep. If NULL, the content of
+ * the token from $start to the end of the content is kept.
+ *
+ * @return bool If the change was accepted.
+ */
+ public function substrToken($stackPtr, $start, $length=null)
+ {
+ $current = $this->getTokenContent($stackPtr);
+
+ if ($length === null) {
+ $newContent = substr($current, $start);
+ } else {
+ $newContent = substr($current, $start, $length);
+ }
+
+ return $this->replaceToken($stackPtr, $newContent);
+
+ }//end substrToken()
+
+
+ /**
+ * Adds a newline to end of a token's content.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ *
+ * @return bool If the change was accepted.
+ */
+ public function addNewline($stackPtr)
+ {
+ $current = $this->getTokenContent($stackPtr);
+ return $this->replaceToken($stackPtr, $current.$this->currentFile->eolChar);
+
+ }//end addNewline()
+
+
+ /**
+ * Adds a newline to the start of a token's content.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ *
+ * @return bool If the change was accepted.
+ */
+ public function addNewlineBefore($stackPtr)
+ {
+ $current = $this->getTokenContent($stackPtr);
+ return $this->replaceToken($stackPtr, $this->currentFile->eolChar.$current);
+
+ }//end addNewlineBefore()
+
+
+ /**
+ * Adds content to the end of a token's current content.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ * @param string $content The content to add.
+ *
+ * @return bool If the change was accepted.
+ */
+ public function addContent($stackPtr, $content)
+ {
+ $current = $this->getTokenContent($stackPtr);
+ return $this->replaceToken($stackPtr, $current.$content);
+
+ }//end addContent()
+
+
+ /**
+ * Adds content to the start of a token's current content.
+ *
+ * @param int $stackPtr The position of the token in the token stack.
+ * @param string $content The content to add.
+ *
+ * @return bool If the change was accepted.
+ */
+ public function addContentBefore($stackPtr, $content)
+ {
+ $current = $this->getTokenContent($stackPtr);
+ return $this->replaceToken($stackPtr, $content.$current);
+
+ }//end addContentBefore()
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php b/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php
new file mode 100644
index 0000000..5604976
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php
@@ -0,0 +1,117 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Generators;
+
+use PHP_CodeSniffer\Ruleset;
+use PHP_CodeSniffer\Autoload;
+
+abstract class Generator
+{
+
+ /**
+ * The ruleset used for the run.
+ *
+ * @var \PHP_CodeSniffer\Ruleset
+ */
+ public $ruleset = null;
+
+ /**
+ * XML documentation files used to produce the final output.
+ *
+ * @var string[]
+ */
+ public $docFiles = [];
+
+
+ /**
+ * Constructs a doc generator.
+ *
+ * @param \PHP_CodeSniffer\Ruleset $ruleset The ruleset used for the run.
+ *
+ * @see generate()
+ */
+ public function __construct(Ruleset $ruleset)
+ {
+ $this->ruleset = $ruleset;
+
+ foreach ($ruleset->sniffs as $className => $sniffClass) {
+ $file = Autoload::getLoadedFileName($className);
+ $docFile = str_replace(
+ DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR,
+ DIRECTORY_SEPARATOR.'Docs'.DIRECTORY_SEPARATOR,
+ $file
+ );
+ $docFile = str_replace('Sniff.php', 'Standard.xml', $docFile);
+
+ if (is_file($docFile) === true) {
+ $this->docFiles[] = $docFile;
+ }
+ }
+
+ }//end __construct()
+
+
+ /**
+ * Retrieves the title of the sniff from the DOMNode supplied.
+ *
+ * @param \DOMNode $doc The DOMNode object for the sniff.
+ * It represents the "documentation" tag in the XML
+ * standard file.
+ *
+ * @return string
+ */
+ protected function getTitle(\DOMNode $doc)
+ {
+ return $doc->getAttribute('title');
+
+ }//end getTitle()
+
+
+ /**
+ * Generates the documentation for a standard.
+ *
+ * It's probably wise for doc generators to override this method so they
+ * have control over how the docs are produced. Otherwise, the processSniff
+ * method should be overridden to output content for each sniff.
+ *
+ * @return void
+ * @see processSniff()
+ */
+ public function generate()
+ {
+ foreach ($this->docFiles as $file) {
+ $doc = new \DOMDocument();
+ $doc->load($file);
+ $documentation = $doc->getElementsByTagName('documentation')->item(0);
+ $this->processSniff($documentation);
+ }
+
+ }//end generate()
+
+
+ /**
+ * Process the documentation for a single sniff.
+ *
+ * Doc generators must implement this function to produce output.
+ *
+ * @param \DOMNode $doc The DOMNode object for the sniff.
+ * It represents the "documentation" tag in the XML
+ * standard file.
+ *
+ * @return void
+ * @see generate()
+ */
+ abstract protected function processSniff(\DOMNode $doc);
+
+
+}//end class
diff --git a/vendor/squizlabs/php_codesniffer/src/Generators/HTML.php b/vendor/squizlabs/php_codesniffer/src/Generators/HTML.php
new file mode 100644
index 0000000..db26468
--- /dev/null
+++ b/vendor/squizlabs/php_codesniffer/src/Generators/HTML.php
@@ -0,0 +1,270 @@
+
+ * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
+ */
+
+namespace PHP_CodeSniffer\Generators;
+
+use PHP_CodeSniffer\Config;
+
+class HTML extends Generator
+{
+
+
+ /**
+ * Generates the documentation for a standard.
+ *
+ * @return void
+ * @see processSniff()
+ */
+ public function generate()
+ {
+ ob_start();
+ $this->printHeader();
+ $this->printToc();
+
+ foreach ($this->docFiles as $file) {
+ $doc = new \DOMDocument();
+ $doc->load($file);
+ $documentation = $doc->getElementsByTagName('documentation')->item(0);
+ $this->processSniff($documentation);
+ }
+
+ $this->printFooter();
+
+ $content = ob_get_contents();
+ ob_end_clean();
+
+ echo $content;
+
+ }//end generate()
+
+
+ /**
+ * Print the header of the HTML page.
+ *
+ * @return void
+ */
+ protected function printHeader()
+ {
+ $standard = $this->ruleset->name;
+ echo ''.PHP_EOL;
+ echo ' '.PHP_EOL;
+ echo " $standard Coding Standards".PHP_EOL;
+ echo ' '.PHP_EOL;
+ echo ' '.PHP_EOL;
+ echo ' '.PHP_EOL;
+ echo "
$standard Coding Standards
".PHP_EOL;
+
+ }//end printHeader()
+
+
+ /**
+ * Print the table of contents for the standard.
+ *
+ * The TOC is just an unordered list of bookmarks to sniffs on the page.
+ *
+ * @return void
+ */
+ protected function printToc()
+ {
+ echo '
'.PHP_EOL;
+
+ }//end printToc()
+
+
+ /**
+ * Print the footer of the HTML page.
+ *
+ * @return void
+ */
+ protected function printFooter()
+ {
+ // Turn off errors so we don't get timezone warnings if people
+ // don't have their timezone set.
+ $errorLevel = error_reporting(0);
+ echo '
'.PHP_EOL;
+ error_reporting($errorLevel);
+
+ echo ' '.PHP_EOL;
+ echo ''.PHP_EOL;
+
+ }//end printFooter()
+
+
+ /**
+ * Process the documentation for a single sniff.
+ *
+ * @param \DOMNode $doc The DOMNode object for the sniff.
+ * It represents the "documentation" tag in the XML
+ * standard file.
+ *
+ * @return void
+ */
+ public function processSniff(\DOMNode $doc)
+ {
+ $title = $this->getTitle($doc);
+ echo ' '.PHP_EOL;
+ echo "
$title
".PHP_EOL;
+
+ foreach ($doc->childNodes as $node) {
+ if ($node->nodeName === 'standard') {
+ $this->printTextBlock($node);
+ } else if ($node->nodeName === 'code_comparison') {
+ $this->printCodeComparisonBlock($node);
+ }
+ }
+
+ }//end processSniff()
+
+
+ /**
+ * Print a text block found in a standard.
+ *
+ * @param \DOMNode $node The DOMNode object for the text block.
+ *
+ * @return void
+ */
+ protected function printTextBlock(\DOMNode $node)
+ {
+ $content = trim($node->nodeValue);
+ $content = htmlspecialchars($content);
+
+ // Allow em tags only.
+ $content = str_replace('<em>', '', $content);
+ $content = str_replace('</em>', '', $content);
+
+ echo "