diff --git a/.gitignore b/.gitignore index b2e0093..cf21d23 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ wp-content/plugins/hello.php .idea vendor/ +node_modules/ diff --git a/composer.json b/composer.json index e53a243..d44c610 100644 --- a/composer.json +++ b/composer.json @@ -3,26 +3,33 @@ "description": "WooCommerce product tables feature plugin", "homepage": "https://github.com/woocommerce/woocommerce-product-tables-feature-plugin", "type": "wordpress-plugin", - "license": "GPL-2.0+", + "license": "GPL-3.0+", + "require": { + "php": ">=5.6|>=7.0" + }, "require-dev": { - "wp-coding-standards/wpcs": "0.14.1", - "woocommerce/woocommerce-git-hooks": "1.0.5", - "phpunit/phpunit": "^6.5" + "phpunit/phpunit": "8.3.5", + "woocommerce/woocommerce-sniffs": "0.0.9" }, "scripts": { - "pre-update-cmd": [ - "WooCommerce\\GitHooks\\Hooks::preHooks" + "test": [ + "phpunit" ], - "pre-install-cmd": [ - "WooCommerce\\GitHooks\\Hooks::preHooks" + "phpcs": [ + "phpcs -s -p" ], - "post-install-cmd": [ - "\"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs", - "WooCommerce\\GitHooks\\Hooks::postHooks" + "phpcs-pre-commit": [ + "phpcs -s -p -n" ], - "post-update-cmd": [ - "\"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs", - "WooCommerce\\GitHooks\\Hooks::postHooks" + "phpcbf": [ + "phpcbf -p" ] + }, + "extra": { + "scripts-description": { + "test": "Run unit tests", + "phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer", + "phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier" + } } } diff --git a/composer.lock b/composer.lock index 307d59a..7202976 100644 --- a/composer.lock +++ b/composer.lock @@ -1,35 +1,103 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c23ce38320817826e7d4dce85bb826f1", + "content-hash": "12bd22039c067eb5d611b630331237d2", "packages": [], "packages-dev": [ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.5.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" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "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" + ], + "time": "2018-10-26T13:21:45+00:00" + }, { "name": "doctrine/instantiator", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + "reference": "a2c590166b2133a4633738648b6b064edae0814a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", + "reference": "a2c590166b2133a4633738648b6b064edae0814a", "shasum": "" }, "require": { "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "^6.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { @@ -54,34 +122,37 @@ } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", "keywords": [ "constructor", "instantiate" ], - "time": "2017-07-22T11:58:36+00:00" + "time": "2019-03-17T17:37:11+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.7.0", + "version": "1.9.3", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", + "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" + "phpunit/phpunit": "^7.1" }, "type": "library", "autoload": { @@ -104,26 +175,26 @@ "object", "object graph" ], - "time": "2017-10-19T19:58:43+00:00" + "time": "2019-08-09T12:45:53+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.1", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^1.0.1", + "phar-io/version": "^2.0", "php": "^5.6 || ^7.0" }, "type": "library", @@ -159,20 +230,20 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", - "version": "1.0.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "shasum": "" }, "require": { @@ -206,39 +277,197 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.3.3", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "1af08ca3861048a8bfb39d0405d0ac3e50ba2696" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/1af08ca3861048a8bfb39d0405d0ac3e50ba2696", + "reference": "1af08ca3861048a8bfb39d0405d0ac3e50ba2696", + "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.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + } + ], + "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" + ], + "time": "2019-11-11T03:25:23+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-paragonie", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", + "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/b862bc32f7e860d0b164b199bd995e690b4b191c", + "reference": "b862bc32f7e860d0b164b199bd995e690b4b191c", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5", + "paragonie/random_compat": "dev-master", + "paragonie/sodium_compat": "dev-master" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || 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." + }, + "type": "phpcodesniffer-standard", + "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" + ], + "time": "2019-11-04T15:17:54+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-wp", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", + "reference": "41bef18ba688af638b7310666db28e1ea9158b2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/41bef18ba688af638b7310666db28e1ea9158b2f", + "reference": "41bef18ba688af638b7310666db28e1ea9158b2f", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/phpcompatibility-paragonie": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || 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." + }, + "type": "phpcodesniffer-standard", + "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" + ], + "time": "2019-08-28T14:22:28+00:00" }, { "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "~6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -260,30 +489,30 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-08-07T13:53:10+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.0", + "version": "4.3.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", - "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", "shasum": "" }, "require": { "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", "webmozart/assert": "^1.0" }, "require-dev": { - "doctrine/instantiator": "~1.0.5", + "doctrine/instantiator": "^1.0.5", "mockery/mockery": "^1.0", "phpunit/phpunit": "^6.4" }, @@ -311,41 +540,40 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-30T07:14:17+00:00" + "time": "2019-09-12T14:27:41+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -358,42 +586,43 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-08-22T18:11:29+00:00" }, { "name": "phpspec/prophecy", - "version": "1.7.5", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401" + "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401", - "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", + "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { - "psr-0": { - "Prophecy\\": "src/" + "psr-4": { + "Prophecy\\": "src/Prophecy" } }, "notification-url": "https://packagist.org/downloads/", @@ -421,44 +650,44 @@ "spy", "stub" ], - "time": "2018-02-19T10:16:54+00:00" + "time": "2019-06-13T12:50:23+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "5.3.0", + "version": "7.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1" + "reference": "7743bbcfff2a907e9ee4a25be13d0f8ec5e73800" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/661f34d0bd3f1a7225ef491a70a020ad23a057a1", - "reference": "661f34d0bd3f1a7225ef491a70a020ad23a057a1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7743bbcfff2a907e9ee4a25be13d0f8ec5e73800", + "reference": "7743bbcfff2a907e9ee4a25be13d0f8ec5e73800", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", + "phpunit/php-token-stream": "^3.1.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", + "sebastian/environment": "^4.2.2", "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "theseer/tokenizer": "^1.1.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^8.2.2" }, "suggest": { - "ext-xdebug": "^2.5.5" + "ext-xdebug": "^2.7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3.x-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -484,29 +713,32 @@ "testing", "xunit" ], - "time": "2017-12-06T09:29:45+00:00" + "time": "2019-07-25T05:31:54+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "050bedf145a257b1ff02746c31894800e5122946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -521,7 +753,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -531,7 +763,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2018-09-13T20:33:42+00:00" }, { "name": "phpunit/php-text-template", @@ -576,28 +808,28 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.9", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -612,7 +844,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -621,33 +853,33 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2019-06-07T04:22:29+00:00" }, { "name": "phpunit/php-token-stream", - "version": "2.0.2", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" + "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e899757bb3df5ff6e95089132f32cd59aac2220a", + "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.2.4" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -670,57 +902,56 @@ "keywords": [ "tokenizer" ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2019-07-25T05:29:42+00:00" }, { "name": "phpunit/phpunit", - "version": "6.5.7", + "version": "8.3.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "6bd77b57707c236833d2b57b968e403df060c9d9" + "reference": "302faed7059fde575cf3403a78c730c5e3a62750" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6bd77b57707c236833d2b57b968e403df060c9d9", - "reference": "6bd77b57707c236833d2b57b968e403df060c9d9", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/302faed7059fde575cf3403a78c730c5e3a62750", + "reference": "302faed7059fde575cf3403a78c730c5e3a62750", "shasum": "" }, "require": { + "doctrine/instantiator": "^1.2.0", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "php": "^7.2", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^7.0.7", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.5", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.2", + "sebastian/exporter": "^3.1.1", + "sebastian/global-state": "^3.0.0", "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", "sebastian/version": "^2.0.1" }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" - }, "require-dev": { "ext-pdo": "*" }, "suggest": { + "ext-soap": "*", "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" + "phpunit/php-invoker": "^2.0.0" }, "bin": [ "phpunit" @@ -728,7 +959,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.5.x-dev" + "dev-master": "8.3-dev" } }, "autoload": { @@ -754,66 +985,7 @@ "testing", "xunit" ], - "time": "2018-02-26T07:01:09+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "33fd41a76e746b8fa96d00b49a23dadfa8334cdf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/33fd41a76e746b8fa96d00b49a23dadfa8334cdf", - "reference": "33fd41a76e746b8fa96d00b49a23dadfa8334cdf", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2018-01-06T05:45:45+00:00" + "time": "2019-09-14T09:12:03+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -862,30 +1034,30 @@ }, { "name": "sebastian/comparator", - "version": "2.1.3", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", + "php": "^7.1", + "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -922,32 +1094,33 @@ "compare", "equality" ], - "time": "2018-02-01T13:46:46+00:00" + "time": "2018-07-12T15:12:46+00:00" }, { "name": "sebastian/diff", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -972,34 +1145,40 @@ "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2017-08-03T08:09:46+00:00" + "time": "2019-02-04T06:01:07+00:00" }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", + "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1024,20 +1203,20 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "time": "2019-05-05T09:05:15+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", - "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", "shasum": "" }, "require": { @@ -1064,6 +1243,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1072,17 +1255,13 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", @@ -1091,27 +1270,30 @@ "export", "exporter" ], - "time": "2017-04-03T13:19:02+00:00" + "time": "2019-09-14T09:02:43+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^8.0" }, "suggest": { "ext-uopz": "*" @@ -1119,7 +1301,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1142,7 +1324,7 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "time": "2019-02-01T05:30:01+00:00" }, { "name": "sebastian/object-enumerator", @@ -1291,25 +1473,25 @@ }, { "name": "sebastian/resource-operations", - "version": "1.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1329,7 +1511,53 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2018-10-04T04:07:39+00:00" + }, + { + "name": "sebastian/type", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "time": "2019-07-02T08:10:15+00:00" }, { "name": "sebastian/version", @@ -1376,16 +1604,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.2.3", + "version": "3.5.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "4842476c434e375f9d3182ff7b89059583aa8b27" + "reference": "65b12cdeaaa6cd276d4c3033a95b9b88b12701e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4842476c434e375f9d3182ff7b89059583aa8b27", - "reference": "4842476c434e375f9d3182ff7b89059583aa8b27", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/65b12cdeaaa6cd276d4c3033a95b9b88b12701e7", + "reference": "65b12cdeaaa6cd276d4c3033a95b9b88b12701e7", "shasum": "" }, "require": { @@ -1418,25 +1646,83 @@ } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], - "time": "2018-02-20T21:35:23+00:00" + "time": "2019-10-28T04:36:32+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-08-06T08:03:45+00:00" }, { "name": "theseer/tokenizer", - "version": "1.1.0", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", - "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", "shasum": "" }, "require": { @@ -1463,28 +1749,28 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2017-04-07T12:08:54+00:00" + "time": "2019-06-13T22:48:21+00:00" }, { "name": "webmozart/assert", - "version": "1.3.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", - "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", + "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" }, "require-dev": { - "phpunit/phpunit": "^4.6", - "sebastian/version": "^1.0.1" + "phpunit/phpunit": "^4.8.36 || ^7.5.13" }, "type": "library", "extra": { @@ -1513,28 +1799,29 @@ "check", "validate" ], - "time": "2018-01-29T19:49:41+00:00" + "time": "2019-08-24T08:43:50+00:00" }, { - "name": "woocommerce/woocommerce-git-hooks", - "version": "1.0.5", + "name": "woocommerce/woocommerce-sniffs", + "version": "0.0.9", "source": { "type": "git", - "url": "https://github.com/woocommerce/woocommerce-git-hooks.git", - "reference": "1e55118258e8487c68b17c06cfde3b48a692d9d4" + "url": "https://github.com/woocommerce/woocommerce-sniffs.git", + "reference": "7677a84e9a355fe1e088f704090be891e7a6d427" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/woocommerce/woocommerce-git-hooks/zipball/1e55118258e8487c68b17c06cfde3b48a692d9d4", - "reference": "1e55118258e8487c68b17c06cfde3b48a692d9d4", + "url": "https://api.github.com/repos/woocommerce/woocommerce-sniffs/zipball/7677a84e9a355fe1e088f704090be891e7a6d427", + "reference": "7677a84e9a355fe1e088f704090be891e7a6d427", "shasum": "" }, - "type": "scripts", - "autoload": { - "psr-4": { - "WooCommerce\\GitHooks\\": "src/" - } + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "0.5.0", + "php": ">=7.0", + "phpcompatibility/phpcompatibility-wp": "2.1.0", + "wp-coding-standards/wpcs": "2.2.0" }, + "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" @@ -1545,29 +1832,40 @@ "email": "claudio@automattic.com" } ], - "description": "WooCommerce Git Hooks", - "time": "2017-12-18T16:55:42+00:00" + "description": "WooCommerce sniffs", + "keywords": [ + "phpcs", + "standards", + "woocommerce", + "wordpress" + ], + "time": "2019-11-11T15:48:34+00:00" }, { "name": "wp-coding-standards/wpcs", - "version": "0.14.1", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", - "reference": "cf6b310caad735816caef7573295f8a534374706" + "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", + "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/cf6b310caad735816caef7573295f8a534374706", - "reference": "cf6b310caad735816caef7573295f8a534374706", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/f90e8692ce97b693633db7ab20bfa78d930f536a", + "reference": "f90e8692ce97b693633db7ab20bfa78d930f536a", "shasum": "" }, "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" + "php": ">=5.4", + "squizlabs/php_codesniffer": "^3.3.1" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "phpcompatibility/php-compatibility": "^9.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3" + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." }, "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", @@ -1577,7 +1875,7 @@ "authors": [ { "name": "Contributors", - "homepage": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/graphs/contributors" + "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" } ], "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", @@ -1586,7 +1884,7 @@ "standards", "wordpress" ], - "time": "2018-02-16T01:57:48+00:00" + "time": "2019-11-11T12:34:03+00:00" } ], "aliases": [], @@ -1594,6 +1892,8 @@ "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, - "platform": [], + "platform": { + "php": ">=5.6|>=7.0" + }, "platform-dev": [] } diff --git a/includes/admin/meta-boxes/class-wc-product-tables-meta-box-product-data.php b/includes/admin/meta-boxes/class-wc-product-tables-meta-box-product-data.php new file mode 100644 index 0000000..df8fdf0 --- /dev/null +++ b/includes/admin/meta-boxes/class-wc-product-tables-meta-box-product-data.php @@ -0,0 +1,32 @@ +set_image_id( isset( $_POST['_thumbnail_id'] ) ? intval( $_POST['_thumbnail_id'] ) : 0 ); // phpcs:ignore WordPress.Security.NonceVerification.Missing + } +} + +WC_Product_Tables_Meta_Box_Product_Data::init(); diff --git a/includes/class-wc-product-tables-backwards-compatibility.php b/includes/class-wc-product-tables-backwards-compatibility.php index ff40a7f..e79ab82 100644 --- a/includes/class-wc-product-tables-backwards-compatibility.php +++ b/includes/class-wc-product-tables-backwards-compatibility.php @@ -11,16 +11,33 @@ class WC_Product_Tables_Backwards_Compatibility { /** - * WC_Product_Tables_Backwards_Compatibility constructor. + * Field mapping. + * + * @var array + */ + protected static $mapping; + + /** + * Hook into WP meta filters. */ - public function __construct() { + public static function hook() { if ( ! apply_filters( 'woocommerce_product_tables_enable_backward_compatibility', true ) || defined( 'WC_PRODUCT_TABLES_DISABLE_BW_COMPAT' ) ) { return; } - add_filter( 'get_post_metadata', array( $this, 'get_metadata_from_tables' ), 99, 4 ); - add_filter( 'add_post_metadata', array( $this, 'add_metadata_to_tables' ), 99, 5 ); - add_filter( 'update_post_metadata', array( $this, 'update_metadata_in_tables' ), 99, 5 ); - add_filter( 'delete_post_metadata', array( $this, 'delete_metadata_from_tables' ), 99, 5 ); + add_filter( 'get_post_metadata', array( __CLASS__, 'get_metadata_from_tables' ), 99, 4 ); + add_filter( 'add_post_metadata', array( __CLASS__, 'add_metadata_to_tables' ), 99, 5 ); + add_filter( 'update_post_metadata', array( __CLASS__, 'update_metadata_in_tables' ), 99, 5 ); + add_filter( 'delete_post_metadata', array( __CLASS__, 'delete_metadata_from_tables' ), 99, 5 ); + } + + /** + * Unhook WP meta filters. + */ + public static function unhook() { + remove_filter( 'get_post_metadata', array( __CLASS__, 'get_metadata_from_tables' ), 99, 4 ); + remove_filter( 'add_post_metadata', array( __CLASS__, 'add_metadata_to_tables' ), 99, 5 ); + remove_filter( 'update_post_metadata', array( __CLASS__, 'update_metadata_in_tables' ), 99, 5 ); + remove_filter( 'delete_post_metadata', array( __CLASS__, 'delete_metadata_from_tables' ), 99, 5 ); } /** @@ -32,9 +49,10 @@ public function __construct() { * @param bool $single Whether to return a single value. * @return string|array */ - public function get_metadata_from_tables( $result, $post_id, $meta_key, $single ) { - $mapping = $this->get_mapping(); - if ( WC_Product_Tables_Migrate_Data::$migrating || ! isset( $mapping[ $meta_key ] ) ) { + public static function get_metadata_from_tables( $result, $post_id, $meta_key, $single ) { + $mapping = self::get_mapping(); + + if ( ! isset( $mapping[ $meta_key ] ) ) { return $result; } @@ -45,7 +63,7 @@ public function get_metadata_from_tables( $result, $post_id, $meta_key, $single $query_results = call_user_func( $mapped_func, $args ); if ( $single && $query_results ) { - return $query_results[0]; + return ( is_array( $query_results ) ) ? $query_results[0] : $query_results; } if ( $single && empty( $query_results ) ) { @@ -65,14 +83,15 @@ public function get_metadata_from_tables( $result, $post_id, $meta_key, $single * @param bool $unique Whether the same key should not be added. * @return array|bool */ - public function add_metadata_to_tables( $result, $post_id, $meta_key, $meta_value, $unique ) { - $mapping = $this->get_mapping(); - if ( WC_Product_Tables_Migrate_Data::$migrating || ! isset( $mapping[ $meta_key ] ) ) { + public static function add_metadata_to_tables( $result, $post_id, $meta_key, $meta_value, $unique ) { + $mapping = self::get_mapping(); + + if ( ! isset( $mapping[ $meta_key ] ) ) { return $result; } if ( $unique ) { - $existing = $this->get_metadata_from_tables( null, $post_id, $meta_key, false ); + $existing = self::get_metadata_from_tables( null, $post_id, $meta_key, false ); if ( $existing ) { return false; } @@ -96,9 +115,10 @@ public function add_metadata_to_tables( $result, $post_id, $meta_key, $meta_valu * @param mixed $prev_value Previous value to check before removing. * @return array|bool */ - public function update_metadata_in_tables( $result, $post_id, $meta_key, $meta_value, $prev_value ) { - $mapping = $this->get_mapping(); - if ( WC_Product_Tables_Migrate_Data::$migrating || ! isset( $mapping[ $meta_key ] ) ) { + public static function update_metadata_in_tables( $result, $post_id, $meta_key, $meta_value, $prev_value ) { + $mapping = self::get_mapping(); + + if ( ! isset( $mapping[ $meta_key ] ) ) { return $result; } @@ -121,9 +141,10 @@ public function update_metadata_in_tables( $result, $post_id, $meta_key, $meta_v * @param bool $delete_all Delete all metadata. * @return array|bool */ - public function delete_metadata_from_tables( $result, $post_id, $meta_key, $prev_value, $delete_all ) { - $mapping = $this->get_mapping(); - if ( WC_Product_Tables_Migrate_Data::$migrating || ! isset( $mapping[ $meta_key ] ) ) { + public static function delete_metadata_from_tables( $result, $post_id, $meta_key, $prev_value, $delete_all ) { + $mapping = self::get_mapping(); + + if ( ! isset( $mapping[ $meta_key ] ) ) { return $result; } @@ -152,7 +173,7 @@ public function delete_metadata_from_tables( $result, $post_id, $meta_key, $prev * } * @return array */ - public function get_from_product_table( $args ) { + public static function get_from_product_table( $args ) { global $wpdb; $defaults = array( @@ -165,6 +186,14 @@ public function get_from_product_table( $args ) { return array(); } + // Look in cache for table. + $cached_data = (array) wp_cache_get( 'woocommerce_product_' . $args['product_id'], 'product' ); + + if ( isset( $cached_data[ $args['column'] ] ) ) { + return $cached_data[ $args['column'] ]; + } + + // Look in cache for bw compat table. $data = wp_cache_get( 'woocommerce_product_backwards_compatibility_' . $args['product_id'], 'product' ); if ( false === $data ) { @@ -172,7 +201,13 @@ public function get_from_product_table( $args ) { } if ( empty( $data[ $args['column'] ] ) ) { - $data[ $args['column'] ] = $wpdb->get_col( $wpdb->prepare( 'SELECT `' . esc_sql( $args['column'] ) . "` from {$wpdb->prefix}wc_products WHERE product_id = %d", $args['product_id'] ) ); // WPCS: db call ok. + $escaped_column = '`' . esc_sql( $args['column'] ) . '`'; + $data[ $args['column'] ] = $wpdb->get_col( + $wpdb->prepare( + "SELECT {$escaped_column} FROM {$wpdb->prefix}wc_products WHERE product_id = %d", // phpcs:ignore + $args['product_id'] + ) + ); wp_cache_set( 'woocommerce_product_backwards_compatibility_' . $args['product_id'], $data, 'product' ); } @@ -193,7 +228,7 @@ public function get_from_product_table( $args ) { * } * @return bool */ - public function update_in_product_table( $args ) { + public static function update_in_product_table( $args ) { global $wpdb; $defaults = array( @@ -261,7 +296,7 @@ public function update_in_product_table( $args ) { * } * @return array */ - public function get_from_relationship_table( $args ) { + public static function get_from_relationship_table( $args ) { global $wpdb; $defaults = array( @@ -301,7 +336,7 @@ public function get_from_relationship_table( $args ) { * } * @return bool */ - public function update_relationship_table( $args ) { + public static function update_relationship_table( $args ) { global $wpdb; $defaults = array( @@ -373,7 +408,7 @@ public function update_relationship_table( $args ) { * } * @return array */ - public function get_variation_description( $args ) { + public static function get_variation_description( $args ) { $defaults = array( 'product_id' => 0, ); @@ -397,7 +432,7 @@ public function get_variation_description( $args ) { * } * @return bool */ - public function set_variation_description( $args ) { + public static function set_variation_description( $args ) { global $wpdb; $defaults = array( @@ -435,7 +470,7 @@ public function set_variation_description( $args ) { // Check for previous value while deleting or updating. if ( ! empty( $args['prev_value'] ) ) { - $description = $this->get_variation_description( $args ); + $description = self::get_variation_description( $args ); if ( $args['prev_value'] !== $description[0] ) { return false; @@ -461,7 +496,7 @@ public function set_variation_description( $args ) { * } * @return array */ - public function get_manage_stock( $args ) { + public static function get_manage_stock( $args ) { $defaults = array( 'product_id' => 0, ); @@ -472,7 +507,7 @@ public function get_manage_stock( $args ) { } $args['column'] = 'stock_quantity'; - $stock = $this->get_from_product_table( $args ); + $stock = self::get_from_product_table( $args ); if ( ! empty( $stock ) && is_numeric( $stock[0] ) ) { return array( true ); } @@ -491,7 +526,7 @@ public function get_manage_stock( $args ) { * } * @return bool */ - public function set_manage_stock( $args ) { + public static function set_manage_stock( $args ) { $defaults = array( 'product_id' => 0, 'value' => false, @@ -507,14 +542,14 @@ public function set_manage_stock( $args ) { if ( $args['value'] ) { $args['value'] = 0; $args['format'] = '%d'; - return $this->update_in_product_table( $args ); + return self::update_in_product_table( $args ); } // Set stock_quantity to NULL if not managing stock. $args['value'] = null; $args['format'] = ''; - return $this->update_in_product_table( $args ); + return self::update_in_product_table( $args ); } /** @@ -527,7 +562,7 @@ public function set_manage_stock( $args ) { * } * @return array */ - public function get_downloadable_files( $args ) { + public static function get_downloadable_files( $args ) { global $wpdb; $defaults = array( @@ -571,7 +606,7 @@ public function get_downloadable_files( $args ) { * } * @return bool */ - public function update_downloadable_files( $args ) { + public static function update_downloadable_files( $args ) { global $wpdb; $defaults = array( @@ -651,7 +686,7 @@ public function update_downloadable_files( $args ) { * } * @return array */ - public function get_product_attributes( $args ) { + public static function get_product_attributes( $args ) { $defaults = array( 'product_id' => 0, ); @@ -660,8 +695,7 @@ public function get_product_attributes( $args ) { if ( ! $args['product_id'] ) { return array(); } - - $product = wc_get_product( $args['product_id'] ); + $product = self::get_product( $args['product_id'] ); if ( ! $product ) { return array(); } @@ -694,7 +728,7 @@ public function get_product_attributes( $args ) { * } * @return bool */ - public function update_product_attributes( $args ) { + public static function update_product_attributes( $args ) { $defaults = array( 'product_id' => 0, 'value' => array(), @@ -708,7 +742,7 @@ public function update_product_attributes( $args ) { $product_id = $args['product_id']; $attributes = $args['value']; - $product = wc_get_product( $product_id ); + $product = self::get_product( $product_id ); if ( ! $product ) { return false; } @@ -742,7 +776,7 @@ public function update_product_attributes( $args ) { * } * @return array */ - public function get_product_default_attributes( $args ) { + public static function get_product_default_attributes( $args ) { $defaults = array( 'product_id' => 0, ); @@ -752,7 +786,7 @@ public function get_product_default_attributes( $args ) { return array(); } - $product = wc_get_product( $args['product_id'] ); + $product = self::get_product( $args['product_id'] ); if ( $product ) { return array( array( $product->get_default_attributes( 'edit' ) ) ); } @@ -771,7 +805,7 @@ public function get_product_default_attributes( $args ) { * } * @return bool */ - public function update_product_default_attributes( $args ) { + public static function update_product_default_attributes( $args ) { $defaults = array( 'product_id' => 0, 'value' => array(), @@ -782,7 +816,7 @@ public function update_product_default_attributes( $args ) { return false; } - $product = wc_get_product( $args['product_id'] ); + $product = self::get_product( $args['product_id'] ); if ( $product ) { $product->set_default_attributes( $args['value'] ); $product->save(); @@ -797,35 +831,68 @@ public function update_product_default_attributes( $args ) { * * @return array */ - protected function get_mapping() { - return array( + protected static function get_mapping() { + if ( self::$mapping ) { + return self::$mapping; + } + self::$mapping = array( /** * In product table. */ + '_thumbnail_id' => array( + 'get' => array( + 'function' => array( __CLASS__, 'get_from_product_table' ), + 'args' => array( + 'column' => 'image_id', + ), + ), + 'add' => array( + 'function' => array( __CLASS__, 'update_in_product_table' ), + 'args' => array( + 'column' => 'image_id', + 'format' => '%d', + ), + ), + 'update' => array( + 'function' => array( __CLASS__, 'update_in_product_table' ), + 'args' => array( + 'column' => 'image_id', + 'format' => '%d', + ), + ), + 'delete' => array( + 'function' => array( __CLASS__, 'update_in_product_table' ), + 'args' => array( + 'column' => 'image_id', + 'format' => '%d', + 'value' => '', + ), + ), + ), '_sku' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'sku', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'sku', 'format' => '%s', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'sku', 'format' => '%s', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'sku', 'format' => '%s', @@ -835,27 +902,27 @@ protected function get_mapping() { ), '_price' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'price', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'price', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'price', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'price', 'format' => '', @@ -865,27 +932,27 @@ protected function get_mapping() { ), '_regular_price' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'regular_price', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'regular_price', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'regular_price', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'regular_price', 'format' => '', @@ -895,27 +962,27 @@ protected function get_mapping() { ), '_sale_price' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'sale_price', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'sale_price', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'sale_price', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'sale_price', 'format' => '', @@ -925,27 +992,27 @@ protected function get_mapping() { ), '_sale_price_dates_from' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'date_on_sale_from', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'date_on_sale_from', - 'format' => '%d', + 'format' => '%s', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'date_on_sale_from', - 'format' => '%d', + 'format' => '%s', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'date_on_sale_from', 'format' => '', @@ -955,27 +1022,27 @@ protected function get_mapping() { ), '_sale_price_dates_to' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'date_on_sale_to', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'date_on_sale_to', 'format' => '%s', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'date_on_sale_to', 'format' => '%s', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'date_on_sale_to', 'format' => '', @@ -985,27 +1052,27 @@ protected function get_mapping() { ), 'total_sales' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'total_sales', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'total_sales', 'format' => '%d', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'total_sales', 'format' => '%d', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'total_sales', 'format' => '%d', @@ -1015,27 +1082,27 @@ protected function get_mapping() { ), '_tax_status' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'tax_status', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'tax_status', 'format' => '%s', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'tax_status', 'format' => '%s', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'tax_status', 'format' => '%s', @@ -1045,27 +1112,27 @@ protected function get_mapping() { ), '_tax_class' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'tax_class', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'tax_class', 'format' => '%s', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'tax_class', 'format' => '%s', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'tax_class', 'format' => '%s', @@ -1075,27 +1142,27 @@ protected function get_mapping() { ), '_stock' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'stock_quantity', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'stock_quantity', 'format' => '%d', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'stock_quantity', 'format' => '%d', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'stock_quantity', 'format' => '', @@ -1105,27 +1172,27 @@ protected function get_mapping() { ), '_stock_status' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'stock_status', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'stock_status', 'format' => '%s', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'stock_status', 'format' => '%s', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'stock_status', 'format' => '%s', @@ -1135,27 +1202,27 @@ protected function get_mapping() { ), '_length' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'length', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'length', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'length', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'length', 'format' => '', @@ -1165,27 +1232,27 @@ protected function get_mapping() { ), '_width' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'width', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'width', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'width', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'width', 'format' => '', @@ -1195,27 +1262,27 @@ protected function get_mapping() { ), '_height' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'height', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'height', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'height', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'height', 'format' => '', @@ -1225,27 +1292,27 @@ protected function get_mapping() { ), '_weight' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'weight', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'weight', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'weight', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'weight', 'format' => '', @@ -1255,27 +1322,27 @@ protected function get_mapping() { ), '_virtual' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'virtual', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'virtual', 'format' => '%d', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'virtual', 'format' => '%d', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'virtual', 'format' => '%d', @@ -1285,27 +1352,27 @@ protected function get_mapping() { ), '_downloadable' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'downloadable', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'downloadable', 'format' => '%d', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'downloadable', 'format' => '%d', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'downloadable', 'format' => '%d', @@ -1315,27 +1382,27 @@ protected function get_mapping() { ), '_wc_average_rating' => array( 'get' => array( - 'function' => array( $this, 'get_from_product_table' ), + 'function' => array( __CLASS__, 'get_from_product_table' ), 'args' => array( 'column' => 'average_rating', ), ), 'add' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'average_rating', 'format' => '%f', ), ), 'update' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'average_rating', 'format' => '%f', ), ), 'delete' => array( - 'function' => array( $this, 'update_in_product_table' ), + 'function' => array( __CLASS__, 'update_in_product_table' ), 'args' => array( 'column' => 'average_rating', 'format' => '%f', @@ -1349,25 +1416,25 @@ protected function get_mapping() { */ '_upsell_ids' => array( 'get' => array( - 'function' => array( $this, 'get_from_relationship_table' ), + 'function' => array( __CLASS__, 'get_from_relationship_table' ), 'args' => array( 'type' => 'upsell', ), ), 'add' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'upsell', ), ), 'update' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'upsell', ), ), 'delete' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'upsell', 'value' => array(), @@ -1376,25 +1443,25 @@ protected function get_mapping() { ), '_crosssell_ids' => array( 'get' => array( - 'function' => array( $this, 'get_from_relationship_table' ), + 'function' => array( __CLASS__, 'get_from_relationship_table' ), 'args' => array( 'type' => 'cross_sell', ), ), 'add' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'cross_sell', ), ), 'update' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'cross_sell', ), ), 'delete' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'cross_sell', 'value' => array(), @@ -1403,25 +1470,25 @@ protected function get_mapping() { ), '_product_image_gallery' => array( 'get' => array( - 'function' => array( $this, 'get_from_relationship_table' ), + 'function' => array( __CLASS__, 'get_from_relationship_table' ), 'args' => array( 'type' => 'image', ), ), 'add' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'image', ), ), 'update' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'image', ), ), 'delete' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'image', 'value' => array(), @@ -1430,25 +1497,25 @@ protected function get_mapping() { ), '_children' => array( 'get' => array( - 'function' => array( $this, 'get_from_relationship_table' ), + 'function' => array( __CLASS__, 'get_from_relationship_table' ), 'args' => array( 'type' => 'grouped', ), ), 'add' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'grouped', ), ), 'update' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'grouped', ), ), 'delete' => array( - 'function' => array( $this, 'update_relationship_table' ), + 'function' => array( __CLASS__, 'update_relationship_table' ), 'args' => array( 'type' => 'grouped', 'value' => array(), @@ -1461,19 +1528,19 @@ protected function get_mapping() { */ '_downloadable_files' => array( 'get' => array( - 'function' => array( $this, 'get_downloadable_files' ), + 'function' => array( __CLASS__, 'get_downloadable_files' ), 'args' => array(), ), 'add' => array( - 'function' => array( $this, 'update_downloadable_files' ), + 'function' => array( __CLASS__, 'update_downloadable_files' ), 'args' => array(), ), 'update' => array( - 'function' => array( $this, 'update_downloadable_files' ), + 'function' => array( __CLASS__, 'update_downloadable_files' ), 'args' => array(), ), 'delete' => array( - 'function' => array( $this, 'update_downloadable_files' ), + 'function' => array( __CLASS__, 'update_downloadable_files' ), 'args' => array( 'value' => array(), ), @@ -1481,19 +1548,19 @@ protected function get_mapping() { ), '_variation_description' => array( 'get' => array( - 'function' => array( $this, 'get_variation_description' ), + 'function' => array( __CLASS__, 'get_variation_description' ), 'args' => array(), ), 'add' => array( - 'function' => array( $this, 'set_variation_description' ), + 'function' => array( __CLASS__, 'set_variation_description' ), 'args' => array(), ), 'update' => array( - 'function' => array( $this, 'set_variation_description' ), + 'function' => array( __CLASS__, 'set_variation_description' ), 'args' => array(), ), 'delete' => array( - 'function' => array( $this, 'set_variation_description' ), + 'function' => array( __CLASS__, 'set_variation_description' ), 'args' => array( 'value' => '', ), @@ -1501,19 +1568,19 @@ protected function get_mapping() { ), '_manage_stock' => array( 'get' => array( - 'function' => array( $this, 'get_manage_stock' ), + 'function' => array( __CLASS__, 'get_manage_stock' ), 'args' => array(), ), 'add' => array( - 'function' => array( $this, 'set_manage_stock' ), + 'function' => array( __CLASS__, 'set_manage_stock' ), 'args' => array(), ), 'update' => array( - 'function' => array( $this, 'set_manage_stock' ), + 'function' => array( __CLASS__, 'set_manage_stock' ), 'args' => array(), ), 'delete' => array( - 'function' => array( $this, 'set_manage_stock' ), + 'function' => array( __CLASS__, 'set_manage_stock' ), 'args' => array( 'value' => false, ), @@ -1521,19 +1588,19 @@ protected function get_mapping() { ), '_product_attributes' => array( 'get' => array( - 'function' => array( $this, 'get_product_attributes' ), + 'function' => array( __CLASS__, 'get_product_attributes' ), 'args' => array(), ), 'add' => array( - 'function' => array( $this, 'update_product_attributes' ), + 'function' => array( __CLASS__, 'update_product_attributes' ), 'args' => array(), ), 'update' => array( - 'function' => array( $this, 'update_product_attributes' ), + 'function' => array( __CLASS__, 'update_product_attributes' ), 'args' => array(), ), 'delete' => array( - 'function' => array( $this, 'update_product_attributes' ), + 'function' => array( __CLASS__, 'update_product_attributes' ), 'args' => array( 'value' => array(), ), @@ -1541,26 +1608,41 @@ protected function get_mapping() { ), '_default_attributes' => array( 'get' => array( - 'function' => array( $this, 'get_product_default_attributes' ), + 'function' => array( __CLASS__, 'get_product_default_attributes' ), 'args' => array(), ), 'add' => array( - 'function' => array( $this, 'update_product_default_attributes' ), + 'function' => array( __CLASS__, 'update_product_default_attributes' ), 'args' => array(), ), 'update' => array( - 'function' => array( $this, 'update_product_default_attributes' ), + 'function' => array( __CLASS__, 'update_product_default_attributes' ), 'args' => array(), ), 'delete' => array( - 'function' => array( $this, 'update_product_default_attributes' ), + 'function' => array( __CLASS__, 'update_product_default_attributes' ), 'args' => array( 'value' => array(), ), ), ), ); + return self::$mapping; + } + + /** + * Helper method to prevent infinite recursion with meta filters + * + * @param int $product_id Product ID. + * @return WC_Product + */ + protected static function get_product( $product_id ) { + self::unhook(); + $product = wc_get_product( $product_id ); + self::hook(); + + return $product; } } -new WC_Product_Tables_Backwards_Compatibility(); +WC_Product_Tables_Backwards_Compatibility::hook(); diff --git a/includes/class-wc-product-tables-bootstrap.php b/includes/class-wc-product-tables-bootstrap.php index b7b3487..9857e98 100644 --- a/includes/class-wc-product-tables-bootstrap.php +++ b/includes/class-wc-product-tables-bootstrap.php @@ -4,8 +4,7 @@ * * Loads everything needed for the plugin to function. * - * @package WooCommerce Product Tables Feature Plugin - * @author Automattic + * @package WooCommerce_Product_Tables_Feature_Plugin */ if ( ! defined( 'ABSPATH' ) ) { @@ -33,6 +32,7 @@ public function includes() { include_once dirname( __FILE__ ) . '/class-wc-product-tables-install.php'; include_once dirname( __FILE__ ) . '/class-wc-product-tables-migrate-data.php'; include_once dirname( __FILE__ ) . '/class-wc-product-tables-query.php'; + include_once dirname( __FILE__ ) . '/class-wc-product-tables-post-data.php'; include_once dirname( __FILE__ ) . '/compatibility/hacks.php'; include_once dirname( __FILE__ ) . '/compatibility/class-wc-product-attribute.php'; @@ -40,6 +40,10 @@ public function includes() { include_once dirname( __FILE__ ) . '/class-wc-product-tables-cli.php'; } + if ( is_admin() ) { + include_once dirname( __FILE__ ) . '/admin/meta-boxes/class-wc-product-tables-meta-box-product-data.php'; + } + $this->query = new WC_Product_Tables_Query(); } diff --git a/includes/class-wc-product-tables-cli.php b/includes/class-wc-product-tables-cli.php index 57153a8..27345e6 100644 --- a/includes/class-wc-product-tables-cli.php +++ b/includes/class-wc-product-tables-cli.php @@ -12,7 +12,7 @@ /** * Provides woocommerce-product-tables-feature-plugin WP-CLI commands. */ -class WC_Product_Tables_Cli { +class WC_Product_Tables_Cli extends WP_CLI_Command { /** * Migrate WooCommerce products from old data structure to the new data structure used by this plugin. @@ -22,19 +22,59 @@ class WC_Product_Tables_Cli { * [--clean-old-data] * : Pass this flag if old data should be removed after the migration * + * [--resume] + * : Pass this flag to resume failed migration without recreating tables + * * @param array $args WP-CLI default args. * @param array $assoc_args WP-CLI default associative args. * @subcommand migrate-data */ public function migrate_data( $args, $assoc_args ) { - $clean_old_data = false; + WC_Product_Tables_Backwards_Compatibility::unhook(); + + $clean_old_data = ! empty( $assoc_args['clean-old-data'] ); + $resume = ! empty( $assoc_args['resume'] ); + + if ( ! $resume ) { + $this->recreate_tables(); + } else { + WC_Product_Tables_Install::activate(); + } - if ( isset( $assoc_args['clean-old-data'] ) && $assoc_args['clean-old-data'] ) { - $clean_old_data = true; + $count = 0; + $products = WC_Product_Tables_Migrate_Data::get_products( 'product' ); + + WP_CLI::line( 'Found ' . count( $products ) . ' products to migrate.' ); + + $progress = \WP_CLI\Utils\make_progress_bar( 'Migrating products', count( $products ) ); + + foreach ( $products as $product ) { + WC_Product_Tables_Migrate_Data::migrate_product( $product, $clean_old_data ); + $progress->tick(); + $count ++; } - $this->recreate_tables(); - WC_Product_Tables_Migrate_Data::migrate( $clean_old_data ); + $progress->finish(); + + $variations = WC_Product_Tables_Migrate_Data::get_products( 'product_variation' ); + + WP_CLI::line( 'Found ' . count( $variations ) . ' variations to migrate.' ); + + $progress = \WP_CLI\Utils\make_progress_bar( 'Migrating variations', count( $variations ) ); + + foreach ( $variations as $product ) { + WC_Product_Tables_Migrate_Data::migrate_product( $product, $clean_old_data ); + $progress->tick(); + $count ++; + } + + wp_cache_flush(); + wc_delete_product_transients(); + + $progress->finish(); + WP_CLI::success( $count . ' products and variations migrated.' ); + + WC_Product_Tables_Backwards_Compatibility::hook(); } /** @@ -44,7 +84,8 @@ public function migrate_data( $args, $assoc_args ) { */ public function recreate_tables() { global $wpdb; - $wpdb->query( "DROP TABLE {$wpdb->prefix}wc_products, {$wpdb->prefix}wc_product_downloads, {$wpdb->prefix}wc_product_attributes, {$wpdb->prefix}wc_product_relationships, {$wpdb->prefix}wc_product_attribute_values, {$wpdb->prefix}wc_product_variation_attribute_values" ); + WP_CLI::line( 'Recreating product tables.' ); + $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wc_products, {$wpdb->prefix}wc_product_downloads, {$wpdb->prefix}wc_product_attributes, {$wpdb->prefix}wc_product_relationships, {$wpdb->prefix}wc_product_attribute_values, {$wpdb->prefix}wc_product_variation_attribute_values" ); WC_Product_Tables_Install::activate(); } } diff --git a/includes/class-wc-product-tables-install.php b/includes/class-wc-product-tables-install.php index 530d138..bbcfbdc 100644 --- a/includes/class-wc-product-tables-install.php +++ b/includes/class-wc-product-tables-install.php @@ -32,23 +32,23 @@ public static function activate() { `product_id` bigint(20) NOT NULL, `sku` varchar(100) NULL default '', `image_id` bigint(20) NULL default 0, - `height` double NULL default NULL, - `width` double NULL default NULL, - `length` double NULL default NULL, - `weight` double NULL default NULL, - `stock_quantity` double NULL default NULL, + `height` decimal(30,14) NULL default NULL, + `width` decimal(30,14) NULL default NULL, + `length` decimal(30,14) NULL default NULL, + `weight` decimal(30,14) NULL default NULL, + `stock_quantity` decimal(30,14) NULL default NULL, `type` varchar(100) NULL default 'simple', `virtual` tinyint(1) NULL default 0, `downloadable` tinyint(1) NULL default 0, `tax_class` varchar(100) NULL default '', `tax_status` varchar(100) NULL default 'taxable', - `total_sales` double NULL default 0, - `price` double NULL default NULL, - `regular_price` double NULL default NULL, - `sale_price` double NULL default NULL, + `total_sales` decimal(30,14) NULL default 0, + `price` decimal(30,14) NULL default NULL, + `regular_price` decimal(30,14) NULL default NULL, + `sale_price` decimal(30,14) NULL default NULL, `date_on_sale_from` datetime NULL default NULL, `date_on_sale_to` datetime NULL default NULL, - `average_rating` float NULL default 0, + `average_rating` decimal(30,14) NULL default 0, `stock_status` varchar(100) NULL default 'instock', PRIMARY KEY (`product_id`), KEY `image_id` (`image_id`), diff --git a/includes/class-wc-product-tables-migrate-data.php b/includes/class-wc-product-tables-migrate-data.php index a9604e3..92898a4 100644 --- a/includes/class-wc-product-tables-migrate-data.php +++ b/includes/class-wc-product-tables-migrate-data.php @@ -53,125 +53,153 @@ class WC_Product_Tables_Migrate_Data { ), ); - /** - * Whether or not the migration is currently running. - * - * @var bool - */ - public static $migrating = false; - /** * Main function that runs the whole migration. * * @param bool $clean_old_data Whether to clean old data or keep it. Old data is kept by default. */ public static function migrate( $clean_old_data = false ) { - global $wpdb; - - self::$migrating = true; + WC_Product_Tables_Backwards_Compatibility::unhook(); $products = self::get_products(); foreach ( $products as $product ) { - $metas = get_post_meta( $product->ID ); + self::migrate_product( $product ); + } - self::migrate_core_product_data( $product, $metas ); + wp_cache_flush(); + wc_delete_product_transients(); - $priority = 1; + WC_Product_Tables_Backwards_Compatibility::hook(); + } - // Migrate download files. - $downloadable_files = isset( $metas['_downloadable_files'] ) ? maybe_unserialize( $metas['_downloadable_files'][0] ) : array(); + /** + * Migrate a single product. + * + * @param object $product A product from the database we're migrating. + * @param bool $clean_old_data Whether to clean old data or keep it. Old data is kept by default. + */ + public static function migrate_product( $product, $clean_old_data = false ) { + global $wpdb; - if ( ! empty( $downloadable_files ) ) { - foreach ( $downloadable_files as $download_key => $downloadable_file ) { - $new_download = array( - 'product_id' => $product->ID, - 'name' => $downloadable_file['name'], - 'file' => $downloadable_file['file'], - 'priority' => $priority, - ); - $new_download_id = self::insert( 'wc_product_downloads', $new_download ); - - $wpdb->update( - $wpdb->prefix . 'woocommerce_downloadable_product_permissions', - array( - 'download_id' => $new_download_id, - ), - array( - 'download_id' => $download_key, - ) - ); + $metas = get_post_meta( $product->ID ); - $priority++; - } - } + self::migrate_core_product_data( $product, $metas ); - // Migrate grouped products. - self::migrate_relationship( $product->ID, 'grouped', '_children' ); + $priority = 1; - // Migrate upsells. - self::migrate_relationship( $product->ID, 'upsell', '_upsell_ids' ); + // Migrate download files. + $downloadable_files = isset( $metas['_downloadable_files'] ) ? maybe_unserialize( $metas['_downloadable_files'][0] ) : array(); + + if ( ! empty( $downloadable_files ) ) { + foreach ( $downloadable_files as $download_key => $downloadable_file ) { + $new_download = array( + 'product_id' => $product->ID, + 'name' => $downloadable_file['name'], + 'file' => $downloadable_file['file'], + 'priority' => $priority, + ); + $new_download_id = self::insert( 'wc_product_downloads', $new_download ); + + $wpdb->update( + $wpdb->prefix . 'woocommerce_downloadable_product_permissions', + array( + 'download_id' => $new_download_id, + ), + array( + 'download_id' => $download_key, + ) + ); + + $priority++; + } + } - // Migrate cross-sells. - self::migrate_relationship( $product->ID, 'crosssell', '_crosssell_ids' ); + if ( ! empty( $metas['_children'][0] ) ) { + self::migrate_relationship( $product->ID, 'grouped', maybe_unserialize( $metas['_children'][0] ) ); + } - $priority = 1; + if ( ! empty( $metas['_upsell_ids'][0] ) ) { + self::migrate_relationship( $product->ID, 'upsell', maybe_unserialize( $metas['_upsell_ids'][0] ) ); + } - // Migrate product images. - $image_ids = get_post_meta( $product->ID, '_product_image_gallery', true ); - if ( ! empty( $image_ids ) ) { - if ( ! is_array( $image_ids ) ) { - if ( false !== strpos( $image_ids, ',' ) ) { - $image_ids = explode( ',', $image_ids ); - } else { - $image_ids = array( $image_ids ); - } - } + if ( ! empty( $metas['_crosssell_ids'][0] ) ) { + self::migrate_relationship( $product->ID, 'crosssell', maybe_unserialize( $metas['_crosssell_ids'][0] ) ); + } - foreach ( $image_ids as $image_id ) { - $relationship = array( - 'type' => 'image', - 'product_id' => $product->ID, - 'object_id' => $image_id, - 'priority' => $priority, - ); + $priority = 1; - self::insert( 'wc_product_relationships', $relationship ); + // Migrate product images. + if ( ! empty( $metas['_product_image_gallery'][0] ) ) { + $image_ids = maybe_unserialize( $metas['_product_image_gallery'][0] ); - $priority++; + if ( ! is_array( $image_ids ) ) { + if ( false !== strpos( $image_ids, ',' ) ) { + $image_ids = explode( ',', $image_ids ); + } else { + $image_ids = array( $image_ids ); } } - self::migrate_attributes( $product ); + foreach ( $image_ids as $image_id ) { + $relationship = array( + 'type' => 'image', + 'product_id' => $product->ID, + 'object_id' => $image_id, + 'priority' => $priority, + ); - // Migrate variation description. - if ( 'product_variation' === $product->post_type ) { - wp_update_post( array( - 'ID' => $product->ID, - 'post_content' => get_post_meta( $product->ID, '_variation_description', true ), - ) ); - } + self::insert( 'wc_product_relationships', $relationship ); - if ( $clean_old_data ) { - self::clean_old_data( $product->ID ); + $priority++; } } - self::$migrating = false; + self::migrate_attributes( $product ); + + // Migrate variation description. + if ( 'product_variation' === $product->post_type ) { + wp_update_post( array( + 'ID' => $product->ID, + 'post_content' => get_post_meta( $product->ID, '_variation_description', true ), + ) ); + } + + if ( $clean_old_data ) { + self::clean_old_data( $product->ID ); + } + + unset( $metas, $downloadable_files, $image_ids ); + $wpdb->flush(); } /** * Get a list of products in the wp_posts table + * + * @param string|array $post_type Post types to get from DB. + * @return array */ - public static function get_products() { + public static function get_products( $post_type = false ) { global $wpdb; + + if ( ! $post_type ) { + $post_type = array( 'product', 'product_variation' ); + } elseif ( ! is_array( $post_type ) ) { + $post_type = array( $post_type ); + } + + $post_type_sql = "'" . implode( "','", array_map( 'esc_sql', $post_type ) ) . "'"; + + // phpcs:disable return $wpdb->get_results( "SELECT ID, post_type FROM {$wpdb->posts} - WHERE post_type IN ('product', 'product_variation') + WHERE post_type IN ({$post_type_sql}) + AND post_status IN ( 'publish', 'future', 'draft', 'private' ) AND ID NOT IN ( SELECT product_id FROM {$wpdb->prefix}wc_products )" ); + // phpcs:enable } /** @@ -197,7 +225,13 @@ public static function migrate_core_product_data( $product, $metas ) { if ( 'product_variation' === $product->post_type ) { $product_type = 'variation'; } else { - $product_type = wp_get_post_terms( $product->ID, 'product_type' )[0]->slug; + $terms = wp_get_post_terms( $product->ID, 'product_type' ); + + if ( $terms && isset( $terms[0]->slug ) ) { + $product_type = $terms[0]->slug; + } else { + $product_type = 'simple'; + } } $new_data = array( @@ -222,17 +256,17 @@ public static function migrate_core_product_data( $product, $metas ) { $meta_value = ( isset( $metas['_sale_price'] ) && '' !== $metas['_sale_price'][0] ) ? $metas['_sale_price'][0] : null; break; case '_sale_price_dates_from': - if ( ! empty( $metas['_sale_price_dates_from'] ) ) { + if ( ! empty( $metas['_sale_price_dates_from'][0] ) ) { $meta_value = date( 'Y-m-d H:i:s', (int) $metas['_sale_price_dates_from'][0] ); } else { - $meta_vaule = null; + $meta_value = null; } break; case '_sale_price_dates_to': - if ( ! empty( $metas['_sale_price_dates_to'] ) ) { + if ( ! empty( $metas['_sale_price_dates_to'][0] ) ) { $meta_value = date( 'Y-m-d H:i:s', (int) $metas['_sale_price_dates_to'][0] ); } else { - $meta_vaule = null; + $meta_value = null; } break; case '_virtual': @@ -257,6 +291,7 @@ public static function migrate_core_product_data( $product, $metas ) { } self::insert( 'wc_products', $new_data ); + unset( $meta_value, $product_type, $new_data ); } /** @@ -265,30 +300,28 @@ public static function migrate_core_product_data( $product, $metas ) { * * @param int $product_id Product ID. * @param string $relationship_type 'grouped', 'upsell' or 'crosssell'. - * @param string $old_meta_key Old meta key. + * @param array $object_ids Object ids to related, from old meta. */ - protected static function migrate_relationship( $product_id, $relationship_type, $old_meta_key ) { + protected static function migrate_relationship( $product_id, $relationship_type, $object_ids ) { global $wpdb; - $priority = 1; - $children = get_post_meta( $product_id, $old_meta_key, true ); - if ( empty( $children ) ) { - return; - } - foreach ( $children as $child ) { - if ( empty( $child ) ) { - continue; - } - $relationship = array( - 'type' => $relationship_type, - 'product_id' => $product_id, - 'object_id' => $child, - 'priority' => $priority, - ); - - $wpdb->insert( $wpdb->prefix . 'wc_product_relationships', $relationship ); + if ( ! empty( $object_ids ) ) { + $priority = 1; - $priority++; + foreach ( $object_ids as $object_id ) { + if ( empty( $object_id ) ) { + continue; + } + $relationship = array( + 'type' => $relationship_type, + 'product_id' => $product_id, + 'object_id' => $object_id, + 'priority' => $priority, + ); + + $wpdb->insert( $wpdb->prefix . 'wc_product_relationships', $relationship ); + $priority++; + } } } @@ -325,9 +358,14 @@ protected static function migrate_variation_attribute_values( $parent_id, $attri 'product_attribute_id' => $attribute_id, ); self::insert( 'wc_product_variation_attribute_values', $variation_data ); + unset( $variation_data ); } + + unset( $variation_value ); } } + + unset( $variable_products, $meta_key ); } /** @@ -337,39 +375,43 @@ protected static function migrate_variation_attribute_values( $parent_id, $attri */ public static function migrate_attributes( &$product ) { $product_attributes = get_post_meta( $product->ID, '_product_attributes', true ); - if ( empty( $product_attributes ) ) { - return; - } - foreach ( $product_attributes as $attr_name => $attr ) { - $attribute_data = array( - 'product_id' => $product->ID, - 'name' => $attr['name'], - 'is_visible' => $attr['is_visible'], - 'is_variation' => $attr['is_variation'], - 'priority' => $attr['position'], - ); - $is_global = false; - if ( false !== strpos( $attr_name, 'pa_' ) ) { - // Global attribute. - $attribute_id = wc_attribute_taxonomy_id_by_name( $attr_name ); - - if ( $attribute_id ) { - $attribute_data['attribute_id'] = $attribute_id; - $is_global = true; + + if ( ! empty( $product_attributes ) ) { + foreach ( $product_attributes as $attr_name => $attr ) { + $attribute_data = array( + 'product_id' => $product->ID, + 'name' => $attr['name'], + 'is_visible' => $attr['is_visible'], + 'is_variation' => $attr['is_variation'], + 'priority' => $attr['position'], + ); + $is_global = false; + if ( false !== strpos( $attr_name, 'pa_' ) ) { + // Global attribute. + $attribute_id = wc_attribute_taxonomy_id_by_name( $attr_name ); + + if ( $attribute_id ) { + $attribute_data['attribute_id'] = $attribute_id; + $is_global = true; + } + } + $product_attribute_id = self::insert( 'wc_product_attributes', $attribute_data ); + if ( $is_global ) { + self::migrate_global_attributes( $product->ID, $product_attribute_id, $attr_name ); + } else { + self::migrate_custom_attributes( $product->ID, $product_attribute_id, $attr_name, $attr['value'] ); } - } - $product_attribute_id = self::insert( 'wc_product_attributes', $attribute_data ); - if ( $is_global ) { - self::migrate_global_attributes( $product->ID, $product_attribute_id, $attr_name ); - } else { - self::migrate_custom_attributes( $product->ID, $product_attribute_id, $attr_name, $attr['value'] ); - } - // Variation attribute values, lets check if the parent product has any child products ie. variations. - if ( 'product' === $product->post_type ) { - self::migrate_variation_attribute_values( $product->ID, $product_attribute_id, $attr_name ); + // Variation attribute values, lets check if the parent product has any child products ie. variations. + if ( 'product' === $product->post_type ) { + self::migrate_variation_attribute_values( $product->ID, $product_attribute_id, $attr_name ); + } + + unset( $attribute_data ); } } + + unset( $product_attributes ); } /** @@ -406,6 +448,7 @@ protected static function migrate_global_attributes( $product_id, $product_attri self::insert( 'wc_product_attribute_values', $term_data ); $count++; } + unset( $attr_terms, $term_data, $default_attributes ); } /** @@ -436,8 +479,10 @@ protected static function migrate_custom_attributes( $product_id, $product_attri } } self::insert( 'wc_product_attribute_values', $attr_value_data ); + unset( $attr_value_data ); $count++; } + unset( $attribute_values, $default_attributes ); } /** @@ -449,13 +494,16 @@ protected static function migrate_custom_attributes( $product_id, $product_attri protected static function clean_old_data( $product_id ) { global $wpdb; - $meta_keys = array_merge( self::$meta_keys['product'], self::$meta_keys['custom'] ); + $meta_keys = array_merge( self::$meta_keys['product'], self::$meta_keys['custom'] ); + $meta_keys_in = "'" . implode( "','", array_map( 'esc_sql', $meta_keys ) ) . "'"; - foreach ( $meta_keys as $meta_key ) { - delete_post_meta( $product_id, $meta_key ); - } + $wpdb->query( + $wpdb->prepare( + "DELETE FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key IN ({$meta_keys_in})", // phpcs:ignore + $product_id + ) + ); - // remove product variation attributes. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key LIKE %s", @@ -463,5 +511,7 @@ protected static function clean_old_data( $product_id ) { $wpdb->esc_like( 'attribute_' ) . '%' ) ); + + unset( $meta_keys ); } } diff --git a/includes/class-wc-product-tables-post-data.php b/includes/class-wc-product-tables-post-data.php new file mode 100644 index 0000000..202f242 --- /dev/null +++ b/includes/class-wc-product-tables-post-data.php @@ -0,0 +1,54 @@ +delete( "{$wpdb->prefix}wc_products", [ 'product_id' => $id ], [ '%d' ] ); + $wpdb->delete( "{$wpdb->prefix}wc_product_relationships", [ 'product_id' => $id ], [ '%d' ] ); + $wpdb->delete( "{$wpdb->prefix}wc_product_downloads", [ 'product_id' => $id ], [ '%d' ] ); + $wpdb->delete( "{$wpdb->prefix}wc_product_variation_attribute_values", [ 'product_id' => $id ], [ '%d' ] ); + $wpdb->delete( "{$wpdb->prefix}wc_product_attribute_values", [ 'product_id' => $id ], [ '%d' ] ); + } +} + +WC_Product_Tables_Post_Data::init(); diff --git a/includes/class-wc-product-tables-query.php b/includes/class-wc-product-tables-query.php index 2515505..9894fcb 100644 --- a/includes/class-wc-product-tables-query.php +++ b/includes/class-wc-product-tables-query.php @@ -37,7 +37,7 @@ public function __construct() { add_filter( 'woocommerce_price_filter_sql', array( $this, 'custom_price_filter_sql' ), 10, 3 ); add_action( 'woocommerce_product_query', array( $this, 'custom_price_filter_args' ) ); } - add_filter( 'posts_results', array( $this, 'prime_product_table_caches' ) ); + add_filter( 'update_post_metadata_cache', array( $this, 'prime_table_caches' ), 10, 2 ); add_action( 'clean_post_cache', array( $this, 'clean_product_table_caches' ) ); } @@ -212,8 +212,23 @@ public function custom_price_filter_post_clauses( $args, $wp_query ) { global $wpdb; if ( $wp_query->is_main_query() ) { - $args['join'] .= " INNER JOIN {$wpdb->prefix}wc_products ON {$wpdb->posts}.ID = {$wpdb->prefix}wc_products.product_id "; - $args['where'] .= " AND {$wpdb->prefix}wc_products.price >= {$this->price_filter_min} AND {$wpdb->prefix}wc_products.price <= {$this->price_filter_max} "; + $args['where'] .= " + AND ( + {$wpdb->posts}.ID IN ( + SELECT product_id + FROM {$wpdb->prefix}wc_products + WHERE {$wpdb->prefix}wc_products.price >= {$this->price_filter_min} + AND {$wpdb->prefix}wc_products.price <= {$this->price_filter_max} + ) + OR {$wpdb->posts}.ID IN ( + SELECT post_parent + FROM {$wpdb->posts} + INNER JOIN {$wpdb->prefix}wc_products ON {$wpdb->posts}.ID = {$wpdb->prefix}wc_products.product_id + WHERE {$wpdb->prefix}wc_products.price >= {$this->price_filter_min} + AND {$wpdb->prefix}wc_products.price <= {$this->price_filter_max} + ) + ) + "; } return $args; @@ -222,111 +237,140 @@ public function custom_price_filter_post_clauses( $args, $wp_query ) { /** * Prime product table caches for a query of multiple products. * - * @param array $posts Array of post objects. - * @return array + * @param mixed $return Return value for filter. + * @param array $object_ids Array of object ids. + * @return null */ - public function prime_product_table_caches( $posts ) { - $prime_ids = array(); - $variation_ids = array(); + public function prime_table_caches( $return, $object_ids ) { + if ( empty( $object_ids ) ) { + return $return; + } + global $wpdb; - foreach ( $posts as $post ) { - if ( ! in_array( $post->post_type, array( 'product', 'product_variation' ), true ) ) { - continue; - } - $prime_ids[] = (int) $post->ID; + $prime_product_ids = array(); + $prime_variation_ids = array(); - if ( 'product_variation' === $post->post_type ) { - $variation_ids[] = (int) $post->ID; + foreach ( $object_ids as $object_id ) { + $cached_post = wp_cache_get( $object_id, 'posts' ); + $post_type = isset( $cached_post->post_type ) ? $cached_post->post_type : get_post_type( $object_id ); + if ( 'product' === $post_type ) { + $prime_product_ids[] = $object_id; + } + if ( 'product_variation' === $post_type ) { + $prime_variation_ids[] = $object_id; } } - if ( ! empty( $prime_ids ) ) { - global $wpdb; + $prime_ids = array_merge( $prime_product_ids, $prime_variation_ids ); - $prime_id_sql = implode( ',', $prime_ids ); - $prime_non_variations_sql = implode( ',', array_diff( $prime_ids, $variation_ids ) ); - $prime_variations_sql = implode( ',', $variation_ids ); + if ( empty( $prime_ids ) ) { + return $return; + } - // Prime product rows. - $rows = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'wc_products WHERE product_id IN (' . $prime_id_sql . ');' ); // WPCS: db call ok, cache ok, unprepared SQL OK. + $prime_ids_sql = implode( ',', $prime_ids ); - foreach ( $rows as $row ) { - wp_cache_set( 'woocommerce_product_' . $row->product_id, $row, 'product' ); - } + // Prime product and variation rows. + $rows = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'wc_products WHERE product_id IN (' . $prime_ids_sql . ');' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - // Prime attribute rows. - if ( $prime_non_variations_sql ) { - $rows = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'wc_product_attributes WHERE product_id IN (' . $prime_non_variations_sql . ');' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - $cache = array_fill_keys( $prime_ids, array() ); + foreach ( $rows as $row ) { + wp_cache_set( 'woocommerce_product_' . $row->product_id, $row, 'product' ); + } - foreach ( $rows as $row ) { - $cache[ $row->product_id ][] = $row; - } + $rel_cache = array_fill_keys( $prime_ids, array() ); + $download_cache = array_fill_keys( $prime_ids, array() ); - foreach ( $prime_ids as $id ) { - wp_cache_set( 'woocommerce_product_attributes_' . $id, $cache[ $id ], 'product' ); - } - } + // Prime relationships. + $rows = $wpdb->get_results( 'SELECT `product_id`, `relationship_id`, `object_id`, `type` FROM ' . $wpdb->prefix . 'wc_product_relationships WHERE product_id IN (' . $prime_ids_sql . ') ORDER BY `priority` ASC;' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - // Prime attribute values. - $rows = $wpdb->get_results( ' - SELECT `product_id`, `product_attribute_id`, `value`, `is_default` - FROM ' . $wpdb->prefix . 'wc_product_attribute_values - WHERE product_id IN (' . $prime_non_variations_sql . '); - ' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - $cache = array_fill_keys( $prime_ids, array() ); - - foreach ( $rows as $row ) { - if ( ! isset( $cache[ $row->product_id ] ) ) { - $cache[ $row->product_id ] = array(); - } - $cache[ $row->product_id ][ $row->product_attribute_id ][] = $row; - } + foreach ( $rows as $row ) { + $rel_cache[ $row->product_id ][] = $row; + } - foreach ( $prime_ids as $id ) { - wp_cache_set( 'woocommerce_product_attribute_values_' . $id, $cache[ $id ], 'product' ); - } + // Prime downloads. + $rows = $wpdb->get_results( 'SELECT `product_id`, `download_id`, `name`, `file`, `priority` FROM ' . $wpdb->prefix . 'wc_product_downloads WHERE product_id IN (' . $prime_ids_sql . ') ORDER BY `priority` ASC;' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - // Prime variation attribute values. - if ( $prime_variations_sql ) { - $rows = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'wc_product_variation_attribute_values WHERE product_id IN (' . $prime_variations_sql . ');' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - $cache = array_fill_keys( $prime_ids, array() ); + foreach ( $rows as $row ) { + $download_cache[ $row->product_id ][] = $row; + } - foreach ( $rows as $row ) { - $cache[ $row->product_id ][] = $row; - } + foreach ( $prime_ids as $id ) { + wp_cache_set( 'woocommerce_product_relationships_' . $id, $rel_cache[ $id ], 'product' ); + wp_cache_set( 'woocommerce_product_downloads_' . $id, $download_cache[ $id ], 'product' ); + } - foreach ( $prime_ids as $id ) { - wp_cache_set( 'woocommerce_product_variation_attribute_values_' . $id, $cache[ $id ], 'product' ); - } - } + if ( ! empty( $prime_product_ids ) ) { + $this->prime_product_table_caches( $prime_product_ids ); + } - // Prime relationships. - $rows = $wpdb->get_results( 'SELECT `product_id`, `relationship_id`, `object_id`, `type` FROM ' . $wpdb->prefix . 'wc_product_relationships WHERE product_id IN (' . $prime_id_sql . ') ORDER BY `priority` ASC;' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - $cache = array_fill_keys( $prime_ids, array() ); + if ( ! empty( $prime_variation_ids ) ) { + $this->prime_product_variation_table_caches( $prime_variation_ids ); + } - foreach ( $rows as $row ) { - $cache[ $row->product_id ][] = $row; - } + return $return; + } - foreach ( $prime_ids as $id ) { - wp_cache_set( 'woocommerce_product_relationships_' . $id, $cache[ $id ], 'product' ); - } + /** + * Prime product table caches for a query of multiple products. + * + * @param array $prime_ids Array of product ids. + */ + protected function prime_product_table_caches( $prime_ids ) { + global $wpdb; - // Prime downloads. - $rows = $wpdb->get_results( 'SELECT `product_id`, `download_id`, `name`, `file`, `priority` FROM ' . $wpdb->prefix . 'wc_product_downloads WHERE product_id IN (' . $prime_id_sql . ') ORDER BY `priority` ASC;' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - $cache = array_fill_keys( $prime_ids, array() ); + $prime_id_sql = implode( ',', $prime_ids ); + $att_cache = array_fill_keys( $prime_ids, array() ); + $att_value_cache = array_fill_keys( $prime_ids, array() ); - foreach ( $rows as $row ) { - $cache[ $row->product_id ][] = $row; - } + // Prime attribute rows. + $rows = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'wc_product_attributes WHERE product_id IN (' . $prime_id_sql . ');' ); // WPCS: db call ok, cache ok, unprepared SQL OK. - foreach ( $prime_ids as $id ) { - wp_cache_set( 'woocommerce_product_downloads_' . $id, $cache[ $id ], 'product' ); + foreach ( $rows as $row ) { + $att_cache[ $row->product_id ][] = $row; + } + + // Prime attribute values. + $rows = $wpdb->get_results( ' + SELECT `product_id`, `product_attribute_id`, `value`, `is_default` + FROM ' . $wpdb->prefix . 'wc_product_attribute_values + WHERE product_id IN (' . $prime_id_sql . '); + ' ); // WPCS: db call ok, cache ok, unprepared SQL OK. + + foreach ( $rows as $row ) { + if ( ! isset( $att_value_cache[ $row->product_id ] ) ) { + $att_value_cache[ $row->product_id ] = array(); } + $att_value_cache[ $row->product_id ][ $row->product_attribute_id ][] = $row; } - return $posts; + foreach ( $prime_ids as $id ) { + wp_cache_set( 'woocommerce_product_attributes_' . $id, $att_cache[ $id ], 'product' ); + wp_cache_set( 'woocommerce_product_attribute_values_' . $id, $att_value_cache[ $id ], 'product' ); + } + } + + /** + * Prime product variation table caches for a query of multiple products. + * + * @param array $prime_ids Array of variation ids. + */ + protected function prime_product_variation_table_caches( $prime_ids ) { + global $wpdb; + + $prime_id_sql = implode( ',', $prime_ids ); + $variation_att_cache = array_fill_keys( $prime_ids, array() ); + $rel_cache = array_fill_keys( $prime_ids, array() ); + $download_cache = array_fill_keys( $prime_ids, array() ); + + // Prime variation attribute values. + $rows = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'wc_product_variation_attribute_values WHERE product_id IN (' . $prime_id_sql . ');' ); // WPCS: db call ok, cache ok, unprepared SQL OK. + + foreach ( $rows as $row ) { + $variation_att_cache[ $row->product_id ][] = $row; + } + + foreach ( $prime_ids as $id ) { + wp_cache_set( 'woocommerce_product_variation_attribute_values_' . $id, $variation_att_cache[ $id ], 'product' ); + } } /** diff --git a/includes/data-stores/class-wc-product-variable-data-store-custom-table.php b/includes/data-stores/class-wc-product-variable-data-store-custom-table.php index 2e0830f..e4d9ed7 100644 --- a/includes/data-stores/class-wc-product-variable-data-store-custom-table.php +++ b/includes/data-stores/class-wc-product-variable-data-store-custom-table.php @@ -24,6 +24,19 @@ class WC_Product_Variable_Data_Store_Custom_Table extends WC_Product_Data_Store_ */ protected $prices_array = array(); + /** + * Relationships. Note - grouped/children is not included here. + * Children are child posts, not related via the table. + * + * @since 4.0.0 + * @var array + */ + protected $relationships = array( + 'image' => 'gallery_image_ids', + 'upsell' => 'upsell_ids', + 'cross_sell' => 'cross_sell_ids', + ); + /** * Read product data. * @@ -36,12 +49,6 @@ protected function read_product_data( &$product ) { // Make sure data which does not apply to variables is unset. $product->set_regular_price( '' ); $product->set_sale_price( '' ); - - // Set directly since individual data needs changed at the WC_Product_Variation level -- these datasets just pull. - $children = $this->read_children( $product ); - $product->set_children( $children['all'] ); - $product->set_visible_children( $children['visible'] ); - $product->set_variation_attributes( $this->read_variation_attributes( $product ) ); } /** @@ -51,7 +58,7 @@ protected function read_product_data( &$product ) { * @param bool $force_read True to bypass the transient. * @return array */ - protected function read_children( &$product, $force_read = false ) { + public function read_children( &$product, $force_read = false ) { $children_transient_name = 'wc_product_children_' . $product->get_id(); $children = get_transient( $children_transient_name ); @@ -59,26 +66,31 @@ protected function read_children( &$product, $force_read = false ) { $all_args = array( 'parent' => $product->get_id(), 'type' => 'variation', - 'orderby' => 'menu_order', + 'orderby' => array( + 'menu_order' => 'ASC', + 'ID' => 'ASC', + ), 'order' => 'ASC', 'limit' => -1, 'return' => 'ids', 'status' => array( 'publish', 'private' ), ); - $all_args = apply_filters( 'woocommerce_variable_children_args', $all_args, $product, false ); $visible_only_args = $all_args; $visible_only_args['post_status'] = 'publish'; + if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { $visible_only_args['stock_status'] = 'instock'; } - $visible_only_args = apply_filters( 'woocommerce_variable_children_args', $visible_only_args, $product, true ); - - $children['all'] = wc_get_products( $this->map_legacy_product_args( $all_args ) ); - $children['visible'] = wc_get_products( $this->map_legacy_product_args( $visible_only_args ) ); + $children['all'] = wc_get_products( apply_filters( 'woocommerce_variable_children_args', $this->map_legacy_product_args( $all_args ), $product, false ) ); + $children['visible'] = wc_get_products( apply_filters( 'woocommerce_variable_children_args', $this->map_legacy_product_args( $visible_only_args ), $product, true ) ); set_transient( $children_transient_name, $children, DAY_IN_SECONDS * 30 ); } + + $children['all'] = wp_parse_id_list( (array) $children['all'] ); + $children['visible'] = wp_parse_id_list( (array) $children['visible'] ); + return $children; } @@ -113,7 +125,7 @@ protected function map_legacy_product_args( $args ) { * * @param WC_Product $product Product object. */ - protected function read_variation_attributes( &$product ) { + public function read_variation_attributes( &$product ) { global $wpdb; $variation_attributes = array(); @@ -127,26 +139,35 @@ protected function read_variation_attributes( &$product ) { return $cached_data; } - if ( ! empty( $child_ids ) && ! empty( $attributes ) ) { + if ( ! empty( $attributes ) ) { foreach ( $attributes as $attribute ) { if ( ! $attribute->get_variation() ) { continue; } - $product_attribute_id = $attribute->get_product_attribute_id(); - $values = array_unique( - $wpdb->get_col( - $wpdb->prepare( - "SELECT value FROM {$wpdb->prefix}wc_product_variation_attribute_values - WHERE product_attribute_id = %d - AND product_id IN (" . implode( ',', array_map( 'absint', $child_ids ) ) . ')', // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared - $product_attribute_id + // Get possible values for this attribute, for only visible variations. + if ( ! empty( $child_ids ) ) { + $product_attribute_id = $attribute->get_product_attribute_id(); + $format = array_fill( 0, count( $child_ids ), '%d' ); + $query_in = '(' . implode( ',', $format ) . ')'; + $query_args = array( 'product_attribute_id' => $product_attribute_id ) + $child_ids; + $values = array_unique( + $wpdb->get_col( + $wpdb->prepare( // wpcs: PreparedSQLPlaceholders replacement count ok. + " + SELECT value FROM {$wpdb->prefix}wc_product_variation_attribute_values + WHERE product_attribute_id = %d + AND product_id IN {$query_in}", // @codingStandardsIgnoreLine. + $query_args + ) ) - ) - ); + ); + } else { + $values = array(); + } // Empty value indicates that all options for given attribute are available. - if ( in_array( null, $values, true ) || empty( $values ) ) { + if ( in_array( null, $values, true ) || in_array( '', $values, true ) || empty( $values ) ) { $values = $attribute->get_slugs(); } elseif ( ! $attribute->is_taxonomy() ) { $text_attributes = array_map( 'trim', $attribute->get_options() ); @@ -176,19 +197,19 @@ protected function read_variation_attributes( &$product ) { * * @since 3.0.0 * @param WC_Product $product Product object. - * @param bool $include_taxes If taxes should be calculated or not. + * @param bool $for_display If true, prices will be adapted for display based on the `woocommerce_tax_display_shop` setting (including or excluding taxes). * @return array of prices */ - public function read_price_data( &$product, $include_taxes = false ) { + public function read_price_data( &$product, $for_display = false ) { /** - * Transient name for storing prices for this product (note: Max transient length is 45). + * Transient name for storing prices for this product (note: Max transient length is 45) * * @since 2.5.0 a single transient is used per product for all prices, rather than many transients per product. */ $transient_name = 'wc_var_prices_' . $product->get_id(); - $price_hash = $this->get_price_hash( $product, $include_taxes ); + $price_hash = $this->get_price_hash( $product, $for_display ); /** * $this->prices_array is an array of values which may have been modified from what is stored in transients - this may not match $transient_cached_prices_array. @@ -199,17 +220,23 @@ public function read_price_data( &$product, $include_taxes = false ) { // If the product version has changed since the transient was last saved, reset the transient cache. if ( empty( $transient_cached_prices_array['version'] ) || WC_Cache_Helper::get_transient_version( 'product' ) !== $transient_cached_prices_array['version'] ) { - $transient_cached_prices_array = array( - 'version' => WC_Cache_Helper::get_transient_version( 'product' ), - ); + $transient_cached_prices_array = array( 'version' => WC_Cache_Helper::get_transient_version( 'product' ) ); } // If the prices are not stored for this hash, generate them and add to the transient. if ( empty( $transient_cached_prices_array[ $price_hash ] ) ) { - $prices = array(); - $regular_prices = array(); - $sale_prices = array(); - $variation_ids = $product->get_visible_children(); + $prices_array = array( + 'price' => array(), + 'regular_price' => array(), + 'sale_price' => array(), + ); + + $variation_ids = $product->get_visible_children(); + + if ( is_callable( '_prime_post_caches' ) ) { + _prime_post_caches( $variation_ids ); + } + foreach ( $variation_ids as $variation_id ) { $variation = wc_get_product( $variation_id ); @@ -229,41 +256,47 @@ public function read_price_data( &$product, $include_taxes = false ) { } // If we are getting prices for display, we need to account for taxes. - if ( $include_taxes ) { + if ( $for_display ) { if ( 'incl' === get_option( 'woocommerce_tax_display_shop' ) ) { $price = '' === $price ? '' : wc_get_price_including_tax( - $variation, array( + $variation, + array( 'qty' => 1, 'price' => $price, ) ); $regular_price = '' === $regular_price ? '' : wc_get_price_including_tax( - $variation, array( + $variation, + array( 'qty' => 1, 'price' => $regular_price, ) ); $sale_price = '' === $sale_price ? '' : wc_get_price_including_tax( - $variation, array( + $variation, + array( 'qty' => 1, 'price' => $sale_price, ) ); } else { $price = '' === $price ? '' : wc_get_price_excluding_tax( - $variation, array( + $variation, + array( 'qty' => 1, 'price' => $price, ) ); $regular_price = '' === $regular_price ? '' : wc_get_price_excluding_tax( - $variation, array( + $variation, + array( 'qty' => 1, 'price' => $regular_price, ) ); $sale_price = '' === $sale_price ? '' : wc_get_price_excluding_tax( - $variation, array( + $variation, + array( 'qty' => 1, 'price' => $sale_price, ) @@ -271,17 +304,18 @@ public function read_price_data( &$product, $include_taxes = false ) { } } - $prices[ $variation_id ] = wc_format_decimal( $price, wc_get_price_decimals() ); - $regular_prices[ $variation_id ] = wc_format_decimal( $regular_price, wc_get_price_decimals() ); - $sale_prices[ $variation_id ] = wc_format_decimal( $sale_price . '.00', wc_get_price_decimals() ); + $prices_array['price'][ $variation_id ] = wc_format_decimal( $price, wc_get_price_decimals() ); + $prices_array['regular_price'][ $variation_id ] = wc_format_decimal( $regular_price, wc_get_price_decimals() ); + $prices_array['sale_price'][ $variation_id ] = wc_format_decimal( $sale_price . '.00', wc_get_price_decimals() ); + + $prices_array = apply_filters( 'woocommerce_variation_prices_array', $prices_array, $variation, $for_display ); } } - $transient_cached_prices_array[ $price_hash ] = array( - 'price' => $prices, - 'regular_price' => $regular_prices, - 'sale_price' => $sale_prices, - ); + // Add all pricing data to the transient array. + foreach ( $prices_array as $key => $values ) { + $transient_cached_prices_array[ $price_hash ][ $key ] = $values; + } set_transient( $transient_name, wp_json_encode( $transient_cached_prices_array ), DAY_IN_SECONDS * 30 ); } @@ -290,7 +324,7 @@ public function read_price_data( &$product, $include_taxes = false ) { * Give plugins one last chance to filter the variation prices array which has been generated and store locally to the class. * This value may differ from the transient cache. It is filtered once before storing locally. */ - $this->prices_array[ $price_hash ] = apply_filters( 'woocommerce_variation_prices', $transient_cached_prices_array[ $price_hash ], $product, $include_taxes ); + $this->prices_array[ $price_hash ] = apply_filters( 'woocommerce_variation_prices', $transient_cached_prices_array[ $price_hash ], $product, $for_display ); } return $this->prices_array[ $price_hash ]; } diff --git a/includes/data-stores/class-wc-product-variation-data-store-custom-table.php b/includes/data-stores/class-wc-product-variation-data-store-custom-table.php index f16db10..be84fad 100644 --- a/includes/data-stores/class-wc-product-variation-data-store-custom-table.php +++ b/includes/data-stores/class-wc-product-variation-data-store-custom-table.php @@ -92,23 +92,8 @@ public function read( &$product ) { * @since 3.0.0 */ protected function read_product_data( &$product ) { - $id = $product->get_id(); - $props = $this->get_product_row_from_db( $product->get_id() ); - $review_count = get_post_meta( $id, '_wc_review_count', true ); - $rating_counts = get_post_meta( $id, '_wc_rating_count', true ); - - if ( '' === $review_count ) { - WC_Comments::get_review_count_for_product( $product ); - } else { - $props['review_count'] = $review_count; - } - - if ( '' === $rating_counts ) { - WC_Comments::get_rating_counts_for_product( $product ); - } else { - $props['rating_counts'] = $rating_counts; - } - + $id = $product->get_id(); + $props = $this->get_product_row_from_db( $product->get_id() ); $props['manage_stock'] = isset( $props['stock_quantity'] ) && ! is_null( $props['stock_quantity'] ); $meta_to_props = array( @@ -124,8 +109,6 @@ protected function read_product_data( &$product ) { } $taxonomies_to_props = array( - 'product_cat' => 'category_ids', - 'product_tag' => 'tag_ids', 'product_shipping_class' => 'shipping_class_id', ); @@ -161,7 +144,26 @@ protected function read_product_data( &$product ) { $parent = wc_get_product( $product->get_parent_id() ); if ( $parent ) { - $product->set_parent_data( array_merge( $parent->get_data(), array( 'title' => $parent->get_title() ) ) ); + $product->set_parent_data( + array( + 'title' => $parent->get_title(), + 'status' => $parent->get_status(), + 'sku' => $parent->get_sku(), + 'manage_stock' => $parent->get_manage_stock(), + 'backorders' => $parent->get_backorders(), + 'low_stock_amount' => $parent->get_low_stock_amount(), + 'stock_quantity' => $parent->get_stock_quantity(), + 'weight' => $parent->get_weight(), + 'length' => $parent->get_length(), + 'width' => $parent->get_width(), + 'height' => $parent->get_height(), + 'tax_class' => $parent->get_tax_class(), + 'shipping_class_id' => $parent->get_shipping_class_id(), + 'image_id' => $parent->get_image_id(), + 'purchase_note' => $parent->get_purchase_note(), + 'catalog_visibility' => $parent->get_catalog_visibility(), + ) + ); // Pull data from the parent when there is no user-facing way to set props. $product->set_sold_individually( $parent->get_sold_individually() ); @@ -575,22 +577,20 @@ protected function get_product_attribute_id_from_slug( &$product, $attribute_slu protected function get_parent_product_attribute_names( &$product ) { global $wpdb; - $attributes = wp_cache_get( 'woocommerce_parent_product_attribute_names_' . $product->get_id(), 'product' ); + $attributes = wp_cache_get( 'woocommerce_product_attributes_' . $product->get_parent_id(), 'product' ); if ( false === $attributes ) { - $attributes = wp_list_pluck( - $wpdb->get_results( - $wpdb->prepare( - "SELECT product_attribute_id, name FROM {$wpdb->prefix}wc_product_attributes WHERE product_id = %d", - $product->get_parent_id() - ) - ), 'name', 'product_attribute_id' + $attributes = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM {$wpdb->prefix}wc_product_attributes WHERE product_id = %d", + $product->get_parent_id() + ) ); // WPCS: db call ok, cache ok. - wp_cache_set( 'woocommerce_parent_product_attribute_names_' . $product->get_id(), $attributes, 'product' ); + wp_cache_set( 'woocommerce_product_attributes_' . $product->get_parent_id(), $attributes, 'product' ); } - return $attributes; + return wp_list_pluck( $attributes, 'name', 'product_attribute_id' ); } /** diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..efcde2f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1542 @@ +{ + "name": "woocommerce-product-tables-feature-plugin", + "version": "3.7.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.12.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.7.tgz", + "integrity": "sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "del": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", + "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "graceful-fs": "^4.2.2", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.1", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "fast-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz", + "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" + } + }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz", + "integrity": "sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA==", + "dev": true + }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true + }, + "husky": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/husky/-/husky-3.0.9.tgz", + "integrity": "sha512-Yolhupm7le2/MqC1VYLk/cNmYxsSsqKkTyBhzQHhPK1jFnC89mmmNVuGtLNabjDI6Aj8UNIr0KpRNuBkiC4+sg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "ci-info": "^2.0.0", + "cosmiconfig": "^5.2.1", + "execa": "^1.0.0", + "get-stdin": "^7.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "read-pkg": "^5.2.0", + "run-node": "^1.0.0", + "slash": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "lint-staged": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.4.3.tgz", + "integrity": "sha512-PejnI+rwOAmKAIO+5UuAZU9gxdej/ovSEOAY34yMfC3OS4Ac82vCBPzAWLReR9zCPOMqeVwQRaZ3bUBpAsaL2Q==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", + "debug": "^4.1.1", + "dedent": "^0.7.0", + "del": "^5.0.0", + "execa": "^2.0.3", + "listr": "^0.14.3", + "log-symbols": "^3.0.0", + "micromatch": "^4.0.2", + "normalize-path": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "string-argv": "^0.3.0", + "stringify-object": "^3.3.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", + "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^3.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "path-key": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", + "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz", + "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", + "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", + "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + } + } + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + } + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz", + "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6318877 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "woocommerce-product-tables-feature-plugin", + "title": "WooCommerce Product Tables Feature Plugin", + "version": "3.7.0", + "homepage": "https://github.com/woocommerce/woocommerce-product-tables-feature-plugin", + "repository": { + "type": "git", + "url": "https://github.com/woocommerce/woocommerce-product-tables-feature-plugin.git" + }, + "license": "GPL-3.0+", + "scripts": { + "git:update-hooks": "rm -r .git/hooks && mkdir -p .git/hooks && node ./node_modules/husky/husky.js install" + }, + "devDependencies": { + "husky": "3.0.9", + "lint-staged": "9.4.3" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.php": [ + "php -d display_errors=1 -l", + "composer run-script phpcs-pre-commit" + ] + } +} diff --git a/phpcs.xml b/phpcs.xml index c295c96..78c5e8c 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -8,27 +8,13 @@ */vendor/* - - - - - - - - - - - - - - - - - - - - - + + + + + + + diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..f45d8f1 --- /dev/null +++ b/renovate.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "config:base" + ] +}