diff --git a/modules/addcolumninlist/addcolumninlist.php b/modules/addcolumninlist/addcolumninlist.php index 8c9bb3b0..29f31744 100644 --- a/modules/addcolumninlist/addcolumninlist.php +++ b/modules/addcolumninlist/addcolumninlist.php @@ -12,127 +12,135 @@ if (!defined('_PS_VERSION_')) exit; } -class AddColumnInList extends Module { - - public function __construct() { - $this->name = 'addcolumninlist'; - $this->tab = 'administration'; - $this->version = '2.0.1'; - $this->author = 'Dominik Wójcicki'; - $this->need_instance = 0; - $this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_); - $this->bootstrap = true; - parent::__construct(); - $this->displayName = $this->l('Add column in list product'); - $this->description = $this->l('Dodatkowe filtorwanie produktów w Back Office'); - $this->confirmUninstall = $this->l('Czy na pewno odinstalować moduł?'); +class AddColumnInList extends Module +{ + + public function __construct() + { + $this->name = 'addcolumninlist'; + $this->tab = 'administration'; + $this->version = '2.0.1'; + $this->author = 'Dominik Wójcicki'; + $this->need_instance = 0; + $this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_); + $this->bootstrap = true; + parent::__construct(); + $this->displayName = $this->l('Add column in list product'); + $this->description = $this->l('Dodatkowe filtorwanie produktów w Back Office'); + $this->confirmUninstall = $this->l('Czy na pewno odinstalować moduł?'); + } + + public function install() + { + if ( + !parent::install() + || !$this->registerHook('displayAdminCatalogTwigProductFilter') + || !$this->registerHook('actionAdminProductsListingFieldsModifier') + || !$this->registerHook('ProductsListingFieldsModifier') + || !$this->registerHook('ManufacturerPagination') + ) + { + return false; } - public function install() { - if (!parent::install() - || !$this->registerHook('displayAdminCatalogTwigProductFilter') - || !$this->registerHook('actionAdminProductsListingFieldsModifier') - || !$this->registerHook('ProductsListingFieldsModifier') - || !$this->registerHook('ManufacturerPagination') - ) { - return false; - } - return true; - } - - public function uninstall() { - return parent::uninstall(); - } - - public function hookManufacturerPagination() - { + } + + public function uninstall() + { + return parent::uninstall(); + } + + public function hookManufacturerPagination() + { return Tools::getValue('filter_column_manufacturer', ''); - } - - - public function hookDisplayAdminCatalogTwigProductFilter($params) - { + } - - $manufacturers = Manufacturer::getManufacturers(); - $this->context->smarty->assign([ - 'filter_column_manufacturer' => Tools::getValue('filter_column_manufacturer', ''), - 'filter_column_ean13' => Tools::getValue('filter_column_ean13', ''), - 'manufacturers' => $manufacturers, - ]); - - return $this->display(__FILE__,'views/templates/hook/displayAdminCatalogTwigProductFilter.tpl'); - - return $this->render('@PrestaShopBundle/Admin/Common/pagination.html.twig', [ - 'filter_column_manufacturer' => Tools::getValue('filter_column_manufacturer', ''), - 'filter_column_ean13' => Tools::getValue('filter_column_ean13', ''), - 'manufacturers' => $manufacturers, - ]); + + public function hookDisplayAdminCatalogTwigProductFilter($params) + { + + + $manufacturers = Manufacturer::getManufacturers(); + $this->context->smarty->assign([ + 'filter_column_manufacturer' => Tools::getValue('filter_column_manufacturer', ''), + 'filter_column_ean13' => Tools::getValue('filter_column_ean13', ''), + 'manufacturers' => $manufacturers, + ]); + + return $this->display(__FILE__, 'views/templates/hook/displayAdminCatalogTwigProductFilter.tpl'); + + return $this->render('@PrestaShopBundle/Admin/Common/pagination.html.twig', [ + 'filter_column_manufacturer' => Tools::getValue('filter_column_manufacturer', ''), + 'filter_column_ean13' => Tools::getValue('filter_column_ean13', ''), + 'manufacturers' => $manufacturers, + ]); + } + + public function hookActionAdminProductsListingFieldsModifier($params) + { + + // EAN13 + $params['sql_select']['ean13'] = [ + 'table' => 'p', + 'field' => 'ean13', + 'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH + ]; + + $ean13_filter = Tools::getValue('filter_column_ean13', false); + if ($ean13_filter && $ean13_filter != '') + { + $params['sql_where'][] .= "p.ean13 = " . $ean13_filter; } - public function hookActionAdminProductsListingFieldsModifier($params) + + // Cena zakupu + $params['sql_select']['wholesale_price'] = [ + 'table' => 'p', + 'field' => 'wholesale_price', + 'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH + ]; + + + $wholesale_price_filter = Tools::getValue('filter_column_name_wholesale_price', false); + if ($wholesale_price_filter && $wholesale_price_filter != '') { - - // EAN13 - $params['sql_select']['ean13'] = [ - 'table' => 'p', - 'field' => 'ean13', - 'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH - ]; - - $ean13_filter = Tools::getValue('filter_column_ean13', false); - if ($ean13_filter && $ean13_filter != '') { - $params['sql_where'][] .= "p.ean13 = ".$ean13_filter; - } - - - // Cena zakupu - $params['sql_select']['wholesale_price'] = [ - 'table' => 'p', - 'field' => 'wholesale_price', - 'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH - ]; - - - $wholesale_price_filter = Tools::getValue('filter_column_name_wholesale_price',false); - if ($wholesale_price_filter && $wholesale_price_filter != '') { - $params['sql_where'][] .= " p.wholesale_price = ".$wholesale_price_filter; - } - - // Marża - $params['sql_select']['trade_margin'] = [ - 'table' => 'p', - 'field' => 'trade_margin', - 'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH - ]; - - $trade_margin_filter = Tools::getValue('filter_column_trade_margin', false); - if ($trade_margin_filter && $trade_margin_filter != '') { - $params['sql_where'][] .= "p.trade_margin = ".$trade_margin_filter; - } - - - // Manufacturer - $params['sql_select']['manufacturer'] = [ - "table" => "m", - "field" => "name", - "filtering" => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH - ]; - - - $params['sql_table']['m'] = [ - "table" => "manufacturer", - "join" => "LEFT JOIN", - 'on' => "p.`id_manufacturer` = m.`id_manufacturer`" - ]; - - - $manufacturer_filter = Tools::getValue('filter_column_manufacturer', false); - if ($manufacturer_filter && $manufacturer_filter != '') { - $params['sql_where'][] .= " p.id_manufacturer = ".$manufacturer_filter; - } - + $params['sql_where'][] .= " p.wholesale_price = " . $wholesale_price_filter; } - -} \ No newline at end of file + + // Marża + $params['sql_select']['trade_margin'] = [ + 'table' => 'p', + 'field' => 'trade_margin', + 'filtering' => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH + ]; + + $trade_margin_filter = Tools::getValue('filter_column_trade_margin', false); + if ($trade_margin_filter && $trade_margin_filter != '') + { + $params['sql_where'][] .= "p.trade_margin = " . $trade_margin_filter; + } + + + // Manufacturer + $params['sql_select']['manufacturer'] = [ + "table" => "m", + "field" => "name", + "filtering" => \PrestaShop\PrestaShop\Adapter\Admin\AbstractAdminQueryBuilder::FILTERING_LIKE_BOTH + ]; + + + $params['sql_table']['m'] = [ + "table" => "manufacturer", + "join" => "LEFT JOIN", + 'on' => "p.`id_manufacturer` = m.`id_manufacturer`" + ]; + + + $manufacturer_filter = Tools::getValue('filter_column_manufacturer', false); + if ($manufacturer_filter && $manufacturer_filter != '') + { + $params['sql_where'][] .= " p.id_manufacturer = " . $manufacturer_filter; + } + } +} diff --git a/modules/empikmarketplace/.gitignore b/modules/empikmarketplace/.gitignore new file mode 100644 index 00000000..4064c4ea --- /dev/null +++ b/modules/empikmarketplace/.gitignore @@ -0,0 +1 @@ +data/*.csv \ No newline at end of file diff --git a/modules/empikmarketplace/api.php b/modules/empikmarketplace/api.php new file mode 100644 index 00000000..14800c76 --- /dev/null +++ b/modules/empikmarketplace/api.php @@ -0,0 +1,34 @@ +getOffer($request); + var_dump($result); // \Mirakl\MMP\Shop\Domain\Offer\ShopOffer + + // You can also retrieve raw response by using run() method of API client: +// $result = $api->run($request); // or $api->raw()->getOffer($request) +// var_dump($result); // returns \Psr\Http\Message\ResponseInterface + +} catch (\Exception $e) { + // An exception is thrown if object requested is not found or if an error occurs + var_dump($e->getMessage()); +} \ No newline at end of file diff --git a/modules/empikmarketplace/classes/EmpikAction.php b/modules/empikmarketplace/classes/EmpikAction.php new file mode 100644 index 00000000..2da5df28 --- /dev/null +++ b/modules/empikmarketplace/classes/EmpikAction.php @@ -0,0 +1,60 @@ + 'empik_action', + 'primary' => 'id_empik_action', + 'fields' => [ + 'id_shop' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isUnsignedInt', + 'required' => true, + ], + 'action' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'status' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'id_import' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isCleanHtml', + ], + 'import_count' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isCleanHtml', + ], + 'date_start' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => true, + ], + 'date_end' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => true, + ], + ], + ]; +} \ No newline at end of file diff --git a/modules/empikmarketplace/classes/EmpikActionLog.php b/modules/empikmarketplace/classes/EmpikActionLog.php new file mode 100644 index 00000000..adbb5f9f --- /dev/null +++ b/modules/empikmarketplace/classes/EmpikActionLog.php @@ -0,0 +1,30 @@ + 'empik_action', + 'primary' => 'id_empik_action_log', + 'fields' => [ + 'id_empik_action' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isUnsignedInt', + 'required' => true, + ], + 'message' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'date_add' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => true, + ], + ], + ]; +} \ No newline at end of file diff --git a/modules/empikmarketplace/classes/EmpikOrder.php b/modules/empikmarketplace/classes/EmpikOrder.php new file mode 100644 index 00000000..8c3ecf6f --- /dev/null +++ b/modules/empikmarketplace/classes/EmpikOrder.php @@ -0,0 +1,87 @@ + 'empik_orders', + 'primary' => 'id_empik_order', + 'fields' => [ + 'id_order' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isUnsignedInt', + 'required' => true, + ], + 'empik_order_reference' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'empik_order_carrier' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'empik_payment' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + 'required' => true, + ], + 'empik_carrier' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + 'required' => true, + ], + 'empik_pickup_point' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'empik_vat_number' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'date_add' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => false, + ], + ], + ]; + + public static function getEmpikOrderByOrderId($orderId) + { + $query = (new DbQuery()) + ->select('eo.*') + ->from('empik_orders', 'eo') + ->where('eo.id_order = "'.pSQL($orderId).'"'); + + return Db::getInstance()->getRow($query); + } + + public static function getEmpikOrderReferenceByOrderId($orderId) + { + $query = (new DbQuery()) + ->select('eo.empik_order_reference') + ->from('empik_orders', 'eo') + ->where('eo.id_order = "'.pSQL($orderId).'"'); + + return Db::getInstance()->getValue($query); + } + + public static function getOrderIdByEmpikOrderReference($empikOrderReference) + { + $query = (new DbQuery()) + ->select('eo.id_order') + ->from('empik_orders', 'eo') + ->where('eo.empik_order_reference = "'.pSQL($empikOrderReference).'"'); + + return Db::getInstance()->getValue($query); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/classes/EmpikProduct.php b/modules/empikmarketplace/classes/EmpikProduct.php new file mode 100644 index 00000000..3c79ff85 --- /dev/null +++ b/modules/empikmarketplace/classes/EmpikProduct.php @@ -0,0 +1,64 @@ + 'empik_product', + 'primary' => 'id_empik_product', + 'fields' => [ + 'id_product' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], + 'id_product_attribute' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true], + 'product_export' => ['type' => self::TYPE_INT, 'validate' => 'isBool', 'required' => false], + 'offer_export' => ['type' => self::TYPE_INT, 'validate' => 'isBool', 'required' => false], + 'offer_price' => ['type' => self::TYPE_FLOAT, 'validate' => 'isPrice', 'required' => false], + 'offer_price_reduced' => ['type' => self::TYPE_FLOAT, 'validate' => 'isPrice', 'required' => false], + 'logistic_class' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => false], + 'condition' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => false], + 'export_original_price' => ['type' => self::TYPE_INT, 'validate' => 'isBool', 'required' => false], + ], + ]; + + public static function getById($productId, $productAttributeId = 0) + { + $sql = new DbQuery(); + $sql->select('*'); + $sql->from('empik_product'); + $sql->where('id_product = '.(int)$productId); + $sql->where('id_product_attribute = '.(int)$productAttributeId); + + $row = Db::getInstance()->getRow($sql); + + if ($row) { + $empikProduct = new EmpikProduct(); + $empikProduct->hydrate($row); + + return $empikProduct; + } + + return null; + } + + public static function getOrCreate($productId, $productAttributeId = 0) + { + $empikProduct = self::getById($productId, $productAttributeId); + if (!$empikProduct) { + $empikProduct = new EmpikProduct(); + $empikProduct->condition = 11; + $empikProduct->id_product = $productId; + $empikProduct->id_product_attribute = $productAttributeId; + $empikProduct->add(); + } + + return $empikProduct; + } +} diff --git a/modules/empikmarketplace/classes/index.php b/modules/empikmarketplace/classes/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/classes/index.php @@ -0,0 +1,11 @@ +=5.6.0", + "composer/installers": "~1.0", + "prestashop/module-lib-service-container": "^1.4" + }, + "autoload": { + "psr-4": { + "Empik\\Marketplace\\": "src/" + }, + "exclude-from-classmap": [], + "classmap": [ + "classes/" + ] + }, + "config": { + "preferred-install": "dist", + "prepend-autoloader": false + } +} diff --git a/modules/empikmarketplace/composer.lock b/modules/empikmarketplace/composer.lock new file mode 100644 index 00000000..d0ad17ca --- /dev/null +++ b/modules/empikmarketplace/composer.lock @@ -0,0 +1,1376 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "45ba57916503a8c5dc60eb14ae04e653", + "packages": [ + { + "name": "composer/installers", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Starbug", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "miaoxing", + "modulework", + "modx", + "moodle", + "osclass", + "pantheon", + "phpbb", + "piwik", + "ppi", + "processwire", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "tastyigniter", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-09-13T08:19:44+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "5.3.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "93bbdb30d59be6cd9839495306c65f2907370eb9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/93bbdb30d59be6cd9839495306c65f2907370eb9", + "reference": "93bbdb30d59be6cd9839495306c65f2907370eb9", + "shasum": "" + }, + "require": { + "guzzlehttp/ringphp": "^1.1", + "php": ">=5.4.0", + "react/promise": "^2.2" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2018-07-31T13:33:10+00:00" + }, + { + "name": "guzzlehttp/ringphp", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/RingPHP.git", + "reference": "5e2a174052995663dd68e6b5ad838afd47dd615b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/5e2a174052995663dd68e6b5ad838afd47dd615b", + "reference": "5e2a174052995663dd68e6b5ad838afd47dd615b", + "shasum": "" + }, + "require": { + "guzzlehttp/streams": "~3.0", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", + "abandoned": true, + "time": "2018-07-31T13:22:33+00:00" + }, + { + "name": "guzzlehttp/streams", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "abandoned": true, + "time": "2014-10-12T19:18:40+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.21", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/96c132c7f2f7bc3230723b66e89f8f150b29d5ae", + "reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2022-02-16T17:07:03+00:00" + }, + { + "name": "prestashop/module-lib-cache-directory-provider", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PrestaShopCorp/module-lib-cache-directory-provider.git", + "reference": "34a577b66a7e52ae16d6f40efd1db17290bad453" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PrestaShopCorp/module-lib-cache-directory-provider/zipball/34a577b66a7e52ae16d6f40efd1db17290bad453", + "reference": "34a577b66a7e52ae16d6f40efd1db17290bad453", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "type": "project", + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibCacheDirectoryProvider\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AFL-3.0" + ], + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "description": "Cache directory provider to use on prestashop modules", + "keywords": [ + "composer", + "modules", + "package", + "prestashop" + ], + "time": "2020-09-08T14:13:23+00:00" + }, + { + "name": "prestashop/module-lib-service-container", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/PrestaShopCorp/module-lib-service-container.git", + "reference": "96f4f551b96cffb1f78462cd4722f0d2b057abda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PrestaShopCorp/module-lib-service-container/zipball/96f4f551b96cffb1f78462cd4722f0d2b057abda", + "reference": "96f4f551b96cffb1f78462cd4722f0d2b057abda", + "shasum": "" + }, + "require": { + "php": ">=5.6.0", + "prestashop/module-lib-cache-directory-provider": "^1.0", + "symfony/config": "^3.4", + "symfony/dependency-injection": "^3.4", + "symfony/expression-language": "^3.4", + "symfony/yaml": "^3.4" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibServiceContainer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AFL-3.0" + ], + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "description": "Service container to use on prestashop modules", + "keywords": [ + "composer", + "modules", + "package", + "prestashop" + ], + "time": "2021-06-01T15:21:20+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "react/promise", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-02-11T10:27:51+00:00" + }, + { + "name": "symfony/cache", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/a7a14c4832760bd1fbd31be2859ffedc9b6ff813", + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "symfony/polyfill-apcu": "~1.1" + }, + "conflict": { + "symfony/var-dumper": "<3.3" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/config", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f", + "reference": "bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/filesystem": "~2.8|~3.0|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3", + "symfony/finder": "<3.3" + }, + "require-dev": { + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0", + "symfony/finder": "~3.3|~4.0", + "symfony/yaml": "~3.0|~4.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "51d2a2708c6ceadad84393f8581df1dcf9e5e84b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/51d2a2708c6ceadad84393f8581df1dcf9e5e84b", + "reference": "51d2a2708c6ceadad84393f8581df1dcf9e5e84b", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/expression-language", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ExpressionLanguage Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + }, + { + "name": "symfony/polyfill-apcu", + "version": "v1.19.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-apcu.git", + "reference": "b44b51e7814c23bfbd793a16ead5d7ce43ed23c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/b44b51e7814c23bfbd793a16ead5d7ce43ed23c5", + "reference": "b44b51e7814c23bfbd793a16ead5d7ce43ed23c5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Apcu\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "apcu", + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-21T09:57:48+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.19.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", + "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "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" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.19.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "88289caa3c166321883f67fe5130188ebbb47094" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", + "reference": "88289caa3c166321883f67fe5130188ebbb47094", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.6.0" + }, + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/modules/empikmarketplace/config/admin/index.php b/modules/empikmarketplace/config/admin/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/config/admin/index.php @@ -0,0 +1,11 @@ + + + empikmarketplace + + + + + + + 0 + 0 + + \ No newline at end of file diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikActionLogController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikActionLogController.php new file mode 100644 index 00000000..2e7779d4 --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikActionLogController.php @@ -0,0 +1,219 @@ +bootstrap = true; + $this->table = 'empik_action'; + $this->className = 'EmpikAction'; + $this->lang = false; + + parent::__construct(); + + $this->empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory'); + $this->empikClient = $this->empikClientFactory->createClient(); + + $this->_select .= 'id_import AS id_import_log'; + $this->_defaultOrderWay = 'DESC'; + + $this->fields_list = [ + 'id_empik_action' => [ + 'title' => $this->l('ID'), + 'align' => 'center', + 'class' => 'fixed-width-xs' + ], + 'action' => [ + 'title' => $this->l('Action'), + ], + 'date_start' => [ + 'title' => $this->l('Date start'), + 'type' => 'datetime', + ], + 'date_end' => [ + 'title' => $this->l('Date end'), + 'type' => 'datetime', + ], + 'status' => [ + 'title' => $this->l('Status'), + ], + 'id_import' => [ + 'title' => $this->l('Import ID'), + ], + 'import_count' => [ + 'title' => $this->l('Nb. products'), + ], + 'id_import_log' => [ + 'title' => $this->l('Report'), + 'class' => 'fixed-width-md', + 'align' => 'center', + 'callback' => 'displayDownloadReportButton', + 'search' => false, + 'orderby' => false, + ], + ]; + } + + public function initToolbar() + { + $this->toolbar_btn = []; + } + + public function initContent() + { + $this->cleanupActionLog(); + + parent::initContent(); + + $this->updateActionLog(); + } + + public function init() + { + if (Tools::getValue('action') === 'downloadLog') { + $this->getExportErrorLog(); + } + + parent::init(); + } + + public function displayDownloadReportButton($val, $row) + { + if (!$val || $row['status'] !== 'COMPLETE') { + return ''; + } + + $this->context->smarty->assign( + [ + 'href' => self::$currentIndex.'&token='.$this->token. '&'.$this->identifier.'='.$row['id_empik_action'].'&action=downloadLog', + ] + ); + + return $this->module->display($this->module->name, 'views/templates/admin/list_action_download.tpl'); + } + + public function getExportErrorLog() + { + /** @var EmpikAction $obj */ + $empikAction = $this->loadObject(); + $importId = $empikAction->id_import; + + if (!$importId) { + $this->errors[] = $this->l('No import ID for selected action'); + return; + } + + try { + switch ($empikAction->action) { + case EmpikAction::ACTION_PRODUCT_EXPORT: + $response = $this->empikClient->getProductImportErrorReport($importId); + break; + case EmpikAction::ACTION_OFFER_EXPORT: + $response = $this->empikClient->getOfferImportErrorReport($importId); + break; + default: + return; + } + + $this->contentOutput($response, sprintf('report_%s.csv', $importId)); + + } catch (Exception $e) { + $this->errors[] = sprintf($this->l('No error report found for import: %s'), $importId); + } + } + + protected function cleanupActionLog() + { + $id = Db::getInstance()->getValue('SELECT MAX(id_empik_action) - '.(int)$this->logLimit.' FROM `'._DB_PREFIX_.'empik_action`'); + Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'empik_action` WHERE id_empik_action <= ' . (int)$id); + } + + protected function updateActionLog() + { + $this->getList(Context::getContext()->language->id); + + $endStatuses = ['COMPLETE', 'FAILED', 'API_ERROR']; + + foreach ($this->_list as $row) { + + $empikAction = new EmpikAction($row['id_empik_action']); + + if (!$empikAction->id_import || in_array($empikAction->status, $endStatuses)) { + continue; + } + + try { + switch ($empikAction->action) { + case EmpikAction::ACTION_PRODUCT_EXPORT: + $response = $this->empikClient->getProductsImport($empikAction->id_import); + $this->updateActionProductImport($response, $empikAction); + break; + case EmpikAction::ACTION_OFFER_EXPORT: + $response = $this->empikClient->getOffersImport($empikAction->id_import); + $this->updateActionOfferImport($response, $empikAction); + break; + } + } catch (Exception $e) { + $this->errors[] = $e->getMessage(); + } + } + } + + /** + * @param array $response + * @param EmpikAction $action + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + protected function updateActionProductImport($response, $action) + { + $action->status = $response['import_status']; + $action->import_count = $response['transform_lines_read']; + $action->update(); + } + + /** + * @param array $response + * @param EmpikAction $action + * @throws PrestaShopDatabaseException + * @throws PrestaShopException + */ + protected function updateActionOfferImport($response, $action) + { + $action->status = $response['status']; + $action->import_count = $response['lines_read']; + $action->update(); + } + + /** + * @param string $content + * @param string $filename + */ + protected function contentOutput($content, $filename = 'error_report.csv') + { + ob_clean(); + header('Content-Type: application/octet-stream'); + header('Content-Disposition: attachment; filename="'.$filename.'"'); + header('Content-Length: ' . strlen($content)); + echo $content; + exit; + } + + protected function l($string, $class = null, $addslashes = false, $htmlentities = true) + { + return Translate::getModuleTranslation($this->module, $string, get_class($this), null, $addslashes); + } +} diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikConnectionController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikConnectionController.php new file mode 100644 index 00000000..ea0605d6 --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikConnectionController.php @@ -0,0 +1,201 @@ +bootstrap = true; + + $this->_conf[self::CONN_SUCCESS] = $this->l('Connection to API works fine.'); + $this->_error[self::CONN_ERROR_API] = $this->l('Unable to connect, check connection details and try again.'); + + $this->empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory'); + $this->link = $this->module->getService('empik.marketplace.adapter.link'); + } + + public function initProcess() + { + $this->display = 'edit'; + + parent::initProcess(); + } + + public function postProcess() + { + if (Tools::getIsset('submit'.$this->controller_name)) { + $this->handleForm(); + } + + parent::postProcess(); + } + + public function handleForm() + { + $environment = Tools::getValue('environment'); + $apiKey = Tools::getValue('api_key'); + + if (!Validator::isValidEnvironment($environment)) { + $this->errors[] = $this->l('Invalid environment field'); + } + + if (!Validator::isValidApiKey($apiKey)) { + $this->errors[] = $this->l('Invalid API key field'); + } + + if (empty($this->errors)) { + + $result = true; + + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_ENVIRONMENT, $environment); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_API_KEY, $apiKey); + + if ($result) { + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => 4]) + ); + } + } + + $this->errors[] = $this->l('Error saving form.'); + } + + public function processTestConnection() + { + $status = $this->getConnectionStatus(); + if ($status === self::CONN_SUCCESS) { + $this->module->setAuthStatus(); + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => self::CONN_SUCCESS]) + ); + } + + $this->errors[] = $this->_error[self::CONN_ERROR_API]; + } + + /** + * @return int + */ + public function getConnectionStatus() + { + try { + $client = $this->empikClientFactory->createClient(); + $client->getAccount(); + } catch (Exception $e) { + return self::CONN_ERROR_API; + } + + return self::CONN_SUCCESS; + } + + public function renderForm() + { + $controller = $this->controller_name; + + $this->context->smarty->assign([ + 'url_test_connection' => $this->link->getAdminLink($controller, ['action' => 'testConnection']) + ]); + + $fields = [ + 'form' => [ + 'legend' => [ + 'title' => $this->l('Configuration'), + 'icon' => 'icon-cogs', + ], + 'input' => [ + [ + 'type' => 'select', + 'name' => 'environment', + 'label' => $this->l('Environment'), + 'hint' => $this->l('Select environment'), + 'options' => [ + 'query' => [ + [ + 'url' => ConfigurationAdapter::ENV_TEST, + 'name' => $this->l('testing'), + ], + [ + 'url' => ConfigurationAdapter::ENV_PROD, + 'name' => $this->l('production'), + ], + ], + 'id' => 'url', + 'name' => 'name', + ], + 'class' => 'fixed-width-xxl', + ], + [ + 'type' => 'text', + 'label' => $this->l('API key'), + 'hint' => $this->l('API key'), + 'name' => 'api_key', + ], + [ + 'label' => '', + 'type' => 'html', + 'name' => 'html_data', + 'html_content' => $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/_partials/test_connection_button.tpl' + ), + ], + [ + 'label' => '', + 'type' => 'html', + 'name' => 'custom_html', + 'html_content' => $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/_partials/test_connection_footer.tpl' + ), + ], + ], + ], + ]; + + $helper = new HelperForm(); + + $helper->show_toolbar = false; + $helper->default_form_language = (int)Configuration::get('PS_LANG_DEFAULT'); + $helper->module = $this->module; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $helper->identifier = $this->identifier; + $helper->submit_action = 'submit'.$controller; + $helper->currentIndex = $this->link->getAdminLink($controller); + $helper->token = Tools::getAdminTokenLite($controller); + $helper->tpl_vars = [ + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id, + 'fields_value' => [ + 'environment' => Tools::getValue('environment', Configuration::get(ConfigurationAdapter::CONF_ENVIRONMENT)), + 'api_key' => Tools::getValue('api_key', Configuration::get(ConfigurationAdapter::CONF_API_KEY)) + ] + ]; + + return $helper->generateForm([$fields]); + } + + protected function l($string, $class = null, $addslashes = false, $htmlentities = true) + { + return Translate::getModuleTranslation($this->module, $string, get_class($this), null, $addslashes); + } +} diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikController.php new file mode 100644 index 00000000..e2eae310 --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikController.php @@ -0,0 +1,6 @@ +bootstrap = true; + + $this->cronJobsHandler = $this->module->getService('empik.marketplace.handler.cronJobs'); + $this->prestaShopContext = $this->module->getService('empik.marketplace.prestaShopContext'); + } + + public function initContent() + { + $this->context->smarty->assign([ + 'cron_jobs' => $this->cronJobsHandler->getAvailableActionsUrls(), + 'url_help' => 'https://www.empik.com/empikplace/pomoc', + 'url_docs' => 'https://www.empik.com/empikplace/integracje/prestashop/instrukcja', + ]); + + $this->content = $this->context->smarty->fetch( + $this->module->getLocalPath() . '/views/templates/admin/help.tpl' + ); + + parent::initContent(); + } + + protected function l($string, $class = null, $addslashes = false, $htmlentities = true) + { + return Translate::getModuleTranslation($this->module, $string, get_class($this), null, $addslashes); + } +} diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikOffersController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikOffersController.php new file mode 100644 index 00000000..56ca7c6e --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikOffersController.php @@ -0,0 +1,341 @@ +bootstrap = true; + + $this->_conf[self::CONF_EXPORT_SUCCESS] = $this->l('Export successful.'); + + $this->exportOfferProcessor = $this->module->getService('empik.marketplace.processor.exportOfferProcessor'); + $this->link = $this->module->getService('empik.marketplace.adapter.link'); + } + + public function init() + { + if (Tools::getIsset('submitOrderForm')) { + $this->handleForm(); + } + + parent::init(); + } + + public function ajaxProcessExportOffers() + { + $page = (int)Tools::getValue('page'); + if ($page < 0) { + $page = 0; + } + + $this->exportOfferProcessor->setPage($page); + $this->exportOfferProcessor->process(); + + $continue = !$this->exportOfferProcessor->isLastPage(); + + $this->ajaxDie(json_encode([ + 'success' => !$this->exportOfferProcessor->hasErrors(), + 'errors' => $this->exportOfferProcessor->getErrors(), + 'continue' => $continue, + 'redirect' => $this->link->getAdminLink($this->controller_name, ['conf' => self::CONF_EXPORT_SUCCESS]), + ])); + } + + public function initContent() + { + $this->display = 'edit'; + + parent::initContent(); + } + + public function setMedia($isNewTheme = false) + { + parent::setMedia($isNewTheme); + + $this->addJS(_MODULE_DIR_ . $this->module->name . '/views/js/admin/empik.js'); + + Media::addJsDef([ + 'empikAjaxUrl' => $this->link->getAdminLink($this->controller_name, ['ajax' => 1]), + ]); + } + + public function renderForm() + { + return $this->renderOrderForm(); + } + + public function renderOrderForm() + { + $controller = $this->controller_name; + $language = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + + $this->context->smarty->assign([ + 'url_export_offers' => $this->link->getAdminLink($controller, ['action' => 'exportOffers']), + 'url_manage_price' => $this->link->getAdminLink('AdminEmpikProductsPrice'), + ]); + + $leadTimeToShip = []; + $leadTimeToShip[] = [ + 'id' => -1, + 'name' => $this->l('- No selection -'), + ]; + for ($x = 0; $x <= 44; $x++) { + $leadTimeToShip[] = [ + 'id' => $x, + 'name' => $x, + ]; + } + + $formFields = [ + 'form' => [ + 'legend' => [ + 'title' => $this->l('Offers'), + 'icon' => 'icon-cogs', + ], + 'input' => [ + [ + 'type' => 'switch', + 'label' => $this->l('Sync Empik Marketplace offers automatically'), + 'hint' => $this->l('Sync Empik Marketplace offers automatically'), + 'name' => 'sync_offers', + 'is_bool' => true, + 'values' => [ + [ + 'id' => 'sync_offers_on', + 'value' => 1, + 'label' => $this->l('Yes'), + ], + [ + 'id' => 'sync_offers_off', + 'value' => 0, + 'label' => $this->l('No'), + ], + ], + ], + [ + 'type' => 'switch', + 'label' => $this->l('Sync logistic class'), + 'hint' => $this->l('Enabling this option will update logistic class for all offers'), + 'name' => 'sync_logistic_class', + 'is_bool' => true, + 'values' => [ + [ + 'id' => 'sync_logistic_class_on', + 'value' => 1, + 'label' => $this->l('Yes'), + ], + [ + 'id' => 'sync_logistic_class_off', + 'value' => 0, + 'label' => $this->l('No'), + ], + ], + ], + [ + 'type' => 'select', + 'label' => $this->l('Offer identifier'), + 'hint' => $this->l('Offer identifier'), + 'name' => 'offer_identifier', + 'options' => [ + 'query' => [ + [ + 'id' => 'EAN', + 'name' => $this->l('EAN'), + ], + [ + 'id' => 'SHOP_SKU', + 'name' => $this->l('SKU'), + ], + ], + 'id' => 'id', + 'name' => 'name', + ], + ], + [ + 'type' => 'select', + 'label' => $this->l('SKU type'), + 'hint' => $this->l('SKU type'), + 'name' => 'sku_type', + 'options' => [ + 'query' => [ + [ + 'id' => 'REFERENCE', + 'name' => $this->l('Reference'), + ], + [ + 'id' => 'EAN', + 'name' => $this->l('EAN'), + ], + [ + 'id' => 'ID', + 'name' => $this->l('ID'), + ], + ], + 'id' => 'id', + 'name' => 'name', + ], + ], + [ + 'type' => 'select', + 'label' => $this->l('Leadtime to ship'), + 'hint' => $this->l('Leadtime to ship'), + 'name' => 'lead_time_to_ship', + 'options' => [ + 'query' => $leadTimeToShip, + 'id' => 'id', + 'name' => 'name', + ], + ], + [ + 'type' => 'text', + 'label' => $this->l('Price ratio'), + 'hint' => $this->l('Price ratio'), + 'name' => 'price_ratio', + ], + [ + 'type' => 'text', + 'label' => $this->l('Add to price'), + 'hint' => $this->l('Add to price'), + 'name' => 'add_to_price', + ], + [ + 'type' => 'text', + 'label' => $this->l('Reduce stock'), + 'hint' => $this->l('Reduce stock'), + 'name' => 'reduce_stock', + ], + [ + 'label' => '', + 'type' => 'html', + 'name' => 'html_data', + 'html_content' => $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/_partials/export_offers_button.tpl' + ), + ], + [ + 'label' => '', + 'type' => 'html', + 'name' => 'html_data', + 'html_content' => $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/_partials/manage_price_button.tpl' + ), + ], + ], + 'buttons' => [], + 'submit' => [ + 'title' => $this->l('Save'), + ], + ], + ]; + + $helper = new HelperForm(); + + $helper->show_toolbar = false; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $helper->default_form_language = $language->id; + $helper->submit_action = 'submitOrderForm'; + $helper->currentIndex = $this->link->getAdminLink($controller); + $helper->token = Tools::getAdminTokenLite('AdminEmpikOffers'); + $helper->tpl_vars = [ + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id, + ]; + + $helper->tpl_vars['fields_value']['sync_offers'] = Tools::getValue('sync_offers', (int)Configuration::get(ConfigurationAdapter::CONF_SYNC_OFFERS)); + $helper->tpl_vars['fields_value']['sync_logistic_class'] = Tools::getValue('sync_logistic_class', (int)Configuration::get(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS)); + $helper->tpl_vars['fields_value']['offer_identifier'] = Tools::getValue('offer_identifier', Configuration::get(ConfigurationAdapter::CONF_OFFER_IDENTIFIER)); + $helper->tpl_vars['fields_value']['sku_type'] = Tools::getValue('sku_type', Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE)); + $helper->tpl_vars['fields_value']['lead_time_to_ship'] = Tools::getValue('lead_time_to_ship', (float)Configuration::get(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP)); + $helper->tpl_vars['fields_value']['price_ratio'] = Tools::getValue('price_ratio', (float)Configuration::get(ConfigurationAdapter::CONF_PRICE_RATIO)); + $helper->tpl_vars['fields_value']['add_to_price'] = Tools::getValue('add_to_price', (float)Configuration::get(ConfigurationAdapter::CONF_ADD_TO_PRICE)); + $helper->tpl_vars['fields_value']['reduce_stock'] = Tools::getValue('reduce_stock', (int)Configuration::get(ConfigurationAdapter::CONF_REDUCE_STOCK)); + + return $helper->generateForm([$formFields]); + } + + public function handleForm() + { + $syncOffers = Tools::getValue('sync_offers'); + $syncLogisticClass = Tools::getValue('sync_logistic_class'); + $offerIdentifier = Tools::getValue('offer_identifier'); + $skuType = Tools::getValue('sku_type'); + $leadTimeToShip = Tools::getValue('lead_time_to_ship'); + $priceRatio = Tools::getValue('price_ratio'); + $addToPrice = Tools::getValue('add_to_price'); + $reduceStock = Tools::getValue('reduce_stock'); + + if (!is_numeric($syncOffers)) { + $this->errors[] = $this->l('Invalid Sync offers field'); + } + + if (!is_numeric($syncLogisticClass)) { + $this->errors[] = $this->l('Invalid Sync logistic class field'); + } + + if (!Validator::isOfferIdentifier($offerIdentifier)) { + $this->errors[] = $this->l('Invalid Offer identifier field'); + } + + if (!Validator::isSkuType($skuType)) { + $this->errors[] = $this->l('Invalid SKU type field'); + } + + if (!Validator::isInt($leadTimeToShip) || $leadTimeToShip < -1 || $leadTimeToShip > 44) { + $this->errors[] = $this->l('Invalid Lead time to ship field'); + } + + if (!Validator::isFloat($priceRatio) || $priceRatio < 0) { + $this->errors[] = $this->l('Invalid Price ratio field'); + } + + if (!Validator::isFloat($addToPrice) || $addToPrice < 0) { + $this->errors[] = $this->l('Invalid Add to price field'); + } + + if (!Validator::isInt($reduceStock) || $reduceStock < 0) { + $this->errors[] = $this->l('Invalid Reduce stock field'); + } + + if (empty($this->errors)) { + + $result = true; + + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SYNC_OFFERS, (int)$syncOffers); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS, (int)$syncLogisticClass); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_OFFER_IDENTIFIER, $offerIdentifier); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SKU_TYPE, $skuType); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP, $leadTimeToShip); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_PRICE_RATIO, (float)$priceRatio); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_ADD_TO_PRICE, (float)$addToPrice); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_REDUCE_STOCK, (float)$reduceStock); + + if ($result) { + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => 4]) + ); + } + } + + $this->errors[] = $this->l('Error saving form.'); + } + + protected function l($string, $class = null, $addslashes = false, $htmlentities = true) + { + return Translate::getModuleTranslation($this->module, $string, get_class($this), null, $addslashes); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikOrdersController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikOrdersController.php new file mode 100644 index 00000000..df7ec186 --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikOrdersController.php @@ -0,0 +1,284 @@ +bootstrap = true; + + $this->empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory'); + $this->carrierMapManager = $this->module->getService('empik.marketplace.manager.carrierMapManager'); + $this->link = $this->module->getService('empik.marketplace.adapter.link'); + } + + public function init() + { + if (Tools::getIsset('submitOrderForm') || Tools::getIsset('submitOrderFormShipping')) { + $this->handleForm(); + } + + parent::init(); + } + + public function initContent() + { + $this->display = 'edit'; + + parent::initContent(); + } + + public function handleForm() + { + $result = true; + + if (Tools::getIsset('submitOrderForm')) { + + $importOrders = Tools::getValue('import_orders'); + $autoAcceptOrders = Tools::getValue('auto_accept_orders'); + $newOrderState = Tools::getValue('new_order_state'); + $shippedOrderState = Tools::getValue('shipped_order_state'); + + if (!Validator::isBool($importOrders)) { + $this->errors[] = $this->l('Invalid Import orders field'); + } + + if (!Validator::isBool($autoAcceptOrders)) { + $this->errors[] = $this->l('Invalid Auto accept orders field'); + } + + if (!Validator::isInt($newOrderState)) { + $this->errors[] = $this->l('Invalid New order state field'); + } + + if (!Validator::isInt($shippedOrderState)) { + $this->errors[] = $this->l('Invalid Shipped order state field'); + } + + if (empty($this->errors)) { + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_IMPORT_ORDERS, (int)$importOrders); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_AUTO_ACCEPT_ORDERS, (int)$autoAcceptOrders); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_NEW_ORDER_STATE, (int)$newOrderState); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SHIPPED_ORDER_STATE, (int)$shippedOrderState); + } + } + + if (Tools::getIsset('submitOrderFormShipping')) { + $result &= $this->carrierMapManager->store(Tools::getValue('carrier', [])); + } + + if ($result && empty($this->errors)) { + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => 4]) + ); + } + + $this->errors[] = $this->l('Error saving form.'); + } + + public function renderForm() + { + if (!$this->module->getAuthStatus()) { + $this->errors[] = $this->l('Before starting, set up the connection'); + return false; + } + + return + $this->renderOrderForm(). + $this->renderShippingMappingForm(); + } + + public function renderOrderForm() + { + $language = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + $orderStates = OrderState::getOrderStates($language->id); + + $formFields = [ + 'form' => [ + 'legend' => [ + 'title' => $this->l('Orders'), + 'icon' => 'icon-cogs', + ], + 'input' => [ + [ + 'type' => 'switch', + 'label' => $this->l('Import orders from Empik Marketplace'), + 'hint' => $this->l('Import orders from Empik Marketplace'), + 'name' => 'import_orders', + 'is_bool' => true, + 'values' => [ + [ + 'id' => 'import_orders_on', + 'value' => 1, + 'label' => $this->l('Yes'), + ], + [ + 'id' => 'import_orders_off', + 'value' => 0, + 'label' => $this->l('No'), + ], + ], + ], + [ + 'type' => 'switch', + 'label' => $this->l('Auto accept orders in Empik Marketplace'), + 'hint' => $this->l('Auto accept orders in Empik Marketplace'), + 'name' => 'auto_accept_orders', + 'is_bool' => true, + 'values' => [ + [ + 'id' => 'auto_accept_orders_on', + 'value' => 1, + 'label' => $this->l('Yes'), + ], + [ + 'id' => 'auto_accept_orders_off', + 'value' => 0, + 'label' => $this->l('No'), + ], + ], + ], + [ + 'type' => 'select', + 'label' => $this->l('New order state'), + 'hint' => $this->l('New order state'), + 'name' => 'new_order_state', + 'options' => [ + 'query' => $orderStates, + 'id' => 'id_order_state', + 'name' => 'name', + ], + 'class' => 'fixed-width-xxl', + ], + [ + 'type' => 'select', + 'label' => $this->l('Shipped order state'), + 'hint' => $this->l('Shipped order state'), + 'name' => 'shipped_order_state', + 'options' => [ + 'query' => $orderStates, + 'id' => 'id_order_state', + 'name' => 'name', + ], + 'class' => 'fixed-width-xxl', + ], + ], + 'buttons' => [], + 'submit' => [ + 'title' => $this->l('Save'), + ], + ], + ]; + + $helper = new HelperForm(); + + $helper->show_toolbar = false; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $helper->default_form_language = $language->id; + $helper->submit_action = 'submitOrderForm'; + $helper->currentIndex = $this->link->getAdminLink($this->controller_name); + $helper->token = Tools::getAdminTokenLite('AdminEmpikOrders'); + $helper->tpl_vars = [ + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id, + ]; + + $helper->tpl_vars['fields_value']['import_orders'] = Tools::getValue('import_orders', (int)Configuration::get(ConfigurationAdapter::CONF_IMPORT_ORDERS)); + $helper->tpl_vars['fields_value']['auto_accept_orders'] = Tools::getValue('auto_accept_orders', (int)Configuration::get(ConfigurationAdapter::CONF_AUTO_ACCEPT_ORDERS)); + $helper->tpl_vars['fields_value']['new_order_state'] = Tools::getValue('new_order_state', (int)Configuration::get(ConfigurationAdapter::CONF_NEW_ORDER_STATE)); + $helper->tpl_vars['fields_value']['shipped_order_state'] = Tools::getValue('shipped_order_state', (int)Configuration::get(ConfigurationAdapter::CONF_SHIPPED_ORDER_STATE)); + + return $helper->generateForm([$formFields]); + } + + public function renderShippingMappingForm() + { + $language = new Language((int)Configuration::get('PS_LANG_DEFAULT')); + + /** @var EmpikClient $client */ + $client = $this->empikClientFactory->createClient(); + + try { + $responseShippingTypes = $client->getShippingTypes(); + $responseCarriers = $client->getCarriers(); + } catch (Exception $e) { + $this->errors[] = $e->getMessage(); + return false; + } + + $shopCarriers = (new CarriersDataProvider())->getCarriers(); + + $this->context->smarty->assign( + [ + 'empik_carriers' => $responseCarriers['carriers'], + 'empik_shipping_types' => $responseShippingTypes['shipping_types'], + 'shop_carriers' => $shopCarriers, + 'map' => $this->carrierMapManager->loadFromConfig(), + ] + ); + + $formFields = [ + 'form' => [ + 'legend' => [ + 'title' => $this->l('Shipping'), + 'icon' => 'icon-cogs', + ], + 'input' => [ + [ + 'type' => 'html', + 'label' => $this->l('Shipping mapping'), + 'name' => 'html_data', + 'html_content' => $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/_partials/shipping_table.tpl' + ), + ], + ], + 'buttons' => [], + 'submit' => [ + 'title' => $this->l('Save'), + ], + ], + ]; + + $helper = new HelperForm(); + + $helper->show_toolbar = false; + $helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0; + $helper->default_form_language = $language->id; + $helper->submit_action = 'submitOrderFormShipping'; + $helper->currentIndex = $this->link->getAdminLink($this->controller_name); + $helper->token = Tools::getAdminTokenLite('AdminEmpikOrders'); + $helper->tpl_vars = [ + 'languages' => $this->context->controller->getLanguages(), + 'id_language' => $this->context->language->id, + ]; + + return $helper->generateForm([$formFields]); + } + + protected function l($string, $class = null, $addslashes = false, $htmlentities = true) + { + return Translate::getModuleTranslation($this->module, $string, get_class($this), null, $addslashes); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikProductsController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikProductsController.php new file mode 100644 index 00000000..f03f4c2d --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikProductsController.php @@ -0,0 +1,472 @@ +table = 'product'; + $this->className = 'Product'; + $this->lang = true; + $this->bootstrap = true; + + parent::__construct(); + + $this->_conf[self::CONF_EXPORT_SUCCESS] = $this->l('Export successful.'); + $this->_conf[self::CONF_EXCLUDE_ALL_SUCCESS] = $this->l('All products removed from export successful.'); + $this->_conf[self::CONF_INCLUDE_ALL_SUCCESS] = $this->l('All products added to export successful.'); + + $this->exportProductProcessor = $this->module->getService('empik.marketplace.processor.exportProductProcessor'); + $this->exportConfiguration = $this->module->getService('empik.marketplace.configuration.exportConfiguration'); + $this->productRepository = $this->module->getService('empik.marketplace.repository.productRepository'); + $this->link = $this->module->getService('empik.marketplace.adapter.link'); + + $langId = Context::getContext()->language->id; + $shopId = Context::getContext()->shop->id; + + if (Tools::getValue('reset_filter_category')) { + $this->context->cookie->id_category_empik_products_filter = false; + } + + $id_category = (int)Tools::getValue('id_category'); + if (Tools::getIsset('id_category')) { + $this->id_current_category = $id_category; + $this->context->cookie->id_category_empik_products_filter = $id_category; + } + + if ($this->context->cookie->id_category_empik_products_filter) { + $this->id_current_category = $this->context->cookie->id_category_empik_products_filter; + } + + if ($this->id_current_category) { + $this->_join .= ' INNER JOIN `'._DB_PREFIX_.'category_product` cp ON ( + cp.`id_product` = a.`id_product` AND cp.`id_category` = '.(int)$this->id_current_category.' + )'; + } + + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'empik_product` ep ON ( + ep.id_product = a.id_product AND ep.id_product_attribute = 0 + )'; + + $this->_select .= ' + a.price AS price_tax_incl, + sa.quantity AS quantity, + cl.name AS category_name, + IFNULL(ep.product_export, 0) AS product_export, + IFNULL(ep.offer_export, 0) AS offer_export + '; + + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'stock_available` sa ON ( + sa.id_product = a.id_product AND + sa.id_product_attribute = 0 '. + StockAvailable::addSqlShopRestriction(null, null, 'sa').')'; + + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON ( + cl.id_category = a.id_category_default AND cl.id_lang = '.(int)$langId.' AND cl.id_shop = '.(int)$shopId.' + )'; + + $this->fields_list = [ + 'id_product' => [ + 'title' => $this->l('ID'), + 'align' => 'center', + 'class' => 'fixed-width-xs', + ], + 'name' => [ + 'title' => $this->l('Name'), + 'filter_key' => 'b!name', + ], + 'category_name' => [ + 'title' => $this->l('Category'), + 'search' => false, + ], + 'reference' => [ + 'title' => $this->l('Reference'), + 'class' => 'fixed-width-md', + ], + 'price' => [ + 'title' => $this->l('Price (tax excl.)'), + 'type' => 'price', + 'class' => 'fixed-width-md', + ], + 'price_tax_incl' => [ + 'title' => $this->l('Price (tax incl.)'), + 'type' => 'price', + 'search' => false, + 'orderby' => false, + 'class' => 'fixed-width-md', + ], + 'quantity' => [ + 'title' => $this->l('Quantity'), + 'filter_key' => 'sa!quantity', + 'class' => 'fixed-width-md', + ], + 'product_export' => [ + 'title' => $this->l('Product export'), + 'product_export' => 'status', + 'type' => 'bool', + 'class' => 'fixed-width-md', + 'align' => 'center', + 'callback' => 'displayEnableProductButton', + ], + 'offer_export' => [ + 'title' => $this->l('Offer export'), + 'offer_export' => 'status', + 'type' => 'bool', + 'class' => 'fixed-width-md', + 'align' => 'center', + 'callback' => 'displayEnableOfferButton', + ], + ]; + + $this->addListActions(); + } + + protected function addListActions() + { + $this->addRowAction('view'); + + $this->bulk_actions = [ + 'addProducts' => [ + 'text' => $this->l('Add products to export'), + 'icon' => 'icon-plus', + ], + 'removeProducts' => [ + 'text' => $this->l('Remove products from export'), + 'icon' => 'icon-trash', + ], + 'addOffers' => [ + 'text' => $this->l('Add offers to export'), + 'icon' => 'icon-plus', + ], + 'removeOffers' => [ + 'text' => $this->l('Remove offers from export'), + 'icon' => 'icon-trash', + ], + ]; + } + + public function displayEnableProductButton($val, $row) + { + $id = $row['id_product']; + $p = Tools::getValue('submitFilter' . $this->table); + + $this->context->smarty->assign( + [ + 'href' => self::$currentIndex.'&token='.$this->token.'&'.$this->identifier.'='.$id.'&action='.(!$val ? 'enableProduct' : 'disableProduct').($p ? '&submitFilter' . $this->table . '=' . $p : ''), + 'action' => $this->l('Enable'), + 'enabled' => $val, + ] + ); + + return $this->module->display($this->module->name, 'views/templates/admin/list_action_enable.tpl'); + } + + public function displayEnableOfferButton($val, $row) + { + $id = $row['id_product']; + $p = Tools::getValue('submitFilter' . $this->table); + + $this->context->smarty->assign( + [ + 'href' => self::$currentIndex.'&token='.$this->token.'&'.$this->identifier.'='.$id.'&action='.(!$val ? 'enableOffer' : 'disableOffer').($p ? '&submitFilter' . $this->table . '=' . $p : ''), + 'action' => $this->l('Enable'), + 'enabled' => $val, + ] + ); + + return $this->module->display($this->module->name, 'views/templates/admin/list_action_enable.tpl'); + } + + public function setMedia($isNewTheme = false) + { + parent::setMedia($isNewTheme); + + $this->addJS(_MODULE_DIR_ . $this->module->name . '/views/js/admin/empik.js'); + + Media::addJsDef([ + 'empikAjaxUrl' => $this->link->getAdminLink($this->controller_name, ['ajax' => 1]), + ]); + } + + public function initToolbar() + { + $this->toolbar_btn = []; + } + + public function getList($id_lang, $orderBy = null, $orderWay = null, $start = 0, $limit = null, $id_lang_shop = null) + { + parent::getList( + $id_lang, + $orderBy, + $orderWay, + $start, + $limit, + true + ); + + foreach ($this->_list as $i => $product) { + $this->_list[$i]['price_tax_incl'] = Product::getPriceStatic($product['id_product']); + } + } + + public function renderView() + { + // PS 1.6 redirect + Tools::redirectAdmin( + $this->link->getAdminLink( + 'AdminProducts', + ['id_product' => Tools::getValue('id_product')] + ) . '&update' . $this->table + ); + } + + public function ajaxProcessExportProducts() + { + $page = (int)Tools::getValue('page'); + if ($page < 0) { + $page = 0; + } + + $this->exportProductProcessor->setPage($page); + $this->exportProductProcessor->process(); + + $continue = !$this->exportProductProcessor->isLastPage(); + + $this->ajaxDie(json_encode([ + 'success' => true, + 'continue' => $continue, + 'redirect' => $this->link->getAdminLink($this->controller_name, ['conf' => self::CONF_EXPORT_SUCCESS]), + 'errors' => $this->errors, + ])); + } + + public function initContent() + { + $exportConf = $this->exportConfiguration; + $csvAbsPath = $exportConf::EXPORT_PATH; + $csvRelPath = $exportConf::EXPORT_DIR . $exportConf::EXPORT_PRODUCT_FILENAME; + + $this->context->smarty->assign( + [ + 'id_category' => $this->id_current_category, + 'tree' => $this->renderCategoryTree(), + 'api_authenticated' => $this->module->getAuthStatus(), + 'url_docs' => $this->link->getAdminLink('AdminEmpikHelp'), + 'url_export_products' => $this->link->getAdminLink($this->controller_name, ['action' => 'exportProducts']), + 'url_exclude_all' => $this->link->getAdminLink($this->controller_name, ['action' => 'excludeAll']), + 'url_include_all' => $this->link->getAdminLink($this->controller_name, ['action' => 'includeAll']), + 'url_products_csv' => file_exists($csvAbsPath) ? $csvRelPath : false, + ] + ); + + $this->content .= $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/products.tpl' + ); + $this->content .= $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/list_category_filter.tpl' + ); + + parent::initContent(); + } + + protected function renderCategoryTree() + { + $tree = new HelperTreeCategories('product_associated_categories'); + $tree->setUseCheckBox(false) + ->setFullTree(true) + ->setRootCategory(Context::getContext()->shop->id_category); + + if ($this->id_current_category) { + $tree->setSelectedCategories([$this->id_current_category]); + } + + $tree->setInputName('category_filter'); + + return $tree->render(); + } + + public function processEnableProduct() + { + $productId = Tools::getValue('id_product'); + + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->product_export = 1; + $empikProduct->save(); + + Db::getInstance()->update('empik_product', ['product_export' => 1], 'id_product = ' . (int)$productId); + } + + public function processDisableProduct() + { + $productId = Tools::getValue('id_product'); + + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->product_export = 0; + $empikProduct->save(); + + Db::getInstance()->update('empik_product', ['product_export' => 0], 'id_product = ' . (int)$productId); + } + + public function processEnableOffer() + { + $productId = Tools::getValue('id_product'); + + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->offer_export = 1; + $empikProduct->save(); + } + + public function processDisableOffer() + { + $productId = Tools::getValue('id_product'); + + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->offer_export = 0; + $empikProduct->save(); + + /** @var UpdateDeleteOfferHandler $handler */ + $handler = $this->module->getService('empik.marketplace.handler.updateDeleteOfferHandler'); + + if (($result = $handler->handle([$productId]))) { + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => 4]) + ); + } + + $this->errors = $handler->getErrors(); + } + + public function processBulkAddProducts() + { + if (is_array($this->boxes) && !empty($this->boxes)) { + foreach ($this->boxes as $productId) { + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->product_export = 1; + $empikProduct->save(); + } + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + + public function processBulkRemoveProducts() + { + if (is_array($this->boxes) && !empty($this->boxes)) { + foreach ($this->boxes as $productId) { + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->product_export = 0; + $empikProduct->save(); + } + + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + + public function processBulkAddOffers() + { + if (is_array($this->boxes) && !empty($this->boxes)) { + foreach ($this->boxes as $productId) { + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->offer_export = 1; + $empikProduct->save(); + } + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + + public function processBulkRemoveOffers() + { + if (is_array($this->boxes) && !empty($this->boxes)) { + + /** @var UpdateDeleteOfferHandler $handler */ + $handler = $this->module->getService('empik.marketplace.handler.updateDeleteOfferHandler'); + + if (($result = $handler->handle($this->boxes))) { + foreach ($this->boxes as $productId) { + $empikProduct = \EmpikProduct::getOrCreate($productId); + $empikProduct->offer_export = 0; + $empikProduct->save(); + } + + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => 4]) + ); + } + + $this->errors = $handler->getErrors(); + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + + public function processExcludeAll() + { + Db::getInstance()->update( + 'empik_product', + [ + 'product_export' => 0, + 'offer_export' => 0, + ] + ); + + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => self::CONF_EXCLUDE_ALL_SUCCESS]) + ); + } + + public function processIncludeAll() + { + $sql = 'INSERT IGNORE INTO `' . _DB_PREFIX_ . 'empik_product` (`id_product`, `id_product_attribute`, `logistic_class`, `product_export`, `offer_export`) + SELECT `id_product`, 0, 0, 1, 1 + FROM `' . _DB_PREFIX_ . 'product` + '; + + Db::getInstance()->execute($sql); + + Db::getInstance()->update( + 'empik_product', + [ + 'product_export' => 1, + 'offer_export' => 1, + ] + ); + + Tools::redirectAdmin( + $this->link->getAdminLink($this->controller_name, ['conf' => self::CONF_INCLUDE_ALL_SUCCESS]) + ); + } + + protected function l($string, $class = null, $addslashes = false, $htmlentities = true) + { + return Translate::getModuleTranslation($this->module, $string, get_class($this), null, $addslashes); + } +} diff --git a/modules/empikmarketplace/controllers/admin/AdminEmpikProductsPriceController.php b/modules/empikmarketplace/controllers/admin/AdminEmpikProductsPriceController.php new file mode 100644 index 00000000..7779065d --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/AdminEmpikProductsPriceController.php @@ -0,0 +1,524 @@ +table = 'empik_product'; + $this->className = EmpikProduct::class; + $this->bootstrap = true; + parent::__construct(); + + // 1.7.0 + if (Tools::getIsset('changeDisplayOriginalPrice')) { + $idEmpikProduct = (int)Tools::getValue('id_empik_product'); + $idProduct = Db::getInstance()->getValue('SELECT id_product FROM ' . _DB_PREFIX_ . 'empik_product + WHERE id_empik_product = ' . (int)$idEmpikProduct); + + if ($idProduct > 0) { + \Db::getInstance()->execute('UPDATE '._DB_PREFIX_.'empik_product + SET export_original_price = IF(export_original_price=1, 0, 1) + WHERE id_product = '.(int)$idProduct); + } + + Tools::redirectAdmin($this->context->link->getAdminLink('AdminEmpikProductsPrice')); + } + + $this->addRowAction('edit'); + + $this->productRepository = $this->module->getService('empik.marketplace.repository.productRepository'); + $this->combinationDataProvider = $this->module->getService('empik.marketplace.dataProvider.combinationDataProvider'); + $this->link = $this->module->getService('empik.marketplace.adapter.link'); + $this->cache = $this->module->getService('empik.marketplace.cache.cache'); + + /** @var EmpikClientFactory $empikClientFactory */ + $empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory'); + $this->empikClient = $empikClientFactory->createClient(); + + $langId = Context::getContext()->language->id; + $shopId = Context::getContext()->shop->id; + + $this->_select .= 'p.reference, p.ean13, pl.name, p.price AS price_tax_incl, + cl.name as category_name, + IFNULL(ep.offer_price, 0) AS offer_price, + IFNULL(ep.offer_price_reduced, 0) AS offer_price_reduced, + CONCAT(ep.id_empik_product, "_", ep.export_original_price) as export_original_price_data + '; // 1.7.0 + + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'product` p ON ( + p.id_product = a.id_product AND a.id_product_attribute = 0 + )'; + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'empik_product` ep ON ( + ep.id_product = a.id_product AND ep.id_product_attribute = 0 + )'; + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON ( + cl.id_category = p.id_category_default AND cl.id_lang = '.(int)$langId.' AND cl.id_shop = '.(int)$shopId.' + )'; + $this->_join .= 'LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON ( + pl.id_product = a.id_product AND pl.id_lang = '.(int)$langId.' AND pl.id_shop = '.(int)$shopId.' + )'; + + $this->_where = 'AND a.id_product_attribute = 0'; + + $this->fields_list = [ + 'id_product' => [ + 'title' => $this->l('ID'), + 'align' => 'center', + 'class' => 'fixed-width-xs', + ], + 'reference' => [ + 'title' => $this->l('Reference'), + 'class' => 'fixed-width-md', + ], + 'ean13' => [ + 'title' => $this->l('EAN'), + 'class' => 'fixed-width-md', + ], + 'name' => [ + 'title' => $this->l('Name'), + 'filter_key' => 'pl!name', + ], + 'category_name' => [ + 'title' => $this->l('Category'), + 'filter_key' => 'cl!name', + ], + 'price_tax_incl' => [ + 'title' => $this->l('Price'), + 'type' => 'price', + 'search' => false, + 'orderby' => false, + 'class' => 'fixed-width-md', + ], + 'offer_price' => [ + 'title' => $this->l('Empik price'), + 'class' => 'fixed-width-md', + 'align' => 'center', + 'callback' => 'displayEmpikPriceColumn', + 'remove_onclick' => true, + ], + 'price_reduced_tax_incl' => [ + 'title' => $this->l('Price reduced'), + 'type' => 'price', + 'search' => false, + 'orderby' => false, + 'class' => 'fixed-width-md', + ], + 'offer_price_reduced' => [ + 'title' => $this->l('Empik price reduced'), + 'class' => 'fixed-width-md', + 'align' => 'center', + 'callback' => 'displayEmpikPriceReducedColumn', + 'remove_onclick' => true, + ], + // 1.7.0 + 'export_original_price_data' => [ + 'title' => $this->l('Display discount'), + 'class' => 'fixed-width-md', + 'align' => 'center', + 'search' => false, + 'orderby' => false, + 'callback' => 'displayEmpikExportOriginalPriceColumn', + 'remove_onclick' => true, + ], + ]; + + $this->addListActions(); + } + + public function displayEmpikPriceColumn($val, $row) + { + $combinations = $this->combinationDataProvider->getCombinationsByProductId($row['id_product']); + + $this->context->smarty->assign([ + 'value' => $val, + 'id_product' => $row['id_product'], + 'combinations' => $combinations, + ]); + + return $this->module->display($this->module->name, 'views/templates/admin/list_action_edit_price.tpl'); + } + + public function displayEmpikPriceReducedColumn($val, $row) + { + $combinations = $this->combinationDataProvider->getCombinationsByProductId($row['id_product']); + + $this->context->smarty->assign([ + 'value' => $val, + 'id_product' => $row['id_product'], + 'combinations' => $combinations, + ]); + + return $this->module->display($this->module->name, 'views/templates/admin/list_action_edit_price_reduced.tpl'); + } + + // 1.7.0 + public function displayEmpikExportOriginalPriceColumn($val) + { + $data = explode('_', $val); + + $this->context->smarty->assign([ + 'displayOriginal' => (bool)$data[1], + 'urlChange' => $this->link->getAdminLink($this->controller_name, ['changeDisplayOriginalPrice' => 1, 'id_empik_product' => $data[0]]), + ]); + + return $this->module->display($this->module->name, 'views/templates/admin/list_action_original_price.tpl'); + } + + public function setMedia($isNewTheme = false) + { + parent::setMedia($isNewTheme); + + $this->addJS(_MODULE_DIR_ . $this->module->name . '/views/js/admin/empik.js'); + + Media::addJsDef([ + 'empikAjaxUrl' => $this->link->getAdminLink($this->controller_name, ['ajax' => 1]), + ]); + } + + public function initToolbar() + { + $this->toolbar_btn = []; + } + + public function initProcess() + { + parent::initProcess(); + + if ($this->action == 'view') { + $this->display = 'edit'; + $this->action = 'edit'; + } + + $this->handleBulkUpdateLogisticClass(); + $this->handleBulkUpdateCondition(); + $this->handleBulkUpdateOriginalPriceOn(); + $this->handleBulkUpdateOriginalPriceOff(); + } + + public function getList($id_lang, $orderBy = null, $orderWay = null, $start = 0, $limit = null, $id_lang_shop = null) + { + parent::getList( + $id_lang, + $orderBy, + $orderWay, + $start, + $limit, + true + ); + + foreach ($this->_list as $i => $product) { + $this->_list[$i]['price_tax_incl'] = Product::getPriceStatic($product['id_product'], true, null, 2, null, false, false); + $this->_list[$i]['price_reduced_tax_incl'] = Product::getPriceStatic($product['id_product'], true, null, 2, null, false, true); + } + } + + public function renderForm() + { + $this->fields_form = [ + 'legend' => [ + 'title' => $this->l('Offer params'), + 'icon' => 'icon-gears', + ], + 'input' => [ + 'name' => [ + 'type' => 'select', + 'label' => $this->l('Logistic class'), + 'name' => 'logistic_class', + 'options' => [ + 'query' => $this->getLogisticClassesOptions(), + 'id' => 'id', + 'name' => 'name', + ], + 'class' => 'fixed-width-xxl', + ], + [ + 'type' => 'select', + 'label' => $this->l('Condition'), + 'name' => 'condition', + 'options' => [ + 'query' => $this->getConditionOptions(), + 'id' => 'id', + 'name' => 'name', + ], + 'class' => 'fixed-width-xxl', + ], + ], + 'submit' => [ + 'title' => $this->l('Save'), + ], + ]; + + return parent::renderForm(); + } + + protected function getLogisticClassesOptions() + { + $logisticClasses = []; + + $response = $this->getLogisticClasses(); + + if (!empty($response['logistic_classes'])) { + foreach ($response['logistic_classes'] as $logisticClass) { + $logisticClasses[] = [ + 'id' => $logisticClass['code'], + 'name' => $logisticClass['label'], + ]; + } + } + + return $logisticClasses; + } + + protected function getConditionOptions() + { + return [ + [ + 'id' => 11, + 'name' => $this->l('New (code 11)') + ], + [ + 'id' => 1, + 'name' => $this->l('Used - very good condition') + ], + [ + 'id' => 2, + 'name' => $this->l('Used - good condition') + ], + [ + 'id' => 3, + 'name' => $this->l('Used - satisfactory condition') + ], + [ + 'id' => 4, + 'name' => $this->l('Renewed - very good condition') + ], + [ + 'id' => 5, + 'name' => $this->l('Renewed - good condition') + ], + [ + 'id' => 6, + 'name' => $this->l('Renewed - satisfactory condition') + ], + [ + 'id' => 7, + 'name' => $this->l('Damaged packaging') + ], + ]; + } + + protected function addListActions() + { + $this->addRowAction('view'); + + // Logistic class + $response = $this->getLogisticClasses(); + if (!empty($response['logistic_classes'])) { + foreach ($response['logistic_classes'] as $logisticClass) { + $key = sprintf('logisticClass_%s', $logisticClass['code']); + $this->bulk_actions[$key] = [ + 'text' => $this->l('Logistic class:') . ' ' . $logisticClass['label'], + 'icon' => 'icon-truck', + ]; + } + } + + // Condition + $conditionOptions = $this->getConditionOptions(); + foreach ($conditionOptions as $conditionOption) { + $key = sprintf('condition_%s', $conditionOption['id']); + $this->bulk_actions[$key] = [ + 'text' => $this->l('Condition:') . ' ' . $conditionOption['name'], + 'icon' => 'icon-gears', + ]; + } + + $key = 'original_price_on'; + $this->bulk_actions[$key] = [ + 'text' => $this->l('Display discounts'), + 'icon' => 'icon-gears', + ]; + + $key = 'original_price_off'; + $this->bulk_actions[$key] = [ + 'text' => $this->l('Do not display discounts'), + 'icon' => 'icon-gears', + ]; + } + + protected function getLogisticClasses() + { + try { + return $this->cache->get('logistic_classes', function () { + return $this->empikClient->getLogisticClasses(); + }); + } catch (Exception $e) { + $this->errors[] = $e->getMessage(); + } + + return []; + } + + protected function handleBulkUpdateLogisticClass() + { + $requestKeys = array_keys($_REQUEST); + $logisticClassRequest = preg_grep('/logisticClass_(\d+)/', $requestKeys); + if (!empty($logisticClassRequest)) { + $logisticClassCode = preg_replace('/\D/', '', reset($logisticClassRequest)); + if (is_numeric($logisticClassCode)) { + $this->processBulkLogisticClass($logisticClassCode); + } + } + } + + protected function handleBulkUpdateCondition() + { + $requestKeys = array_keys($_REQUEST); + $conditionRequest = preg_grep('/condition_(\d+)/', $requestKeys); + if (!empty($conditionRequest)) { + $conditionCode = preg_replace('/\D/', '', reset($conditionRequest)); + if (is_numeric($conditionCode)) { + $this->processBulkCondition($conditionCode); + } + } + } + + protected function handleBulkUpdateOriginalPriceOn() + { + $requestKeys = array_keys($_REQUEST); + $request = preg_grep('/original_price_on/', $requestKeys); + + if (!empty($request)) { + if (is_array($this->boxes) && !empty($this->boxes)) { + $this->toggleOriginalPrice(1); + + $this->confirmations[] = $this->l('Price settings updated successfully!'); + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + } + + protected function handleBulkUpdateOriginalPriceOff() + { + $requestKeys = array_keys($_REQUEST); + $request = preg_grep('/original_price_off/', $requestKeys); + + if (!empty($request)) { + if (is_array($this->boxes) && !empty($this->boxes)) { + $this->toggleOriginalPrice(0); + $this->confirmations[] = $this->l('Price settings updated successfully!'); + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + } + + private function toggleOriginalPrice($value) + { + $idProducts = Db::getInstance()->executeS('SELECT id_product FROM ' . _DB_PREFIX_ . 'empik_product + WHERE id_empik_product IN (' . implode(',', array_map('intval', $this->boxes)) . ')'); + + if (!empty($idProducts)) { + foreach ($idProducts as $idProduct) { + Db::getInstance()->execute( + 'UPDATE ' . _DB_PREFIX_ . 'empik_product + SET `export_original_price` = '.(int)$value.' + WHERE id_product = ' . (int)$idProduct['id_product'] + ); + } + } + } + + public function ajaxProcessSavePrice() + { + $productId = Tools::getValue('id_product'); + $productAttributeId = Tools::getValue('id_product_attribute'); + $price = Tools::getValue('price'); + + $this->productRepository->updateOfferPrice($productId, $productAttributeId, $price); + + $this->ajaxDie(json_encode([ + 'success' => true, + 'message' => $this->l('Price saved successfully!'), + 'errors' => $this->errors, + ])); + } + + public function ajaxProcessSaveReducedPrice() + { + $productId = Tools::getValue('id_product'); + $productAttributeId = Tools::getValue('id_product_attribute'); + $price = Tools::getValue('price'); + + $this->productRepository->updateOfferPriceReduced($productId, $productAttributeId, $price); + + $this->ajaxDie(json_encode([ + 'success' => true, + 'message' => $this->l('Price saved successfully!'), + 'errors' => $this->errors, + ])); + } + + public function processBulkLogisticClass($logisticClass) + { + if (is_array($this->boxes) && !empty($this->boxes)) { + Db::getInstance()->update( + 'empik_product', + [ + 'logistic_class' => (int)$logisticClass, + ], + 'id_empik_product IN (' . implode(',', array_map('intval', $this->boxes)) . ')' + ); + + $this->confirmations[] = $this->l('Logistic class updated successfully!'); + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } + + public function processBulkCondition($condition) + { + if (is_array($this->boxes) && !empty($this->boxes)) { + Db::getInstance()->update( + 'empik_product', + [ + 'condition' => (int)$condition, + ], + 'id_empik_product IN (' . implode(',', array_map('intval', $this->boxes)) . ')' + ); + + $this->confirmations[] = $this->l('Condition updated successfully!'); + } else { + $this->errors[] = $this->l('You must select at least one item'); + } + } +} diff --git a/modules/empikmarketplace/controllers/admin/index.php b/modules/empikmarketplace/controllers/admin/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/controllers/admin/index.php @@ -0,0 +1,11 @@ +cronJobsHandler = $this->module->getService('empik.marketplace.handler.cronJobs'); + } + + public function postProcess() + { + if ($this->cronJobsHandler->checkToken(Tools::getValue('token'))) { + try { + $this->cronJobsHandler->handle(Tools::getValue('action')); + + die($this->module->l('Job complete')); + } catch (InvalidActionException $exception) { + die($this->module->l('Unknown action')); + } catch (Exception $exception) { + die(sprintf($this->module->l('Job failed: %s'), $exception->getMessage())); + } + } else { + die($this->module->l('Invalid token')); + } + } +} diff --git a/modules/empikmarketplace/controllers/front/index.php b/modules/empikmarketplace/controllers/front/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/controllers/front/index.php @@ -0,0 +1,11 @@ +name = 'empikmarketplace'; + $this->version = '2.0.0'; + $this->author = 'Waynet'; + $this->tab = 'market_place'; + $this->need_instance = 0; + $this->bootstrap = true; + + parent::__construct(); + + $this->displayName = $this->l('EmpikPlace'); + $this->description = $this->l('Integration with Empik Marketplace'); + $this->confirmUninstall = $this->l('Are you sure you want to uninstall this module?'); + + $this->controllers = ['cron']; + $this->ps_versions_compliancy = ['min' => '1.7', 'max' => _PS_VERSION_]; + } + + public function getService($serviceName) + { + if (!isset($this->serviceContainer)) { + $this->serviceContainer = new PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer( + $this->name, + $this->getLocalPath() + ); + } + + return $this->serviceContainer->getService($serviceName); + } + + public static function safeAddColumn($table, $column, $def) + { + $count = Db::getInstance()->getValue('SELECT count(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND COLUMN_NAME=\'' . $column . '\' AND TABLE_NAME=\'' . _DB_PREFIX_ . $table . '\''); + if (!$count) + return Db::getInstance()->execute('ALTER TABLE `' . _DB_PREFIX_ . $table . '` ADD `' . $column . '` ' . $def); + + return true; + } + + public function install() + { + $return = true; + + $return &= parent::install(); + $return &= $this->getInstaller()->install(); + $return &= self::safeAddColumn('empik_product', 'condition', 'INT(4) NOT NULL DEFAULT 11 AFTER logistic_class'); + $return &= self::safeAddColumn('empik_product', 'export_original_price', 'INT(1) NOT NULL DEFAULT 0 AFTER logistic_class'); + + return (bool)$return; + } + + public function getInstaller() + { + if (!isset($this->installer)) { + $this->installer = $this->getService('empik.marketplace.install.installer'); + } + + return $this->installer; + } + + public function uninstall() + { + $return = true; + + $return &= $this->getUninstaller()->uninstall(); + $return &= parent::uninstall(); + + return (bool)$return; + } + + public function getUninstaller() + { + if (!isset($this->uninstaller)) { + $this->uninstaller = $this->getService('empik.marketplace.install.uninstaller'); + } + + return $this->uninstaller; + } + + public function isUsingNewTranslationSystem() + { + return false; + } + + public function getAdminTabs() + { + /** @var \Empik\Marketplace\PrestaShopContext $prestaShopContext */ + $prestaShopContext = $this->getService('empik.marketplace.prestaShopContext'); + + return [ + [ + 'className' => 'AdminEmpik', + 'parent' => $prestaShopContext->is17() ? 'SELL' : 0, + 'name' => $this->l('Empik'), + 'module' => $this->name, + 'active' => true, + 'icon' => 'next_week', + ], + [ + 'className' => 'AdminEmpikConnection', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Connection'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + [ + 'className' => 'AdminEmpikProducts', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Products'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + [ + 'className' => 'AdminEmpikProductsPrice', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Products parameters'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + [ + 'className' => 'AdminEmpikOffers', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Offers'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + [ + 'className' => 'AdminEmpikOrders', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Orders'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + [ + 'className' => 'AdminEmpikActionLog', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Last actions'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + [ + 'className' => 'AdminEmpikHelp', + 'parent' => 'AdminEmpik', + 'name' => $this->l('Help'), + 'module' => $this->name, + 'active' => true, + 'icon' => '', + ], + ]; + } + + protected function getHookAction() + { + if (!isset($this->hookAction)) { + $this->hookAction = $this->getService('empik.marketplace.hook.hookAction'); + } + + return $this->hookAction; + } + + public function hookActionAdminOrdersListingFieldsModifier($params) + { + $this->getHookAction()->hookActionAdminOrdersListingFieldsModifier($params); + } + + public function hookActionOrderGridDefinitionModifier(array $params) + { + $this->getHookAction()->hookActionOrderGridDefinitionModifier($params); + } + + public function hookActionOrderGridQueryBuilderModifier(array $params) + { + $this->getHookAction()->hookActionOrderGridQueryBuilderModifier($params); + } + + public function hookActionAdminOrdersTrackingNumberUpdate($params) + { + $this->getHookAction()->hookActionAdminOrdersTrackingNumberUpdate($params); + } + + public function hookActionOrderHistoryAddAfter($params) + { + $this->getHookAction()->hookActionOrderHistoryAddAfter($params); + } + + public function hookDisplayAdminOrderSideBottom(array $params) + { + return $this->getHookAction()->hookDisplayAdminOrder($params); + } + + public function hookDisplayAdminOrderLeft(array $params) + { + return $this->getHookAction()->hookDisplayAdminOrder($params); + } + + public function hookActionAdminControllerSetMedia($params) + { + return $this->getHookAction()->hookActionAdminControllerSetMedia($params); + } + + public function hookActionObjectProductDeleteBefore($params) + { + return $this->getHookAction()->hookActionObjectProductDeleteBefore($params); + } + + public function setAuthStatus() + { + $env = Configuration::get(Empik\Marketplace\Adapter\ConfigurationAdapter::CONF_ENVIRONMENT); + $apiKey = Configuration::get(Empik\Marketplace\Adapter\ConfigurationAdapter::CONF_API_KEY); + + Configuration::updateValue( + Empik\Marketplace\Adapter\ConfigurationAdapter::CONF_AUTH_STATUS, + md5($env.$apiKey) + ); + } + + /** @return bool */ + public function getAuthStatus() + { + $env = Configuration::get(Empik\Marketplace\Adapter\ConfigurationAdapter::CONF_ENVIRONMENT); + $apiKey = Configuration::get(Empik\Marketplace\Adapter\ConfigurationAdapter::CONF_API_KEY); + $status = Configuration::get(Empik\Marketplace\Adapter\ConfigurationAdapter::CONF_AUTH_STATUS); + + return $status === md5($env.$apiKey); + } +} diff --git a/modules/empikmarketplace/index.php b/modules/empikmarketplace/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/index.php @@ -0,0 +1,11 @@ +apiUrl = $apiUrl; + $this->apiKey = $apiKey; + $this->client = $httpClientFactory->createHttpClient($apiUrl); + } + + /** + * @param int|string $id + * @param array $headers + * @param array $body + * + * @return false|array + */ + private function post($id, array $headers = [], array $body = []) + { + return $this->sendRequest($id, $headers, $body, 'POST'); + } + + /** + * @param int|string $id + * @param array $headers + * @param array $body + * + * @return false|array + */ + private function put($id, array $headers = [], array $body = []) + { + return $this->sendRequest($id, $headers, $body, 'PUT'); + } + + /** + * @param int|string $id + * @param array $headers + * @param array $body + * + * @return false|array + */ + private function get($id, array $headers = [], array $body = []) + { + return $this->sendRequest($id, $headers, $body, 'GET'); + } + + /** + * @param int|string $id + * @param array $headers + * @param array $body + * @param string $method + * + * @return false|array|string + */ + private function sendRequest($id, array $headers, array $body, $method) + { + $headers['Authorization'] = $this->apiKey; + + switch ($method) + { + case 'POST': + $response = $this->client->post( + $this->apiUrl . $id, + $headers, + $body + ); + break; + case 'PUT': + $response = $this->client->put( + $this->apiUrl . $id, + $headers, + $body + ); + break; + case 'GET': + $response = $this->client->get( + $this->apiUrl . $id, + $headers, + $body + ); + break; + } + + return $response; + } + + /** + * @return array|bool|false + */ + public function getAccount() + { + return $this->get( + '/api/account' + ); + } + + /** + * P41 - Import products to the operator information + * + * @param string $csvPath + * + * @return array|false + * @throws InvalidArgumentException + */ + public function postProducts($csvPath) + { + if (!file_exists($csvPath)) { + throw new InvalidArgumentException(sprintf('CSV product file does not exists: %s', $csvPath)); + } + + return $this->post( + '/api/products/imports', + [], + [ + 'file' => [ + 'filename' => basename($csvPath), + 'filepath' => $csvPath, + ] + ] + ); + } + + /** + * OF01 - Import a file to add offers + * + * @param string $csvPath + * @param string $importMode + * + * @return array|false + * @throws InvalidArgumentException + */ + public function postOffersImports($csvPath, $importMode = self::IMPORT_MODE_NORMAL) + { + if (!file_exists($csvPath)) { + throw new InvalidArgumentException(sprintf('CSV offer file does not exists: %s', $csvPath)); + } + + if (!in_array($importMode, [self::IMPORT_MODE_NORMAL, self::IMPORT_MODE_PARTIAL_UPDATE, self::IMPORT_MODE_REPLACE])) { + throw new InvalidArgumentException(sprintf('Unsupported import mode: %s', $importMode)); + } + + return $this->post( + '/api/offers/imports', + [], + [ + 'import_mode' => $importMode, + 'file' => [ + 'filename' => basename($csvPath), + 'filepath' => $csvPath, + ] + ] + ); + } + + /** + * OF24 - Create, update, or delete offers + * + * @param array $offers + * + * @return array|false + */ + public function postOffers(array $offers) + { + return $this->post( + '/api/offers', + [ + 'Content-Type' => 'application/json' + ], + [ + 'offers' => $offers, + ] + ); + } + + /** + * GET P42 - Get the import status for a product import + * + * @param int $importId + * @return array|bool|false + */ + public function getProductsImport($importId) + { + return $this->get( + '/api/products/imports/' . (int)$importId + ); + } + + /** + * GET OF02 - Get information and statistics about an offer import + * + * @param int $importId + * @return array|bool|false + */ + public function getOffersImport($importId) + { + return $this->get( + '/api/offers/imports/' . (int)$importId + ); + } + + /** + * GET SH21 - List all carriers + * + * @return array|bool|false + */ + public function getCarriers() + { + return $this->get( + '/api/shipping/carriers' + ); + } + + /** + * GET SH12 - List all active shipping methods + * + * @return array|bool|false + */ + public function getShippingTypes() + { + return $this->get( + '/api/shipping/types' + ); + } + + /** + * GET OR11 - List orders + * + * @param array $filterParams + * @return array|bool|false + */ + public function getOrders($filterParams = []) + { + $filterParams = array_merge([ + 'sort' => 'dateCreated', + 'order' => 'desc', + 'max' => '20', + ], $filterParams); + + $query = http_build_query($filterParams); + + return $this->get( + '/api/orders' . '?' . $query + ); + } + + /** + * PUT OR21 - Accept or refuse order lines + * + * @param int|string $orderReference + * @param array $orderLines + * @return array|bool|false + */ + public function putOrderAccept($orderReference, array $orderLines) + { + $bodyParams['order_lines'] = $orderLines; + + return $this->put( + '/api/orders/' . $orderReference . '/accept', + [ + 'Content-Type' => 'application/json' + ], + $bodyParams + ); + } + + /** + * PUT OR24 - Validate the shipment of an order + * + * @param int|string $orderReference + * @return array|bool|false + */ + public function putOrderShip($orderReference) + { + return $this->put( + '/api/orders/' . $orderReference . '/ship', + [ + 'Content-Type' => 'application/json' + ] + ); + } + + /** + * PUT OR23 - Update carrier tracking information for a specific order + * + * @param int|string $orderReference + * @param string $carrierCode + * @param string $carrierName + * @param string $carrierUrl + * @param string $trackingNumber + * @return array|false + */ + public function putOrderTracking( + $orderReference, + $carrierCode = null, + $carrierName = null, + $carrierUrl = null, + $trackingNumber = null + ) + { + $bodyParams = []; + + if ($carrierCode) { + $bodyParams['carrier_code'] = $carrierCode; + } + + if ($carrierName) { + $bodyParams['carrier_name'] = $carrierName; + } + + if ($carrierUrl) { + $bodyParams['carrier_url'] = $carrierUrl; + } + + if ($trackingNumber) { + $bodyParams['tracking_number'] = $trackingNumber; + } + + return $this->put( + '/api/orders/' . $orderReference . '/tracking', + [ + 'Content-Type' => 'application/json' + ], + $bodyParams + ); + } + + /** + * GET P44 - Get the error report file for a product import + * + * @param string $importId + * @return array|bool|false + */ + public function getProductImportErrorReport($importId) + { + return $this->get( + '/api/products/imports/' . $importId . '/new_product_report' + ); + } + + /** + * GET P44 - Get the error report file for a product import + * + * @param string $importId + * @return array|bool|false + */ + public function getOfferImportErrorReport($importId) + { + return $this->get( + '/api/offers/imports/' . $importId . '/error_report' + ); + } + + /** + * GET SH31 - List all logistic classes + * + * @return array|bool|false + */ + public function getLogisticClasses() + { + return $this->get( + '/api/shipping/logistic_classes' + ); + } +} diff --git a/modules/empikmarketplace/src/API/HttpClientInterface.php b/modules/empikmarketplace/src/API/HttpClientInterface.php new file mode 100644 index 00000000..258799f3 --- /dev/null +++ b/modules/empikmarketplace/src/API/HttpClientInterface.php @@ -0,0 +1,11 @@ +create($id, $headers); + + curl_setopt($ch, CURLOPT_POST,1); + + if (isset($headers['Content-Type']) && $headers['Content-Type'] == 'application/json') { + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); + } else { + curl_setopt($ch, CURLOPT_POSTFIELDS, $body); + } + + $response = $this->execute($ch); + + curl_close($ch); + + return $response; + } + + public function put($id, array $headers = [], array $body = []) + { + $ch = $this->create($id, $headers); + + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); + + $response = $this->execute($ch); + + curl_close($ch); + + return $response; + } + + public function get($id, array $headers = [], array $body = []) + { + $ch = $this->create($id, $headers); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + $response = $this->execute($ch); + + curl_close($ch); + + return $response; + } + + protected function create($id, $headers = []) + { + $ch = curl_init($id); + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + if ($headers) { + $headersString = []; + foreach ($headers as $key => $value) { + $headersString[] = $key . ': ' . $value; + } + + curl_setopt($ch, CURLOPT_HTTPHEADER, $headersString); + } + + return $ch; + } + + protected function execute($ch) + { + $response = curl_exec($ch); + + $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + // is 2xx http code + if ($httpCode < 200 || $httpCode >= 300) { + throw new \Exception('Request failed with HTTP code ' . $httpCode . '.'); + } + + if ($contentType === 'application/json') { + $response = json_decode($response, true); + } + + return $response; + } +} diff --git a/modules/empikmarketplace/src/API/index.php b/modules/empikmarketplace/src/API/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/API/index.php @@ -0,0 +1,11 @@ +shopId = $shopId ? $shopId : Context::getContext()->shop->id; + } + + public function get($key, $langId = null, $shopGroupId = null, $shopId = null, $default = false) + { + if ($shopId === null) { + $shopId = $this->shopId; + } + + return Configuration::get($key, $langId, $shopGroupId, $shopId, $default); + } + + public function updateValue($key, $values, $html = false, $shopGroupId = null, $shopId = null) + { + if ($shopId === null) { + $shopId = $this->shopId; + } + + return Configuration::updateValue($key, $values, $html, $shopGroupId, $shopId); + } + + public function deleteByName($key) + { + return Configuration::deleteByName($key); + } +} diff --git a/modules/empikmarketplace/src/Adapter/LinkAdapter.php b/modules/empikmarketplace/src/Adapter/LinkAdapter.php new file mode 100644 index 00000000..db20bb70 --- /dev/null +++ b/modules/empikmarketplace/src/Adapter/LinkAdapter.php @@ -0,0 +1,37 @@ +prestaShopContext = $prestaShopContext; + $this->link = Context::getContext()->link; + } + + /** + * @param string $controller + * @param array $params + * @return string + */ + public function getAdminLink($controller, $params = []) + { + if ($this->prestaShopContext->is17()) { + return $this->link->getAdminLink($controller, true, [], $params); + } else { + $paramsQuery = $params ? '&' . http_build_query($params) : ''; + return $this->link->getAdminLink($controller, true) . $paramsQuery; + } + } +} diff --git a/modules/empikmarketplace/src/Adapter/LoggerAdapter.php b/modules/empikmarketplace/src/Adapter/LoggerAdapter.php new file mode 100644 index 00000000..aebcfd13 --- /dev/null +++ b/modules/empikmarketplace/src/Adapter/LoggerAdapter.php @@ -0,0 +1,60 @@ +log($message, self::LOG_SEVERITY_LEVEL_INFORMATIVE); + } + + /** + * @param string $message + * @return bool + */ + public function logWarning($message) + { + return $this->log($message, self::LOG_SEVERITY_LEVEL_WARNING); + } + + /** + * @param string $message + * @return bool + */ + public function logError($message) + { + return $this->log($message, self::LOG_SEVERITY_LEVEL_ERROR); + } + + /** + * @param string $message + * @return bool + */ + public function logMajor($message) + { + return $this->log($message, self::LOG_SEVERITY_LEVEL_MAJOR); + } +} diff --git a/modules/empikmarketplace/src/Adapter/ToolsAdapter.php b/modules/empikmarketplace/src/Adapter/ToolsAdapter.php new file mode 100644 index 00000000..4c511600 --- /dev/null +++ b/modules/empikmarketplace/src/Adapter/ToolsAdapter.php @@ -0,0 +1,46 @@ +context = Context::getContext(); + } + + public function hash($value) + { + if ($this->is176()) { + return Tools::hash($value); + } + + return Tools::encrypt($value); + } + + public function is17() + { + return version_compare(_PS_VERSION_, '1.7.0', '>='); + } + + public function is176() + { + return version_compare(_PS_VERSION_, '1.7.6', '>='); + } + + public static function is17static() + { + return version_compare(_PS_VERSION_, '1.7.0', '>='); + } + + public static function is176static() + { + return version_compare(_PS_VERSION_, '1.7.6', '>='); + } +} diff --git a/modules/empikmarketplace/src/Adapter/TranslateAdapter.php b/modules/empikmarketplace/src/Adapter/TranslateAdapter.php new file mode 100644 index 00000000..0fb329ce --- /dev/null +++ b/modules/empikmarketplace/src/Adapter/TranslateAdapter.php @@ -0,0 +1,110 @@ +=')) { + return Translate::getModuleTranslation($module, $originalString, $source, null, false, $iso); + } elseif ($iso === null) { + return Translate::getModuleTranslation($module, $originalString, $source); + } + + static $translations; + static $langCache = []; + static $translationsMerged = []; + + $name = $module instanceof Module ? $module->name : $module; + + if (empty($iso)) { + $iso = Context::getContext()->language->iso_code; + } + + if (!isset($translationsMerged[$name][$iso])) { + $filesByPriority = [ + // PrestaShop 1.5 translations + _PS_MODULE_DIR_ . $name . '/translations/' . $iso . '.php', + // PrestaShop 1.4 translations + _PS_MODULE_DIR_ . $name . '/' . $iso . '.php', + // Translations in theme + _PS_THEME_DIR_ . 'modules/' . $name . '/translations/' . $iso . '.php', + _PS_THEME_DIR_ . 'modules/' . $name . '/' . $iso . '.php', + ]; + + foreach ($filesByPriority as $file) { + if (file_exists($file)) { + $_MODULE = null; + include $file; + + if (isset($_MODULE)) { + $translations[$iso] = isset($translations[$iso]) + ? array_merge($translations[$iso], $_MODULE) + : $_MODULE; + } + } + } + + $translationsMerged[$name][$iso] = true; + } + + $string = preg_replace("/\\\*'/", "\'", $originalString); + $key = md5($string); + + $cacheKey = $name . '|' . $string . '|' . $source . '|' . $iso; + if (!isset($langCache[$cacheKey])) { + if (!isset($translations[$iso])) { + return str_replace('"', '"', $string); + } + + $currentKey = Tools::strtolower('<{' . $name . '}' . _THEME_NAME_ . '>' . $source) . '_' . $key; + $defaultKey = Tools::strtolower('<{' . $name . '}prestashop>' . $source) . '_' . $key; + + if ('controller' == Tools::substr($source, -10, 10)) { + $file = Tools::substr($source, 0, -10); + $currentKeyFile = Tools::strtolower('<{' . $name . '}' . _THEME_NAME_ . '>' . $file) . '_' . $key; + $defaultKeyFile = Tools::strtolower('<{' . $name . '}prestashop>' . $file) . '_' . $key; + } + + if (isset($currentKeyFile) && !empty($translations[$iso][$currentKeyFile])) { + $ret = Tools::stripslashes($translations[$iso][$currentKeyFile]); + } elseif (isset($defaultKeyFile) && !empty($translations[$iso][$defaultKeyFile])) { + $ret = Tools::stripslashes($translations[$iso][$defaultKeyFile]); + } elseif (!empty($translations[$iso][$currentKey])) { + $ret = Tools::stripslashes($translations[$iso][$currentKey]); + } elseif (!empty($translations[$iso][$defaultKey])) { + $ret = Tools::stripslashes($translations[$iso][$defaultKey]); + } else { + $ret = Tools::stripslashes($string); + } + + $langCache[$cacheKey] = htmlspecialchars($ret, ENT_COMPAT, 'UTF-8'); + } + + return $langCache[$cacheKey]; + } +} diff --git a/modules/empikmarketplace/src/Adapter/index.php b/modules/empikmarketplace/src/Adapter/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Adapter/index.php @@ -0,0 +1,11 @@ +cacheEnvironment = Configuration::get(ConfigurationAdapter::CONF_ENVIRONMENT); + $this->cacheNamespace = $cacheNamespace; + + $this->cacheDirectory = new CacheDirectoryProvider( + _PS_VERSION_, + _PS_ROOT_DIR_, + _PS_MODE_DEV_ + ); + } + + public function get($key, callable $callback, $ttl = 3600) + { + $cacheElem = sprintf('%s/%s_%s.tmp', rtrim($this->cacheDirectory->getPath(), '/'), $this->cacheNamespace, md5($key . $this->cacheEnvironment)); + + if (file_exists($cacheElem) && (time() - filemtime($cacheElem)) < $ttl) { + return unserialize(file_get_contents($cacheElem)); + } + + try { + $result = $callback(); + } catch (\Exception $e) { + return false; + } + + file_put_contents($cacheElem, serialize($result)); + + return $result; + } +} diff --git a/modules/empikmarketplace/src/Cache/CacheClearer.php b/modules/empikmarketplace/src/Cache/CacheClearer.php new file mode 100644 index 00000000..734c4f2b --- /dev/null +++ b/modules/empikmarketplace/src/Cache/CacheClearer.php @@ -0,0 +1,44 @@ +module = $module; + + $this->cacheDirectory = new CacheDirectoryProvider( + _PS_VERSION_, + _PS_ROOT_DIR_, + false + ); + } + + public function clear() + { + foreach (self::CONTAINERS as $containerName) { + $containerFilePath = sprintf( + '%s/%s%sContainer.php', + rtrim($this->cacheDirectory->getPath(), '/'), + ucfirst($this->module->name), + ucfirst($containerName) + ); + + if (file_exists($containerFilePath)) { + unlink($containerFilePath); + } + } + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Configuration/ExportConfiguration.php b/modules/empikmarketplace/src/Configuration/ExportConfiguration.php new file mode 100644 index 00000000..55a93132 --- /dev/null +++ b/modules/empikmarketplace/src/Configuration/ExportConfiguration.php @@ -0,0 +1,68 @@ +configurationAdapter = $configurationAdapter; + } + + public function getExportPath() + { + return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME; + } + + public function getProductExportPath() + { + return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME; + } + + public function getOfferExportPath() + { + return self::EXPORT_PATH . self::EXPORT_OFFER_FILENAME; + } + + public function getCsvDelimiter() + { + return self::CSV_FIELD_SEPARATOR; + } + + public function getProductIdType() + { + return $this->configurationAdapter->get('EMPIK_OFFER_IDENTIFIER'); + } + + public function getPriceRatio() + { + return (float)$this->configurationAdapter->get('EMPIK_PRICE_RATIO'); + } + + public function getAddToPrice() + { + return (float)$this->configurationAdapter->get('EMPIK_ADD_TO_PRICE'); + } + + public function getStockReduce() + { + return (float)$this->configurationAdapter->get('EMPIK_REDUCE_STOCK'); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Configuration/ExportProductConfiguration.php b/modules/empikmarketplace/src/Configuration/ExportProductConfiguration.php new file mode 100644 index 00000000..7dfef1cf --- /dev/null +++ b/modules/empikmarketplace/src/Configuration/ExportProductConfiguration.php @@ -0,0 +1,61 @@ +configurationAdapter = $configurationAdapter; + } + + public function getExportPath() + { + return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME; + } + + public function getProductExportPath() + { + return self::EXPORT_PATH . self::EXPORT_PRODUCT_FILENAME; + } + + public function getOfferExportPath() + { + return self::EXPORT_PATH . self::EXPORT_OFFER_FILENAME; + } + + public function getCsvDelimiter() + { + return self::CSV_FIELD_SEPARATOR; + } + + public function getProductIdType() + { + return $this->configurationAdapter->get('EMPIK_OFFER_IDENTIFIER'); + } + + public function getPriceRatio() + { + return (float)$this->configurationAdapter->get('EMPIK_PRICE_RATIO'); + } + + public function getAddToPrice() + { + return (float)$this->configurationAdapter->get('EMPIK_ADD_TO_PRICE'); + } + + public function getStockReduce() + { + return (float)$this->configurationAdapter->get('EMPIK_REDUCE_STOCK'); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Configuration/index.php b/modules/empikmarketplace/src/Configuration/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Configuration/index.php @@ -0,0 +1,11 @@ +db = Db::getInstance(); + $this->context = Context::getContext(); + $this->countryId = Utils::getCountryId(); + } + + public function getCarriers() + { + $sql = new DbQuery(); + $sql->select('c.*'); + $sql->from('carrier', 'c'); + $sql->where('c.deleted = 0'); + + $result = $this->db->executeS($sql); + + return $result; + } +} diff --git a/modules/empikmarketplace/src/DataProvider/CombinationDataProvider.php b/modules/empikmarketplace/src/DataProvider/CombinationDataProvider.php new file mode 100644 index 00000000..260971a9 --- /dev/null +++ b/modules/empikmarketplace/src/DataProvider/CombinationDataProvider.php @@ -0,0 +1,46 @@ +context = Context::getContext(); + } + + public function getCombinationsByProductId($id_product) + { + $product = new Product($id_product); + $combinations = $product->getAttributeCombinations($this->context->language->id); + $combinationsGrouped = []; + foreach ($combinations as $combination) { + if (!isset($combinationsGrouped[$combination['id_product_attribute']])) { + $combinationsGrouped[$combination['id_product_attribute']] = $combination; + } + $combinationsGrouped[$combination['id_product_attribute']]['attributes'][] = sprintf( + '%s: %s', $combination['group_name'], $combination['attribute_name'] + ); + + $empikProduct = \EmpikProduct::getOrCreate($id_product, $combination['id_product_attribute']); + + $combinationsGrouped[$combination['id_product_attribute']]['offer_price'] = $empikProduct->offer_price; + $combinationsGrouped[$combination['id_product_attribute']]['offer_price_reduced'] = $empikProduct->offer_price_reduced; + } + + if (!empty($combinationsGrouped)) { + foreach ($combinationsGrouped as $idProductAttribute => $combination) { + $combinationsGrouped[$idProductAttribute]['attributes_list'] = implode(', ', $combination['attributes']); + } + } + + return $combinationsGrouped; + } +} diff --git a/modules/empikmarketplace/src/DataProvider/OffersDataProvider.php b/modules/empikmarketplace/src/DataProvider/OffersDataProvider.php new file mode 100644 index 00000000..af90a110 --- /dev/null +++ b/modules/empikmarketplace/src/DataProvider/OffersDataProvider.php @@ -0,0 +1,53 @@ +productRepository = $productRepository; + $this->identifierExtractor = $identifierExtractor; + } + + public function getOffersDataByProductIds(array $ids, $updateDeleteMode = 'delete') + { + if (!in_array($updateDeleteMode, ['update', 'delete'])) { + throw new InvalidArgumentException(sprintf('Invalid mode "%s"', $updateDeleteMode)); + } + + $offers = []; + + $products = $this->productRepository->getOffersByIds($ids); + + foreach ($products as $product) { + $offers[] = [ + 'description' => $product['description'], + 'internal_description' => $product['id_product'], + 'price' => $product['price'], + 'product_id' => $this->identifierExtractor->extract($product), + 'product_id_type' => $this->identifierExtractor->getIdentifierType(), + 'shop_sku' => $product['reference'], + 'state_code' => self::STATE_CODE_NEW, + 'update_delete' => $updateDeleteMode, + ]; + } + + return $offers; + } +} diff --git a/modules/empikmarketplace/src/DataProvider/ProductDataProvider.php b/modules/empikmarketplace/src/DataProvider/ProductDataProvider.php new file mode 100644 index 00000000..6fcde864 --- /dev/null +++ b/modules/empikmarketplace/src/DataProvider/ProductDataProvider.php @@ -0,0 +1,98 @@ +db = Db::getInstance(); + $this->shopId = Context::getContext()->shop->id; + $this->langId = Context::getContext()->language->id; + } + + public function getOneBy($params = []) + { + $sql = new DbQuery(); + $sql->select(' + p.id_product, + p.cache_default_attribute AS id_product_attribute, + p.price, + p.wholesale_price, + p.reference, + p.supplier_reference, + p.ean13, + # p.isbn, + # p.mpn, + p.upc, + p.unity, + p.width, + p.height, + p.depth, + p.weight, + p.condition, + p.additional_shipping_cost, + p.available_date, + p.minimal_quantity, + p.active, + pl.name, + pl.description, + pl.description_short, + pl.link_rewrite, + pl.meta_description, + pl.meta_keywords, + pl.meta_title, + pl.available_now, + pl.available_later, + # pl.delivery_in_stock, + # pl.delivery_out_stock, + sav.quantity, + sav.depends_on_stock, + m.name AS manufacturer_name'); + $sql->from('product', 'p'); + $sql->leftJoin( + 'manufacturer', + 'm', + 'm.id_manufacturer = p.id_manufacturer' + ); + $sql->leftJoin( + 'product_lang', + 'pl', + 'pl.id_product = p.id_product AND + pl.id_lang = ' . (int)$this->langId . ' AND + pl.id_shop = ' . (int)$this->shopId + ); + + // stock + $sql->leftJoin( + 'stock_available', + 'sav', + 'sav.id_product = p.id_product AND + sav.id_product_attribute = 0 AND + sav.id_shop = ' . (int)$this->shopId . ' AND + sav.id_shop_group = 0' + ); + + foreach ($params as $param => $value) { + $sql->where(pSQL($param) . ' = ' . '"'.pSQL($value).'"'); + } + + $result = $this->db->getRow($sql); + + return $result; + } +} diff --git a/modules/empikmarketplace/src/DataProvider/index.php b/modules/empikmarketplace/src/DataProvider/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/DataProvider/index.php @@ -0,0 +1,11 @@ + 'empik_action', + 'primary' => 'id_empik_action', + 'fields' => [ + 'id_shop' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isUnsignedInt', + 'required' => true, + ], + 'action' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'status' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'id_import' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isCleanHtml', + ], + 'import_count' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isCleanHtml', + ], + 'date_start' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => true, + ], + 'date_end' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => true, + ], + ], + ]; +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Entity/EmpikActionLog.php b/modules/empikmarketplace/src/Entity/EmpikActionLog.php new file mode 100644 index 00000000..adbb5f9f --- /dev/null +++ b/modules/empikmarketplace/src/Entity/EmpikActionLog.php @@ -0,0 +1,30 @@ + 'empik_action', + 'primary' => 'id_empik_action_log', + 'fields' => [ + 'id_empik_action' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isUnsignedInt', + 'required' => true, + ], + 'message' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'date_add' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => true, + ], + ], + ]; +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Entity/EmpikOrder.php b/modules/empikmarketplace/src/Entity/EmpikOrder.php new file mode 100644 index 00000000..8c3ecf6f --- /dev/null +++ b/modules/empikmarketplace/src/Entity/EmpikOrder.php @@ -0,0 +1,87 @@ + 'empik_orders', + 'primary' => 'id_empik_order', + 'fields' => [ + 'id_order' => [ + 'type' => self::TYPE_INT, + 'validate' => 'isUnsignedInt', + 'required' => true, + ], + 'empik_order_reference' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'empik_order_carrier' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'empik_payment' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + 'required' => true, + ], + 'empik_carrier' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + 'required' => true, + ], + 'empik_pickup_point' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'empik_vat_number' => [ + 'type' => self::TYPE_STRING, + 'validate' => 'isCleanHtml', + ], + 'date_add' => [ + 'type' => self::TYPE_DATE, + 'validate' => 'isDate', + 'required' => false, + ], + ], + ]; + + public static function getEmpikOrderByOrderId($orderId) + { + $query = (new DbQuery()) + ->select('eo.*') + ->from('empik_orders', 'eo') + ->where('eo.id_order = "'.pSQL($orderId).'"'); + + return Db::getInstance()->getRow($query); + } + + public static function getEmpikOrderReferenceByOrderId($orderId) + { + $query = (new DbQuery()) + ->select('eo.empik_order_reference') + ->from('empik_orders', 'eo') + ->where('eo.id_order = "'.pSQL($orderId).'"'); + + return Db::getInstance()->getValue($query); + } + + public static function getOrderIdByEmpikOrderReference($empikOrderReference) + { + $query = (new DbQuery()) + ->select('eo.id_order') + ->from('empik_orders', 'eo') + ->where('eo.empik_order_reference = "'.pSQL($empikOrderReference).'"'); + + return Db::getInstance()->getValue($query); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Exception/InvalidActionException.php b/modules/empikmarketplace/src/Exception/InvalidActionException.php new file mode 100644 index 00000000..dd93d739 --- /dev/null +++ b/modules/empikmarketplace/src/Exception/InvalidActionException.php @@ -0,0 +1,10 @@ +configurationAdapter = $configurationAdapter; + } + + public function createClient() + { + $apiUrl = $this->configurationAdapter->get(ConfigurationAdapter::CONF_ENVIRONMENT); + $apiKey = $this->configurationAdapter->get(ConfigurationAdapter::CONF_API_KEY); + + return new EmpikClient($apiUrl, $apiKey); + } +} diff --git a/modules/empikmarketplace/src/Factory/EmpikCurlHttpClientFactory.php b/modules/empikmarketplace/src/Factory/EmpikCurlHttpClientFactory.php new file mode 100644 index 00000000..d9d4f62d --- /dev/null +++ b/modules/empikmarketplace/src/Factory/EmpikCurlHttpClientFactory.php @@ -0,0 +1,20 @@ + $apiUrl]); + } +} diff --git a/modules/empikmarketplace/src/Factory/EmpikGuzzleHttpClientFactory.php b/modules/empikmarketplace/src/Factory/EmpikGuzzleHttpClientFactory.php new file mode 100644 index 00000000..fbea0ffa --- /dev/null +++ b/modules/empikmarketplace/src/Factory/EmpikGuzzleHttpClientFactory.php @@ -0,0 +1,14 @@ + $apiUrl]); + } +} diff --git a/modules/empikmarketplace/src/Factory/HttpClientFactoryInterface.php b/modules/empikmarketplace/src/Factory/HttpClientFactoryInterface.php new file mode 100644 index 00000000..136518e0 --- /dev/null +++ b/modules/empikmarketplace/src/Factory/HttpClientFactoryInterface.php @@ -0,0 +1,15 @@ +module = $module; + $this->tools = $tools; + $this->exportProductProcessor = $exportProductProcessor; + $this->exportOfferProcessor = $exportOfferProcessor; + $this->orderProcessor = $orderProcessor; + + $this->context = Context::getContext(); + } + + public function handle($action) + { + set_time_limit(0); + + switch ($action) { + case self::ACTION_EXPORT_PRODUCTS: + $this->exportProductProcessor->process(); + break; + case self::ACTION_EXPORT_OFFERS: + $this->exportOfferProcessor->process(); + break; + case self::ACTION_IMPORT_ORDERS: + $this->orderProcessor->process(); + break; + default: + throw new InvalidActionException(); + } + } + + public function getAvailableActionsUrls() + { + $urls = []; + + foreach (self::ACTIONS as $action) { + $urls[$action] = $this->getActionUrl($action); + } + + return $urls; + } + + public function checkToken($token) + { + return $token === $this->getToken(); + } + + protected function getActionUrl($action) + { + return $this->context->link->getModuleLink($this->module->name, 'cron', [ + 'action' => $action, + 'token' => $this->getToken(), + ]); + } + + protected function getToken() + { + return $this->tools->hash($this->module->name . '_cron'); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Handler/ExportOfferHandler.php b/modules/empikmarketplace/src/Handler/ExportOfferHandler.php new file mode 100644 index 00000000..5195afc2 --- /dev/null +++ b/modules/empikmarketplace/src/Handler/ExportOfferHandler.php @@ -0,0 +1,189 @@ +module = $module; + $this->exportConfig = $exportConfig; + $this->productRepository = $productRepository; + $this->featureRepository = $featureRepository; + $this->taxRepository = $taxRepository; + $this->categoryRepository = $categoryRepository; + $this->imageRepository = $imageRepository; + $this->productNameFormatter = $productNameFormatter; + $this->categoryPathBuilder = $categoryPathBuilder; + $this->identifierExtractor = $identifierExtractor; + $this->skuExtractor = $skuExtractor; + $this->offerPriceCalculator = $offerPriceCalculator; + $this->offerQuantityCalculator = $offerQuantityCalculator; + + $this->csvManager = new CsvManager( + $this->exportConfig->getOfferExportPath(), + ExportConfiguration::CSV_FIELD_SEPARATOR + ); + $this->context = Context::getContext(); + } + + public function isLastPage($page) + { + $total = $this->productRepository->getProductsTotal(ProductRepository::SRC_OFFER); + + return $page * ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE > $total; + } + + public function handle($page = null) + { + if (!$page && file_exists($this->exportConfig->getOfferExportPath())) { + $this->csvManager->remove(); + } + + $localPage = $page === null ? 0 : $page; + $leadTimeToShip = \Configuration::get(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP); + $syncLogisticClass = \Configuration::get(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS); + + do { + $products = $this->productRepository->getProductsPaginate( + $localPage, + ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE, + ProductRepository::SRC_OFFER + ); + + foreach ($products as $i => $product) { + $offer = []; + + $priceWithReduction = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2); + $priceWithoutReduction = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2, null, false, false); + + $calculatedPriceWithReduction = $this->offerPriceCalculator->calculate($priceWithReduction); + $calculatedPriceWithoutReduction = $this->offerPriceCalculator->calculate($priceWithoutReduction); + $hasReduction = $calculatedPriceWithoutReduction > $calculatedPriceWithReduction; + + $quantity = \StockAvailable::getQuantityAvailableByProduct($product['id_product'], $product['id_product_attribute']); + + $calculatedQuantity = $this->offerQuantityCalculator->calculate($quantity); + + $offer['product-id-type'] = $this->identifierExtractor->getIdentifierType(); + $offer['product-id'] = $this->identifierExtractor->extract($product); + $offer['sku'] = $this->skuExtractor->extract($product); + $offer['state'] = !empty($product['empik_condition']) ? $product['empik_condition'] : self::STATE_CODE_NEW; + + if ($product['offer_price'] > 0) { + $offer['price'] = $product['offer_price']; + } else { + $offer['price'] = $calculatedPriceWithoutReduction; + } + + if ((int)$product['export_original_price'] > 0) { + if ($product['offer_price_reduced'] > 0) { + $offer['discount-price'] = $product['offer_price_reduced']; + } else { + $offer['discount-price'] = $hasReduction ? $calculatedPriceWithReduction : null; + } + } else { + $offer['discount-price'] = ''; + } + + $offer['quantity'] = $calculatedQuantity; + + if ($leadTimeToShip && $leadTimeToShip >= 0) { + $offer['leadtime-to-ship'] = $leadTimeToShip; + } + + if ($syncLogisticClass) { + $offer['logistic-class'] = $product['logistic_class']; + } + + // add csv header + if ($i === 0 && ($page === 0 || $page === null && $localPage === 0)) { + $this->csvManager->addRow(array_keys($offer)); + } + + $this->csvManager->addRow($offer); + } + + $localPage++; + } while ($products && $page === null); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Handler/ExportProductHandler.php b/modules/empikmarketplace/src/Handler/ExportProductHandler.php new file mode 100644 index 00000000..60d88039 --- /dev/null +++ b/modules/empikmarketplace/src/Handler/ExportProductHandler.php @@ -0,0 +1,259 @@ +module = $module; + $this->exportConfig = $exportConfig; + $this->productRepository = $productRepository; + $this->featureRepository = $featureRepository; + $this->attributeRepository = $attributeRepository; + $this->taxRepository = $taxRepository; + $this->categoryRepository = $categoryRepository; + $this->imageRepository = $imageRepository; + $this->productNameFormatter = $productNameFormatter; + $this->categoryPathBuilder = $categoryPathBuilder; + $this->identifierExtractor = $identifierExtractor; + + $this->csvManager = new CsvManager( + $this->exportConfig->getProductExportPath(), + ExportConfiguration::CSV_FIELD_SEPARATOR + ); + $this->context = Context::getContext(); + } + + public function isLastPage($page) + { + $total = $this->productRepository->getProductsTotal(ProductRepository::SRC_PRODUCT); + + return $page * ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE > $total; + } + + public function handle($page = null) + { + if (!$page && file_exists($this->exportConfig->getProductExportPath())) { + $this->csvManager->remove(); + } + + $localPage = $page === null ? 0 : $page; + + do { + $products = $this->productRepository->getProductsPaginate( + $localPage, + ExportConfiguration::EXPORT_PRODUCTS_PER_PAGE, + ProductRepository::SRC_PRODUCT + ); + + foreach ($products as $i => $product) { + + $product = $this->addName($product); + $product = $this->addPrices($product); + $product = $this->addQuantity($product); + $product = $this->addTax($product); + $product = $this->addCategories($product); + $product = $this->addFeatures($product); + $product = $this->addAttributes($product); + $product = $this->addImages($product); + + // add csv header + if ($i === 0 && ($page === 0 || $page === null && $localPage === 0)) { + $this->csvManager->addRow(array_keys($product)); + } + + $this->csvManager->addRow($product); + } + + $localPage++; + } while ($products && $page === null); + } + + + /** + * @param array $product + * @return array + */ + protected function addName($product) + { + $product['name'] = $this->productNameFormatter->format($product['name']); + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addFeatures($product) + { + $features = $this->featureRepository->getFeatures($product['id_product']); + + foreach ($features as $feature) { + $product[sprintf('feature[%s]', $feature['feature_name'])] = $feature['value']; + } + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addAttributes($product) + { + $features = $this->attributeRepository->getAttributes($product['id_product'], $product['id_product_attribute']); + + foreach ($features as $feature) { + $product[sprintf('attribute[%s]', $feature['name'])] = $feature['value']; + } + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addPrices($product) + { + $product['price'] = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2); + $product['price_without_reduction'] = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2, null, false, false); + $product['reduction'] = Product::getPriceStatic($product['id_product'], true, $product['id_product_attribute'], 2, null, true); + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addQuantity($product) + { + $quantity = StockAvailable::getQuantityAvailableByProduct( + $product['id_product'], + $product['id_product_attribute'] + ); + + $product['quantity'] = (int)$quantity; + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addTax($product) + { + $product['vat'] = $this->taxRepository->getTaxRateByProductId($product['id_product']); + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addCategories($product) + { + $categories = $this->categoryRepository->getCategoriesByProductId($product['id_product']); + + $path = $this->categoryPathBuilder->buildPath($categories); + + $product['category'] = $path; + + return $product; + } + + /** + * @param array $product + * @return array + */ + protected function addImages($product) + { + $images = $this->imageRepository->getImages($product['id_product'], $product['id_product_attribute']); + + for ($i = 0; $i < ExportConfiguration::EXPORT_IMG_LIMIT; $i++) { + $imageUrl = null; + if (isset($images[$i])) { + $imageUrl = $this->context->link->getImageLink( + Tools::link_rewrite($product['link_rewrite'] ? $product['link_rewrite'] : $product['name']), + $images[$i]['id_image'] + ); + } + + $product[sprintf('image_%d', $i + 1)] = isset($imageUrl) ? $imageUrl : null; + } + + return $product; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Handler/UpdateDeleteOfferHandler.php b/modules/empikmarketplace/src/Handler/UpdateDeleteOfferHandler.php new file mode 100644 index 00000000..7877c88c --- /dev/null +++ b/modules/empikmarketplace/src/Handler/UpdateDeleteOfferHandler.php @@ -0,0 +1,55 @@ +empikClientFactory = $empikClientFactory; + $this->productRepository = $productRepository; + $this->offersDataProvider = $offersDataProvider; + + $this->empikClient = $this->empikClientFactory->createClient(); + } + + public function handle(array $ids) + { + try { + $offersData = $this->offersDataProvider->getOffersDataByProductIds($ids); + $this->empikClient->postOffers($offersData); + + return true; + + } catch (Exception $e) { + $this->addError($e->getMessage()); + } + + return false; + } +} + diff --git a/modules/empikmarketplace/src/Handler/index.php b/modules/empikmarketplace/src/Handler/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Handler/index.php @@ -0,0 +1,11 @@ +carrierMapManager = $carrierMapManager; + + $this->module = Module::getInstanceByName('empikmarketplace'); + $this->context = Context::getContext(); + } + + public function hookActionOrderGridDefinitionModifier(array $params) + { + /** @var GridDefinitionInterface $definition */ + $definition = $params['definition']; + + $definition + ->getColumns() + ->addAfter( + 'reference', + (new DataColumn('empik_order_reference')) + ->setName('Empik') + ->setOptions( + [ + 'field' => 'empik_order_reference', + ] + ) + ); + + $definition->getFilters()->add( + (new Filter('empik_order_reference', TextType::class)) + ->setTypeOptions([ + 'required' => false, + ]) + ->setAssociatedColumn('empik_order_reference') + ); + } + + public function hookActionOrderGridQueryBuilderModifier(array $params) + { + /** @var QueryBuilder[] $queryBuilders */ + $queryBuilders = [ + 'search' => $params['search_query_builder'], + 'count' => $params['count_query_builder'], + ]; + + /** @var OrderFilters $searchCriteria */ + $searchCriteria = $params['search_criteria']; + $filters = $searchCriteria->getFilters(); + + foreach ($queryBuilders as $queryBuilder) { + if (isset($filters['empik_order_reference'])) { + $queryBuilder + ->andWhere('empik.empik_order_reference = :empik_order_reference') + ->setParameter('empik_order_reference', $filters['empik_order_reference']); + } + } + + foreach ($queryBuilders as $queryBuilder) { + $queryBuilder + ->addSelect( + 'empik.empik_order_reference' + ) + ->leftJoin( + 'o', + _DB_PREFIX_.'empik_orders', + 'empik', + 'empik.id_order = o.id_order' + ) + ; + } + + /** @var QueryBuilder $searchQueryBuilder */ + $searchQueryBuilder = $params['search_query_builder']; + + if ('empik_order_reference' === $searchCriteria->getOrderBy()) { + $searchQueryBuilder->orderBy('empik.empik_order_reference', $searchCriteria->getOrderWay()); + } + } + + public function hookActionOrderHistoryAddAfter(array $params) + { + /** @var OrderHistory $orderHistory */ + $orderHistory = $params['order_history']; + + $empikOrderId = EmpikOrder::getEmpikOrderReferenceByOrderId($orderHistory->id_order); + + if (!$empikOrderId) { + return; + } + + if ($orderHistory->id_order_state == Configuration::get(ConfigurationAdapter::CONF_SHIPPED_ORDER_STATE)) { + + /** @var LoggerAdapter $logger */ + $logger = $this->module->getService('empik.marketplace.adapter.loggerAdapter'); + + /** @var EmpikClientFactory $empikClientFactory */ + $empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory'); + $empikClient = $empikClientFactory->createClient(); + + try { + $empikClient->putOrderShip($empikOrderId); + } catch (Exception $e) { + $logger->logError($e->getMessage()); + } + } + } + + public function hookActionAdminOrdersListingFieldsModifier($params) + { + if (isset($params['select'])) { + + if (strpos('a.reference', $params['select']) === false) { + $params['select'] .= ',a.reference'; + } + + $params['select'] .= ',eo.empik_order_reference'; + $params['join'] .= ' LEFT JOIN `'._DB_PREFIX_.'empik_orders` eo ON (eo.`id_order` = a.`id_order`)'; + } + + $params['fields']['empik_order_reference'] = [ + 'title' => $this->module->l('Empik'), + 'align' => 'center', + ]; + } + + public function hookDisplayAdminOrder($params) + { + $empikOrder = EmpikOrder::getEmpikOrderByOrderId($params['id_order']); + + if (!$empikOrder) { + return null; + } + + $this->context->smarty->assign( + [ + 'empik_order' => $empikOrder, + ] + ); + + return $this->context->smarty->fetch( + $this->module->getLocalPath().'/views/templates/admin/hook/admin_order.tpl' + ); + } + + public function hookActionAdminOrdersTrackingNumberUpdate(array $params) + { + /** @var Order $order */ + $order = $params['order']; + + /** @var Carrier $carrier */ + $carrier = $params['carrier']; + + $trackingNumber = isset($_POST['update_order_shipping']['tracking_number']) + ? $_POST['update_order_shipping']['tracking_number'] + : $order->shipping_number + ; + + if ($trackingNumber) { + + $empikOrder = EmpikOrder::getEmpikOrderByOrderId($order->id); + + if (!$empikOrder) { + return; + } + + /** @var EmpikClientFactory $empikClientFactory */ + $empikClientFactory = $this->module->getService('empik.marketplace.factory.empikClientFactory'); + $empikClient = $empikClientFactory->createClient(); + + /** @var LoggerAdapter $logger */ + $logger = $this->module->getService('empik.marketplace.adapter.loggerAdapter'); + + $carrierName = null; + $carrierUrl = null; + + $carrierCode = $this->carrierMapManager->getTypeByCode($empikOrder['empik_order_carrier']); + if (!$carrierCode) { + $carrierName = $carrier->name; + $carrierUrl = str_replace('@', $trackingNumber, $carrier->url); + } + + try { + $empikClient->putOrderTracking( + $empikOrder['empik_order_reference'], + $carrierCode, + $carrierName, + $carrierUrl, + $trackingNumber + ); + } catch (Exception $e) { + $logger->logError($e->getMessage()); + } + } + } + + public function hookActionObjectProductDeleteBefore($params) + { + /** @var Product $product */ + $product = $params['object']; + + if (!$this->module->getAuthStatus()) { + return; + } + + /** @var UpdateDeleteOfferHandler $handler */ + $handler = $this->module->getService('empik.marketplace.handler.updateDeleteOfferHandler'); + + /** @var LoggerAdapter $logger */ + $logger = $this->module->getService('empik.marketplace.adapter.loggerAdapter'); + + if (!$handler->handle([$product->id])) { + foreach ($handler->getErrors() as $error) { + $logger->logError($error); + } + } + } + + public function hookActionAdminControllerSetMedia($params) + { + $this->context->controller->addCSS($this->module->getPathUri() . '/views/css/admin/empik.css'); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Hook/index.php b/modules/empikmarketplace/src/Hook/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Hook/index.php @@ -0,0 +1,11 @@ +prestaShopContext = $prestaShopContext; + + $this->db = Db::getInstance(); + $this->module = Module::getInstanceByName('empikmarketplace'); + } + + public function install() + { + $result = true; + + $result &= $this->createTabs(); + $result &= $this->crateTables(); + $result &= $this->registerHooks(); + $result &= $this->createConfig(); + + return (bool)$result; + } + + public function createTabs() + { + $result = true; + + foreach ($this->module->getAdminTabs() as $tab) { + $result &= $this->installTab( + $tab['className'], + $tab['parent'], + $tab['name'], + $tab['module'], + $tab['active'], + $tab['icon'] + ); + } + + return $result; + } + + public function crateTables() + { + try { + include __DIR__ . '/Sql/install.php'; + } catch (Exception $e) { + $this->errors[] = $this->module->l('Failed to install database tables'); + + return false; + } + + return true; + } + + public function registerHooks() + { + $module = $this->module; + $hooksCommon = $module::HOOK_LIST_COMMON; + $hooks17 = $module::HOOK_LIST_17; + $hooks16 = $module::HOOK_LIST_16; + + if ($this->prestaShopContext->is177()) { + $hooks = array_merge($hooksCommon, $hooks17); + } else { + $hooks = array_merge($hooksCommon, $hooks16); + } + + return $this->module->registerHook( + $hooks + ); + } + + public function createConfig() + { + $result = true; + + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP, -1); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_PRICE_RATIO, 1); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_ADD_TO_PRICE, 0); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS, 0); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_REDUCE_STOCK, 0); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_OFFER_IDENTIFIER, 'EAN'); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SKU_TYPE, 'REFERENCE'); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_ID_EMPLOYEE, (int)Context::getContext()->employee->id); + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_ENVIRONMENT, ConfigurationAdapter::ENV_TEST); + + return $result; + } + + protected function installTab($className, $parent, $name, $module, $active, $icon) + { + if (Tab::getIdFromClassName($className)) { + return true; + } + + $parentId = is_int($parent) ? $parent : Tab::getIdFromClassName($parent); + + $moduleTab = new Tab(); + $moduleTab->class_name = $className; + $moduleTab->id_parent = $parentId; + $moduleTab->module = $module; + $moduleTab->active = $active; + if (property_exists($moduleTab, 'icon')) { + $moduleTab->icon = $icon; + } + + $languages = Language::getLanguages(true); + foreach ($languages as $language) { + $moduleTab->name[$language['id_lang']] = $name; + } + + return (bool)$moduleTab->add(); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Install/Sql/index.php b/modules/empikmarketplace/src/Install/Sql/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Install/Sql/index.php @@ -0,0 +1,11 @@ +execute($query) == false) { + return false; + } +} + +return true; diff --git a/modules/empikmarketplace/src/Install/Sql/uninstall.php b/modules/empikmarketplace/src/Install/Sql/uninstall.php new file mode 100644 index 00000000..cd2ac59e --- /dev/null +++ b/modules/empikmarketplace/src/Install/Sql/uninstall.php @@ -0,0 +1,16 @@ +execute($query) == false) { + return false; + } +} + +return true; diff --git a/modules/empikmarketplace/src/Install/Uninstaller.php b/modules/empikmarketplace/src/Install/Uninstaller.php new file mode 100644 index 00000000..e4bd976f --- /dev/null +++ b/modules/empikmarketplace/src/Install/Uninstaller.php @@ -0,0 +1,95 @@ +db = \Db::getInstance(); + $this->module = \Module::getInstanceByName('empikmarketplace'); + } + + public function uninstall() + { + $result = true; + + $result &= $this->dropTabs(); + $result &= $this->dropTables(); + $result &= $this->dropConfig(); + + return $result; + } + + public function dropTabs() + { + $result = true; + + /** @var Tab $tab */ + foreach (Tab::getCollectionFromModule($this->module->name) as $tab) { + $result &= (bool)$tab->delete(); + } + + return $result; + } + + public function dropTables() + { + try { + include __DIR__ . '/Sql/uninstall.php'; + } catch (Exception $e) { + $this->errors[] = $this->module->l('Failed to uninstall database tables'); + + return false; + } + + return true; + } + + public function dropConfig() + { + $result = true; + + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_ENVIRONMENT); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_API_KEY); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_AUTH_STATUS); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_SYNC_OFFERS); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_SYNC_LOGISTIC_CLASS); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_OFFER_IDENTIFIER); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_LEAD_TIME_TO_SHIP); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_PRICE_RATIO); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_ADD_TO_PRICE); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_REDUCE_STOCK); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_IMPORT_ORDERS); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_AUTO_ACCEPT_ORDERS); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_NEW_ORDER_STATE); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_SHIPPED_ORDER_STATE); + $result &= Configuration::deleteByName(ConfigurationAdapter::CONF_CARRIER_MAP); + + return $result; + } + + protected function uninstallTab($className) + { + $tab = new Tab(Tab::getIdFromClassName($className)); + + return (bool)$tab->delete(); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Install/index.php b/modules/empikmarketplace/src/Install/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Install/index.php @@ -0,0 +1,11 @@ +configurationAdapter = $configurationAdapter; + + $this->loadFromConfig(); + } + + /** + * @return array|mixed + */ + public function loadFromConfig() + { + $jsonString = $this->configurationAdapter->get(ConfigurationAdapter::CONF_CARRIER_MAP); + + if ($jsonString) { + $this->map = json_decode($jsonString, true); + } + + return $this->map; + } + + /** + * @param $map + * @return bool + */ + public function setMap($map) + { + if ($this->validate($map)) { + $this->map = $map; + return true; + } + + return false; + } + + /** + * @param $map + * @return bool + */ + public function store($map) + { + if ($this->validate($map)) { + return $this->configurationAdapter->updateValue( + ConfigurationAdapter::CONF_CARRIER_MAP, + json_encode($map) + ); + } + + return true; + } + + /** + * @param $code + * @return mixed + */ + public function getTypeByCode($code) + { + foreach ($this->map as $carrierCode => $carrier) { + if ($carrierCode === $code) { + return $carrier['type']; + } + } + + return false; + } + + /** + * @param $code + * @return mixed + */ + public function getIdByCode($code) + { + foreach ($this->map as $carrierCode => $carrier) { + if ($carrierCode === $code) { + return $carrier['id_carrier']; + } + } + + return false; + } + + /** + * @param $map + * @return bool + */ + protected function validate($map) + { + if (!is_array($map)) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Manager/CsvManager.php b/modules/empikmarketplace/src/Manager/CsvManager.php new file mode 100644 index 00000000..27025521 --- /dev/null +++ b/modules/empikmarketplace/src/Manager/CsvManager.php @@ -0,0 +1,52 @@ +csvPath = $csvPath; + $this->delimiter = $delimiter; + } + + function __destruct() + { + if ($this->fileHandle) { + fclose($this->fileHandle); + } + } + + public function remove() + { + if (file_exists($this->csvPath)) { + return unlink($this->csvPath); + } + + return true; + } + + public function addRow(array $row) + { + if (!$this->fileHandle) { + $this->fileHandle = fopen($this->csvPath, 'a'); + } + + if (!$row) { + throw new InvalidArgumentException('Invalid CSV row'); + } + + return fputcsv($this->fileHandle, $row, $this->delimiter); + } +} diff --git a/modules/empikmarketplace/src/Manager/OrderManager.php b/modules/empikmarketplace/src/Manager/OrderManager.php new file mode 100644 index 00000000..b2cbdb93 --- /dev/null +++ b/modules/empikmarketplace/src/Manager/OrderManager.php @@ -0,0 +1,8 @@ +processModel = new EmpikAction(); + $this->processModel->id_shop = Context::getContext()->shop->id; + } + + public function start($action = null) + { + if ($action) { + $this->processModel->action = $action; + } + + $this->setDateStart(); + $this->setDateEnd(); + } + + public function end() + { + $this->setDateEnd(); + $this->processModel->save(); + } + + public function setStatus($status) + { + $this->processModel->status = $status; + $this->processModel->save(); + } + + protected function setDateStart() + { + $time = new DateTime(); + $this->processModel->date_start = $time->format('Y-m-d H:i:s'); + } + + protected function setDateEnd() + { + $time = new DateTime(); + $this->processModel->date_end = $time->format('Y-m-d H:i:s'); + } + + public function updateFromResponse(array $response) + { + if (isset($response['import_id'])) { + $this->processModel->id_import = (int)$response['import_id']; + } + + $this->processModel->save(); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Manager/index.php b/modules/empikmarketplace/src/Manager/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Manager/index.php @@ -0,0 +1,11 @@ +setData($data); + $this->setOrder($order); + + $this->productDataProvider = new ProductDataProvider(); + } + + /** + * @return bool + */ + public function exist() + { + $data = $this->getData(); + + return (bool)\EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']); + } + + /** + * @return bool + */ + public function isAcceptable() + { + foreach ($this->getAcceptanceLines() as $orderLine) { + if (!$orderLine['accepted']) { + return false; + } + } + + return true; + } + + /** + * @return array + */ + public function getAcceptanceLines() + { + $return = []; + + foreach ($this->getData()['order_lines'] as $orderLine) { + $pr = $this->productDataProvider->getOneBy([ + 'p.reference' => $orderLine['offer_sku'] // @todo + ]); + + $return[] = [ + 'id' => (string)$orderLine['order_line_id'], + 'accepted' => $pr && $pr['active'] && $pr['quantity'] >= $orderLine['quantity'], + ]; + } + + return $return; + } + + public function add() + { + $context = \Context::getContext(); + + if ($this->customer && !$this->customer->id) { + $this->customer->id_shop = $context->shop->id; + $this->customer->id_shop_group = $context->shop->id_shop_group; + $this->customer->add(); + } + + if ($this->shippingAddress && !$this->shippingAddress->id) { + $this->shippingAddress->id_customer = $this->customer->id; + $this->shippingAddress->add(); + } + + if ($this->billingAddress && !$this->billingAddress->id) { + $this->shippingAddress->id_customer = $this->customer->id; + $this->billingAddress->add(); + } + + $this->cart->id_customer = $this->customer->id; + // $this->cart->add(); + + $this->order->id_address_delivery = $this->shippingAddress->id; + $this->order->id_address_invoice = $this->billingAddress->id; + + $this->order->id_cart = $this->cart->id; + $this->order->id_currency = $context->currency->id; + $this->order->id_lang = $context->language->id; + + $this->order->id_shop = $context->shop->id; + $this->order->id_shop_group = $context->shop->id_shop_group; + + $this->order->id_customer = $this->customer->id; + $this->order->id_carrier = $this->carrier->id_carrier; + + $this->order->payment = $this->data['payment_type']; + $this->order->module = 'empikmarketplace'; + + $this->order->total_paid = (float)$this->data['total_price']; + $this->order->total_paid_tax_incl = (float)$this->data['total_price']; + $this->order->total_paid_tax_excl = (float)$this->data['total_price']; + + $this->order->total_paid_real = (float)$this->data['total_price']; + + $this->order->total_products = (float)$this->data['price']; + $this->order->total_products_wt = (float)$this->data['price']; + + $this->order->total_shipping = (float)$this->data['shipping_price']; + $this->order->total_shipping_tax_incl = (float)$this->data['shipping_price']; + $this->order->total_shipping_tax_excl = (float)$this->data['shipping_price']; + + $this->order->conversion_rate = 1; + + $this->order->secure_key = $this->customer->secure_key; + + do { + $this->order->reference = Order::generateReference(); + } while (Order::getByReference($this->order->reference)->count()); + + if ($this->orderHistory) { + $this->order->current_state = end($this->orderHistory)->id_order_state; + } + +// foreach ($this->notes as $note) { +// $this->order->note .= !$this->order->note ? $note : "\r\n\r\n" . $note; +// } + + // create order + $this->order->add(); + + // add message (ps 1.6) +// if ($this->order->note && !ToolsAdapter::is17static()) { +// $msg = new \Message(); +// $msg->message = $this->order->note; +// $msg->id_cart = $this->cart->id; +// $msg->id_customer = $this->customer->id; +// $msg->id_order = $this->order->id; +// $msg->private = 1; +// $msg->add(); +// } + + // add order carrier + $this->carrier->id_order = $this->order->id; + $this->carrier->shipping_cost_tax_excl = $this->order->total_shipping_tax_excl; + $this->carrier->shipping_cost_tax_incl = $this->order->total_shipping_tax_incl; + $this->carrier->add(); + + foreach ($this->orderDetails as $orderDetail) { + $orderDetail->id_order = $this->order->id; + $orderDetail->add(); + } + + foreach ($this->orderHistory as $history) { + $history->id_order = $this->order->id; + $history->add(); + } + + // @todo + $empikOrder = new \EmpikOrder(); + $empikOrder->id_order = $this->order->id; + $empikOrder->empik_order_reference = $this->data['order_id']; + $empikOrder->empik_order_carrier = $this->data['shipping_type_code']; + $empikOrder->empik_payment = $this->data['payment_type']; + $empikOrder->empik_carrier = $this->data['shipping_type_label']; + + foreach ($this->data['order_additional_fields'] as $additionalField) { + if ($additionalField['code'] === 'delivery-point-name') { + $empikOrder->empik_pickup_point = $additionalField['value']; + } + if ($additionalField['code'] === 'nip') { + $empikOrder->empik_vat_number = $additionalField['value']; + } + } + + $empikOrder->add(); + } + + /** + * @return Cart + */ + public function getCart() + { + return $this->cart; + } + + /** + * @param Cart $cart + */ + public function setCart($cart) + { + $this->cart = $cart; + } + + /** + * @return OrderHistory[] + */ + public function getOrderHistory() + { + return $this->orderHistory; + } + + /** + * @param OrderHistory[] $orderHistory + */ + public function setOrderHistory($orderHistory) + { + $this->orderHistory = $orderHistory; + } + + /** + * @return OrderCarrier + */ + public function getCarrier() + { + return $this->carrier; + } + + /** + * @param OrderCarrier $carrier + */ + public function setCarrier($carrier) + { + $this->carrier = $carrier; + } + + /** + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * @param array $data + */ + public function setData($data) + { + $this->data = $data; + } + + /** + * @return Order + */ + public function getOrder() + { + return $this->order; + } + + /** + * @param Order $order + */ + public function setOrder($order) + { + $this->order = $order; + } + + /** + * @return OrderDetail[] + */ + public function getOrderDetails() + { + return $this->orderDetails; + } + + /** + * @param OrderDetail[] $orderDetails + */ + public function setOrderDetails($orderDetails) + { + $this->orderDetails = $orderDetails; + } + + /** + * @return Customer + */ + public function getCustomer() + { + return $this->customer; + } + + /** + * @param Customer $customer + */ + public function setCustomer($customer) + { + $this->customer = $customer; + } + + /** + * @return Address + */ + public function getShippingAddress() + { + return $this->shippingAddress; + } + + /** + * @param Address $shippingAddress + */ + public function setShippingAddress($shippingAddress) + { + $this->shippingAddress = $shippingAddress; + } + + /** + * @return Address + */ + public function getBillingAddress() + { + return $this->billingAddress; + } + + /** + * @param Address $billingAddress + */ + public function setBillingAddress($billingAddress) + { + $this->billingAddress = $billingAddress; + } + + /** + * @return array + */ + public function getNotes(): array + { + return $this->notes; + } + + /** + * @param array $notes + */ + public function setNotes(array $notes): void + { + $this->notes = $notes; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/OrderFulfiller/EmpikOrderWrapper.php b/modules/empikmarketplace/src/OrderFulfiller/EmpikOrderWrapper.php new file mode 100644 index 00000000..d7888918 --- /dev/null +++ b/modules/empikmarketplace/src/OrderFulfiller/EmpikOrderWrapper.php @@ -0,0 +1,394 @@ +productDataProvider = new ProductDataProvider(); + $this->productRepository = new ProductRepository( + new PrestaShopContext() + ); + $this->identifierExtractor = new IdentifierExtractor(); + } + + public function init($data) + { + $id = EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']); + $order = new Order($id); + + $this->setData($data); + $this->setOrder($order); + } + + /** + * @return bool + */ + public function exist() + { + $data = $this->getData(); + + return (bool)\EmpikOrder::getOrderIdByEmpikOrderReference($data['order_id']); + } + + /** + * @return bool + */ + public function isAcceptable() + { + foreach ($this->getAcceptanceLines() as $orderLine) { + if (!$orderLine['accepted']) { + return false; + } + } + + return true; + } + + /** + * @return array + */ + public function getAcceptanceLines() + { + $skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE); + + $return = []; + + foreach ($this->getData()['order_lines'] as $orderLine) { + + if ($skuType === 'ID') { + $product = $this->productRepository->getProductOrCombinationById($orderLine['offer_sku']); + } elseif ($skuType === 'EAN') { + $product = $this->productRepository->getProductOrCombinationByEan($orderLine['offer_sku']); + } elseif ($skuType === 'REFERENCE') { + $product = $this->productRepository->getProductOrCombinationBySku($orderLine['offer_sku']); + } + + $return[] = [ + 'id' => (string)$orderLine['order_line_id'], + 'accepted' => $product && $product['active'] && $product['quantity'] >= $orderLine['quantity'], + ]; + } + + return $return; + } + + public function add() + { + $context = \Context::getContext(); + + if ($this->customer && !$this->customer->id) { + $this->customer->id_shop = $context->shop->id; + $this->customer->id_shop_group = $context->shop->id_shop_group; + $this->customer->add(); + } + + if ($this->shippingAddress && !$this->shippingAddress->id) { + $this->shippingAddress->id_customer = $this->customer->id; + $this->shippingAddress->add(); + } + + if ($this->billingAddress && !$this->billingAddress->id) { + $this->billingAddress->id_customer = $this->customer->id; + $this->billingAddress->add(); + } + + $this->cart->id_customer = $this->customer->id; + $this->cart->id_address_delivery = $this->shippingAddress->id; + $this->cart->id_address_invoice = $this->billingAddress->id; + $this->cart->update(); + + $this->order->id_address_delivery = $this->shippingAddress->id; + $this->order->id_address_invoice = $this->billingAddress->id; + + $this->order->id_cart = $this->cart->id; + $this->order->id_currency = $context->currency->id; + $this->order->id_lang = $context->language->id; + + $this->order->id_shop = $context->shop->id; + $this->order->id_shop_group = $context->shop->id_shop_group; + + $this->order->id_customer = $this->customer->id; + $this->order->id_carrier = $this->carrier->id_carrier; + + $this->order->payment = $this->data['payment_type']; + $this->order->module = 'empikmarketplace'; + + $this->order->total_paid = (float)$this->data['total_price']; + $this->order->total_paid_tax_incl = (float)$this->data['total_price']; + $this->order->total_paid_tax_excl = (float)$this->data['total_price']; + + $this->order->total_paid_real = (float)$this->data['total_price']; + + $this->order->total_products = (float)$this->data['price']; + $this->order->total_products_wt = (float)$this->data['price']; + + $this->order->total_shipping = (float)$this->data['shipping_price']; + $this->order->total_shipping_tax_incl = (float)$this->data['shipping_price']; + $this->order->total_shipping_tax_excl = (float)$this->data['shipping_price']; + + $this->order->conversion_rate = 1; + + $this->order->secure_key = $this->customer->secure_key; + + do { + $this->order->reference = Order::generateReference(); + } while (Order::getByReference($this->order->reference)->count()); + + if ($this->orderHistory) { + $this->order->current_state = end($this->orderHistory)->id_order_state; + } + + // create order + $this->order->add(); + + // add order carrier + $this->carrier->id_order = $this->order->id; + $this->carrier->shipping_cost_tax_excl = $this->order->total_shipping_tax_excl; + $this->carrier->shipping_cost_tax_incl = $this->order->total_shipping_tax_incl; + $this->carrier->add(); + + foreach ($this->orderDetails as $orderDetail) { + $orderDetail->id_order = $this->order->id; + $orderDetail->add(); + + if ($this->order->current_state != Configuration::get('PS_OS_CANCELED') + && $this->order->current_state != Configuration::get('PS_OS_ERROR')) { + if (!StockAvailable::dependsOnStock($orderDetail->product_id)) { + StockAvailable::updateQuantity( + $orderDetail->product_id, + $orderDetail->product_attribute_id, + -(int) $orderDetail->product_quantity, + $orderDetail->id_shop, + true + ); + } + } + } + + foreach ($this->orderHistory as $history) { + $history->id_order = $this->order->id; + $history->add(); + } + + $this->createEmpikOrder(); + } + + public function createEmpikOrder() + { + $empikOrder = new EmpikOrder(); + $empikOrder->id_order = $this->order->id; + $empikOrder->empik_order_reference = $this->data['order_id']; + $empikOrder->empik_order_carrier = $this->data['shipping_type_code']; + $empikOrder->empik_payment = $this->data['payment_type']; + $empikOrder->empik_carrier = $this->data['shipping_type_label']; + + foreach ($this->data['order_additional_fields'] as $additionalField) { + if ($additionalField['code'] === 'delivery-point-name') { + $empikOrder->empik_pickup_point = $additionalField['value']; + } + if ($additionalField['code'] === 'nip') { + $empikOrder->empik_vat_number = $additionalField['value']; + } + } + + $empikOrder->add(); + } + + /** + * @return Cart + */ + public function getCart() + { + return $this->cart; + } + + /** + * @param Cart $cart + */ + public function setCart($cart) + { + $this->cart = $cart; + } + + /** + * @return OrderHistory[] + */ + public function getOrderHistory() + { + return $this->orderHistory; + } + + /** + * @param OrderHistory[] $orderHistory + */ + public function setOrderHistory($orderHistory) + { + $this->orderHistory = $orderHistory; + } + + /** + * @return OrderCarrier + */ + public function getCarrier() + { + return $this->carrier; + } + + /** + * @param OrderCarrier $carrier + */ + public function setCarrier($carrier) + { + $this->carrier = $carrier; + } + + /** + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * @param array $data + */ + public function setData($data) + { + $this->data = $data; + } + + /** + * @return Order + */ + public function getOrder() + { + return $this->order; + } + + /** + * @param Order $order + */ + public function setOrder($order) + { + $this->order = $order; + } + + /** + * @return OrderDetail[] + */ + public function getOrderDetails() + { + return $this->orderDetails; + } + + /** + * @param OrderDetail[] $orderDetails + */ + public function setOrderDetails($orderDetails) + { + $this->orderDetails = $orderDetails; + } + + /** + * @return Customer + */ + public function getCustomer() + { + return $this->customer; + } + + /** + * @param Customer $customer + */ + public function setCustomer($customer) + { + $this->customer = $customer; + } + + /** + * @return Address + */ + public function getShippingAddress() + { + return $this->shippingAddress; + } + + /** + * @param Address $shippingAddress + */ + public function setShippingAddress($shippingAddress) + { + $this->shippingAddress = $shippingAddress; + } + + /** + * @return Address + */ + public function getBillingAddress() + { + return $this->billingAddress; + } + + /** + * @param Address $billingAddress + */ + public function setBillingAddress($billingAddress) + { + $this->billingAddress = $billingAddress; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/OrderFulfiller/OrderFulfiller.php b/modules/empikmarketplace/src/OrderFulfiller/OrderFulfiller.php new file mode 100644 index 00000000..5d1aff83 --- /dev/null +++ b/modules/empikmarketplace/src/OrderFulfiller/OrderFulfiller.php @@ -0,0 +1,122 @@ +addressProvider = $addressProvider; + $this->customerProvider = $customerProvider; + $this->orderLinesProvider = $orderLinesProvider; + $this->carrierProvider = $carrierProvider; + $this->historyProvider = $historyProvider; + $this->cartProvider = $cartProvider; + } + + /** + * @param EmpikOrderWrapper $order + * @throws OrderProcessException + * @throws \PrestaShopDatabaseException + * @throws \PrestaShopException + */ + public function fulfill(EmpikOrderWrapper $order) + { + $data = $order->getData(); + + $this->validate($data); + + // add customer + $prestaShopCustomer = $this->customerProvider->provide($data); + $order->setCustomer($prestaShopCustomer); + + // add addresses + $billingAddress = isset($data['customer']['billing_address']) ? $data['customer']['billing_address'] : null; + $shippingAddress = isset($data['customer']['shipping_address']) ? $data['customer']['shipping_address'] : null; + $additionalFields = isset($data['order_additional_fields']) ? $data['order_additional_fields'] : []; + + $prestaShopShippingAddress = $this->addressProvider->provide( + $shippingAddress, + $order->getCustomer() + ); + $order->setShippingAddress($prestaShopShippingAddress); + + $prestaShopBillingAddress = $this->addressProvider->provide( + $billingAddress, + $order->getCustomer(), + $additionalFields + ); + $order->setBillingAddress($prestaShopBillingAddress); + + // add cart + $cart = $this->cartProvider->provide($data); + $order->setCart($cart); + + // add order lines + $orderLines = $this->orderLinesProvider->provide($data); + $order->setOrderDetails($orderLines); + + // add carrier + $carrier = $this->carrierProvider->provide($data); + $order->setCarrier($carrier); + + // add order status + $history = $this->historyProvider->provide($data); + $order->setOrderHistory($history); + + $order->add(); + } + + /** + * @param array $data + * @throws OrderProcessException + */ + protected function validate($data) + { + if ( + ( + empty($data['customer']['shipping_address']) && + empty($data['customer']['billing_address']) + ) || + empty($data['order_id']) || + empty($data['order_lines']) || + empty($data['order_state']) || + empty($data['total_price']) + ) { + throw new OrderProcessException(sprintf('Invalid order data for order: %s', $data['order_id'])); + } + } +} diff --git a/modules/empikmarketplace/src/OrderFulfiller/index.php b/modules/empikmarketplace/src/OrderFulfiller/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/OrderFulfiller/index.php @@ -0,0 +1,11 @@ +='); + } + + public function is177() + { + return version_compare(_PS_VERSION_, '1.7.7', '>='); + } +} diff --git a/modules/empikmarketplace/src/Processor/ExportOfferProcessor.php b/modules/empikmarketplace/src/Processor/ExportOfferProcessor.php new file mode 100644 index 00000000..9328e3cf --- /dev/null +++ b/modules/empikmarketplace/src/Processor/ExportOfferProcessor.php @@ -0,0 +1,80 @@ +processManager = $processManager; + $this->empikClientFactory = $empikClientFactory; + $this->exportOfferHandler = $exportOfferHandler; + $this->exportConfiguration = $exportConfiguration; + + $this->empikClient = $this->empikClientFactory->createClient(); + } + + public function setPage($page) + { + $this->page = $page; + } + + public function process() + { + try { + $this->processManager->start(\EmpikAction::ACTION_OFFER_EXPORT); + + // create CSV + $this->exportOfferHandler->handle( + $this->page + ); + + // post CSV + if ($this->isLastPage()) { + $response = $this->empikClient->postOffersImports( + $this->exportConfiguration->getOfferExportPath() + ); + $this->processManager->updateFromResponse($response); + $this->processManager->end(); + } + } catch (Exception $e) { + $this->addError($e->getMessage()); + } + } + + public function isLastPage() + { + return $this->page === null || $this->exportOfferHandler->isLastPage($this->page); + } +} diff --git a/modules/empikmarketplace/src/Processor/ExportProductProcessor.php b/modules/empikmarketplace/src/Processor/ExportProductProcessor.php new file mode 100644 index 00000000..3402ea10 --- /dev/null +++ b/modules/empikmarketplace/src/Processor/ExportProductProcessor.php @@ -0,0 +1,81 @@ +processManager = $processManager; + $this->empikClientFactory = $empikClientFactory; + $this->exportProductHandler = $exportProductHandler; + $this->exportConfiguration = $exportConfiguration; + + $this->empikClient = $this->empikClientFactory->createClient(); + } + + public function setPage($page) + { + $this->page = $page; + } + + public function process() + { + try { + $this->processManager->start(\EmpikAction::ACTION_PRODUCT_EXPORT); + + // create CSV + $this->exportProductHandler->handle( + $this->page + ); + + // post CSV + if ($this->isLastPage()) { + $response = $this->empikClient->postProducts( + $this->exportConfiguration->getProductExportPath() + ); + + $this->processManager->updateFromResponse($response); + $this->processManager->end(); + } + } catch (Exception $e) { + $this->addError($e->getMessage()); + } + } + + public function isLastPage() + { + return $this->page === null || $this->exportProductHandler->isLastPage($this->page); + } +} diff --git a/modules/empikmarketplace/src/Processor/OrderProcessor.php b/modules/empikmarketplace/src/Processor/OrderProcessor.php new file mode 100644 index 00000000..d350336c --- /dev/null +++ b/modules/empikmarketplace/src/Processor/OrderProcessor.php @@ -0,0 +1,129 @@ +processManager = $processManager; + $this->empikClientFactory = $empikClientFactory; + $this->orderFulfiller = $orderFulfiller; + $this->logger = $loggerAdapter; + + $this->empikClient = $this->empikClientFactory->createClient(); + + $this->allowAccept = (bool)Configuration::get(ConfigurationAdapter::CONF_AUTO_ACCEPT_ORDERS); + $this->allowImport = (bool)Configuration::get(ConfigurationAdapter::CONF_IMPORT_ORDERS); + } + + public function process() + { + if (!$this->allowAccept && !$this->allowImport) { + return; + } + + $response = $this->empikClient->getOrders([ + 'order_state_codes' => implode(',', $this->getOrderCodesForProcess()), + ]); + + foreach ($response['orders'] as $order) { + + $empikOrder = new EmpikOrderWrapper(); + $empikOrder->init($order); + + if ($this->allowAccept && $empikOrder->isAcceptable() && !$empikOrder->exist()) { + $this->accept($empikOrder); + } + + if ($this->allowImport) { + if (!$empikOrder->exist()) { + $this->import($empikOrder); + } + } + } + } + + protected function import(EmpikOrderWrapper $empikOrder) + { + try { + Db::getInstance()->execute('START TRANSACTION'); + $this->orderFulfiller->fulfill($empikOrder); + Db::getInstance()->execute('COMMIT'); + } catch (Exception $e) { + Db::getInstance()->execute('ROLLBACK'); + $this->logger->logError(sprintf('Error importing order [%s]', $e->getMessage())); + } + } + + protected function accept(EmpikOrderWrapper $empikOrder) + { + $acceptLines = $empikOrder->getAcceptanceLines(); + + try { + $this->empikClient->putOrderAccept( + $empikOrder->getData()['order_id'], + $acceptLines + ); + } catch (ClientException $e) { + $responseJson = $e->getResponse()->json(); + $message = isset($responseJson['message']) ? $responseJson['message'] : null; + $this->logger->logError(sprintf('Error accepting order [%s]', $message)); + + } catch (Exception $e) { + $this->logger->logError(sprintf('Error accepting order [%s]', $e->getMessage())); + } + } + + protected function getOrderCodesForProcess() + { + $codes = []; + + if ($this->allowAccept) { + $codes[] = self::CODE_WAITING_ACCEPTANCE; + } + + if ($this->allowImport) { + $codes[] = self::CODE_SHIPPING; + } + + return $codes; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Processor/OrdersProcessor.php b/modules/empikmarketplace/src/Processor/OrdersProcessor.php new file mode 100644 index 00000000..e7d41850 --- /dev/null +++ b/modules/empikmarketplace/src/Processor/OrdersProcessor.php @@ -0,0 +1,42 @@ +orderRepository = $orderRepository; + $this->orderManager = $orderManager; + $this->orderFulfiller = $orderFulfiller; + } + + public function process($limit = 0, $step = 0) + { + $orders = $this->orderRepository->find($limit, $step); + foreach ($orders as $order) { + try { + $this->orderFulfiller->fulfill($order); + } catch (\Exception $e) { + + } + } + } +} diff --git a/modules/empikmarketplace/src/Processor/index.php b/modules/empikmarketplace/src/Processor/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Processor/index.php @@ -0,0 +1,11 @@ +addressRepository = $addressRepository; + } + + /** + * @param array $addressData + * @param Customer $customer + * @return Address + */ + public function provide(array $addressData, Customer $customer, array $additionalFields = []) + { + $address = $this->getAddress($addressData, $customer); + if ($address) { + return $address; + } + + $isPickupPointAddress = false; + $isCompanyAddress = false; + + if (empty($addressData['firstname']) && !empty($addressData['lastname']) && !empty($addressData['company'])) { + $isCompanyAddress = true; + } elseif (empty($addressData['firstname']) && !empty($addressData['lastname'])) { + $isPickupPointAddress = true; + } + + $obj = new Address(); + + if ($isCompanyAddress) { + $obj->lastname = isset($addressData['lastname']) ? $addressData['lastname'] : self::NAME_EMPTY; + $obj->firstname = isset($addressData['firstname']) ? $addressData['firstname'] : self::NAME_EMPTY; + } elseif ($isPickupPointAddress) { + $obj->lastname = self::NAME_PICKUP_POINT; + $obj->firstname = self::NAME_PICKUP_POINT; + $obj->address2 = $addressData['lastname']; + } else { + $obj->lastname = $addressData['lastname']; + $obj->firstname = $addressData['firstname']; + $obj->address2 = $addressData['street_2']; + } + + if ($additionalFields) { + foreach ($additionalFields as $additionalField) { + if ($additionalField['code'] === 'nip' && $additionalField['value']) { + $obj->vat_number = $additionalField['value']; + } + } + } + + $obj->id_country = $this->getCountryId($addressData); + $obj->address1 = $addressData['street_1']; + $obj->city = $addressData['city']; + $obj->company = $addressData['company']; + $obj->postcode = $addressData['zip_code']; + + $obj->phone = !empty($addressData['phone']) ? $addressData['phone'] : null; + $obj->other = !empty($addressData['additional_info']) ? $addressData['additional_info'] : null; + + $obj->alias = mb_substr( + sprintf('%s - %s', $obj->city, $obj->address1), + 0, + 32 + ); + + return $obj; + } + + /** + * @param $addressData + * @param Customer $customer + * @return Address|bool + */ + protected function getAddress($addressData, Customer $customer) + { + $address = $this->addressRepository->getOneBy([ + 'id_customer' => (int)$customer->id, + 'lastname' => !empty($addressData['lastname']) ? $addressData['lastname'] : self::NAME_EMPTY, + 'firstname' => !empty($addressData['firstname']) ? $addressData['firstname'] : self::NAME_EMPTY, + 'city' => $addressData['city'], + 'address1' => $addressData['street_1'], + ]); + + if ($address) { + return new Address($address['id_address']); + } + + return false; + } + + /** + * @param array $address + * @return int + */ + protected function getCountryId(array $address) + { + $countryId = null; + + $isoCode = $address['country_iso_code']; + if ($isoCode) { + $countryId = (int)Country::getByIso($isoCode); + } + + if (!$countryId) { + $countryId = (int)Configuration::get('PS_COUNTRY_DEFAULT'); + } + + return $countryId; + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/CarrierProvider.php b/modules/empikmarketplace/src/Provider/Order/CarrierProvider.php new file mode 100644 index 00000000..ed190325 --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/CarrierProvider.php @@ -0,0 +1,52 @@ +carrierMapManager = $carrierMapManager; + } + + /** + * @param array $data + * @return OrderCarrier + * @throws OrderProcessException + */ + function provide($data) + { + $obj = $this->getCarrier($data['shipping_type_code']); + + if (!$obj || !\Validate::isLoadedObject($obj)) { + throw new OrderProcessException( + sprintf( + 'Unmapped carrier (%s) for order: %s', + $data['shipping_type_code'], + $data['order_id'] + ) + ); + } + + $orderCarrier = new OrderCarrier(); + $orderCarrier->id_carrier = $obj->id; + + return $orderCarrier; + } + + protected function getCarrier($carrierCode) + { + $carrierId = $this->carrierMapManager->getIdByCode($carrierCode); + + return new Carrier($carrierId); + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/CartProvider.php b/modules/empikmarketplace/src/Provider/Order/CartProvider.php new file mode 100644 index 00000000..daf1066f --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/CartProvider.php @@ -0,0 +1,86 @@ +productRepository = $productRepository; + $this->identifierExtractor = $identifierExtractor; + + $this->context = Context::getContext(); + } + + /** + * @param array $data + * @return Cart + * @throws \PrestaShopDatabaseException + * @throws \PrestaShopException + */ + function provide($data) + { + $cart = new Cart(); + $cart->id_currency = $this->context->currency->id; + $cart->id_lang = $this->context->language->id; + + $cart->add(); + + foreach ($data['order_lines'] as $orderLine) { + + $productData = $this->getProductByRef($orderLine); + + if (!$productData) { + throw new OrderProcessException(sprintf('Products "%s" not found', $orderLine['product_title'])); + } + + Db::getInstance()->insert('cart_product', [ + 'id_cart' => $cart->id, + 'id_product' => $productData['id_product'], + 'id_shop' => $this->context->shop->id, + 'quantity' => (int)$orderLine['quantity'], + 'date_add' => date('Y-m-d H:i:s'), + ]); + } + + return $cart; + } + + /** + * @param $orderLine + * @return array|bool|false|object|null + */ + protected function getProductByRef($orderLine) + { + $skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE); + + if ($skuType === 'ID') { + $product = $this->productRepository->getProductOrCombinationById($orderLine['offer_sku']); + } elseif ($skuType === 'EAN') { + $product = $this->productRepository->getProductOrCombinationByEan($orderLine['offer_sku']); + } elseif ($skuType === 'REFERENCE') { + $product = $this->productRepository->getProductOrCombinationBySku($orderLine['offer_sku']); + } + + return !empty($product) ? $product : false; + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/CustomerProvider.php b/modules/empikmarketplace/src/Provider/Order/CustomerProvider.php new file mode 100644 index 00000000..5046e1bc --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/CustomerProvider.php @@ -0,0 +1,58 @@ +getCustomerIdByEmail($email); + + if ($customerId) { + return new Customer($customerId); + } + + $obj = new Customer(); + + $obj->lastname = !empty($data['customer']['lastname']) ? $data['customer']['lastname'] : '--'; + $obj->firstname = !empty($data['customer']['firstname']) ? $data['customer']['firstname'] : '--'; + $obj->email = $email; + $obj->passwd = md5(Tools::passwdGen()); + $obj->secure_key = md5(microtime() . _COOKIE_KEY_); + $obj->is_guest = Configuration::get('PS_GUEST_CHECKOUT_ENABLED') ? 1 : 0; + + return $obj; + } + + /** + * @param string $email + * @return bool|int + */ + public function getCustomerIdByEmail($email) + { + return Customer::customerExists($email, true, false); + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/HistoryProvider.php b/modules/empikmarketplace/src/Provider/Order/HistoryProvider.php new file mode 100644 index 00000000..04609136 --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/HistoryProvider.php @@ -0,0 +1,27 @@ +id_employee = Utils::getEmployeeId(); + $obj->id_order_state = Configuration::get(ConfigurationAdapter::CONF_NEW_ORDER_STATE); + + return [ + $obj + ]; + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/NotesProvider.php b/modules/empikmarketplace/src/Provider/Order/NotesProvider.php new file mode 100644 index 00000000..266e23d9 --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/NotesProvider.php @@ -0,0 +1,47 @@ +module = Module::getInstanceByName('empikmarketplace'); + } + + /** + * @param array $data + * @return array + */ + function provide($data) + { + $notes = []; + + $notes[] = $this->module->l('Empik order reference:') . ' ' . $data['order_id']; + $notes[] = $this->module->l('Payment type:') . ' ' . $data['payment_type']; + $notes[] = $this->module->l('Shipping option name:') . ' ' . $data['shipping_type_label']; + + foreach ($data['order_additional_fields'] as $additionalField) { + if ($additionalField['code'] === 'nip') { + $notes[] = $this->module->l('VAT number:') . ' ' . $additionalField['value']; + break; + } + } + + foreach ($data['order_additional_fields'] as $additionalField) { + if ($additionalField['code'] === 'delivery-point-name') { + $notes[] = $this->module->l('Pickup point:') . ' ' . $additionalField['value']; + break; + } + } + + return $notes; + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/OrderLinesProvider.php b/modules/empikmarketplace/src/Provider/Order/OrderLinesProvider.php new file mode 100644 index 00000000..39c66b35 --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/OrderLinesProvider.php @@ -0,0 +1,151 @@ +prestaShopContext = $prestaShopContext; + $this->productRepository = $productRepository; + $this->identifierExtractor = $identifierExtractor; + + $this->context = Context::getContext(); + } + + function provide($data) + { + $lines = []; + + foreach ($data['order_lines'] as $orderLine) { + + $productData = $this->getProductByRef($orderLine); + + if (!$productData) { + continue; + } + + $obj = new OrderDetail(); + $obj->id_warehouse = 0; + $obj->id_shop = $this->context->shop->id; + $obj->product_name = !empty($orderLine['product_title']) ? $orderLine['product_title'] : '--'; + $obj->product_reference = !empty($orderLine['product_sku']) ? $orderLine['product_sku'] : null; + $obj->product_quantity = (int)$orderLine['quantity']; + + if ($productData) { + $obj->product_id = $productData['id_product']; + $obj->product_ean13 = $productData['ean13']; + $obj->product_reference = $productData['reference']; + + if ($this->prestaShopContext->is17()) { + $obj->product_isbn = isset($productData['isbn']) ? $productData['isbn'] : null; + $obj->product_upc = isset($productData['upc']) ? $productData['upc'] : null; + $obj->product_mpn = isset($productData['mpn']) ? $productData['mpn'] : null; + } + } + + $obj->product_price = $orderLine['price_unit']; + + $obj->unit_price_tax_incl = $orderLine['price_unit']; + $obj->total_price_tax_incl = $obj->unit_price_tax_incl * $obj->product_quantity; + + $taxRate = $this->getProductTaxRateByDefaultCountry($productData); + $taxRateMultiplier = (100 + $taxRate) / 100; + + $obj->total_price_tax_excl = round($obj->total_price_tax_incl / $taxRateMultiplier, 6); + $obj->unit_price_tax_excl = round($obj->unit_price_tax_incl / $taxRateMultiplier, 6); + $obj->original_product_price = Product::getPriceStatic( + $obj->product_id, + false, + (int) $obj->product_attribute_id, + 6, + null, + false, + false, + 1, + false, + null, + null, + null, + $null, + true, + true, + $this->context + ); + $obj->tax_computation_method = TaxCalculator::COMBINE_METHOD; + $obj->purchase_supplier_price = (float) $productData['wholesale_price']; + if ($productData['id_supplier'] > 0 && ($supplierPrice = ProductSupplier::getProductPrice((int) $productData['id_supplier'], $productData['id_product'], $productData['id_product_attribute'], true)) > 0) { + $obj->purchase_supplier_price = (float) $supplierPrice; + } + $obj->tax_rate = $taxRate; + $obj->id_tax_rules_group = $productData['id_tax_rules_group']; + + $lines[] = $obj; + } + + return $lines; + } + + /** + * @param $orderLine + * @return array|bool|false|object|null + */ + protected function getProductByRef($orderLine) + { + $skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE); + + if ($skuType === 'ID') { + $product = $this->productRepository->getProductOrCombinationById($orderLine['offer_sku']); + } elseif ($skuType === 'EAN') { + $product = $this->productRepository->getProductOrCombinationByEan($orderLine['offer_sku']); + } elseif ($skuType === 'REFERENCE') { + $product = $this->productRepository->getProductOrCombinationBySku($orderLine['offer_sku']); + } + + return !empty($product) ? $product : false; + } + + /** + * @param $productData + * @return float + */ + protected function getProductTaxRateByDefaultCountry($productData) + { + $taxRate = 0.00; + $defaultCountryId = Configuration::get('PS_COUNTRY_DEFAULT'); + + $taxRates = TaxRulesGroup::getAssociatedTaxRatesByIdCountry($defaultCountryId); + if (!empty($taxRates)) { + $taxRate = reset($taxRates); + } + + return $taxRate; + } +} diff --git a/modules/empikmarketplace/src/Provider/Order/index.php b/modules/empikmarketplace/src/Provider/Order/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Provider/Order/index.php @@ -0,0 +1,11 @@ +db = Db::getInstance(); + } + + public function getOneBy($filter = []) + { + $sql = new DbQuery(); + $sql->select('a.*'); + $sql->from('address', 'a'); + + foreach ($filter as $name => $value) { + $sql->where('a.' . pSQL($name) . ' = ' . '"'.pSQL($value).'"'); + } + + $result = $this->db->getRow($sql); + + return $result ? $result : []; + } +} diff --git a/modules/empikmarketplace/src/Repository/AttributeRepository.php b/modules/empikmarketplace/src/Repository/AttributeRepository.php new file mode 100644 index 00000000..4e79b32a --- /dev/null +++ b/modules/empikmarketplace/src/Repository/AttributeRepository.php @@ -0,0 +1,46 @@ +db = Db::getInstance(); + $this->langId = Utils::getLangId(); + } + + public function getAttributes($productId, $productAttributeId) + { + $sql = new DbQuery(); + $sql->select('al.name AS value, agl.public_name AS name'); + $sql->from('attribute_group', 'ag'); + $sql->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = ag.id_attribute_group AND agl.id_lang = ' . (int)$this->langId); + $sql->leftJoin('product_attribute', 'pa', 'pa.id_product = ' . (int)$productId . ' AND pa.id_product_attribute = ' . (int)$productAttributeId); + $sql->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute'); + $sql->leftJoin('attribute', 'a', 'a.id_attribute = pac.id_attribute AND ag.id_attribute_group = a.id_attribute_group'); + $sql->leftJoin('attribute_lang', 'al', 'al.id_attribute = a.id_attribute AND al.id_lang = ' . (int)$this->langId); + $sql->orderBy('ag.id_attribute_group'); + + $result = $this->db->executeS($sql); + + $resultGrouped = []; + foreach ($result as $item) { + if (!isset($resultGrouped[$item['name']]) || $item['value']) { + $resultGrouped[$item['name']] = $item; + } + } + + return (array)$resultGrouped; + } +} diff --git a/modules/empikmarketplace/src/Repository/CategoryRepository.php b/modules/empikmarketplace/src/Repository/CategoryRepository.php new file mode 100644 index 00000000..5d4280c1 --- /dev/null +++ b/modules/empikmarketplace/src/Repository/CategoryRepository.php @@ -0,0 +1,42 @@ +db = Db::getInstance(); + $this->shopId = Context::getContext()->shop->id; + $this->langId = Utils::getLangId(); + } + + public function getCategoriesByProductId($productId) + { + $sql = new DbQuery(); + $sql->select('cp.id_category, c.id_parent, c.level_depth, cl.name'); + $sql->from('category_product', 'cp'); + $sql->leftJoin('category_lang', 'cl', 'cl.id_category = cp.id_category AND cl.id_shop = ' . (int)$this->shopId . ' AND cl.id_lang = ' . (int)$this->langId); + $sql->leftJoin('category', 'c', 'c.id_category = cp.id_category'); + $sql->where('cp.id_product = ' . (int)$productId); + $sql->orderBy('c.level_depth ASC, c.position ASC'); + + $result = $this->db->executeS($sql); + + return (array)$result; + } +} diff --git a/modules/empikmarketplace/src/Repository/FeatureRepository.php b/modules/empikmarketplace/src/Repository/FeatureRepository.php new file mode 100644 index 00000000..4bdcee2e --- /dev/null +++ b/modules/empikmarketplace/src/Repository/FeatureRepository.php @@ -0,0 +1,40 @@ +db = Db::getInstance(); + $this->langId = Utils::getLangId(); + } + + public function getFeatures($productId) + { + $sql = new DbQuery(); + $sql->select('fl.name AS feature_name, f.id_feature, fp.id_product, GROUP_CONCAT(fvl.value SEPARATOR "'.pSQL(self::SEPARATOR).'") AS value'); + $sql->from('feature', 'f'); + $sql->leftJoin('feature_lang', 'fl', 'fl.id_feature = f.id_feature AND fl.id_lang = ' . (int)$this->langId); + $sql->leftJoin('feature_product', 'fp', 'fp.id_feature = f.id_feature AND fp.id_product = ' . (int)$productId); + $sql->leftJoin('feature_value_lang', 'fvl', 'fvl.id_feature_value = fp.id_feature_value AND fvl.id_lang = ' . (int)$this->langId); + $sql->orderBy('f.id_feature'); + $sql->groupBy('f.id_feature'); + + $result = $this->db->executeS($sql); + + return (array)$result; + } +} diff --git a/modules/empikmarketplace/src/Repository/ImageRepository.php b/modules/empikmarketplace/src/Repository/ImageRepository.php new file mode 100644 index 00000000..71d43584 --- /dev/null +++ b/modules/empikmarketplace/src/Repository/ImageRepository.php @@ -0,0 +1,84 @@ +db = Db::getInstance(); + $this->context = Context::getContext(); + $this->shopId = $this->context->shop->id; + $this->langId = Utils::getLangId(); + } + + public function getImages($productId, $productAttributeId = null) + { + $query = $this->getBaseQuery($productId); + + if ($productAttributeId) { + $query->rightJoin( + 'product_attribute_image', + 'pai', + 'pai.id_image = i.id_image AND pai.id_product_attribute = ' . (int)$productAttributeId + ); + } + + $result = $this->db->executeS($query); + + if ($productAttributeId && count((array)$result) == 0) { + // If no images were found for given product attribute, perform query without product attribute + // condition to get all product images + $newQuery = $this->getBaseQuery($productId); + $result = $this->db->executeS($newQuery); + } + + return (array)$result; + } + + private function getBaseQuery($productId) + { + $sql = new DbQuery(); + $sql->select('i.position, is.id_image, is.cover, il.legend'); + $sql->from('image', 'i'); + $sql->leftJoin( + 'image_shop', + 'is', + 'i.id_image = is.id_image AND is.id_shop = ' . (int)$this->shopId + ); + $sql->leftJoin( + 'image_lang', + 'il', + 'i.id_image = il.id_image AND il.id_lang = ' . (int)$this->shopId + ); + $sql->where('i.id_product = ' . (int)$productId); + $sql->orderBy('is.cover DESC, i.position ASC'); + + return $sql; + } +} diff --git a/modules/empikmarketplace/src/Repository/OrderRepository.php b/modules/empikmarketplace/src/Repository/OrderRepository.php new file mode 100644 index 00000000..0f606f3c --- /dev/null +++ b/modules/empikmarketplace/src/Repository/OrderRepository.php @@ -0,0 +1,13 @@ +shopContext = $shopContext; + + $this->db = Db::getInstance(); + $this->shopId = Context::getContext()->shop->id; + $this->langId = Utils::getLangId(); + } + + protected function getProductsCommonSql() + { + $sql = new DbQuery(); + + $sql->select('SQL_CALC_FOUND_ROWS ps.id_product, ps.price, ps.id_tax_rules_group, ps.wholesale_price, p.id_supplier, p.active'); + $sql->select('p.upc, p.unity, p.width, p.height, p.depth, p.condition, p.additional_shipping_cost'); + $sql->select(' + IFNULL(epb.logistic_class, 0) AS logistic_class, + IFNULL(epb.condition, 0) AS empik_condition, + IFNULL(epb.product_export, 0) AS product_export, + IFNULL(epb.offer_export, 0) AS offer_export, + IFNULL(ep.offer_price, 0) AS offer_price, + IFNULL(ep.offer_price_reduced, 0) AS offer_price_reduced, + IFNULL(ep.export_original_price, 0) AS export_original_price + '); + + // combinations / base product + $sql->select('IFNULL(pa.reference, p.reference) AS reference'); + $sql->select('IFNULL(pa.supplier_reference, p.supplier_reference) AS supplier_reference'); + $sql->select('IFNULL(pa.ean13, p.ean13) AS ean13'); + $sql->select('IFNULL(pa.minimal_quantity, ps.minimal_quantity) AS minimal_quantity'); + $sql->select('IFNULL(pa.weight, p.weight) AS weight'); + $sql->select('IFNULL(pa.wholesale_price, p.wholesale_price) AS wholesale_price'); + $sql->select('IFNULL(pa.price, (ps.price + pa.price)) AS price'); + + $sql->select('pl.name, pl.description, pl.description_short, pl.link_rewrite, pl.meta_description, pl.meta_keywords, pl.meta_title, pl.available_now, pl.available_later'); + $sql->select('pa.id_product_attribute'); + $sql->select('m.name AS manufacturer_name'); + $sql->select('sav.depends_on_stock, sav.quantity'); + + if ($this->shopContext->is177()) { + $sql->select('p.isbn, p.mpn'); + $sql->select('pl.delivery_in_stock, pl.delivery_out_stock'); + } + + $sql->from('product', 'p'); + + $sql->leftJoin('product_shop', 'ps', 'ps.id_product = p.id_product AND ps.id_shop = ' . (int)$this->shopId); + $sql->leftJoin('manufacturer', 'm', 'm.id_manufacturer = p.id_manufacturer'); + $sql->leftJoin('product_lang', 'pl', 'pl.id_product = p.id_product AND pl.id_lang = ' . (int)$this->langId . ' AND pl.id_shop = ' . (int)$this->shopId); + + // combinations + $sql->leftJoin('product_attribute', 'pa', 'pa.id_product = p.id_product'); + $sql->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute'); + $sql->leftJoin('attribute', 'a', 'a.id_attribute = pac.id_attribute'); + $sql->leftJoin('attribute_lang', 'al', 'al.id_attribute = a.id_attribute AND al.id_lang = ' . (int)$this->langId); + $sql->leftJoin('attribute_group', 'ag', 'ag.id_attribute_group = a.id_attribute_group'); + $sql->leftJoin('attribute_group_lang', 'agl', 'agl.id_attribute_group = ag.id_attribute_group AND agl.id_lang = ' . (int)$this->langId); + + $sql->leftJoin('empik_product', 'epb', 'epb.id_product = p.id_product AND epb.id_product_attribute = 0'); + $sql->leftJoin('empik_product', 'ep', 'ep.id_product = p.id_product AND ep.id_product_attribute = IFNULL(pa.id_product_attribute, 0)'); + + // stock + $sql->leftJoin('stock_available', 'sav', 'sav.id_product = p.id_product AND sav.id_product_attribute = IFNULL(pa.id_product_attribute, 0) AND sav.id_shop = ' . (int)$this->shopId . ' AND sav.id_shop_group = 0'); + + $sql->where('ps.active = 1'); + $sql->groupBy('p.id_product, pa.id_product_attribute'); + + return $sql; + } + + /** + * @param int $page + * @param int $productsPerPage + * @param null $src + * @return array + * @throws \PrestaShopDatabaseException + */ + public function getProductsPaginate($page = null, $productsPerPage = 10, $src = null) + { + $sql = $this->getProductsCommonSql(); + + if ($page !== null) { + $sql->limit((int)$productsPerPage, (int)($page * $productsPerPage)); + } + + if ($src === self::SRC_PRODUCT) { + $sql->where('epb.product_export = 1'); + } + if ($src === self::SRC_OFFER) { + $sql->where('epb.offer_export = 1'); + } + + $result = $this->db->executeS($sql); + + return (array)$result; + } + + public function getProductsTotal($src = null) + { + $sql = $this->getProductsCommonSql(); + + if ($src === self::SRC_PRODUCT) { + $sql->where('epb.product_export = 1'); + } + if ($src === self::SRC_OFFER) { + $sql->where('epb.offer_export = 1'); + } + + $sql->limit(1, 0); + + $this->db->executeS($sql); + + $result = $this->db->getValue('SELECT FOUND_ROWS()'); + + return (int)$result; + } + + public function getProductOrCombinationByEan($ean) + { + $sql = $this->getProductsCommonSql(); + + $sql->where('p.ean13 = "'.pSQL($ean).'" OR pa.ean13 = "'.pSQL($ean).'"'); + + return $this->db->getRow($sql); + } + + public function getProductOrCombinationBySku($sku) + { + $sql = $this->getProductsCommonSql(); + + $sql->where('p.reference = "'.pSQL($sku).'" OR pa.reference = "'.pSQL($sku).'"'); + + return $this->db->getRow($sql); + } + + public function getProductOrCombinationById($id) + { + $sql = $this->getProductsCommonSql(); + + $id = explode('-', $id); + $productId = isset($id[0]) ? (int)$id[0] : 0; + $productAttributeId = isset($id[1]) ? (int)$id[1] : 0; + + if ($productAttributeId) { + $sql->where('pa.id_product_attribute = "'.pSQL($productAttributeId).'"'); + } else { + $sql->where('p.id_product = "'.pSQL($productId).'"'); + } + + return $this->db->getRow($sql); + } + + public function getOffersByIds(array $ids) + { + $ids = array_map('intval', $ids); + + $sql = $this->getProductsCommonSql(); + + if (count($ids)) { + $sql->where('ps.id_product IN ('.implode(',', $ids).')'); + } + + $result = $this->db->executeS($sql); + + return (array)$result; + } + + public function updateOfferPrice($productId, $productAttributeId, $price) + { + $empikProduct = \EmpikProduct::getOrCreate($productId, $productAttributeId); + $empikProduct->offer_price = (float)$price; + $empikProduct->save(); + } + + public function updateOfferPriceReduced($productId, $productAttributeId, $price) + { + $empikProduct = \EmpikProduct::getOrCreate($productId, $productAttributeId); + $empikProduct->offer_price_reduced = (float)$price; + $empikProduct->save(); + } +} diff --git a/modules/empikmarketplace/src/Repository/TaxRepository.php b/modules/empikmarketplace/src/Repository/TaxRepository.php new file mode 100644 index 00000000..bc102bce --- /dev/null +++ b/modules/empikmarketplace/src/Repository/TaxRepository.php @@ -0,0 +1,39 @@ +db = Db::getInstance(); + $this->countryId = Utils::getCountryId(); + } + + public function getTaxRateByProductId($productId) + { + $sql = new DbQuery(); + $sql->select('t.rate'); + $sql->from('product', 'p'); + $sql->leftJoin('tax_rules_group', 'trg', 'p.id_tax_rules_group = trg.id_tax_rules_group'); + $sql->leftJoin('tax_rule', 'tr', 'tr.id_tax_rules_group = trg.id_tax_rules_group AND tr.id_country = ' . (int)$this->countryId); + $sql->leftJoin('tax', 't', 't.id_tax = tr.id_tax'); + $sql->where('t.active = 1'); + $sql->where('t.deleted = 0'); + $sql->where('p.id_product = ' . (int)$productId); + + $result = $this->db->getValue($sql); + + return (int)$result; + } +} diff --git a/modules/empikmarketplace/src/Repository/index.php b/modules/empikmarketplace/src/Repository/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Repository/index.php @@ -0,0 +1,11 @@ +errors); + } + + public function getErrors() + { + return $this->errors; + } + + protected function resetErrors() + { + $this->errors = []; + + return $this; + } + + protected function addError($error) + { + $this->errors[] = $error; + + return $this; + } + + protected function setErrors(array $errors) + { + $this->errors = $errors; + + return $this; + } +} diff --git a/modules/empikmarketplace/src/Traits/index.php b/modules/empikmarketplace/src/Traits/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/src/Traits/index.php @@ -0,0 +1,11 @@ +categories = $categories; + + $names = []; + foreach ($this->categories as $c) { + $names[] = $c['name']; + } + + return implode(ExportConfiguration::CSV_VALUE_SEPARATOR, $names); + } +} diff --git a/modules/empikmarketplace/src/Utils/IdentifierExtractor.php b/modules/empikmarketplace/src/Utils/IdentifierExtractor.php new file mode 100644 index 00000000..6276b6c0 --- /dev/null +++ b/modules/empikmarketplace/src/Utils/IdentifierExtractor.php @@ -0,0 +1,72 @@ +identifierType = Configuration::get(ConfigurationAdapter::CONF_OFFER_IDENTIFIER); + } + + /** + * @return bool|false|string + */ + public function getIdentifierType() + { + return $this->identifierType; + } + + /** + * @return string + * @throws LogicException + */ + public function getFilterKey() + { + switch ($this->identifierType) { + case self::IDENTIFIER_EAN: + $key = 'p.ean13'; + break; + case self::IDENTIFIER_SKU: + $key = 'p.reference'; + break; + default: + throw new LogicException(sprintf('Unknown identifier type: "%s"', $this->identifierType)); + } + + return $key; + } + + /** + * @param array $product + * @return mixed|string + * @throws LogicException + */ + public function extract(array $product) + { + switch ($this->identifierType) { + case self::IDENTIFIER_EAN: + $identifier = isset($product['ean13']) ? $product['ean13'] : ''; + break; + case self::IDENTIFIER_SKU: + // $identifier = isset($product['reference']) ? $product['reference'] : ''; + $skuExtractor = new SkuExtractor(); + $identifier = $skuExtractor->extract($product); + break; + default: + throw new LogicException(sprintf('Unknown identifier type: "%s"', $this->identifierType)); + } + + return $identifier; + } +} diff --git a/modules/empikmarketplace/src/Utils/OfferPriceCalculator.php b/modules/empikmarketplace/src/Utils/OfferPriceCalculator.php new file mode 100644 index 00000000..e28da953 --- /dev/null +++ b/modules/empikmarketplace/src/Utils/OfferPriceCalculator.php @@ -0,0 +1,44 @@ +addToPrice = (float)Configuration::get(ConfigurationAdapter::CONF_ADD_TO_PRICE); + $this->priceRatio = (float)Configuration::get(ConfigurationAdapter::CONF_PRICE_RATIO); + } + + /** + * @param $price + * @return float + */ + public function calculate($price) + { + $price = (float)$price; + + if ($this->priceRatio != 1) { + $price *= $this->priceRatio; + } + + if ($this->addToPrice != 0) { + $price += $this->addToPrice; + } + + return Tools::ps_round($price, self::ROUND_PRECISION); + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Utils/OfferQuantityCalculator.php b/modules/empikmarketplace/src/Utils/OfferQuantityCalculator.php new file mode 100644 index 00000000..aabb2759 --- /dev/null +++ b/modules/empikmarketplace/src/Utils/OfferQuantityCalculator.php @@ -0,0 +1,31 @@ +stockReduce = (int)Configuration::get(ConfigurationAdapter::CONF_REDUCE_STOCK); + } + + /** + * @param int $quantity + * @return float + */ + public function calculate($quantity) + { + $quantity = (int)$quantity; + + $quantity = max($quantity - $this->stockReduce, 0); + + return $quantity; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/src/Utils/SkuExtractor.php b/modules/empikmarketplace/src/Utils/SkuExtractor.php new file mode 100644 index 00000000..7217836f --- /dev/null +++ b/modules/empikmarketplace/src/Utils/SkuExtractor.php @@ -0,0 +1,59 @@ +skuType = Configuration::get(ConfigurationAdapter::CONF_SKU_TYPE); + } + + /** + * @return bool|false|string + */ + public function getSkuType() + { + return $this->skuType; + } + + /** + * @param array $product + * @return mixed|string + * @throws LogicException + */ + public function extract(array $product) + { + switch ($this->skuType) { + case self::SKU_REFERENCE: + $identifier = isset($product['reference']) ? $product['reference'] : ''; + break; + case self::SKU_EAN: + $identifier = isset($product['ean13']) ? $product['ean13'] : ''; + break; + case self::SKU_ID: + $identifier = isset($product['id_product']) ? $product['id_product'] : ''; + + if (isset($product['id_product_attribute']) && $product['id_product_attribute'] > 0) { + $identifier .= '-' . $product['id_product_attribute']; + } + + break; + default: + throw new LogicException(sprintf('Unknown SKU type: "%s"', $this->skuType)); + } + + return $identifier; + } +} diff --git a/modules/empikmarketplace/src/Utils/Utils.php b/modules/empikmarketplace/src/Utils/Utils.php new file mode 100644 index 00000000..004471c3 --- /dev/null +++ b/modules/empikmarketplace/src/Utils/Utils.php @@ -0,0 +1,96 @@ +empikmarketplace_a830eff1fc5a82ebe5bee9c296a44209'] = 'EmpikPlace'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_c96b0d791e454aecffce03d68f66066e'] = 'Integracja z Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_bb9fe2c1c60ad48dd84acad839bd5487'] = 'Empik'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_c2cc7082a89c1ad6631a2f66af5f00c0'] = 'Połączenie'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_068f80c7519d0528fb08e82137a72131'] = 'Produkty'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_e5ddec57f3621b8be90e50d319aa3a0d'] = 'Parametry produktów'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_9461bed8b71377318436990e57106729'] = 'Oferty'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_7442e29d7d53e549b78d93c46b8cdcfc'] = 'Zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_95fe0f8a473d777ef7f45a09c7d193b9'] = 'Ostatnie akcje'; +$_MODULE['<{empikmarketplace}prestashop>empikmarketplace_6a26f548831e6a8c26bfbbd9f6ec61e0'] = 'Pomoc'; +$_MODULE['<{empikmarketplace}prestashop>install-1.2.0_e5ddec57f3621b8be90e50d319aa3a0d'] = 'Parametry produktów'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_0dcd765946a2754ab184042261f174da'] = 'Błędne Importuj zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_18cdc3e4cdc9ffcc80e41a31ab0a3fad'] = 'Błędne Automatycznie potwierdzaj zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_0fdd583c3792d0ed24882fe7f292c515'] = 'Błędny Status nowego zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_6efc2bb6c00ae00fc49bb21f9d15daf4'] = 'Błędny Status wysłanego zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_3fe1bdb72bf08548ff58df96e1d8f552'] = 'Błąd podczas zapisu formularza.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_8e1cd90755f52a0ea71ab43bcdd54958'] = 'Musisz skonfigurować połączenie z API'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_7442e29d7d53e549b78d93c46b8cdcfc'] = 'Zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_57cf56dae47cce791c7045c19e73eedb'] = 'Pobieraj zamówienia z Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_93cba07454f06a4a960172bbd6e2a435'] = 'Tak'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_bafd7322c6e97d25b6299b5d6fe8920b'] = 'Nie'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_f8c7732878b837924db3fc56cf00279f'] = 'Automatycznie potwierdzaj zamówienia w Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_362b1ae67eb25b2035ccab5f79e78e21'] = 'Status nowego zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_9abb149c95d75463bc3f2cf0822350d5'] = 'Status wysłanego zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_c9cc8cce247e49bae79f15173ce97354'] = 'Zapisz'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_ea9cf7e47ff33b2be14e6dd07cbcefc6'] = 'Dostawa'; +$_MODULE['<{empikmarketplace}prestashop>adminempikorderscontroller_f586efed44bbd49237cd2cebcf56b018'] = 'Mapowanie form dostawy'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_5777a463a633264be0fb504c31b55a86'] = 'Połączenie z API działa poprawnie'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_1bd9557a02b1ee3e6cd1143587486ce2'] = 'Błąd połączenia, sprawdź poprawność danych'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_f35e0bba58156c64f5aeb07cb8abb66c'] = 'Błędne Środowisko'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_2e61736e2418f02cf2b15f76e5df7941'] = 'Błędny Klucz API'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_3fe1bdb72bf08548ff58df96e1d8f552'] = 'Błąd podczas zapisu formularza.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_254f642527b45bc260048e30704edb39'] = 'Konfiguracja'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_0ba29c6a1afacf586b03a26162c72274'] = 'Środowisko'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_d9b8ff82fe88da6949f93a95ac83ef2a'] = 'Wybierz środowisko'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_ae2b1fca515949e5d54fb22b8ed95575'] = 'testowe'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_fd89784e59c72499525556f80289b2c7'] = 'produkcyjne'; +$_MODULE['<{empikmarketplace}prestashop>adminempikconnectioncontroller_656a6828d7ef1bb791e42087c4b5ee6e'] = 'Klucz API'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_8d84055c6839f08eedbbc2283b7ba32c'] = 'Eksport wykonany poprawnie.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_718bcaf22df6a1c795e0f1ee58c22233'] = 'Wszystkie produkty usunięte poprawnie.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_687c2bda8ee9f4a8f4c42c1c00501e6d'] = 'Wszystkie produkty dodane do eksportu poprawnie.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_b718adec73e04ce3ec720dd11a06a308'] = 'ID'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_49ee3087348e8d44e1feda1917443987'] = 'Nazwa'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_3adbdb3ac060038aa0e6e6c138ef9873'] = 'Kategoria'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_63d5049791d9d79d86e9a108b0a999ca'] = 'Indeks'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_e192956d901dff59c35fd2c477ed28d6'] = 'Cena (bez VAT)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_77eb276f5dcdf4fbca854e908216f7b2'] = 'Cena (z VAT)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_694e8d1f2ee056f98ee488bdc4982d73'] = 'Ilość'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_3ac64dc4e3a75611f07817ad926dd963'] = 'Eksport produktów'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_c5aa9128c5db7742a49ae2cd9f76ab8d'] = 'Eksport ofert'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_7270f2ed1faed6abcd140d2131e9be5d'] = 'Dodaj produkty do eksportu'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_76f3cc15fb507cbdf6690bd8e63f9c3f'] = 'Usuń produkty z eksportu'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_90b4c9d0632ac01be5cbea03b0bcbcf6'] = 'Dodaj oferty do eksportu'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_1af7eadb0fd18bf0a0b80fd97e9af64f'] = 'Usuń oferty z eksportu'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_2faec1f9f8cc7f8f40d521c4dd574f49'] = 'Włączony'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductscontroller_3df8760fcb4a8db5967ee7ffe66c2bee'] = 'Wybierz przynajmniej jedną pozycję'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_b718adec73e04ce3ec720dd11a06a308'] = 'ID'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_63d5049791d9d79d86e9a108b0a999ca'] = 'Indeks'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_1a5cfa5d07a7c36cc9d95215a81fcc59'] = 'EAN'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_49ee3087348e8d44e1feda1917443987'] = 'Nazwa'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_3adbdb3ac060038aa0e6e6c138ef9873'] = 'Kategoria'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_3601146c4e948c32b6424d2c0a7f0118'] = 'Cena'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_04e0b278b0022198e6921bd3944cf57d'] = 'Cena dla EmpikPlace'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_c8bb67a706a0a99b893d4d92a5a2e648'] = 'Cena promocyjna'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_3e24f6481576e890c9492438d738d77b'] = 'Cena promocyjna dla EmpikPlace'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_402a8ce01c476c3cccf4abe2a631e2b6'] = 'Pokaż promocję'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_0341fb2cb1d0b0b093d568cbdacb2687'] = 'Parametry oferty'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_a7345a8cf91f932b956d0fe9ea9725eb'] = 'Klasa logistyczna'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_9e2941b3c81256fac10392aaca4ccfde'] = 'Stan produktu'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_c9cc8cce247e49bae79f15173ce97354'] = 'Zapisz'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_25f746074f7d0d3347097ebeae0e4fb3'] = 'Nowy (kod 11)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_5b27ea346a14079df6bb94c24e0d6766'] = 'Używany – stan bardzo dobry (kod=1)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_9d85e9367fd32fd6aad8d5b0a33d5fbc'] = 'Używany – stan dobry (kod=2)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_5591d52018fccf96e73f2dced5f5f36d'] = 'Używany – stan zadowalający (kod=3)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_5da473627b399f9eb0a63693d3a17430'] = 'Odnowiony - stan bardzo dobry (kod=4)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_8bd949c6c51b1a2b81c07837696000b1'] = 'Odnowiony - stan dobry (kod=5)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_8eb3220568b46cd10b2cdd7a35d241b3'] = 'Odnowiony - stan zadowalający (kod=6)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_f9dba5cadc2a49edb05333dc5ca2f3b6'] = 'Uszkodzone opakowanie (kod=7)'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_b9f0916589cf973365093a3fa5874365'] = 'Klasa logistyczna:'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_ed51222f31afbf17ca5f3b0654db8969'] = 'Stan produktu:'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_fe82d0301eb1971d22d412b3d44f0fbe'] = 'Pokaż promocje'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_bad3b1589c7fa08d362d9a99bf1902b0'] = 'Nie pokazuj promocji'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_9ac0579c67b0981dfbf2a2effebb167f'] = 'Ustawienia cen zostały zapisane!'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_3df8760fcb4a8db5967ee7ffe66c2bee'] = 'Musisz wybrać co najmniej jedną pozycję.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_b9e46c3b3c8dcfe474dee78476f32516'] = 'Cena zapisana poprawnie!'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_955e1c17be178adec1cc07a2b5cc468d'] = 'Klasa logistyczna zapisana poprawnie!'; +$_MODULE['<{empikmarketplace}prestashop>adminempikproductspricecontroller_4af5a845886b6f921729058bda5f5a7f'] = 'Stan produktu zapisana poprawnie!'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_b718adec73e04ce3ec720dd11a06a308'] = 'ID'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_004bf6c9a40003140292e97330236c53'] = 'Typ akcji'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_111893dc2ad3535a627f8d904e9acf80'] = 'Data rozpoczęcia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_7d6da8f6cb6897fb1a8ce7f74e826c2e'] = 'Data zakończenia'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_ec53a8c4f07baed5d8825072c89799be'] = 'Status'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_ae1471706f9047829c6bc80b00658799'] = 'ID importu'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_efbb34579851829586ac31ce4f8c01ae'] = 'Liczba produktów'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_4b1b4dc8cf38b3c64b1d657da8f5ac8c'] = 'Raport'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_0241c13a7dbc4b5d79394ebe0e425476'] = 'Brak ID importu dla wybranej akcji'; +$_MODULE['<{empikmarketplace}prestashop>adminempikactionlogcontroller_669e4579cfdf5754c6fcffca7d0dc63e'] = 'Nie znaleziono raportu dla importu o ID: %s'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_8d84055c6839f08eedbbc2283b7ba32c'] = 'Eksport wykonany poprawnie.'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_fd3f933639bf944d5e3fa5f8a9c9d4d0'] = '- Brak ustawienia -'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_9461bed8b71377318436990e57106729'] = 'Oferty'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_ec18711ec6656fa8d9f6f53ff6d813e2'] = 'Synchronizuj oferty automatycznie z Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_93cba07454f06a4a960172bbd6e2a435'] = 'Tak'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_bafd7322c6e97d25b6299b5d6fe8920b'] = 'Nie'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_087239a312ab7c44ba4acf9a52c897e5'] = 'Synchronizuj klasę logistyczną'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_b1e8d8dea4afaf283f5c67eb52389d95'] = 'Aktywowanie tej opcji będzie skutkowało wysyłaniem domyślnej klasy logistycznej (Średnia kod=2) lub wybranej wartości w zakładce \"Parametry produktów\"'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_2f40334154b6af06a4b7f60105f69327'] = 'Wskaż identyfikator dla ofert Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_1a5cfa5d07a7c36cc9d95215a81fcc59'] = 'EAN'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_6665e3761028c84e1d228de3432229ed'] = 'SKU'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_fbfabced04353738e35b2d5d74553eea'] = 'Wartość SKU'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_63d5049791d9d79d86e9a108b0a999ca'] = 'Indeks'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_b718adec73e04ce3ec720dd11a06a308'] = 'ID'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_6b21b64c47165f9038e347072acc1ede'] = 'Czas wysyłki'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_3b147b615b1760260834656e701e92e1'] = 'Mnożnik ceny'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_b54c490a946f8b112beb8ce2b7b17458'] = 'Dodaj do ceny'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_63191f80cffd2822ed6d516bb44e97b5'] = 'Obniż stan magazynowy'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_c9cc8cce247e49bae79f15173ce97354'] = 'Zapisz'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_ff71722a9bcd0167d9f1218aad7b5b9d'] = 'Błędne Synchronizuj oferty'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_e0fa52261b4aa29b5b1c4374103c8b82'] = 'Błędne Synchronizuj klasę logistyczną'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_d265e835350f8fcc88094980ce38b44a'] = 'Błędny Identyfikator dla ofert'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_81f1db2d8bde456fe2bcd7205ebfb305'] = 'Błędna wartość SKU'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_8f05bd76d8fc1cbe703b59b7964aa8f9'] = 'Błędny Czas wysyłki'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_7537bb1c72ca079f5c887ddd6c186b95'] = 'Błędny Mnożnik ceny'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_69740bfdc0fbc8d76267b879f508e22e'] = 'Błędne Dodaj do ceny'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_89477f34473b3c1d9fe998d6628ba43b'] = 'Błędne Obniż stan magazynowy'; +$_MODULE['<{empikmarketplace}prestashop>adminempikofferscontroller_3fe1bdb72bf08548ff58df96e1d8f552'] = 'Błąd podczas zapisu formularza.'; +$_MODULE['<{empikmarketplace}prestashop>list_action_edit_price_reduced_287234a1ff35a314b5b6bc4e5828e745'] = 'Warianty'; +$_MODULE['<{empikmarketplace}prestashop>products_06df33001c1d7187fdd81ea1f5b277aa'] = 'Akcje'; +$_MODULE['<{empikmarketplace}prestashop>products_a3abab5f17872b3533b285d67b059232'] = 'Wyślij pojedynczy import produktów'; +$_MODULE['<{empikmarketplace}prestashop>products_b34df594d3356262b9cf6f1902a40e93'] = 'Zobacz jak wybrać produkty, które mają być wysłane do Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>products_172780a04ccf40c98ad2f9e55ca7a295'] = 'Po wykonaniu importu produktów, należy skorzystać z kreatora mapowania w Panelu Sprzedaży EmpikPlace.'; +$_MODULE['<{empikmarketplace}prestashop>products_8d58de8c22ba2d49193c99faa5170cc9'] = 'Instrukcja znajduje się w filmie instruktażowym oraz instrukcji modułu.'; +$_MODULE['<{empikmarketplace}prestashop>products_79df7aa00c265aa4cffe5b5d4f0ea734'] = 'Pobierz ostatni wygenerowany plik z produktami'; +$_MODULE['<{empikmarketplace}prestashop>products_470fba857f6a0b93f4e7331a7e19757b'] = 'Dodaj wszystkie produkty do Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>products_2708fe6a0826a3adabec2e7217ecd81e'] = 'Usuń wszystkie produkty z Empik Marketplace'; +$_MODULE['<{empikmarketplace}prestashop>products_f9ab5f3d1d544cd899d24b4ce7bdd42f'] = 'Przed rozpoczęciem pracy, podaj dane uwierzytelniające w zakładce \"Połączenie\".'; +$_MODULE['<{empikmarketplace}prestashop>list_action_edit_price_287234a1ff35a314b5b6bc4e5828e745'] = 'Warianty'; +$_MODULE['<{empikmarketplace}prestashop>list_action_original_price_93cba07454f06a4a960172bbd6e2a435'] = 'Tak'; +$_MODULE['<{empikmarketplace}prestashop>list_action_original_price_bafd7322c6e97d25b6299b5d6fe8920b'] = 'Nie'; +$_MODULE['<{empikmarketplace}prestashop>list_action_enable_00d23a76e43b46dae9ec7aa9dcbebb32'] = 'Włączony'; +$_MODULE['<{empikmarketplace}prestashop>list_action_enable_b9f5c797ebbf55adccdd8539a65a0241'] = 'Wyłączony'; +$_MODULE['<{empikmarketplace}prestashop>help_6a26f548831e6a8c26bfbbd9f6ec61e0'] = 'Pomoc'; +$_MODULE['<{empikmarketplace}prestashop>help_e7688b51379d3009efeb9efc9d9bfe2d'] = 'Zadania CRON'; +$_MODULE['<{empikmarketplace}prestashop>help_1f11d64febcbb2b9fbd72cc24ee554ca'] = 'Aktualizacja ofert'; +$_MODULE['<{empikmarketplace}prestashop>help_4ed2cbb99dd730ccef9d12a72a075984'] = 'Import zamówień'; +$_MODULE['<{empikmarketplace}prestashop>help_c934a51b465c3328c310affd968d4604'] = 'Eksport produktów'; +$_MODULE['<{empikmarketplace}prestashop>list_action_download_801ab24683a4a8c433c6eb40c48bcd9d'] = 'Pobierz'; +$_MODULE['<{empikmarketplace}prestashop>shipping_table_c0c7642e35709c02e07fe8f1fe0cb2ff'] = 'Dostawca Empik'; +$_MODULE['<{empikmarketplace}prestashop>shipping_table_51d1f5caed9f98b8f303141e9a5b2be1'] = 'Dostawca w sklepie'; +$_MODULE['<{empikmarketplace}prestashop>shipping_table_5ef2ce2e8f53259ebbb796e985df5072'] = 'Typ przewoźnika'; +$_MODULE['<{empikmarketplace}prestashop>export_offers_button_88d4d0429ed36fd93d6829bb29345175'] = 'Eksport ofert'; +$_MODULE['<{empikmarketplace}prestashop>manage_price_button_446945b2a978b1716f4673f3bf32afb3'] = 'Ustaw dedykowane ceny dla EmpikPlace'; +$_MODULE['<{empikmarketplace}prestashop>admin_order_90e38ebb90482ab49713e8e63fc875e9'] = 'Empik marketplace'; +$_MODULE['<{empikmarketplace}prestashop>admin_order_5d4710f9a8250b13164a82c94d5b00d1'] = 'Numer zamówienia'; +$_MODULE['<{empikmarketplace}prestashop>admin_order_08f02f84939ab5a4f98ac21360f99bf4'] = 'Rodzaj płatności'; +$_MODULE['<{empikmarketplace}prestashop>admin_order_e4bc2d6d67a3bc1fcaa8e4f4adf005fa'] = 'Rodzaj przewoźnika'; +$_MODULE['<{empikmarketplace}prestashop>admin_order_ee5c5839980b47f1893220655a3de0fb'] = 'Punkt odbioru'; +$_MODULE['<{empikmarketplace}prestashop>admin_order_7cb32e708d6b961d476baced73d362bb'] = 'Numer NIP'; +$_MODULE['<{empikmarketplace}prestashop>hookaction_bb9fe2c1c60ad48dd84acad839bd5487'] = 'Empik'; diff --git a/modules/empikmarketplace/upgrade/install-1.1.0.php b/modules/empikmarketplace/upgrade/install-1.1.0.php new file mode 100644 index 00000000..a7ae8c2f --- /dev/null +++ b/modules/empikmarketplace/upgrade/install-1.1.0.php @@ -0,0 +1,33 @@ +clear(); + + $result = true; + + $installer = $object->getInstaller(); + + $result &= $installer->createTabs(); + + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product` ADD COLUMN `empik_offer_price` DECIMAL(20, 2) NOT NULL DEFAULT 0;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product` ADD COLUMN `empik_offer_price_reduced` DECIMAL(20, 2) NOT NULL DEFAULT 0;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product_attribute` ADD COLUMN `empik_offer_price` DECIMAL(20, 2) NOT NULL DEFAULT 0;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product_attribute` ADD COLUMN `empik_offer_price_reduced` DECIMAL(20, 2) NOT NULL DEFAULT 0;'; + + foreach ($sql as $query) { + $result &= Db::getInstance()->execute($query); + } + + return $result; +} diff --git a/modules/empikmarketplace/upgrade/install-1.1.3.php b/modules/empikmarketplace/upgrade/install-1.1.3.php new file mode 100644 index 00000000..a5fa2813 --- /dev/null +++ b/modules/empikmarketplace/upgrade/install-1.1.3.php @@ -0,0 +1,18 @@ +clear(); + + return true; +} diff --git a/modules/empikmarketplace/upgrade/install-1.1.4.php b/modules/empikmarketplace/upgrade/install-1.1.4.php new file mode 100644 index 00000000..109a7e77 --- /dev/null +++ b/modules/empikmarketplace/upgrade/install-1.1.4.php @@ -0,0 +1,22 @@ +clear(); + + $result = true; + $result &= Configuration::updateValue(ConfigurationAdapter::CONF_SKU_TYPE, 'REFERENCE'); + + return $result; +} diff --git a/modules/empikmarketplace/upgrade/install-1.2.0.php b/modules/empikmarketplace/upgrade/install-1.2.0.php new file mode 100644 index 00000000..823eee8c --- /dev/null +++ b/modules/empikmarketplace/upgrade/install-1.2.0.php @@ -0,0 +1,65 @@ +clear(); + + $result = true; + + $sql[] = 'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'empik_product` ( + `id_empik_product` INT(11) NOT NULL AUTO_INCREMENT, + `id_product` INT(11) NOT NULL, + `id_product_attribute` INT(11) NOT NULL, + `logistic_class` INT(4) NOT NULL DEFAULT 2, + `product_export` INT(1) NOT NULL DEFAULT 0, + `offer_export` INT(1) NOT NULL DEFAULT 0, + `offer_price` DECIMAL(20, 2) NOT NULL DEFAULT 0, + `offer_price_reduced` DECIMAL(20, 2) NOT NULL DEFAULT 0, + UNIQUE (`id_product`, `id_product_attribute`), + PRIMARY KEY (`id_empik_product`) + )'; + + $sql[] = 'INSERT INTO `' . _DB_PREFIX_ . 'empik_product` (`id_product`, `id_product_attribute`, `logistic_class`, `product_export`, `offer_export`, `offer_price`, `offer_price_reduced`) + SELECT `id_product`, 0, 0, IF(`empik_product_disabled`, 0, 1), IF(`empik_offer_disabled`, 0, 1), `empik_offer_price`, `empik_offer_price_reduced` + FROM `' . _DB_PREFIX_ . 'product` + WHERE (`empik_product_disabled` = 0 OR `empik_offer_disabled` = 0) + '; + + $sql[] = 'INSERT INTO `' . _DB_PREFIX_ . 'empik_product` (`id_product`, `id_product_attribute`, `logistic_class`, `product_export`, `offer_export`, `offer_price`, `offer_price_reduced`) + SELECT `id_product`, `id_product_attribute`, 0, 1, 1, `empik_offer_price`, `empik_offer_price_reduced` + FROM `' . _DB_PREFIX_ . 'product_attribute` + WHERE (`empik_offer_price` > 0 OR `empik_offer_price_reduced` > 0) + '; + + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product` DROP COLUMN `empik_product_disabled`;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product` DROP COLUMN `empik_offer_disabled`;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product` DROP COLUMN `empik_offer_price`;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product` DROP COLUMN `empik_offer_price_reduced`;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product_attribute` DROP COLUMN `empik_offer_price`;'; + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'product_attribute` DROP COLUMN `empik_offer_price_reduced`;'; + + foreach ($sql as $query) { + $result &= Db::getInstance()->execute($query); + } + + if (($tab = Tab::getIdFromClassName('AdminEmpikProductsPrice'))) { + $tab = new Tab($tab); + foreach (Language::getLanguages() as $language) { + $tab->name[$language['id_lang']] = $object->l('Products parameters'); + } + $result &= $tab->save(); + } + + return $result; +} diff --git a/modules/empikmarketplace/upgrade/install-1.4.0.php b/modules/empikmarketplace/upgrade/install-1.4.0.php new file mode 100644 index 00000000..3d9c684a --- /dev/null +++ b/modules/empikmarketplace/upgrade/install-1.4.0.php @@ -0,0 +1,27 @@ +clear(); + + $result = true; + + $sql[] = 'ALTER TABLE `' . _DB_PREFIX_ . 'empik_product` ADD COLUMN `condition` INT(4) NOT NULL DEFAULT 11 AFTER `logistic_class`;'; + + foreach ($sql as $query) { + $result &= Db::getInstance()->execute($query); + } + + return $result; +} diff --git a/modules/empikmarketplace/vendor/.htaccess b/modules/empikmarketplace/vendor/.htaccess new file mode 100644 index 00000000..3de9e400 --- /dev/null +++ b/modules/empikmarketplace/vendor/.htaccess @@ -0,0 +1,10 @@ +# Apache 2.2 + + Order deny,allow + Deny from all + + +# Apache 2.4 + + Require all denied + diff --git a/modules/empikmarketplace/vendor/autoload.php b/modules/empikmarketplace/vendor/autoload.php new file mode 100644 index 00000000..ab697949 --- /dev/null +++ b/modules/empikmarketplace/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/modules/empikmarketplace/vendor/composer/InstalledVersions.php b/modules/empikmarketplace/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..d50e0c9f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/InstalledVersions.php @@ -0,0 +1,350 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']); + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints($constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php'; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = require __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + $installed[] = self::$installed; + + return $installed; + } +} diff --git a/modules/empikmarketplace/vendor/composer/LICENSE b/modules/empikmarketplace/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/modules/empikmarketplace/vendor/composer/autoload_classmap.php b/modules/empikmarketplace/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..b23c667e --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/autoload_classmap.php @@ -0,0 +1,20 @@ + $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', + 'AssertionError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php', + 'DivisionByZeroError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php', + 'EmpikAction' => $baseDir . '/classes/EmpikAction.php', + 'EmpikActionLog' => $baseDir . '/classes/EmpikActionLog.php', + 'EmpikOrder' => $baseDir . '/classes/EmpikOrder.php', + 'EmpikProduct' => $baseDir . '/classes/EmpikProduct.php', + 'Error' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/Error.php', + 'ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php', + 'SessionUpdateTimestampHandlerInterface' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php', + 'TypeError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/TypeError.php', +); diff --git a/modules/empikmarketplace/vendor/composer/autoload_files.php b/modules/empikmarketplace/vendor/composer/autoload_files.php new file mode 100644 index 00000000..893a137b --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/autoload_files.php @@ -0,0 +1,14 @@ + $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php', + '32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php', + '023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php', + 'ad155f8f1cf0d418fe49e248db8c661b' => $vendorDir . '/react/promise/src/functions_include.php', +); diff --git a/modules/empikmarketplace/vendor/composer/autoload_namespaces.php b/modules/empikmarketplace/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..b7fc0125 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/symfony/polyfill-php70'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Symfony\\Polyfill\\Apcu\\' => array($vendorDir . '/symfony/polyfill-apcu'), + 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), + 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'), + 'Symfony\\Component\\ExpressionLanguage\\' => array($vendorDir . '/symfony/expression-language'), + 'Symfony\\Component\\DependencyInjection\\' => array($vendorDir . '/symfony/dependency-injection'), + 'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'), + 'Symfony\\Component\\Cache\\' => array($vendorDir . '/symfony/cache'), + 'React\\Promise\\' => array($vendorDir . '/react/promise/src'), + 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), + 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), + 'PrestaShop\\ModuleLibServiceContainer\\' => array($vendorDir . '/prestashop/module-lib-service-container/src'), + 'PrestaShop\\ModuleLibCacheDirectoryProvider\\' => array($vendorDir . '/prestashop/module-lib-cache-directory-provider/src'), + 'GuzzleHttp\\Stream\\' => array($vendorDir . '/guzzlehttp/streams/src'), + 'GuzzleHttp\\Ring\\' => array($vendorDir . '/guzzlehttp/ringphp/src'), + 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), + 'Empik\\Marketplace\\' => array($baseDir . '/src'), + 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), +); diff --git a/modules/empikmarketplace/vendor/composer/autoload_real.php b/modules/empikmarketplace/vendor/composer/autoload_real.php new file mode 100644 index 00000000..1f8f69b4 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/autoload_real.php @@ -0,0 +1,73 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit245c4a2a3c66452037dc17f6dafa78a8::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(false); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit245c4a2a3c66452037dc17f6dafa78a8::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire245c4a2a3c66452037dc17f6dafa78a8($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire245c4a2a3c66452037dc17f6dafa78a8($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/modules/empikmarketplace/vendor/composer/autoload_static.php b/modules/empikmarketplace/vendor/composer/autoload_static.php new file mode 100644 index 00000000..2fc57161 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/autoload_static.php @@ -0,0 +1,169 @@ + __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php', + '32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php', + '023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php', + 'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symfony\\Polyfill\\Php70\\' => 23, + 'Symfony\\Polyfill\\Ctype\\' => 23, + 'Symfony\\Polyfill\\Apcu\\' => 22, + 'Symfony\\Component\\Yaml\\' => 23, + 'Symfony\\Component\\Filesystem\\' => 29, + 'Symfony\\Component\\ExpressionLanguage\\' => 37, + 'Symfony\\Component\\DependencyInjection\\' => 38, + 'Symfony\\Component\\Config\\' => 25, + 'Symfony\\Component\\Cache\\' => 24, + ), + 'R' => + array ( + 'React\\Promise\\' => 14, + ), + 'P' => + array ( + 'Psr\\SimpleCache\\' => 16, + 'Psr\\Log\\' => 8, + 'Psr\\Container\\' => 14, + 'Psr\\Cache\\' => 10, + 'PrestaShop\\ModuleLibServiceContainer\\' => 37, + 'PrestaShop\\ModuleLibCacheDirectoryProvider\\' => 43, + ), + 'G' => + array ( + 'GuzzleHttp\\Stream\\' => 18, + 'GuzzleHttp\\Ring\\' => 16, + 'GuzzleHttp\\' => 11, + ), + 'E' => + array ( + 'Empik\\Marketplace\\' => 18, + ), + 'C' => + array ( + 'Composer\\Installers\\' => 20, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Php70\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php70', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'Symfony\\Polyfill\\Apcu\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-apcu', + ), + 'Symfony\\Component\\Yaml\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/yaml', + ), + 'Symfony\\Component\\Filesystem\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/filesystem', + ), + 'Symfony\\Component\\ExpressionLanguage\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/expression-language', + ), + 'Symfony\\Component\\DependencyInjection\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/dependency-injection', + ), + 'Symfony\\Component\\Config\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/config', + ), + 'Symfony\\Component\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/cache', + ), + 'React\\Promise\\' => + array ( + 0 => __DIR__ . '/..' . '/react/promise/src', + ), + 'Psr\\SimpleCache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/simple-cache/src', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'Psr\\Container\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/container/src', + ), + 'Psr\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/cache/src', + ), + 'PrestaShop\\ModuleLibServiceContainer\\' => + array ( + 0 => __DIR__ . '/..' . '/prestashop/module-lib-service-container/src', + ), + 'PrestaShop\\ModuleLibCacheDirectoryProvider\\' => + array ( + 0 => __DIR__ . '/..' . '/prestashop/module-lib-cache-directory-provider/src', + ), + 'GuzzleHttp\\Stream\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/streams/src', + ), + 'GuzzleHttp\\Ring\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/ringphp/src', + ), + 'GuzzleHttp\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', + ), + 'Empik\\Marketplace\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + 'Composer\\Installers\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', + ), + ); + + public static $classMap = array ( + 'ArithmeticError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php', + 'AssertionError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/AssertionError.php', + 'DivisionByZeroError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php', + 'EmpikAction' => __DIR__ . '/../..' . '/classes/EmpikAction.php', + 'EmpikActionLog' => __DIR__ . '/../..' . '/classes/EmpikActionLog.php', + 'EmpikOrder' => __DIR__ . '/../..' . '/classes/EmpikOrder.php', + 'EmpikProduct' => __DIR__ . '/../..' . '/classes/EmpikProduct.php', + 'Error' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/Error.php', + 'ParseError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/ParseError.php', + 'SessionUpdateTimestampHandlerInterface' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php', + 'TypeError' => __DIR__ . '/..' . '/symfony/polyfill-php70/Resources/stubs/TypeError.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit245c4a2a3c66452037dc17f6dafa78a8::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit245c4a2a3c66452037dc17f6dafa78a8::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit245c4a2a3c66452037dc17f6dafa78a8::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/modules/empikmarketplace/vendor/composer/installed.json b/modules/empikmarketplace/vendor/composer/installed.json new file mode 100644 index 00000000..ad1d99e1 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installed.json @@ -0,0 +1,1399 @@ +[ + { + "name": "composer/installers", + "version": "v1.12.0", + "version_normalized": "1.12.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.3" + }, + "time": "2021-09-13T08:19:44+00:00", + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Starbug", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "miaoxing", + "modulework", + "modx", + "moodle", + "osclass", + "pantheon", + "phpbb", + "piwik", + "ppi", + "processwire", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "tastyigniter", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ] + }, + { + "name": "guzzlehttp/guzzle", + "version": "5.3.3", + "version_normalized": "5.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "93bbdb30d59be6cd9839495306c65f2907370eb9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/93bbdb30d59be6cd9839495306c65f2907370eb9", + "reference": "93bbdb30d59be6cd9839495306c65f2907370eb9", + "shasum": "" + }, + "require": { + "guzzlehttp/ringphp": "^1.1", + "php": ">=5.4.0", + "react/promise": "^2.2" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0" + }, + "time": "2018-07-31T13:33:10+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ] + }, + { + "name": "guzzlehttp/ringphp", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/RingPHP.git", + "reference": "5e2a174052995663dd68e6b5ad838afd47dd615b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/5e2a174052995663dd68e6b5ad838afd47dd615b", + "reference": "5e2a174052995663dd68e6b5ad838afd47dd615b", + "shasum": "" + }, + "require": { + "guzzlehttp/streams": "~3.0", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "time": "2018-07-31T13:22:33+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", + "abandoned": true + }, + { + "name": "guzzlehttp/streams", + "version": "3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "time": "2014-10-12T19:18:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "abandoned": true + }, + { + "name": "paragonie/random_compat", + "version": "v2.0.21", + "version_normalized": "2.0.21.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/96c132c7f2f7bc3230723b66e89f8f150b29d5ae", + "reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2022-02-16T17:07:03+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ] + }, + { + "name": "prestashop/module-lib-cache-directory-provider", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/PrestaShopCorp/module-lib-cache-directory-provider.git", + "reference": "34a577b66a7e52ae16d6f40efd1db17290bad453" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PrestaShopCorp/module-lib-cache-directory-provider/zipball/34a577b66a7e52ae16d6f40efd1db17290bad453", + "reference": "34a577b66a7e52ae16d6f40efd1db17290bad453", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "time": "2020-09-08T14:13:23+00:00", + "type": "project", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibCacheDirectoryProvider\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AFL-3.0" + ], + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "description": "Cache directory provider to use on prestashop modules", + "keywords": [ + "composer", + "modules", + "package", + "prestashop" + ] + }, + { + "name": "prestashop/module-lib-service-container", + "version": "1.4.0", + "version_normalized": "1.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/PrestaShopCorp/module-lib-service-container.git", + "reference": "96f4f551b96cffb1f78462cd4722f0d2b057abda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PrestaShopCorp/module-lib-service-container/zipball/96f4f551b96cffb1f78462cd4722f0d2b057abda", + "reference": "96f4f551b96cffb1f78462cd4722f0d2b057abda", + "shasum": "" + }, + "require": { + "php": ">=5.6.0", + "prestashop/module-lib-cache-directory-provider": "^1.0", + "symfony/config": "^3.4", + "symfony/dependency-injection": "^3.4", + "symfony/expression-language": "^3.4", + "symfony/yaml": "^3.4" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "time": "2021-06-01T15:21:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibServiceContainer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AFL-3.0" + ], + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "description": "Service container to use on prestashop modules", + "keywords": [ + "composer", + "modules", + "package", + "prestashop" + ] + }, + { + "name": "psr/cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2016-08-06T20:24:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ] + }, + { + "name": "psr/container", + "version": "1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2017-02-14T16:28:37+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ] + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2017-10-23T01:57:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ] + }, + { + "name": "react/promise", + "version": "v2.9.0", + "version_normalized": "2.9.0.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "time": "2022-02-11T10:27:51+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "React\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ] + }, + { + "name": "symfony/cache", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/a7a14c4832760bd1fbd31be2859ffedc9b6ff813", + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "symfony/polyfill-apcu": "~1.1" + }, + "conflict": { + "symfony/var-dumper": "<3.3" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/config", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f", + "reference": "bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/filesystem": "~2.8|~3.0|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3", + "symfony/finder": "<3.3" + }, + "require-dev": { + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0", + "symfony/finder": "~3.3|~4.0", + "symfony/yaml": "~3.0|~4.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/dependency-injection", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "51d2a2708c6ceadad84393f8581df1dcf9e5e84b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/51d2a2708c6ceadad84393f8581df1dcf9e5e84b", + "reference": "51d2a2708c6ceadad84393f8581df1dcf9e5e84b", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/expression-language", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ExpressionLanguage Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/filesystem", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/polyfill-apcu", + "version": "v1.19.0", + "version_normalized": "1.19.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-apcu.git", + "reference": "b44b51e7814c23bfbd793a16ead5d7ce43ed23c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/b44b51e7814c23bfbd793a16ead5d7ce43ed23c5", + "reference": "b44b51e7814c23bfbd793a16ead5d7ce43ed23c5", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2020-10-21T09:57:48+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Apcu\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "apcu", + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.19.0", + "version_normalized": "1.19.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", + "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2020-10-23T09:01:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "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" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.19.0", + "version_normalized": "1.19.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "time": "2020-10-23T09:01:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/yaml", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "88289caa3c166321883f67fe5130188ebbb47094" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", + "reference": "88289caa3c166321883f67fe5130188ebbb47094", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + } +] diff --git a/modules/empikmarketplace/vendor/composer/installed.php b/modules/empikmarketplace/vendor/composer/installed.php new file mode 100644 index 00000000..414cf72a --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installed.php @@ -0,0 +1,242 @@ + array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'type' => 'prestashop-module', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'name' => 'waynet/empik', + 'dev' => true, + ), + 'versions' => array( + 'composer/installers' => array( + 'pretty_version' => 'v1.12.0', + 'version' => '1.12.0.0', + 'type' => 'composer-plugin', + 'install_path' => __DIR__ . '/./installers', + 'aliases' => array(), + 'reference' => 'd20a64ed3c94748397ff5973488761b22f6d3f19', + 'dev_requirement' => false, + ), + 'guzzlehttp/guzzle' => array( + 'pretty_version' => '5.3.3', + 'version' => '5.3.3.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', + 'aliases' => array(), + 'reference' => '93bbdb30d59be6cd9839495306c65f2907370eb9', + 'dev_requirement' => false, + ), + 'guzzlehttp/ringphp' => array( + 'pretty_version' => '1.1.1', + 'version' => '1.1.1.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/ringphp', + 'aliases' => array(), + 'reference' => '5e2a174052995663dd68e6b5ad838afd47dd615b', + 'dev_requirement' => false, + ), + 'guzzlehttp/streams' => array( + 'pretty_version' => '3.0.0', + 'version' => '3.0.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/streams', + 'aliases' => array(), + 'reference' => '47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5', + 'dev_requirement' => false, + ), + 'paragonie/random_compat' => array( + 'pretty_version' => 'v2.0.20', + 'version' => '2.0.20.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/random_compat', + 'aliases' => array(), + 'reference' => '0f1f60250fccffeaf5dda91eea1c018aed1adc2a', + 'dev_requirement' => false, + ), + 'prestashop/module-lib-cache-directory-provider' => array( + 'pretty_version' => 'v1.0.0', + 'version' => '1.0.0.0', + 'type' => 'project', + 'install_path' => __DIR__ . '/../prestashop/module-lib-cache-directory-provider', + 'aliases' => array(), + 'reference' => '34a577b66a7e52ae16d6f40efd1db17290bad453', + 'dev_requirement' => false, + ), + 'prestashop/module-lib-service-container' => array( + 'pretty_version' => '1.4.0', + 'version' => '1.4.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../prestashop/module-lib-service-container', + 'aliases' => array(), + 'reference' => '96f4f551b96cffb1f78462cd4722f0d2b057abda', + 'dev_requirement' => false, + ), + 'psr/cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/cache', + 'aliases' => array(), + 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'dev_requirement' => false, + ), + 'psr/cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/container' => array( + 'pretty_version' => '1.0.0', + 'version' => '1.0.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'reference' => 'b7ce3b176482dbbc1245ebf52b181af44c2cf55f', + 'dev_requirement' => false, + ), + 'psr/container-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'dev_requirement' => false, + ), + 'psr/simple-cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/simple-cache', + 'aliases' => array(), + 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', + 'dev_requirement' => false, + ), + 'psr/simple-cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0', + ), + ), + 'react/promise' => array( + 'pretty_version' => 'v2.9.0', + 'version' => '2.9.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../react/promise', + 'aliases' => array(), + 'reference' => '234f8fd1023c9158e2314fa9d7d0e6a83db42910', + 'dev_requirement' => false, + ), + 'roundcube/plugin-installer' => array( + 'dev_requirement' => false, + 'replaced' => array( + 0 => '*', + ), + ), + 'shama/baton' => array( + 'dev_requirement' => false, + 'replaced' => array( + 0 => '*', + ), + ), + 'symfony/cache' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/cache', + 'aliases' => array(), + 'reference' => 'a7a14c4832760bd1fbd31be2859ffedc9b6ff813', + 'dev_requirement' => false, + ), + 'symfony/config' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/config', + 'aliases' => array(), + 'reference' => 'bc6b3fd3930d4b53a60b42fe2ed6fc466b75f03f', + 'dev_requirement' => false, + ), + 'symfony/dependency-injection' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/dependency-injection', + 'aliases' => array(), + 'reference' => '51d2a2708c6ceadad84393f8581df1dcf9e5e84b', + 'dev_requirement' => false, + ), + 'symfony/expression-language' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/expression-language', + 'aliases' => array(), + 'reference' => 'de38e66398fca1fcb9c48e80279910e6889cb28f', + 'dev_requirement' => false, + ), + 'symfony/filesystem' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/filesystem', + 'aliases' => array(), + 'reference' => 'e58d7841cddfed6e846829040dca2cca0ebbbbb3', + 'dev_requirement' => false, + ), + 'symfony/polyfill-apcu' => array( + 'pretty_version' => 'v1.19.0', + 'version' => '1.19.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-apcu', + 'aliases' => array(), + 'reference' => 'b44b51e7814c23bfbd793a16ead5d7ce43ed23c5', + 'dev_requirement' => false, + ), + 'symfony/polyfill-ctype' => array( + 'pretty_version' => 'v1.19.0', + 'version' => '1.19.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', + 'aliases' => array(), + 'reference' => 'aed596913b70fae57be53d86faa2e9ef85a2297b', + 'dev_requirement' => false, + ), + 'symfony/polyfill-php70' => array( + 'pretty_version' => 'v1.19.0', + 'version' => '1.19.0.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php70', + 'aliases' => array(), + 'reference' => '3fe414077251a81a1b15b1c709faf5c2fbae3d4e', + 'dev_requirement' => false, + ), + 'symfony/yaml' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/yaml', + 'aliases' => array(), + 'reference' => '88289caa3c166321883f67fe5130188ebbb47094', + 'dev_requirement' => false, + ), + 'waynet/empik' => array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'type' => 'prestashop-module', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'reference' => NULL, + 'dev_requirement' => false, + ), + ), +); diff --git a/modules/empikmarketplace/vendor/composer/installers/.github/workflows/continuous-integration.yml b/modules/empikmarketplace/vendor/composer/installers/.github/workflows/continuous-integration.yml new file mode 100644 index 00000000..34b8f91f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/.github/workflows/continuous-integration.yml @@ -0,0 +1,76 @@ +name: "Continuous Integration" + +on: + - push + - pull_request + +env: + COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist" + SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT: "1" + +jobs: + tests: + name: "CI" + + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: + - "5.3" + - "5.4" + - "5.5" + - "5.6" + - "7.0" + - "7.1" + - "7.2" + - "7.3" + - "7.4" + - "8.0" + - "8.1" + dependencies: [locked] + include: + - php-version: "5.3" + dependencies: lowest + - php-version: "8.1" + dependencies: lowest + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + tools: composer:snapshot + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: "Handle lowest dependencies update" + if: "contains(matrix.dependencies, 'lowest')" + run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV" + + - name: "Upgrade phpunit-bridge if needed for php 8 lowest build" + if: "contains(matrix.php-version, '8.')" + run: | + composer require symfony/phpunit-bridge:^5.3.3 --dev --no-update + + - name: "Install latest dependencies" + run: | + # Remove PHPStan as it requires a newer PHP + composer remove phpstan/phpstan phpstan/phpstan-phpunit --dev --no-update + composer update ${{ env.COMPOSER_FLAGS }} + + - name: "Run tests" + run: "vendor/bin/simple-phpunit --verbose" diff --git a/modules/empikmarketplace/vendor/composer/installers/.github/workflows/lint.yml b/modules/empikmarketplace/vendor/composer/installers/.github/workflows/lint.yml new file mode 100644 index 00000000..81a1ac4d --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/.github/workflows/lint.yml @@ -0,0 +1,30 @@ +name: "PHP Lint" + +on: + - push + - pull_request + +jobs: + tests: + name: "Lint" + + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: + - "5.3" + - "8.0" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + + - name: "Lint PHP files" + run: "find src/ -type f -name '*.php' -print0 | xargs -0 -L1 -P4 -- php -l -f" diff --git a/modules/empikmarketplace/vendor/composer/installers/.github/workflows/phpstan.yml b/modules/empikmarketplace/vendor/composer/installers/.github/workflows/phpstan.yml new file mode 100644 index 00000000..ac4c4a92 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/.github/workflows/phpstan.yml @@ -0,0 +1,51 @@ +name: "PHPStan" + +on: + - push + - pull_request + +env: + COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist" + SYMFONY_PHPUNIT_VERSION: "" + +jobs: + tests: + name: "PHPStan" + + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: + # pinned to 7.4 because we need PHPUnit 7.5 which does not support PHP 8 + - "7.4" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2" + + - name: "Install PHP" + uses: "shivammathur/setup-php@v2" + with: + coverage: "none" + php-version: "${{ matrix.php-version }}" + + - name: Get composer cache directory + id: composercache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: "Install latest dependencies" + run: "composer update ${{ env.COMPOSER_FLAGS }}" + + - name: Run PHPStan + # Locked to phpunit 7.5 here as newer ones have void return types which break inheritance + run: | + composer require --dev phpunit/phpunit:^7.5.20 --with-all-dependencies ${{ env.COMPOSER_FLAGS }} + vendor/bin/phpstan analyse diff --git a/modules/empikmarketplace/vendor/composer/installers/LICENSE b/modules/empikmarketplace/vendor/composer/installers/LICENSE new file mode 100644 index 00000000..85f97fc7 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Kyle Robinson Young + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/composer/installers/composer.json b/modules/empikmarketplace/vendor/composer/installers/composer.json new file mode 100644 index 00000000..4a7fd3c3 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/composer.json @@ -0,0 +1,122 @@ +{ + "name": "composer/installers", + "type": "composer-plugin", + "license": "MIT", + "description": "A multi-framework Composer library installer", + "keywords": [ + "installer", + "Aimeos", + "AGL", + "AnnotateCms", + "Attogram", + "Bitrix", + "CakePHP", + "Chef", + "Cockpit", + "CodeIgniter", + "concrete5", + "Craft", + "Croogo", + "DokuWiki", + "Dolibarr", + "Drupal", + "Elgg", + "Eliasis", + "ExpressionEngine", + "eZ Platform", + "FuelPHP", + "Grav", + "Hurad", + "ImageCMS", + "iTop", + "Joomla", + "Kanboard", + "Known", + "Kohana", + "Lan Management System", + "Laravel", + "Lavalite", + "Lithium", + "Magento", + "majima", + "Mako", + "MantisBT", + "Mautic", + "Maya", + "MODX", + "MODX Evo", + "MediaWiki", + "Miaoxing", + "OXID", + "osclass", + "MODULEWork", + "Moodle", + "Pantheon", + "Piwik", + "pxcms", + "phpBB", + "Plentymarkets", + "PPI", + "Puppet", + "Porto", + "ProcessWire", + "RadPHP", + "ReIndex", + "Roundcube", + "shopware", + "SilverStripe", + "SMF", + "Starbug", + "SyDES", + "Sylius", + "symfony", + "TastyIgniter", + "Thelia", + "TYPO3", + "WHMCS", + "WolfCMS", + "WordPress", + "YAWIK", + "Zend", + "Zikula" + ], + "homepage": "https://composer.github.io/installers/", + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "autoload": { + "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" } + }, + "autoload-dev": { + "psr-4": { "Composer\\Installers\\Test\\": "tests/Composer/Installers/Test" } + }, + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "replace": { + "shama/baton": "*", + "roundcube/plugin-installer": "*" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "symfony/phpunit-bridge": "^4.2 || ^5", + "phpstan/phpstan": "^0.12.55", + "symfony/process": "^2.3", + "phpstan/phpstan-phpunit": "^0.12.16" + }, + "scripts": { + "test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit", + "phpstan": "vendor/bin/phpstan analyse" + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/phpstan.neon.dist b/modules/empikmarketplace/vendor/composer/installers/phpstan.neon.dist new file mode 100644 index 00000000..8e3d81e9 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/phpstan.neon.dist @@ -0,0 +1,10 @@ +parameters: + level: 5 + paths: + - src + - tests + excludes_analyse: + - tests/Composer/Installers/Test/PolyfillTestCase.php + +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AglInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AglInstaller.php new file mode 100644 index 00000000..01b8a416 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AglInstaller.php @@ -0,0 +1,21 @@ + 'More/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) { + return strtoupper($matches[1]); + }, $vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php new file mode 100644 index 00000000..79a0e958 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AimeosInstaller.php @@ -0,0 +1,9 @@ + 'ext/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php new file mode 100644 index 00000000..89d7ad90 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php @@ -0,0 +1,11 @@ + 'addons/modules/{$name}/', + 'component' => 'addons/components/{$name}/', + 'service' => 'addons/services/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php new file mode 100644 index 00000000..22dad1b9 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php @@ -0,0 +1,49 @@ + 'Modules/{$name}/', + 'theme' => 'Themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type asgard-module, cut off a trailing '-plugin' if present. + * + * For package type asgard-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'asgard-module') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'asgard-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php new file mode 100644 index 00000000..d62fd8fd --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php new file mode 100644 index 00000000..70dde907 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BaseInstaller.php @@ -0,0 +1,137 @@ +composer = $composer; + $this->package = $package; + $this->io = $io; + } + + /** + * Return the install path based on package type. + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $type = $this->package->getType(); + + $prettyName = $this->package->getPrettyName(); + if (strpos($prettyName, '/') !== false) { + list($vendor, $name) = explode('/', $prettyName); + } else { + $vendor = ''; + $name = $prettyName; + } + + $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type')); + + $extra = $package->getExtra(); + if (!empty($extra['installer-name'])) { + $availableVars['name'] = $extra['installer-name']; + } + + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + if (!empty($extra['installer-paths'])) { + $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); + if ($customPath !== false) { + return $this->templatePath($customPath, $availableVars); + } + } + } + + $packageType = substr($type, strlen($frameworkType) + 1); + $locations = $this->getLocations(); + if (!isset($locations[$packageType])) { + throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type)); + } + + return $this->templatePath($locations[$packageType], $availableVars); + } + + /** + * For an installer to override to modify the vars per installer. + * + * @param array $vars This will normally receive array{name: string, vendor: string, type: string} + * @return array + */ + public function inflectPackageVars($vars) + { + return $vars; + } + + /** + * Gets the installer's locations + * + * @return array map of package types => install path + */ + public function getLocations() + { + return $this->locations; + } + + /** + * Replace vars in a path + * + * @param string $path + * @param array $vars + * @return string + */ + protected function templatePath($path, array $vars = array()) + { + if (strpos($path, '{') !== false) { + extract($vars); + preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches); + if (!empty($matches[1])) { + foreach ($matches[1] as $var) { + $path = str_replace('{$' . $var . '}', $$var, $path); + } + } + } + + return $path; + } + + /** + * Search through a passed paths array for a custom install path. + * + * @param array $paths + * @param string $name + * @param string $type + * @param string $vendor = NULL + * @return string|false + */ + protected function mapCustomInstallPaths(array $paths, $name, $type, $vendor = NULL) + { + foreach ($paths as $path => $names) { + $names = (array) $names; + if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) { + return $path; + } + } + + return false; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php new file mode 100644 index 00000000..e80cd1e1 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php @@ -0,0 +1,126 @@ +.`. + * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`. + * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`. + * + * You can set custom path to directory with Bitrix kernel in `composer.json`: + * + * ```json + * { + * "extra": { + * "bitrix-dir": "s1/bitrix" + * } + * } + * ``` + * + * @author Nik Samokhvalov + * @author Denis Kulichkin + */ +class BitrixInstaller extends BaseInstaller +{ + protected $locations = array( + 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) + 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/', + 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/', + 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/', + ); + + /** + * @var array Storage for informations about duplicates at all the time of installation packages. + */ + private static $checkedDuplicates = array(); + + /** + * {@inheritdoc} + */ + public function inflectPackageVars($vars) + { + if ($this->composer->getPackage()) { + $extra = $this->composer->getPackage()->getExtra(); + + if (isset($extra['bitrix-dir'])) { + $vars['bitrix_dir'] = $extra['bitrix-dir']; + } + } + + if (!isset($vars['bitrix_dir'])) { + $vars['bitrix_dir'] = 'bitrix'; + } + + return parent::inflectPackageVars($vars); + } + + /** + * {@inheritdoc} + */ + protected function templatePath($path, array $vars = array()) + { + $templatePath = parent::templatePath($path, $vars); + $this->checkDuplicates($templatePath, $vars); + + return $templatePath; + } + + /** + * Duplicates search packages. + * + * @param string $path + * @param array $vars + */ + protected function checkDuplicates($path, array $vars = array()) + { + $packageType = substr($vars['type'], strlen('bitrix') + 1); + $localDir = explode('/', $vars['bitrix_dir']); + array_pop($localDir); + $localDir[] = 'local'; + $localDir = implode('/', $localDir); + + $oldPath = str_replace( + array('{$bitrix_dir}', '{$name}'), + array($localDir, $vars['name']), + $this->locations[$packageType] + ); + + if (in_array($oldPath, static::$checkedDuplicates)) { + return; + } + + if ($oldPath !== $path && file_exists($oldPath) && $this->io && $this->io->isInteractive()) { + + $this->io->writeError(' Duplication of packages:'); + $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ''); + + while (true) { + switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) { + case 'y': + $fs = new Filesystem(); + $fs->removeDirectory($oldPath); + break 2; + + case 'n': + break 2; + + case '?': + default: + $this->io->writeError(array( + ' y - delete package ' . $oldPath . ' and to continue with the installation', + ' n - don\'t delete and to continue with the installation', + )); + $this->io->writeError(' ? - print help'); + break; + } + } + } + + static::$checkedDuplicates[] = $oldPath; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php new file mode 100644 index 00000000..da3aad2a --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php @@ -0,0 +1,9 @@ + 'Packages/{$vendor}/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php new file mode 100644 index 00000000..1e2ddd02 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php @@ -0,0 +1,66 @@ + 'Plugin/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + if ($this->matchesCakeVersion('>=', '3.0.0')) { + return $vars; + } + + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + + return $vars; + } + + /** + * Change the default plugin location when cakephp >= 3.0 + */ + public function getLocations() + { + if ($this->matchesCakeVersion('>=', '3.0.0')) { + $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/'; + } + return $this->locations; + } + + /** + * Check if CakePHP version matches against a version + * + * @param string $matcher + * @param string $version + * @return bool + * @phpstan-param Constraint::STR_OP_* $matcher + */ + protected function matchesCakeVersion($matcher, $version) + { + $repositoryManager = $this->composer->getRepositoryManager(); + if (! $repositoryManager) { + return false; + } + + $repos = $repositoryManager->getLocalRepository(); + if (!$repos) { + return false; + } + + return $repos->findPackage('cakephp/cakephp', new Constraint($matcher, $version)) !== null; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php new file mode 100644 index 00000000..ab2f9aad --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ChefInstaller.php @@ -0,0 +1,11 @@ + 'Chef/{$vendor}/{$name}/', + 'role' => 'Chef/roles/{$name}/', + ); +} + diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php new file mode 100644 index 00000000..6673aea9 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php @@ -0,0 +1,9 @@ + 'ext/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php new file mode 100644 index 00000000..c887815c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php @@ -0,0 +1,10 @@ + 'CCF/orbit/{$name}/', + 'theme' => 'CCF/app/themes/{$name}/', + ); +} \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php new file mode 100644 index 00000000..053f3ffd --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php @@ -0,0 +1,32 @@ + 'cockpit/modules/addons/{$name}/', + ); + + /** + * Format module name. + * + * Strip `module-` prefix from package name. + * + * {@inheritDoc} + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'cockpit-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = ucfirst(preg_replace('/cockpit-/i', '', $vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php new file mode 100644 index 00000000..3b4a4ece --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php @@ -0,0 +1,11 @@ + 'application/libraries/{$name}/', + 'third-party' => 'application/third_party/{$name}/', + 'module' => 'application/modules/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php new file mode 100644 index 00000000..5c01bafd --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php @@ -0,0 +1,13 @@ + 'concrete/', + 'block' => 'application/blocks/{$name}/', + 'package' => 'packages/{$name}/', + 'theme' => 'application/themes/{$name}/', + 'update' => 'updates/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php new file mode 100644 index 00000000..d37a77ae --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CraftInstaller.php @@ -0,0 +1,35 @@ + 'craft/plugins/{$name}/', + ); + + /** + * Strip `craft-` prefix and/or `-plugin` suffix from package names + * + * @param array $vars + * + * @return array + */ + final public function inflectPackageVars($vars) + { + return $this->inflectPluginVars($vars); + } + + private function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-' . self::NAME_SUFFIX . '$/i', '', $vars['name']); + $vars['name'] = preg_replace('/^' . self::NAME_PREFIX . '-/i', '', $vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php new file mode 100644 index 00000000..d94219d3 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php @@ -0,0 +1,21 @@ + 'Plugin/{$name}/', + 'theme' => 'View/Themed/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name'])); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php new file mode 100644 index 00000000..f4837a6c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php @@ -0,0 +1,10 @@ + 'app/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php new file mode 100644 index 00000000..70788163 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DframeInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$vendor}/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php new file mode 100644 index 00000000..cfd638d5 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php @@ -0,0 +1,50 @@ + 'lib/plugins/{$name}/', + 'template' => 'lib/tpl/{$name}/', + ); + + /** + * Format package name. + * + * For package type dokuwiki-plugin, cut off a trailing '-plugin', + * or leading dokuwiki_ if present. + * + * For package type dokuwiki-template, cut off a trailing '-template' if present. + * + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] === 'dokuwiki-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'dokuwiki-template') { + return $this->inflectTemplateVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-plugin$/', '', $vars['name']); + $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + + return $vars; + } + + protected function inflectTemplateVars($vars) + { + $vars['name'] = preg_replace('/-template$/', '', $vars['name']); + $vars['name'] = preg_replace('/^dokuwiki_?-?/', '', $vars['name']); + + return $vars; + } + +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php new file mode 100644 index 00000000..21f7e8e8 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php @@ -0,0 +1,16 @@ + + */ +class DolibarrInstaller extends BaseInstaller +{ + //TODO: Add support for scripts and themes + protected $locations = array( + 'module' => 'htdocs/custom/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php new file mode 100644 index 00000000..73282392 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php @@ -0,0 +1,22 @@ + 'core/', + 'module' => 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + 'library' => 'libraries/{$name}/', + 'profile' => 'profiles/{$name}/', + 'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/', + 'drush' => 'drush/{$name}/', + 'custom-theme' => 'themes/custom/{$name}/', + 'custom-module' => 'modules/custom/{$name}/', + 'custom-profile' => 'profiles/custom/{$name}/', + 'drupal-multisite' => 'sites/{$name}/', + 'console' => 'console/{$name}/', + 'console-language' => 'console/language/{$name}/', + 'config' => 'config/sync/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php new file mode 100644 index 00000000..c0bb609f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ElggInstaller.php @@ -0,0 +1,9 @@ + 'mod/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php new file mode 100644 index 00000000..6f3dc97b --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php @@ -0,0 +1,12 @@ + 'components/{$name}/', + 'module' => 'modules/{$name}/', + 'plugin' => 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php new file mode 100644 index 00000000..d5321a8c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php @@ -0,0 +1,29 @@ + 'system/expressionengine/third_party/{$name}/', + 'theme' => 'themes/third_party/{$name}/', + ); + + private $ee3Locations = array( + 'addon' => 'system/user/addons/{$name}/', + 'theme' => 'themes/user/{$name}/', + ); + + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + + $version = "{$frameworkType}Locations"; + $this->locations = $this->$version; + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php new file mode 100644 index 00000000..f30ebcc7 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php @@ -0,0 +1,10 @@ + 'web/assets/ezplatform/', + 'assets' => 'web/assets/ezplatform/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php new file mode 100644 index 00000000..6eba2e34 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/FuelInstaller.php @@ -0,0 +1,11 @@ + 'fuel/app/modules/{$name}/', + 'package' => 'fuel/packages/{$name}/', + 'theme' => 'fuel/app/themes/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php new file mode 100644 index 00000000..29d980b3 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php @@ -0,0 +1,9 @@ + 'components/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/GravInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/GravInstaller.php new file mode 100644 index 00000000..dbe63e07 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/GravInstaller.php @@ -0,0 +1,30 @@ + 'user/plugins/{$name}/', + 'theme' => 'user/themes/{$name}/', + ); + + /** + * Format package name + * + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $restrictedWords = implode('|', array_keys($this->locations)); + + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui', + '$1', + $vars['name'] + ); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php new file mode 100644 index 00000000..8fe017f0 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/HuradInstaller.php @@ -0,0 +1,25 @@ + 'plugins/{$name}/', + 'theme' => 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php new file mode 100644 index 00000000..5e2142ea --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php @@ -0,0 +1,11 @@ + 'templates/{$name}/', + 'module' => 'application/modules/{$name}/', + 'library' => 'application/libraries/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Installer.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Installer.php new file mode 100644 index 00000000..9c9c24f7 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Installer.php @@ -0,0 +1,298 @@ + 'AimeosInstaller', + 'asgard' => 'AsgardInstaller', + 'attogram' => 'AttogramInstaller', + 'agl' => 'AglInstaller', + 'annotatecms' => 'AnnotateCmsInstaller', + 'bitrix' => 'BitrixInstaller', + 'bonefish' => 'BonefishInstaller', + 'cakephp' => 'CakePHPInstaller', + 'chef' => 'ChefInstaller', + 'civicrm' => 'CiviCrmInstaller', + 'ccframework' => 'ClanCatsFrameworkInstaller', + 'cockpit' => 'CockpitInstaller', + 'codeigniter' => 'CodeIgniterInstaller', + 'concrete5' => 'Concrete5Installer', + 'craft' => 'CraftInstaller', + 'croogo' => 'CroogoInstaller', + 'dframe' => 'DframeInstaller', + 'dokuwiki' => 'DokuWikiInstaller', + 'dolibarr' => 'DolibarrInstaller', + 'decibel' => 'DecibelInstaller', + 'drupal' => 'DrupalInstaller', + 'elgg' => 'ElggInstaller', + 'eliasis' => 'EliasisInstaller', + 'ee3' => 'ExpressionEngineInstaller', + 'ee2' => 'ExpressionEngineInstaller', + 'ezplatform' => 'EzPlatformInstaller', + 'fuel' => 'FuelInstaller', + 'fuelphp' => 'FuelphpInstaller', + 'grav' => 'GravInstaller', + 'hurad' => 'HuradInstaller', + 'tastyigniter' => 'TastyIgniterInstaller', + 'imagecms' => 'ImageCMSInstaller', + 'itop' => 'ItopInstaller', + 'joomla' => 'JoomlaInstaller', + 'kanboard' => 'KanboardInstaller', + 'kirby' => 'KirbyInstaller', + 'known' => 'KnownInstaller', + 'kodicms' => 'KodiCMSInstaller', + 'kohana' => 'KohanaInstaller', + 'lms' => 'LanManagementSystemInstaller', + 'laravel' => 'LaravelInstaller', + 'lavalite' => 'LavaLiteInstaller', + 'lithium' => 'LithiumInstaller', + 'magento' => 'MagentoInstaller', + 'majima' => 'MajimaInstaller', + 'mantisbt' => 'MantisBTInstaller', + 'mako' => 'MakoInstaller', + 'maya' => 'MayaInstaller', + 'mautic' => 'MauticInstaller', + 'mediawiki' => 'MediaWikiInstaller', + 'miaoxing' => 'MiaoxingInstaller', + 'microweber' => 'MicroweberInstaller', + 'modulework' => 'MODULEWorkInstaller', + 'modx' => 'ModxInstaller', + 'modxevo' => 'MODXEvoInstaller', + 'moodle' => 'MoodleInstaller', + 'october' => 'OctoberInstaller', + 'ontowiki' => 'OntoWikiInstaller', + 'oxid' => 'OxidInstaller', + 'osclass' => 'OsclassInstaller', + 'pxcms' => 'PxcmsInstaller', + 'phpbb' => 'PhpBBInstaller', + 'pimcore' => 'PimcoreInstaller', + 'piwik' => 'PiwikInstaller', + 'plentymarkets'=> 'PlentymarketsInstaller', + 'ppi' => 'PPIInstaller', + 'puppet' => 'PuppetInstaller', + 'radphp' => 'RadPHPInstaller', + 'phifty' => 'PhiftyInstaller', + 'porto' => 'PortoInstaller', + 'processwire' => 'ProcessWireInstaller', + 'quicksilver' => 'PantheonInstaller', + 'redaxo' => 'RedaxoInstaller', + 'redaxo5' => 'Redaxo5Installer', + 'reindex' => 'ReIndexInstaller', + 'roundcube' => 'RoundcubeInstaller', + 'shopware' => 'ShopwareInstaller', + 'sitedirect' => 'SiteDirectInstaller', + 'silverstripe' => 'SilverStripeInstaller', + 'smf' => 'SMFInstaller', + 'starbug' => 'StarbugInstaller', + 'sydes' => 'SyDESInstaller', + 'sylius' => 'SyliusInstaller', + 'symfony1' => 'Symfony1Installer', + 'tao' => 'TaoInstaller', + 'thelia' => 'TheliaInstaller', + 'tusk' => 'TuskInstaller', + 'typo3-cms' => 'TYPO3CmsInstaller', + 'typo3-flow' => 'TYPO3FlowInstaller', + 'userfrosting' => 'UserFrostingInstaller', + 'vanilla' => 'VanillaInstaller', + 'whmcs' => 'WHMCSInstaller', + 'winter' => 'WinterInstaller', + 'wolfcms' => 'WolfCMSInstaller', + 'wordpress' => 'WordPressInstaller', + 'yawik' => 'YawikInstaller', + 'zend' => 'ZendInstaller', + 'zikula' => 'ZikulaInstaller', + 'prestashop' => 'PrestashopInstaller' + ); + + /** + * Installer constructor. + * + * Disables installers specified in main composer extra installer-disable + * list + * + * @param IOInterface $io + * @param Composer $composer + * @param string $type + * @param Filesystem|null $filesystem + * @param BinaryInstaller|null $binaryInstaller + */ + public function __construct( + IOInterface $io, + Composer $composer, + $type = 'library', + Filesystem $filesystem = null, + BinaryInstaller $binaryInstaller = null + ) { + parent::__construct($io, $composer, $type, $filesystem, + $binaryInstaller); + $this->removeDisabledInstallers(); + } + + /** + * {@inheritDoc} + */ + public function getInstallPath(PackageInterface $package) + { + $type = $package->getType(); + $frameworkType = $this->findFrameworkType($type); + + if ($frameworkType === false) { + throw new \InvalidArgumentException( + 'Sorry the package type of this package is not yet supported.' + ); + } + + $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + $installer = new $class($package, $this->composer, $this->getIO()); + + return $installer->getInstallPath($package, $frameworkType); + } + + public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) + { + $installPath = $this->getPackageBasePath($package); + $io = $this->io; + $outputStatus = function () use ($io, $installPath) { + $io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted')); + }; + + $promise = parent::uninstall($repo, $package); + + // Composer v2 might return a promise here + if ($promise instanceof PromiseInterface) { + return $promise->then($outputStatus); + } + + // If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async) + $outputStatus(); + + return null; + } + + /** + * {@inheritDoc} + */ + public function supports($packageType) + { + $frameworkType = $this->findFrameworkType($packageType); + + if ($frameworkType === false) { + return false; + } + + $locationPattern = $this->getLocationPattern($frameworkType); + + return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1; + } + + /** + * Finds a supported framework type if it exists and returns it + * + * @param string $type + * @return string|false + */ + protected function findFrameworkType($type) + { + krsort($this->supportedTypes); + + foreach ($this->supportedTypes as $key => $val) { + if ($key === substr($type, 0, strlen($key))) { + return substr($type, 0, strlen($key)); + } + } + + return false; + } + + /** + * Get the second part of the regular expression to check for support of a + * package type + * + * @param string $frameworkType + * @return string + */ + protected function getLocationPattern($frameworkType) + { + $pattern = false; + if (!empty($this->supportedTypes[$frameworkType])) { + $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; + /** @var BaseInstaller $framework */ + $framework = new $frameworkClass(null, $this->composer, $this->getIO()); + $locations = array_keys($framework->getLocations()); + $pattern = $locations ? '(' . implode('|', $locations) . ')' : false; + } + + return $pattern ? : '(\w+)'; + } + + /** + * Get I/O object + * + * @return IOInterface + */ + private function getIO() + { + return $this->io; + } + + /** + * Look for installers set to be disabled in composer's extra config and + * remove them from the list of supported installers. + * + * Globals: + * - true, "all", and "*" - disable all installers. + * - false - enable all installers (useful with + * wikimedia/composer-merge-plugin or similar) + * + * @return void + */ + protected function removeDisabledInstallers() + { + $extra = $this->composer->getPackage()->getExtra(); + + if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) { + // No installers are disabled + return; + } + + // Get installers to disable + $disable = $extra['installer-disable']; + + // Ensure $disabled is an array + if (!is_array($disable)) { + $disable = array($disable); + } + + // Check which installers should be disabled + $all = array(true, "all", "*"); + $intersect = array_intersect($all, $disable); + if (!empty($intersect)) { + // Disable all installers + $this->supportedTypes = array(); + } else { + // Disable specified installers + foreach ($disable as $key => $installer) { + if (is_string($installer) && key_exists($installer, $this->supportedTypes)) { + unset($this->supportedTypes[$installer]); + } + } + } + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php new file mode 100644 index 00000000..c6c1b337 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ItopInstaller.php @@ -0,0 +1,9 @@ + 'extensions/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php new file mode 100644 index 00000000..9ee77596 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/JoomlaInstaller.php @@ -0,0 +1,15 @@ + 'components/{$name}/', + 'module' => 'modules/{$name}/', + 'template' => 'templates/{$name}/', + 'plugin' => 'plugins/{$name}/', + 'library' => 'libraries/{$name}/', + ); + + // TODO: Add inflector for mod_ and com_ names +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php new file mode 100644 index 00000000..9cb7b8cd --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php @@ -0,0 +1,18 @@ + 'plugins/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php new file mode 100644 index 00000000..36b2f84a --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KirbyInstaller.php @@ -0,0 +1,11 @@ + 'site/plugins/{$name}/', + 'field' => 'site/fields/{$name}/', + 'tag' => 'site/tags/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php new file mode 100644 index 00000000..c5d08c5f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KnownInstaller.php @@ -0,0 +1,11 @@ + 'IdnoPlugins/{$name}/', + 'theme' => 'Themes/{$name}/', + 'console' => 'ConsolePlugins/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php new file mode 100644 index 00000000..7143e232 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php @@ -0,0 +1,10 @@ + 'cms/plugins/{$name}/', + 'media' => 'cms/media/vendor/{$name}/' + ); +} \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php new file mode 100644 index 00000000..dcd6d263 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php new file mode 100644 index 00000000..903143a5 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php @@ -0,0 +1,27 @@ + 'plugins/{$name}/', + 'template' => 'templates/{$name}/', + 'document-template' => 'documents/templates/{$name}/', + 'userpanel-module' => 'userpanel/modules/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php new file mode 100644 index 00000000..be4d53a7 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php @@ -0,0 +1,9 @@ + 'libraries/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php new file mode 100644 index 00000000..412c0b5c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php @@ -0,0 +1,10 @@ + 'packages/{$vendor}/{$name}/', + 'theme' => 'public/themes/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php new file mode 100644 index 00000000..47bbd4ca --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php @@ -0,0 +1,10 @@ + 'libraries/{$name}/', + 'source' => 'libraries/_source/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php new file mode 100644 index 00000000..9c2e9fb4 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php new file mode 100644 index 00000000..5a664608 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php @@ -0,0 +1,16 @@ + 'assets/snippets/{$name}/', + 'plugin' => 'assets/plugins/{$name}/', + 'module' => 'assets/modules/{$name}/', + 'template' => 'assets/templates/{$name}/', + 'lib' => 'assets/lib/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php new file mode 100644 index 00000000..cf18e947 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php @@ -0,0 +1,11 @@ + 'app/design/frontend/{$name}/', + 'skin' => 'skin/frontend/default/{$name}/', + 'library' => 'lib/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php new file mode 100644 index 00000000..e463756f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php @@ -0,0 +1,37 @@ + 'plugins/{$name}/', + ); + + /** + * Transforms the names + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + return $this->correctPluginName($vars); + } + + /** + * Change hyphenated names to camelcase + * @param array $vars + * @return array + */ + private function correctPluginName($vars) + { + $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + $vars['name'] = ucfirst($camelCasedName); + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php new file mode 100644 index 00000000..ca3cfacb --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MakoInstaller.php @@ -0,0 +1,9 @@ + 'app/packages/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php new file mode 100644 index 00000000..dadb1dbb --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php @@ -0,0 +1,23 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php new file mode 100644 index 00000000..c3dd2b6f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MauticInstaller.php @@ -0,0 +1,48 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + 'core' => 'app/', + ); + + private function getDirectoryName() + { + $extra = $this->package->getExtra(); + if (!empty($extra['install-directory-name'])) { + return $extra['install-directory-name']; + } + + return $this->toCamelCase($this->package->getPrettyName()); + } + + /** + * @param string $packageName + * + * @return string + */ + private function toCamelCase($packageName) + { + return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName)))); + } + + /** + * Format package name of mautic-plugins to CamelCase + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') { + $directoryName = $this->getDirectoryName(); + $vars['name'] = $directoryName; + } + + return $vars; + } + +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php new file mode 100644 index 00000000..30a91676 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MayaInstaller.php @@ -0,0 +1,33 @@ + 'modules/{$name}/', + ); + + /** + * Format package name. + * + * For package type maya-module, cut off a trailing '-module' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'maya-module') { + return $this->inflectModuleVars($vars); + } + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php new file mode 100644 index 00000000..f5a8957e --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php @@ -0,0 +1,51 @@ + 'core/', + 'extension' => 'extensions/{$name}/', + 'skin' => 'skins/{$name}/', + ); + + /** + * Format package name. + * + * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform + * to CamelCase keeping existing uppercase chars. + * + * For package type mediawiki-skin, cut off a trailing '-skin' if present. + * + */ + public function inflectPackageVars($vars) + { + + if ($vars['type'] === 'mediawiki-extension') { + return $this->inflectExtensionVars($vars); + } + + if ($vars['type'] === 'mediawiki-skin') { + return $this->inflectSkinVars($vars); + } + + return $vars; + } + + protected function inflectExtensionVars($vars) + { + $vars['name'] = preg_replace('/-extension$/', '', $vars['name']); + $vars['name'] = str_replace('-', ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectSkinVars($vars) + { + $vars['name'] = preg_replace('/-skin$/', '', $vars['name']); + + return $vars; + } + +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php new file mode 100644 index 00000000..66d8369c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php @@ -0,0 +1,10 @@ + 'plugins/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php new file mode 100644 index 00000000..b7d97039 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php @@ -0,0 +1,119 @@ + 'userfiles/modules/{$install_item_dir}/', + 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/', + 'template' => 'userfiles/templates/{$install_item_dir}/', + 'element' => 'userfiles/elements/{$install_item_dir}/', + 'vendor' => 'vendor/{$install_item_dir}/', + 'components' => 'components/{$install_item_dir}/' + ); + + /** + * Format package name. + * + * For package type microweber-module, cut off a trailing '-module' if present + * + * For package type microweber-template, cut off a trailing '-template' if present. + * + */ + public function inflectPackageVars($vars) + { + + + if ($this->package->getTargetDir()) { + $vars['install_item_dir'] = $this->package->getTargetDir(); + } else { + $vars['install_item_dir'] = $vars['name']; + if ($vars['type'] === 'microweber-template') { + return $this->inflectTemplateVars($vars); + } + if ($vars['type'] === 'microweber-templates') { + return $this->inflectTemplatesVars($vars); + } + if ($vars['type'] === 'microweber-core') { + return $this->inflectCoreVars($vars); + } + if ($vars['type'] === 'microweber-adapter') { + return $this->inflectCoreVars($vars); + } + if ($vars['type'] === 'microweber-module') { + return $this->inflectModuleVars($vars); + } + if ($vars['type'] === 'microweber-modules') { + return $this->inflectModulesVars($vars); + } + if ($vars['type'] === 'microweber-skin') { + return $this->inflectSkinVars($vars); + } + if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') { + return $this->inflectElementVars($vars); + } + } + + + return $vars; + } + + protected function inflectTemplateVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-template$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/template-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectTemplatesVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-templates$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/templates-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectCoreVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-providers$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-provider$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-adapter$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-module$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/module-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectModulesVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-modules$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/modules-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectSkinVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-skin$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/skin-$/', '', $vars['install_item_dir']); + + return $vars; + } + + protected function inflectElementVars($vars) + { + $vars['install_item_dir'] = preg_replace('/-elements$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/elements-$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/-element$/', '', $vars['install_item_dir']); + $vars['install_item_dir'] = preg_replace('/element-$/', '', $vars['install_item_dir']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php new file mode 100644 index 00000000..0ee140ab --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ModxInstaller.php @@ -0,0 +1,12 @@ + 'core/packages/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php new file mode 100644 index 00000000..05317995 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php @@ -0,0 +1,59 @@ + 'mod/{$name}/', + 'admin_report' => 'admin/report/{$name}/', + 'atto' => 'lib/editor/atto/plugins/{$name}/', + 'tool' => 'admin/tool/{$name}/', + 'assignment' => 'mod/assignment/type/{$name}/', + 'assignsubmission' => 'mod/assign/submission/{$name}/', + 'assignfeedback' => 'mod/assign/feedback/{$name}/', + 'auth' => 'auth/{$name}/', + 'availability' => 'availability/condition/{$name}/', + 'block' => 'blocks/{$name}/', + 'booktool' => 'mod/book/tool/{$name}/', + 'cachestore' => 'cache/stores/{$name}/', + 'cachelock' => 'cache/locks/{$name}/', + 'calendartype' => 'calendar/type/{$name}/', + 'fileconverter' => 'files/converter/{$name}/', + 'format' => 'course/format/{$name}/', + 'coursereport' => 'course/report/{$name}/', + 'customcertelement' => 'mod/customcert/element/{$name}/', + 'datafield' => 'mod/data/field/{$name}/', + 'datapreset' => 'mod/data/preset/{$name}/', + 'editor' => 'lib/editor/{$name}/', + 'enrol' => 'enrol/{$name}/', + 'filter' => 'filter/{$name}/', + 'gradeexport' => 'grade/export/{$name}/', + 'gradeimport' => 'grade/import/{$name}/', + 'gradereport' => 'grade/report/{$name}/', + 'gradingform' => 'grade/grading/form/{$name}/', + 'local' => 'local/{$name}/', + 'logstore' => 'admin/tool/log/store/{$name}/', + 'ltisource' => 'mod/lti/source/{$name}/', + 'ltiservice' => 'mod/lti/service/{$name}/', + 'message' => 'message/output/{$name}/', + 'mnetservice' => 'mnet/service/{$name}/', + 'plagiarism' => 'plagiarism/{$name}/', + 'portfolio' => 'portfolio/{$name}/', + 'qbehaviour' => 'question/behaviour/{$name}/', + 'qformat' => 'question/format/{$name}/', + 'qtype' => 'question/type/{$name}/', + 'quizaccess' => 'mod/quiz/accessrule/{$name}/', + 'quiz' => 'mod/quiz/report/{$name}/', + 'report' => 'report/{$name}/', + 'repository' => 'repository/{$name}/', + 'scormreport' => 'mod/scorm/report/{$name}/', + 'search' => 'search/engine/{$name}/', + 'theme' => 'theme/{$name}/', + 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/', + 'profilefield' => 'user/profile/field/{$name}/', + 'webservice' => 'webservice/{$name}/', + 'workshopallocation' => 'mod/workshop/allocation/{$name}/', + 'workshopeval' => 'mod/workshop/eval/{$name}/', + 'workshopform' => 'mod/workshop/form/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php new file mode 100644 index 00000000..489ef02a --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php @@ -0,0 +1,48 @@ + 'modules/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/', + 'theme' => 'themes/{$vendor}-{$name}/' + ); + + /** + * Format package name. + * + * For package type october-plugin, cut off a trailing '-plugin' if present. + * + * For package type october-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'october-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'october-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-plugin$/', '', $vars['name']); + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/^oc-|-theme$/', '', $vars['name']); + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php new file mode 100644 index 00000000..5dd3438d --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php @@ -0,0 +1,24 @@ + 'extensions/{$name}/', + 'theme' => 'extensions/themes/{$name}/', + 'translation' => 'extensions/translations/{$name}/', + ); + + /** + * Format package name to lower case and remove ".ontowiki" suffix + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower($vars['name']); + $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']); + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = preg_replace('/-translation$/', '', $vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php new file mode 100644 index 00000000..3ca7954c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php @@ -0,0 +1,14 @@ + 'oc-content/plugins/{$name}/', + 'theme' => 'oc-content/themes/{$name}/', + 'language' => 'oc-content/languages/{$name}/', + ); + +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php new file mode 100644 index 00000000..1797a22c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/OxidInstaller.php @@ -0,0 +1,59 @@ +.+)\/.+/'; + + protected $locations = array( + 'module' => 'modules/{$name}/', + 'theme' => 'application/views/{$name}/', + 'out' => 'out/{$name}/', + ); + + /** + * getInstallPath + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + $installPath = parent::getInstallPath($package, $frameworkType); + $type = $this->package->getType(); + if ($type === 'oxid-module') { + $this->prepareVendorDirectory($installPath); + } + return $installPath; + } + + /** + * prepareVendorDirectory + * + * Makes sure there is a vendormetadata.php file inside + * the vendor folder if there is a vendor folder. + * + * @param string $installPath + * @return void + */ + protected function prepareVendorDirectory($installPath) + { + $matches = ''; + $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); + if (!$hasVendorDirectory) { + return; + } + + $vendorDirectory = $matches['vendor']; + $vendorPath = getcwd() . '/modules/' . $vendorDirectory; + if (!file_exists($vendorPath)) { + mkdir($vendorPath, 0755, true); + } + + $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; + touch($vendorMetaDataPath); + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php new file mode 100644 index 00000000..170136f9 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PPIInstaller.php @@ -0,0 +1,9 @@ + 'modules/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php new file mode 100644 index 00000000..439f61a0 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php @@ -0,0 +1,12 @@ + */ + protected $locations = array( + 'script' => 'web/private/scripts/quicksilver/{$name}', + 'module' => 'web/private/scripts/quicksilver/{$name}', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php new file mode 100644 index 00000000..4e59a8a7 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php @@ -0,0 +1,11 @@ + 'bundles/{$name}/', + 'library' => 'libraries/{$name}/', + 'framework' => 'frameworks/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php new file mode 100644 index 00000000..deb2b77a --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php @@ -0,0 +1,11 @@ + 'ext/{$vendor}/{$name}/', + 'language' => 'language/{$name}/', + 'style' => 'styles/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php new file mode 100644 index 00000000..4781fa6d --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PimcoreInstaller.php @@ -0,0 +1,21 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php new file mode 100644 index 00000000..c17f4572 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php @@ -0,0 +1,32 @@ + 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php new file mode 100644 index 00000000..903e55f6 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php @@ -0,0 +1,29 @@ + '{$name}/' + ); + + /** + * Remove hyphen, "plugin" and format to camelcase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = explode("-", $vars['name']); + foreach ($vars['name'] as $key => $name) { + $vars['name'][$key] = ucfirst($vars['name'][$key]); + if (strcasecmp($name, "Plugin") == 0) { + unset($vars['name'][$key]); + } + } + $vars['name'] = implode("",$vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Plugin.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Plugin.php new file mode 100644 index 00000000..e60da0e7 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Plugin.php @@ -0,0 +1,27 @@ +installer = new Installer($io, $composer); + $composer->getInstallationManager()->addInstaller($this->installer); + } + + public function deactivate(Composer $composer, IOInterface $io) + { + $composer->getInstallationManager()->removeInstaller($this->installer); + } + + public function uninstall(Composer $composer, IOInterface $io) + { + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php new file mode 100644 index 00000000..dbf85e63 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PortoInstaller.php @@ -0,0 +1,9 @@ + 'app/Containers/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php new file mode 100644 index 00000000..4c8421e3 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php new file mode 100644 index 00000000..e6834a0c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php @@ -0,0 +1,22 @@ + 'site/modules/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php new file mode 100644 index 00000000..77cc3dd8 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php @@ -0,0 +1,11 @@ + 'modules/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php new file mode 100644 index 00000000..65510580 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php @@ -0,0 +1,63 @@ + 'app/Modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name. + * + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'pxcms-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'pxcms-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + /** + * For package type pxcms-module, cut off a trailing '-plugin' if present. + * + * return string + */ + protected function inflectModuleVars($vars) + { + $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) + $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module- + $vars['name'] = preg_replace('/-module$/', '', $vars['name']); // strip out -module + $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s + $vars['name'] = ucwords($vars['name']); // make module name camelcased + + return $vars; + } + + + /** + * For package type pxcms-module, cut off a trailing '-plugin' if present. + * + * return string + */ + protected function inflectThemeVars($vars) + { + $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) + $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme- + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); // strip out -theme + $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s + $vars['name'] = ucwords($vars['name']); // make module name camelcased + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php new file mode 100644 index 00000000..0f78b5ca --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php @@ -0,0 +1,24 @@ + 'src/{$name}/' + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $nameParts = explode('/', $vars['name']); + foreach ($nameParts as &$value) { + $value = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $value)); + $value = str_replace(array('-', '_'), ' ', $value); + $value = str_replace(' ', '', ucwords($value)); + } + $vars['name'] = implode('/', $nameParts); + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php new file mode 100644 index 00000000..252c7339 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php @@ -0,0 +1,10 @@ + 'themes/{$name}/', + 'plugin' => 'plugins/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php new file mode 100644 index 00000000..23a20347 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php @@ -0,0 +1,10 @@ + 'redaxo/src/addons/{$name}/', + 'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php new file mode 100644 index 00000000..09544576 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php @@ -0,0 +1,10 @@ + 'redaxo/include/addons/{$name}/', + 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php new file mode 100644 index 00000000..d8d795be --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php @@ -0,0 +1,22 @@ + 'plugins/{$name}/', + ); + + /** + * Lowercase name and changes the name to a underscores + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(str_replace('-', '_', $vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php new file mode 100644 index 00000000..1acd3b14 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SMFInstaller.php @@ -0,0 +1,10 @@ + 'Sources/{$name}/', + 'theme' => 'Themes/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php new file mode 100644 index 00000000..7d20d27a --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php @@ -0,0 +1,60 @@ + 'engine/Shopware/Plugins/Local/Backend/{$name}/', + 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/', + 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/', + 'theme' => 'templates/{$name}/', + 'plugin' => 'custom/plugins/{$name}/', + 'frontend-theme' => 'themes/Frontend/{$name}/', + ); + + /** + * Transforms the names + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'shopware-theme') { + return $this->correctThemeName($vars); + } + + return $this->correctPluginName($vars); + } + + /** + * Changes the name to a camelcased combination of vendor and name + * @param array $vars + * @return array + */ + private function correctPluginName($vars) + { + $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + + $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName); + + return $vars; + } + + /** + * Changes the name to a underscore separated name + * @param array $vars + * @return array + */ + private function correctThemeName($vars) + { + $vars['name'] = str_replace('-', '_', $vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php new file mode 100644 index 00000000..81910e9f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php @@ -0,0 +1,35 @@ + '{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Return the install path based on package type. + * + * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework + * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0 + * + * @param PackageInterface $package + * @param string $frameworkType + * @return string + */ + public function getInstallPath(PackageInterface $package, $frameworkType = '') + { + if ( + $package->getName() == 'silverstripe/framework' + && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion()) + && version_compare($package->getVersion(), '2.999.999') < 0 + ) { + return $this->templatePath($this->locations['module'], array('name' => 'sapphire')); + } + + return parent::getInstallPath($package, $frameworkType); + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php new file mode 100644 index 00000000..762d94c6 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php @@ -0,0 +1,25 @@ + 'modules/{$vendor}/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/' + ); + + public function inflectPackageVars($vars) + { + return $this->parseVars($vars); + } + + protected function parseVars($vars) + { + $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor']; + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php new file mode 100644 index 00000000..a31c9fda --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php @@ -0,0 +1,12 @@ + 'modules/{$name}/', + 'theme' => 'themes/{$name}/', + 'custom-module' => 'app/modules/{$name}/', + 'custom-theme' => 'app/themes/{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php new file mode 100644 index 00000000..8626a9bc --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php @@ -0,0 +1,47 @@ + 'app/modules/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format module name. + * + * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. + * + * {@inerhitDoc} + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] == 'sydes-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'sydes-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + public function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']); + $vars['name'] = strtolower($vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php new file mode 100644 index 00000000..4357a35b --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php @@ -0,0 +1,9 @@ + 'themes/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php new file mode 100644 index 00000000..1675c4f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/Symfony1Installer.php @@ -0,0 +1,26 @@ + + */ +class Symfony1Installer extends BaseInstaller +{ + protected $locations = array( + 'plugin' => 'plugins/{$name}/', + ); + + /** + * Format package name to CamelCase + */ + public function inflectPackageVars($vars) + { + $vars['name'] = preg_replace_callback('/(-[a-z])/', function ($matches) { + return strtoupper($matches[0][1]); + }, $vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php new file mode 100644 index 00000000..b1663e84 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php @@ -0,0 +1,16 @@ + + */ +class TYPO3CmsInstaller extends BaseInstaller +{ + protected $locations = array( + 'extension' => 'typo3conf/ext/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php new file mode 100644 index 00000000..42572f44 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php @@ -0,0 +1,38 @@ + 'Packages/Application/{$name}/', + 'framework' => 'Packages/Framework/{$name}/', + 'plugin' => 'Packages/Plugins/{$name}/', + 'site' => 'Packages/Sites/{$name}/', + 'boilerplate' => 'Packages/Boilerplates/{$name}/', + 'build' => 'Build/{$name}/', + ); + + /** + * Modify the package name to be a TYPO3 Flow style key. + * + * @param array $vars + * @return array + */ + public function inflectPackageVars($vars) + { + $autoload = $this->package->getAutoload(); + if (isset($autoload['psr-0']) && is_array($autoload['psr-0'])) { + $namespace = key($autoload['psr-0']); + $vars['name'] = str_replace('\\', '.', $namespace); + } + if (isset($autoload['psr-4']) && is_array($autoload['psr-4'])) { + $namespace = key($autoload['psr-4']); + $vars['name'] = rtrim(str_replace('\\', '.', $namespace), '.'); + } + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php new file mode 100644 index 00000000..4f79a45f --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TaoInstaller.php @@ -0,0 +1,30 @@ + '{$name}' + ); + + public function inflectPackageVars($vars) + { + $extra = $this->package->getExtra(); + + if (array_key_exists(self::EXTRA_TAO_EXTENSION_NAME, $extra)) { + $vars['name'] = $extra[self::EXTRA_TAO_EXTENSION_NAME]; + return $vars; + } + + $vars['name'] = str_replace('extension-', '', $vars['name']); + $vars['name'] = str_replace('-', ' ', $vars['name']); + $vars['name'] = lcfirst(str_replace(' ', '', ucwords($vars['name']))); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php new file mode 100644 index 00000000..e20e65b8 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php @@ -0,0 +1,32 @@ + 'extensions/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/', + ); + + /** + * Format package name. + * + * Cut off leading 'ti-ext-' or 'ti-theme-' if present. + * Strip vendor name of characters that is not alphanumeric or an underscore + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'tastyigniter-extension') { + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + $vars['name'] = preg_replace('/^ti-ext-/', '', $vars['name']); + } + + if ($vars['type'] === 'tastyigniter-theme') { + $vars['name'] = preg_replace('/^ti-theme-/', '', $vars['name']); + } + + return $vars; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php new file mode 100644 index 00000000..158af526 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php @@ -0,0 +1,12 @@ + 'local/modules/{$name}/', + 'frontoffice-template' => 'templates/frontOffice/{$name}/', + 'backoffice-template' => 'templates/backOffice/{$name}/', + 'email-template' => 'templates/email/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php new file mode 100644 index 00000000..7c0113b8 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/TuskInstaller.php @@ -0,0 +1,14 @@ + + */ + class TuskInstaller extends BaseInstaller + { + protected $locations = array( + 'task' => '.tusk/tasks/{$name}/', + 'command' => '.tusk/commands/{$name}/', + 'asset' => 'assets/tusk/{$name}/', + ); + } diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php new file mode 100644 index 00000000..fcb414ab --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php @@ -0,0 +1,9 @@ + 'app/sprinkles/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php new file mode 100644 index 00000000..24ca6451 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php @@ -0,0 +1,10 @@ + 'plugins/{$name}/', + 'theme' => 'themes/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php new file mode 100644 index 00000000..7d90c5e6 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php @@ -0,0 +1,49 @@ + 'src/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type vgmcp-bundle, cut off a trailing '-bundle' if present. + * + * For package type vgmcp-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'vgmcp-bundle') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'vgmcp-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/-theme$/', '', $vars['name']); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php new file mode 100644 index 00000000..b65dbbaf --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php @@ -0,0 +1,21 @@ + 'modules/addons/{$vendor}_{$name}/', + 'fraud' => 'modules/fraud/{$vendor}_{$name}/', + 'gateways' => 'modules/gateways/{$vendor}_{$name}/', + 'notifications' => 'modules/notifications/{$vendor}_{$name}/', + 'registrars' => 'modules/registrars/{$vendor}_{$name}/', + 'reports' => 'modules/reports/{$vendor}_{$name}/', + 'security' => 'modules/security/{$vendor}_{$name}/', + 'servers' => 'modules/servers/{$vendor}_{$name}/', + 'social' => 'modules/social/{$vendor}_{$name}/', + 'support' => 'modules/support/{$vendor}_{$name}/', + 'templates' => 'templates/{$vendor}_{$name}/', + 'includes' => 'includes/{$vendor}_{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php new file mode 100644 index 00000000..cff1bf19 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WinterInstaller.php @@ -0,0 +1,58 @@ + 'modules/{$name}/', + 'plugin' => 'plugins/{$vendor}/{$name}/', + 'theme' => 'themes/{$name}/' + ); + + /** + * Format package name. + * + * For package type winter-plugin, cut off a trailing '-plugin' if present. + * + * For package type winter-theme, cut off a trailing '-theme' if present. + * + */ + public function inflectPackageVars($vars) + { + if ($vars['type'] === 'winter-module') { + return $this->inflectModuleVars($vars); + } + + if ($vars['type'] === 'winter-plugin') { + return $this->inflectPluginVars($vars); + } + + if ($vars['type'] === 'winter-theme') { + return $this->inflectThemeVars($vars); + } + + return $vars; + } + + protected function inflectModuleVars($vars) + { + $vars['name'] = preg_replace('/^wn-|-module$/', '', $vars['name']); + + return $vars; + } + + protected function inflectPluginVars($vars) + { + $vars['name'] = preg_replace('/^wn-|-plugin$/', '', $vars['name']); + $vars['vendor'] = preg_replace('/[^a-z0-9_]/i', '', $vars['vendor']); + + return $vars; + } + + protected function inflectThemeVars($vars) + { + $vars['name'] = preg_replace('/^wn-|-theme$/', '', $vars['name']); + + return $vars; + } +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php new file mode 100644 index 00000000..cb387881 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php @@ -0,0 +1,9 @@ + 'wolf/plugins/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php new file mode 100644 index 00000000..91c46ad9 --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php @@ -0,0 +1,12 @@ + 'wp-content/plugins/{$name}/', + 'theme' => 'wp-content/themes/{$name}/', + 'muplugin' => 'wp-content/mu-plugins/{$name}/', + 'dropin' => 'wp-content/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php new file mode 100644 index 00000000..27f429ff --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/YawikInstaller.php @@ -0,0 +1,32 @@ + 'module/{$name}/', + ); + + /** + * Format package name to CamelCase + * @param array $vars + * + * @return array + */ + public function inflectPackageVars($vars) + { + $vars['name'] = strtolower(preg_replace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); + $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); + $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); + + return $vars; + } +} \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php new file mode 100644 index 00000000..bde9bc8c --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ZendInstaller.php @@ -0,0 +1,11 @@ + 'library/{$name}/', + 'extra' => 'extras/library/{$name}/', + 'module' => 'module/{$name}/', + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php new file mode 100644 index 00000000..56cdf5da --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php @@ -0,0 +1,10 @@ + 'modules/{$vendor}-{$name}/', + 'theme' => 'themes/{$vendor}-{$name}/' + ); +} diff --git a/modules/empikmarketplace/vendor/composer/installers/src/bootstrap.php b/modules/empikmarketplace/vendor/composer/installers/src/bootstrap.php new file mode 100644 index 00000000..0de276ee --- /dev/null +++ b/modules/empikmarketplace/vendor/composer/installers/src/bootstrap.php @@ -0,0 +1,13 @@ += 50600)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/.travis.yml b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/.travis.yml new file mode 100644 index 00000000..607b00a0 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/.travis.yml @@ -0,0 +1,52 @@ +language: php + +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - hhvm + - nightly + +env: + global: + - TEST_COMMAND="composer test" + +before_script: + - curl --version + - pear config-set php_ini ~/.phpenv/versions/`php -r 'echo phpversion();'`/etc/php.ini || echo 'Error modifying PEAR' + - pecl install uri_template || echo 'Error installing uri_template' + # To be removed when this issue will be resolved: https://github.com/composer/composer/issues/5355 + - if [[ "$COMPOSER_FLAGS" == *"--prefer-lowest"* ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable --quiet; fi + - travis_retry composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction + - ~/.nvm/nvm.sh install v0.6.14 + - ~/.nvm/nvm.sh run v0.6.14 + +script: $TEST_COMMAND + +matrix: + allow_failures: + - php: hhvm + - php: nightly + fast_finish: true + include: + - php: 5.4 + env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" COVERAGE=true TEST_COMMAND="composer test-ci" + +before_deploy: + - make package + +deploy: + provider: releases + api_key: + secure: UpypqlYgsU68QT/x40YzhHXvzWjFwCNo9d+G8KAdm7U9+blFfcWhV1aMdzugvPMl6woXgvJj7qHq5tAL4v6oswCORhpSBfLgOQVFaica5LiHsvWlAedOhxGmnJqMTwuepjBCxXhs3+I8Kof1n4oUL9gKytXjOVCX/f7XU1HiinU= + file: + - build/artifacts/guzzle.phar + - build/artifacts/guzzle.zip + on: + repo: guzzle/guzzle + tags: true + all_branches: true + php: 5.4 diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/CHANGELOG.md b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/CHANGELOG.md new file mode 100644 index 00000000..56ec2b7e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/CHANGELOG.md @@ -0,0 +1,1071 @@ +# CHANGELOG + +## 5.3.3 - 2018-07-31 + +* Fix bug parsing 0 epoch expiry times +* Fix PHP 7.3 compatibility + +## 5.3.2 - 2018-01-15 + +* Improve tests +* Fix react promise dependency +* Fix PHP 7 compatibility + +## 5.3.1 - 2016-07-18 + +* Address HTTP_PROXY security vulnerability, CVE-2016-5385: + https://httpoxy.org/ +* Event name fix: https://github.com/guzzle/guzzle/commit/fcae91ff31de41e312fe113ec3acbcda31b2622e +* Response header case sensitivity fix: https://github.com/guzzle/guzzle/commit/043eeadf20ee40ddc6712faee4d3957a91f2b041 + +## 5.3.0 - 2015-05-19 + +* Mock now supports `save_to` +* Marked `AbstractRequestEvent::getTransaction()` as public. +* Fixed a bug in which multiple headers using different casing would overwrite + previous headers in the associative array. +* Added `Utils::getDefaultHandler()` +* Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated. +* URL scheme is now always lowercased. + +## 5.2.0 - 2015-01-27 + +* Added `AppliesHeadersInterface` to make applying headers to a request based + on the body more generic and not specific to `PostBodyInterface`. +* Reduced the number of stack frames needed to send requests. +* Nested futures are now resolved in the client rather than the RequestFsm +* Finishing state transitions is now handled in the RequestFsm rather than the + RingBridge. +* Added a guard in the Pool class to not use recursion for request retries. + +## 5.1.0 - 2014-12-19 + +* Pool class no longer uses recursion when a request is intercepted. +* The size of a Pool can now be dynamically adjusted using a callback. + See https://github.com/guzzle/guzzle/pull/943. +* Setting a request option to `null` when creating a request with a client will + ensure that the option is not set. This allows you to overwrite default + request options on a per-request basis. + See https://github.com/guzzle/guzzle/pull/937. +* Added the ability to limit which protocols are allowed for redirects by + specifying a `protocols` array in the `allow_redirects` request option. +* Nested futures due to retries are now resolved when waiting for synchronous + responses. See https://github.com/guzzle/guzzle/pull/947. +* `"0"` is now an allowed URI path. See + https://github.com/guzzle/guzzle/pull/935. +* `Query` no longer typehints on the `$query` argument in the constructor, + allowing for strings and arrays. +* Exceptions thrown in the `end` event are now correctly wrapped with Guzzle + specific exceptions if necessary. + +## 5.0.3 - 2014-11-03 + +This change updates query strings so that they are treated as un-encoded values +by default where the value represents an un-encoded value to send over the +wire. A Query object then encodes the value before sending over the wire. This +means that even value query string values (e.g., ":") are url encoded. This +makes the Query class match PHP's http_build_query function. However, if you +want to send requests over the wire using valid query string characters that do +not need to be encoded, then you can provide a string to Url::setQuery() and +pass true as the second argument to specify that the query string is a raw +string that should not be parsed or encoded (unless a call to getQuery() is +subsequently made, forcing the query-string to be converted into a Query +object). + +## 5.0.2 - 2014-10-30 + +* Added a trailing `\r\n` to multipart/form-data payloads. See + https://github.com/guzzle/guzzle/pull/871 +* Added a `GuzzleHttp\Pool::send()` convenience method to match the docs. +* Status codes are now returned as integers. See + https://github.com/guzzle/guzzle/issues/881 +* No longer overwriting an existing `application/x-www-form-urlencoded` header + when sending POST requests, allowing for customized headers. See + https://github.com/guzzle/guzzle/issues/877 +* Improved path URL serialization. + + * No longer double percent-encoding characters in the path or query string if + they are already encoded. + * Now properly encoding the supplied path to a URL object, instead of only + encoding ' ' and '?'. + * Note: This has been changed in 5.0.3 to now encode query string values by + default unless the `rawString` argument is provided when setting the query + string on a URL: Now allowing many more characters to be present in the + query string without being percent encoded. See http://tools.ietf.org/html/rfc3986#appendix-A + +## 5.0.1 - 2014-10-16 + +Bugfix release. + +* Fixed an issue where connection errors still returned response object in + error and end events event though the response is unusable. This has been + corrected so that a response is not returned in the `getResponse` method of + these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867 +* Fixed an issue where transfer statistics were not being populated in the + RingBridge. https://github.com/guzzle/guzzle/issues/866 + +## 5.0.0 - 2014-10-12 + +Adding support for non-blocking responses and some minor API cleanup. + +### New Features + +* Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`. +* Added a public API for creating a default HTTP adapter. +* Updated the redirect plugin to be non-blocking so that redirects are sent + concurrently. Other plugins like this can now be updated to be non-blocking. +* Added a "progress" event so that you can get upload and download progress + events. +* Added `GuzzleHttp\Pool` which implements FutureInterface and transfers + requests concurrently using a capped pool size as efficiently as possible. +* Added `hasListeners()` to EmitterInterface. +* Removed `GuzzleHttp\ClientInterface::sendAll` and marked + `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the + recommended way). + +### Breaking changes + +The breaking changes in this release are relatively minor. The biggest thing to +look out for is that request and response objects no longer implement fluent +interfaces. + +* Removed the fluent interfaces (i.e., `return $this`) from requests, + responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`, + `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and + `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of + why I did this: http://ocramius.github.io/blog/fluent-interfaces-are-evil/. + This also makes the Guzzle message interfaces compatible with the current + PSR-7 message proposal. +* Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except + for the HTTP request functions from function.php, these functions are now + implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode` + moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to + `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to + `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be + `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php + caused problems for many users: they aren't PSR-4 compliant, require an + explicit include, and needed an if-guard to ensure that the functions are not + declared multiple times. +* Rewrote adapter layer. + * Removing all classes from `GuzzleHttp\Adapter`, these are now + implemented as callables that are stored in `GuzzleHttp\Ring\Client`. + * Removed the concept of "parallel adapters". Sending requests serially or + concurrently is now handled using a single adapter. + * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The + Transaction object now exposes the request, response, and client as public + properties. The getters and setters have been removed. +* Removed the "headers" event. This event was only useful for changing the + body a response once the headers of the response were known. You can implement + a similar behavior in a number of ways. One example might be to use a + FnStream that has access to the transaction being sent. For example, when the + first byte is written, you could check if the response headers match your + expectations, and if so, change the actual stream body that is being + written to. +* Removed the `asArray` parameter from + `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header + value as an array, then use the newly added `getHeaderAsArray()` method of + `MessageInterface`. This change makes the Guzzle interfaces compatible with + the PSR-7 interfaces. +* `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add + custom request options using double-dispatch (this was an implementation + detail). Instead, you should now provide an associative array to the + constructor which is a mapping of the request option name mapping to a + function that applies the option value to a request. +* Removed the concept of "throwImmediately" from exceptions and error events. + This control mechanism was used to stop a transfer of concurrent requests + from completing. This can now be handled by throwing the exception or by + cancelling a pool of requests or each outstanding future request individually. +* Updated to "GuzzleHttp\Streams" 3.0. + * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a + `maxLen` parameter. This update makes the Guzzle streams project + compatible with the current PSR-7 proposal. + * `GuzzleHttp\Stream\Stream::__construct`, + `GuzzleHttp\Stream\Stream::factory`, and + `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second + argument. They now accept an associative array of options, including the + "size" key and "metadata" key which can be used to provide custom metadata. + +## 4.2.2 - 2014-09-08 + +* Fixed a memory leak in the CurlAdapter when reusing cURL handles. +* No longer using `request_fulluri` in stream adapter proxies. +* Relative redirects are now based on the last response, not the first response. + +## 4.2.1 - 2014-08-19 + +* Ensuring that the StreamAdapter does not always add a Content-Type header +* Adding automated github releases with a phar and zip + +## 4.2.0 - 2014-08-17 + +* Now merging in default options using a case-insensitive comparison. + Closes https://github.com/guzzle/guzzle/issues/767 +* Added the ability to automatically decode `Content-Encoding` response bodies + using the `decode_content` request option. This is set to `true` by default + to decode the response body if it comes over the wire with a + `Content-Encoding`. Set this value to `false` to disable decoding the + response content, and pass a string to provide a request `Accept-Encoding` + header and turn on automatic response decoding. This feature now allows you + to pass an `Accept-Encoding` header in the headers of a request but still + disable automatic response decoding. + Closes https://github.com/guzzle/guzzle/issues/764 +* Added the ability to throw an exception immediately when transferring + requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760 +* Updating guzzlehttp/streams dependency to ~2.1 +* No longer utilizing the now deprecated namespaced methods from the stream + package. + +## 4.1.8 - 2014-08-14 + +* Fixed an issue in the CurlFactory that caused setting the `stream=false` + request option to throw an exception. + See: https://github.com/guzzle/guzzle/issues/769 +* TransactionIterator now calls rewind on the inner iterator. + See: https://github.com/guzzle/guzzle/pull/765 +* You can now set the `Content-Type` header to `multipart/form-data` + when creating POST requests to force multipart bodies. + See https://github.com/guzzle/guzzle/issues/768 + +## 4.1.7 - 2014-08-07 + +* Fixed an error in the HistoryPlugin that caused the same request and response + to be logged multiple times when an HTTP protocol error occurs. +* Ensuring that cURL does not add a default Content-Type when no Content-Type + has been supplied by the user. This prevents the adapter layer from modifying + the request that is sent over the wire after any listeners may have already + put the request in a desired state (e.g., signed the request). +* Throwing an exception when you attempt to send requests that have the + "stream" set to true in parallel using the MultiAdapter. +* Only calling curl_multi_select when there are active cURL handles. This was + previously changed and caused performance problems on some systems due to PHP + always selecting until the maximum select timeout. +* Fixed a bug where multipart/form-data POST fields were not correctly + aggregated (e.g., values with "&"). + +## 4.1.6 - 2014-08-03 + +* Added helper methods to make it easier to represent messages as strings, + including getting the start line and getting headers as a string. + +## 4.1.5 - 2014-08-02 + +* Automatically retrying cURL "Connection died, retrying a fresh connect" + errors when possible. +* cURL implementation cleanup +* Allowing multiple event subscriber listeners to be registered per event by + passing an array of arrays of listener configuration. + +## 4.1.4 - 2014-07-22 + +* Fixed a bug that caused multi-part POST requests with more than one field to + serialize incorrectly. +* Paths can now be set to "0" +* `ResponseInterface::xml` now accepts a `libxml_options` option and added a + missing default argument that was required when parsing XML response bodies. +* A `save_to` stream is now created lazily, which means that files are not + created on disk unless a request succeeds. + +## 4.1.3 - 2014-07-15 + +* Various fixes to multipart/form-data POST uploads +* Wrapping function.php in an if-statement to ensure Guzzle can be used + globally and in a Composer install +* Fixed an issue with generating and merging in events to an event array +* POST headers are only applied before sending a request to allow you to change + the query aggregator used before uploading +* Added much more robust query string parsing +* Fixed various parsing and normalization issues with URLs +* Fixing an issue where multi-valued headers were not being utilized correctly + in the StreamAdapter + +## 4.1.2 - 2014-06-18 + +* Added support for sending payloads with GET requests + +## 4.1.1 - 2014-06-08 + +* Fixed an issue related to using custom message factory options in subclasses +* Fixed an issue with nested form fields in a multi-part POST +* Fixed an issue with using the `json` request option for POST requests +* Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar` + +## 4.1.0 - 2014-05-27 + +* Added a `json` request option to easily serialize JSON payloads. +* Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON. +* Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`. +* Added the ability to provide an emitter to a client in the client constructor. +* Added the ability to persist a cookie session using $_SESSION. +* Added a trait that can be used to add event listeners to an iterator. +* Removed request method constants from RequestInterface. +* Fixed warning when invalid request start-lines are received. +* Updated MessageFactory to work with custom request option methods. +* Updated cacert bundle to latest build. + +4.0.2 (2014-04-16) +------------------ + +* Proxy requests using the StreamAdapter now properly use request_fulluri (#632) +* Added the ability to set scalars as POST fields (#628) + +## 4.0.1 - 2014-04-04 + +* The HTTP status code of a response is now set as the exception code of + RequestException objects. +* 303 redirects will now correctly switch from POST to GET requests. +* The default parallel adapter of a client now correctly uses the MultiAdapter. +* HasDataTrait now initializes the internal data array as an empty array so + that the toArray() method always returns an array. + +## 4.0.0 - 2014-03-29 + +* For more information on the 4.0 transition, see: + http://mtdowling.com/blog/2014/03/15/guzzle-4-rc/ +* For information on changes and upgrading, see: + https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 +* Added `GuzzleHttp\batch()` as a convenience function for sending requests in + parallel without needing to write asynchronous code. +* Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`. + You can now pass a callable or an array of associative arrays where each + associative array contains the "fn", "priority", and "once" keys. + +## 4.0.0.rc-2 - 2014-03-25 + +* Removed `getConfig()` and `setConfig()` from clients to avoid confusion + around whether things like base_url, message_factory, etc. should be able to + be retrieved or modified. +* Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface +* functions.php functions were renamed using snake_case to match PHP idioms +* Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and + `GUZZLE_CURL_SELECT_TIMEOUT` environment variables +* Added the ability to specify custom `sendAll()` event priorities +* Added the ability to specify custom stream context options to the stream + adapter. +* Added a functions.php function for `get_path()` and `set_path()` +* CurlAdapter and MultiAdapter now use a callable to generate curl resources +* MockAdapter now properly reads a body and emits a `headers` event +* Updated Url class to check if a scheme and host are set before adding ":" + and "//". This allows empty Url (e.g., "") to be serialized as "". +* Parsing invalid XML no longer emits warnings +* Curl classes now properly throw AdapterExceptions +* Various performance optimizations +* Streams are created with the faster `Stream\create()` function +* Marked deprecation_proxy() as internal +* Test server is now a collection of static methods on a class + +## 4.0.0-rc.1 - 2014-03-15 + +* See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 + +## 3.8.1 - 2014-01-28 + +* Bug: Always using GET requests when redirecting from a 303 response +* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in + `Guzzle\Http\ClientInterface::setSslVerification()` +* Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL +* Bug: The body of a request can now be set to `"0"` +* Sending PHP stream requests no longer forces `HTTP/1.0` +* Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of + each sub-exception +* Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than + clobbering everything). +* Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators) +* Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`. + For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`. +* Now properly escaping the regular expression delimiter when matching Cookie domains. +* Network access is now disabled when loading XML documents + +## 3.8.0 - 2013-12-05 + +* Added the ability to define a POST name for a file +* JSON response parsing now properly walks additionalProperties +* cURL error code 18 is now retried automatically in the BackoffPlugin +* Fixed a cURL error when URLs contain fragments +* Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were + CurlExceptions +* CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e) +* Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS` +* Fixed a bug that was encountered when parsing empty header parameters +* UriTemplate now has a `setRegex()` method to match the docs +* The `debug` request parameter now checks if it is truthy rather than if it exists +* Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin +* Added the ability to combine URLs using strict RFC 3986 compliance +* Command objects can now return the validation errors encountered by the command +* Various fixes to cache revalidation (#437 and 29797e5) +* Various fixes to the AsyncPlugin +* Cleaned up build scripts + +## 3.7.4 - 2013-10-02 + +* Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430) +* Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp + (see https://github.com/aws/aws-sdk-php/issues/147) +* Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots +* Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420) +* Updated the bundled cacert.pem (#419) +* OauthPlugin now supports adding authentication to headers or query string (#425) + +## 3.7.3 - 2013-09-08 + +* Added the ability to get the exception associated with a request/command when using `MultiTransferException` and + `CommandTransferException`. +* Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description +* Schemas are only injected into response models when explicitly configured. +* No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of + an EntityBody. +* Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator. +* Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`. +* Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody() +* Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin +* Bug fix: Visiting XML attributes first before visiting XML children when serializing requests +* Bug fix: Properly parsing headers that contain commas contained in quotes +* Bug fix: mimetype guessing based on a filename is now case-insensitive + +## 3.7.2 - 2013-08-02 + +* Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander + See https://github.com/guzzle/guzzle/issues/371 +* Bug fix: Cookie domains are now matched correctly according to RFC 6265 + See https://github.com/guzzle/guzzle/issues/377 +* Bug fix: GET parameters are now used when calculating an OAuth signature +* Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted +* `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched +* `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input. + See https://github.com/guzzle/guzzle/issues/379 +* Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See + https://github.com/guzzle/guzzle/pull/380 +* cURL multi cleanup and optimizations + +## 3.7.1 - 2013-07-05 + +* Bug fix: Setting default options on a client now works +* Bug fix: Setting options on HEAD requests now works. See #352 +* Bug fix: Moving stream factory before send event to before building the stream. See #353 +* Bug fix: Cookies no longer match on IP addresses per RFC 6265 +* Bug fix: Correctly parsing header parameters that are in `<>` and quotes +* Added `cert` and `ssl_key` as request options +* `Host` header can now diverge from the host part of a URL if the header is set manually +* `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter +* OAuth parameters are only added via the plugin if they aren't already set +* Exceptions are now thrown when a URL cannot be parsed +* Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails +* Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin + +## 3.7.0 - 2013-06-10 + +* See UPGRADING.md for more information on how to upgrade. +* Requests now support the ability to specify an array of $options when creating a request to more easily modify a + request. You can pass a 'request.options' configuration setting to a client to apply default request options to + every request created by a client (e.g. default query string variables, headers, curl options, etc.). +* Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`. + See `Guzzle\Http\StaticClient::mount`. +* Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests + created by a command (e.g. custom headers, query string variables, timeout settings, etc.). +* Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the + headers of a response +* Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key + (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`) +* ServiceBuilders now support storing and retrieving arbitrary data +* CachePlugin can now purge all resources for a given URI +* CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource +* CachePlugin now uses the Vary header to determine if a resource is a cache hit +* `Guzzle\Http\Message\Response` now implements `\Serializable` +* Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters +* `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable +* Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()` +* Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size +* `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message +* Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older + Symfony users can still use the old version of Monolog. +* Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`. + Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`. +* Several performance improvements to `Guzzle\Common\Collection` +* Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: + createRequest, head, delete, put, patch, post, options, prepareRequest +* Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` +* Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` +* Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to + `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a + resource, string, or EntityBody into the $options parameter to specify the download location of the response. +* Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a + default `array()` +* Added `Guzzle\Stream\StreamInterface::isRepeatable` +* Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use + $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or + $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`. +* Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`. +* Removed `Guzzle\Http\ClientInterface::expandTemplate()` +* Removed `Guzzle\Http\ClientInterface::setRequestFactory()` +* Removed `Guzzle\Http\ClientInterface::getCurlMulti()` +* Removed `Guzzle\Http\Message\RequestInterface::canCache` +* Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect` +* Removed `Guzzle\Http\Message\RequestInterface::isRedirect` +* Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. +* You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting + `Guzzle\Common\Version::$emitWarnings` to true. +* Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use + `$request->getResponseBody()->isRepeatable()` instead. +* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use + `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. +* Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use + `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. +* Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. +* Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. +* Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated +* Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. + These will work through Guzzle 4.0 +* Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params]. +* Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. +* Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`. +* Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. +* Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. +* Marked `Guzzle\Common\Collection::inject()` as deprecated. +* Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');` +* CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a + CacheStorageInterface. These two objects and interface will be removed in a future version. +* Always setting X-cache headers on cached responses +* Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin +* `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface + $request, Response $response);` +* `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` +* `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` +* Added `CacheStorageInterface::purge($url)` +* `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin + $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, + CanCacheStrategyInterface $canCache = null)` +* Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` + +## 3.6.0 - 2013-05-29 + +* ServiceDescription now implements ToArrayInterface +* Added command.hidden_params to blacklist certain headers from being treated as additionalParameters +* Guzzle can now correctly parse incomplete URLs +* Mixed casing of headers are now forced to be a single consistent casing across all values for that header. +* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution +* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). +* Specific header implementations can be created for complex headers. When a message creates a header, it uses a + HeaderFactory which can map specific headers to specific header classes. There is now a Link header and + CacheControl header implementation. +* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate +* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() +* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in + Guzzle\Http\Curl\RequestMediator +* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. +* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface +* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() +* Removed Guzzle\Parser\ParserRegister::get(). Use getParser() +* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). +* All response header helper functions return a string rather than mixing Header objects and strings inconsistently +* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle + directly via interfaces +* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist + but are a no-op until removed. +* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a + `Guzzle\Service\Command\ArrayCommandInterface`. +* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response + on a request while the request is still being transferred +* The ability to case-insensitively search for header values +* Guzzle\Http\Message\Header::hasExactHeader +* Guzzle\Http\Message\Header::raw. Use getAll() +* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object + instead. +* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess +* Added the ability to cast Model objects to a string to view debug information. + +## 3.5.0 - 2013-05-13 + +* Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times +* Bug: Better cleanup of one-time events across the board (when an event is meant to fire once, it will now remove + itself from the EventDispatcher) +* Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values +* Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too +* Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a + non-existent key +* Bug: All __call() method arguments are now required (helps with mocking frameworks) +* Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference + to help with refcount based garbage collection of resources created by sending a request +* Deprecating ZF1 cache and log adapters. These will be removed in the next major version. +* Deprecating `Response::getPreviousResponse()` (method signature still exists, but it'sdeprecated). Use the + HistoryPlugin for a history. +* Added a `responseBody` alias for the `response_body` location +* Refactored internals to no longer rely on Response::getRequest() +* HistoryPlugin can now be cast to a string +* HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests + and responses that are sent over the wire +* Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects + +## 3.4.3 - 2013-04-30 + +* Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response +* Added a check to re-extract the temp cacert bundle from the phar before sending each request + +## 3.4.2 - 2013-04-29 + +* Bug fix: Stream objects now work correctly with "a" and "a+" modes +* Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present +* Bug fix: AsyncPlugin no longer forces HEAD requests +* Bug fix: DateTime timezones are now properly handled when using the service description schema formatter +* Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails +* Setting a response on a request will write to the custom request body from the response body if one is specified +* LogPlugin now writes to php://output when STDERR is undefined +* Added the ability to set multiple POST files for the same key in a single call +* application/x-www-form-urlencoded POSTs now use the utf-8 charset by default +* Added the ability to queue CurlExceptions to the MockPlugin +* Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send) +* Configuration loading now allows remote files + +## 3.4.1 - 2013-04-16 + +* Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti + handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost. +* Exceptions are now properly grouped when sending requests in parallel +* Redirects are now properly aggregated when a multi transaction fails +* Redirects now set the response on the original object even in the event of a failure +* Bug fix: Model names are now properly set even when using $refs +* Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax +* Added support for oauth_callback in OAuth signatures +* Added support for oauth_verifier in OAuth signatures +* Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection + +## 3.4.0 - 2013-04-11 + +* Bug fix: URLs are now resolved correctly based on http://tools.ietf.org/html/rfc3986#section-5.2. #289 +* Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289 +* Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263 +* Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264. +* Bug fix: Added `number` type to service descriptions. +* Bug fix: empty parameters are removed from an OAuth signature +* Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header +* Bug fix: Fixed "array to string" error when validating a union of types in a service description +* Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream +* Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin. +* Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs. +* The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections. +* Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if + the Content-Type can be determined based on the entity body or the path of the request. +* Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder. +* Added support for a PSR-3 LogAdapter. +* Added a `command.after_prepare` event +* Added `oauth_callback` parameter to the OauthPlugin +* Added the ability to create a custom stream class when using a stream factory +* Added a CachingEntityBody decorator +* Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized. +* The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar. +* You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies +* POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This + means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use + POST fields or files (the latter is only used when emulating a form POST in the browser). +* Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest + +## 3.3.1 - 2013-03-10 + +* Added the ability to create PHP streaming responses from HTTP requests +* Bug fix: Running any filters when parsing response headers with service descriptions +* Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing +* Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across + response location visitors. +* Bug fix: Removed the possibility of creating configuration files with circular dependencies +* RequestFactory::create() now uses the key of a POST file when setting the POST file name +* Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set + +## 3.3.0 - 2013-03-03 + +* A large number of performance optimizations have been made +* Bug fix: Added 'wb' as a valid write mode for streams +* Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned +* Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()` +* BC: Removed `Guzzle\Http\Utils` class +* BC: Setting a service description on a client will no longer modify the client's command factories. +* BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using + the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' +* BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to + lowercase +* Operation parameter objects are now lazy loaded internally +* Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses +* Added support for instantiating responseType=class responseClass classes. Classes must implement + `Guzzle\Service\Command\ResponseClassInterface` +* Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These + additional properties also support locations and can be used to parse JSON responses where the outermost part of the + JSON is an array +* Added support for nested renaming of JSON models (rename sentAs to name) +* CachePlugin + * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error + * Debug headers can now added to cached response in the CachePlugin + +## 3.2.0 - 2013-02-14 + +* CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients. +* URLs with no path no longer contain a "/" by default +* Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url. +* BadResponseException no longer includes the full request and response message +* Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface +* Adding getResponseBody() to Guzzle\Http\Message\RequestInterface +* Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription +* Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list +* xmlEncoding can now be customized for the XML declaration of a XML service description operation +* Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value + aggregation and no longer uses callbacks +* The URL encoding implementation of Guzzle\Http\QueryString can now be customized +* Bug fix: Filters were not always invoked for array service description parameters +* Bug fix: Redirects now use a target response body rather than a temporary response body +* Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded +* Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives + +## 3.1.2 - 2013-01-27 + +* Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the + response body. For example, the XmlVisitor now parses the XML response into an array in the before() method. +* Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent +* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444) +* Fixed a bug where redirect responses were not chained correctly using getPreviousResponse() +* Setting default headers on a client after setting the user-agent will not erase the user-agent setting + +## 3.1.1 - 2013-01-20 + +* Adding wildcard support to Guzzle\Common\Collection::getPath() +* Adding alias support to ServiceBuilder configs +* Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface + +## 3.1.0 - 2013-01-12 + +* BC: CurlException now extends from RequestException rather than BadResponseException +* BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse() +* Added getData to ServiceDescriptionInterface +* Added context array to RequestInterface::setState() +* Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http +* Bug: Adding required content-type when JSON request visitor adds JSON to a command +* Bug: Fixing the serialization of a service description with custom data +* Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing + an array of successful and failed responses +* Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection +* Added Guzzle\Http\IoEmittingEntityBody +* Moved command filtration from validators to location visitors +* Added `extends` attributes to service description parameters +* Added getModels to ServiceDescriptionInterface + +## 3.0.7 - 2012-12-19 + +* Fixing phar detection when forcing a cacert to system if null or true +* Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()` +* Cleaning up `Guzzle\Common\Collection::inject` method +* Adding a response_body location to service descriptions + +## 3.0.6 - 2012-12-09 + +* CurlMulti performance improvements +* Adding setErrorResponses() to Operation +* composer.json tweaks + +## 3.0.5 - 2012-11-18 + +* Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin +* Bug: Response body can now be a string containing "0" +* Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert +* Bug: QueryString::fromString now properly parses query string parameters that contain equal signs +* Added support for XML attributes in service description responses +* DefaultRequestSerializer now supports array URI parameter values for URI template expansion +* Added better mimetype guessing to requests and post files + +## 3.0.4 - 2012-11-11 + +* Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value +* Bug: Cookies can now be added that have a name, domain, or value set to "0" +* Bug: Using the system cacert bundle when using the Phar +* Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures +* Enhanced cookie jar de-duplication +* Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added +* Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies +* Added the ability to create any sort of hash for a stream rather than just an MD5 hash + +## 3.0.3 - 2012-11-04 + +* Implementing redirects in PHP rather than cURL +* Added PECL URI template extension and using as default parser if available +* Bug: Fixed Content-Length parsing of Response factory +* Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams. +* Adding ToArrayInterface throughout library +* Fixing OauthPlugin to create unique nonce values per request + +## 3.0.2 - 2012-10-25 + +* Magic methods are enabled by default on clients +* Magic methods return the result of a command +* Service clients no longer require a base_url option in the factory +* Bug: Fixed an issue with URI templates where null template variables were being expanded + +## 3.0.1 - 2012-10-22 + +* Models can now be used like regular collection objects by calling filter, map, etc. +* Models no longer require a Parameter structure or initial data in the constructor +* Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator` + +## 3.0.0 - 2012-10-15 + +* Rewrote service description format to be based on Swagger + * Now based on JSON schema + * Added nested input structures and nested response models + * Support for JSON and XML input and output models + * Renamed `commands` to `operations` + * Removed dot class notation + * Removed custom types +* Broke the project into smaller top-level namespaces to be more component friendly +* Removed support for XML configs and descriptions. Use arrays or JSON files. +* Removed the Validation component and Inspector +* Moved all cookie code to Guzzle\Plugin\Cookie +* Magic methods on a Guzzle\Service\Client now return the command un-executed. +* Calling getResult() or getResponse() on a command will lazily execute the command if needed. +* Now shipping with cURL's CA certs and using it by default +* Added previousResponse() method to response objects +* No longer sending Accept and Accept-Encoding headers on every request +* Only sending an Expect header by default when a payload is greater than 1MB +* Added/moved client options: + * curl.blacklist to curl.option.blacklist + * Added ssl.certificate_authority +* Added a Guzzle\Iterator component +* Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin +* Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin) +* Added a more robust caching plugin +* Added setBody to response objects +* Updating LogPlugin to use a more flexible MessageFormatter +* Added a completely revamped build process +* Cleaning up Collection class and removing default values from the get method +* Fixed ZF2 cache adapters + +## 2.8.8 - 2012-10-15 + +* Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did + +## 2.8.7 - 2012-09-30 + +* Bug: Fixed config file aliases for JSON includes +* Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests +* Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload +* Bug: Hardening request and response parsing to account for missing parts +* Bug: Fixed PEAR packaging +* Bug: Fixed Request::getInfo +* Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail +* Adding the ability for the namespace Iterator factory to look in multiple directories +* Added more getters/setters/removers from service descriptions +* Added the ability to remove POST fields from OAuth signatures +* OAuth plugin now supports 2-legged OAuth + +## 2.8.6 - 2012-09-05 + +* Added the ability to modify and build service descriptions +* Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command +* Added a `json` parameter location +* Now allowing dot notation for classes in the CacheAdapterFactory +* Using the union of two arrays rather than an array_merge when extending service builder services and service params +* Ensuring that a service is a string before doing strpos() checks on it when substituting services for references + in service builder config files. +* Services defined in two different config files that include one another will by default replace the previously + defined service, but you can now create services that extend themselves and merge their settings over the previous +* The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like + '_default' with a default JSON configuration file. + +## 2.8.5 - 2012-08-29 + +* Bug: Suppressed empty arrays from URI templates +* Bug: Added the missing $options argument from ServiceDescription::factory to enable caching +* Added support for HTTP responses that do not contain a reason phrase in the start-line +* AbstractCommand commands are now invokable +* Added a way to get the data used when signing an Oauth request before a request is sent + +## 2.8.4 - 2012-08-15 + +* Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin +* Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable. +* Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream +* Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream +* Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5()) +* Added additional response status codes +* Removed SSL information from the default User-Agent header +* DELETE requests can now send an entity body +* Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries +* Added the ability of the MockPlugin to consume mocked request bodies +* LogPlugin now exposes request and response objects in the extras array + +## 2.8.3 - 2012-07-30 + +* Bug: Fixed a case where empty POST requests were sent as GET requests +* Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body +* Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new +* Added multiple inheritance to service description commands +* Added an ApiCommandInterface and added `getParamNames()` and `hasParam()` +* Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything +* Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles + +## 2.8.2 - 2012-07-24 + +* Bug: Query string values set to 0 are no longer dropped from the query string +* Bug: A Collection object is no longer created each time a call is made to `Guzzle\Service\Command\AbstractCommand::getRequestHeaders()` +* Bug: `+` is now treated as an encoded space when parsing query strings +* QueryString and Collection performance improvements +* Allowing dot notation for class paths in filters attribute of a service descriptions + +## 2.8.1 - 2012-07-16 + +* Loosening Event Dispatcher dependency +* POST redirects can now be customized using CURLOPT_POSTREDIR + +## 2.8.0 - 2012-07-15 + +* BC: Guzzle\Http\Query + * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl) + * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding() + * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool) + * Changed the aggregation functions of QueryString to be static methods + * Can now use fromString() with querystrings that have a leading ? +* cURL configuration values can be specified in service descriptions using `curl.` prefixed parameters +* Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body +* Cookies are no longer URL decoded by default +* Bug: URI template variables set to null are no longer expanded + +## 2.7.2 - 2012-07-02 + +* BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser. +* BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty() +* CachePlugin now allows for a custom request parameter function to check if a request can be cached +* Bug fix: CachePlugin now only caches GET and HEAD requests by default +* Bug fix: Using header glue when transferring headers over the wire +* Allowing deeply nested arrays for composite variables in URI templates +* Batch divisors can now return iterators or arrays + +## 2.7.1 - 2012-06-26 + +* Minor patch to update version number in UA string +* Updating build process + +## 2.7.0 - 2012-06-25 + +* BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes. +* BC: Removed magic setX methods from commands +* BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method +* Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable. +* Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity) +* Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace +* Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin +* Added the ability to set POST fields and files in a service description +* Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method +* Adding a command.before_prepare event to clients +* Added BatchClosureTransfer and BatchClosureDivisor +* BatchTransferException now includes references to the batch divisor and transfer strategies +* Fixed some tests so that they pass more reliably +* Added Guzzle\Common\Log\ArrayLogAdapter + +## 2.6.6 - 2012-06-10 + +* BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin +* BC: Removing Guzzle\Service\Command\CommandSet +* Adding generic batching system (replaces the batch queue plugin and command set) +* Updating ZF cache and log adapters and now using ZF's composer repository +* Bug: Setting the name of each ApiParam when creating through an ApiCommand +* Adding result_type, result_doc, deprecated, and doc_url to service descriptions +* Bug: Changed the default cookie header casing back to 'Cookie' + +## 2.6.5 - 2012-06-03 + +* BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource() +* BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from +* BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data +* BC: Renaming methods in the CookieJarInterface +* Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations +* Making the default glue for HTTP headers ';' instead of ',' +* Adding a removeValue to Guzzle\Http\Message\Header +* Adding getCookies() to request interface. +* Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber() + +## 2.6.4 - 2012-05-30 + +* BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class. +* BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand +* Bug: Fixing magic method command calls on clients +* Bug: Email constraint only validates strings +* Bug: Aggregate POST fields when POST files are present in curl handle +* Bug: Fixing default User-Agent header +* Bug: Only appending or prepending parameters in commands if they are specified +* Bug: Not requiring response reason phrases or status codes to match a predefined list of codes +* Allowing the use of dot notation for class namespaces when using instance_of constraint +* Added any_match validation constraint +* Added an AsyncPlugin +* Passing request object to the calculateWait method of the ExponentialBackoffPlugin +* Allowing the result of a command object to be changed +* Parsing location and type sub values when instantiating a service description rather than over and over at runtime + +## 2.6.3 - 2012-05-23 + +* [BC] Guzzle\Common\FromConfigInterface no longer requires any config options. +* [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields. +* You can now use an array of data when creating PUT request bodies in the request factory. +* Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable. +* [Http] Adding support for Content-Type in multipart POST uploads per upload +* [Http] Added support for uploading multiple files using the same name (foo[0], foo[1]) +* Adding more POST data operations for easier manipulation of POST data. +* You can now set empty POST fields. +* The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files. +* Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate. +* CS updates + +## 2.6.2 - 2012-05-19 + +* [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method. + +## 2.6.1 - 2012-05-19 + +* [BC] Removing 'path' support in service descriptions. Use 'uri'. +* [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache. +* [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it. +* [BC] Removing Guzzle\Common\XmlElement. +* All commands, both dynamic and concrete, have ApiCommand objects. +* Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits. +* Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored. +* Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible. + +## 2.6.0 - 2012-05-15 + +* [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder +* [BC] Executing a Command returns the result of the command rather than the command +* [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed. +* [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args. +* [BC] Moving ResourceIterator* to Guzzle\Service\Resource +* [BC] Completely refactored ResourceIterators to iterate over a cloned command object +* [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate +* [BC] Guzzle\Guzzle is now deprecated +* Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject +* Adding Guzzle\Version class to give version information about Guzzle +* Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate() +* Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data +* ServiceDescription and ServiceBuilder are now cacheable using similar configs +* Changing the format of XML and JSON service builder configs. Backwards compatible. +* Cleaned up Cookie parsing +* Trimming the default Guzzle User-Agent header +* Adding a setOnComplete() method to Commands that is called when a command completes +* Keeping track of requests that were mocked in the MockPlugin +* Fixed a caching bug in the CacheAdapterFactory +* Inspector objects can be injected into a Command object +* Refactoring a lot of code and tests to be case insensitive when dealing with headers +* Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL +* Adding the ability to set global option overrides to service builder configs +* Adding the ability to include other service builder config files from within XML and JSON files +* Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method. + +## 2.5.0 - 2012-05-08 + +* Major performance improvements +* [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated. +* [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component. +* [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}" +* Added the ability to passed parameters to all requests created by a client +* Added callback functionality to the ExponentialBackoffPlugin +* Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies. +* Rewinding request stream bodies when retrying requests +* Exception is thrown when JSON response body cannot be decoded +* Added configurable magic method calls to clients and commands. This is off by default. +* Fixed a defect that added a hash to every parsed URL part +* Fixed duplicate none generation for OauthPlugin. +* Emitting an event each time a client is generated by a ServiceBuilder +* Using an ApiParams object instead of a Collection for parameters of an ApiCommand +* cache.* request parameters should be renamed to params.cache.* +* Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle. +* Added the ability to disable type validation of service descriptions +* ServiceDescriptions and ServiceBuilders are now Serializable diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/LICENSE b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/LICENSE new file mode 100644 index 00000000..9af9fba6 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011-2015 Michael Dowling, https://github.com/mtdowling + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/README.md b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/README.md new file mode 100644 index 00000000..d41e7e75 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/README.md @@ -0,0 +1,70 @@ +Guzzle, PHP HTTP client and webservice framework +================================================ + +[![Build Status](https://secure.travis-ci.org/guzzle/guzzle.svg?branch=master)](http://travis-ci.org/guzzle/guzzle) + +Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and +trivial to integrate with web services. + +- Manages things like persistent connections, represents query strings as + collections, simplifies sending streaming POST requests with fields and + files, and abstracts away the underlying HTTP transport layer. +- Can send both synchronous and asynchronous requests using the same interface + without requiring a dependency on a specific event loop. +- Pluggable HTTP adapters allows Guzzle to integrate with any method you choose + for sending HTTP requests over the wire (e.g., cURL, sockets, PHP's stream + wrapper, non-blocking event loops like ReactPHP. +- Guzzle makes it so that you no longer need to fool around with cURL options, + stream contexts, or sockets. + +```php +$client = new GuzzleHttp\Client(); +$response = $client->get('http://guzzlephp.org'); +$res = $client->get('https://api.github.com/user', ['auth' => ['user', 'pass']]); +echo $res->getStatusCode(); +// "200" +echo $res->getHeader('content-type'); +// 'application/json; charset=utf8' +echo $res->getBody(); +// {"type":"User"...' +var_export($res->json()); +// Outputs the JSON decoded data + +// Send an asynchronous request. +$req = $client->createRequest('GET', 'http://httpbin.org', ['future' => true]); +$client->send($req)->then(function ($response) { + echo 'I completed! ' . $response; +}); +``` + +Get more information and answers with the +[Documentation](http://guzzlephp.org/), +[Forums](https://groups.google.com/forum/?hl=en#!forum/guzzle), +and [Gitter](https://gitter.im/guzzle/guzzle). + +### Installing via Composer + +The recommended way to install Guzzle is through +[Composer](http://getcomposer.org). + +```bash +# Install Composer +curl -sS https://getcomposer.org/installer | php +``` + +Next, run the Composer command to install the latest stable version of Guzzle: + +```bash +composer.phar require guzzlehttp/guzzle +``` + +After installing, you need to require Composer's autoloader: + +```php +require 'vendor/autoload.php'; +``` + +### Documentation + +More information can be found in the online documentation at +http://guzzlephp.org/. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/UPGRADING.md b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/UPGRADING.md new file mode 100644 index 00000000..2b3877fa --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/UPGRADING.md @@ -0,0 +1,1050 @@ +Guzzle Upgrade Guide +==================== + +4.x to 5.0 +---------- + +## Rewritten Adapter Layer + +Guzzle now uses [RingPHP](http://ringphp.readthedocs.org/en/latest) to send +HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor +is still supported, but it has now been renamed to `handler`. Instead of +passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP +`callable` that follows the RingPHP specification. + +## Removed Fluent Interfaces + +[Fluent interfaces were removed](http://ocramius.github.io/blog/fluent-interfaces-are-evil) +from the following classes: + +- `GuzzleHttp\Collection` +- `GuzzleHttp\Url` +- `GuzzleHttp\Query` +- `GuzzleHttp\Post\PostBody` +- `GuzzleHttp\Cookie\SetCookie` + +## Removed functions.php + +Removed "functions.php", so that Guzzle is truly PSR-4 compliant. The following +functions can be used as replacements. + +- `GuzzleHttp\json_decode` -> `GuzzleHttp\Utils::jsonDecode` +- `GuzzleHttp\get_path` -> `GuzzleHttp\Utils::getPath` +- `GuzzleHttp\Utils::setPath` -> `GuzzleHttp\set_path` +- `GuzzleHttp\Pool::batch` -> `GuzzleHttp\batch`. This function is, however, + deprecated in favor of using `GuzzleHttp\Pool::batch()`. + +The "procedural" global client has been removed with no replacement (e.g., +`GuzzleHttp\get()`, `GuzzleHttp\post()`, etc.). Use a `GuzzleHttp\Client` +object as a replacement. + +## `throwImmediately` has been removed + +The concept of "throwImmediately" has been removed from exceptions and error +events. This control mechanism was used to stop a transfer of concurrent +requests from completing. This can now be handled by throwing the exception or +by cancelling a pool of requests or each outstanding future request +individually. + +## headers event has been removed + +Removed the "headers" event. This event was only useful for changing the +body a response once the headers of the response were known. You can implement +a similar behavior in a number of ways. One example might be to use a +FnStream that has access to the transaction being sent. For example, when the +first byte is written, you could check if the response headers match your +expectations, and if so, change the actual stream body that is being +written to. + +## Updates to HTTP Messages + +Removed the `asArray` parameter from +`GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header +value as an array, then use the newly added `getHeaderAsArray()` method of +`MessageInterface`. This change makes the Guzzle interfaces compatible with +the PSR-7 interfaces. + +3.x to 4.0 +---------- + +## Overarching changes: + +- Now requires PHP 5.4 or greater. +- No longer requires cURL to send requests. +- Guzzle no longer wraps every exception it throws. Only exceptions that are + recoverable are now wrapped by Guzzle. +- Various namespaces have been removed or renamed. +- No longer requiring the Symfony EventDispatcher. A custom event dispatcher + based on the Symfony EventDispatcher is + now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant + speed and functionality improvements). + +Changes per Guzzle 3.x namespace are described below. + +## Batch + +The `Guzzle\Batch` namespace has been removed. This is best left to +third-parties to implement on top of Guzzle's core HTTP library. + +## Cache + +The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement +has been implemented yet, but hoping to utilize a PSR cache interface). + +## Common + +- Removed all of the wrapped exceptions. It's better to use the standard PHP + library for unrecoverable exceptions. +- `FromConfigInterface` has been removed. +- `Guzzle\Common\Version` has been removed. The VERSION constant can be found + at `GuzzleHttp\ClientInterface::VERSION`. + +### Collection + +- `getAll` has been removed. Use `toArray` to convert a collection to an array. +- `inject` has been removed. +- `keySearch` has been removed. +- `getPath` no longer supports wildcard expressions. Use something better like + JMESPath for this. +- `setPath` now supports appending to an existing array via the `[]` notation. + +### Events + +Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses +`GuzzleHttp\Event\Emitter`. + +- `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by + `GuzzleHttp\Event\EmitterInterface`. +- `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by + `GuzzleHttp\Event\Emitter`. +- `Symfony\Component\EventDispatcher\Event` is replaced by + `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in + `GuzzleHttp\Event\EventInterface`. +- `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and + `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the + event emitter of a request, client, etc. now uses the `getEmitter` method + rather than the `getDispatcher` method. + +#### Emitter + +- Use the `once()` method to add a listener that automatically removes itself + the first time it is invoked. +- Use the `listeners()` method to retrieve a list of event listeners rather than + the `getListeners()` method. +- Use `emit()` instead of `dispatch()` to emit an event from an emitter. +- Use `attach()` instead of `addSubscriber()` and `detach()` instead of + `removeSubscriber()`. + +```php +$mock = new Mock(); +// 3.x +$request->getEventDispatcher()->addSubscriber($mock); +$request->getEventDispatcher()->removeSubscriber($mock); +// 4.x +$request->getEmitter()->attach($mock); +$request->getEmitter()->detach($mock); +``` + +Use the `on()` method to add a listener rather than the `addListener()` method. + +```php +// 3.x +$request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } ); +// 4.x +$request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } ); +``` + +## Http + +### General changes + +- The cacert.pem certificate has been moved to `src/cacert.pem`. +- Added the concept of adapters that are used to transfer requests over the + wire. +- Simplified the event system. +- Sending requests in parallel is still possible, but batching is no longer a + concept of the HTTP layer. Instead, you must use the `complete` and `error` + events to asynchronously manage parallel request transfers. +- `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`. +- `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`. +- QueryAggregators have been rewritten so that they are simply callable + functions. +- `GuzzleHttp\StaticClient` has been removed. Use the functions provided in + `functions.php` for an easy to use static client instance. +- Exceptions in `GuzzleHttp\Exception` have been updated to all extend from + `GuzzleHttp\Exception\TransferException`. + +### Client + +Calling methods like `get()`, `post()`, `head()`, etc. no longer create and +return a request, but rather creates a request, sends the request, and returns +the response. + +```php +// 3.0 +$request = $client->get('/'); +$response = $request->send(); + +// 4.0 +$response = $client->get('/'); + +// or, to mirror the previous behavior +$request = $client->createRequest('GET', '/'); +$response = $client->send($request); +``` + +`GuzzleHttp\ClientInterface` has changed. + +- The `send` method no longer accepts more than one request. Use `sendAll` to + send multiple requests in parallel. +- `setUserAgent()` has been removed. Use a default request option instead. You + could, for example, do something like: + `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`. +- `setSslVerification()` has been removed. Use default request options instead, + like `$client->setConfig('defaults/verify', true)`. + +`GuzzleHttp\Client` has changed. + +- The constructor now accepts only an associative array. You can include a + `base_url` string or array to use a URI template as the base URL of a client. + You can also specify a `defaults` key that is an associative array of default + request options. You can pass an `adapter` to use a custom adapter, + `batch_adapter` to use a custom adapter for sending requests in parallel, or + a `message_factory` to change the factory used to create HTTP requests and + responses. +- The client no longer emits a `client.create_request` event. +- Creating requests with a client no longer automatically utilize a URI + template. You must pass an array into a creational method (e.g., + `createRequest`, `get`, `put`, etc.) in order to expand a URI template. + +### Messages + +Messages no longer have references to their counterparts (i.e., a request no +longer has a reference to it's response, and a response no loger has a +reference to its request). This association is now managed through a +`GuzzleHttp\Adapter\TransactionInterface` object. You can get references to +these transaction objects using request events that are emitted over the +lifecycle of a request. + +#### Requests with a body + +- `GuzzleHttp\Message\EntityEnclosingRequest` and + `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The + separation between requests that contain a body and requests that do not + contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface` + handles both use cases. +- Any method that previously accepts a `GuzzleHttp\Response` object now accept a + `GuzzleHttp\Message\ResponseInterface`. +- `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to + `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create + both requests and responses and is implemented in + `GuzzleHttp\Message\MessageFactory`. +- POST field and file methods have been removed from the request object. You + must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface` + to control the format of a POST body. Requests that are created using a + standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use + a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if + the method is POST and no body is provided. + +```php +$request = $client->createRequest('POST', '/'); +$request->getBody()->setField('foo', 'bar'); +$request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r'))); +``` + +#### Headers + +- `GuzzleHttp\Message\Header` has been removed. Header values are now simply + represented by an array of values or as a string. Header values are returned + as a string by default when retrieving a header value from a message. You can + pass an optional argument of `true` to retrieve a header value as an array + of strings instead of a single concatenated string. +- `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to + `GuzzleHttp\Post`. This interface has been simplified and now allows the + addition of arbitrary headers. +- Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most + of the custom headers are now handled separately in specific + subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has + been updated to properly handle headers that contain parameters (like the + `Link` header). + +#### Responses + +- `GuzzleHttp\Message\Response::getInfo()` and + `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event + system to retrieve this type of information. +- `GuzzleHttp\Message\Response::getRawHeaders()` has been removed. +- `GuzzleHttp\Message\Response::getMessage()` has been removed. +- `GuzzleHttp\Message\Response::calculateAge()` and other cache specific + methods have moved to the CacheSubscriber. +- Header specific helper functions like `getContentMd5()` have been removed. + Just use `getHeader('Content-MD5')` instead. +- `GuzzleHttp\Message\Response::setRequest()` and + `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event + system to work with request and response objects as a transaction. +- `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the + Redirect subscriber instead. +- `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have + been removed. Use `getStatusCode()` instead. + +#### Streaming responses + +Streaming requests can now be created by a client directly, returning a +`GuzzleHttp\Message\ResponseInterface` object that contains a body stream +referencing an open PHP HTTP stream. + +```php +// 3.0 +use Guzzle\Stream\PhpStreamRequestFactory; +$request = $client->get('/'); +$factory = new PhpStreamRequestFactory(); +$stream = $factory->fromRequest($request); +$data = $stream->read(1024); + +// 4.0 +$response = $client->get('/', ['stream' => true]); +// Read some data off of the stream in the response body +$data = $response->getBody()->read(1024); +``` + +#### Redirects + +The `configureRedirects()` method has been removed in favor of a +`allow_redirects` request option. + +```php +// Standard redirects with a default of a max of 5 redirects +$request = $client->createRequest('GET', '/', ['allow_redirects' => true]); + +// Strict redirects with a custom number of redirects +$request = $client->createRequest('GET', '/', [ + 'allow_redirects' => ['max' => 5, 'strict' => true] +]); +``` + +#### EntityBody + +EntityBody interfaces and classes have been removed or moved to +`GuzzleHttp\Stream`. All classes and interfaces that once required +`GuzzleHttp\EntityBodyInterface` now require +`GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no +longer uses `GuzzleHttp\EntityBody::factory` but now uses +`GuzzleHttp\Stream\Stream::factory` or even better: +`GuzzleHttp\Stream\create()`. + +- `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface` +- `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream` +- `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream` +- `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream` +- `Guzzle\Http\IoEmittyinEntityBody` has been removed. + +#### Request lifecycle events + +Requests previously submitted a large number of requests. The number of events +emitted over the lifecycle of a request has been significantly reduced to make +it easier to understand how to extend the behavior of a request. All events +emitted during the lifecycle of a request now emit a custom +`GuzzleHttp\Event\EventInterface` object that contains context providing +methods and a way in which to modify the transaction at that specific point in +time (e.g., intercept the request and set a response on the transaction). + +- `request.before_send` has been renamed to `before` and now emits a + `GuzzleHttp\Event\BeforeEvent` +- `request.complete` has been renamed to `complete` and now emits a + `GuzzleHttp\Event\CompleteEvent`. +- `request.sent` has been removed. Use `complete`. +- `request.success` has been removed. Use `complete`. +- `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`. +- `request.exception` has been removed. Use `error`. +- `request.receive.status_line` has been removed. +- `curl.callback.progress` has been removed. Use a custom `StreamInterface` to + maintain a status update. +- `curl.callback.write` has been removed. Use a custom `StreamInterface` to + intercept writes. +- `curl.callback.read` has been removed. Use a custom `StreamInterface` to + intercept reads. + +`headers` is a new event that is emitted after the response headers of a +request have been received before the body of the response is downloaded. This +event emits a `GuzzleHttp\Event\HeadersEvent`. + +You can intercept a request and inject a response using the `intercept()` event +of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and +`GuzzleHttp\Event\ErrorEvent` event. + +See: http://docs.guzzlephp.org/en/latest/events.html + +## Inflection + +The `Guzzle\Inflection` namespace has been removed. This is not a core concern +of Guzzle. + +## Iterator + +The `Guzzle\Iterator` namespace has been removed. + +- `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and + `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of + Guzzle itself. +- `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent + class is shipped with PHP 5.4. +- `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because + it's easier to just wrap an iterator in a generator that maps values. + +For a replacement of these iterators, see https://github.com/nikic/iter + +## Log + +The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The +`Guzzle\Log` namespace has been removed. Guzzle now relies on +`Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been +moved to `GuzzleHttp\Subscriber\Log\Formatter`. + +## Parser + +The `Guzzle\Parser` namespace has been removed. This was previously used to +make it possible to plug in custom parsers for cookies, messages, URI +templates, and URLs; however, this level of complexity is not needed in Guzzle +so it has been removed. + +- Cookie: Cookie parsing logic has been moved to + `GuzzleHttp\Cookie\SetCookie::fromString`. +- Message: Message parsing logic for both requests and responses has been moved + to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only + used in debugging or deserializing messages, so it doesn't make sense for + Guzzle as a library to add this level of complexity to parsing messages. +- UriTemplate: URI template parsing has been moved to + `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL + URI template library if it is installed. +- Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously + it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary, + then developers are free to subclass `GuzzleHttp\Url`. + +## Plugin + +The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`. +Several plugins are shipping with the core Guzzle library under this namespace. + +- `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar + code has moved to `GuzzleHttp\Cookie`. +- `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin. +- `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is + received. +- `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin. +- `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before + sending. This subscriber is attached to all requests by default. +- `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin. + +The following plugins have been removed (third-parties are free to re-implement +these if needed): + +- `GuzzleHttp\Plugin\Async` has been removed. +- `GuzzleHttp\Plugin\CurlAuth` has been removed. +- `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This + functionality should instead be implemented with event listeners that occur + after normal response parsing occurs in the guzzle/command package. + +The following plugins are not part of the core Guzzle package, but are provided +in separate repositories: + +- `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be muchs simpler + to build custom retry policies using simple functions rather than various + chained classes. See: https://github.com/guzzle/retry-subscriber +- `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to + https://github.com/guzzle/cache-subscriber +- `Guzzle\Http\Plugin\Log\LogPlugin` has moved to + https://github.com/guzzle/log-subscriber +- `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to + https://github.com/guzzle/message-integrity-subscriber +- `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to + `GuzzleHttp\Subscriber\MockSubscriber`. +- `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to + https://github.com/guzzle/oauth-subscriber + +## Service + +The service description layer of Guzzle has moved into two separate packages: + +- http://github.com/guzzle/command Provides a high level abstraction over web + services by representing web service operations using commands. +- http://github.com/guzzle/guzzle-services Provides an implementation of + guzzle/command that provides request serialization and response parsing using + Guzzle service descriptions. + +## Stream + +Stream have moved to a separate package available at +https://github.com/guzzle/streams. + +`Guzzle\Stream\StreamInterface` has been given a large update to cleanly take +on the responsibilities of `Guzzle\Http\EntityBody` and +`Guzzle\Http\EntityBodyInterface` now that they have been removed. The number +of methods implemented by the `StreamInterface` has been drastically reduced to +allow developers to more easily extend and decorate stream behavior. + +## Removed methods from StreamInterface + +- `getStream` and `setStream` have been removed to better encapsulate streams. +- `getMetadata` and `setMetadata` have been removed in favor of + `GuzzleHttp\Stream\MetadataStreamInterface`. +- `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been + removed. This data is accessible when + using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`. +- `rewind` has been removed. Use `seek(0)` for a similar behavior. + +## Renamed methods + +- `detachStream` has been renamed to `detach`. +- `feof` has been renamed to `eof`. +- `ftell` has been renamed to `tell`. +- `readLine` has moved from an instance method to a static class method of + `GuzzleHttp\Stream\Stream`. + +## Metadata streams + +`GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams +that contain additional metadata accessible via `getMetadata()`. +`GuzzleHttp\Stream\StreamInterface::getMetadata` and +`GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed. + +## StreamRequestFactory + +The entire concept of the StreamRequestFactory has been removed. The way this +was used in Guzzle 3 broke the actual interface of sending streaming requests +(instead of getting back a Response, you got a StreamInterface). Streeaming +PHP requests are now implemented throught the `GuzzleHttp\Adapter\StreamAdapter`. + +3.6 to 3.7 +---------- + +### Deprecations + +- You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.: + +```php +\Guzzle\Common\Version::$emitWarnings = true; +``` + +The following APIs and options have been marked as deprecated: + +- Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead. +- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. +- Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. +- Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. +- Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. +- Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated +- Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. +- Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. +- Marked `Guzzle\Common\Collection::inject()` as deprecated. +- Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use + `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or + `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` + +3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational +request methods. When paired with a client's configuration settings, these options allow you to specify default settings +for various aspects of a request. Because these options make other previous configuration options redundant, several +configuration options and methods of a client and AbstractCommand have been deprecated. + +- Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`. +- Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`. +- Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')` +- Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0 + + $command = $client->getCommand('foo', array( + 'command.headers' => array('Test' => '123'), + 'command.response_body' => '/path/to/file' + )); + + // Should be changed to: + + $command = $client->getCommand('foo', array( + 'command.request_options' => array( + 'headers' => array('Test' => '123'), + 'save_as' => '/path/to/file' + ) + )); + +### Interface changes + +Additions and changes (you will need to update any implementations or subclasses you may have created): + +- Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: + createRequest, head, delete, put, patch, post, options, prepareRequest +- Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` +- Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` +- Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to + `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a + resource, string, or EntityBody into the $options parameter to specify the download location of the response. +- Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a + default `array()` +- Added `Guzzle\Stream\StreamInterface::isRepeatable` +- Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. + +The following methods were removed from interfaces. All of these methods are still available in the concrete classes +that implement them, but you should update your code to use alternative methods: + +- Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use + `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or + `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or + `$client->setDefaultOption('headers/{header_name}', 'value')`. or + `$client->setDefaultOption('headers', array('header_name' => 'value'))`. +- Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`. +- Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail. +- Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail. +- Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail. +- Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin. +- Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin. +- Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin. + +### Cache plugin breaking changes + +- CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a + CacheStorageInterface. These two objects and interface will be removed in a future version. +- Always setting X-cache headers on cached responses +- Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin +- `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface + $request, Response $response);` +- `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` +- `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` +- Added `CacheStorageInterface::purge($url)` +- `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin + $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, + CanCacheStrategyInterface $canCache = null)` +- Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` + +3.5 to 3.6 +---------- + +* Mixed casing of headers are now forced to be a single consistent casing across all values for that header. +* Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution +* Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). + For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader(). + Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request. +* Specific header implementations can be created for complex headers. When a message creates a header, it uses a + HeaderFactory which can map specific headers to specific header classes. There is now a Link header and + CacheControl header implementation. +* Moved getLinks() from Response to just be used on a Link header object. + +If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the +HeaderInterface (e.g. toArray(), getAll(), etc.). + +### Interface changes + +* Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate +* Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() +* Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in + Guzzle\Http\Curl\RequestMediator +* Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. +* Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface +* Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() + +### Removed deprecated functions + +* Removed Guzzle\Parser\ParserRegister::get(). Use getParser() +* Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). + +### Deprecations + +* The ability to case-insensitively search for header values +* Guzzle\Http\Message\Header::hasExactHeader +* Guzzle\Http\Message\Header::raw. Use getAll() +* Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object + instead. + +### Other changes + +* All response header helper functions return a string rather than mixing Header objects and strings inconsistently +* Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle + directly via interfaces +* Removed the injecting of a request object onto a response object. The methods to get and set a request still exist + but are a no-op until removed. +* Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a + `Guzzle\Service\Command\ArrayCommandInterface`. +* Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response + on a request while the request is still being transferred +* `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess + +3.3 to 3.4 +---------- + +Base URLs of a client now follow the rules of http://tools.ietf.org/html/rfc3986#section-5.2.2 when merging URLs. + +3.2 to 3.3 +---------- + +### Response::getEtag() quote stripping removed + +`Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header + +### Removed `Guzzle\Http\Utils` + +The `Guzzle\Http\Utils` class was removed. This class was only used for testing. + +### Stream wrapper and type + +`Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase. + +### curl.emit_io became emit_io + +Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the +'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' + +3.1 to 3.2 +---------- + +### CurlMulti is no longer reused globally + +Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added +to a single client can pollute requests dispatched from other clients. + +If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the +ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is +created. + +```php +$multi = new Guzzle\Http\Curl\CurlMulti(); +$builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json'); +$builder->addListener('service_builder.create_client', function ($event) use ($multi) { + $event['client']->setCurlMulti($multi); +} +}); +``` + +### No default path + +URLs no longer have a default path value of '/' if no path was specified. + +Before: + +```php +$request = $client->get('http://www.foo.com'); +echo $request->getUrl(); +// >> http://www.foo.com/ +``` + +After: + +```php +$request = $client->get('http://www.foo.com'); +echo $request->getUrl(); +// >> http://www.foo.com +``` + +### Less verbose BadResponseException + +The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and +response information. You can, however, get access to the request and response object by calling `getRequest()` or +`getResponse()` on the exception object. + +### Query parameter aggregation + +Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a +setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is +responsible for handling the aggregation of multi-valued query string variables into a flattened hash. + +2.8 to 3.x +---------- + +### Guzzle\Service\Inspector + +Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig` + +**Before** + +```php +use Guzzle\Service\Inspector; + +class YourClient extends \Guzzle\Service\Client +{ + public static function factory($config = array()) + { + $default = array(); + $required = array('base_url', 'username', 'api_key'); + $config = Inspector::fromConfig($config, $default, $required); + + $client = new self( + $config->get('base_url'), + $config->get('username'), + $config->get('api_key') + ); + $client->setConfig($config); + + $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); + + return $client; + } +``` + +**After** + +```php +use Guzzle\Common\Collection; + +class YourClient extends \Guzzle\Service\Client +{ + public static function factory($config = array()) + { + $default = array(); + $required = array('base_url', 'username', 'api_key'); + $config = Collection::fromConfig($config, $default, $required); + + $client = new self( + $config->get('base_url'), + $config->get('username'), + $config->get('api_key') + ); + $client->setConfig($config); + + $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); + + return $client; + } +``` + +### Convert XML Service Descriptions to JSON + +**Before** + +```xml + + + + + + Get a list of groups + + + Uses a search query to get a list of groups + + + + Create a group + + + + + Delete a group by ID + + + + + + + Update a group + + + + + + +``` + +**After** + +```json +{ + "name": "Zendesk REST API v2", + "apiVersion": "2012-12-31", + "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users", + "operations": { + "list_groups": { + "httpMethod":"GET", + "uri": "groups.json", + "summary": "Get a list of groups" + }, + "search_groups":{ + "httpMethod":"GET", + "uri": "search.json?query=\"{query} type:group\"", + "summary": "Uses a search query to get a list of groups", + "parameters":{ + "query":{ + "location": "uri", + "description":"Zendesk Search Query", + "type": "string", + "required": true + } + } + }, + "create_group": { + "httpMethod":"POST", + "uri": "groups.json", + "summary": "Create a group", + "parameters":{ + "data": { + "type": "array", + "location": "body", + "description":"Group JSON", + "filters": "json_encode", + "required": true + }, + "Content-Type":{ + "type": "string", + "location":"header", + "static": "application/json" + } + } + }, + "delete_group": { + "httpMethod":"DELETE", + "uri": "groups/{id}.json", + "summary": "Delete a group", + "parameters":{ + "id":{ + "location": "uri", + "description":"Group to delete by ID", + "type": "integer", + "required": true + } + } + }, + "get_group": { + "httpMethod":"GET", + "uri": "groups/{id}.json", + "summary": "Get a ticket", + "parameters":{ + "id":{ + "location": "uri", + "description":"Group to get by ID", + "type": "integer", + "required": true + } + } + }, + "update_group": { + "httpMethod":"PUT", + "uri": "groups/{id}.json", + "summary": "Update a group", + "parameters":{ + "id": { + "location": "uri", + "description":"Group to update by ID", + "type": "integer", + "required": true + }, + "data": { + "type": "array", + "location": "body", + "description":"Group JSON", + "filters": "json_encode", + "required": true + }, + "Content-Type":{ + "type": "string", + "location":"header", + "static": "application/json" + } + } + } +} +``` + +### Guzzle\Service\Description\ServiceDescription + +Commands are now called Operations + +**Before** + +```php +use Guzzle\Service\Description\ServiceDescription; + +$sd = new ServiceDescription(); +$sd->getCommands(); // @returns ApiCommandInterface[] +$sd->hasCommand($name); +$sd->getCommand($name); // @returns ApiCommandInterface|null +$sd->addCommand($command); // @param ApiCommandInterface $command +``` + +**After** + +```php +use Guzzle\Service\Description\ServiceDescription; + +$sd = new ServiceDescription(); +$sd->getOperations(); // @returns OperationInterface[] +$sd->hasOperation($name); +$sd->getOperation($name); // @returns OperationInterface|null +$sd->addOperation($operation); // @param OperationInterface $operation +``` + +### Guzzle\Common\Inflection\Inflector + +Namespace is now `Guzzle\Inflection\Inflector` + +### Guzzle\Http\Plugin + +Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below. + +### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log + +Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively. + +**Before** + +```php +use Guzzle\Common\Log\ClosureLogAdapter; +use Guzzle\Http\Plugin\LogPlugin; + +/** @var \Guzzle\Http\Client */ +$client; + +// $verbosity is an integer indicating desired message verbosity level +$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE); +``` + +**After** + +```php +use Guzzle\Log\ClosureLogAdapter; +use Guzzle\Log\MessageFormatter; +use Guzzle\Plugin\Log\LogPlugin; + +/** @var \Guzzle\Http\Client */ +$client; + +// $format is a string indicating desired message format -- @see MessageFormatter +$client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT); +``` + +### Guzzle\Http\Plugin\CurlAuthPlugin + +Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`. + +### Guzzle\Http\Plugin\ExponentialBackoffPlugin + +Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes. + +**Before** + +```php +use Guzzle\Http\Plugin\ExponentialBackoffPlugin; + +$backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge( + ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429) + )); + +$client->addSubscriber($backoffPlugin); +``` + +**After** + +```php +use Guzzle\Plugin\Backoff\BackoffPlugin; +use Guzzle\Plugin\Backoff\HttpBackoffStrategy; + +// Use convenient factory method instead -- see implementation for ideas of what +// you can do with chaining backoff strategies +$backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge( + HttpBackoffStrategy::getDefaultFailureCodes(), array(429) + )); +$client->addSubscriber($backoffPlugin); +``` + +### Known Issues + +#### [BUG] Accept-Encoding header behavior changed unintentionally. + +(See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e) + +In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to +properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen. +See issue #217 for a workaround, or use a version containing the fix. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/composer.json b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/composer.json new file mode 100644 index 00000000..d8bb1203 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/composer.json @@ -0,0 +1,38 @@ +{ + "name": "guzzlehttp/guzzle", + "type": "library", + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "keywords": ["framework", "http", "rest", "web service", "curl", "client", "HTTP client"], + "homepage": "http://guzzlephp.org/", + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.4.0", + "guzzlehttp/ringphp": "^1.1", + "react/promise": "^2.2" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0" + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "GuzzleHttp\\Tests\\": "tests/" + } + }, + "scripts": { + "test": "make test", + "test-ci": "make coverage" + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/BatchResults.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/BatchResults.php new file mode 100644 index 00000000..e5af433d --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/BatchResults.php @@ -0,0 +1,148 @@ +hash = $hash; + } + + /** + * Get the keys that are available on the batch result. + * + * @return array + */ + public function getKeys() + { + return iterator_to_array($this->hash); + } + + /** + * Gets a result from the container for the given object. When getting + * results for a batch of requests, provide the request object. + * + * @param object $forObject Object to retrieve the result for. + * + * @return mixed|null + */ + public function getResult($forObject) + { + return isset($this->hash[$forObject]) ? $this->hash[$forObject] : null; + } + + /** + * Get an array of successful results. + * + * @return array + */ + public function getSuccessful() + { + $results = []; + foreach ($this->hash as $key) { + if (!($this->hash[$key] instanceof \Exception)) { + $results[] = $this->hash[$key]; + } + } + + return $results; + } + + /** + * Get an array of failed results. + * + * @return array + */ + public function getFailures() + { + $results = []; + foreach ($this->hash as $key) { + if ($this->hash[$key] instanceof \Exception) { + $results[] = $this->hash[$key]; + } + } + + return $results; + } + + /** + * Allows iteration over all batch result values. + * + * @return \ArrayIterator + */ + public function getIterator() + { + $results = []; + foreach ($this->hash as $key) { + $results[] = $this->hash[$key]; + } + + return new \ArrayIterator($results); + } + + /** + * Counts the number of elements in the batch result. + * + * @return int + */ + public function count() + { + return count($this->hash); + } + + /** + * Checks if the batch contains a specific numerical array index. + * + * @param int $key Index to access + * + * @return bool + */ + public function offsetExists($key) + { + return $key < count($this->hash); + } + + /** + * Allows access of the batch using a numerical array index. + * + * @param int $key Index to access. + * + * @return mixed|null + */ + public function offsetGet($key) + { + $i = -1; + foreach ($this->hash as $obj) { + if ($key === ++$i) { + return $this->hash[$obj]; + } + } + + return null; + } + + public function offsetUnset($key) + { + throw new \RuntimeException('Not implemented'); + } + + public function offsetSet($key, $value) + { + throw new \RuntimeException('Not implemented'); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Client.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Client.php new file mode 100644 index 00000000..cf5dd469 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Client.php @@ -0,0 +1,362 @@ + [ + * 'http://www.foo.com/{version}/', + * ['version' => '123'] + * ], + * 'defaults' => [ + * 'timeout' => 10, + * 'allow_redirects' => false, + * 'proxy' => '192.168.16.1:10' + * ] + * ]); + * + * @param array $config Client configuration settings + * - base_url: Base URL of the client that is merged into relative URLs. + * Can be a string or an array that contains a URI template followed + * by an associative array of expansion variables to inject into the + * URI template. + * - handler: callable RingPHP handler used to transfer requests + * - message_factory: Factory used to create request and response object + * - defaults: Default request options to apply to each request + * - emitter: Event emitter used for request events + * - fsm: (internal use only) The request finite state machine. A + * function that accepts a transaction and optional final state. The + * function is responsible for transitioning a request through its + * lifecycle events. + */ + public function __construct(array $config = []) + { + $this->configureBaseUrl($config); + $this->configureDefaults($config); + + if (isset($config['emitter'])) { + $this->emitter = $config['emitter']; + } + + $this->messageFactory = isset($config['message_factory']) + ? $config['message_factory'] + : new MessageFactory(); + + if (isset($config['fsm'])) { + $this->fsm = $config['fsm']; + } else { + if (isset($config['handler'])) { + $handler = $config['handler']; + } elseif (isset($config['adapter'])) { + $handler = $config['adapter']; + } else { + $handler = Utils::getDefaultHandler(); + } + $this->fsm = new RequestFsm($handler, $this->messageFactory); + } + } + + public function getDefaultOption($keyOrPath = null) + { + return $keyOrPath === null + ? $this->defaults + : Utils::getPath($this->defaults, $keyOrPath); + } + + public function setDefaultOption($keyOrPath, $value) + { + Utils::setPath($this->defaults, $keyOrPath, $value); + } + + public function getBaseUrl() + { + return (string) $this->baseUrl; + } + + public function createRequest($method, $url = null, array $options = []) + { + $options = $this->mergeDefaults($options); + // Use a clone of the client's emitter + $options['config']['emitter'] = clone $this->getEmitter(); + $url = $url || (is_string($url) && strlen($url)) + ? $this->buildUrl($url) + : (string) $this->baseUrl; + + return $this->messageFactory->createRequest($method, $url, $options); + } + + public function get($url = null, $options = []) + { + return $this->send($this->createRequest('GET', $url, $options)); + } + + public function head($url = null, array $options = []) + { + return $this->send($this->createRequest('HEAD', $url, $options)); + } + + public function delete($url = null, array $options = []) + { + return $this->send($this->createRequest('DELETE', $url, $options)); + } + + public function put($url = null, array $options = []) + { + return $this->send($this->createRequest('PUT', $url, $options)); + } + + public function patch($url = null, array $options = []) + { + return $this->send($this->createRequest('PATCH', $url, $options)); + } + + public function post($url = null, array $options = []) + { + return $this->send($this->createRequest('POST', $url, $options)); + } + + public function options($url = null, array $options = []) + { + return $this->send($this->createRequest('OPTIONS', $url, $options)); + } + + public function send(RequestInterface $request) + { + $isFuture = $request->getConfig()->get('future'); + $trans = new Transaction($this, $request, $isFuture); + $fn = $this->fsm; + + try { + $fn($trans); + if ($isFuture) { + // Turn the normal response into a future if needed. + return $trans->response instanceof FutureInterface + ? $trans->response + : new FutureResponse(new FulfilledPromise($trans->response)); + } + // Resolve deep futures if this is not a future + // transaction. This accounts for things like retries + // that do not have an immediate side-effect. + while ($trans->response instanceof FutureInterface) { + $trans->response = $trans->response->wait(); + } + return $trans->response; + } catch (\Exception $e) { + if ($isFuture) { + // Wrap the exception in a promise + return new FutureResponse(new RejectedPromise($e)); + } + throw RequestException::wrapException($trans->request, $e); + } catch (\TypeError $error) { + $exception = new \Exception($error->getMessage(), $error->getCode(), $error); + if ($isFuture) { + // Wrap the exception in a promise + return new FutureResponse(new RejectedPromise($exception)); + } + throw RequestException::wrapException($trans->request, $exception); + } + } + + /** + * Get an array of default options to apply to the client + * + * @return array + */ + protected function getDefaultOptions() + { + $settings = [ + 'allow_redirects' => true, + 'exceptions' => true, + 'decode_content' => true, + 'verify' => true + ]; + + // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. + // We can only trust the HTTP_PROXY environment variable in a CLI + // process due to the fact that PHP has no reliable mechanism to + // get environment variables that start with "HTTP_". + if (php_sapi_name() == 'cli' && getenv('HTTP_PROXY')) { + $settings['proxy']['http'] = getenv('HTTP_PROXY'); + } + + if ($proxy = getenv('HTTPS_PROXY')) { + $settings['proxy']['https'] = $proxy; + } + + return $settings; + } + + /** + * Expand a URI template and inherit from the base URL if it's relative + * + * @param string|array $url URL or an array of the URI template to expand + * followed by a hash of template varnames. + * @return string + * @throws \InvalidArgumentException + */ + private function buildUrl($url) + { + // URI template (absolute or relative) + if (!is_array($url)) { + return strpos($url, '://') + ? (string) $url + : (string) $this->baseUrl->combine($url); + } + + if (!isset($url[1])) { + throw new \InvalidArgumentException('You must provide a hash of ' + . 'varname options in the second element of a URL array.'); + } + + // Absolute URL + if (strpos($url[0], '://')) { + return Utils::uriTemplate($url[0], $url[1]); + } + + // Combine the relative URL with the base URL + return (string) $this->baseUrl->combine( + Utils::uriTemplate($url[0], $url[1]) + ); + } + + private function configureBaseUrl(&$config) + { + if (!isset($config['base_url'])) { + $this->baseUrl = new Url('', ''); + } elseif (!is_array($config['base_url'])) { + $this->baseUrl = Url::fromString($config['base_url']); + } elseif (count($config['base_url']) < 2) { + throw new \InvalidArgumentException('You must provide a hash of ' + . 'varname options in the second element of a base_url array.'); + } else { + $this->baseUrl = Url::fromString( + Utils::uriTemplate( + $config['base_url'][0], + $config['base_url'][1] + ) + ); + $config['base_url'] = (string) $this->baseUrl; + } + } + + private function configureDefaults($config) + { + if (!isset($config['defaults'])) { + $this->defaults = $this->getDefaultOptions(); + } else { + $this->defaults = array_replace( + $this->getDefaultOptions(), + $config['defaults'] + ); + } + + // Add the default user-agent header + if (!isset($this->defaults['headers'])) { + $this->defaults['headers'] = [ + 'User-Agent' => Utils::getDefaultUserAgent() + ]; + } elseif (!Core::hasHeader($this->defaults, 'User-Agent')) { + // Add the User-Agent header if one was not already set + $this->defaults['headers']['User-Agent'] = Utils::getDefaultUserAgent(); + } + } + + /** + * Merges default options into the array passed by reference. + * + * @param array $options Options to modify by reference + * + * @return array + */ + private function mergeDefaults($options) + { + $defaults = $this->defaults; + + // Case-insensitively merge in default headers if both defaults and + // options have headers specified. + if (!empty($defaults['headers']) && !empty($options['headers'])) { + // Create a set of lowercased keys that are present. + $lkeys = []; + foreach (array_keys($options['headers']) as $k) { + $lkeys[strtolower($k)] = true; + } + // Merge in lowercase default keys when not present in above set. + foreach ($defaults['headers'] as $key => $value) { + if (!isset($lkeys[strtolower($key)])) { + $options['headers'][$key] = $value; + } + } + // No longer need to merge in headers. + unset($defaults['headers']); + } + + $result = array_replace_recursive($defaults, $options); + foreach ($options as $k => $v) { + if ($v === null) { + unset($result[$k]); + } + } + + return $result; + } + + /** + * @deprecated Use {@see GuzzleHttp\Pool} instead. + * @see GuzzleHttp\Pool + */ + public function sendAll($requests, array $options = []) + { + Pool::send($this, $requests, $options); + } + + /** + * @deprecated Use GuzzleHttp\Utils::getDefaultHandler + */ + public static function getDefaultHandler() + { + return Utils::getDefaultHandler(); + } + + /** + * @deprecated Use GuzzleHttp\Utils::getDefaultUserAgent + */ + public static function getDefaultUserAgent() + { + return Utils::getDefaultUserAgent(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/ClientInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/ClientInterface.php new file mode 100644 index 00000000..6668597d --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/ClientInterface.php @@ -0,0 +1,150 @@ +data = $data; + } + + /** + * Create a new collection from an array, validate the keys, and add default + * values where missing + * + * @param array $config Configuration values to apply. + * @param array $defaults Default parameters + * @param array $required Required parameter names + * + * @return self + * @throws \InvalidArgumentException if a parameter is missing + */ + public static function fromConfig( + array $config = [], + array $defaults = [], + array $required = [] + ) { + $data = $config + $defaults; + + if ($missing = array_diff($required, array_keys($data))) { + throw new \InvalidArgumentException( + 'Config is missing the following keys: ' . + implode(', ', $missing)); + } + + return new self($data); + } + + /** + * Removes all key value pairs + */ + public function clear() + { + $this->data = []; + } + + /** + * Get a specific key value. + * + * @param string $key Key to retrieve. + * + * @return mixed|null Value of the key or NULL + */ + public function get($key) + { + return isset($this->data[$key]) ? $this->data[$key] : null; + } + + /** + * Set a key value pair + * + * @param string $key Key to set + * @param mixed $value Value to set + */ + public function set($key, $value) + { + $this->data[$key] = $value; + } + + /** + * Add a value to a key. If a key of the same name has already been added, + * the key value will be converted into an array and the new value will be + * pushed to the end of the array. + * + * @param string $key Key to add + * @param mixed $value Value to add to the key + */ + public function add($key, $value) + { + if (!array_key_exists($key, $this->data)) { + $this->data[$key] = $value; + } elseif (is_array($this->data[$key])) { + $this->data[$key][] = $value; + } else { + $this->data[$key] = array($this->data[$key], $value); + } + } + + /** + * Remove a specific key value pair + * + * @param string $key A key to remove + */ + public function remove($key) + { + unset($this->data[$key]); + } + + /** + * Get all keys in the collection + * + * @return array + */ + public function getKeys() + { + return array_keys($this->data); + } + + /** + * Returns whether or not the specified key is present. + * + * @param string $key The key for which to check the existence. + * + * @return bool + */ + public function hasKey($key) + { + return array_key_exists($key, $this->data); + } + + /** + * Checks if any keys contains a certain value + * + * @param string $value Value to search for + * + * @return mixed Returns the key if the value was found FALSE if the value + * was not found. + */ + public function hasValue($value) + { + return array_search($value, $this->data, true); + } + + /** + * Replace the data of the object with the value of an array + * + * @param array $data Associative array of data + */ + public function replace(array $data) + { + $this->data = $data; + } + + /** + * Add and merge in a Collection or array of key value pair data. + * + * @param Collection|array $data Associative array of key value pair data + */ + public function merge($data) + { + foreach ($data as $key => $value) { + $this->add($key, $value); + } + } + + /** + * Overwrite key value pairs in this collection with all of the data from + * an array or collection. + * + * @param array|\Traversable $data Values to override over this config + */ + public function overwriteWith($data) + { + if (is_array($data)) { + $this->data = $data + $this->data; + } elseif ($data instanceof Collection) { + $this->data = $data->toArray() + $this->data; + } else { + foreach ($data as $key => $value) { + $this->data[$key] = $value; + } + } + } + + /** + * Returns a Collection containing all the elements of the collection after + * applying the callback function to each one. + * + * The callable should accept three arguments: + * - (string) $key + * - (string) $value + * - (array) $context + * + * The callable must return a the altered or unaltered value. + * + * @param callable $closure Map function to apply + * @param array $context Context to pass to the callable + * + * @return Collection + */ + public function map(callable $closure, array $context = []) + { + $collection = new static(); + foreach ($this as $key => $value) { + $collection[$key] = $closure($key, $value, $context); + } + + return $collection; + } + + /** + * Iterates over each key value pair in the collection passing them to the + * callable. If the callable returns true, the current value from input is + * returned into the result Collection. + * + * The callable must accept two arguments: + * - (string) $key + * - (string) $value + * + * @param callable $closure Evaluation function + * + * @return Collection + */ + public function filter(callable $closure) + { + $collection = new static(); + foreach ($this->data as $key => $value) { + if ($closure($key, $value)) { + $collection[$key] = $value; + } + } + + return $collection; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php new file mode 100644 index 00000000..f8ac7dd3 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -0,0 +1,248 @@ +strictMode = $strictMode; + + foreach ($cookieArray as $cookie) { + if (!($cookie instanceof SetCookie)) { + $cookie = new SetCookie($cookie); + } + $this->setCookie($cookie); + } + } + + /** + * Create a new Cookie jar from an associative array and domain. + * + * @param array $cookies Cookies to create the jar from + * @param string $domain Domain to set the cookies to + * + * @return self + */ + public static function fromArray(array $cookies, $domain) + { + $cookieJar = new self(); + foreach ($cookies as $name => $value) { + $cookieJar->setCookie(new SetCookie([ + 'Domain' => $domain, + 'Name' => $name, + 'Value' => $value, + 'Discard' => true + ])); + } + + return $cookieJar; + } + + /** + * Quote the cookie value if it is not already quoted and it contains + * problematic characters. + * + * @param string $value Value that may or may not need to be quoted + * + * @return string + */ + public static function getCookieValue($value) + { + if (substr($value, 0, 1) !== '"' && + substr($value, -1, 1) !== '"' && + strpbrk($value, ';,') + ) { + $value = '"' . $value . '"'; + } + + return $value; + } + + public function toArray() + { + return array_map(function (SetCookie $cookie) { + return $cookie->toArray(); + }, $this->getIterator()->getArrayCopy()); + } + + public function clear($domain = null, $path = null, $name = null) + { + if (!$domain) { + $this->cookies = []; + return; + } elseif (!$path) { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) use ($path, $domain) { + return !$cookie->matchesDomain($domain); + } + ); + } elseif (!$name) { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) use ($path, $domain) { + return !($cookie->matchesPath($path) && + $cookie->matchesDomain($domain)); + } + ); + } else { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) use ($path, $domain, $name) { + return !($cookie->getName() == $name && + $cookie->matchesPath($path) && + $cookie->matchesDomain($domain)); + } + ); + } + } + + public function clearSessionCookies() + { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) { + return !$cookie->getDiscard() && $cookie->getExpires(); + } + ); + } + + public function setCookie(SetCookie $cookie) + { + // Only allow cookies with set and valid domain, name, value + $result = $cookie->validate(); + if ($result !== true) { + if ($this->strictMode) { + throw new \RuntimeException('Invalid cookie: ' . $result); + } else { + $this->removeCookieIfEmpty($cookie); + return false; + } + } + + // Resolve conflicts with previously set cookies + foreach ($this->cookies as $i => $c) { + + // Two cookies are identical, when their path, and domain are + // identical. + if ($c->getPath() != $cookie->getPath() || + $c->getDomain() != $cookie->getDomain() || + $c->getName() != $cookie->getName() + ) { + continue; + } + + // The previously set cookie is a discard cookie and this one is + // not so allow the new cookie to be set + if (!$cookie->getDiscard() && $c->getDiscard()) { + unset($this->cookies[$i]); + continue; + } + + // If the new cookie's expiration is further into the future, then + // replace the old cookie + if ($cookie->getExpires() > $c->getExpires()) { + unset($this->cookies[$i]); + continue; + } + + // If the value has changed, we better change it + if ($cookie->getValue() !== $c->getValue()) { + unset($this->cookies[$i]); + continue; + } + + // The cookie exists, so no need to continue + return false; + } + + $this->cookies[] = $cookie; + + return true; + } + + public function count() + { + return count($this->cookies); + } + + public function getIterator() + { + return new \ArrayIterator(array_values($this->cookies)); + } + + public function extractCookies( + RequestInterface $request, + ResponseInterface $response + ) { + if ($cookieHeader = $response->getHeaderAsArray('Set-Cookie')) { + foreach ($cookieHeader as $cookie) { + $sc = SetCookie::fromString($cookie); + if (!$sc->getDomain()) { + $sc->setDomain($request->getHost()); + } + $this->setCookie($sc); + } + } + } + + public function addCookieHeader(RequestInterface $request) + { + $values = []; + $scheme = $request->getScheme(); + $host = $request->getHost(); + $path = $request->getPath(); + + foreach ($this->cookies as $cookie) { + if ($cookie->matchesPath($path) && + $cookie->matchesDomain($host) && + !$cookie->isExpired() && + (!$cookie->getSecure() || $scheme == 'https') + ) { + $values[] = $cookie->getName() . '=' + . self::getCookieValue($cookie->getValue()); + } + } + + if ($values) { + $request->setHeader('Cookie', implode('; ', $values)); + } + } + + /** + * If a cookie already exists and the server asks to set it again with a + * null value, the cookie must be deleted. + * + * @param SetCookie $cookie + */ + private function removeCookieIfEmpty(SetCookie $cookie) + { + $cookieValue = $cookie->getValue(); + if ($cookieValue === null || $cookieValue === '') { + $this->clear( + $cookie->getDomain(), + $cookie->getPath(), + $cookie->getName() + ); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php new file mode 100644 index 00000000..4ea8567e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php @@ -0,0 +1,75 @@ +filename = $cookieFile; + + if (file_exists($cookieFile)) { + $this->load($cookieFile); + } + } + + /** + * Saves the file when shutting down + */ + public function __destruct() + { + $this->save($this->filename); + } + + /** + * Saves the cookies to a file. + * + * @param string $filename File to save + * @throws \RuntimeException if the file cannot be found or created + */ + public function save($filename) + { + $json = []; + foreach ($this as $cookie) { + if ($cookie->getExpires() && !$cookie->getDiscard()) { + $json[] = $cookie->toArray(); + } + } + + if (false === file_put_contents($filename, json_encode($json))) { + // @codeCoverageIgnoreStart + throw new \RuntimeException("Unable to save file {$filename}"); + // @codeCoverageIgnoreEnd + } + } + + /** + * Load cookies from a JSON formatted file. + * + * Old cookies are kept unless overwritten by newly loaded ones. + * + * @param string $filename Cookie file to load. + * @throws \RuntimeException if the file cannot be loaded. + */ + public function load($filename) + { + $json = file_get_contents($filename); + if (false === $json) { + // @codeCoverageIgnoreStart + throw new \RuntimeException("Unable to load file {$filename}"); + // @codeCoverageIgnoreEnd + } + + $data = Utils::jsonDecode($json, true); + if (is_array($data)) { + foreach (Utils::jsonDecode($json, true) as $cookie) { + $this->setCookie(new SetCookie($cookie)); + } + } elseif (strlen($data)) { + throw new \RuntimeException("Invalid cookie file: {$filename}"); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php new file mode 100644 index 00000000..71a02d56 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php @@ -0,0 +1,66 @@ +sessionKey = $sessionKey; + $this->load(); + } + + /** + * Saves cookies to session when shutting down + */ + public function __destruct() + { + $this->save(); + } + + /** + * Save cookies to the client session + */ + public function save() + { + $json = []; + foreach ($this as $cookie) { + if ($cookie->getExpires() && !$cookie->getDiscard()) { + $json[] = $cookie->toArray(); + } + } + + $_SESSION[$this->sessionKey] = json_encode($json); + } + + /** + * Load the contents of the client session into the data array + */ + protected function load() + { + $cookieJar = isset($_SESSION[$this->sessionKey]) + ? $_SESSION[$this->sessionKey] + : null; + + $data = Utils::jsonDecode($cookieJar, true); + if (is_array($data)) { + foreach ($data as $cookie) { + $this->setCookie(new SetCookie($cookie)); + } + } elseif (strlen($data)) { + throw new \RuntimeException("Invalid cookie data"); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php new file mode 100644 index 00000000..6fdee0dd --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php @@ -0,0 +1,373 @@ + null, + 'Value' => null, + 'Domain' => null, + 'Path' => '/', + 'Max-Age' => null, + 'Expires' => null, + 'Secure' => false, + 'Discard' => false, + 'HttpOnly' => false + ]; + + /** @var array Cookie data */ + private $data; + + /** + * Create a new SetCookie object from a string + * + * @param string $cookie Set-Cookie header string + * + * @return self + */ + public static function fromString($cookie) + { + // Create the default return array + $data = self::$defaults; + // Explode the cookie string using a series of semicolons + $pieces = array_filter(array_map('trim', explode(';', $cookie))); + // The name of the cookie (first kvp) must include an equal sign. + if (empty($pieces) || !strpos($pieces[0], '=')) { + return new self($data); + } + + // Add the cookie pieces into the parsed data array + foreach ($pieces as $part) { + + $cookieParts = explode('=', $part, 2); + $key = trim($cookieParts[0]); + $value = isset($cookieParts[1]) + ? trim($cookieParts[1], " \n\r\t\0\x0B\"") + : true; + + // Only check for non-cookies when cookies have been found + if (empty($data['Name'])) { + $data['Name'] = $key; + $data['Value'] = $value; + } else { + foreach (array_keys(self::$defaults) as $search) { + if (!strcasecmp($search, $key)) { + $data[$search] = $value; + continue 2; + } + } + $data[$key] = $value; + } + } + + return new self($data); + } + + /** + * @param array $data Array of cookie data provided by a Cookie parser + */ + public function __construct(array $data = []) + { + $this->data = array_replace(self::$defaults, $data); + // Extract the Expires value and turn it into a UNIX timestamp if needed + if (!$this->getExpires() && $this->getMaxAge()) { + // Calculate the Expires date + $this->setExpires(time() + $this->getMaxAge()); + } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { + $this->setExpires($this->getExpires()); + } + } + + public function __toString() + { + $str = $this->data['Name'] . '=' . $this->data['Value'] . '; '; + foreach ($this->data as $k => $v) { + if ($k != 'Name' && $k != 'Value' && $v !== null && $v !== false) { + if ($k == 'Expires') { + $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; + } else { + $str .= ($v === true ? $k : "{$k}={$v}") . '; '; + } + } + } + + return rtrim($str, '; '); + } + + public function toArray() + { + return $this->data; + } + + /** + * Get the cookie name + * + * @return string + */ + public function getName() + { + return $this->data['Name']; + } + + /** + * Set the cookie name + * + * @param string $name Cookie name + */ + public function setName($name) + { + $this->data['Name'] = $name; + } + + /** + * Get the cookie value + * + * @return string + */ + public function getValue() + { + return $this->data['Value']; + } + + /** + * Set the cookie value + * + * @param string $value Cookie value + */ + public function setValue($value) + { + $this->data['Value'] = $value; + } + + /** + * Get the domain + * + * @return string|null + */ + public function getDomain() + { + return $this->data['Domain']; + } + + /** + * Set the domain of the cookie + * + * @param string $domain + */ + public function setDomain($domain) + { + $this->data['Domain'] = $domain; + } + + /** + * Get the path + * + * @return string + */ + public function getPath() + { + return $this->data['Path']; + } + + /** + * Set the path of the cookie + * + * @param string $path Path of the cookie + */ + public function setPath($path) + { + $this->data['Path'] = $path; + } + + /** + * Maximum lifetime of the cookie in seconds + * + * @return int|null + */ + public function getMaxAge() + { + return $this->data['Max-Age']; + } + + /** + * Set the max-age of the cookie + * + * @param int $maxAge Max age of the cookie in seconds + */ + public function setMaxAge($maxAge) + { + $this->data['Max-Age'] = $maxAge; + } + + /** + * The UNIX timestamp when the cookie Expires + * + * @return mixed + */ + public function getExpires() + { + return $this->data['Expires']; + } + + /** + * Set the unix timestamp for which the cookie will expire + * + * @param int $timestamp Unix timestamp + */ + public function setExpires($timestamp) + { + $this->data['Expires'] = is_numeric($timestamp) + ? (int) $timestamp + : strtotime($timestamp); + } + + /** + * Get whether or not this is a secure cookie + * + * @return null|bool + */ + public function getSecure() + { + return $this->data['Secure']; + } + + /** + * Set whether or not the cookie is secure + * + * @param bool $secure Set to true or false if secure + */ + public function setSecure($secure) + { + $this->data['Secure'] = $secure; + } + + /** + * Get whether or not this is a session cookie + * + * @return null|bool + */ + public function getDiscard() + { + return $this->data['Discard']; + } + + /** + * Set whether or not this is a session cookie + * + * @param bool $discard Set to true or false if this is a session cookie + */ + public function setDiscard($discard) + { + $this->data['Discard'] = $discard; + } + + /** + * Get whether or not this is an HTTP only cookie + * + * @return bool + */ + public function getHttpOnly() + { + return $this->data['HttpOnly']; + } + + /** + * Set whether or not this is an HTTP only cookie + * + * @param bool $httpOnly Set to true or false if this is HTTP only + */ + public function setHttpOnly($httpOnly) + { + $this->data['HttpOnly'] = $httpOnly; + } + + /** + * Check if the cookie matches a path value + * + * @param string $path Path to check against + * + * @return bool + */ + public function matchesPath($path) + { + return !$this->getPath() || 0 === stripos($path, $this->getPath()); + } + + /** + * Check if the cookie matches a domain value + * + * @param string $domain Domain to check against + * + * @return bool + */ + public function matchesDomain($domain) + { + // Remove the leading '.' as per spec in RFC 6265. + // http://tools.ietf.org/html/rfc6265#section-5.2.3 + $cookieDomain = ltrim($this->getDomain(), '.'); + + // Domain not set or exact match. + if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { + return true; + } + + // Matching the subdomain according to RFC 6265. + // http://tools.ietf.org/html/rfc6265#section-5.1.3 + if (filter_var($domain, FILTER_VALIDATE_IP)) { + return false; + } + + return (bool) preg_match('/\.' . preg_quote($cookieDomain) . '$/i', $domain); + } + + /** + * Check if the cookie is expired + * + * @return bool + */ + public function isExpired() + { + return $this->getExpires() !== null && time() > $this->getExpires(); + } + + /** + * Check if the cookie is valid according to RFC 6265 + * + * @return bool|string Returns true if valid or an error message if invalid + */ + public function validate() + { + // Names must not be empty, but can be 0 + $name = $this->getName(); + if (empty($name) && !is_numeric($name)) { + return 'The cookie name must not be empty'; + } + + // Check if any of the invalid characters are present in the cookie name + if (preg_match("/[=,; \t\r\n\013\014]/", $name)) { + return "Cookie name must not cannot invalid characters: =,; \\t\\r\\n\\013\\014"; + } + + // Value must not be empty, but can be 0 + $value = $this->getValue(); + if (empty($value) && !is_numeric($value)) { + return 'The cookie value must not be empty'; + } + + // Domains must not be empty, but can be 0 + // A "0" is not a valid internet domain, but may be used as server name + // in a private network. + $domain = $this->getDomain(); + if (empty($domain) && !is_numeric($domain)) { + return 'The cookie domain must not be empty'; + } + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractEvent.php new file mode 100644 index 00000000..0d2f4dbf --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractEvent.php @@ -0,0 +1,20 @@ +propagationStopped; + } + + public function stopPropagation() + { + $this->propagationStopped = true; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractRequestEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractRequestEvent.php new file mode 100644 index 00000000..8a6ee47c --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractRequestEvent.php @@ -0,0 +1,61 @@ +transaction = $transaction; + } + + /** + * Get the HTTP client associated with the event. + * + * @return ClientInterface + */ + public function getClient() + { + return $this->transaction->client; + } + + /** + * Get the request object + * + * @return RequestInterface + */ + public function getRequest() + { + return $this->transaction->request; + } + + /** + * Get the number of transaction retries. + * + * @return int + */ + public function getRetryCount() + { + return $this->transaction->retries; + } + + /** + * @return Transaction + */ + public function getTransaction() + { + return $this->transaction; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractRetryableEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractRetryableEvent.php new file mode 100644 index 00000000..bbbdfaf8 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractRetryableEvent.php @@ -0,0 +1,40 @@ +transaction->state = 'retry'; + + if ($afterDelay) { + $this->transaction->request->getConfig()->set('delay', $afterDelay); + } + + $this->stopPropagation(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractTransferEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractTransferEvent.php new file mode 100644 index 00000000..3b106df0 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/AbstractTransferEvent.php @@ -0,0 +1,63 @@ +transaction->transferInfo; + } + + return isset($this->transaction->transferInfo[$name]) + ? $this->transaction->transferInfo[$name] + : null; + } + + /** + * Returns true/false if a response is available. + * + * @return bool + */ + public function hasResponse() + { + return !($this->transaction->response instanceof FutureInterface); + } + + /** + * Get the response. + * + * @return ResponseInterface|null + */ + public function getResponse() + { + return $this->hasResponse() ? $this->transaction->response : null; + } + + /** + * Intercept the request and associate a response + * + * @param ResponseInterface $response Response to set + */ + public function intercept(ResponseInterface $response) + { + $this->transaction->response = $response; + $this->transaction->exception = null; + $this->stopPropagation(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/BeforeEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/BeforeEvent.php new file mode 100644 index 00000000..f313c375 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/BeforeEvent.php @@ -0,0 +1,26 @@ +transaction->response = $response; + $this->transaction->exception = null; + $this->stopPropagation(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/CompleteEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/CompleteEvent.php new file mode 100644 index 00000000..56cc557e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/CompleteEvent.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + * + * @link https://github.com/symfony/symfony/tree/master/src/Symfony/Component/EventDispatcher + */ +class Emitter implements EmitterInterface +{ + /** @var array */ + private $listeners = []; + + /** @var array */ + private $sorted = []; + + public function on($eventName, callable $listener, $priority = 0) + { + if ($priority === 'first') { + $priority = isset($this->listeners[$eventName]) + ? max(array_keys($this->listeners[$eventName])) + 1 + : 1; + } elseif ($priority === 'last') { + $priority = isset($this->listeners[$eventName]) + ? min(array_keys($this->listeners[$eventName])) - 1 + : -1; + } + + $this->listeners[$eventName][$priority][] = $listener; + unset($this->sorted[$eventName]); + } + + public function once($eventName, callable $listener, $priority = 0) + { + $onceListener = function ( + EventInterface $event + ) use (&$onceListener, $eventName, $listener, $priority) { + $this->removeListener($eventName, $onceListener); + $listener($event, $eventName); + }; + + $this->on($eventName, $onceListener, $priority); + } + + public function removeListener($eventName, callable $listener) + { + if (empty($this->listeners[$eventName])) { + return; + } + + foreach ($this->listeners[$eventName] as $priority => $listeners) { + if (false !== ($key = array_search($listener, $listeners, true))) { + unset( + $this->listeners[$eventName][$priority][$key], + $this->sorted[$eventName] + ); + } + } + } + + public function listeners($eventName = null) + { + // Return all events in a sorted priority order + if ($eventName === null) { + foreach (array_keys($this->listeners) as $eventName) { + if (empty($this->sorted[$eventName])) { + $this->listeners($eventName); + } + } + return $this->sorted; + } + + // Return the listeners for a specific event, sorted in priority order + if (empty($this->sorted[$eventName])) { + $this->sorted[$eventName] = []; + if (isset($this->listeners[$eventName])) { + krsort($this->listeners[$eventName], SORT_NUMERIC); + foreach ($this->listeners[$eventName] as $listeners) { + foreach ($listeners as $listener) { + $this->sorted[$eventName][] = $listener; + } + } + } + } + + return $this->sorted[$eventName]; + } + + public function hasListeners($eventName) + { + return !empty($this->listeners[$eventName]); + } + + public function emit($eventName, EventInterface $event) + { + if (isset($this->listeners[$eventName])) { + foreach ($this->listeners($eventName) as $listener) { + $listener($event, $eventName); + if ($event->isPropagationStopped()) { + break; + } + } + } + + return $event; + } + + public function attach(SubscriberInterface $subscriber) + { + foreach ($subscriber->getEvents() as $eventName => $listeners) { + if (is_array($listeners[0])) { + foreach ($listeners as $listener) { + $this->on( + $eventName, + [$subscriber, $listener[0]], + isset($listener[1]) ? $listener[1] : 0 + ); + } + } else { + $this->on( + $eventName, + [$subscriber, $listeners[0]], + isset($listeners[1]) ? $listeners[1] : 0 + ); + } + } + } + + public function detach(SubscriberInterface $subscriber) + { + foreach ($subscriber->getEvents() as $eventName => $listener) { + $this->removeListener($eventName, [$subscriber, $listener[0]]); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/EmitterInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/EmitterInterface.php new file mode 100644 index 00000000..9783efd1 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/EmitterInterface.php @@ -0,0 +1,96 @@ +transaction->exception; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ErrorEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ErrorEvent.php new file mode 100644 index 00000000..7432134d --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ErrorEvent.php @@ -0,0 +1,27 @@ +transaction->exception; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/EventInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/EventInterface.php new file mode 100644 index 00000000..97247e84 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/EventInterface.php @@ -0,0 +1,23 @@ +emitter) { + $this->emitter = new Emitter(); + } + + return $this->emitter; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ListenerAttacherTrait.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ListenerAttacherTrait.php new file mode 100644 index 00000000..407dc92d --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ListenerAttacherTrait.php @@ -0,0 +1,88 @@ +getEmitter(); + foreach ($listeners as $el) { + if ($el['once']) { + $emitter->once($el['name'], $el['fn'], $el['priority']); + } else { + $emitter->on($el['name'], $el['fn'], $el['priority']); + } + } + } + + /** + * Extracts the allowed events from the provided array, and ignores anything + * else in the array. The event listener must be specified as a callable or + * as an array of event listener data ("name", "fn", "priority", "once"). + * + * @param array $source Array containing callables or hashes of data to be + * prepared as event listeners. + * @param array $events Names of events to look for in the provided $source + * array. Other keys are ignored. + * @return array + */ + private function prepareListeners(array $source, array $events) + { + $listeners = []; + foreach ($events as $name) { + if (isset($source[$name])) { + $this->buildListener($name, $source[$name], $listeners); + } + } + + return $listeners; + } + + /** + * Creates a complete event listener definition from the provided array of + * listener data. Also works recursively if more than one listeners are + * contained in the provided array. + * + * @param string $name Name of the event the listener is for. + * @param array|callable $data Event listener data to prepare. + * @param array $listeners Array of listeners, passed by reference. + * + * @throws \InvalidArgumentException if the event data is malformed. + */ + private function buildListener($name, $data, &$listeners) + { + static $defaults = ['priority' => 0, 'once' => false]; + + // If a callable is provided, normalize it to the array format. + if (is_callable($data)) { + $data = ['fn' => $data]; + } + + // Prepare the listener and add it to the array, recursively. + if (isset($data['fn'])) { + $data['name'] = $name; + $listeners[] = $data + $defaults; + } elseif (is_array($data)) { + foreach ($data as $listenerData) { + $this->buildListener($name, $listenerData, $listeners); + } + } else { + throw new \InvalidArgumentException('Each event listener must be a ' + . 'callable or an associative array containing a "fn" key.'); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ProgressEvent.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ProgressEvent.php new file mode 100644 index 00000000..3fd0de4a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/ProgressEvent.php @@ -0,0 +1,51 @@ +downloadSize = $downloadSize; + $this->downloaded = $downloaded; + $this->uploadSize = $uploadSize; + $this->uploaded = $uploaded; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php new file mode 100644 index 00000000..f51d4206 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Event/RequestEvents.php @@ -0,0 +1,56 @@ + ['methodName']] + * - ['eventName' => ['methodName', $priority]] + * - ['eventName' => [['methodName'], ['otherMethod']] + * - ['eventName' => [['methodName'], ['otherMethod', $priority]] + * - ['eventName' => [['methodName', $priority], ['otherMethod', $priority]] + * + * @return array + */ + public function getEvents(); +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php new file mode 100644 index 00000000..fd78431e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php @@ -0,0 +1,7 @@ +response = $response; + } + /** + * Get the associated response + * + * @return ResponseInterface|null + */ + public function getResponse() + { + return $this->response; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php new file mode 100644 index 00000000..3f052d36 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/RequestException.php @@ -0,0 +1,121 @@ +getStatusCode() + : 0; + parent::__construct($message, $code, $previous); + $this->request = $request; + $this->response = $response; + } + + /** + * Wrap non-RequestExceptions with a RequestException + * + * @param RequestInterface $request + * @param \Exception $e + * + * @return RequestException + */ + public static function wrapException(RequestInterface $request, \Exception $e) + { + if ($e instanceof RequestException) { + return $e; + } elseif ($e instanceof ConnectException) { + return new HttpConnectException($e->getMessage(), $request, null, $e); + } else { + return new RequestException($e->getMessage(), $request, null, $e); + } + } + + /** + * Factory method to create a new exception with a normalized error message + * + * @param RequestInterface $request Request + * @param ResponseInterface $response Response received + * @param \Exception $previous Previous exception + * + * @return self + */ + public static function create( + RequestInterface $request, + ResponseInterface $response = null, + \Exception $previous = null + ) { + if (!$response) { + return new self('Error completing request', $request, null, $previous); + } + + $level = floor($response->getStatusCode() / 100); + if ($level == '4') { + $label = 'Client error response'; + $className = __NAMESPACE__ . '\\ClientException'; + } elseif ($level == '5') { + $label = 'Server error response'; + $className = __NAMESPACE__ . '\\ServerException'; + } else { + $label = 'Unsuccessful response'; + $className = __CLASS__; + } + + $message = $label . ' [url] ' . $request->getUrl() + . ' [status code] ' . $response->getStatusCode() + . ' [reason phrase] ' . $response->getReasonPhrase(); + + return new $className($message, $request, $response, $previous); + } + + /** + * Get the request that caused the exception + * + * @return RequestInterface + */ + public function getRequest() + { + return $this->request; + } + + /** + * Get the associated response + * + * @return ResponseInterface|null + */ + public function getResponse() + { + return $this->response; + } + + /** + * Check if a response was received + * + * @return bool + */ + public function hasResponse() + { + return $this->response !== null; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php new file mode 100644 index 00000000..7cdd3408 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php @@ -0,0 +1,7 @@ +error = $error; + } + + /** + * Get the associated error + * + * @return \LibXMLError|null + */ + public function getError() + { + return $this->error; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/HasDataTrait.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/HasDataTrait.php new file mode 100644 index 00000000..020dfc9a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/HasDataTrait.php @@ -0,0 +1,75 @@ +data); + } + + public function offsetGet($offset) + { + return isset($this->data[$offset]) ? $this->data[$offset] : null; + } + + public function offsetSet($offset, $value) + { + $this->data[$offset] = $value; + } + + public function offsetExists($offset) + { + return isset($this->data[$offset]); + } + + public function offsetUnset($offset) + { + unset($this->data[$offset]); + } + + public function toArray() + { + return $this->data; + } + + public function count() + { + return count($this->data); + } + + /** + * Get a value from the collection using a path syntax to retrieve nested + * data. + * + * @param string $path Path to traverse and retrieve a value from + * + * @return mixed|null + */ + public function getPath($path) + { + return Utils::getPath($this->data, $path); + } + + /** + * Set a value into a nested array key. Keys will be created as needed to + * set the value. + * + * @param string $path Path to set + * @param mixed $value Value to set at the key + * + * @throws \RuntimeException when trying to setPath using a nested path + * that travels through a scalar value + */ + public function setPath($path, $value) + { + Utils::setPath($this->data, $path, $value); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/AbstractMessage.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/AbstractMessage.php new file mode 100644 index 00000000..f118e0fe --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/AbstractMessage.php @@ -0,0 +1,253 @@ +getBody(); + } + + public function getProtocolVersion() + { + return $this->protocolVersion; + } + + public function getBody() + { + return $this->body; + } + + public function setBody(StreamInterface $body = null) + { + if ($body === null) { + // Setting a null body will remove the body of the request + $this->removeHeader('Content-Length'); + $this->removeHeader('Transfer-Encoding'); + } + + $this->body = $body; + } + + public function addHeader($header, $value) + { + if (is_array($value)) { + $current = array_merge($this->getHeaderAsArray($header), $value); + } else { + $current = $this->getHeaderAsArray($header); + $current[] = (string) $value; + } + + $this->setHeader($header, $current); + } + + public function addHeaders(array $headers) + { + foreach ($headers as $name => $header) { + $this->addHeader($name, $header); + } + } + + public function getHeader($header) + { + $name = strtolower($header); + return isset($this->headers[$name]) + ? implode(', ', $this->headers[$name]) + : ''; + } + + public function getHeaderAsArray($header) + { + $name = strtolower($header); + return isset($this->headers[$name]) ? $this->headers[$name] : []; + } + + public function getHeaders() + { + $headers = []; + foreach ($this->headers as $name => $values) { + $headers[$this->headerNames[$name]] = $values; + } + + return $headers; + } + + public function setHeader($header, $value) + { + $header = trim($header); + $name = strtolower($header); + $this->headerNames[$name] = $header; + + if (is_array($value)) { + foreach ($value as &$v) { + $v = trim($v); + } + $this->headers[$name] = $value; + } else { + $this->headers[$name] = [trim($value)]; + } + } + + public function setHeaders(array $headers) + { + $this->headers = $this->headerNames = []; + foreach ($headers as $key => $value) { + $this->addHeader($key, $value); + } + } + + public function hasHeader($header) + { + return isset($this->headers[strtolower($header)]); + } + + public function removeHeader($header) + { + $name = strtolower($header); + unset($this->headers[$name], $this->headerNames[$name]); + } + + /** + * Parse an array of header values containing ";" separated data into an + * array of associative arrays representing the header key value pair + * data of the header. When a parameter does not contain a value, but just + * contains a key, this function will inject a key with a '' string value. + * + * @param MessageInterface $message That contains the header + * @param string $header Header to retrieve from the message + * + * @return array Returns the parsed header values. + */ + public static function parseHeader(MessageInterface $message, $header) + { + static $trimmed = "\"' \n\t\r"; + $params = $matches = []; + + foreach (self::normalizeHeader($message, $header) as $val) { + $part = []; + foreach (preg_split('/;(?=([^"]*"[^"]*")*[^"]*$)/', $val) as $kvp) { + if (preg_match_all('/<[^>]+>|[^=]+/', $kvp, $matches)) { + $m = $matches[0]; + if (isset($m[1])) { + $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); + } else { + $part[] = trim($m[0], $trimmed); + } + } + } + if ($part) { + $params[] = $part; + } + } + + return $params; + } + + /** + * Converts an array of header values that may contain comma separated + * headers into an array of headers with no comma separated values. + * + * @param MessageInterface $message That contains the header + * @param string $header Header to retrieve from the message + * + * @return array Returns the normalized header field values. + */ + public static function normalizeHeader(MessageInterface $message, $header) + { + $h = $message->getHeaderAsArray($header); + for ($i = 0, $total = count($h); $i < $total; $i++) { + if (strpos($h[$i], ',') === false) { + continue; + } + foreach (preg_split('/,(?=([^"]*"[^"]*")*[^"]*$)/', $h[$i]) as $v) { + $h[] = trim($v); + } + unset($h[$i]); + } + + return $h; + } + + /** + * Gets the start-line and headers of a message as a string + * + * @param MessageInterface $message + * + * @return string + */ + public static function getStartLineAndHeaders(MessageInterface $message) + { + return static::getStartLine($message) + . self::getHeadersAsString($message); + } + + /** + * Gets the headers of a message as a string + * + * @param MessageInterface $message + * + * @return string + */ + public static function getHeadersAsString(MessageInterface $message) + { + $result = ''; + foreach ($message->getHeaders() as $name => $values) { + $result .= "\r\n{$name}: " . implode(', ', $values); + } + + return $result; + } + + /** + * Gets the start line of a message + * + * @param MessageInterface $message + * + * @return string + * @throws \InvalidArgumentException + */ + public static function getStartLine(MessageInterface $message) + { + if ($message instanceof RequestInterface) { + return trim($message->getMethod() . ' ' + . $message->getResource()) + . ' HTTP/' . $message->getProtocolVersion(); + } elseif ($message instanceof ResponseInterface) { + return 'HTTP/' . $message->getProtocolVersion() . ' ' + . $message->getStatusCode() . ' ' + . $message->getReasonPhrase(); + } else { + throw new \InvalidArgumentException('Unknown message type'); + } + } + + /** + * Accepts and modifies the options provided to the message in the + * constructor. + * + * Can be overridden in subclasses as necessary. + * + * @param array $options Options array passed by reference. + */ + protected function handleOptions(array &$options) + { + if (isset($options['protocol_version'])) { + $this->protocolVersion = $options['protocol_version']; + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/AppliesHeadersInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/AppliesHeadersInterface.php new file mode 100644 index 00000000..ca42f20f --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/AppliesHeadersInterface.php @@ -0,0 +1,24 @@ +then($onFulfilled, $onRejected, $onProgress), + [$future, 'wait'], + [$future, 'cancel'] + ); + } + + public function getStatusCode() + { + return $this->_value->getStatusCode(); + } + + public function setStatusCode($code) + { + $this->_value->setStatusCode($code); + } + + public function getReasonPhrase() + { + return $this->_value->getReasonPhrase(); + } + + public function setReasonPhrase($phrase) + { + $this->_value->setReasonPhrase($phrase); + } + + public function getEffectiveUrl() + { + return $this->_value->getEffectiveUrl(); + } + + public function setEffectiveUrl($url) + { + $this->_value->setEffectiveUrl($url); + } + + public function json(array $config = []) + { + return $this->_value->json($config); + } + + public function xml(array $config = []) + { + return $this->_value->xml($config); + } + + public function __toString() + { + try { + return $this->_value->__toString(); + } catch (\Exception $e) { + trigger_error($e->getMessage(), E_USER_WARNING); + return ''; + } + } + + public function getProtocolVersion() + { + return $this->_value->getProtocolVersion(); + } + + public function setBody(StreamInterface $body = null) + { + $this->_value->setBody($body); + } + + public function getBody() + { + return $this->_value->getBody(); + } + + public function getHeaders() + { + return $this->_value->getHeaders(); + } + + public function getHeader($header) + { + return $this->_value->getHeader($header); + } + + public function getHeaderAsArray($header) + { + return $this->_value->getHeaderAsArray($header); + } + + public function hasHeader($header) + { + return $this->_value->hasHeader($header); + } + + public function removeHeader($header) + { + $this->_value->removeHeader($header); + } + + public function addHeader($header, $value) + { + $this->_value->addHeader($header, $value); + } + + public function addHeaders(array $headers) + { + $this->_value->addHeaders($headers); + } + + public function setHeader($header, $value) + { + $this->_value->setHeader($header, $value); + } + + public function setHeaders(array $headers) + { + $this->_value->setHeaders($headers); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php new file mode 100644 index 00000000..b366d6d3 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageFactory.php @@ -0,0 +1,364 @@ + 1, 'timeout' => 1, 'verify' => 1, 'ssl_key' => 1, + 'cert' => 1, 'proxy' => 1, 'debug' => 1, 'save_to' => 1, 'stream' => 1, + 'expect' => 1, 'future' => 1 + ]; + + /** @var array Default allow_redirects request option settings */ + private static $defaultRedirect = [ + 'max' => 5, + 'strict' => false, + 'referer' => false, + 'protocols' => ['http', 'https'] + ]; + + /** + * @param array $customOptions Associative array of custom request option + * names mapping to functions used to apply + * the option. The function accepts the request + * and the option value to apply. + */ + public function __construct(array $customOptions = []) + { + $this->errorPlugin = new HttpError(); + $this->redirectPlugin = new Redirect(); + $this->customOptions = $customOptions; + } + + public function createResponse( + $statusCode, + array $headers = [], + $body = null, + array $options = [] + ) { + if (null !== $body) { + $body = Stream::factory($body); + } + + return new Response($statusCode, $headers, $body, $options); + } + + public function createRequest($method, $url, array $options = []) + { + // Handle the request protocol version option that needs to be + // specified in the request constructor. + if (isset($options['version'])) { + $options['config']['protocol_version'] = $options['version']; + unset($options['version']); + } + + $request = new Request($method, $url, [], null, + isset($options['config']) ? $options['config'] : []); + + unset($options['config']); + + // Use a POST body by default + if (strtoupper($method) == 'POST' + && !isset($options['body']) + && !isset($options['json']) + ) { + $options['body'] = []; + } + + if ($options) { + $this->applyOptions($request, $options); + } + + return $request; + } + + /** + * Create a request or response object from an HTTP message string + * + * @param string $message Message to parse + * + * @return RequestInterface|ResponseInterface + * @throws \InvalidArgumentException if unable to parse a message + */ + public function fromMessage($message) + { + static $parser; + if (!$parser) { + $parser = new MessageParser(); + } + + // Parse a response + if (strtoupper(substr($message, 0, 4)) == 'HTTP') { + $data = $parser->parseResponse($message); + return $this->createResponse( + $data['code'], + $data['headers'], + $data['body'] === '' ? null : $data['body'], + $data + ); + } + + // Parse a request + if (!($data = ($parser->parseRequest($message)))) { + throw new \InvalidArgumentException('Unable to parse request'); + } + + return $this->createRequest( + $data['method'], + Url::buildUrl($data['request_url']), + [ + 'headers' => $data['headers'], + 'body' => $data['body'] === '' ? null : $data['body'], + 'config' => [ + 'protocol_version' => $data['protocol_version'] + ] + ] + ); + } + + /** + * Apply POST fields and files to a request to attempt to give an accurate + * representation. + * + * @param RequestInterface $request Request to update + * @param array $body Body to apply + */ + protected function addPostData(RequestInterface $request, array $body) + { + static $fields = ['string' => true, 'array' => true, 'NULL' => true, + 'boolean' => true, 'double' => true, 'integer' => true]; + + $post = new PostBody(); + foreach ($body as $key => $value) { + if (isset($fields[gettype($value)])) { + $post->setField($key, $value); + } elseif ($value instanceof PostFileInterface) { + $post->addFile($value); + } else { + $post->addFile(new PostFile($key, $value)); + } + } + + if ($request->getHeader('Content-Type') == 'multipart/form-data') { + $post->forceMultipartUpload(true); + } + + $request->setBody($post); + } + + protected function applyOptions( + RequestInterface $request, + array $options = [] + ) { + $config = $request->getConfig(); + $emitter = $request->getEmitter(); + + foreach ($options as $key => $value) { + + if (isset(self::$configMap[$key])) { + $config[$key] = $value; + continue; + } + + switch ($key) { + + case 'allow_redirects': + + if ($value === false) { + continue 2; + } + + if ($value === true) { + $value = self::$defaultRedirect; + } elseif (!is_array($value)) { + throw new Iae('allow_redirects must be true, false, or array'); + } else { + // Merge the default settings with the provided settings + $value += self::$defaultRedirect; + } + + $config['redirect'] = $value; + $emitter->attach($this->redirectPlugin); + break; + + case 'decode_content': + + if ($value === false) { + continue 2; + } + + $config['decode_content'] = true; + if ($value !== true) { + $request->setHeader('Accept-Encoding', $value); + } + break; + + case 'headers': + + if (!is_array($value)) { + throw new Iae('header value must be an array'); + } + foreach ($value as $k => $v) { + $request->setHeader($k, $v); + } + break; + + case 'exceptions': + + if ($value === true) { + $emitter->attach($this->errorPlugin); + } + break; + + case 'body': + + if (is_array($value)) { + $this->addPostData($request, $value); + } elseif ($value !== null) { + $request->setBody(Stream::factory($value)); + } + break; + + case 'auth': + + if (!$value) { + continue 2; + } + + if (is_array($value)) { + $type = isset($value[2]) ? strtolower($value[2]) : 'basic'; + } else { + $type = strtolower($value); + } + + $config['auth'] = $value; + + if ($type == 'basic') { + $request->setHeader( + 'Authorization', + 'Basic ' . base64_encode("$value[0]:$value[1]") + ); + } elseif ($type == 'digest') { + // @todo: Do not rely on curl + $config->setPath('curl/' . CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); + $config->setPath('curl/' . CURLOPT_USERPWD, "$value[0]:$value[1]"); + } + break; + + case 'query': + + if ($value instanceof Query) { + $original = $request->getQuery(); + // Do not overwrite existing query string variables by + // overwriting the object with the query string data passed + // in the URL + $value->overwriteWith($original->toArray()); + $request->setQuery($value); + } elseif (is_array($value)) { + // Do not overwrite existing query string variables + $query = $request->getQuery(); + foreach ($value as $k => $v) { + if (!isset($query[$k])) { + $query[$k] = $v; + } + } + } else { + throw new Iae('query must be an array or Query object'); + } + break; + + case 'cookies': + + if ($value === true) { + static $cookie = null; + if (!$cookie) { + $cookie = new Cookie(); + } + $emitter->attach($cookie); + } elseif (is_array($value)) { + $emitter->attach( + new Cookie(CookieJar::fromArray($value, $request->getHost())) + ); + } elseif ($value instanceof CookieJarInterface) { + $emitter->attach(new Cookie($value)); + } elseif ($value !== false) { + throw new Iae('cookies must be an array, true, or CookieJarInterface'); + } + break; + + case 'events': + + if (!is_array($value)) { + throw new Iae('events must be an array'); + } + + $this->attachListeners($request, + $this->prepareListeners( + $value, + ['before', 'complete', 'error', 'progress', 'end'] + ) + ); + break; + + case 'subscribers': + + if (!is_array($value)) { + throw new Iae('subscribers must be an array'); + } + + foreach ($value as $subscribers) { + $emitter->attach($subscribers); + } + break; + + case 'json': + + $request->setBody(Stream::factory(json_encode($value))); + if (!$request->hasHeader('Content-Type')) { + $request->setHeader('Content-Type', 'application/json'); + } + break; + + default: + + // Check for custom handler functions. + if (isset($this->customOptions[$key])) { + $fn = $this->customOptions[$key]; + $fn($request, $value); + continue 2; + } + + throw new Iae("No method can handle the {$key} config key"); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageFactoryInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageFactoryInterface.php new file mode 100644 index 00000000..86ae9c7e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageFactoryInterface.php @@ -0,0 +1,71 @@ +getHeaders() as $name => $values) { + * echo $name . ": " . implode(", ", $values); + * } + * + * @return array Returns an associative array of the message's headers. + */ + public function getHeaders(); + + /** + * Retrieve a header by the given case-insensitive name. + * + * @param string $header Case-insensitive header name. + * + * @return string + */ + public function getHeader($header); + + /** + * Retrieves a header by the given case-insensitive name as an array of strings. + * + * @param string $header Case-insensitive header name. + * + * @return string[] + */ + public function getHeaderAsArray($header); + + /** + * Checks if a header exists by the given case-insensitive name. + * + * @param string $header Case-insensitive header name. + * + * @return bool Returns true if any header names match the given header + * name using a case-insensitive string comparison. Returns false if + * no matching header name is found in the message. + */ + public function hasHeader($header); + + /** + * Remove a specific header by case-insensitive name. + * + * @param string $header Case-insensitive header name. + */ + public function removeHeader($header); + + /** + * Appends a header value to any existing values associated with the + * given header name. + * + * @param string $header Header name to add + * @param string $value Value of the header + */ + public function addHeader($header, $value); + + /** + * Merges in an associative array of headers. + * + * Each array key MUST be a string representing the case-insensitive name + * of a header. Each value MUST be either a string or an array of strings. + * For each value, the value is appended to any existing header of the same + * name, or, if a header does not already exist by the given name, then the + * header is added. + * + * @param array $headers Associative array of headers to add to the message + */ + public function addHeaders(array $headers); + + /** + * Sets a header, replacing any existing values of any headers with the + * same case-insensitive name. + * + * The header values MUST be a string or an array of strings. + * + * @param string $header Header name + * @param string|array $value Header value(s) + */ + public function setHeader($header, $value); + + /** + * Sets headers, replacing any headers that have already been set on the + * message. + * + * The array keys MUST be a string. The array values must be either a + * string or an array of strings. + * + * @param array $headers Headers to set. + */ + public function setHeaders(array $headers); +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageParser.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageParser.php new file mode 100644 index 00000000..c3cc195e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/MessageParser.php @@ -0,0 +1,171 @@ +parseMessage($message))) { + return false; + } + + // Parse the protocol and protocol version + if (isset($parts['start_line'][2])) { + $startParts = explode('/', $parts['start_line'][2]); + $protocol = strtoupper($startParts[0]); + $version = isset($startParts[1]) ? $startParts[1] : '1.1'; + } else { + $protocol = 'HTTP'; + $version = '1.1'; + } + + $parsed = [ + 'method' => strtoupper($parts['start_line'][0]), + 'protocol' => $protocol, + 'protocol_version' => $version, + 'headers' => $parts['headers'], + 'body' => $parts['body'] + ]; + + $parsed['request_url'] = $this->getUrlPartsFromMessage( + (isset($parts['start_line'][1]) ? $parts['start_line'][1] : ''), $parsed); + + return $parsed; + } + + /** + * Parse an HTTP response message into an associative array of parts. + * + * @param string $message HTTP response to parse + * + * @return array|bool Returns false if the message is invalid + */ + public function parseResponse($message) + { + if (!($parts = $this->parseMessage($message))) { + return false; + } + + list($protocol, $version) = explode('/', trim($parts['start_line'][0])); + + return [ + 'protocol' => $protocol, + 'protocol_version' => $version, + 'code' => $parts['start_line'][1], + 'reason_phrase' => isset($parts['start_line'][2]) ? $parts['start_line'][2] : '', + 'headers' => $parts['headers'], + 'body' => $parts['body'] + ]; + } + + /** + * Parse a message into parts + * + * @param string $message Message to parse + * + * @return array|bool + */ + private function parseMessage($message) + { + if (!$message) { + return false; + } + + $startLine = null; + $headers = []; + $body = ''; + + // Iterate over each line in the message, accounting for line endings + $lines = preg_split('/(\\r?\\n)/', $message, -1, PREG_SPLIT_DELIM_CAPTURE); + for ($i = 0, $totalLines = count($lines); $i < $totalLines; $i += 2) { + + $line = $lines[$i]; + + // If two line breaks were encountered, then this is the end of body + if (empty($line)) { + if ($i < $totalLines - 1) { + $body = implode('', array_slice($lines, $i + 2)); + } + break; + } + + // Parse message headers + if (!$startLine) { + $startLine = explode(' ', $line, 3); + } elseif (strpos($line, ':')) { + $parts = explode(':', $line, 2); + $key = trim($parts[0]); + $value = isset($parts[1]) ? trim($parts[1]) : ''; + if (!isset($headers[$key])) { + $headers[$key] = $value; + } elseif (!is_array($headers[$key])) { + $headers[$key] = [$headers[$key], $value]; + } else { + $headers[$key][] = $value; + } + } + } + + return [ + 'start_line' => $startLine, + 'headers' => $headers, + 'body' => $body + ]; + } + + /** + * Create URL parts from HTTP message parts + * + * @param string $requestUrl Associated URL + * @param array $parts HTTP message parts + * + * @return array + */ + private function getUrlPartsFromMessage($requestUrl, array $parts) + { + // Parse the URL information from the message + $urlParts = ['path' => $requestUrl, 'scheme' => 'http']; + + // Check for the Host header + if (isset($parts['headers']['Host'])) { + $urlParts['host'] = $parts['headers']['Host']; + } elseif (isset($parts['headers']['host'])) { + $urlParts['host'] = $parts['headers']['host']; + } else { + $urlParts['host'] = null; + } + + if (false === strpos($urlParts['host'], ':')) { + $urlParts['port'] = ''; + } else { + $hostParts = explode(':', $urlParts['host']); + $urlParts['host'] = trim($hostParts[0]); + $urlParts['port'] = (int) trim($hostParts[1]); + if ($urlParts['port'] == 443) { + $urlParts['scheme'] = 'https'; + } + } + + // Check if a query is present + $path = $urlParts['path']; + $qpos = strpos($path, '?'); + if ($qpos) { + $urlParts['query'] = substr($path, $qpos + 1); + $urlParts['path'] = substr($path, 0, $qpos); + } else { + $urlParts['query'] = ''; + } + + return $urlParts; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/Request.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/Request.php new file mode 100644 index 00000000..38714af8 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/Request.php @@ -0,0 +1,195 @@ +setUrl($url); + $this->method = strtoupper($method); + $this->handleOptions($options); + $this->transferOptions = new Collection($options); + $this->addPrepareEvent(); + + if ($body !== null) { + $this->setBody($body); + } + + if ($headers) { + foreach ($headers as $key => $value) { + $this->addHeader($key, $value); + } + } + } + + public function __clone() + { + if ($this->emitter) { + $this->emitter = clone $this->emitter; + } + $this->transferOptions = clone $this->transferOptions; + $this->url = clone $this->url; + } + + public function setUrl($url) + { + $this->url = $url instanceof Url ? $url : Url::fromString($url); + $this->updateHostHeaderFromUrl(); + } + + public function getUrl() + { + return (string) $this->url; + } + + public function setQuery($query) + { + $this->url->setQuery($query); + } + + public function getQuery() + { + return $this->url->getQuery(); + } + + public function setMethod($method) + { + $this->method = strtoupper($method); + } + + public function getMethod() + { + return $this->method; + } + + public function getScheme() + { + return $this->url->getScheme(); + } + + public function setScheme($scheme) + { + $this->url->setScheme($scheme); + } + + public function getPort() + { + return $this->url->getPort(); + } + + public function setPort($port) + { + $this->url->setPort($port); + $this->updateHostHeaderFromUrl(); + } + + public function getHost() + { + return $this->url->getHost(); + } + + public function setHost($host) + { + $this->url->setHost($host); + $this->updateHostHeaderFromUrl(); + } + + public function getPath() + { + return '/' . ltrim($this->url->getPath(), '/'); + } + + public function setPath($path) + { + $this->url->setPath($path); + } + + public function getResource() + { + $resource = $this->getPath(); + if ($query = (string) $this->url->getQuery()) { + $resource .= '?' . $query; + } + + return $resource; + } + + public function getConfig() + { + return $this->transferOptions; + } + + protected function handleOptions(array &$options) + { + parent::handleOptions($options); + // Use a custom emitter if one is specified, and remove it from + // options that are exposed through getConfig() + if (isset($options['emitter'])) { + $this->emitter = $options['emitter']; + unset($options['emitter']); + } + } + + /** + * Adds a subscriber that ensures a request's body is prepared before + * sending. + */ + private function addPrepareEvent() + { + static $subscriber; + if (!$subscriber) { + $subscriber = new Prepare(); + } + + $this->getEmitter()->attach($subscriber); + } + + private function updateHostHeaderFromUrl() + { + $port = $this->url->getPort(); + $scheme = $this->url->getScheme(); + if ($host = $this->url->getHost()) { + if (($port == 80 && $scheme == 'http') || + ($port == 443 && $scheme == 'https') + ) { + $this->setHeader('Host', $host); + } else { + $this->setHeader('Host', "{$host}:{$port}"); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/RequestInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/RequestInterface.php new file mode 100644 index 00000000..f6a69d1e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/RequestInterface.php @@ -0,0 +1,136 @@ + 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 208 => 'Already Reported', + 226 => 'IM Used', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 424 => 'Failed Dependency', + 425 => 'Reserved for WebDAV advanced collections expired proposal', + 426 => 'Upgrade required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates (Experimental)', + 507 => 'Insufficient Storage', + 508 => 'Loop Detected', + 510 => 'Not Extended', + 511 => 'Network Authentication Required', + ]; + + /** @var string The reason phrase of the response (human readable code) */ + private $reasonPhrase; + + /** @var string The status code of the response */ + private $statusCode; + + /** @var string The effective URL that returned this response */ + private $effectiveUrl; + + /** + * @param int|string $statusCode The response status code (e.g. 200) + * @param array $headers The response headers + * @param StreamInterface $body The body of the response + * @param array $options Response message options + * - reason_phrase: Set a custom reason phrase + * - protocol_version: Set a custom protocol version + */ + public function __construct( + $statusCode, + array $headers = [], + StreamInterface $body = null, + array $options = [] + ) { + $this->statusCode = (int) $statusCode; + $this->handleOptions($options); + + // Assume a reason phrase if one was not applied as an option + if (!$this->reasonPhrase && + isset(self::$statusTexts[$this->statusCode]) + ) { + $this->reasonPhrase = self::$statusTexts[$this->statusCode]; + } + + if ($headers) { + $this->setHeaders($headers); + } + + if ($body) { + $this->setBody($body); + } + } + + public function getStatusCode() + { + return $this->statusCode; + } + + public function setStatusCode($code) + { + return $this->statusCode = (int) $code; + } + + public function getReasonPhrase() + { + return $this->reasonPhrase; + } + + public function setReasonPhrase($phrase) + { + return $this->reasonPhrase = $phrase; + } + + public function json(array $config = []) + { + try { + return Utils::jsonDecode( + (string) $this->getBody(), + isset($config['object']) ? !$config['object'] : true, + 512, + isset($config['big_int_strings']) ? JSON_BIGINT_AS_STRING : 0 + ); + } catch (\InvalidArgumentException $e) { + throw new ParseException( + $e->getMessage(), + $this + ); + } + } + + public function xml(array $config = []) + { + $disableEntities = libxml_disable_entity_loader(true); + $internalErrors = libxml_use_internal_errors(true); + + try { + // Allow XML to be retrieved even if there is no response body + $xml = new \SimpleXMLElement( + (string) $this->getBody() ?: '', + isset($config['libxml_options']) ? $config['libxml_options'] : LIBXML_NONET, + false, + isset($config['ns']) ? $config['ns'] : '', + isset($config['ns_is_prefix']) ? $config['ns_is_prefix'] : false + ); + libxml_disable_entity_loader($disableEntities); + libxml_use_internal_errors($internalErrors); + } catch (\Exception $e) { + libxml_disable_entity_loader($disableEntities); + libxml_use_internal_errors($internalErrors); + throw new XmlParseException( + 'Unable to parse response body into XML: ' . $e->getMessage(), + $this, + $e, + (libxml_get_last_error()) ?: null + ); + } + + return $xml; + } + + public function getEffectiveUrl() + { + return $this->effectiveUrl; + } + + public function setEffectiveUrl($url) + { + $this->effectiveUrl = $url; + } + + /** + * Accepts and modifies the options provided to the response in the + * constructor. + * + * @param array $options Options array passed by reference. + */ + protected function handleOptions(array &$options = []) + { + parent::handleOptions($options); + if (isset($options['reason_phrase'])) { + $this->reasonPhrase = $options['reason_phrase']; + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/ResponseInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/ResponseInterface.php new file mode 100644 index 00000000..c0ae9be9 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Message/ResponseInterface.php @@ -0,0 +1,111 @@ + 'text/vnd.in3d.3dml', + '3g2' => 'video/3gpp2', + '3gp' => 'video/3gpp', + '7z' => 'application/x-7z-compressed', + 'aab' => 'application/x-authorware-bin', + 'aac' => 'audio/x-aac', + 'aam' => 'application/x-authorware-map', + 'aas' => 'application/x-authorware-seg', + 'abw' => 'application/x-abiword', + 'ac' => 'application/pkix-attr-cert', + 'acc' => 'application/vnd.americandynamics.acc', + 'ace' => 'application/x-ace-compressed', + 'acu' => 'application/vnd.acucobol', + 'acutc' => 'application/vnd.acucorp', + 'adp' => 'audio/adpcm', + 'aep' => 'application/vnd.audiograph', + 'afm' => 'application/x-font-type1', + 'afp' => 'application/vnd.ibm.modcap', + 'ahead' => 'application/vnd.ahead.space', + 'ai' => 'application/postscript', + 'aif' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'air' => 'application/vnd.adobe.air-application-installer-package+zip', + 'ait' => 'application/vnd.dvb.ait', + 'ami' => 'application/vnd.amiga.ami', + 'apk' => 'application/vnd.android.package-archive', + 'application' => 'application/x-ms-application', + 'apr' => 'application/vnd.lotus-approach', + 'asa' => 'text/plain', + 'asax' => 'application/octet-stream', + 'asc' => 'application/pgp-signature', + 'ascx' => 'text/plain', + 'asf' => 'video/x-ms-asf', + 'ashx' => 'text/plain', + 'asm' => 'text/x-asm', + 'asmx' => 'text/plain', + 'aso' => 'application/vnd.accpac.simply.aso', + 'asp' => 'text/plain', + 'aspx' => 'text/plain', + 'asx' => 'video/x-ms-asf', + 'atc' => 'application/vnd.acucorp', + 'atom' => 'application/atom+xml', + 'atomcat' => 'application/atomcat+xml', + 'atomsvc' => 'application/atomsvc+xml', + 'atx' => 'application/vnd.antix.game-component', + 'au' => 'audio/basic', + 'avi' => 'video/x-msvideo', + 'aw' => 'application/applixware', + 'axd' => 'text/plain', + 'azf' => 'application/vnd.airzip.filesecure.azf', + 'azs' => 'application/vnd.airzip.filesecure.azs', + 'azw' => 'application/vnd.amazon.ebook', + 'bat' => 'application/x-msdownload', + 'bcpio' => 'application/x-bcpio', + 'bdf' => 'application/x-font-bdf', + 'bdm' => 'application/vnd.syncml.dm+wbxml', + 'bed' => 'application/vnd.realvnc.bed', + 'bh2' => 'application/vnd.fujitsu.oasysprs', + 'bin' => 'application/octet-stream', + 'bmi' => 'application/vnd.bmi', + 'bmp' => 'image/bmp', + 'book' => 'application/vnd.framemaker', + 'box' => 'application/vnd.previewsystems.box', + 'boz' => 'application/x-bzip2', + 'bpk' => 'application/octet-stream', + 'btif' => 'image/prs.btif', + 'bz' => 'application/x-bzip', + 'bz2' => 'application/x-bzip2', + 'c' => 'text/x-c', + 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', + 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', + 'c4d' => 'application/vnd.clonk.c4group', + 'c4f' => 'application/vnd.clonk.c4group', + 'c4g' => 'application/vnd.clonk.c4group', + 'c4p' => 'application/vnd.clonk.c4group', + 'c4u' => 'application/vnd.clonk.c4group', + 'cab' => 'application/vnd.ms-cab-compressed', + 'car' => 'application/vnd.curl.car', + 'cat' => 'application/vnd.ms-pki.seccat', + 'cc' => 'text/x-c', + 'cct' => 'application/x-director', + 'ccxml' => 'application/ccxml+xml', + 'cdbcmsg' => 'application/vnd.contact.cmsg', + 'cdf' => 'application/x-netcdf', + 'cdkey' => 'application/vnd.mediastation.cdkey', + 'cdmia' => 'application/cdmi-capability', + 'cdmic' => 'application/cdmi-container', + 'cdmid' => 'application/cdmi-domain', + 'cdmio' => 'application/cdmi-object', + 'cdmiq' => 'application/cdmi-queue', + 'cdx' => 'chemical/x-cdx', + 'cdxml' => 'application/vnd.chemdraw+xml', + 'cdy' => 'application/vnd.cinderella', + 'cer' => 'application/pkix-cert', + 'cfc' => 'application/x-coldfusion', + 'cfm' => 'application/x-coldfusion', + 'cgm' => 'image/cgm', + 'chat' => 'application/x-chat', + 'chm' => 'application/vnd.ms-htmlhelp', + 'chrt' => 'application/vnd.kde.kchart', + 'cif' => 'chemical/x-cif', + 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', + 'cil' => 'application/vnd.ms-artgalry', + 'cla' => 'application/vnd.claymore', + 'class' => 'application/java-vm', + 'clkk' => 'application/vnd.crick.clicker.keyboard', + 'clkp' => 'application/vnd.crick.clicker.palette', + 'clkt' => 'application/vnd.crick.clicker.template', + 'clkw' => 'application/vnd.crick.clicker.wordbank', + 'clkx' => 'application/vnd.crick.clicker', + 'clp' => 'application/x-msclip', + 'cmc' => 'application/vnd.cosmocaller', + 'cmdf' => 'chemical/x-cmdf', + 'cml' => 'chemical/x-cml', + 'cmp' => 'application/vnd.yellowriver-custom-menu', + 'cmx' => 'image/x-cmx', + 'cod' => 'application/vnd.rim.cod', + 'com' => 'application/x-msdownload', + 'conf' => 'text/plain', + 'cpio' => 'application/x-cpio', + 'cpp' => 'text/x-c', + 'cpt' => 'application/mac-compactpro', + 'crd' => 'application/x-mscardfile', + 'crl' => 'application/pkix-crl', + 'crt' => 'application/x-x509-ca-cert', + 'cryptonote' => 'application/vnd.rig.cryptonote', + 'cs' => 'text/plain', + 'csh' => 'application/x-csh', + 'csml' => 'chemical/x-csml', + 'csp' => 'application/vnd.commonspace', + 'css' => 'text/css', + 'cst' => 'application/x-director', + 'csv' => 'text/csv', + 'cu' => 'application/cu-seeme', + 'curl' => 'text/vnd.curl', + 'cww' => 'application/prs.cww', + 'cxt' => 'application/x-director', + 'cxx' => 'text/x-c', + 'dae' => 'model/vnd.collada+xml', + 'daf' => 'application/vnd.mobius.daf', + 'dataless' => 'application/vnd.fdsn.seed', + 'davmount' => 'application/davmount+xml', + 'dcr' => 'application/x-director', + 'dcurl' => 'text/vnd.curl.dcurl', + 'dd2' => 'application/vnd.oma.dd2+xml', + 'ddd' => 'application/vnd.fujixerox.ddd', + 'deb' => 'application/x-debian-package', + 'def' => 'text/plain', + 'deploy' => 'application/octet-stream', + 'der' => 'application/x-x509-ca-cert', + 'dfac' => 'application/vnd.dreamfactory', + 'dic' => 'text/x-c', + 'dir' => 'application/x-director', + 'dis' => 'application/vnd.mobius.dis', + 'dist' => 'application/octet-stream', + 'distz' => 'application/octet-stream', + 'djv' => 'image/vnd.djvu', + 'djvu' => 'image/vnd.djvu', + 'dll' => 'application/x-msdownload', + 'dmg' => 'application/octet-stream', + 'dms' => 'application/octet-stream', + 'dna' => 'application/vnd.dna', + 'doc' => 'application/msword', + 'docm' => 'application/vnd.ms-word.document.macroenabled.12', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dot' => 'application/msword', + 'dotm' => 'application/vnd.ms-word.template.macroenabled.12', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', + 'dp' => 'application/vnd.osgi.dp', + 'dpg' => 'application/vnd.dpgraph', + 'dra' => 'audio/vnd.dra', + 'dsc' => 'text/prs.lines.tag', + 'dssc' => 'application/dssc+der', + 'dtb' => 'application/x-dtbook+xml', + 'dtd' => 'application/xml-dtd', + 'dts' => 'audio/vnd.dts', + 'dtshd' => 'audio/vnd.dts.hd', + 'dump' => 'application/octet-stream', + 'dvi' => 'application/x-dvi', + 'dwf' => 'model/vnd.dwf', + 'dwg' => 'image/vnd.dwg', + 'dxf' => 'image/vnd.dxf', + 'dxp' => 'application/vnd.spotfire.dxp', + 'dxr' => 'application/x-director', + 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', + 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', + 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', + 'ecma' => 'application/ecmascript', + 'edm' => 'application/vnd.novadigm.edm', + 'edx' => 'application/vnd.novadigm.edx', + 'efif' => 'application/vnd.picsel', + 'ei6' => 'application/vnd.pg.osasli', + 'elc' => 'application/octet-stream', + 'eml' => 'message/rfc822', + 'emma' => 'application/emma+xml', + 'eol' => 'audio/vnd.digital-winds', + 'eot' => 'application/vnd.ms-fontobject', + 'eps' => 'application/postscript', + 'epub' => 'application/epub+zip', + 'es3' => 'application/vnd.eszigno3+xml', + 'esf' => 'application/vnd.epson.esf', + 'et3' => 'application/vnd.eszigno3+xml', + 'etx' => 'text/x-setext', + 'exe' => 'application/x-msdownload', + 'exi' => 'application/exi', + 'ext' => 'application/vnd.novadigm.ext', + 'ez' => 'application/andrew-inset', + 'ez2' => 'application/vnd.ezpix-album', + 'ez3' => 'application/vnd.ezpix-package', + 'f' => 'text/x-fortran', + 'f4v' => 'video/x-f4v', + 'f77' => 'text/x-fortran', + 'f90' => 'text/x-fortran', + 'fbs' => 'image/vnd.fastbidsheet', + 'fcs' => 'application/vnd.isac.fcs', + 'fdf' => 'application/vnd.fdf', + 'fe_launch' => 'application/vnd.denovo.fcselayout-link', + 'fg5' => 'application/vnd.fujitsu.oasysgp', + 'fgd' => 'application/x-director', + 'fh' => 'image/x-freehand', + 'fh4' => 'image/x-freehand', + 'fh5' => 'image/x-freehand', + 'fh7' => 'image/x-freehand', + 'fhc' => 'image/x-freehand', + 'fig' => 'application/x-xfig', + 'fli' => 'video/x-fli', + 'flo' => 'application/vnd.micrografx.flo', + 'flv' => 'video/x-flv', + 'flw' => 'application/vnd.kde.kivio', + 'flx' => 'text/vnd.fmi.flexstor', + 'fly' => 'text/vnd.fly', + 'fm' => 'application/vnd.framemaker', + 'fnc' => 'application/vnd.frogans.fnc', + 'for' => 'text/x-fortran', + 'fpx' => 'image/vnd.fpx', + 'frame' => 'application/vnd.framemaker', + 'fsc' => 'application/vnd.fsc.weblaunch', + 'fst' => 'image/vnd.fst', + 'ftc' => 'application/vnd.fluxtime.clip', + 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', + 'fvt' => 'video/vnd.fvt', + 'fxp' => 'application/vnd.adobe.fxp', + 'fxpl' => 'application/vnd.adobe.fxp', + 'fzs' => 'application/vnd.fuzzysheet', + 'g2w' => 'application/vnd.geoplan', + 'g3' => 'image/g3fax', + 'g3w' => 'application/vnd.geospace', + 'gac' => 'application/vnd.groove-account', + 'gdl' => 'model/vnd.gdl', + 'geo' => 'application/vnd.dynageo', + 'gex' => 'application/vnd.geometry-explorer', + 'ggb' => 'application/vnd.geogebra.file', + 'ggt' => 'application/vnd.geogebra.tool', + 'ghf' => 'application/vnd.groove-help', + 'gif' => 'image/gif', + 'gim' => 'application/vnd.groove-identity-message', + 'gmx' => 'application/vnd.gmx', + 'gnumeric' => 'application/x-gnumeric', + 'gph' => 'application/vnd.flographit', + 'gqf' => 'application/vnd.grafeq', + 'gqs' => 'application/vnd.grafeq', + 'gram' => 'application/srgs', + 'gre' => 'application/vnd.geometry-explorer', + 'grv' => 'application/vnd.groove-injector', + 'grxml' => 'application/srgs+xml', + 'gsf' => 'application/x-font-ghostscript', + 'gtar' => 'application/x-gtar', + 'gtm' => 'application/vnd.groove-tool-message', + 'gtw' => 'model/vnd.gtw', + 'gv' => 'text/vnd.graphviz', + 'gxt' => 'application/vnd.geonext', + 'h' => 'text/x-c', + 'h261' => 'video/h261', + 'h263' => 'video/h263', + 'h264' => 'video/h264', + 'hal' => 'application/vnd.hal+xml', + 'hbci' => 'application/vnd.hbci', + 'hdf' => 'application/x-hdf', + 'hh' => 'text/x-c', + 'hlp' => 'application/winhlp', + 'hpgl' => 'application/vnd.hp-hpgl', + 'hpid' => 'application/vnd.hp-hpid', + 'hps' => 'application/vnd.hp-hps', + 'hqx' => 'application/mac-binhex40', + 'hta' => 'application/octet-stream', + 'htc' => 'text/html', + 'htke' => 'application/vnd.kenameaapp', + 'htm' => 'text/html', + 'html' => 'text/html', + 'hvd' => 'application/vnd.yamaha.hv-dic', + 'hvp' => 'application/vnd.yamaha.hv-voice', + 'hvs' => 'application/vnd.yamaha.hv-script', + 'i2g' => 'application/vnd.intergeo', + 'icc' => 'application/vnd.iccprofile', + 'ice' => 'x-conference/x-cooltalk', + 'icm' => 'application/vnd.iccprofile', + 'ico' => 'image/x-icon', + 'ics' => 'text/calendar', + 'ief' => 'image/ief', + 'ifb' => 'text/calendar', + 'ifm' => 'application/vnd.shana.informed.formdata', + 'iges' => 'model/iges', + 'igl' => 'application/vnd.igloader', + 'igm' => 'application/vnd.insors.igm', + 'igs' => 'model/iges', + 'igx' => 'application/vnd.micrografx.igx', + 'iif' => 'application/vnd.shana.informed.interchange', + 'imp' => 'application/vnd.accpac.simply.imp', + 'ims' => 'application/vnd.ms-ims', + 'in' => 'text/plain', + 'ini' => 'text/plain', + 'ipfix' => 'application/ipfix', + 'ipk' => 'application/vnd.shana.informed.package', + 'irm' => 'application/vnd.ibm.rights-management', + 'irp' => 'application/vnd.irepository.package+xml', + 'iso' => 'application/octet-stream', + 'itp' => 'application/vnd.shana.informed.formtemplate', + 'ivp' => 'application/vnd.immervision-ivp', + 'ivu' => 'application/vnd.immervision-ivu', + 'jad' => 'text/vnd.sun.j2me.app-descriptor', + 'jam' => 'application/vnd.jam', + 'jar' => 'application/java-archive', + 'java' => 'text/x-java-source', + 'jisp' => 'application/vnd.jisp', + 'jlt' => 'application/vnd.hp-jlyt', + 'jnlp' => 'application/x-java-jnlp-file', + 'joda' => 'application/vnd.joost.joda-archive', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpgm' => 'video/jpm', + 'jpgv' => 'video/jpeg', + 'jpm' => 'video/jpm', + 'js' => 'text/javascript', + 'json' => 'application/json', + 'kar' => 'audio/midi', + 'karbon' => 'application/vnd.kde.karbon', + 'kfo' => 'application/vnd.kde.kformula', + 'kia' => 'application/vnd.kidspiration', + 'kml' => 'application/vnd.google-earth.kml+xml', + 'kmz' => 'application/vnd.google-earth.kmz', + 'kne' => 'application/vnd.kinar', + 'knp' => 'application/vnd.kinar', + 'kon' => 'application/vnd.kde.kontour', + 'kpr' => 'application/vnd.kde.kpresenter', + 'kpt' => 'application/vnd.kde.kpresenter', + 'ksp' => 'application/vnd.kde.kspread', + 'ktr' => 'application/vnd.kahootz', + 'ktx' => 'image/ktx', + 'ktz' => 'application/vnd.kahootz', + 'kwd' => 'application/vnd.kde.kword', + 'kwt' => 'application/vnd.kde.kword', + 'lasxml' => 'application/vnd.las.las+xml', + 'latex' => 'application/x-latex', + 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', + 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', + 'les' => 'application/vnd.hhe.lesson-player', + 'lha' => 'application/octet-stream', + 'link66' => 'application/vnd.route66.link66+xml', + 'list' => 'text/plain', + 'list3820' => 'application/vnd.ibm.modcap', + 'listafp' => 'application/vnd.ibm.modcap', + 'log' => 'text/plain', + 'lostxml' => 'application/lost+xml', + 'lrf' => 'application/octet-stream', + 'lrm' => 'application/vnd.ms-lrm', + 'ltf' => 'application/vnd.frogans.ltf', + 'lvp' => 'audio/vnd.lucent.voice', + 'lwp' => 'application/vnd.lotus-wordpro', + 'lzh' => 'application/octet-stream', + 'm13' => 'application/x-msmediaview', + 'm14' => 'application/x-msmediaview', + 'm1v' => 'video/mpeg', + 'm21' => 'application/mp21', + 'm2a' => 'audio/mpeg', + 'm2v' => 'video/mpeg', + 'm3a' => 'audio/mpeg', + 'm3u' => 'audio/x-mpegurl', + 'm3u8' => 'application/vnd.apple.mpegurl', + 'm4a' => 'audio/mp4', + 'm4u' => 'video/vnd.mpegurl', + 'm4v' => 'video/mp4', + 'ma' => 'application/mathematica', + 'mads' => 'application/mads+xml', + 'mag' => 'application/vnd.ecowin.chart', + 'maker' => 'application/vnd.framemaker', + 'man' => 'text/troff', + 'mathml' => 'application/mathml+xml', + 'mb' => 'application/mathematica', + 'mbk' => 'application/vnd.mobius.mbk', + 'mbox' => 'application/mbox', + 'mc1' => 'application/vnd.medcalcdata', + 'mcd' => 'application/vnd.mcd', + 'mcurl' => 'text/vnd.curl.mcurl', + 'mdb' => 'application/x-msaccess', + 'mdi' => 'image/vnd.ms-modi', + 'me' => 'text/troff', + 'mesh' => 'model/mesh', + 'meta4' => 'application/metalink4+xml', + 'mets' => 'application/mets+xml', + 'mfm' => 'application/vnd.mfmp', + 'mgp' => 'application/vnd.osgeo.mapguide.package', + 'mgz' => 'application/vnd.proteus.magazine', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mif' => 'application/vnd.mif', + 'mime' => 'message/rfc822', + 'mj2' => 'video/mj2', + 'mjp2' => 'video/mj2', + 'mlp' => 'application/vnd.dolby.mlp', + 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', + 'mmf' => 'application/vnd.smaf', + 'mmr' => 'image/vnd.fujixerox.edmics-mmr', + 'mny' => 'application/x-msmoney', + 'mobi' => 'application/x-mobipocket-ebook', + 'mods' => 'application/mods+xml', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'mp2' => 'audio/mpeg', + 'mp21' => 'application/mp21', + 'mp2a' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'mp4a' => 'audio/mp4', + 'mp4s' => 'application/mp4', + 'mp4v' => 'video/mp4', + 'mpc' => 'application/vnd.mophun.certificate', + 'mpe' => 'video/mpeg', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpg4' => 'video/mp4', + 'mpga' => 'audio/mpeg', + 'mpkg' => 'application/vnd.apple.installer+xml', + 'mpm' => 'application/vnd.blueice.multipass', + 'mpn' => 'application/vnd.mophun.application', + 'mpp' => 'application/vnd.ms-project', + 'mpt' => 'application/vnd.ms-project', + 'mpy' => 'application/vnd.ibm.minipay', + 'mqy' => 'application/vnd.mobius.mqy', + 'mrc' => 'application/marc', + 'mrcx' => 'application/marcxml+xml', + 'ms' => 'text/troff', + 'mscml' => 'application/mediaservercontrol+xml', + 'mseed' => 'application/vnd.fdsn.mseed', + 'mseq' => 'application/vnd.mseq', + 'msf' => 'application/vnd.epson.msf', + 'msh' => 'model/mesh', + 'msi' => 'application/x-msdownload', + 'msl' => 'application/vnd.mobius.msl', + 'msty' => 'application/vnd.muvee.style', + 'mts' => 'model/vnd.mts', + 'mus' => 'application/vnd.musician', + 'musicxml' => 'application/vnd.recordare.musicxml+xml', + 'mvb' => 'application/x-msmediaview', + 'mwf' => 'application/vnd.mfer', + 'mxf' => 'application/mxf', + 'mxl' => 'application/vnd.recordare.musicxml', + 'mxml' => 'application/xv+xml', + 'mxs' => 'application/vnd.triscape.mxs', + 'mxu' => 'video/vnd.mpegurl', + 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', + 'n3' => 'text/n3', + 'nb' => 'application/mathematica', + 'nbp' => 'application/vnd.wolfram.player', + 'nc' => 'application/x-netcdf', + 'ncx' => 'application/x-dtbncx+xml', + 'ngdat' => 'application/vnd.nokia.n-gage.data', + 'nlu' => 'application/vnd.neurolanguage.nlu', + 'nml' => 'application/vnd.enliven', + 'nnd' => 'application/vnd.noblenet-directory', + 'nns' => 'application/vnd.noblenet-sealer', + 'nnw' => 'application/vnd.noblenet-web', + 'npx' => 'image/vnd.net-fpx', + 'nsf' => 'application/vnd.lotus-notes', + 'oa2' => 'application/vnd.fujitsu.oasys2', + 'oa3' => 'application/vnd.fujitsu.oasys3', + 'oas' => 'application/vnd.fujitsu.oasys', + 'obd' => 'application/x-msbinder', + 'oda' => 'application/oda', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'odc' => 'application/vnd.oasis.opendocument.chart', + 'odf' => 'application/vnd.oasis.opendocument.formula', + 'odft' => 'application/vnd.oasis.opendocument.formula-template', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odi' => 'application/vnd.oasis.opendocument.image', + 'odm' => 'application/vnd.oasis.opendocument.text-master', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'oga' => 'audio/ogg', + 'ogg' => 'audio/ogg', + 'ogv' => 'video/ogg', + 'ogx' => 'application/ogg', + 'onepkg' => 'application/onenote', + 'onetmp' => 'application/onenote', + 'onetoc' => 'application/onenote', + 'onetoc2' => 'application/onenote', + 'opf' => 'application/oebps-package+xml', + 'oprc' => 'application/vnd.palm', + 'org' => 'application/vnd.lotus-organizer', + 'osf' => 'application/vnd.yamaha.openscoreformat', + 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', + 'otc' => 'application/vnd.oasis.opendocument.chart-template', + 'otf' => 'application/x-font-otf', + 'otg' => 'application/vnd.oasis.opendocument.graphics-template', + 'oth' => 'application/vnd.oasis.opendocument.text-web', + 'oti' => 'application/vnd.oasis.opendocument.image-template', + 'otp' => 'application/vnd.oasis.opendocument.presentation-template', + 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', + 'ott' => 'application/vnd.oasis.opendocument.text-template', + 'oxt' => 'application/vnd.openofficeorg.extension', + 'p' => 'text/x-pascal', + 'p10' => 'application/pkcs10', + 'p12' => 'application/x-pkcs12', + 'p7b' => 'application/x-pkcs7-certificates', + 'p7c' => 'application/pkcs7-mime', + 'p7m' => 'application/pkcs7-mime', + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'p8' => 'application/pkcs8', + 'pas' => 'text/x-pascal', + 'paw' => 'application/vnd.pawaafile', + 'pbd' => 'application/vnd.powerbuilder6', + 'pbm' => 'image/x-portable-bitmap', + 'pcf' => 'application/x-font-pcf', + 'pcl' => 'application/vnd.hp-pcl', + 'pclxl' => 'application/vnd.hp-pclxl', + 'pct' => 'image/x-pict', + 'pcurl' => 'application/vnd.curl.pcurl', + 'pcx' => 'image/x-pcx', + 'pdb' => 'application/vnd.palm', + 'pdf' => 'application/pdf', + 'pfa' => 'application/x-font-type1', + 'pfb' => 'application/x-font-type1', + 'pfm' => 'application/x-font-type1', + 'pfr' => 'application/font-tdpfr', + 'pfx' => 'application/x-pkcs12', + 'pgm' => 'image/x-portable-graymap', + 'pgn' => 'application/x-chess-pgn', + 'pgp' => 'application/pgp-encrypted', + 'php' => 'text/x-php', + 'phps' => 'application/x-httpd-phps', + 'pic' => 'image/x-pict', + 'pkg' => 'application/octet-stream', + 'pki' => 'application/pkixcmp', + 'pkipath' => 'application/pkix-pkipath', + 'plb' => 'application/vnd.3gpp.pic-bw-large', + 'plc' => 'application/vnd.mobius.plc', + 'plf' => 'application/vnd.pocketlearn', + 'pls' => 'application/pls+xml', + 'pml' => 'application/vnd.ctc-posml', + 'png' => 'image/png', + 'pnm' => 'image/x-portable-anymap', + 'portpkg' => 'application/vnd.macports.portpkg', + 'pot' => 'application/vnd.ms-powerpoint', + 'potm' => 'application/vnd.ms-powerpoint.template.macroenabled.12', + 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', + 'ppam' => 'application/vnd.ms-powerpoint.addin.macroenabled.12', + 'ppd' => 'application/vnd.cups-ppd', + 'ppm' => 'image/x-portable-pixmap', + 'pps' => 'application/vnd.ms-powerpoint', + 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', + 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', + 'ppt' => 'application/vnd.ms-powerpoint', + 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroenabled.12', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pqa' => 'application/vnd.palm', + 'prc' => 'application/x-mobipocket-ebook', + 'pre' => 'application/vnd.lotus-freelance', + 'prf' => 'application/pics-rules', + 'ps' => 'application/postscript', + 'psb' => 'application/vnd.3gpp.pic-bw-small', + 'psd' => 'image/vnd.adobe.photoshop', + 'psf' => 'application/x-font-linux-psf', + 'pskcxml' => 'application/pskc+xml', + 'ptid' => 'application/vnd.pvi.ptid1', + 'pub' => 'application/x-mspublisher', + 'pvb' => 'application/vnd.3gpp.pic-bw-var', + 'pwn' => 'application/vnd.3m.post-it-notes', + 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyv' => 'video/vnd.ms-playready.media.pyv', + 'qam' => 'application/vnd.epson.quickanime', + 'qbo' => 'application/vnd.intu.qbo', + 'qfx' => 'application/vnd.intu.qfx', + 'qps' => 'application/vnd.publishare-delta-tree', + 'qt' => 'video/quicktime', + 'qwd' => 'application/vnd.quark.quarkxpress', + 'qwt' => 'application/vnd.quark.quarkxpress', + 'qxb' => 'application/vnd.quark.quarkxpress', + 'qxd' => 'application/vnd.quark.quarkxpress', + 'qxl' => 'application/vnd.quark.quarkxpress', + 'qxt' => 'application/vnd.quark.quarkxpress', + 'ra' => 'audio/x-pn-realaudio', + 'ram' => 'audio/x-pn-realaudio', + 'rar' => 'application/x-rar-compressed', + 'ras' => 'image/x-cmu-raster', + 'rb' => 'text/plain', + 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', + 'rdf' => 'application/rdf+xml', + 'rdz' => 'application/vnd.data-vision.rdz', + 'rep' => 'application/vnd.businessobjects', + 'res' => 'application/x-dtbresource+xml', + 'resx' => 'text/xml', + 'rgb' => 'image/x-rgb', + 'rif' => 'application/reginfo+xml', + 'rip' => 'audio/vnd.rip', + 'rl' => 'application/resource-lists+xml', + 'rlc' => 'image/vnd.fujixerox.edmics-rlc', + 'rld' => 'application/resource-lists-diff+xml', + 'rm' => 'application/vnd.rn-realmedia', + 'rmi' => 'audio/midi', + 'rmp' => 'audio/x-pn-realaudio-plugin', + 'rms' => 'application/vnd.jcp.javame.midlet-rms', + 'rnc' => 'application/relax-ng-compact-syntax', + 'roff' => 'text/troff', + 'rp9' => 'application/vnd.cloanto.rp9', + 'rpss' => 'application/vnd.nokia.radio-presets', + 'rpst' => 'application/vnd.nokia.radio-preset', + 'rq' => 'application/sparql-query', + 'rs' => 'application/rls-services+xml', + 'rsd' => 'application/rsd+xml', + 'rss' => 'application/rss+xml', + 'rtf' => 'application/rtf', + 'rtx' => 'text/richtext', + 's' => 'text/x-asm', + 'saf' => 'application/vnd.yamaha.smaf-audio', + 'sbml' => 'application/sbml+xml', + 'sc' => 'application/vnd.ibm.secure-container', + 'scd' => 'application/x-msschedule', + 'scm' => 'application/vnd.lotus-screencam', + 'scq' => 'application/scvp-cv-request', + 'scs' => 'application/scvp-cv-response', + 'scurl' => 'text/vnd.curl.scurl', + 'sda' => 'application/vnd.stardivision.draw', + 'sdc' => 'application/vnd.stardivision.calc', + 'sdd' => 'application/vnd.stardivision.impress', + 'sdkd' => 'application/vnd.solent.sdkm+xml', + 'sdkm' => 'application/vnd.solent.sdkm+xml', + 'sdp' => 'application/sdp', + 'sdw' => 'application/vnd.stardivision.writer', + 'see' => 'application/vnd.seemail', + 'seed' => 'application/vnd.fdsn.seed', + 'sema' => 'application/vnd.sema', + 'semd' => 'application/vnd.semd', + 'semf' => 'application/vnd.semf', + 'ser' => 'application/java-serialized-object', + 'setpay' => 'application/set-payment-initiation', + 'setreg' => 'application/set-registration-initiation', + 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', + 'sfs' => 'application/vnd.spotfire.sfs', + 'sgl' => 'application/vnd.stardivision.writer-global', + 'sgm' => 'text/sgml', + 'sgml' => 'text/sgml', + 'sh' => 'application/x-sh', + 'shar' => 'application/x-shar', + 'shf' => 'application/shf+xml', + 'sig' => 'application/pgp-signature', + 'silo' => 'model/mesh', + 'sis' => 'application/vnd.symbian.install', + 'sisx' => 'application/vnd.symbian.install', + 'sit' => 'application/x-stuffit', + 'sitx' => 'application/x-stuffitx', + 'skd' => 'application/vnd.koan', + 'skm' => 'application/vnd.koan', + 'skp' => 'application/vnd.koan', + 'skt' => 'application/vnd.koan', + 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', + 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', + 'slt' => 'application/vnd.epson.salt', + 'sm' => 'application/vnd.stepmania.stepchart', + 'smf' => 'application/vnd.stardivision.math', + 'smi' => 'application/smil+xml', + 'smil' => 'application/smil+xml', + 'snd' => 'audio/basic', + 'snf' => 'application/x-font-snf', + 'so' => 'application/octet-stream', + 'spc' => 'application/x-pkcs7-certificates', + 'spf' => 'application/vnd.yamaha.smaf-phrase', + 'spl' => 'application/x-futuresplash', + 'spot' => 'text/vnd.in3d.spot', + 'spp' => 'application/scvp-vp-response', + 'spq' => 'application/scvp-vp-request', + 'spx' => 'audio/ogg', + 'src' => 'application/x-wais-source', + 'sru' => 'application/sru+xml', + 'srx' => 'application/sparql-results+xml', + 'sse' => 'application/vnd.kodak-descriptor', + 'ssf' => 'application/vnd.epson.ssf', + 'ssml' => 'application/ssml+xml', + 'st' => 'application/vnd.sailingtracker.track', + 'stc' => 'application/vnd.sun.xml.calc.template', + 'std' => 'application/vnd.sun.xml.draw.template', + 'stf' => 'application/vnd.wt.stf', + 'sti' => 'application/vnd.sun.xml.impress.template', + 'stk' => 'application/hyperstudio', + 'stl' => 'application/vnd.ms-pki.stl', + 'str' => 'application/vnd.pg.format', + 'stw' => 'application/vnd.sun.xml.writer.template', + 'sub' => 'image/vnd.dvb.subtitle', + 'sus' => 'application/vnd.sus-calendar', + 'susp' => 'application/vnd.sus-calendar', + 'sv4cpio' => 'application/x-sv4cpio', + 'sv4crc' => 'application/x-sv4crc', + 'svc' => 'application/vnd.dvb.service', + 'svd' => 'application/vnd.svd', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swa' => 'application/x-director', + 'swf' => 'application/x-shockwave-flash', + 'swi' => 'application/vnd.aristanetworks.swi', + 'sxc' => 'application/vnd.sun.xml.calc', + 'sxd' => 'application/vnd.sun.xml.draw', + 'sxg' => 'application/vnd.sun.xml.writer.global', + 'sxi' => 'application/vnd.sun.xml.impress', + 'sxm' => 'application/vnd.sun.xml.math', + 'sxw' => 'application/vnd.sun.xml.writer', + 't' => 'text/troff', + 'tao' => 'application/vnd.tao.intent-module-archive', + 'tar' => 'application/x-tar', + 'tcap' => 'application/vnd.3gpp2.tcap', + 'tcl' => 'application/x-tcl', + 'teacher' => 'application/vnd.smart.teacher', + 'tei' => 'application/tei+xml', + 'teicorpus' => 'application/tei+xml', + 'tex' => 'application/x-tex', + 'texi' => 'application/x-texinfo', + 'texinfo' => 'application/x-texinfo', + 'text' => 'text/plain', + 'tfi' => 'application/thraud+xml', + 'tfm' => 'application/x-tex-tfm', + 'thmx' => 'application/vnd.ms-officetheme', + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'tmo' => 'application/vnd.tmobile-livetv', + 'torrent' => 'application/x-bittorrent', + 'tpl' => 'application/vnd.groove-tool-template', + 'tpt' => 'application/vnd.trid.tpt', + 'tr' => 'text/troff', + 'tra' => 'application/vnd.trueapp', + 'trm' => 'application/x-msterminal', + 'tsd' => 'application/timestamped-data', + 'tsv' => 'text/tab-separated-values', + 'ttc' => 'application/x-font-ttf', + 'ttf' => 'application/x-font-ttf', + 'ttl' => 'text/turtle', + 'twd' => 'application/vnd.simtech-mindmapper', + 'twds' => 'application/vnd.simtech-mindmapper', + 'txd' => 'application/vnd.genomatix.tuxedo', + 'txf' => 'application/vnd.mobius.txf', + 'txt' => 'text/plain', + 'u32' => 'application/x-authorware-bin', + 'udeb' => 'application/x-debian-package', + 'ufd' => 'application/vnd.ufdl', + 'ufdl' => 'application/vnd.ufdl', + 'umj' => 'application/vnd.umajin', + 'unityweb' => 'application/vnd.unity', + 'uoml' => 'application/vnd.uoml+xml', + 'uri' => 'text/uri-list', + 'uris' => 'text/uri-list', + 'urls' => 'text/uri-list', + 'ustar' => 'application/x-ustar', + 'utz' => 'application/vnd.uiq.theme', + 'uu' => 'text/x-uuencode', + 'uva' => 'audio/vnd.dece.audio', + 'uvd' => 'application/vnd.dece.data', + 'uvf' => 'application/vnd.dece.data', + 'uvg' => 'image/vnd.dece.graphic', + 'uvh' => 'video/vnd.dece.hd', + 'uvi' => 'image/vnd.dece.graphic', + 'uvm' => 'video/vnd.dece.mobile', + 'uvp' => 'video/vnd.dece.pd', + 'uvs' => 'video/vnd.dece.sd', + 'uvt' => 'application/vnd.dece.ttml+xml', + 'uvu' => 'video/vnd.uvvu.mp4', + 'uvv' => 'video/vnd.dece.video', + 'uvva' => 'audio/vnd.dece.audio', + 'uvvd' => 'application/vnd.dece.data', + 'uvvf' => 'application/vnd.dece.data', + 'uvvg' => 'image/vnd.dece.graphic', + 'uvvh' => 'video/vnd.dece.hd', + 'uvvi' => 'image/vnd.dece.graphic', + 'uvvm' => 'video/vnd.dece.mobile', + 'uvvp' => 'video/vnd.dece.pd', + 'uvvs' => 'video/vnd.dece.sd', + 'uvvt' => 'application/vnd.dece.ttml+xml', + 'uvvu' => 'video/vnd.uvvu.mp4', + 'uvvv' => 'video/vnd.dece.video', + 'uvvx' => 'application/vnd.dece.unspecified', + 'uvx' => 'application/vnd.dece.unspecified', + 'vcd' => 'application/x-cdlink', + 'vcf' => 'text/x-vcard', + 'vcg' => 'application/vnd.groove-vcard', + 'vcs' => 'text/x-vcalendar', + 'vcx' => 'application/vnd.vcx', + 'vis' => 'application/vnd.visionary', + 'viv' => 'video/vnd.vivo', + 'vor' => 'application/vnd.stardivision.writer', + 'vox' => 'application/x-authorware-bin', + 'vrml' => 'model/vrml', + 'vsd' => 'application/vnd.visio', + 'vsf' => 'application/vnd.vsf', + 'vss' => 'application/vnd.visio', + 'vst' => 'application/vnd.visio', + 'vsw' => 'application/vnd.visio', + 'vtu' => 'model/vnd.vtu', + 'vxml' => 'application/voicexml+xml', + 'w3d' => 'application/x-director', + 'wad' => 'application/x-doom', + 'wav' => 'audio/x-wav', + 'wax' => 'audio/x-ms-wax', + 'wbmp' => 'image/vnd.wap.wbmp', + 'wbs' => 'application/vnd.criticaltools.wbs+xml', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wcm' => 'application/vnd.ms-works', + 'wdb' => 'application/vnd.ms-works', + 'weba' => 'audio/webm', + 'webm' => 'video/webm', + 'webp' => 'image/webp', + 'wg' => 'application/vnd.pmi.widget', + 'wgt' => 'application/widget', + 'wks' => 'application/vnd.ms-works', + 'wm' => 'video/x-ms-wm', + 'wma' => 'audio/x-ms-wma', + 'wmd' => 'application/x-ms-wmd', + 'wmf' => 'application/x-msmetafile', + 'wml' => 'text/vnd.wap.wml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'wmls' => 'text/vnd.wap.wmlscript', + 'wmlsc' => 'application/vnd.wap.wmlscriptc', + 'wmv' => 'video/x-ms-wmv', + 'wmx' => 'video/x-ms-wmx', + 'wmz' => 'application/x-ms-wmz', + 'woff' => 'application/x-font-woff', + 'wpd' => 'application/vnd.wordperfect', + 'wpl' => 'application/vnd.ms-wpl', + 'wps' => 'application/vnd.ms-works', + 'wqd' => 'application/vnd.wqd', + 'wri' => 'application/x-mswrite', + 'wrl' => 'model/vrml', + 'wsdl' => 'application/wsdl+xml', + 'wspolicy' => 'application/wspolicy+xml', + 'wtb' => 'application/vnd.webturbo', + 'wvx' => 'video/x-ms-wvx', + 'x32' => 'application/x-authorware-bin', + 'x3d' => 'application/vnd.hzn-3d-crossword', + 'xap' => 'application/x-silverlight-app', + 'xar' => 'application/vnd.xara', + 'xbap' => 'application/x-ms-xbap', + 'xbd' => 'application/vnd.fujixerox.docuworks.binder', + 'xbm' => 'image/x-xbitmap', + 'xdf' => 'application/xcap-diff+xml', + 'xdm' => 'application/vnd.syncml.dm+xml', + 'xdp' => 'application/vnd.adobe.xdp+xml', + 'xdssc' => 'application/dssc+xml', + 'xdw' => 'application/vnd.fujixerox.docuworks', + 'xenc' => 'application/xenc+xml', + 'xer' => 'application/patch-ops-error+xml', + 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdl' => 'application/vnd.xfdl', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', + 'xhvml' => 'application/xv+xml', + 'xif' => 'image/vnd.xiff', + 'xla' => 'application/vnd.ms-excel', + 'xlam' => 'application/vnd.ms-excel.addin.macroenabled.12', + 'xlc' => 'application/vnd.ms-excel', + 'xlm' => 'application/vnd.ms-excel', + 'xls' => 'application/vnd.ms-excel', + 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12', + 'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'xlt' => 'application/vnd.ms-excel', + 'xltm' => 'application/vnd.ms-excel.template.macroenabled.12', + 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', + 'xlw' => 'application/vnd.ms-excel', + 'xml' => 'application/xml', + 'xo' => 'application/vnd.olpc-sugar', + 'xop' => 'application/xop+xml', + 'xpi' => 'application/x-xpinstall', + 'xpm' => 'image/x-xpixmap', + 'xpr' => 'application/vnd.is-xpr', + 'xps' => 'application/vnd.ms-xpsdocument', + 'xpw' => 'application/vnd.intercon.formnet', + 'xpx' => 'application/vnd.intercon.formnet', + 'xsl' => 'application/xml', + 'xslt' => 'application/xslt+xml', + 'xsm' => 'application/vnd.syncml+xml', + 'xspf' => 'application/xspf+xml', + 'xul' => 'application/vnd.mozilla.xul+xml', + 'xvm' => 'application/xv+xml', + 'xvml' => 'application/xv+xml', + 'xwd' => 'image/x-xwindowdump', + 'xyz' => 'chemical/x-xyz', + 'yaml' => 'text/yaml', + 'yang' => 'application/yang', + 'yin' => 'application/yin+xml', + 'yml' => 'text/yaml', + 'zaz' => 'application/vnd.zzazz.deck+xml', + 'zip' => 'application/zip', + 'zir' => 'application/vnd.zul', + 'zirz' => 'application/vnd.zul', + 'zmm' => 'application/vnd.handheld-entertainment+xml' + ); + + /** + * Get a singleton instance of the class + * + * @return self + * @codeCoverageIgnore + */ + public static function getInstance() + { + if (!self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + /** + * Get a mimetype value from a file extension + * + * @param string $extension File extension + * + * @return string|null + * + */ + public function fromExtension($extension) + { + $extension = strtolower($extension); + + return isset($this->mimetypes[$extension]) + ? $this->mimetypes[$extension] + : null; + } + + /** + * Get a mimetype from a filename + * + * @param string $filename Filename to generate a mimetype from + * + * @return string|null + */ + public function fromFilename($filename) + { + return $this->fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Pool.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Pool.php new file mode 100644 index 00000000..7b9d83a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Pool.php @@ -0,0 +1,333 @@ +client = $client; + $this->iter = $this->coerceIterable($requests); + $this->deferred = new Deferred(); + $this->promise = $this->deferred->promise(); + $this->poolSize = isset($options['pool_size']) + ? $options['pool_size'] : 25; + $this->eventListeners = $this->prepareListeners( + $options, + ['before', 'complete', 'error', 'end'] + ); + } + + /** + * Sends multiple requests in parallel and returns an array of responses + * and exceptions that uses the same ordering as the provided requests. + * + * IMPORTANT: This method keeps every request and response in memory, and + * as such, is NOT recommended when sending a large number or an + * indeterminate number of requests concurrently. + * + * @param ClientInterface $client Client used to send the requests + * @param array|\Iterator $requests Requests to send in parallel + * @param array $options Passes through the options available in + * {@see GuzzleHttp\Pool::__construct} + * + * @return BatchResults Returns a container for the results. + * @throws \InvalidArgumentException if the event format is incorrect. + */ + public static function batch( + ClientInterface $client, + $requests, + array $options = [] + ) { + $hash = new \SplObjectStorage(); + foreach ($requests as $request) { + $hash->attach($request); + } + + // In addition to the normally run events when requests complete, add + // and event to continuously track the results of transfers in the hash. + (new self($client, $requests, RequestEvents::convertEventArray( + $options, + ['end'], + [ + 'priority' => RequestEvents::LATE, + 'fn' => function (EndEvent $e) use ($hash) { + $hash[$e->getRequest()] = $e->getException() + ? $e->getException() + : $e->getResponse(); + } + ] + )))->wait(); + + return new BatchResults($hash); + } + + /** + * Creates a Pool and immediately sends the requests. + * + * @param ClientInterface $client Client used to send the requests + * @param array|\Iterator $requests Requests to send in parallel + * @param array $options Passes through the options available in + * {@see GuzzleHttp\Pool::__construct} + */ + public static function send( + ClientInterface $client, + $requests, + array $options = [] + ) { + $pool = new self($client, $requests, $options); + $pool->wait(); + } + + private function getPoolSize() + { + return is_callable($this->poolSize) + ? call_user_func($this->poolSize, count($this->waitQueue)) + : $this->poolSize; + } + + /** + * Add as many requests as possible up to the current pool limit. + */ + private function addNextRequests() + { + $limit = max($this->getPoolSize() - count($this->waitQueue), 0); + while ($limit--) { + if (!$this->addNextRequest()) { + break; + } + } + } + + public function wait() + { + if ($this->isRealized) { + return false; + } + + // Seed the pool with N number of requests. + $this->addNextRequests(); + + // Stop if the pool was cancelled while transferring requests. + if ($this->isRealized) { + return false; + } + + // Wait on any outstanding FutureResponse objects. + while ($response = array_pop($this->waitQueue)) { + try { + $response->wait(); + } catch (\Exception $e) { + // Eat exceptions because they should be handled asynchronously + } + $this->addNextRequests(); + } + + // Clean up no longer needed state. + $this->isRealized = true; + $this->waitQueue = $this->eventListeners = []; + $this->client = $this->iter = null; + $this->deferred->resolve(true); + + return true; + } + + /** + * {@inheritdoc} + * + * Attempt to cancel all outstanding requests (requests that are queued for + * dereferencing). Returns true if all outstanding requests can be + * cancelled. + * + * @return bool + */ + public function cancel() + { + if ($this->isRealized) { + return false; + } + + $success = $this->isRealized = true; + foreach ($this->waitQueue as $response) { + if (!$response->cancel()) { + $success = false; + } + } + + return $success; + } + + /** + * Returns a promise that is invoked when the pool completed. There will be + * no passed value. + * + * {@inheritdoc} + */ + public function then( + callable $onFulfilled = null, + callable $onRejected = null, + callable $onProgress = null + ) { + return $this->promise->then($onFulfilled, $onRejected, $onProgress); + } + + public function promise() + { + return $this->promise; + } + + private function coerceIterable($requests) + { + if ($requests instanceof \Iterator) { + return $requests; + } elseif (is_array($requests)) { + return new \ArrayIterator($requests); + } + + throw new \InvalidArgumentException('Expected Iterator or array. ' + . 'Found ' . Core::describeType($requests)); + } + + /** + * Adds the next request to pool and tracks what requests need to be + * dereferenced when completing the pool. + */ + private function addNextRequest() + { + add_next: + + if ($this->isRealized || !$this->iter || !$this->iter->valid()) { + return false; + } + + $request = $this->iter->current(); + $this->iter->next(); + + if (!($request instanceof RequestInterface)) { + throw new \InvalidArgumentException(sprintf( + 'All requests in the provided iterator must implement ' + . 'RequestInterface. Found %s', + Core::describeType($request) + )); + } + + // Be sure to use "lazy" futures, meaning they do not send right away. + $request->getConfig()->set('future', 'lazy'); + $hash = spl_object_hash($request); + $this->attachListeners($request, $this->eventListeners); + $request->getEmitter()->on('before', [$this, '_trackRetries'], RequestEvents::EARLY); + $response = $this->client->send($request); + $this->waitQueue[$hash] = $response; + $promise = $response->promise(); + + // Don't recursively call itself for completed or rejected responses. + if ($promise instanceof FulfilledPromise + || $promise instanceof RejectedPromise + ) { + try { + $this->finishResponse($request, $response->wait(), $hash); + } catch (\Exception $e) { + $this->finishResponse($request, $e, $hash); + } + goto add_next; + } + + // Use this function for both resolution and rejection. + $thenFn = function ($value) use ($request, $hash) { + $this->finishResponse($request, $value, $hash); + if (!$request->getConfig()->get('_pool_retries')) { + $this->addNextRequests(); + } + }; + + $promise->then($thenFn, $thenFn); + + return true; + } + + public function _trackRetries(BeforeEvent $e) + { + $e->getRequest()->getConfig()->set('_pool_retries', $e->getRetryCount()); + } + + private function finishResponse($request, $value, $hash) + { + unset($this->waitQueue[$hash]); + $result = $value instanceof ResponseInterface + ? ['request' => $request, 'response' => $value, 'error' => null] + : ['request' => $request, 'response' => null, 'error' => $value]; + $this->deferred->notify($result); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php new file mode 100644 index 00000000..1149e623 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/MultipartBody.php @@ -0,0 +1,109 @@ +boundary = $boundary ?: uniqid(); + $this->stream = $this->createStream($fields, $files); + } + + /** + * Get the boundary + * + * @return string + */ + public function getBoundary() + { + return $this->boundary; + } + + public function isWritable() + { + return false; + } + + /** + * Get the string needed to transfer a POST field + */ + private function getFieldString($name, $value) + { + return sprintf( + "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", + $this->boundary, + $name, + $value + ); + } + + /** + * Get the headers needed before transferring the content of a POST file + */ + private function getFileHeaders(PostFileInterface $file) + { + $headers = ''; + foreach ($file->getHeaders() as $key => $value) { + $headers .= "{$key}: {$value}\r\n"; + } + + return "--{$this->boundary}\r\n" . trim($headers) . "\r\n\r\n"; + } + + /** + * Create the aggregate stream that will be used to upload the POST data + */ + protected function createStream(array $fields, array $files) + { + $stream = new AppendStream(); + + foreach ($fields as $name => $fieldValues) { + foreach ((array) $fieldValues as $value) { + $stream->addStream( + Stream::factory($this->getFieldString($name, $value)) + ); + } + } + + foreach ($files as $file) { + + if (!$file instanceof PostFileInterface) { + throw new \InvalidArgumentException('All POST fields must ' + . 'implement PostFieldInterface'); + } + + $stream->addStream( + Stream::factory($this->getFileHeaders($file)) + ); + $stream->addStream($file->getContent()); + $stream->addStream(Stream::factory("\r\n")); + } + + // Add the trailing boundary with CRLF + $stream->addStream(Stream::factory("--{$this->boundary}--\r\n")); + + return $stream; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostBody.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostBody.php new file mode 100644 index 00000000..ed14d1f7 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostBody.php @@ -0,0 +1,287 @@ +files || $this->forceMultipart) { + $request->setHeader( + 'Content-Type', + 'multipart/form-data; boundary=' . $this->getBody()->getBoundary() + ); + } elseif ($this->fields && !$request->hasHeader('Content-Type')) { + $request->setHeader( + 'Content-Type', + 'application/x-www-form-urlencoded' + ); + } + + if ($size = $this->getSize()) { + $request->setHeader('Content-Length', $size); + } + } + + public function forceMultipartUpload($force) + { + $this->forceMultipart = $force; + } + + public function setAggregator(callable $aggregator) + { + $this->aggregator = $aggregator; + } + + public function setField($name, $value) + { + $this->fields[$name] = $value; + $this->mutate(); + } + + public function replaceFields(array $fields) + { + $this->fields = $fields; + $this->mutate(); + } + + public function getField($name) + { + return isset($this->fields[$name]) ? $this->fields[$name] : null; + } + + public function removeField($name) + { + unset($this->fields[$name]); + $this->mutate(); + } + + public function getFields($asString = false) + { + if (!$asString) { + return $this->fields; + } + + $query = new Query($this->fields); + $query->setEncodingType(Query::RFC1738); + $query->setAggregator($this->getAggregator()); + + return (string) $query; + } + + public function hasField($name) + { + return isset($this->fields[$name]); + } + + public function getFile($name) + { + foreach ($this->files as $file) { + if ($file->getName() == $name) { + return $file; + } + } + + return null; + } + + public function getFiles() + { + return $this->files; + } + + public function addFile(PostFileInterface $file) + { + $this->files[] = $file; + $this->mutate(); + } + + public function clearFiles() + { + $this->files = []; + $this->mutate(); + } + + /** + * Returns the numbers of fields + files + * + * @return int + */ + public function count() + { + return count($this->files) + count($this->fields); + } + + public function __toString() + { + return (string) $this->getBody(); + } + + public function getContents($maxLength = -1) + { + return $this->getBody()->getContents(); + } + + public function close() + { + $this->detach(); + } + + public function detach() + { + $this->detached = true; + $this->fields = $this->files = []; + + if ($this->body) { + $this->body->close(); + $this->body = null; + } + } + + public function attach($stream) + { + throw new CannotAttachException(); + } + + public function eof() + { + return $this->getBody()->eof(); + } + + public function tell() + { + return $this->body ? $this->body->tell() : 0; + } + + public function isSeekable() + { + return true; + } + + public function isReadable() + { + return true; + } + + public function isWritable() + { + return false; + } + + public function getSize() + { + return $this->getBody()->getSize(); + } + + public function seek($offset, $whence = SEEK_SET) + { + return $this->getBody()->seek($offset, $whence); + } + + public function read($length) + { + return $this->getBody()->read($length); + } + + public function write($string) + { + return false; + } + + public function getMetadata($key = null) + { + return $key ? null : []; + } + + /** + * Return a stream object that is built from the POST fields and files. + * + * If one has already been created, the previously created stream will be + * returned. + */ + private function getBody() + { + if ($this->body) { + return $this->body; + } elseif ($this->files || $this->forceMultipart) { + return $this->body = $this->createMultipart(); + } elseif ($this->fields) { + return $this->body = $this->createUrlEncoded(); + } else { + return $this->body = Stream::factory(); + } + } + + /** + * Get the aggregator used to join multi-valued field parameters + * + * @return callable + */ + final protected function getAggregator() + { + if (!$this->aggregator) { + $this->aggregator = Query::phpAggregator(); + } + + return $this->aggregator; + } + + /** + * Creates a multipart/form-data body stream + * + * @return MultipartBody + */ + private function createMultipart() + { + // Flatten the nested query string values using the correct aggregator + return new MultipartBody( + call_user_func($this->getAggregator(), $this->fields), + $this->files + ); + } + + /** + * Creates an application/x-www-form-urlencoded stream body + * + * @return StreamInterface + */ + private function createUrlEncoded() + { + return Stream::factory($this->getFields(true)); + } + + /** + * Get rid of any cached data + */ + private function mutate() + { + $this->body = null; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostBodyInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostBodyInterface.php new file mode 100644 index 00000000..c2ec9a62 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostBodyInterface.php @@ -0,0 +1,109 @@ +headers = $headers; + $this->name = $name; + $this->prepareContent($content); + $this->prepareFilename($filename); + $this->prepareDefaultHeaders(); + } + + public function getName() + { + return $this->name; + } + + public function getFilename() + { + return $this->filename; + } + + public function getContent() + { + return $this->content; + } + + public function getHeaders() + { + return $this->headers; + } + + /** + * Prepares the contents of a POST file. + * + * @param mixed $content Content of the POST file + */ + private function prepareContent($content) + { + $this->content = $content; + + if (!($this->content instanceof StreamInterface)) { + $this->content = Stream::factory($this->content); + } elseif ($this->content instanceof MultipartBody) { + if (!$this->hasHeader('Content-Disposition')) { + $disposition = 'form-data; name="' . $this->name .'"'; + $this->headers['Content-Disposition'] = $disposition; + } + + if (!$this->hasHeader('Content-Type')) { + $this->headers['Content-Type'] = sprintf( + "multipart/form-data; boundary=%s", + $this->content->getBoundary() + ); + } + } + } + + /** + * Applies a file name to the POST file based on various checks. + * + * @param string|null $filename Filename to apply (or null to guess) + */ + private function prepareFilename($filename) + { + $this->filename = $filename; + + if (!$this->filename) { + $this->filename = $this->content->getMetadata('uri'); + } + + if (!$this->filename || substr($this->filename, 0, 6) === 'php://') { + $this->filename = $this->name; + } + } + + /** + * Applies default Content-Disposition and Content-Type headers if needed. + */ + private function prepareDefaultHeaders() + { + // Set a default content-disposition header if one was no provided + if (!$this->hasHeader('Content-Disposition')) { + $this->headers['Content-Disposition'] = sprintf( + 'form-data; name="%s"; filename="%s"', + $this->name, + basename($this->filename) + ); + } + + // Set a default Content-Type if one was not supplied + if (!$this->hasHeader('Content-Type')) { + $this->headers['Content-Type'] = Mimetypes::getInstance() + ->fromFilename($this->filename) ?: 'text/plain'; + } + } + + /** + * Check if a specific header exists on the POST file by name. + * + * @param string $name Case-insensitive header to check + * + * @return bool + */ + private function hasHeader($name) + { + return isset(array_change_key_case($this->headers)[strtolower($name)]); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostFileInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostFileInterface.php new file mode 100644 index 00000000..2e816c08 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Post/PostFileInterface.php @@ -0,0 +1,41 @@ +setEncodingType($urlEncoding); + } + + $qp->parseInto($q, $query, $urlEncoding); + + return $q; + } + + /** + * Convert the query string parameters to a query string string + * + * @return string + */ + public function __toString() + { + if (!$this->data) { + return ''; + } + + // The default aggregator is statically cached + static $defaultAggregator; + + if (!$this->aggregator) { + if (!$defaultAggregator) { + $defaultAggregator = self::phpAggregator(); + } + $this->aggregator = $defaultAggregator; + } + + $result = ''; + $aggregator = $this->aggregator; + $encoder = $this->encoding; + + foreach ($aggregator($this->data) as $key => $values) { + foreach ($values as $value) { + if ($result) { + $result .= '&'; + } + $result .= $encoder($key); + if ($value !== null) { + $result .= '=' . $encoder($value); + } + } + } + + return $result; + } + + /** + * Controls how multi-valued query string parameters are aggregated into a + * string. + * + * $query->setAggregator($query::duplicateAggregator()); + * + * @param callable $aggregator Callable used to convert a deeply nested + * array of query string variables into a flattened array of key value + * pairs. The callable accepts an array of query data and returns a + * flattened array of key value pairs where each value is an array of + * strings. + */ + public function setAggregator(callable $aggregator) + { + $this->aggregator = $aggregator; + } + + /** + * Specify how values are URL encoded + * + * @param string|bool $type One of 'RFC1738', 'RFC3986', or false to disable encoding + * + * @throws \InvalidArgumentException + */ + public function setEncodingType($type) + { + switch ($type) { + case self::RFC3986: + $this->encoding = 'rawurlencode'; + break; + case self::RFC1738: + $this->encoding = 'urlencode'; + break; + case false: + $this->encoding = function ($v) { return $v; }; + break; + default: + throw new \InvalidArgumentException('Invalid URL encoding type'); + } + } + + /** + * Query string aggregator that does not aggregate nested query string + * values and allows duplicates in the resulting array. + * + * Example: http://test.com?q=1&q=2 + * + * @return callable + */ + public static function duplicateAggregator() + { + return function (array $data) { + return self::walkQuery($data, '', function ($key, $prefix) { + return is_int($key) ? $prefix : "{$prefix}[{$key}]"; + }); + }; + } + + /** + * Aggregates nested query string variables using the same technique as + * ``http_build_query()``. + * + * @param bool $numericIndices Pass false to not include numeric indices + * when multi-values query string parameters are present. + * + * @return callable + */ + public static function phpAggregator($numericIndices = true) + { + return function (array $data) use ($numericIndices) { + return self::walkQuery( + $data, + '', + function ($key, $prefix) use ($numericIndices) { + return !$numericIndices && is_int($key) + ? "{$prefix}[]" + : "{$prefix}[{$key}]"; + } + ); + }; + } + + /** + * Easily create query aggregation functions by providing a key prefix + * function to this query string array walker. + * + * @param array $query Query string to walk + * @param string $keyPrefix Key prefix (start with '') + * @param callable $prefixer Function used to create a key prefix + * + * @return array + */ + public static function walkQuery(array $query, $keyPrefix, callable $prefixer) + { + $result = []; + foreach ($query as $key => $value) { + if ($keyPrefix) { + $key = $prefixer($key, $keyPrefix); + } + if (is_array($value)) { + $result += self::walkQuery($value, $key, $prefixer); + } elseif (isset($result[$key])) { + $result[$key][] = $value; + } else { + $result[$key] = array($value); + } + } + + return $result; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/QueryParser.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/QueryParser.php new file mode 100644 index 00000000..90727cc6 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/QueryParser.php @@ -0,0 +1,163 @@ +duplicates = false; + $this->numericIndices = true; + $decoder = self::getDecoder($urlEncoding); + + foreach (explode('&', $str) as $kvp) { + + $parts = explode('=', $kvp, 2); + $key = $decoder($parts[0]); + $value = isset($parts[1]) ? $decoder($parts[1]) : null; + + // Special handling needs to be taken for PHP nested array syntax + if (strpos($key, '[') !== false) { + $this->parsePhpValue($key, $value, $result); + continue; + } + + if (!isset($result[$key])) { + $result[$key] = $value; + } else { + $this->duplicates = true; + if (!is_array($result[$key])) { + $result[$key] = [$result[$key]]; + } + $result[$key][] = $value; + } + } + + $query->replace($result); + + if (!$this->numericIndices) { + $query->setAggregator(Query::phpAggregator(false)); + } elseif ($this->duplicates) { + $query->setAggregator(Query::duplicateAggregator()); + } + } + + /** + * Returns a callable that is used to URL decode query keys and values. + * + * @param string|bool $type One of true, false, RFC3986, and RFC1738 + * + * @return callable|string + */ + private static function getDecoder($type) + { + if ($type === true) { + return function ($value) { + return rawurldecode(str_replace('+', ' ', $value)); + }; + } elseif ($type == Query::RFC3986) { + return 'rawurldecode'; + } elseif ($type == Query::RFC1738) { + return 'urldecode'; + } else { + return function ($str) { return $str; }; + } + } + + /** + * Parses a PHP style key value pair. + * + * @param string $key Key to parse (e.g., "foo[a][b]") + * @param string|null $value Value to set + * @param array $result Result to modify by reference + */ + private function parsePhpValue($key, $value, array &$result) + { + $node =& $result; + $keyBuffer = ''; + + for ($i = 0, $t = strlen($key); $i < $t; $i++) { + switch ($key[$i]) { + case '[': + if ($keyBuffer) { + $this->prepareNode($node, $keyBuffer); + $node =& $node[$keyBuffer]; + $keyBuffer = ''; + } + break; + case ']': + $k = $this->cleanKey($node, $keyBuffer); + $this->prepareNode($node, $k); + $node =& $node[$k]; + $keyBuffer = ''; + break; + default: + $keyBuffer .= $key[$i]; + break; + } + } + + if (isset($node)) { + $this->duplicates = true; + $node[] = $value; + } else { + $node = $value; + } + } + + /** + * Prepares a value in the array at the given key. + * + * If the key already exists, the key value is converted into an array. + * + * @param array $node Result node to modify + * @param string $key Key to add or modify in the node + */ + private function prepareNode(&$node, $key) + { + if (!isset($node[$key])) { + $node[$key] = null; + } elseif (!is_array($node[$key])) { + $node[$key] = [$node[$key]]; + } + } + + /** + * Returns the appropriate key based on the node and key. + */ + private function cleanKey($node, $key) + { + if ($key === '') { + $key = $node ? (string) count($node) : 0; + // Found a [] key, so track this to ensure that we disable numeric + // indexing of keys in the resolved query aggregator. + $this->numericIndices = false; + } + + return $key; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/RequestFsm.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/RequestFsm.php new file mode 100644 index 00000000..b37c190d --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/RequestFsm.php @@ -0,0 +1,153 @@ +mf = $messageFactory; + $this->maxTransitions = $maxTransitions; + $this->handler = $handler; + } + + /** + * Runs the state machine until a terminal state is entered or the + * optionally supplied $finalState is entered. + * + * @param Transaction $trans Transaction being transitioned. + * + * @throws \Exception if a terminal state throws an exception. + */ + public function __invoke(Transaction $trans) + { + $trans->_transitionCount = 0; + + if (!$trans->state) { + $trans->state = 'before'; + } + + transition: + + if (++$trans->_transitionCount > $this->maxTransitions) { + throw new StateException("Too many state transitions were " + . "encountered ({$trans->_transitionCount}). This likely " + . "means that a combination of event listeners are in an " + . "infinite loop."); + } + + switch ($trans->state) { + case 'before': goto before; + case 'complete': goto complete; + case 'error': goto error; + case 'retry': goto retry; + case 'send': goto send; + case 'end': goto end; + default: throw new StateException("Invalid state: {$trans->state}"); + } + + before: { + try { + $trans->request->getEmitter()->emit('before', new BeforeEvent($trans)); + $trans->state = 'send'; + if ((bool) $trans->response) { + $trans->state = 'complete'; + } + } catch (\Exception $e) { + $trans->state = 'error'; + $trans->exception = $e; + } + goto transition; + } + + complete: { + try { + if ($trans->response instanceof FutureInterface) { + // Futures will have their own end events emitted when + // dereferenced. + return; + } + $trans->state = 'end'; + $trans->response->setEffectiveUrl($trans->request->getUrl()); + $trans->request->getEmitter()->emit('complete', new CompleteEvent($trans)); + } catch (\Exception $e) { + $trans->state = 'error'; + $trans->exception = $e; + } + goto transition; + } + + error: { + try { + // Convert non-request exception to a wrapped exception + $trans->exception = RequestException::wrapException( + $trans->request, $trans->exception + ); + $trans->state = 'end'; + $trans->request->getEmitter()->emit('error', new ErrorEvent($trans)); + // An intercepted request (not retried) transitions to complete + if (!$trans->exception && $trans->state !== 'retry') { + $trans->state = 'complete'; + } + } catch (\Exception $e) { + $trans->state = 'end'; + $trans->exception = $e; + } + goto transition; + } + + retry: { + $trans->retries++; + $trans->response = null; + $trans->exception = null; + $trans->state = 'before'; + goto transition; + } + + send: { + $fn = $this->handler; + $trans->response = FutureResponse::proxy( + $fn(RingBridge::prepareRingRequest($trans)), + function ($value) use ($trans) { + RingBridge::completeRingResponse($trans, $value, $this->mf, $this); + $this($trans); + return $trans->response; + } + ); + return; + } + + end: { + $trans->request->getEmitter()->emit('end', new EndEvent($trans)); + // Throw exceptions in the terminal event if the exception + // was not handled by an "end" event listener. + if ($trans->exception) { + if (!($trans->exception instanceof RequestException)) { + $trans->exception = RequestException::wrapException( + $trans->request, $trans->exception + ); + } + throw $trans->exception; + } + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/RingBridge.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/RingBridge.php new file mode 100644 index 00000000..bc6841d4 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/RingBridge.php @@ -0,0 +1,165 @@ +getConfig()->toArray(); + $url = $request->getUrl(); + // No need to calculate the query string twice (in URL and query). + $qs = ($pos = strpos($url, '?')) ? substr($url, $pos + 1) : null; + + return [ + 'scheme' => $request->getScheme(), + 'http_method' => $request->getMethod(), + 'url' => $url, + 'uri' => $request->getPath(), + 'headers' => $request->getHeaders(), + 'body' => $request->getBody(), + 'version' => $request->getProtocolVersion(), + 'client' => $options, + 'query_string' => $qs, + 'future' => isset($options['future']) ? $options['future'] : false + ]; + } + + /** + * Creates a Ring request from a request object AND prepares the callbacks. + * + * @param Transaction $trans Transaction to update. + * + * @return array Converted Guzzle Ring request. + */ + public static function prepareRingRequest(Transaction $trans) + { + // Clear out the transaction state when initiating. + $trans->exception = null; + $request = self::createRingRequest($trans->request); + + // Emit progress events if any progress listeners are registered. + if ($trans->request->getEmitter()->hasListeners('progress')) { + $emitter = $trans->request->getEmitter(); + $request['client']['progress'] = function ($a, $b, $c, $d) use ($trans, $emitter) { + $emitter->emit('progress', new ProgressEvent($trans, $a, $b, $c, $d)); + }; + } + + return $request; + } + + /** + * Handles the process of processing a response received from a ring + * handler. The created response is added to the transaction, and the + * transaction stat is set appropriately. + * + * @param Transaction $trans Owns request and response. + * @param array $response Ring response array + * @param MessageFactoryInterface $messageFactory Creates response objects. + */ + public static function completeRingResponse( + Transaction $trans, + array $response, + MessageFactoryInterface $messageFactory + ) { + $trans->state = 'complete'; + $trans->transferInfo = isset($response['transfer_stats']) + ? $response['transfer_stats'] : []; + + if (!empty($response['status'])) { + $options = []; + if (isset($response['version'])) { + $options['protocol_version'] = $response['version']; + } + if (isset($response['reason'])) { + $options['reason_phrase'] = $response['reason']; + } + $trans->response = $messageFactory->createResponse( + $response['status'], + isset($response['headers']) ? $response['headers'] : [], + isset($response['body']) ? $response['body'] : null, + $options + ); + if (isset($response['effective_url'])) { + $trans->response->setEffectiveUrl($response['effective_url']); + } + } elseif (empty($response['error'])) { + // When nothing was returned, then we need to add an error. + $response['error'] = self::getNoRingResponseException($trans->request); + } + + if (isset($response['error'])) { + $trans->state = 'error'; + $trans->exception = $response['error']; + } + } + + /** + * Creates a Guzzle request object using a ring request array. + * + * @param array $request Ring request + * + * @return Request + * @throws \InvalidArgumentException for incomplete requests. + */ + public static function fromRingRequest(array $request) + { + $options = []; + if (isset($request['version'])) { + $options['protocol_version'] = $request['version']; + } + + if (!isset($request['http_method'])) { + throw new \InvalidArgumentException('No http_method'); + } + + return new Request( + $request['http_method'], + Core::url($request), + isset($request['headers']) ? $request['headers'] : [], + isset($request['body']) ? Stream::factory($request['body']) : null, + $options + ); + } + + /** + * Get an exception that can be used when a RingPHP handler does not + * populate a response. + * + * @param RequestInterface $request + * + * @return RequestException + */ + public static function getNoRingResponseException(RequestInterface $request) + { + $message = <<cookieJar = $cookieJar ?: new CookieJar(); + } + + public function getEvents() + { + // Fire the cookie plugin complete event before redirecting + return [ + 'before' => ['onBefore'], + 'complete' => ['onComplete', RequestEvents::REDIRECT_RESPONSE + 10] + ]; + } + + /** + * Get the cookie cookieJar + * + * @return CookieJarInterface + */ + public function getCookieJar() + { + return $this->cookieJar; + } + + public function onBefore(BeforeEvent $event) + { + $this->cookieJar->addCookieHeader($event->getRequest()); + } + + public function onComplete(CompleteEvent $event) + { + $this->cookieJar->extractCookies( + $event->getRequest(), + $event->getResponse() + ); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/History.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/History.php new file mode 100644 index 00000000..5cf06119 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/History.php @@ -0,0 +1,172 @@ +limit = $limit; + } + + public function getEvents() + { + return [ + 'complete' => ['onComplete', RequestEvents::EARLY], + 'error' => ['onError', RequestEvents::EARLY], + ]; + } + + /** + * Convert to a string that contains all request and response headers + * + * @return string + */ + public function __toString() + { + $lines = array(); + foreach ($this->transactions as $entry) { + $response = isset($entry['response']) ? $entry['response'] : ''; + $lines[] = '> ' . trim($entry['sent_request']) + . "\n\n< " . trim($response) . "\n"; + } + + return implode("\n", $lines); + } + + public function onComplete(CompleteEvent $event) + { + $this->add($event->getRequest(), $event->getResponse()); + } + + public function onError(ErrorEvent $event) + { + // Only track when no response is present, meaning this didn't ever + // emit a complete event + if (!$event->getResponse()) { + $this->add($event->getRequest()); + } + } + + /** + * Returns an Iterator that yields associative array values where each + * associative array contains the following key value pairs: + * + * - request: Representing the actual request that was received. + * - sent_request: A clone of the request that will not be mutated. + * - response: The response that was received (if available). + * + * @return \Iterator + */ + public function getIterator() + { + return new \ArrayIterator($this->transactions); + } + + /** + * Get all of the requests sent through the plugin. + * + * Requests can be modified after they are logged by the history + * subscriber. By default this method will return the actual request + * instances that were received. Pass true to this method if you wish to + * get copies of the requests that represent the request state when it was + * initially logged by the history subscriber. + * + * @param bool $asSent Set to true to get clones of the requests that have + * not been mutated since the request was received by + * the history subscriber. + * + * @return RequestInterface[] + */ + public function getRequests($asSent = false) + { + return array_map(function ($t) use ($asSent) { + return $asSent ? $t['sent_request'] : $t['request']; + }, $this->transactions); + } + + /** + * Get the number of requests in the history + * + * @return int + */ + public function count() + { + return count($this->transactions); + } + + /** + * Get the last request sent. + * + * Requests can be modified after they are logged by the history + * subscriber. By default this method will return the actual request + * instance that was received. Pass true to this method if you wish to get + * a copy of the request that represents the request state when it was + * initially logged by the history subscriber. + * + * @param bool $asSent Set to true to get a clone of the last request that + * has not been mutated since the request was received + * by the history subscriber. + * + * @return RequestInterface + */ + public function getLastRequest($asSent = false) + { + return $asSent + ? end($this->transactions)['sent_request'] + : end($this->transactions)['request']; + } + + /** + * Get the last response in the history + * + * @return ResponseInterface|null + */ + public function getLastResponse() + { + return end($this->transactions)['response']; + } + + /** + * Clears the history + */ + public function clear() + { + $this->transactions = array(); + } + + /** + * Add a request to the history + * + * @param RequestInterface $request Request to add + * @param ResponseInterface $response Response of the request + */ + private function add( + RequestInterface $request, + ResponseInterface $response = null + ) { + $this->transactions[] = [ + 'request' => $request, + 'sent_request' => clone $request, + 'response' => $response + ]; + if (count($this->transactions) > $this->limit) { + array_shift($this->transactions); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/HttpError.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/HttpError.php new file mode 100644 index 00000000..ed9de5bc --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/HttpError.php @@ -0,0 +1,36 @@ + ['onComplete', RequestEvents::VERIFY_RESPONSE]]; + } + + /** + * Throw a RequestException on an HTTP protocol error + * + * @param CompleteEvent $event Emitted event + * @throws RequestException + */ + public function onComplete(CompleteEvent $event) + { + $code = (string) $event->getResponse()->getStatusCode(); + // Throw an exception for an unsuccessful response + if ($code[0] >= 4) { + throw RequestException::create( + $event->getRequest(), + $event->getResponse() + ); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Mock.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Mock.php new file mode 100644 index 00000000..2af4d375 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Mock.php @@ -0,0 +1,147 @@ +factory = new MessageFactory(); + $this->readBodies = $readBodies; + $this->addMultiple($items); + } + + public function getEvents() + { + // Fire the event last, after signing + return ['before' => ['onBefore', RequestEvents::SIGN_REQUEST - 10]]; + } + + /** + * @throws \OutOfBoundsException|\Exception + */ + public function onBefore(BeforeEvent $event) + { + if (!$item = array_shift($this->queue)) { + throw new \OutOfBoundsException('Mock queue is empty'); + } elseif ($item instanceof RequestException) { + throw $item; + } + + // Emulate reading a response body + $request = $event->getRequest(); + if ($this->readBodies && $request->getBody()) { + while (!$request->getBody()->eof()) { + $request->getBody()->read(8096); + } + } + + $saveTo = $event->getRequest()->getConfig()->get('save_to'); + + if (null !== $saveTo) { + $body = $item->getBody(); + + if (is_resource($saveTo)) { + fwrite($saveTo, $body); + } elseif (is_string($saveTo)) { + file_put_contents($saveTo, $body); + } elseif ($saveTo instanceof StreamInterface) { + $saveTo->write($body); + } + } + + $event->intercept($item); + } + + public function count() + { + return count($this->queue); + } + + /** + * Add a response to the end of the queue + * + * @param string|ResponseInterface $response Response or path to response file + * + * @return self + * @throws \InvalidArgumentException if a string or Response is not passed + */ + public function addResponse($response) + { + if (is_string($response)) { + $response = file_exists($response) + ? $this->factory->fromMessage(file_get_contents($response)) + : $this->factory->fromMessage($response); + } elseif (!($response instanceof ResponseInterface)) { + throw new \InvalidArgumentException('Response must a message ' + . 'string, response object, or path to a file'); + } + + $this->queue[] = $response; + + return $this; + } + + /** + * Add an exception to the end of the queue + * + * @param RequestException $e Exception to throw when the request is executed + * + * @return self + */ + public function addException(RequestException $e) + { + $this->queue[] = $e; + + return $this; + } + + /** + * Add multiple items to the queue + * + * @param array $items Items to add + */ + public function addMultiple(array $items) + { + foreach ($items as $item) { + if ($item instanceof RequestException) { + $this->addException($item); + } else { + $this->addResponse($item); + } + } + } + + /** + * Clear the queue + */ + public function clearQueue() + { + $this->queue = []; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Prepare.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Prepare.php new file mode 100644 index 00000000..b5ed4e26 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Prepare.php @@ -0,0 +1,130 @@ + ['onBefore', RequestEvents::PREPARE_REQUEST]]; + } + + public function onBefore(BeforeEvent $event) + { + $request = $event->getRequest(); + + // Set the appropriate Content-Type for a request if one is not set and + // there are form fields + if (!($body = $request->getBody())) { + return; + } + + $this->addContentLength($request, $body); + + if ($body instanceof AppliesHeadersInterface) { + // Synchronize the body with the request headers + $body->applyRequestHeaders($request); + } elseif (!$request->hasHeader('Content-Type')) { + $this->addContentType($request, $body); + } + + $this->addExpectHeader($request, $body); + } + + private function addContentType( + RequestInterface $request, + StreamInterface $body + ) { + if (!($uri = $body->getMetadata('uri'))) { + return; + } + + // Guess the content-type based on the stream's "uri" metadata value. + // The file extension is used to determine the appropriate mime-type. + if ($contentType = Mimetypes::getInstance()->fromFilename($uri)) { + $request->setHeader('Content-Type', $contentType); + } + } + + private function addContentLength( + RequestInterface $request, + StreamInterface $body + ) { + // Set the Content-Length header if it can be determined, and never + // send a Transfer-Encoding: chunked and Content-Length header in + // the same request. + if ($request->hasHeader('Content-Length')) { + // Remove transfer-encoding if content-length is set. + $request->removeHeader('Transfer-Encoding'); + return; + } + + if ($request->hasHeader('Transfer-Encoding')) { + return; + } + + if (null !== ($size = $body->getSize())) { + $request->setHeader('Content-Length', $size); + $request->removeHeader('Transfer-Encoding'); + } elseif ('1.1' == $request->getProtocolVersion()) { + // Use chunked Transfer-Encoding if there is no determinable + // content-length header and we're using HTTP/1.1. + $request->setHeader('Transfer-Encoding', 'chunked'); + $request->removeHeader('Content-Length'); + } + } + + private function addExpectHeader( + RequestInterface $request, + StreamInterface $body + ) { + // Determine if the Expect header should be used + if ($request->hasHeader('Expect')) { + return; + } + + $expect = $request->getConfig()['expect']; + + // Return if disabled or if you're not using HTTP/1.1 + if ($expect === false || $request->getProtocolVersion() !== '1.1') { + return; + } + + // The expect header is unconditionally enabled + if ($expect === true) { + $request->setHeader('Expect', '100-Continue'); + return; + } + + // By default, send the expect header when the payload is > 1mb + if ($expect === null) { + $expect = 1048576; + } + + // Always add if the body cannot be rewound, the size cannot be + // determined, or the size is greater than the cutoff threshold + $size = $body->getSize(); + if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { + $request->setHeader('Expect', '100-Continue'); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Redirect.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Redirect.php new file mode 100644 index 00000000..ff992268 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Subscriber/Redirect.php @@ -0,0 +1,176 @@ + ['onComplete', RequestEvents::REDIRECT_RESPONSE]]; + } + + /** + * Rewind the entity body of the request if needed + * + * @param RequestInterface $redirectRequest + * @throws CouldNotRewindStreamException + */ + public static function rewindEntityBody(RequestInterface $redirectRequest) + { + // Rewind the entity body of the request if needed + if ($body = $redirectRequest->getBody()) { + // Only rewind the body if some of it has been read already, and + // throw an exception if the rewind fails + if ($body->tell() && !$body->seek(0)) { + throw new CouldNotRewindStreamException( + 'Unable to rewind the non-seekable request body after redirecting', + $redirectRequest + ); + } + } + } + + /** + * Called when a request receives a redirect response + * + * @param CompleteEvent $event Event emitted + * @throws TooManyRedirectsException + */ + public function onComplete(CompleteEvent $event) + { + $response = $event->getResponse(); + + if (substr($response->getStatusCode(), 0, 1) != '3' + || !$response->hasHeader('Location') + ) { + return; + } + + $request = $event->getRequest(); + $config = $request->getConfig(); + + // Increment the redirect and initialize the redirect state. + if ($redirectCount = $config['redirect_count']) { + $config['redirect_count'] = ++$redirectCount; + } else { + $config['redirect_scheme'] = $request->getScheme(); + $config['redirect_count'] = $redirectCount = 1; + } + + $max = $config->getPath('redirect/max') ?: 5; + + if ($redirectCount > $max) { + throw new TooManyRedirectsException( + "Will not follow more than {$redirectCount} redirects", + $request + ); + } + + $this->modifyRedirectRequest($request, $response); + $event->retry(); + } + + private function modifyRedirectRequest( + RequestInterface $request, + ResponseInterface $response + ) { + $config = $request->getConfig(); + $protocols = $config->getPath('redirect/protocols') ?: ['http', 'https']; + + // Use a GET request if this is an entity enclosing request and we are + // not forcing RFC compliance, but rather emulating what all browsers + // would do. + $statusCode = $response->getStatusCode(); + if ($statusCode == 303 || + ($statusCode <= 302 && $request->getBody() && !$config->getPath('redirect/strict')) + ) { + $request->setMethod('GET'); + $request->setBody(null); + } + + $previousUrl = $request->getUrl(); + $this->setRedirectUrl($request, $response, $protocols); + $this->rewindEntityBody($request); + + // Add the Referer header if it is told to do so and only + // add the header if we are not redirecting from https to http. + if ($config->getPath('redirect/referer') + && ($request->getScheme() == 'https' || $request->getScheme() == $config['redirect_scheme']) + ) { + $url = Url::fromString($previousUrl); + $url->setUsername(null); + $url->setPassword(null); + $request->setHeader('Referer', (string) $url); + } else { + $request->removeHeader('Referer'); + } + } + + /** + * Set the appropriate URL on the request based on the location header + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @param array $protocols + */ + private function setRedirectUrl( + RequestInterface $request, + ResponseInterface $response, + array $protocols + ) { + $location = $response->getHeader('Location'); + $location = Url::fromString($location); + + // Combine location with the original URL if it is not absolute. + if (!$location->isAbsolute()) { + $originalUrl = Url::fromString($request->getUrl()); + // Remove query string parameters and just take what is present on + // the redirect Location header + $originalUrl->getQuery()->clear(); + $location = $originalUrl->combine($location); + } + + // Ensure that the redirect URL is allowed based on the protocols. + if (!in_array($location->getScheme(), $protocols)) { + throw new BadResponseException( + sprintf( + 'Redirect URL, %s, does not use one of the allowed redirect protocols: %s', + $location, + implode(', ', $protocols) + ), + $request, + $response + ); + } + + $request->setUrl($location); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/ToArrayInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/ToArrayInterface.php new file mode 100644 index 00000000..d57c0229 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/ToArrayInterface.php @@ -0,0 +1,15 @@ +client = $client; + $this->request = $request; + $this->_future = $future; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/UriTemplate.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/UriTemplate.php new file mode 100644 index 00000000..55dfeb5a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/UriTemplate.php @@ -0,0 +1,241 @@ + array('prefix' => '', 'joiner' => ',', 'query' => false), + '+' => array('prefix' => '', 'joiner' => ',', 'query' => false), + '#' => array('prefix' => '#', 'joiner' => ',', 'query' => false), + '.' => array('prefix' => '.', 'joiner' => '.', 'query' => false), + '/' => array('prefix' => '/', 'joiner' => '/', 'query' => false), + ';' => array('prefix' => ';', 'joiner' => ';', 'query' => true), + '?' => array('prefix' => '?', 'joiner' => '&', 'query' => true), + '&' => array('prefix' => '&', 'joiner' => '&', 'query' => true) + ); + + /** @var array Delimiters */ + private static $delims = array(':', '/', '?', '#', '[', ']', '@', '!', '$', + '&', '\'', '(', ')', '*', '+', ',', ';', '='); + + /** @var array Percent encoded delimiters */ + private static $delimsPct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', + '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', + '%3B', '%3D'); + + public function expand($template, array $variables) + { + if (false === strpos($template, '{')) { + return $template; + } + + $this->template = $template; + $this->variables = $variables; + + return preg_replace_callback( + '/\{([^\}]+)\}/', + [$this, 'expandMatch'], + $this->template + ); + } + + /** + * Parse an expression into parts + * + * @param string $expression Expression to parse + * + * @return array Returns an associative array of parts + */ + private function parseExpression($expression) + { + $result = array(); + + if (isset(self::$operatorHash[$expression[0]])) { + $result['operator'] = $expression[0]; + $expression = substr($expression, 1); + } else { + $result['operator'] = ''; + } + + foreach (explode(',', $expression) as $value) { + $value = trim($value); + $varspec = array(); + if ($colonPos = strpos($value, ':')) { + $varspec['value'] = substr($value, 0, $colonPos); + $varspec['modifier'] = ':'; + $varspec['position'] = (int) substr($value, $colonPos + 1); + } elseif (substr($value, -1) == '*') { + $varspec['modifier'] = '*'; + $varspec['value'] = substr($value, 0, -1); + } else { + $varspec['value'] = (string) $value; + $varspec['modifier'] = ''; + } + $result['values'][] = $varspec; + } + + return $result; + } + + /** + * Process an expansion + * + * @param array $matches Matches met in the preg_replace_callback + * + * @return string Returns the replacement string + */ + private function expandMatch(array $matches) + { + static $rfc1738to3986 = array('+' => '%20', '%7e' => '~'); + + $replacements = array(); + $parsed = self::parseExpression($matches[1]); + $prefix = self::$operatorHash[$parsed['operator']]['prefix']; + $joiner = self::$operatorHash[$parsed['operator']]['joiner']; + $useQuery = self::$operatorHash[$parsed['operator']]['query']; + + foreach ($parsed['values'] as $value) { + + if (!isset($this->variables[$value['value']])) { + continue; + } + + $variable = $this->variables[$value['value']]; + $actuallyUseQuery = $useQuery; + $expanded = ''; + + if (is_array($variable)) { + + $isAssoc = $this->isAssoc($variable); + $kvp = array(); + foreach ($variable as $key => $var) { + + if ($isAssoc) { + $key = rawurlencode($key); + $isNestedArray = is_array($var); + } else { + $isNestedArray = false; + } + + if (!$isNestedArray) { + $var = rawurlencode($var); + if ($parsed['operator'] == '+' || + $parsed['operator'] == '#' + ) { + $var = $this->decodeReserved($var); + } + } + + if ($value['modifier'] == '*') { + if ($isAssoc) { + if ($isNestedArray) { + // Nested arrays must allow for deeply nested + // structures. + $var = strtr( + http_build_query([$key => $var]), + $rfc1738to3986 + ); + } else { + $var = $key . '=' . $var; + } + } elseif ($key > 0 && $actuallyUseQuery) { + $var = $value['value'] . '=' . $var; + } + } + + $kvp[$key] = $var; + } + + if (empty($variable)) { + $actuallyUseQuery = false; + } elseif ($value['modifier'] == '*') { + $expanded = implode($joiner, $kvp); + if ($isAssoc) { + // Don't prepend the value name when using the explode + // modifier with an associative array. + $actuallyUseQuery = false; + } + } else { + if ($isAssoc) { + // When an associative array is encountered and the + // explode modifier is not set, then the result must be + // a comma separated list of keys followed by their + // respective values. + foreach ($kvp as $k => &$v) { + $v = $k . ',' . $v; + } + } + $expanded = implode(',', $kvp); + } + + } else { + if ($value['modifier'] == ':') { + $variable = substr($variable, 0, $value['position']); + } + $expanded = rawurlencode($variable); + if ($parsed['operator'] == '+' || $parsed['operator'] == '#') { + $expanded = $this->decodeReserved($expanded); + } + } + + if ($actuallyUseQuery) { + if (!$expanded && $joiner != '&') { + $expanded = $value['value']; + } else { + $expanded = $value['value'] . '=' . $expanded; + } + } + + $replacements[] = $expanded; + } + + $ret = implode($joiner, $replacements); + if ($ret && $prefix) { + return $prefix . $ret; + } + + return $ret; + } + + /** + * Determines if an array is associative. + * + * This makes the assumption that input arrays are sequences or hashes. + * This assumption is a tradeoff for accuracy in favor of speed, but it + * should work in almost every case where input is supplied for a URI + * template. + * + * @param array $array Array to check + * + * @return bool + */ + private function isAssoc(array $array) + { + return $array && array_keys($array)[0] !== 0; + } + + /** + * Removes percent encoding on reserved characters (used with + and # + * modifiers). + * + * @param string $string String to fix + * + * @return string + */ + private function decodeReserved($string) + { + return str_replace(self::$delimsPct, self::$delims, $string); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Url.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Url.php new file mode 100644 index 00000000..637f60c2 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Url.php @@ -0,0 +1,595 @@ + 80, 'https' => 443, 'ftp' => 21]; + private static $pathPattern = '/[^a-zA-Z0-9\-\._~!\$&\'\(\)\*\+,;=%:@\/]+|%(?![A-Fa-f0-9]{2})/'; + private static $queryPattern = '/[^a-zA-Z0-9\-\._~!\$\'\(\)\*\+,;%:@\/\?=&]+|%(?![A-Fa-f0-9]{2})/'; + /** @var Query|string Query part of the URL */ + private $query; + + /** + * Factory method to create a new URL from a URL string + * + * @param string $url Full URL used to create a Url object + * + * @return Url + * @throws \InvalidArgumentException + */ + public static function fromString($url) + { + static $defaults = ['scheme' => null, 'host' => null, + 'path' => null, 'port' => null, 'query' => null, + 'user' => null, 'pass' => null, 'fragment' => null]; + + if (false === ($parts = parse_url($url))) { + throw new \InvalidArgumentException('Unable to parse malformed ' + . 'url: ' . $url); + } + + $parts += $defaults; + + // Convert the query string into a Query object + if ($parts['query'] || 0 !== strlen($parts['query'])) { + $parts['query'] = Query::fromString($parts['query']); + } + + return new static($parts['scheme'], $parts['host'], $parts['user'], + $parts['pass'], $parts['port'], $parts['path'], $parts['query'], + $parts['fragment']); + } + + /** + * Build a URL from parse_url parts. The generated URL will be a relative + * URL if a scheme or host are not provided. + * + * @param array $parts Array of parse_url parts + * + * @return string + */ + public static function buildUrl(array $parts) + { + $url = $scheme = ''; + + if (!empty($parts['scheme'])) { + $scheme = $parts['scheme']; + $url .= $scheme . ':'; + } + + if (!empty($parts['host'])) { + $url .= '//'; + if (isset($parts['user'])) { + $url .= $parts['user']; + if (isset($parts['pass'])) { + $url .= ':' . $parts['pass']; + } + $url .= '@'; + } + + $url .= $parts['host']; + + // Only include the port if it is not the default port of the scheme + if (isset($parts['port']) && + (!isset(self::$defaultPorts[$scheme]) || + $parts['port'] != self::$defaultPorts[$scheme]) + ) { + $url .= ':' . $parts['port']; + } + } + + // Add the path component if present + if (isset($parts['path']) && strlen($parts['path'])) { + // Always ensure that the path begins with '/' if set and something + // is before the path + if (!empty($parts['host']) && $parts['path'][0] != '/') { + $url .= '/'; + } + $url .= $parts['path']; + } + + // Add the query string if present + if (isset($parts['query'])) { + $queryStr = (string) $parts['query']; + if ($queryStr || $queryStr === '0') { + $url .= '?' . $queryStr; + } + } + + // Ensure that # is only added to the url if fragment contains anything. + if (isset($parts['fragment'])) { + $url .= '#' . $parts['fragment']; + } + + return $url; + } + + /** + * Create a new URL from URL parts + * + * @param string $scheme Scheme of the URL + * @param string $host Host of the URL + * @param string $username Username of the URL + * @param string $password Password of the URL + * @param int $port Port of the URL + * @param string $path Path of the URL + * @param Query|array|string $query Query string of the URL + * @param string $fragment Fragment of the URL + */ + public function __construct( + $scheme, + $host, + $username = null, + $password = null, + $port = null, + $path = null, + $query = null, + $fragment = null + ) { + $this->scheme = strtolower($scheme); + $this->host = $host; + $this->port = $port; + $this->username = $username; + $this->password = $password; + $this->fragment = $fragment; + + if ($query) { + $this->setQuery($query); + } + + $this->setPath($path); + } + + /** + * Clone the URL + */ + public function __clone() + { + if ($this->query instanceof Query) { + $this->query = clone $this->query; + } + } + + /** + * Returns the URL as a URL string + * + * @return string + */ + public function __toString() + { + return static::buildUrl($this->getParts()); + } + + /** + * Get the parts of the URL as an array + * + * @return array + */ + public function getParts() + { + return array( + 'scheme' => $this->scheme, + 'user' => $this->username, + 'pass' => $this->password, + 'host' => $this->host, + 'port' => $this->port, + 'path' => $this->path, + 'query' => $this->query, + 'fragment' => $this->fragment, + ); + } + + /** + * Set the host of the request. + * + * @param string $host Host to set (e.g. www.yahoo.com, yahoo.com) + * + * @return Url + */ + public function setHost($host) + { + if (strpos($host, ':') === false) { + $this->host = $host; + } else { + list($host, $port) = explode(':', $host); + $this->host = $host; + $this->setPort($port); + } + } + + /** + * Get the host part of the URL + * + * @return string + */ + public function getHost() + { + return $this->host; + } + + /** + * Set the scheme part of the URL (http, https, ftp, etc.) + * + * @param string $scheme Scheme to set + */ + public function setScheme($scheme) + { + // Remove the default port if one is specified + if ($this->port + && isset(self::$defaultPorts[$this->scheme]) + && self::$defaultPorts[$this->scheme] == $this->port + ) { + $this->port = null; + } + + $this->scheme = strtolower($scheme); + } + + /** + * Get the scheme part of the URL + * + * @return string + */ + public function getScheme() + { + return $this->scheme; + } + + /** + * Set the port part of the URL + * + * @param int $port Port to set + */ + public function setPort($port) + { + $this->port = $port; + } + + /** + * Get the port part of the URl. + * + * If no port was set, this method will return the default port for the + * scheme of the URI. + * + * @return int|null + */ + public function getPort() + { + if ($this->port) { + return $this->port; + } elseif (isset(self::$defaultPorts[$this->scheme])) { + return self::$defaultPorts[$this->scheme]; + } + + return null; + } + + /** + * Set the path part of the URL. + * + * The provided URL is URL encoded as necessary. + * + * @param string $path Path string to set + */ + public function setPath($path) + { + $this->path = self::encodePath($path); + } + + /** + * Removes dot segments from a URL + * @link http://tools.ietf.org/html/rfc3986#section-5.2.4 + */ + public function removeDotSegments() + { + static $noopPaths = ['' => true, '/' => true, '*' => true]; + static $ignoreSegments = ['.' => true, '..' => true]; + + if (isset($noopPaths[$this->path])) { + return; + } + + $results = []; + $segments = $this->getPathSegments(); + foreach ($segments as $segment) { + if ($segment == '..') { + array_pop($results); + } elseif (!isset($ignoreSegments[$segment])) { + $results[] = $segment; + } + } + + $newPath = implode('/', $results); + + // Add the leading slash if necessary + if (substr($this->path, 0, 1) === '/' && + substr($newPath, 0, 1) !== '/' + ) { + $newPath = '/' . $newPath; + } + + // Add the trailing slash if necessary + if ($newPath != '/' && isset($ignoreSegments[end($segments)])) { + $newPath .= '/'; + } + + $this->path = $newPath; + } + + /** + * Add a relative path to the currently set path. + * + * @param string $relativePath Relative path to add + */ + public function addPath($relativePath) + { + if ($relativePath != '/' && + is_string($relativePath) && + strlen($relativePath) > 0 + ) { + // Add a leading slash if needed + if ($relativePath[0] !== '/' && + substr($this->path, -1, 1) !== '/' + ) { + $relativePath = '/' . $relativePath; + } + + $this->setPath($this->path . $relativePath); + } + } + + /** + * Get the path part of the URL + * + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * Get the path segments of the URL as an array + * + * @return array + */ + public function getPathSegments() + { + return explode('/', $this->path); + } + + /** + * Set the password part of the URL + * + * @param string $password Password to set + */ + public function setPassword($password) + { + $this->password = $password; + } + + /** + * Get the password part of the URL + * + * @return null|string + */ + public function getPassword() + { + return $this->password; + } + + /** + * Set the username part of the URL + * + * @param string $username Username to set + */ + public function setUsername($username) + { + $this->username = $username; + } + + /** + * Get the username part of the URl + * + * @return null|string + */ + public function getUsername() + { + return $this->username; + } + + /** + * Get the query part of the URL as a Query object + * + * @return Query + */ + public function getQuery() + { + // Convert the query string to a query object if not already done. + if (!$this->query instanceof Query) { + $this->query = $this->query === null + ? new Query() + : Query::fromString($this->query); + } + + return $this->query; + } + + /** + * Set the query part of the URL. + * + * You may provide a query string as a string and pass $rawString as true + * to provide a query string that is not parsed until a call to getQuery() + * is made. Setting a raw query string will still encode invalid characters + * in a query string. + * + * @param Query|string|array $query Query string value to set. Can + * be a string that will be parsed into a Query object, an array + * of key value pairs, or a Query object. + * @param bool $rawString Set to true when providing a raw query string. + * + * @throws \InvalidArgumentException + */ + public function setQuery($query, $rawString = false) + { + if ($query instanceof Query) { + $this->query = $query; + } elseif (is_string($query)) { + if (!$rawString) { + $this->query = Query::fromString($query); + } else { + // Ensure the query does not have illegal characters. + $this->query = preg_replace_callback( + self::$queryPattern, + [__CLASS__, 'encodeMatch'], + $query + ); + } + + } elseif (is_array($query)) { + $this->query = new Query($query); + } else { + throw new \InvalidArgumentException('Query must be a Query, ' + . 'array, or string. Got ' . Core::describeType($query)); + } + } + + /** + * Get the fragment part of the URL + * + * @return null|string + */ + public function getFragment() + { + return $this->fragment; + } + + /** + * Set the fragment part of the URL + * + * @param string $fragment Fragment to set + */ + public function setFragment($fragment) + { + $this->fragment = $fragment; + } + + /** + * Check if this is an absolute URL + * + * @return bool + */ + public function isAbsolute() + { + return $this->scheme && $this->host; + } + + /** + * Combine the URL with another URL and return a new URL instance. + * + * Follows the rules specific in RFC 3986 section 5.4. + * + * @param string $url Relative URL to combine with + * + * @return Url + * @throws \InvalidArgumentException + * @link http://tools.ietf.org/html/rfc3986#section-5.4 + */ + public function combine($url) + { + $url = static::fromString($url); + + // Use the more absolute URL as the base URL + if (!$this->isAbsolute() && $url->isAbsolute()) { + $url = $url->combine($this); + } + + $parts = $url->getParts(); + + // Passing a URL with a scheme overrides everything + if ($parts['scheme']) { + return clone $url; + } + + // Setting a host overrides the entire rest of the URL + if ($parts['host']) { + return new static( + $this->scheme, + $parts['host'], + $parts['user'], + $parts['pass'], + $parts['port'], + $parts['path'], + $parts['query'] instanceof Query + ? clone $parts['query'] + : $parts['query'], + $parts['fragment'] + ); + } + + if (!$parts['path'] && $parts['path'] !== '0') { + // The relative URL has no path, so check if it is just a query + $path = $this->path ?: ''; + $query = $parts['query'] ?: $this->query; + } else { + $query = $parts['query']; + if ($parts['path'][0] == '/' || !$this->path) { + // Overwrite the existing path if the rel path starts with "/" + $path = $parts['path']; + } else { + // If the relative URL does not have a path or the base URL + // path does not end in a "/" then overwrite the existing path + // up to the last "/" + $path = substr($this->path, 0, strrpos($this->path, '/') + 1) . $parts['path']; + } + } + + $result = new self( + $this->scheme, + $this->host, + $this->username, + $this->password, + $this->port, + $path, + $query instanceof Query ? clone $query : $query, + $parts['fragment'] + ); + + if ($path) { + $result->removeDotSegments(); + } + + return $result; + } + + /** + * Encodes the path part of a URL without double-encoding percent-encoded + * key value pairs. + * + * @param string $path Path to encode + * + * @return string + */ + public static function encodePath($path) + { + static $cb = [__CLASS__, 'encodeMatch']; + return preg_replace_callback(self::$pathPattern, $cb, $path); + } + + private static function encodeMatch(array $match) + { + return rawurlencode($match[0]); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Utils.php b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Utils.php new file mode 100644 index 00000000..17547190 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/guzzle/src/Utils.php @@ -0,0 +1,215 @@ +expand($template, $variables); + } + + /** + * Wrapper for JSON decode that implements error detection with helpful + * error messages. + * + * @param string $json JSON data to parse + * @param bool $assoc When true, returned objects will be converted + * into associative arrays. + * @param int $depth User specified recursion depth. + * @param int $options Bitmask of JSON decode options. + * + * @return mixed + * @throws \InvalidArgumentException if the JSON cannot be parsed. + * @link http://www.php.net/manual/en/function.json-decode.php + */ + public static function jsonDecode($json, $assoc = false, $depth = 512, $options = 0) + { + if ($json === '' || $json === null) { + return null; + } + + static $jsonErrors = [ + JSON_ERROR_DEPTH => 'JSON_ERROR_DEPTH - Maximum stack depth exceeded', + JSON_ERROR_STATE_MISMATCH => 'JSON_ERROR_STATE_MISMATCH - Underflow or the modes mismatch', + JSON_ERROR_CTRL_CHAR => 'JSON_ERROR_CTRL_CHAR - Unexpected control character found', + JSON_ERROR_SYNTAX => 'JSON_ERROR_SYNTAX - Syntax error, malformed JSON', + JSON_ERROR_UTF8 => 'JSON_ERROR_UTF8 - Malformed UTF-8 characters, possibly incorrectly encoded' + ]; + + $data = \json_decode($json, $assoc, $depth, $options); + + if (JSON_ERROR_NONE !== json_last_error()) { + $last = json_last_error(); + throw new \InvalidArgumentException( + 'Unable to parse JSON data: ' + . (isset($jsonErrors[$last]) + ? $jsonErrors[$last] + : 'Unknown error') + ); + } + + return $data; + } + + /** + * Get the default User-Agent string to use with Guzzle + * + * @return string + */ + public static function getDefaultUserAgent() + { + static $defaultAgent = ''; + if (!$defaultAgent) { + $defaultAgent = 'Guzzle/' . ClientInterface::VERSION; + if (extension_loaded('curl')) { + $defaultAgent .= ' curl/' . curl_version()['version']; + } + $defaultAgent .= ' PHP/' . PHP_VERSION; + } + + return $defaultAgent; + } + + /** + * Create a default handler to use based on the environment + * + * @throws \RuntimeException if no viable Handler is available. + */ + public static function getDefaultHandler() + { + $default = $future = null; + + if (extension_loaded('curl')) { + $config = [ + 'select_timeout' => getenv('GUZZLE_CURL_SELECT_TIMEOUT') ?: 1 + ]; + if ($maxHandles = getenv('GUZZLE_CURL_MAX_HANDLES')) { + $config['max_handles'] = $maxHandles; + } + if (function_exists('curl_reset')) { + $default = new CurlHandler(); + $future = new CurlMultiHandler($config); + } else { + $default = new CurlMultiHandler($config); + } + } + + if (ini_get('allow_url_fopen')) { + $default = !$default + ? new StreamHandler() + : Middleware::wrapStreaming($default, new StreamHandler()); + } elseif (!$default) { + throw new \RuntimeException('Guzzle requires cURL, the ' + . 'allow_url_fopen ini setting, or a custom HTTP handler.'); + } + + return $future ? Middleware::wrapFuture($default, $future) : $default; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.editorconfig b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.editorconfig new file mode 100644 index 00000000..70dabca1 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[{Makefile,*.mk}] +indent_style = tab diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.gitignore b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.gitignore new file mode 100644 index 00000000..290a9452 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.gitignore @@ -0,0 +1,4 @@ +vendor +build/artifacts/ +composer.lock +docs/_build/ diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.travis.yml b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.travis.yml new file mode 100644 index 00000000..18562e42 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/.travis.yml @@ -0,0 +1,43 @@ +language: php + +cache: + directories: + - $HOME/.composer/cache/files + +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - hhvm + - nightly + +env: + global: + - TEST_COMMAND="composer test" + +matrix: + allow_failures: + - php: hhvm + - php: nightly + fast_finish: true + include: + - php: 5.4 + env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" + +before_install: + - if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi + +install: + # To be removed when this issue will be resolved: https://github.com/composer/composer/issues/5355 + - if [[ "$COMPOSER_FLAGS" == *"--prefer-lowest"* ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable --quiet; fi + - travis_retry composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction + +before_script: + - ~/.nvm/nvm.sh install v0.6.14 + - ~/.nvm/nvm.sh run v0.6.14 + +script: + - $TEST_COMMAND diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/CHANGELOG.md b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/CHANGELOG.md new file mode 100644 index 00000000..8e12bf3c --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/CHANGELOG.md @@ -0,0 +1,118 @@ +# Changelog + + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + + +## [Unreleased] + + +## [1.1.1] - 2018-07-31 + +### Fixed + +- `continue` keyword usage on PHP 7.3 + + +## [1.1.0] - 2015-05-19 + +### Added + +- Added `CURL_HTTP_VERSION_2_0` + +### Changed + +- The PHP stream wrapper handler now sets `allow_self_signed` to `false` to + match the cURL handler when `verify` is set to `true` or a certificate file. +- Ensuring that a directory exists before using the `save_to` option. +- Response protocol version is now correctly extracted from a response. + +### Fixed + +- Fixed a bug in which the result of `CurlFactory::retryFailedRewind` did not + return an array. + + +## [1.0.7] - 2015-03-29 + +### Fixed + +- PHP 7 fixes. + + +## [1.0.6] - 2015-02-26 + +### Changed + +- The multi handle of the CurlMultiHandler is now created lazily. + +### Fixed + +- Bug fix: futures now extend from React's PromiseInterface to ensure that they + are properly forwarded down the promise chain. + + +## [1.0.5] - 2014-12-10 + +### Added + +- Adding more error information to PHP stream wrapper exceptions. +- Added digest auth integration test support to test server. + + +## [1.0.4] - 2014-12-01 + +### Added + +- Added support for older versions of cURL that do not have CURLOPT_TIMEOUT_MS. +- Added a fix to the StreamHandler to return a `FutureArrayInterface` when an + +### Changed + +- Setting debug to `false` does not enable debug output. error occurs. + + +## [1.0.3] - 2014-11-03 + +### Fixed + +- Setting the `header` stream option as a string to be compatible with GAE. +- Header parsing now ensures that header order is maintained in the parsed + message. + + +## [1.0.2] - 2014-10-28 + +### Fixed + +- Now correctly honoring a `version` option is supplied in a request. + See https://github.com/guzzle/RingPHP/pull/8 + + +## [1.0.1] - 2014-10-26 + +### Fixed + +- Fixed a header parsing issue with the `CurlHandler` and `CurlMultiHandler` + that caused cURL requests with multiple responses to merge repsonses together + (e.g., requests with digest authentication). + + +## 1.0.0 - 2014-10-12 + +- Initial release + + +[Unreleased]: https://github.com/guzzle/RingPHP/compare/1.1.1...HEAD +[1.1.1]: https://github.com/guzzle/RingPHP/compare/1.1.0...1.1.1 +[1.1.0]: https://github.com/guzzle/RingPHP/compare/1.0.7...1.1.0 +[1.0.7]: https://github.com/guzzle/RingPHP/compare/1.0.6...1.0.7 +[1.0.6]: https://github.com/guzzle/RingPHP/compare/1.0.5...1.0.6 +[1.0.5]: https://github.com/guzzle/RingPHP/compare/1.0.4...1.0.5 +[1.0.4]: https://github.com/guzzle/RingPHP/compare/1.0.3...1.0.4 +[1.0.3]: https://github.com/guzzle/RingPHP/compare/1.0.2...1.0.3 +[1.0.2]: https://github.com/guzzle/RingPHP/compare/1.0.1...1.0.2 +[1.0.1]: https://github.com/guzzle/RingPHP/compare/1.0.0...1.0.1 diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/LICENSE b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/LICENSE new file mode 100644 index 00000000..71d3b783 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Michael Dowling, https://github.com/mtdowling + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/Makefile b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/Makefile new file mode 100644 index 00000000..21c812e3 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/Makefile @@ -0,0 +1,46 @@ +all: clean coverage docs + +docs: + cd docs && make html + +view-docs: + open docs/_build/html/index.html + +start-server: stop-server + node tests/Client/server.js &> /dev/null & + +stop-server: + @PID=$(shell ps axo pid,command \ + | grep 'tests/Client/server.js' \ + | grep -v grep \ + | cut -f 1 -d " "\ + ) && [ -n "$$PID" ] && kill $$PID || true + +test: start-server + vendor/bin/phpunit $(TEST) + $(MAKE) stop-server + +coverage: start-server + vendor/bin/phpunit --coverage-html=build/artifacts/coverage $(TEST) + $(MAKE) stop-server + +view-coverage: + open build/artifacts/coverage/index.html + +clean: + rm -rf build/artifacts/* + cd docs && make clean + +tag: + $(if $(TAG),,$(error TAG is not defined. Pass via "make tag TAG=4.2.1")) + @echo Tagging $(TAG) + chag update -m '$(TAG) ()' + git add -A + git commit -m '$(TAG) release' + chag tag + +perf: start-server + php tests/perf.php + $(MAKE) stop-server + +.PHONY: docs diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/README.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/README.rst new file mode 100644 index 00000000..10374e81 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/README.rst @@ -0,0 +1,46 @@ +======= +RingPHP +======= + +Provides a simple API and specification that abstracts away the details of HTTP +into a single PHP function. RingPHP be used to power HTTP clients and servers +through a PHP function that accepts a request hash and returns a response hash +that is fulfilled using a `promise `_, +allowing RingPHP to support both synchronous and asynchronous workflows. + +By abstracting the implementation details of different HTTP clients and +servers, RingPHP allows you to utilize pluggable HTTP clients and servers +without tying your application to a specific implementation. + +.. code-block:: php + + 'GET', + 'uri' => '/', + 'headers' => [ + 'host' => ['www.google.com'], + 'x-foo' => ['baz'] + ] + ]); + + $response->then(function (array $response) { + echo $response['status']; + }); + + $response->wait(); + +RingPHP is inspired by Clojure's `Ring `_, +which, in turn, was inspired by Python's WSGI and Ruby's Rack. RingPHP is +utilized as the handler layer in `Guzzle `_ 5.0+ to send +HTTP requests. + +Documentation +------------- + +See http://ringphp.readthedocs.org/ for the full online documentation. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/composer.json b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/composer.json new file mode 100644 index 00000000..8df60ecc --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/composer.json @@ -0,0 +1,43 @@ +{ + "name": "guzzlehttp/ringphp", + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.4.0", + "guzzlehttp/streams": "~3.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "GuzzleHttp\\Tests\\Ring\\": "tests/" + } + }, + "scripts": { + "test": "make test", + "test-ci": "make coverage" + }, + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/Makefile b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/Makefile new file mode 100644 index 00000000..51270aa5 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/GuzzleRing.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/GuzzleRing.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/GuzzleRing" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/GuzzleRing" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/client_handlers.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/client_handlers.rst new file mode 100644 index 00000000..3151f002 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/client_handlers.rst @@ -0,0 +1,173 @@ +=============== +Client Handlers +=============== + +Client handlers accept a request array and return a future response array that +can be used synchronously as an array or asynchronously using a promise. + +Built-In Handlers +----------------- + +RingPHP comes with three built-in client handlers. + +Stream Handler +~~~~~~~~~~~~~~ + +The ``GuzzleHttp\Ring\Client\StreamHandler`` uses PHP's +`http stream wrapper `_ to send +requests. + +.. note:: + + This handler cannot send requests concurrently. + +You can provide an associative array of custom stream context options to the +StreamHandler using the ``stream_context`` key of the ``client`` request +option. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\StreamHandler; + + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => ['httpbin.org']], + 'client' => [ + 'stream_context' => [ + 'http' => [ + 'request_fulluri' => true, + 'method' => 'HEAD' + ], + 'socket' => [ + 'bindto' => '127.0.0.1:0' + ], + 'ssl' => [ + 'verify_peer' => false + ] + ] + ] + ]); + + // Even though it's already completed, you can still use a promise + $response->then(function ($response) { + echo $response['status']; // 200 + }); + + // Or access the response using the future interface + echo $response['status']; // 200 + +cURL Handler +~~~~~~~~~~~~ + +The ``GuzzleHttp\Ring\Client\CurlHandler`` can be used with PHP 5.5+ to send +requests using cURL easy handles. This handler is great for sending requests +one at a time because the execute and select loop is implemented in C code +which executes faster and consumes less memory than using PHP's +``curl_multi_*`` interface. + +.. note:: + + This handler cannot send requests concurrently. + +When using the CurlHandler, custom curl options can be specified as an +associative array of `cURL option constants `_ +mapping to values in the ``client`` option of a requst using the **curl** key. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlHandler; + + $handler = new CurlHandler(); + + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]] + ]; + + $response = $handler($request); + + // The response can be used directly as an array. + echo $response['status']; // 200 + + // Or, it can be used as a promise (that has already fulfilled). + $response->then(function ($response) { + echo $response['status']; // 200 + }); + +cURL Multi Handler +~~~~~~~~~~~~~~~~~~ + +The ``GuzzleHttp\Ring\Client\CurlMultiHandler`` transfers requests using +cURL's `multi API `_. The +``CurlMultiHandler`` is great for sending requests concurrently. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlMultiHandler; + + $handler = new CurlMultiHandler(); + + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]] + ]; + + // this call returns a future array immediately. + $response = $handler($request); + + // Ideally, you should use the promise API to not block. + $response + ->then(function ($response) { + // Got the response at some point in the future + echo $response['status']; // 200 + // Don't break the chain + return $response; + })->then(function ($response) { + // ... + }); + + // If you really need to block, then you can use the response as an + // associative array. This will block until it has completed. + echo $response['status']; // 200 + +Just like the ``CurlHandler``, the ``CurlMultiHandler`` accepts custom curl +option in the ``curl`` key of the ``client`` request option. + +Mock Handler +~~~~~~~~~~~~ + +The ``GuzzleHttp\Ring\Client\MockHandler`` is used to return mock responses. +When constructed, the handler can be configured to return the same response +array over and over, a future response, or a the evaluation of a callback +function. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\MockHandler; + + // Return a canned response. + $mock = new MockHandler(['status' => 200]); + $response = $mock([]); + assert(200 == $response['status']); + assert([] == $response['headers']); + +Implementing Handlers +--------------------- + +Client handlers are just PHP callables (functions or classes that have the +``__invoke`` magic method). The callable accepts a request array and MUST +return an instance of ``GuzzleHttp\Ring\Future\FutureArrayInterface`` so that +the response can be used by both blocking and non-blocking consumers. + +Handlers need to follow a few simple rules: + +1. Do not throw exceptions. If an error is encountered, return an array that + contains the ``error`` key that maps to an ``\Exception`` value. +2. If the request has a ``delay`` client option, then the handler should only + send the request after the specified delay time in seconds. Blocking + handlers may find it convenient to just let the + ``GuzzleHttp\Ring\Core::doSleep($request)`` function handle this for them. +3. Always return an instance of ``GuzzleHttp\Ring\Future\FutureArrayInterface``. +4. Complete any outstanding requests when the handler is destructed. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/client_middleware.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/client_middleware.rst new file mode 100644 index 00000000..5a2c1a8a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/client_middleware.rst @@ -0,0 +1,165 @@ +================= +Client Middleware +================= + +Middleware intercepts requests before they are sent over the wire and can be +used to add functionality to handlers. + +Modifying Requests +------------------ + +Let's say you wanted to modify requests before they are sent over the wire +so that they always add specific headers. This can be accomplished by creating +a function that accepts a handler and returns a new function that adds the +composed behavior. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlHandler; + + $handler = new CurlHandler(); + + $addHeaderHandler = function (callable $handler, array $headers = []) { + return function (array $request) use ($handler, $headers) { + // Add our custom headers + foreach ($headers as $key => $value) { + $request['headers'][$key] = $value; + } + + // Send the request using the handler and return the response. + return $handler($request); + } + }; + + // Create a new handler that adds headers to each request. + $handler = $addHeaderHandler($handler, [ + 'X-AddMe' => 'hello', + 'Authorization' => 'Basic xyz' + ]); + + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['Host' => ['httpbin.org']] + ]); + +Modifying Responses +------------------- + +You can change a response as it's returned from a middleware. Remember that +responses returned from an handler (including middleware) must implement +``GuzzleHttp\Ring\Future\FutureArrayInterface``. In order to be a good citizen, +you should not expect that the responses returned through your middleware will +be completed synchronously. Instead, you should use the +``GuzzleHttp\Ring\Core::proxy()`` function to modify the response when the +underlying promise is resolved. This function is a helper function that makes it +easy to create a new instance of ``FutureArrayInterface`` that wraps an existing +``FutureArrayInterface`` object. + +Let's say you wanted to add headers to a response as they are returned from +your middleware, but you want to make sure you aren't causing future +responses to be dereferenced right away. You can achieve this by modifying the +incoming request and using the ``Core::proxy`` function. + +.. code-block:: php + + use GuzzleHttp\Ring\Core; + use GuzzleHttp\Ring\Client\CurlHandler; + + $handler = new CurlHandler(); + + $responseHeaderHandler = function (callable $handler, array $headers) { + return function (array $request) use ($handler, $headers) { + // Send the request using the wrapped handler. + return Core::proxy($handler($request), function ($response) use ($headers) { + // Add the headers to the response when it is available. + foreach ($headers as $key => $value) { + $response['headers'][$key] = (array) $value; + } + // Note that you can return a regular response array when using + // the proxy method. + return $response; + }); + } + }; + + // Create a new handler that adds headers to each response. + $handler = $responseHeaderHandler($handler, ['X-Header' => 'hello!']); + + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['Host' => ['httpbin.org']] + ]); + + assert($response['headers']['X-Header'] == 'hello!'); + +Built-In Middleware +------------------- + +RingPHP comes with a few basic client middlewares that modify requests +and responses. + +Streaming Middleware +~~~~~~~~~~~~~~~~~~~~ + +If you want to send all requests with the ``streaming`` option to a specific +handler but other requests to a different handler, then use the streaming +middleware. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlHandler; + use GuzzleHttp\Ring\Client\StreamHandler; + use GuzzleHttp\Ring\Client\Middleware; + + $defaultHandler = new CurlHandler(); + $streamingHandler = new StreamHandler(); + $streamingHandler = Middleware::wrapStreaming( + $defaultHandler, + $streamingHandler + ); + + // Send the request using the streaming handler. + $response = $streamingHandler([ + 'http_method' => 'GET', + 'headers' => ['Host' => ['www.google.com']], + 'stream' => true + ]); + + // Send the request using the default handler. + $response = $streamingHandler([ + 'http_method' => 'GET', + 'headers' => ['Host' => ['www.google.com']] + ]); + +Future Middleware +~~~~~~~~~~~~~~~~~ + +If you want to send all requests with the ``future`` option to a specific +handler but other requests to a different handler, then use the future +middleware. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlHandler; + use GuzzleHttp\Ring\Client\CurlMultiHandler; + use GuzzleHttp\Ring\Client\Middleware; + + $defaultHandler = new CurlHandler(); + $futureHandler = new CurlMultiHandler(); + $futureHandler = Middleware::wrapFuture( + $defaultHandler, + $futureHandler + ); + + // Send the request using the blocking CurlHandler. + $response = $futureHandler([ + 'http_method' => 'GET', + 'headers' => ['Host' => ['www.google.com']] + ]); + + // Send the request using the non-blocking CurlMultiHandler. + $response = $futureHandler([ + 'http_method' => 'GET', + 'headers' => ['Host' => ['www.google.com']], + 'future' => true + ]); diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/conf.py b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/conf.py new file mode 100644 index 00000000..c6404aa1 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/conf.py @@ -0,0 +1,23 @@ +import sys, os +import sphinx_rtd_theme +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer + + +lexers['php'] = PhpLexer(startinline=True, linenos=1) +lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1) +primary_domain = 'php' + +extensions = [] +templates_path = ['_templates'] +source_suffix = '.rst' +master_doc = 'index' +project = u'RingPHP' +copyright = u'2014, Michael Dowling' +version = '1.0.0-alpha' +exclude_patterns = ['_build'] + +html_title = "RingPHP" +html_short_title = "RingPHP" +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/futures.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/futures.rst new file mode 100644 index 00000000..af29cb37 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/futures.rst @@ -0,0 +1,164 @@ +======= +Futures +======= + +Futures represent a computation that may have not yet completed. RingPHP +uses hybrid of futures and promises to provide a consistent API that can be +used for both blocking and non-blocking consumers. + +Promises +-------- + +You can get the result of a future when it is ready using the promise interface +of a future. Futures expose a promise API via a ``then()`` method that utilizes +`React's promise library `_. You should +use this API when you do not wish to block. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlMultiHandler; + + $request = [ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => ['httpbin.org']] + ]; + + $response = $handler($request); + + // Use the then() method to use the promise API of the future. + $response->then(function ($response) { + echo $response['status']; + }); + +You can get the promise used by a future, an instance of +``React\Promise\PromiseInterface``, by calling the ``promise()`` method. + +.. code-block:: php + + $response = $handler($request); + $promise = $response->promise(); + $promise->then(function ($response) { + echo $response['status']; + }); + +This promise value can be used with React's +`aggregate promise functions `_. + +Waiting +------- + +You can wait on a future to complete and retrieve the value, or *dereference* +the future, using the ``wait()`` method. Calling the ``wait()`` method of a +future will block until the result is available. The result is then returned or +an exception is thrown if and exception was encountered while waiting on the +the result. Subsequent calls to dereference a future will return the previously +completed result or throw the previously encountered exception. Futures can be +cancelled, which stops the computation if possible. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlMultiHandler; + + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => ['httpbin.org']] + ]); + + // You can explicitly call block to wait on a result. + $realizedResponse = $response->wait(); + + // Future responses can be used like a regular PHP array. + echo $response['status']; + +In addition to explicitly calling the ``wait()`` function, using a future like +a normal value will implicitly trigger the ``wait()`` function. + +Future Responses +---------------- + +RingPHP uses futures to return asynchronous responses immediately. Client +handlers always return future responses that implement +``GuzzleHttp\Ring\Future\ArrayFutureInterface``. These future responses act +just like normal PHP associative arrays for blocking access and provide a +promise interface for non-blocking access. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlMultiHandler; + + $handler = new CurlMultiHandler(); + + $request = [ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['Host' => ['www.google.com']] + ]; + + $response = $handler($request); + + // Use the promise API for non-blocking access to the response. The actual + // response value will be delivered to the promise. + $response->then(function ($response) { + echo $response['status']; + }); + + // You can wait (block) until the future is completed. + $response->wait(); + + // This will implicitly call wait(), and will block too! + $response['status']; + +.. important:: + + Futures that are not completed by the time the underlying handler is + destructed will be completed when the handler is shutting down. + +Cancelling +---------- + +Futures can be cancelled if they have not already been dereferenced. + +RingPHP futures are typically implemented with the +``GuzzleHttp\Ring\Future\BaseFutureTrait``. This trait provides the cancellation +functionality that should be common to most implementations. Cancelling a +future response will try to prevent the request from sending over the wire. + +When a future is cancelled, the cancellation function is invoked and performs +the actual work needed to cancel the request from sending if possible +(e.g., telling an event loop to stop sending a request or to close a socket). +If no cancellation function is provided, then a request cannot be cancelled. If +a cancel function is provided, then it should accept the future as an argument +and return true if the future was successfully cancelled or false if it could +not be cancelled. + +Wrapping an existing Promise +---------------------------- + +You can easily create a future from any existing promise using the +``GuzzleHttp\Ring\Future\FutureValue`` class. This class's constructor +accepts a promise as the first argument, a wait function as the second +argument, and a cancellation function as the third argument. The dereference +function is used to force the promise to resolve (for example, manually ticking +an event loop). The cancel function is optional and is used to tell the thing +that created the promise that it can stop computing the result (for example, +telling an event loop to stop transferring a request). + +.. code-block:: php + + use GuzzleHttp\Ring\Future\FutureValue; + use React\Promise\Deferred; + + $deferred = new Deferred(); + $promise = $deferred->promise(); + + $f = new FutureValue( + $promise, + function () use ($deferred) { + // This function is responsible for blocking and resolving the + // promise. Here we pass in a reference to the deferred so that + // it can be resolved or rejected. + $deferred->resolve('foo'); + } + ); diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/index.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/index.rst new file mode 100644 index 00000000..4bbce631 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/index.rst @@ -0,0 +1,50 @@ +======= +RingPHP +======= + +Provides a simple API and specification that abstracts away the details of HTTP +into a single PHP function. RingPHP be used to power HTTP clients and servers +through a PHP function that accepts a request hash and returns a response hash +that is fulfilled using a `promise `_, +allowing RingPHP to support both synchronous and asynchronous workflows. + +By abstracting the implementation details of different HTTP clients and +servers, RingPHP allows you to utilize pluggable HTTP clients and servers +without tying your application to a specific implementation. + +.. toctree:: + :maxdepth: 2 + + spec + futures + client_middleware + client_handlers + testing + +.. code-block:: php + + 'GET', + 'uri' => '/', + 'headers' => [ + 'host' => ['www.google.com'], + 'x-foo' => ['baz'] + ] + ]); + + $response->then(function (array $response) { + echo $response['status']; + }); + + $response->wait(); + +RingPHP is inspired by Clojure's `Ring `_, +which, in turn, was inspired by Python's WSGI and Ruby's Rack. RingPHP is +utilized as the handler layer in `Guzzle `_ 5.0+ to send +HTTP requests. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/requirements.txt b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/requirements.txt new file mode 100644 index 00000000..483a4e96 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/requirements.txt @@ -0,0 +1 @@ +sphinx_rtd_theme diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/spec.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/spec.rst new file mode 100644 index 00000000..bc910789 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/spec.rst @@ -0,0 +1,311 @@ +============= +Specification +============= + +RingPHP applications consist of handlers, requests, responses, and +middleware. + +Handlers +-------- + +Handlers are implemented as a PHP ``callable`` that accept a request array +and return a response array (``GuzzleHttp\Ring\Future\FutureArrayInterface``). + +For example: + +.. code-block:: php + + use GuzzleHttp\Ring\Future\CompletedFutureArray; + + $mockHandler = function (array $request) { + return new CompletedFutureArray([ + 'status' => 200, + 'headers' => ['X-Foo' => ['Bar']], + 'body' => 'Hello!' + ]); + }; + +This handler returns the same response each time it is invoked. All RingPHP +handlers must return a ``GuzzleHttp\Ring\Future\FutureArrayInterface``. Use +``GuzzleHttp\Ring\Future\CompletedFutureArray`` when returning a response that +has already completed. + +Requests +-------- + +A request array is a PHP associative array that contains the configuration +settings need to send a request. + +.. code-block:: php + + $request = [ + 'http_method' => 'GET', + 'scheme' => 'http', + 'uri' => '/', + 'body' => 'hello!', + 'client' => ['timeout' => 1.0], + 'headers' => [ + 'host' => ['httpbin.org'], + 'X-Foo' => ['baz', 'bar'] + ] + ]; + +The request array contains the following key value pairs: + +request_method + (string, required) The HTTP request method, must be all caps corresponding + to a HTTP request method, such as ``GET`` or ``POST``. + +scheme + (string) The transport protocol, must be one of ``http`` or ``https``. + Defaults to ``http``. + +uri + (string, required) The request URI excluding the query string. Must + start with "/". + +query_string + (string) The query string, if present (e.g., ``foo=bar``). + +version + (string) HTTP protocol version. Defaults to ``1.1``. + +headers + (required, array) Associative array of headers. Each key represents the + header name. Each value contains an array of strings where each entry of + the array SHOULD be sent over the wire on a separate header line. + +body + (string, fopen resource, ``Iterator``, ``GuzzleHttp\Stream\StreamInterface``) + The body of the request, if present. Can be a string, resource returned + from fopen, an ``Iterator`` that yields chunks of data, an object that + implemented ``__toString``, or a ``GuzzleHttp\Stream\StreamInterface``. + +future + (bool, string) Controls the asynchronous behavior of a response. + + Set to ``true`` or omit the ``future`` option to *request* that a request + will be completed asynchronously. Keep in mind that your request might not + necessarily be completed asynchronously based on the handler you are using. + Set the ``future`` option to ``false`` to request that a synchronous + response be provided. + + You can provide a string value to specify fine-tuned future behaviors that + may be specific to the underlying handlers you are using. There are, + however, some common future options that handlers should implement if + possible. + + lazy + Requests that the handler does not open and send the request + immediately, but rather only opens and sends the request once the + future is dereferenced. This option is often useful for sending a large + number of requests concurrently to allow handlers to take better + advantage of non-blocking transfers by first building up a pool of + requests. + + If an handler does not implement or understand a provided string value, + then the request MUST be treated as if the user provided ``true`` rather + than the string value. + + Future responses created by asynchronous handlers MUST attempt to complete + any outstanding future responses when they are destructed. Asynchronous + handlers MAY choose to automatically complete responses when the number + of outstanding requests reaches an handler-specific threshold. + +Client Specific Options +~~~~~~~~~~~~~~~~~~~~~~~ + +The following options are only used in ring client handlers. + +.. _client-options: + +client + (array) Associative array of client specific transfer options. The + ``client`` request key value pair can contain the following keys: + + cert + (string, array) Set to a string to specify the path to a file + containing a PEM formatted SSL client side certificate. If a password + is required, then set ``cert`` to an array containing the path to the + PEM file in the first array element followed by the certificate + password in the second array element. + + connect_timeout + (float) Float describing the number of seconds to wait while trying to + connect to a server. Use ``0`` to wait indefinitely (the default + behavior). + + debug + (bool, fopen() resource) Set to true or set to a PHP stream returned by + fopen() to enable debug output with the handler used to send a request. + If set to ``true``, the output is written to PHP's STDOUT. If a PHP + ``fopen`` resource handle is provided, the output is written to the + stream. + + "Debug output" is handler specific: different handlers will yield + different output and various various level of detail. For example, when + using cURL to transfer requests, cURL's `CURLOPT_VERBOSE `_ + will be used. When using the PHP stream wrapper, `stream notifications `_ + will be emitted. + + decode_content + (bool) Specify whether or not ``Content-Encoding`` responses + (gzip, deflate, etc.) are automatically decoded. Set to ``true`` to + automatically decode encoded responses. Set to ``false`` to not decode + responses. By default, content is *not* decoded automatically. + + delay + (int) The number of milliseconds to delay before sending the request. + This is often used for delaying before retrying a request. Handlers + SHOULD implement this if possible, but it is not a strict requirement. + + progress + (function) Defines a function to invoke when transfer progress is made. + The function accepts the following arguments: + + 1. The total number of bytes expected to be downloaded + 2. The number of bytes downloaded so far + 3. The number of bytes expected to be uploaded + 4. The number of bytes uploaded so far + + proxy + (string, array) Pass a string to specify an HTTP proxy, or an + associative array to specify different proxies for different protocols + where the scheme is the key and the value is the proxy address. + + .. code-block:: php + + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => ['httpbin.org']], + 'client' => [ + // Use different proxies for different URI schemes. + 'proxy' => [ + 'http' => 'http://proxy.example.com:5100', + 'https' => 'https://proxy.example.com:6100' + ] + ] + ]; + + ssl_key + (string, array) Specify the path to a file containing a private SSL key + in PEM format. If a password is required, then set to an array + containing the path to the SSL key in the first array element followed + by the password required for the certificate in the second element. + + save_to + (string, fopen resource, ``GuzzleHttp\Stream\StreamInterface``) + Specifies where the body of the response is downloaded. Pass a string to + open a local file on disk and save the output to the file. Pass an fopen + resource to save the output to a PHP stream resource. Pass a + ``GuzzleHttp\Stream\StreamInterface`` to save the output to a Guzzle + StreamInterface. Omitting this option will typically save the body of a + response to a PHP temp stream. + + stream + (bool) Set to true to stream a response rather than download it all + up-front. This option will only be utilized when the corresponding + handler supports it. + + timeout + (float) Float describing the timeout of the request in seconds. Use 0 to + wait indefinitely (the default behavior). + + verify + (bool, string) Describes the SSL certificate verification behavior of a + request. Set to true to enable SSL certificate verification using the + system CA bundle when available (the default). Set to false to disable + certificate verification (this is insecure!). Set to a string to provide + the path to a CA bundle on disk to enable verification using a custom + certificate. + + version + (string) HTTP protocol version to use with the request. + +Server Specific Options +~~~~~~~~~~~~~~~~~~~~~~~ + +The following options are only used in ring server handlers. + +server_port + (integer) The port on which the request is being handled. This is only + used with ring servers, and is required. + +server_name + (string) The resolved server name, or the server IP address. Required when + using a Ring server. + +remote_addr + (string) The IP address of the client or the last proxy that sent the + request. Required when using a Ring server. + +Responses +--------- + +A response is an array-like object that implements +``GuzzleHttp\Ring\Future\FutureArrayInterface``. Responses contain the +following key value pairs: + +body + (string, fopen resource, ``Iterator``, ``GuzzleHttp\Stream\StreamInterface``) + The body of the response, if present. Can be a string, resource returned + from fopen, an ``Iterator`` that yields chunks of data, an object that + implemented ``__toString``, or a ``GuzzleHttp\Stream\StreamInterface``. + +effective_url + (string) The URL that returned the resulting response. + +error + (``\Exception``) Contains an exception describing any errors that were + encountered during the transfer. + +headers + (Required, array) Associative array of headers. Each key represents the + header name. Each value contains an array of strings where each entry of + the array is a header line. The headers array MAY be an empty array in the + event an error occurred before a response was received. + +reason + (string) Optional reason phrase. This option should be provided when the + reason phrase does not match the typical reason phrase associated with the + ``status`` code. See `RFC 7231 `_ + for a list of HTTP reason phrases mapped to status codes. + +status + (Required, integer) The HTTP status code. The status code MAY be set to + ``null`` in the event an error occurred before a response was received + (e.g., a networking error). + +transfer_stats + (array) Provides an associative array of arbitrary transfer statistics if + provided by the underlying handler. + +version + (string) HTTP protocol version. Defaults to ``1.1``. + +Middleware +---------- + +Ring middleware augments the functionality of handlers by invoking them in the +process of generating responses. Middleware is typically implemented as a +higher-order function that takes one or more handlers as arguments followed by +an optional associative array of options as the last argument, returning a new +handler with the desired compound behavior. + +Here's an example of a middleware that adds a Content-Type header to each +request. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\CurlHandler; + use GuzzleHttp\Ring\Core; + + $contentTypeHandler = function(callable $handler, $contentType) { + return function (array $request) use ($handler, $contentType) { + return $handler(Core::setHeader('Content-Type', $contentType)); + }; + }; + + $baseHandler = new CurlHandler(); + $wrappedHandler = $contentTypeHandler($baseHandler, 'text/html'); + $response = $wrappedHandler([/** request hash **/]); diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/testing.rst b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/testing.rst new file mode 100644 index 00000000..9df2562e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/docs/testing.rst @@ -0,0 +1,74 @@ +======= +Testing +======= + +RingPHP tests client handlers using `PHPUnit `_ and a +built-in node.js web server. + +Running Tests +------------- + +First, install the dependencies using `Composer `_. + + composer.phar install + +Next, run the unit tests using ``Make``. + + make test + +The tests are also run on Travis-CI on each commit: https://travis-ci.org/guzzle/guzzle-ring + +Test Server +----------- + +Testing client handlers usually involves actually sending HTTP requests. +RingPHP provides a node.js web server that returns canned responses and +keep a list of the requests that have been received. The server can then +be queried to get a list of the requests that were sent by the client so that +you can ensure that the client serialized and transferred requests as intended. + +The server keeps a list of queued responses and returns responses that are +popped off of the queue as HTTP requests are received. When there are not +more responses to serve, the server returns a 500 error response. + +The test server uses the ``GuzzleHttp\Tests\Ring\Client\Server`` class to +control the server. + +.. code-block:: php + + use GuzzleHttp\Ring\Client\StreamHandler; + use GuzzleHttp\Tests\Ring\Client\Server; + + // First return a 200 followed by a 404 response. + Server::enqueue([ + ['status' => 200], + ['status' => 404] + ]); + + $handler = new StreamHandler(); + + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'uri' => '/' + ]); + + assert(200 == $response['status']); + + $response = $handler([ + 'http_method' => 'HEAD', + 'headers' => ['host' => [Server::$host]], + 'uri' => '/' + ]); + + assert(404 == $response['status']); + +After requests have been sent, you can get a list of the requests as they +were sent over the wire to ensure they were sent correctly. + +.. code-block:: php + + $received = Server::received(); + + assert('GET' == $received[0]['http_method']); + assert('HEAD' == $received[1]['http_method']); diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/phpunit.xml.dist b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/phpunit.xml.dist new file mode 100644 index 00000000..1d192902 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/phpunit.xml.dist @@ -0,0 +1,14 @@ + + + + + tests + + + + + src + + + diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/ClientUtils.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/ClientUtils.php new file mode 100644 index 00000000..27d5fe7e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/ClientUtils.php @@ -0,0 +1,74 @@ +getDefaultOptions($request, $headers); + $this->applyMethod($request, $options); + + if (isset($request['client'])) { + $this->applyHandlerOptions($request, $options); + } + + $this->applyHeaders($request, $options); + unset($options['_headers']); + + // Add handler options from the request's configuration options + if (isset($request['client']['curl'])) { + $options = $this->applyCustomCurlOptions( + $request['client']['curl'], + $options + ); + } + + if (!$handle) { + $handle = curl_init(); + } + + $body = $this->getOutputBody($request, $options); + curl_setopt_array($handle, $options); + + return [$handle, &$headers, $body]; + } + + /** + * Creates a response hash from a cURL result. + * + * @param callable $handler Handler that was used. + * @param array $request Request that sent. + * @param array $response Response hash to update. + * @param array $headers Headers received during transfer. + * @param resource $body Body fopen response. + * + * @return array + */ + public static function createResponse( + callable $handler, + array $request, + array $response, + array $headers, + $body + ) { + if (isset($response['transfer_stats']['url'])) { + $response['effective_url'] = $response['transfer_stats']['url']; + } + + if (!empty($headers)) { + $startLine = explode(' ', array_shift($headers), 3); + $headerList = Core::headersFromLines($headers); + $response['headers'] = $headerList; + $response['version'] = isset($startLine[0]) ? substr($startLine[0], 5) : null; + $response['status'] = isset($startLine[1]) ? (int) $startLine[1] : null; + $response['reason'] = isset($startLine[2]) ? $startLine[2] : null; + $response['body'] = $body; + Core::rewindBody($response); + } + + return !empty($response['curl']['errno']) || !isset($response['status']) + ? self::createErrorResponse($handler, $request, $response) + : $response; + } + + private static function createErrorResponse( + callable $handler, + array $request, + array $response + ) { + static $connectionErrors = [ + CURLE_OPERATION_TIMEOUTED => true, + CURLE_COULDNT_RESOLVE_HOST => true, + CURLE_COULDNT_CONNECT => true, + CURLE_SSL_CONNECT_ERROR => true, + CURLE_GOT_NOTHING => true, + ]; + + // Retry when nothing is present or when curl failed to rewind. + if (!isset($response['err_message']) + && (empty($response['curl']['errno']) + || $response['curl']['errno'] == 65) + ) { + return self::retryFailedRewind($handler, $request, $response); + } + + $message = isset($response['err_message']) + ? $response['err_message'] + : sprintf('cURL error %s: %s', + $response['curl']['errno'], + isset($response['curl']['error']) + ? $response['curl']['error'] + : 'See http://curl.haxx.se/libcurl/c/libcurl-errors.html'); + + $error = isset($response['curl']['errno']) + && isset($connectionErrors[$response['curl']['errno']]) + ? new ConnectException($message) + : new RingException($message); + + return $response + [ + 'status' => null, + 'reason' => null, + 'body' => null, + 'headers' => [], + 'error' => $error, + ]; + } + + private function getOutputBody(array $request, array &$options) + { + // Determine where the body of the response (if any) will be streamed. + if (isset($options[CURLOPT_WRITEFUNCTION])) { + return $request['client']['save_to']; + } + + if (isset($options[CURLOPT_FILE])) { + return $options[CURLOPT_FILE]; + } + + if ($request['http_method'] != 'HEAD') { + // Create a default body if one was not provided + return $options[CURLOPT_FILE] = fopen('php://temp', 'w+'); + } + + return null; + } + + private function getDefaultOptions(array $request, array &$headers) + { + $url = Core::url($request); + $startingResponse = false; + + $options = [ + '_headers' => $request['headers'], + CURLOPT_CUSTOMREQUEST => $request['http_method'], + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => false, + CURLOPT_HEADER => false, + CURLOPT_CONNECTTIMEOUT => 150, + CURLOPT_HEADERFUNCTION => function ($ch, $h) use (&$headers, &$startingResponse) { + $value = trim($h); + if ($value === '') { + $startingResponse = true; + } elseif ($startingResponse) { + $startingResponse = false; + $headers = [$value]; + } else { + $headers[] = $value; + } + return strlen($h); + }, + ]; + + if (isset($request['version'])) { + if ($request['version'] == 2.0) { + $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; + } else if ($request['version'] == 1.1) { + $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; + } else { + $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; + } + } + + if (defined('CURLOPT_PROTOCOLS')) { + $options[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; + } + + return $options; + } + + private function applyMethod(array $request, array &$options) + { + if (isset($request['body'])) { + $this->applyBody($request, $options); + return; + } + + switch ($request['http_method']) { + case 'PUT': + case 'POST': + // See http://tools.ietf.org/html/rfc7230#section-3.3.2 + if (!Core::hasHeader($request, 'Content-Length')) { + $options[CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; + } + break; + case 'HEAD': + $options[CURLOPT_NOBODY] = true; + unset( + $options[CURLOPT_WRITEFUNCTION], + $options[CURLOPT_READFUNCTION], + $options[CURLOPT_FILE], + $options[CURLOPT_INFILE] + ); + } + } + + private function applyBody(array $request, array &$options) + { + $contentLength = Core::firstHeader($request, 'Content-Length'); + $size = $contentLength !== null ? (int) $contentLength : null; + + // Send the body as a string if the size is less than 1MB OR if the + // [client][curl][body_as_string] request value is set. + if (($size !== null && $size < 1000000) || + isset($request['client']['curl']['body_as_string']) || + is_string($request['body']) + ) { + $options[CURLOPT_POSTFIELDS] = Core::body($request); + // Don't duplicate the Content-Length header + $this->removeHeader('Content-Length', $options); + $this->removeHeader('Transfer-Encoding', $options); + } else { + $options[CURLOPT_UPLOAD] = true; + if ($size !== null) { + // Let cURL handle setting the Content-Length header + $options[CURLOPT_INFILESIZE] = $size; + $this->removeHeader('Content-Length', $options); + } + $this->addStreamingBody($request, $options); + } + + // If the Expect header is not present, prevent curl from adding it + if (!Core::hasHeader($request, 'Expect')) { + $options[CURLOPT_HTTPHEADER][] = 'Expect:'; + } + + // cURL sometimes adds a content-type by default. Prevent this. + if (!Core::hasHeader($request, 'Content-Type')) { + $options[CURLOPT_HTTPHEADER][] = 'Content-Type:'; + } + } + + private function addStreamingBody(array $request, array &$options) + { + $body = $request['body']; + + if ($body instanceof StreamInterface) { + $options[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) { + return (string) $body->read($length); + }; + if (!isset($options[CURLOPT_INFILESIZE])) { + if ($size = $body->getSize()) { + $options[CURLOPT_INFILESIZE] = $size; + } + } + } elseif (is_resource($body)) { + $options[CURLOPT_INFILE] = $body; + } elseif ($body instanceof \Iterator) { + $buf = ''; + $options[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body, &$buf) { + if ($body->valid()) { + $buf .= $body->current(); + $body->next(); + } + $result = (string) substr($buf, 0, $length); + $buf = substr($buf, $length); + return $result; + }; + } else { + throw new \InvalidArgumentException('Invalid request body provided'); + } + } + + private function applyHeaders(array $request, array &$options) + { + foreach ($options['_headers'] as $name => $values) { + foreach ($values as $value) { + $options[CURLOPT_HTTPHEADER][] = "$name: $value"; + } + } + + // Remove the Accept header if one was not set + if (!Core::hasHeader($request, 'Accept')) { + $options[CURLOPT_HTTPHEADER][] = 'Accept:'; + } + } + + /** + * Takes an array of curl options specified in the 'curl' option of a + * request's configuration array and maps them to CURLOPT_* options. + * + * This method is only called when a request has a 'curl' config setting. + * + * @param array $config Configuration array of custom curl option + * @param array $options Array of existing curl options + * + * @return array Returns a new array of curl options + */ + private function applyCustomCurlOptions(array $config, array $options) + { + $curlOptions = []; + foreach ($config as $key => $value) { + if (is_int($key)) { + $curlOptions[$key] = $value; + } + } + + return $curlOptions + $options; + } + + /** + * Remove a header from the options array. + * + * @param string $name Case-insensitive header to remove + * @param array $options Array of options to modify + */ + private function removeHeader($name, array &$options) + { + foreach (array_keys($options['_headers']) as $key) { + if (!strcasecmp($key, $name)) { + unset($options['_headers'][$key]); + return; + } + } + } + + /** + * Applies an array of request client options to a the options array. + * + * This method uses a large switch rather than double-dispatch to save on + * high overhead of calling functions in PHP. + */ + private function applyHandlerOptions(array $request, array &$options) + { + foreach ($request['client'] as $key => $value) { + switch ($key) { + // Violating PSR-4 to provide more room. + case 'verify': + + if ($value === false) { + unset($options[CURLOPT_CAINFO]); + $options[CURLOPT_SSL_VERIFYHOST] = 0; + $options[CURLOPT_SSL_VERIFYPEER] = false; + continue 2; + } + + $options[CURLOPT_SSL_VERIFYHOST] = 2; + $options[CURLOPT_SSL_VERIFYPEER] = true; + + if (is_string($value)) { + $options[CURLOPT_CAINFO] = $value; + if (!file_exists($value)) { + throw new \InvalidArgumentException( + "SSL CA bundle not found: $value" + ); + } + } + break; + + case 'decode_content': + + if ($value === false) { + continue 2; + } + + $accept = Core::firstHeader($request, 'Accept-Encoding'); + if ($accept) { + $options[CURLOPT_ENCODING] = $accept; + } else { + $options[CURLOPT_ENCODING] = ''; + // Don't let curl send the header over the wire + $options[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; + } + break; + + case 'save_to': + + if (is_string($value)) { + if (!is_dir(dirname($value))) { + throw new \RuntimeException(sprintf( + 'Directory %s does not exist for save_to value of %s', + dirname($value), + $value + )); + } + $value = new LazyOpenStream($value, 'w+'); + } + + if ($value instanceof StreamInterface) { + $options[CURLOPT_WRITEFUNCTION] = + function ($ch, $write) use ($value) { + return $value->write($write); + }; + } elseif (is_resource($value)) { + $options[CURLOPT_FILE] = $value; + } else { + throw new \InvalidArgumentException('save_to must be a ' + . 'GuzzleHttp\Stream\StreamInterface or resource'); + } + break; + + case 'timeout': + + if (defined('CURLOPT_TIMEOUT_MS')) { + $options[CURLOPT_TIMEOUT_MS] = $value * 1000; + } else { + $options[CURLOPT_TIMEOUT] = $value; + } + break; + + case 'connect_timeout': + + if (defined('CURLOPT_CONNECTTIMEOUT_MS')) { + $options[CURLOPT_CONNECTTIMEOUT_MS] = $value * 1000; + } else { + $options[CURLOPT_CONNECTTIMEOUT] = $value; + } + break; + + case 'proxy': + + if (!is_array($value)) { + $options[CURLOPT_PROXY] = $value; + } elseif (isset($request['scheme'])) { + $scheme = $request['scheme']; + if (isset($value[$scheme])) { + $options[CURLOPT_PROXY] = $value[$scheme]; + } + } + break; + + case 'cert': + + if (is_array($value)) { + $options[CURLOPT_SSLCERTPASSWD] = $value[1]; + $value = $value[0]; + } + + if (!file_exists($value)) { + throw new \InvalidArgumentException( + "SSL certificate not found: {$value}" + ); + } + + $options[CURLOPT_SSLCERT] = $value; + break; + + case 'ssl_key': + + if (is_array($value)) { + $options[CURLOPT_SSLKEYPASSWD] = $value[1]; + $value = $value[0]; + } + + if (!file_exists($value)) { + throw new \InvalidArgumentException( + "SSL private key not found: {$value}" + ); + } + + $options[CURLOPT_SSLKEY] = $value; + break; + + case 'progress': + + if (!is_callable($value)) { + throw new \InvalidArgumentException( + 'progress client option must be callable' + ); + } + + $options[CURLOPT_NOPROGRESS] = false; + $options[CURLOPT_PROGRESSFUNCTION] = + function () use ($value) { + $args = func_get_args(); + // PHP 5.5 pushed the handle onto the start of the args + if (is_resource($args[0])) { + array_shift($args); + } + call_user_func_array($value, $args); + }; + break; + + case 'debug': + + if ($value) { + $options[CURLOPT_STDERR] = Core::getDebugResource($value); + $options[CURLOPT_VERBOSE] = true; + } + break; + } + } + } + + /** + * This function ensures that a response was set on a transaction. If one + * was not set, then the request is retried if possible. This error + * typically means you are sending a payload, curl encountered a + * "Connection died, retrying a fresh connect" error, tried to rewind the + * stream, and then encountered a "necessary data rewind wasn't possible" + * error, causing the request to be sent through curl_multi_info_read() + * without an error status. + */ + private static function retryFailedRewind( + callable $handler, + array $request, + array $response + ) { + // If there is no body, then there is some other kind of issue. This + // is weird and should probably never happen. + if (!isset($request['body'])) { + $response['err_message'] = 'No response was received for a request ' + . 'with no body. This could mean that you are saturating your ' + . 'network.'; + return self::createErrorResponse($handler, $request, $response); + } + + if (!Core::rewindBody($request)) { + $response['err_message'] = 'The connection unexpectedly failed ' + . 'without providing an error. The request would have been ' + . 'retried, but attempting to rewind the request body failed.'; + return self::createErrorResponse($handler, $request, $response); + } + + // Retry no more than 3 times before giving up. + if (!isset($request['curl']['retries'])) { + $request['curl']['retries'] = 1; + } elseif ($request['curl']['retries'] == 2) { + $response['err_message'] = 'The cURL request was retried 3 times ' + . 'and did no succeed. cURL was unable to rewind the body of ' + . 'the request and subsequent retries resulted in the same ' + . 'error. Turn on the debug option to see what went wrong. ' + . 'See https://bugs.php.net/bug.php?id=47204 for more information.'; + return self::createErrorResponse($handler, $request, $response); + } else { + $request['curl']['retries']++; + } + + return $handler($request); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/CurlHandler.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/CurlHandler.php new file mode 100644 index 00000000..e00aa4ea --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/CurlHandler.php @@ -0,0 +1,135 @@ +handles = $this->ownedHandles = []; + $this->factory = isset($options['handle_factory']) + ? $options['handle_factory'] + : new CurlFactory(); + $this->maxHandles = isset($options['max_handles']) + ? $options['max_handles'] + : 5; + } + + public function __destruct() + { + foreach ($this->handles as $handle) { + if (is_resource($handle)) { + curl_close($handle); + } + } + } + + /** + * @param array $request + * + * @return CompletedFutureArray + */ + public function __invoke(array $request) + { + return new CompletedFutureArray( + $this->_invokeAsArray($request) + ); + } + + /** + * @internal + * + * @param array $request + * + * @return array + */ + public function _invokeAsArray(array $request) + { + $factory = $this->factory; + + // Ensure headers are by reference. They're updated elsewhere. + $result = $factory($request, $this->checkoutEasyHandle()); + $h = $result[0]; + $hd =& $result[1]; + $bd = $result[2]; + Core::doSleep($request); + curl_exec($h); + $response = ['transfer_stats' => curl_getinfo($h)]; + $response['curl']['error'] = curl_error($h); + $response['curl']['errno'] = curl_errno($h); + $response['transfer_stats'] = array_merge($response['transfer_stats'], $response['curl']); + $this->releaseEasyHandle($h); + + return CurlFactory::createResponse([$this, '_invokeAsArray'], $request, $response, $hd, $bd); + } + + private function checkoutEasyHandle() + { + // Find an unused handle in the cache + if (false !== ($key = array_search(false, $this->ownedHandles, true))) { + $this->ownedHandles[$key] = true; + return $this->handles[$key]; + } + + // Add a new handle + $handle = curl_init(); + $id = (int) $handle; + $this->handles[$id] = $handle; + $this->ownedHandles[$id] = true; + + return $handle; + } + + private function releaseEasyHandle($handle) + { + $id = (int) $handle; + if (count($this->ownedHandles) > $this->maxHandles) { + curl_close($this->handles[$id]); + unset($this->handles[$id], $this->ownedHandles[$id]); + } else { + // curl_reset doesn't clear these out for some reason + static $unsetValues = [ + CURLOPT_HEADERFUNCTION => null, + CURLOPT_WRITEFUNCTION => null, + CURLOPT_READFUNCTION => null, + CURLOPT_PROGRESSFUNCTION => null, + ]; + curl_setopt_array($handle, $unsetValues); + curl_reset($handle); + $this->ownedHandles[$id] = false; + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php new file mode 100644 index 00000000..f84cf199 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/CurlMultiHandler.php @@ -0,0 +1,248 @@ +_mh = $options['mh']; + } + $this->factory = isset($options['handle_factory']) + ? $options['handle_factory'] : new CurlFactory(); + $this->selectTimeout = isset($options['select_timeout']) + ? $options['select_timeout'] : 1; + $this->maxHandles = isset($options['max_handles']) + ? $options['max_handles'] : 100; + } + + public function __get($name) + { + if ($name === '_mh') { + return $this->_mh = curl_multi_init(); + } + + throw new \BadMethodCallException(); + } + + public function __destruct() + { + // Finish any open connections before terminating the script. + if ($this->handles) { + $this->execute(); + } + + if (isset($this->_mh)) { + curl_multi_close($this->_mh); + unset($this->_mh); + } + } + + public function __invoke(array $request) + { + $factory = $this->factory; + $result = $factory($request); + $entry = [ + 'request' => $request, + 'response' => [], + 'handle' => $result[0], + 'headers' => &$result[1], + 'body' => $result[2], + 'deferred' => new Deferred(), + ]; + + $id = (int) $result[0]; + + $future = new FutureArray( + $entry['deferred']->promise(), + [$this, 'execute'], + function () use ($id) { + return $this->cancel($id); + } + ); + + $this->addRequest($entry); + + // Transfer outstanding requests if there are too many open handles. + if (count($this->handles) >= $this->maxHandles) { + $this->execute(); + } + + return $future; + } + + /** + * Runs until all outstanding connections have completed. + */ + public function execute() + { + do { + + if ($this->active && + curl_multi_select($this->_mh, $this->selectTimeout) === -1 + ) { + // Perform a usleep if a select returns -1. + // See: https://bugs.php.net/bug.php?id=61141 + usleep(250); + } + + // Add any delayed futures if needed. + if ($this->delays) { + $this->addDelays(); + } + + do { + $mrc = curl_multi_exec($this->_mh, $this->active); + } while ($mrc === CURLM_CALL_MULTI_PERFORM); + + $this->processMessages(); + + // If there are delays but no transfers, then sleep for a bit. + if (!$this->active && $this->delays) { + usleep(500); + } + + } while ($this->active || $this->handles); + } + + private function addRequest(array &$entry) + { + $id = (int) $entry['handle']; + $this->handles[$id] = $entry; + + // If the request is a delay, then add the reques to the curl multi + // pool only after the specified delay. + if (isset($entry['request']['client']['delay'])) { + $this->delays[$id] = microtime(true) + ($entry['request']['client']['delay'] / 1000); + } elseif (empty($entry['request']['future'])) { + curl_multi_add_handle($this->_mh, $entry['handle']); + } else { + curl_multi_add_handle($this->_mh, $entry['handle']); + // "lazy" futures are only sent once the pool has many requests. + if ($entry['request']['future'] !== 'lazy') { + do { + $mrc = curl_multi_exec($this->_mh, $this->active); + } while ($mrc === CURLM_CALL_MULTI_PERFORM); + $this->processMessages(); + } + } + } + + private function removeProcessed($id) + { + if (isset($this->handles[$id])) { + curl_multi_remove_handle( + $this->_mh, + $this->handles[$id]['handle'] + ); + curl_close($this->handles[$id]['handle']); + unset($this->handles[$id], $this->delays[$id]); + } + } + + /** + * Cancels a handle from sending and removes references to it. + * + * @param int $id Handle ID to cancel and remove. + * + * @return bool True on success, false on failure. + */ + private function cancel($id) + { + // Cannot cancel if it has been processed. + if (!isset($this->handles[$id])) { + return false; + } + + $handle = $this->handles[$id]['handle']; + unset($this->delays[$id], $this->handles[$id]); + curl_multi_remove_handle($this->_mh, $handle); + curl_close($handle); + + return true; + } + + private function addDelays() + { + $currentTime = microtime(true); + + foreach ($this->delays as $id => $delay) { + if ($currentTime >= $delay) { + unset($this->delays[$id]); + curl_multi_add_handle( + $this->_mh, + $this->handles[$id]['handle'] + ); + } + } + } + + private function processMessages() + { + while ($done = curl_multi_info_read($this->_mh)) { + $id = (int) $done['handle']; + + if (!isset($this->handles[$id])) { + // Probably was cancelled. + continue; + } + + $entry = $this->handles[$id]; + $entry['response']['transfer_stats'] = curl_getinfo($done['handle']); + + if ($done['result'] !== CURLM_OK) { + $entry['response']['curl']['errno'] = $done['result']; + $entry['response']['curl']['error'] = curl_error($done['handle']); + } + + $result = CurlFactory::createResponse( + $this, + $entry['request'], + $entry['response'], + $entry['headers'], + $entry['body'] + ); + + $this->removeProcessed($id); + $entry['deferred']->resolve($result); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/Middleware.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/Middleware.php new file mode 100644 index 00000000..6fa7318a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/Middleware.php @@ -0,0 +1,58 @@ +result = $result; + } + + public function __invoke(array $request) + { + Core::doSleep($request); + $response = is_callable($this->result) + ? call_user_func($this->result, $request) + : $this->result; + + if (is_array($response)) { + $response = new CompletedFutureArray($response + [ + 'status' => null, + 'body' => null, + 'headers' => [], + 'reason' => null, + 'effective_url' => null, + ]); + } elseif (!$response instanceof FutureArrayInterface) { + throw new \InvalidArgumentException( + 'Response must be an array or FutureArrayInterface. Found ' + . Core::describeType($request) + ); + } + + return $response; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/StreamHandler.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/StreamHandler.php new file mode 100644 index 00000000..4bacec13 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Client/StreamHandler.php @@ -0,0 +1,414 @@ +options = $options; + } + + public function __invoke(array $request) + { + $url = Core::url($request); + Core::doSleep($request); + + try { + // Does not support the expect header. + $request = Core::removeHeader($request, 'Expect'); + $stream = $this->createStream($url, $request); + return $this->createResponse($request, $url, $stream); + } catch (RingException $e) { + return $this->createErrorResponse($url, $e); + } + } + + private function createResponse(array $request, $url, $stream) + { + $hdrs = $this->lastHeaders; + $this->lastHeaders = null; + $parts = explode(' ', array_shift($hdrs), 3); + $response = [ + 'version' => substr($parts[0], 5), + 'status' => $parts[1], + 'reason' => isset($parts[2]) ? $parts[2] : null, + 'headers' => Core::headersFromLines($hdrs), + 'effective_url' => $url, + ]; + + $stream = $this->checkDecode($request, $response, $stream); + + // If not streaming, then drain the response into a stream. + if (empty($request['client']['stream'])) { + $dest = isset($request['client']['save_to']) + ? $request['client']['save_to'] + : fopen('php://temp', 'r+'); + $stream = $this->drain($stream, $dest); + } + + $response['body'] = $stream; + + return new CompletedFutureArray($response); + } + + private function checkDecode(array $request, array $response, $stream) + { + // Automatically decode responses when instructed. + if (!empty($request['client']['decode_content'])) { + switch (Core::firstHeader($response, 'Content-Encoding', true)) { + case 'gzip': + case 'deflate': + $stream = new InflateStream(Stream::factory($stream)); + break; + } + } + + return $stream; + } + + /** + * Drains the stream into the "save_to" client option. + * + * @param resource $stream + * @param string|resource|StreamInterface $dest + * + * @return Stream + * @throws \RuntimeException when the save_to option is invalid. + */ + private function drain($stream, $dest) + { + if (is_resource($stream)) { + if (!is_resource($dest)) { + $stream = Stream::factory($stream); + } else { + stream_copy_to_stream($stream, $dest); + fclose($stream); + rewind($dest); + return $dest; + } + } + + // Stream the response into the destination stream + $dest = is_string($dest) + ? new Stream(Utils::open($dest, 'r+')) + : Stream::factory($dest); + + Utils::copyToStream($stream, $dest); + $dest->seek(0); + $stream->close(); + + return $dest; + } + + /** + * Creates an error response for the given stream. + * + * @param string $url + * @param RingException $e + * + * @return array + */ + private function createErrorResponse($url, RingException $e) + { + // Determine if the error was a networking error. + $message = $e->getMessage(); + + // This list can probably get more comprehensive. + if (strpos($message, 'getaddrinfo') // DNS lookup failed + || strpos($message, 'Connection refused') + ) { + $e = new ConnectException($e->getMessage(), 0, $e); + } + + return new CompletedFutureArray([ + 'status' => null, + 'body' => null, + 'headers' => [], + 'effective_url' => $url, + 'error' => $e + ]); + } + + /** + * Create a resource and check to ensure it was created successfully + * + * @param callable $callback Callable that returns stream resource + * + * @return resource + * @throws \RuntimeException on error + */ + private function createResource(callable $callback) + { + $errors = null; + set_error_handler(function ($_, $msg, $file, $line) use (&$errors) { + $errors[] = [ + 'message' => $msg, + 'file' => $file, + 'line' => $line + ]; + return true; + }); + + $resource = $callback(); + restore_error_handler(); + + if (!$resource) { + $message = 'Error creating resource: '; + foreach ($errors as $err) { + foreach ($err as $key => $value) { + $message .= "[$key] $value" . PHP_EOL; + } + } + throw new RingException(trim($message)); + } + + return $resource; + } + + private function createStream($url, array $request) + { + static $methods; + if (!$methods) { + $methods = array_flip(get_class_methods(__CLASS__)); + } + + // HTTP/1.1 streams using the PHP stream wrapper require a + // Connection: close header + if ((!isset($request['version']) || $request['version'] == '1.1') + && !Core::hasHeader($request, 'Connection') + ) { + $request['headers']['Connection'] = ['close']; + } + + // Ensure SSL is verified by default + if (!isset($request['client']['verify'])) { + $request['client']['verify'] = true; + } + + $params = []; + $options = $this->getDefaultOptions($request); + + if (isset($request['client'])) { + foreach ($request['client'] as $key => $value) { + $method = "add_{$key}"; + if (isset($methods[$method])) { + $this->{$method}($request, $options, $value, $params); + } + } + } + + return $this->createStreamResource( + $url, + $request, + $options, + $this->createContext($request, $options, $params) + ); + } + + private function getDefaultOptions(array $request) + { + $headers = ""; + foreach ($request['headers'] as $name => $value) { + foreach ((array) $value as $val) { + $headers .= "$name: $val\r\n"; + } + } + + $context = [ + 'http' => [ + 'method' => $request['http_method'], + 'header' => $headers, + 'protocol_version' => isset($request['version']) ? $request['version'] : 1.1, + 'ignore_errors' => true, + 'follow_location' => 0, + ], + ]; + + $body = Core::body($request); + if (isset($body)) { + $context['http']['content'] = $body; + // Prevent the HTTP handler from adding a Content-Type header. + if (!Core::hasHeader($request, 'Content-Type')) { + $context['http']['header'] .= "Content-Type:\r\n"; + } + } + + $context['http']['header'] = rtrim($context['http']['header']); + + return $context; + } + + private function add_proxy(array $request, &$options, $value, &$params) + { + if (!is_array($value)) { + $options['http']['proxy'] = $value; + } else { + $scheme = isset($request['scheme']) ? $request['scheme'] : 'http'; + if (isset($value[$scheme])) { + $options['http']['proxy'] = $value[$scheme]; + } + } + } + + private function add_timeout(array $request, &$options, $value, &$params) + { + $options['http']['timeout'] = $value; + } + + private function add_verify(array $request, &$options, $value, &$params) + { + if ($value === true) { + // PHP 5.6 or greater will find the system cert by default. When + // < 5.6, use the Guzzle bundled cacert. + if (PHP_VERSION_ID < 50600) { + $options['ssl']['cafile'] = ClientUtils::getDefaultCaBundle(); + } + } elseif (is_string($value)) { + $options['ssl']['cafile'] = $value; + if (!file_exists($value)) { + throw new RingException("SSL CA bundle not found: $value"); + } + } elseif ($value === false) { + $options['ssl']['verify_peer'] = false; + $options['ssl']['allow_self_signed'] = true; + return; + } else { + throw new RingException('Invalid verify request option'); + } + + $options['ssl']['verify_peer'] = true; + $options['ssl']['allow_self_signed'] = false; + } + + private function add_cert(array $request, &$options, $value, &$params) + { + if (is_array($value)) { + $options['ssl']['passphrase'] = $value[1]; + $value = $value[0]; + } + + if (!file_exists($value)) { + throw new RingException("SSL certificate not found: {$value}"); + } + + $options['ssl']['local_cert'] = $value; + } + + private function add_progress(array $request, &$options, $value, &$params) + { + $fn = function ($code, $_1, $_2, $_3, $transferred, $total) use ($value) { + if ($code == STREAM_NOTIFY_PROGRESS) { + $value($total, $transferred, null, null); + } + }; + + // Wrap the existing function if needed. + $params['notification'] = isset($params['notification']) + ? Core::callArray([$params['notification'], $fn]) + : $fn; + } + + private function add_debug(array $request, &$options, $value, &$params) + { + if ($value === false) { + return; + } + + static $map = [ + STREAM_NOTIFY_CONNECT => 'CONNECT', + STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', + STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', + STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', + STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', + STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', + STREAM_NOTIFY_PROGRESS => 'PROGRESS', + STREAM_NOTIFY_FAILURE => 'FAILURE', + STREAM_NOTIFY_COMPLETED => 'COMPLETED', + STREAM_NOTIFY_RESOLVE => 'RESOLVE', + ]; + + static $args = ['severity', 'message', 'message_code', + 'bytes_transferred', 'bytes_max']; + + $value = Core::getDebugResource($value); + $ident = $request['http_method'] . ' ' . Core::url($request); + $fn = function () use ($ident, $value, $map, $args) { + $passed = func_get_args(); + $code = array_shift($passed); + fprintf($value, '<%s> [%s] ', $ident, $map[$code]); + foreach (array_filter($passed) as $i => $v) { + fwrite($value, $args[$i] . ': "' . $v . '" '); + } + fwrite($value, "\n"); + }; + + // Wrap the existing function if needed. + $params['notification'] = isset($params['notification']) + ? Core::callArray([$params['notification'], $fn]) + : $fn; + } + + private function applyCustomOptions(array $request, array &$options) + { + if (!isset($request['client']['stream_context'])) { + return; + } + + if (!is_array($request['client']['stream_context'])) { + throw new RingException('stream_context must be an array'); + } + + $options = array_replace_recursive( + $options, + $request['client']['stream_context'] + ); + } + + private function createContext(array $request, array $options, array $params) + { + $this->applyCustomOptions($request, $options); + return $this->createResource( + function () use ($request, $options, $params) { + return stream_context_create($options, $params); + }, + $request, + $options + ); + } + + private function createStreamResource( + $url, + array $request, + array $options, + $context + ) { + return $this->createResource( + function () use ($url, $context) { + if (false === strpos($url, 'http')) { + trigger_error("URL is invalid: {$url}", E_USER_WARNING); + return null; + } + $resource = fopen($url, 'r', null, $context); + $this->lastHeaders = $http_response_header; + return $resource; + }, + $request, + $options + ); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Core.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Core.php new file mode 100644 index 00000000..dd7d1a0c --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Core.php @@ -0,0 +1,364 @@ + $value) { + if (!strcasecmp($name, $header)) { + $result = array_merge($result, $value); + } + } + } + + return $result; + } + + /** + * Gets a header value from a message as a string or null + * + * This method searches through the "headers" key of a message for a header + * using a case-insensitive search. The lines of the header are imploded + * using commas into a single string return value. + * + * @param array $message Request or response hash. + * @param string $header Header to retrieve + * + * @return string|null Returns the header string if found, or null if not. + */ + public static function header($message, $header) + { + $match = self::headerLines($message, $header); + return $match ? implode(', ', $match) : null; + } + + /** + * Returns the first header value from a message as a string or null. If + * a header line contains multiple values separated by a comma, then this + * function will return the first value in the list. + * + * @param array $message Request or response hash. + * @param string $header Header to retrieve + * + * @return string|null Returns the value as a string if found. + */ + public static function firstHeader($message, $header) + { + if (!empty($message['headers'])) { + foreach ($message['headers'] as $name => $value) { + if (!strcasecmp($name, $header)) { + // Return the match itself if it is a single value. + $pos = strpos($value[0], ','); + return $pos ? substr($value[0], 0, $pos) : $value[0]; + } + } + } + + return null; + } + + /** + * Returns true if a message has the provided case-insensitive header. + * + * @param array $message Request or response hash. + * @param string $header Header to check + * + * @return bool + */ + public static function hasHeader($message, $header) + { + if (!empty($message['headers'])) { + foreach ($message['headers'] as $name => $value) { + if (!strcasecmp($name, $header)) { + return true; + } + } + } + + return false; + } + + /** + * Parses an array of header lines into an associative array of headers. + * + * @param array $lines Header lines array of strings in the following + * format: "Name: Value" + * @return array + */ + public static function headersFromLines($lines) + { + $headers = []; + + foreach ($lines as $line) { + $parts = explode(':', $line, 2); + $headers[trim($parts[0])][] = isset($parts[1]) + ? trim($parts[1]) + : null; + } + + return $headers; + } + + /** + * Removes a header from a message using a case-insensitive comparison. + * + * @param array $message Message that contains 'headers' + * @param string $header Header to remove + * + * @return array + */ + public static function removeHeader(array $message, $header) + { + if (isset($message['headers'])) { + foreach (array_keys($message['headers']) as $key) { + if (!strcasecmp($header, $key)) { + unset($message['headers'][$key]); + } + } + } + + return $message; + } + + /** + * Replaces any existing case insensitive headers with the given value. + * + * @param array $message Message that contains 'headers' + * @param string $header Header to set. + * @param array $value Value to set. + * + * @return array + */ + public static function setHeader(array $message, $header, array $value) + { + $message = self::removeHeader($message, $header); + $message['headers'][$header] = $value; + + return $message; + } + + /** + * Creates a URL string from a request. + * + * If the "url" key is present on the request, it is returned, otherwise + * the url is built up based on the scheme, host, uri, and query_string + * request values. + * + * @param array $request Request to get the URL from + * + * @return string Returns the request URL as a string. + * @throws \InvalidArgumentException if no Host header is present. + */ + public static function url(array $request) + { + if (isset($request['url'])) { + return $request['url']; + } + + $uri = (isset($request['scheme']) + ? $request['scheme'] : 'http') . '://'; + + if ($host = self::header($request, 'host')) { + $uri .= $host; + } else { + throw new \InvalidArgumentException('No Host header was provided'); + } + + if (isset($request['uri'])) { + $uri .= $request['uri']; + } + + if (isset($request['query_string'])) { + $uri .= '?' . $request['query_string']; + } + + return $uri; + } + + /** + * Reads the body of a message into a string. + * + * @param array|FutureArrayInterface $message Array containing a "body" key + * + * @return null|string Returns the body as a string or null if not set. + * @throws \InvalidArgumentException if a request body is invalid. + */ + public static function body($message) + { + if (!isset($message['body'])) { + return null; + } + + if ($message['body'] instanceof StreamInterface) { + return (string) $message['body']; + } + + switch (gettype($message['body'])) { + case 'string': + return $message['body']; + case 'resource': + return stream_get_contents($message['body']); + case 'object': + if ($message['body'] instanceof \Iterator) { + return implode('', iterator_to_array($message['body'])); + } elseif (method_exists($message['body'], '__toString')) { + return (string) $message['body']; + } + default: + throw new \InvalidArgumentException('Invalid request body: ' + . self::describeType($message['body'])); + } + } + + /** + * Rewind the body of the provided message if possible. + * + * @param array $message Message that contains a 'body' field. + * + * @return bool Returns true on success, false on failure + */ + public static function rewindBody($message) + { + if ($message['body'] instanceof StreamInterface) { + return $message['body']->seek(0); + } + + if ($message['body'] instanceof \Generator) { + return false; + } + + if ($message['body'] instanceof \Iterator) { + $message['body']->rewind(); + return true; + } + + if (is_resource($message['body'])) { + return rewind($message['body']); + } + + return is_string($message['body']) + || (is_object($message['body']) + && method_exists($message['body'], '__toString')); + } + + /** + * Debug function used to describe the provided value type and class. + * + * @param mixed $input + * + * @return string Returns a string containing the type of the variable and + * if a class is provided, the class name. + */ + public static function describeType($input) + { + switch (gettype($input)) { + case 'object': + return 'object(' . get_class($input) . ')'; + case 'array': + return 'array(' . count($input) . ')'; + default: + ob_start(); + var_dump($input); + // normalize float vs double + return str_replace('double(', 'float(', rtrim(ob_get_clean())); + } + } + + /** + * Sleep for the specified amount of time specified in the request's + * ['client']['delay'] option if present. + * + * This function should only be used when a non-blocking sleep is not + * possible. + * + * @param array $request Request to sleep + */ + public static function doSleep(array $request) + { + if (isset($request['client']['delay'])) { + usleep($request['client']['delay'] * 1000); + } + } + + /** + * Returns a proxied future that modifies the dereferenced value of another + * future using a promise. + * + * @param FutureArrayInterface $future Future to wrap with a new future + * @param callable $onFulfilled Invoked when the future fulfilled + * @param callable $onRejected Invoked when the future rejected + * @param callable $onProgress Invoked when the future progresses + * + * @return FutureArray + */ + public static function proxy( + FutureArrayInterface $future, + callable $onFulfilled = null, + callable $onRejected = null, + callable $onProgress = null + ) { + return new FutureArray( + $future->then($onFulfilled, $onRejected, $onProgress), + [$future, 'wait'], + [$future, 'cancel'] + ); + } + + /** + * Returns a debug stream based on the provided variable. + * + * @param mixed $value Optional value + * + * @return resource + */ + public static function getDebugResource($value = null) + { + if (is_resource($value)) { + return $value; + } elseif (defined('STDOUT')) { + return STDOUT; + } else { + return fopen('php://output', 'w'); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Exception/CancelledException.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Exception/CancelledException.php new file mode 100644 index 00000000..95b353ac --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Exception/CancelledException.php @@ -0,0 +1,7 @@ +wrappedPromise = $promise; + $this->waitfn = $wait; + $this->cancelfn = $cancel; + } + + public function wait() + { + if (!$this->isRealized) { + $this->addShadow(); + if (!$this->isRealized && $this->waitfn) { + $this->invokeWait(); + } + if (!$this->isRealized) { + $this->error = new RingException('Waiting did not resolve future'); + } + } + + if ($this->error) { + throw $this->error; + } + + return $this->result; + } + + public function promise() + { + return $this->wrappedPromise; + } + + public function then( + callable $onFulfilled = null, + callable $onRejected = null, + callable $onProgress = null + ) { + return $this->wrappedPromise->then($onFulfilled, $onRejected, $onProgress); + } + + public function cancel() + { + if (!$this->isRealized) { + $cancelfn = $this->cancelfn; + $this->waitfn = $this->cancelfn = null; + $this->isRealized = true; + $this->error = new CancelledFutureAccessException(); + if ($cancelfn) { + $cancelfn($this); + } + } + } + + private function addShadow() + { + // Get the result and error when the promise is resolved. Note that + // calling this function might trigger the resolution immediately. + $this->wrappedPromise->then( + function ($value) { + $this->isRealized = true; + $this->result = $value; + $this->waitfn = $this->cancelfn = null; + }, + function ($error) { + $this->isRealized = true; + $this->error = $error; + $this->waitfn = $this->cancelfn = null; + } + ); + } + + private function invokeWait() + { + try { + $wait = $this->waitfn; + $this->waitfn = null; + $wait(); + } catch (\Exception $e) { + // Defer can throw to reject. + $this->error = $e; + $this->isRealized = true; + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php new file mode 100644 index 00000000..0a90c939 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureArray.php @@ -0,0 +1,43 @@ +result[$offset]); + } + + public function offsetGet($offset) + { + return $this->result[$offset]; + } + + public function offsetSet($offset, $value) + { + $this->result[$offset] = $value; + } + + public function offsetUnset($offset) + { + unset($this->result[$offset]); + } + + public function count() + { + return count($this->result); + } + + public function getIterator() + { + return new \ArrayIterator($this->result); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php new file mode 100644 index 00000000..0d25af72 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/CompletedFutureValue.php @@ -0,0 +1,57 @@ +result = $result; + $this->error = $e; + } + + public function wait() + { + if ($this->error) { + throw $this->error; + } + + return $this->result; + } + + public function cancel() {} + + public function promise() + { + if (!$this->cachedPromise) { + $this->cachedPromise = $this->error + ? new RejectedPromise($this->error) + : new FulfilledPromise($this->result); + } + + return $this->cachedPromise; + } + + public function then( + callable $onFulfilled = null, + callable $onRejected = null, + callable $onProgress = null + ) { + return $this->promise()->then($onFulfilled, $onRejected, $onProgress); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/FutureArray.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/FutureArray.php new file mode 100644 index 00000000..3d64c964 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/FutureArray.php @@ -0,0 +1,40 @@ +_value[$offset]); + } + + public function offsetGet($offset) + { + return $this->_value[$offset]; + } + + public function offsetSet($offset, $value) + { + $this->_value[$offset] = $value; + } + + public function offsetUnset($offset) + { + unset($this->_value[$offset]); + } + + public function count() + { + return count($this->_value); + } + + public function getIterator() + { + return new \ArrayIterator($this->_value); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php new file mode 100644 index 00000000..58f5f736 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/src/Future/FutureArrayInterface.php @@ -0,0 +1,11 @@ +_value = $this->wait(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlFactoryTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlFactoryTest.php new file mode 100644 index 00000000..ebde187c --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlFactoryTest.php @@ -0,0 +1,821 @@ + 200, + 'headers' => [ + 'Foo' => ['Bar'], + 'Baz' => ['bam'], + 'Content-Length' => [2], + ], + 'body' => 'hi', + ]]); + + $stream = Stream::factory(); + + $request = [ + 'http_method' => 'PUT', + 'headers' => [ + 'host' => [Server::$url], + 'Hi' => [' 123'], + ], + 'body' => 'testing', + 'client' => ['save_to' => $stream], + ]; + + $f = new CurlFactory(); + $result = $f($request); + $this->assertInternalType('array', $result); + $this->assertCount(3, $result); + $this->assertInternalType('resource', $result[0]); + $this->assertInternalType('array', $result[1]); + $this->assertSame($stream, $result[2]); + curl_close($result[0]); + + $this->assertEquals('PUT', $_SERVER['_curl'][CURLOPT_CUSTOMREQUEST]); + $this->assertEquals( + 'http://http://127.0.0.1:8125/', + $_SERVER['_curl'][CURLOPT_URL] + ); + // Sends via post fields when the request is small enough + $this->assertEquals('testing', $_SERVER['_curl'][CURLOPT_POSTFIELDS]); + $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_RETURNTRANSFER]); + $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_HEADER]); + $this->assertEquals(150, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT]); + $this->assertInstanceOf('Closure', $_SERVER['_curl'][CURLOPT_HEADERFUNCTION]); + + if (defined('CURLOPT_PROTOCOLS')) { + $this->assertEquals( + CURLPROTO_HTTP | CURLPROTO_HTTPS, + $_SERVER['_curl'][CURLOPT_PROTOCOLS] + ); + } + + $this->assertContains('Expect:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + $this->assertContains('Accept:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + $this->assertContains('Content-Type:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + $this->assertContains('Hi: 123', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + $this->assertContains('host: http://127.0.0.1:8125/', $_SERVER['_curl'][CURLOPT_HTTPHEADER]); + } + + public function testSendsHeadRequests() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'HEAD', + 'headers' => ['host' => [Server::$host]], + ]); + $response->wait(); + $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_NOBODY]); + $checks = [CURLOPT_WRITEFUNCTION, CURLOPT_READFUNCTION, CURLOPT_FILE, CURLOPT_INFILE]; + foreach ($checks as $check) { + $this->assertArrayNotHasKey($check, $_SERVER['_curl']); + } + $this->assertEquals('HEAD', Server::received()[0]['http_method']); + } + + public function testCanAddCustomCurlOptions() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]], + ]); + $this->assertEquals(10, $_SERVER['_curl'][CURLOPT_LOW_SPEED_LIMIT]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage SSL CA bundle not found: /does/not/exist + */ + public function testValidatesVerify() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['verify' => '/does/not/exist'], + ]); + } + + public function testCanSetVerifyToFile() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['verify' => __FILE__], + ]); + $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_CAINFO]); + $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + } + + public function testAddsVerifyAsTrue() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['verify' => true], + ]); + $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + $this->assertArrayNotHasKey(CURLOPT_CAINFO, $_SERVER['_curl']); + } + + public function testCanDisableVerify() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['verify' => false], + ]); + $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]); + $this->assertEquals(false, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]); + } + + public function testAddsProxy() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['proxy' => 'http://bar.com'], + ]); + $this->assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]); + } + + public function testAddsViaScheme() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'scheme' => 'http', + 'headers' => ['host' => ['foo.com']], + 'client' => [ + 'proxy' => ['http' => 'http://bar.com', 'https' => 'https://t'], + ], + ]); + $this->assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage SSL private key not found: /does/not/exist + */ + public function testValidatesSslKey() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['ssl_key' => '/does/not/exist'], + ]); + } + + public function testAddsSslKey() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['ssl_key' => __FILE__], + ]); + $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); + } + + public function testAddsSslKeyWithPassword() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['ssl_key' => [__FILE__, 'test']], + ]); + $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]); + $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLKEYPASSWD]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage SSL certificate not found: /does/not/exist + */ + public function testValidatesCert() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['cert' => '/does/not/exist'], + ]); + } + + public function testAddsCert() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['cert' => __FILE__], + ]); + $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]); + } + + public function testAddsCertWithPassword() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['cert' => [__FILE__, 'test']], + ]); + $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]); + $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLCERTPASSWD]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage progress client option must be callable + */ + public function testValidatesProgress() + { + $f = new CurlFactory(); + $f([ + 'http_method' => 'GET', + 'headers' => ['host' => ['foo.com']], + 'client' => ['progress' => 'foo'], + ]); + } + + public function testEmitsDebugInfoToStream() + { + $res = fopen('php://memory', 'r+'); + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'HEAD', + 'headers' => ['host' => [Server::$host]], + 'client' => ['debug' => $res], + ]); + $response->wait(); + rewind($res); + $output = str_replace("\r", '', stream_get_contents($res)); + $this->assertContains( + "> HEAD / HTTP/1.1\nhost: 127.0.0.1:8125\n\n", + $output + ); + $this->assertContains("< HTTP/1.1 200", $output); + fclose($res); + } + + public function testEmitsProgressToFunction() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $called = []; + $response = $a([ + 'http_method' => 'HEAD', + 'headers' => ['host' => [Server::$host]], + 'client' => [ + 'progress' => function () use (&$called) { + $called[] = func_get_args(); + }, + ], + ]); + $response->wait(); + $this->assertNotEmpty($called); + foreach ($called as $call) { + $this->assertCount(4, $call); + } + } + + private function addDecodeResponse($withEncoding = true) + { + $content = gzencode('test'); + $response = [ + 'status' => 200, + 'reason' => 'OK', + 'headers' => ['Content-Length' => [strlen($content)]], + 'body' => $content, + ]; + + if ($withEncoding) { + $response['headers']['Content-Encoding'] = ['gzip']; + } + + Server::flush(); + Server::enqueue([$response]); + + return $content; + } + + public function testDecodesGzippedResponses() + { + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['decode_content' => true], + ]); + $response->wait(); + $this->assertEquals('test', Core::body($response)); + $this->assertEquals('', $_SERVER['_curl'][CURLOPT_ENCODING]); + $sent = Server::received()[0]; + $this->assertNull(Core::header($sent, 'Accept-Encoding')); + } + + public function testDecodesGzippedResponsesWithHeader() + { + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => [ + 'host' => [Server::$host], + 'Accept-Encoding' => ['gzip'], + ], + 'client' => ['decode_content' => true], + ]); + $response->wait(); + $this->assertEquals('gzip', $_SERVER['_curl'][CURLOPT_ENCODING]); + $sent = Server::received()[0]; + $this->assertEquals('gzip', Core::header($sent, 'Accept-Encoding')); + $this->assertEquals('test', Core::body($response)); + } + + public function testDoesNotForceDecode() + { + $content = $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['decode_content' => false], + ]); + $response->wait(); + $sent = Server::received()[0]; + $this->assertNull(Core::header($sent, 'Accept-Encoding')); + $this->assertEquals($content, Core::body($response)); + } + + public function testProtocolVersion() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'version' => 1.0, + ]); + $this->assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testValidatesSaveTo() + { + $handler = new CurlMultiHandler(); + $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['save_to' => true], + ]); + } + + public function testSavesToStream() + { + $stream = fopen('php://memory', 'r+'); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => [ + 'decode_content' => true, + 'save_to' => $stream, + ], + ]); + $response->wait(); + rewind($stream); + $this->assertEquals('test', stream_get_contents($stream)); + } + + public function testSavesToGuzzleStream() + { + $stream = Stream::factory(); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => [ + 'decode_content' => true, + 'save_to' => $stream, + ], + ]); + $response->wait(); + $this->assertEquals('test', (string) $stream); + } + + public function testSavesToFileOnDisk() + { + $tmpfile = tempnam(sys_get_temp_dir(), 'testfile'); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => [ + 'decode_content' => true, + 'save_to' => $tmpfile, + ], + ]); + $response->wait(); + $this->assertEquals('test', file_get_contents($tmpfile)); + unlink($tmpfile); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testValidatesBody() + { + $handler = new CurlMultiHandler(); + $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'body' => false, + ]); + } + + public function testAddsLargePayloadFromStreamWithNoSizeUsingChunked() + { + $stream = Stream::factory('foo'); + $stream = FnStream::decorate($stream, [ + 'getSize' => function () { + return null; + } + ]); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'body' => $stream, + ]); + $response->wait(); + $sent = Server::received()[0]; + $this->assertEquals('chunked', Core::header($sent, 'Transfer-Encoding')); + $this->assertNull(Core::header($sent, 'Content-Length')); + $this->assertEquals('foo', $sent['body']); + } + + public function testAddsPayloadFromIterator() + { + $iter = new \ArrayIterator(['f', 'o', 'o']); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'body' => $iter, + ]); + $response->wait(); + $sent = Server::received()[0]; + $this->assertEquals('chunked', Core::header($sent, 'Transfer-Encoding')); + $this->assertNull(Core::header($sent, 'Content-Length')); + $this->assertEquals('foo', $sent['body']); + } + + public function testAddsPayloadFromResource() + { + $res = fopen('php://memory', 'r+'); + $data = str_repeat('.', 1000000); + fwrite($res, $data); + rewind($res); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => [ + 'host' => [Server::$host], + 'content-length' => [1000000], + ], + 'body' => $res, + ]); + $response->wait(); + $sent = Server::received()[0]; + $this->assertNull(Core::header($sent, 'Transfer-Encoding')); + $this->assertEquals(1000000, Core::header($sent, 'Content-Length')); + $this->assertEquals($data, $sent['body']); + } + + public function testAddsContentLengthFromStream() + { + $stream = Stream::factory('foo'); + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'body' => $stream, + ]); + $response->wait(); + $sent = Server::received()[0]; + $this->assertEquals(3, Core::header($sent, 'Content-Length')); + $this->assertNull(Core::header($sent, 'Transfer-Encoding')); + $this->assertEquals('foo', $sent['body']); + } + + public function testDoesNotAddMultipleContentLengthHeaders() + { + $this->addDecodeResponse(); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => [ + 'host' => [Server::$host], + 'content-length' => [3], + ], + 'body' => 'foo', + ]); + $response->wait(); + $sent = Server::received()[0]; + $this->assertEquals(3, Core::header($sent, 'Content-Length')); + $this->assertNull(Core::header($sent, 'Transfer-Encoding')); + $this->assertEquals('foo', $sent['body']); + } + + public function testSendsPostWithNoBodyOrDefaultContentType() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $handler = new CurlMultiHandler(); + $response = $handler([ + 'http_method' => 'POST', + 'uri' => '/', + 'headers' => ['host' => [Server::$host]], + ]); + $response->wait(); + $received = Server::received()[0]; + $this->assertEquals('POST', $received['http_method']); + $this->assertNull(Core::header($received, 'content-type')); + $this->assertSame('0', Core::firstHeader($received, 'content-length')); + } + + public function testParseProtocolVersion() + { + $res = CurlFactory::createResponse( + function () {}, + [], + ['curl' => ['errno' => null]], + ['HTTP/1.1 200 Ok'], + null + ); + + $this->assertSame('1.1', $res['version']); + } + + public function testFailsWhenNoResponseAndNoBody() + { + $res = CurlFactory::createResponse(function () {}, [], [], [], null); + $this->assertInstanceOf('GuzzleHttp\Ring\Exception\RingException', $res['error']); + $this->assertContains( + 'No response was received for a request with no body', + $res['error']->getMessage() + ); + } + + public function testFailsWhenCannotRewindRetry() + { + $res = CurlFactory::createResponse(function () {}, [ + 'body' => new NoSeekStream(Stream::factory('foo')) + ], [], [], null); + $this->assertInstanceOf('GuzzleHttp\Ring\Exception\RingException', $res['error']); + $this->assertContains( + 'rewind the request body failed', + $res['error']->getMessage() + ); + } + + public function testRetriesWhenBodyCanBeRewound() + { + $callHandler = $called = false; + $res = CurlFactory::createResponse(function () use (&$callHandler) { + $callHandler = true; + return ['status' => 200]; + }, [ + 'body' => FnStream::decorate(Stream::factory('test'), [ + 'seek' => function () use (&$called) { + $called = true; + return true; + } + ]) + ], [], [], null); + + $this->assertTrue($callHandler); + $this->assertTrue($called); + $this->assertEquals('200', $res['status']); + } + + public function testFailsWhenRetryMoreThanThreeTimes() + { + $call = 0; + $mock = new MockHandler(function (array $request) use (&$mock, &$call) { + $call++; + return CurlFactory::createResponse($mock, $request, [], [], null); + }); + $response = $mock([ + 'http_method' => 'GET', + 'body' => 'test', + ]); + $this->assertEquals(3, $call); + $this->assertArrayHasKey('error', $response); + $this->assertContains( + 'The cURL request was retried 3 times', + $response['error']->getMessage() + ); + } + + public function testHandles100Continue() + { + Server::flush(); + Server::enqueue([ + [ + 'status' => '200', + 'reason' => 'OK', + 'headers' => [ + 'Test' => ['Hello'], + 'Content-Length' => ['4'], + ], + 'body' => 'test', + ], + ]); + + $request = [ + 'http_method' => 'PUT', + 'headers' => [ + 'Host' => [Server::$host], + 'Expect' => ['100-Continue'], + ], + 'body' => 'test', + ]; + + $handler = new CurlMultiHandler(); + $response = $handler($request)->wait(); + $this->assertEquals(200, $response['status']); + $this->assertEquals('OK', $response['reason']); + $this->assertEquals(['Hello'], $response['headers']['Test']); + $this->assertEquals(['4'], $response['headers']['Content-Length']); + $this->assertEquals('test', Core::body($response)); + } + + public function testCreatesConnectException() + { + $m = new \ReflectionMethod('GuzzleHttp\Ring\Client\CurlFactory', 'createErrorResponse'); + $m->setAccessible(true); + $response = $m->invoke( + null, + function () {}, + [], + [ + 'err_message' => 'foo', + 'curl' => [ + 'errno' => CURLE_COULDNT_CONNECT, + ] + ] + ); + $this->assertInstanceOf('GuzzleHttp\Ring\Exception\ConnectException', $response['error']); + } + + public function testParsesLastResponseOnly() + { + $response1 = [ + 'status' => 301, + 'headers' => [ + 'Content-Length' => ['0'], + 'Location' => ['/foo'] + ] + ]; + + $response2 = [ + 'status' => 200, + 'headers' => [ + 'Content-Length' => ['0'], + 'Foo' => ['bar'] + ] + ]; + + Server::flush(); + Server::enqueue([$response1, $response2]); + + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['Host' => [Server::$host]], + 'client' => [ + 'curl' => [ + CURLOPT_FOLLOWLOCATION => true + ] + ] + ])->wait(); + + $this->assertEquals(1, $response['transfer_stats']['redirect_count']); + $this->assertEquals('http://127.0.0.1:8125/foo', $response['effective_url']); + $this->assertEquals(['bar'], $response['headers']['Foo']); + $this->assertEquals(200, $response['status']); + $this->assertFalse(Core::hasHeader($response, 'Location')); + } + + public function testMaintainsMultiHeaderOrder() + { + Server::flush(); + Server::enqueue([ + [ + 'status' => 200, + 'headers' => [ + 'Content-Length' => ['0'], + 'Foo' => ['a', 'b'], + 'foo' => ['c', 'd'], + ] + ] + ]); + + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['Host' => [Server::$host]] + ])->wait(); + + $this->assertEquals( + ['a', 'b', 'c', 'd'], + Core::headerLines($response, 'Foo') + ); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Directory /path/to/does/not does not exist for save_to value of /path/to/does/not/exist.txt + */ + public function testThrowsWhenDirNotFound() + { + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$url]], + 'client' => ['save_to' => '/path/to/does/not/exist.txt'], + ]; + + $f = new CurlFactory(); + $f($request); + } +} + +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlHandlerTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlHandlerTest.php new file mode 100644 index 00000000..ba03b8cd --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlHandlerTest.php @@ -0,0 +1,96 @@ +markTestSkipped('curl_reset() is not available'); + } + } + + protected function getHandler($factory = null, $options = []) + { + return new CurlHandler($options); + } + + public function testCanSetMaxHandles() + { + $a = new CurlHandler(['max_handles' => 10]); + $this->assertEquals(10, $this->readAttribute($a, 'maxHandles')); + } + + public function testCreatesCurlErrors() + { + $handler = new CurlHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => ['localhost:123']], + 'client' => ['timeout' => 0.001, 'connect_timeout' => 0.001], + ]); + $this->assertNull($response['status']); + $this->assertNull($response['reason']); + $this->assertEquals([], $response['headers']); + $this->assertInstanceOf( + 'GuzzleHttp\Ring\Exception\RingException', + $response['error'] + ); + + $this->assertEquals( + 1, + preg_match('/^cURL error \d+: .*$/', $response['error']->getMessage()) + ); + } + + public function testReleasesAdditionalEasyHandles() + { + Server::flush(); + $response = [ + 'status' => 200, + 'headers' => ['Content-Length' => [4]], + 'body' => 'test', + ]; + + Server::enqueue([$response, $response, $response, $response]); + $a = new CurlHandler(['max_handles' => 2]); + + $fn = function () use (&$calls, $a, &$fn) { + if (++$calls < 4) { + $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['progress' => $fn], + ]); + } + }; + + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => [ + 'progress' => $fn, + ], + ]; + + $a($request); + $this->assertCount(2, $this->readAttribute($a, 'handles')); + } + + public function testReusesHandles() + { + Server::flush(); + $response = ['status' => 200]; + Server::enqueue([$response, $response]); + $a = new CurlHandler(); + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + ]; + $a($request); + $a($request); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlMultiHandlerTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlMultiHandlerTest.php new file mode 100644 index 00000000..530b2394 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/CurlMultiHandlerTest.php @@ -0,0 +1,181 @@ + 200]]); + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + ]); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $this->assertEquals(200, $response['status']); + $this->assertArrayHasKey('transfer_stats', $response); + $realUrl = trim($response['transfer_stats']['url'], '/'); + $this->assertEquals(trim(Server::$url, '/'), $realUrl); + $this->assertArrayHasKey('effective_url', $response); + $this->assertEquals( + trim(Server::$url, '/'), + trim($response['effective_url'], '/') + ); + } + + public function testCreatesErrorResponses() + { + $url = 'http://localhost:123/'; + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['host' => ['localhost:123']], + ]); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $this->assertNull($response['status']); + $this->assertNull($response['reason']); + $this->assertEquals([], $response['headers']); + $this->assertArrayHasKey('error', $response); + $this->assertContains('cURL error ', $response['error']->getMessage()); + $this->assertArrayHasKey('transfer_stats', $response); + $this->assertEquals( + trim($url, '/'), + trim($response['transfer_stats']['url'], '/') + ); + $this->assertArrayHasKey('effective_url', $response); + $this->assertEquals( + trim($url, '/'), + trim($response['effective_url'], '/') + ); + } + + public function testSendsFuturesWhenDestructed() + { + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + ]); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $a->__destruct(); + $this->assertEquals(200, $response['status']); + } + + public function testCanSetMaxHandles() + { + $a = new CurlMultiHandler(['max_handles' => 2]); + $this->assertEquals(2, $this->readAttribute($a, 'maxHandles')); + } + + public function testCanSetSelectTimeout() + { + $a = new CurlMultiHandler(['select_timeout' => 2]); + $this->assertEquals(2, $this->readAttribute($a, 'selectTimeout')); + } + + public function testSendsFuturesWhenMaxHandlesIsReached() + { + $request = [ + 'http_method' => 'PUT', + 'headers' => ['host' => [Server::$host]], + 'future' => 'lazy', // passing this to control the test + ]; + $response = ['status' => 200]; + Server::flush(); + Server::enqueue([$response, $response, $response]); + $a = new CurlMultiHandler(['max_handles' => 3]); + for ($i = 0; $i < 5; $i++) { + $responses[] = $a($request); + } + $this->assertCount(3, Server::received()); + $responses[3]->cancel(); + $responses[4]->cancel(); + } + + public function testCanCancel() + { + Server::flush(); + $response = ['status' => 200]; + Server::enqueue(array_fill_keys(range(0, 10), $response)); + $a = new CurlMultiHandler(); + $responses = []; + + for ($i = 0; $i < 10; $i++) { + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'future' => 'lazy', + ]); + $response->cancel(); + $responses[] = $response; + } + + $this->assertCount(0, Server::received()); + + foreach ($responses as $response) { + $this->assertTrue($this->readAttribute($response, 'isRealized')); + } + } + + public function testCannotCancelFinished() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + ]); + $response->wait(); + $response->cancel(); + } + + public function testDelaysInParallel() + { + Server::flush(); + Server::enqueue([['status' => 200]]); + $a = new CurlMultiHandler(); + $expected = microtime(true) + (100 / 1000); + $response = $a([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'client' => ['delay' => 100], + ]); + $response->wait(); + $this->assertGreaterThanOrEqual($expected, microtime(true)); + } + + public function testSendsNonLazyFutures() + { + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'future' => true, + ]; + Server::flush(); + Server::enqueue([['status' => 202]]); + $a = new CurlMultiHandler(); + $response = $a($request); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $this->assertEquals(202, $response['status']); + } + + public function testExtractsErrors() + { + $request = [ + 'http_method' => 'GET', + 'headers' => ['host' => ['127.0.0.1:123']], + 'future' => true, + ]; + Server::flush(); + Server::enqueue([['status' => 202]]); + $a = new CurlMultiHandler(); + $response = $a($request); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $this->assertEquals(CURLE_COULDNT_CONNECT, $response['curl']['errno']); + $this->assertNotEmpty($response['curl']['error']); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/MiddlewareTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/MiddlewareTest.php new file mode 100644 index 00000000..a47bb30b --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/MiddlewareTest.php @@ -0,0 +1,65 @@ + 200]); + $calledA = false; + $a = function (array $req) use (&$calledA, $future) { + $calledA = true; + return $future; + }; + $calledB = false; + $b = function (array $req) use (&$calledB) { $calledB = true; }; + $s = Middleware::wrapFuture($a, $b); + $s([]); + $this->assertTrue($calledA); + $this->assertFalse($calledB); + } + + public function testFutureCallsStreamingHandler() + { + $future = new CompletedFutureArray(['status' => 200]); + $calledA = false; + $a = function (array $req) use (&$calledA) { $calledA = true; }; + $calledB = false; + $b = function (array $req) use (&$calledB, $future) { + $calledB = true; + return $future; + }; + $s = Middleware::wrapFuture($a, $b); + $result = $s(['client' => ['future' => true]]); + $this->assertFalse($calledA); + $this->assertTrue($calledB); + $this->assertSame($future, $result); + } + + public function testStreamingCallsDefaultHandler() + { + $calledA = false; + $a = function (array $req) use (&$calledA) { $calledA = true; }; + $calledB = false; + $b = function (array $req) use (&$calledB) { $calledB = true; }; + $s = Middleware::wrapStreaming($a, $b); + $s([]); + $this->assertTrue($calledA); + $this->assertFalse($calledB); + } + + public function testStreamingCallsStreamingHandler() + { + $calledA = false; + $a = function (array $req) use (&$calledA) { $calledA = true; }; + $calledB = false; + $b = function (array $req) use (&$calledB) { $calledB = true; }; + $s = Middleware::wrapStreaming($a, $b); + $s(['client' => ['stream' => true]]); + $this->assertFalse($calledA); + $this->assertTrue($calledB); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/MockHandlerTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/MockHandlerTest.php new file mode 100644 index 00000000..26bcd6cd --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/MockHandlerTest.php @@ -0,0 +1,86 @@ + 200]); + $response = $mock([]); + $this->assertEquals(200, $response['status']); + $this->assertEquals([], $response['headers']); + $this->assertNull($response['body']); + $this->assertNull($response['reason']); + $this->assertNull($response['effective_url']); + } + + public function testReturnsFutures() + { + $deferred = new Deferred(); + $future = new FutureArray( + $deferred->promise(), + function () use ($deferred) { + $deferred->resolve(['status' => 200]); + } + ); + $mock = new MockHandler($future); + $response = $mock([]); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $this->assertEquals(200, $response['status']); + } + + public function testReturnsFuturesWithThenCall() + { + $deferred = new Deferred(); + $future = new FutureArray( + $deferred->promise(), + function () use ($deferred) { + $deferred->resolve(['status' => 200]); + } + ); + $mock = new MockHandler($future); + $response = $mock([]); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $this->assertEquals(200, $response['status']); + $req = null; + $promise = $response->then(function ($value) use (&$req) { + $req = $value; + $this->assertEquals(200, $req['status']); + }); + $this->assertInstanceOf('React\Promise\PromiseInterface', $promise); + $this->assertEquals(200, $req['status']); + } + + public function testReturnsFuturesAndProxiesCancel() + { + $c = null; + $deferred = new Deferred(); + $future = new FutureArray( + $deferred->promise(), + function () {}, + function () use (&$c) { + $c = true; + return true; + } + ); + $mock = new MockHandler($future); + $response = $mock([]); + $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response); + $response->cancel(); + $this->assertTrue($c); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Response must be an array or FutureArrayInterface. Found + */ + public function testEnsuresMockIsValid() + { + $mock = new MockHandler('foo'); + $mock([]); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/Server.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/Server.php new file mode 100644 index 00000000..14665a55 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/Server.php @@ -0,0 +1,183 @@ + [], 'reason' => '', 'body' => '']; + $data[] = $response; + } + + self::send('PUT', '/guzzle-server/responses', json_encode($data)); + } + + /** + * Get all of the received requests as a RingPHP request structure. + * + * @return array + * @throws \RuntimeException + */ + public static function received() + { + if (!self::$started) { + return []; + } + + $response = self::send('GET', '/guzzle-server/requests'); + $body = Core::body($response); + $result = json_decode($body, true); + if ($result === false) { + throw new \RuntimeException('Error decoding response: ' + . json_last_error()); + } + + foreach ($result as &$res) { + if (isset($res['uri'])) { + $res['resource'] = $res['uri']; + } + if (isset($res['query_string'])) { + $res['resource'] .= '?' . $res['query_string']; + } + if (!isset($res['resource'])) { + $res['resource'] = ''; + } + // Ensure that headers are all arrays + if (isset($res['headers'])) { + foreach ($res['headers'] as &$h) { + $h = (array) $h; + } + unset($h); + } + } + + unset($res); + return $result; + } + + /** + * Stop running the node.js server + */ + public static function stop() + { + if (self::$started) { + self::send('DELETE', '/guzzle-server'); + } + + self::$started = false; + } + + public static function wait($maxTries = 20) + { + $tries = 0; + while (!self::isListening() && ++$tries < $maxTries) { + usleep(100000); + } + + if (!self::isListening()) { + throw new \RuntimeException('Unable to contact node.js server'); + } + } + + public static function start() + { + if (self::$started) { + return; + } + + try { + self::wait(); + } catch (\Exception $e) { + exec('node ' . __DIR__ . \DIRECTORY_SEPARATOR . 'server.js ' + . self::$port . ' >> /tmp/server.log 2>&1 &'); + self::wait(); + } + + self::$started = true; + } + + private static function isListening() + { + $response = self::send('GET', '/guzzle-server/perf', null, [ + 'connect_timeout' => 1, + 'timeout' => 1 + ]); + + return !isset($response['error']); + } + + private static function send( + $method, + $path, + $body = null, + array $client = [] + ) { + $handler = new StreamHandler(); + + $request = [ + 'http_method' => $method, + 'uri' => $path, + 'request_port' => 8125, + 'headers' => ['host' => ['127.0.0.1:8125']], + 'body' => $body, + 'client' => $client, + ]; + + if ($body) { + $request['headers']['content-length'] = [strlen($body)]; + } + + return $handler($request); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/StreamHandlerTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/StreamHandlerTest.php new file mode 100644 index 00000000..3cb9a8e1 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/StreamHandlerTest.php @@ -0,0 +1,480 @@ +queueRes(); + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => [ + 'host' => [Server::$host], + 'Foo' => ['Bar'], + ], + ]); + + $this->assertEquals('1.1', $response['version']); + $this->assertEquals(200, $response['status']); + $this->assertEquals('OK', $response['reason']); + $this->assertEquals(['Bar'], $response['headers']['Foo']); + $this->assertEquals(['8'], $response['headers']['Content-Length']); + $this->assertEquals('hi there', Core::body($response)); + + $sent = Server::received()[0]; + $this->assertEquals('GET', $sent['http_method']); + $this->assertEquals('/', $sent['resource']); + $this->assertEquals(['127.0.0.1:8125'], $sent['headers']['host']); + $this->assertEquals('Bar', Core::header($sent, 'foo')); + } + + public function testAddsErrorToResponse() + { + $handler = new StreamHandler(); + $result = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => ['localhost:123']], + 'client' => ['timeout' => 0.01], + ]); + $this->assertInstanceOf( + 'GuzzleHttp\Ring\Future\CompletedFutureArray', + $result + ); + $this->assertNull($result['status']); + $this->assertNull($result['body']); + $this->assertEquals([], $result['headers']); + $this->assertInstanceOf( + 'GuzzleHttp\Ring\Exception\RingException', + $result['error'] + ); + } + + public function testEnsuresTheHttpProtocol() + { + $handler = new StreamHandler(); + $result = $handler([ + 'http_method' => 'GET', + 'url' => 'ftp://localhost:123', + ]); + $this->assertArrayHasKey('error', $result); + $this->assertContains( + 'URL is invalid: ftp://localhost:123', + $result['error']->getMessage() + ); + } + + public function testStreamAttributeKeepsStreamOpen() + { + $this->queueRes(); + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'PUT', + 'uri' => '/foo', + 'query_string' => 'baz=bar', + 'headers' => [ + 'host' => [Server::$host], + 'Foo' => ['Bar'], + ], + 'body' => 'test', + 'client' => ['stream' => true], + ]); + + $this->assertEquals(200, $response['status']); + $this->assertEquals('OK', $response['reason']); + $this->assertEquals('8', Core::header($response, 'Content-Length')); + $body = $response['body']; + $this->assertTrue(is_resource($body)); + $this->assertEquals('http', stream_get_meta_data($body)['wrapper_type']); + $this->assertEquals('hi there', stream_get_contents($body)); + fclose($body); + $sent = Server::received()[0]; + $this->assertEquals('PUT', $sent['http_method']); + $this->assertEquals('/foo', $sent['uri']); + $this->assertEquals('baz=bar', $sent['query_string']); + $this->assertEquals('/foo?baz=bar', $sent['resource']); + $this->assertEquals('127.0.0.1:8125', Core::header($sent, 'host')); + $this->assertEquals('Bar', Core::header($sent, 'foo')); + } + + public function testDrainsResponseIntoTempStream() + { + $this->queueRes(); + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => [Server::$host]], + ]); + $body = $response['body']; + $this->assertEquals('php://temp', stream_get_meta_data($body)['uri']); + $this->assertEquals('hi', fread($body, 2)); + fclose($body); + } + + public function testDrainsResponseIntoSaveToBody() + { + $r = fopen('php://temp', 'r+'); + $this->queueRes(); + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => [Server::$host]], + 'client' => ['save_to' => $r], + ]); + $body = $response['body']; + $this->assertEquals('php://temp', stream_get_meta_data($body)['uri']); + $this->assertEquals('hi', fread($body, 2)); + $this->assertEquals(' there', stream_get_contents($r)); + fclose($r); + } + + public function testDrainsResponseIntoSaveToBodyAtPath() + { + $tmpfname = tempnam('/tmp', 'save_to_path'); + $this->queueRes(); + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => [Server::$host]], + 'client' => ['save_to' => $tmpfname], + ]); + $body = $response['body']; + $this->assertInstanceOf('GuzzleHttp\Stream\StreamInterface', $body); + $this->assertEquals($tmpfname, $body->getMetadata('uri')); + $this->assertEquals('hi', $body->read(2)); + $body->close(); + unlink($tmpfname); + } + + public function testAutomaticallyDecompressGzip() + { + Server::flush(); + $content = gzencode('test'); + Server::enqueue([ + [ + 'status' => 200, + 'reason' => 'OK', + 'headers' => [ + 'Content-Encoding' => ['gzip'], + 'Content-Length' => [strlen($content)], + ], + 'body' => $content, + ], + ]); + + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'uri' => '/', + 'client' => ['decode_content' => true], + ]); + $this->assertEquals('test', Core::body($response)); + } + + public function testDoesNotForceGzipDecode() + { + Server::flush(); + $content = gzencode('test'); + Server::enqueue([ + [ + 'status' => 200, + 'reason' => 'OK', + 'headers' => [ + 'Content-Encoding' => ['gzip'], + 'Content-Length' => [strlen($content)], + ], + 'body' => $content, + ], + ]); + + $handler = new StreamHandler(); + $response = $handler([ + 'http_method' => 'GET', + 'headers' => ['host' => [Server::$host]], + 'uri' => '/', + 'client' => ['stream' => true, 'decode_content' => false], + ]); + $this->assertSame($content, Core::body($response)); + } + + public function testProtocolVersion() + { + $this->queueRes(); + $handler = new StreamHandler(); + $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => [Server::$host]], + 'version' => 1.0, + ]); + + $this->assertEquals(1.0, Server::received()[0]['version']); + } + + protected function getSendResult(array $opts) + { + $this->queueRes(); + $handler = new StreamHandler(); + $opts['stream'] = true; + return $handler([ + 'http_method' => 'GET', + 'uri' => '/', + 'headers' => ['host' => [Server::$host]], + 'client' => $opts, + ]); + } + + public function testAddsProxy() + { + $res = $this->getSendResult(['stream' => true, 'proxy' => '127.0.0.1:8125']); + $opts = stream_context_get_options($res['body']); + $this->assertEquals('127.0.0.1:8125', $opts['http']['proxy']); + } + + public function testAddsTimeout() + { + $res = $this->getSendResult(['stream' => true, 'timeout' => 200]); + $opts = stream_context_get_options($res['body']); + $this->assertEquals(200, $opts['http']['timeout']); + } + + public function testVerifiesVerifyIsValidIfPath() + { + $res = $this->getSendResult(['verify' => '/does/not/exist']); + $this->assertContains( + 'SSL CA bundle not found: /does/not/exist', + (string) $res['error'] + ); + } + + public function testVerifyCanBeDisabled() + { + $res = $this->getSendResult(['verify' => false]); + $this->assertArrayNotHasKey('error', $res); + } + + public function testVerifiesCertIfValidPath() + { + $res = $this->getSendResult(['cert' => '/does/not/exist']); + $this->assertContains( + 'SSL certificate not found: /does/not/exist', + (string) $res['error'] + ); + } + + public function testVerifyCanBeSetToPath() + { + $path = $path = ClientUtils::getDefaultCaBundle(); + $res = $this->getSendResult(['verify' => $path]); + $this->assertArrayNotHasKey('error', $res); + $opts = stream_context_get_options($res['body']); + $this->assertEquals(true, $opts['ssl']['verify_peer']); + $this->assertEquals($path, $opts['ssl']['cafile']); + $this->assertTrue(file_exists($opts['ssl']['cafile'])); + } + + public function testUsesSystemDefaultBundle() + { + $path = $path = ClientUtils::getDefaultCaBundle(); + $res = $this->getSendResult(['verify' => true]); + $this->assertArrayNotHasKey('error', $res); + $opts = stream_context_get_options($res['body']); + if (PHP_VERSION_ID < 50600) { + $this->assertEquals($path, $opts['ssl']['cafile']); + } + } + + public function testEnsuresVerifyOptionIsValid() + { + $res = $this->getSendResult(['verify' => 10]); + $this->assertContains( + 'Invalid verify request option', + (string) $res['error'] + ); + } + + public function testCanSetPasswordWhenSettingCert() + { + $path = __FILE__; + $res = $this->getSendResult(['cert' => [$path, 'foo']]); + $opts = stream_context_get_options($res['body']); + $this->assertEquals($path, $opts['ssl']['local_cert']); + $this->assertEquals('foo', $opts['ssl']['passphrase']); + } + + public function testDebugAttributeWritesToStream() + { + $this->queueRes(); + $f = fopen('php://temp', 'w+'); + $this->getSendResult(['debug' => $f]); + fseek($f, 0); + $contents = stream_get_contents($f); + $this->assertContains(' [CONNECT]', $contents); + $this->assertContains(' [FILE_SIZE_IS]', $contents); + $this->assertContains(' [PROGRESS]', $contents); + } + + public function testDebugAttributeWritesStreamInfoToBuffer() + { + $called = false; + $this->queueRes(); + $buffer = fopen('php://temp', 'r+'); + $this->getSendResult([ + 'progress' => function () use (&$called) { $called = true; }, + 'debug' => $buffer, + ]); + fseek($buffer, 0); + $contents = stream_get_contents($buffer); + $this->assertContains(' [CONNECT]', $contents); + $this->assertContains(' [FILE_SIZE_IS] message: "Content-Length: 8"', $contents); + $this->assertContains(' [PROGRESS] bytes_max: "8"', $contents); + $this->assertTrue($called); + } + + public function testEmitsProgressInformation() + { + $called = []; + $this->queueRes(); + $this->getSendResult([ + 'progress' => function () use (&$called) { + $called[] = func_get_args(); + }, + ]); + $this->assertNotEmpty($called); + $this->assertEquals(8, $called[0][0]); + $this->assertEquals(0, $called[0][1]); + } + + public function testEmitsProgressInformationAndDebugInformation() + { + $called = []; + $this->queueRes(); + $buffer = fopen('php://memory', 'w+'); + $this->getSendResult([ + 'debug' => $buffer, + 'progress' => function () use (&$called) { + $called[] = func_get_args(); + }, + ]); + $this->assertNotEmpty($called); + $this->assertEquals(8, $called[0][0]); + $this->assertEquals(0, $called[0][1]); + rewind($buffer); + $this->assertNotEmpty(stream_get_contents($buffer)); + fclose($buffer); + } + + public function testAddsProxyByProtocol() + { + $url = str_replace('http', 'tcp', Server::$url); + $res = $this->getSendResult(['proxy' => ['http' => $url]]); + $opts = stream_context_get_options($res['body']); + $this->assertEquals($url, $opts['http']['proxy']); + } + + public function testPerformsShallowMergeOfCustomContextOptions() + { + $res = $this->getSendResult([ + 'stream_context' => [ + 'http' => [ + 'request_fulluri' => true, + 'method' => 'HEAD', + ], + 'socket' => [ + 'bindto' => '127.0.0.1:0', + ], + 'ssl' => [ + 'verify_peer' => false, + ], + ], + ]); + + $opts = stream_context_get_options($res['body']); + $this->assertEquals('HEAD', $opts['http']['method']); + $this->assertTrue($opts['http']['request_fulluri']); + $this->assertFalse($opts['ssl']['verify_peer']); + $this->assertEquals('127.0.0.1:0', $opts['socket']['bindto']); + } + + public function testEnsuresThatStreamContextIsAnArray() + { + $res = $this->getSendResult(['stream_context' => 'foo']); + $this->assertContains( + 'stream_context must be an array', + (string) $res['error'] + ); + } + + public function testDoesNotAddContentTypeByDefault() + { + $this->queueRes(); + $handler = new StreamHandler(); + $handler([ + 'http_method' => 'PUT', + 'uri' => '/', + 'headers' => ['host' => [Server::$host], 'content-length' => [3]], + 'body' => 'foo', + ]); + $req = Server::received()[0]; + $this->assertEquals('', Core::header($req, 'Content-Type')); + $this->assertEquals(3, Core::header($req, 'Content-Length')); + } + + private function queueRes() + { + Server::flush(); + Server::enqueue([ + [ + 'status' => 200, + 'reason' => 'OK', + 'headers' => [ + 'Foo' => ['Bar'], + 'Content-Length' => [8], + ], + 'body' => 'hi there', + ], + ]); + } + + public function testSupports100Continue() + { + Server::flush(); + Server::enqueue([ + [ + 'status' => '200', + 'reason' => 'OK', + 'headers' => [ + 'Test' => ['Hello'], + 'Content-Length' => ['4'], + ], + 'body' => 'test', + ], + ]); + + $request = [ + 'http_method' => 'PUT', + 'headers' => [ + 'Host' => [Server::$host], + 'Expect' => ['100-Continue'], + ], + 'body' => 'test', + ]; + + $handler = new StreamHandler(); + $response = $handler($request); + $this->assertEquals(200, $response['status']); + $this->assertEquals('OK', $response['reason']); + $this->assertEquals(['Hello'], $response['headers']['Test']); + $this->assertEquals(['4'], $response['headers']['Content-Length']); + $this->assertEquals('test', Core::body($response)); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/server.js b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/server.js new file mode 100644 index 00000000..6a03e33a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Client/server.js @@ -0,0 +1,241 @@ +/** + * Guzzle node.js test server to return queued responses to HTTP requests and + * expose a RESTful API for enqueueing responses and retrieving the requests + * that have been received. + * + * - Delete all requests that have been received: + * > DELETE /guzzle-server/requests + * > Host: 127.0.0.1:8125 + * + * - Enqueue responses + * > PUT /guzzle-server/responses + * > Host: 127.0.0.1:8125 + * > + * > [{'status': 200, 'reason': 'OK', 'headers': {}, 'body': '' }] + * + * - Get the received requests + * > GET /guzzle-server/requests + * > Host: 127.0.0.1:8125 + * + * < HTTP/1.1 200 OK + * < + * < [{'http_method': 'GET', 'uri': '/', 'headers': {}, 'body': 'string'}] + * + * - Attempt access to the secure area + * > GET /secure/by-digest/qop-auth/guzzle-server/requests + * > Host: 127.0.0.1:8125 + * + * < HTTP/1.1 401 Unauthorized + * < WWW-Authenticate: Digest realm="Digest Test", qop="auth", nonce="0796e98e1aeef43141fab2a66bf4521a", algorithm="MD5", stale="false" + * < + * < 401 Unauthorized + * + * - Shutdown the server + * > DELETE /guzzle-server + * > Host: 127.0.0.1:8125 + * + * @package Guzzle PHP + * @license See the LICENSE file that was distributed with this source code. + */ + +var http = require('http'); +var url = require('url'); + +/** + * Guzzle node.js server + * @class + */ +var GuzzleServer = function(port, log) { + + this.port = port; + this.log = log; + this.responses = []; + this.requests = []; + var that = this; + + var md5 = function(input) { + var crypto = require('crypto'); + var hasher = crypto.createHash('md5'); + hasher.update(input); + return hasher.digest('hex'); + } + + /** + * Node.js HTTP server authentication module. + * + * It is only initialized on demand (by loadAuthentifier). This avoids + * requiring the dependency to http-auth on standard operations, and the + * performance hit at startup. + */ + var auth; + + /** + * Provides authentication handlers (Basic, Digest). + */ + var loadAuthentifier = function(type, options) { + var typeId = type; + if (type == 'digest') { + typeId += '.'+(options && options.qop ? options.qop : 'none'); + } + if (!loadAuthentifier[typeId]) { + if (!auth) { + try { + auth = require('http-auth'); + } catch (e) { + if (e.code == 'MODULE_NOT_FOUND') { + return; + } + } + } + switch (type) { + case 'digest': + var digestParams = { + realm: 'Digest Test', + login: 'me', + password: 'test' + }; + if (options && options.qop) { + digestParams.qop = options.qop; + } + loadAuthentifier[typeId] = auth.digest(digestParams, function(username, callback) { + callback(md5(digestParams.login + ':' + digestParams.realm + ':' + digestParams.password)); + }); + break + } + } + return loadAuthentifier[typeId]; + }; + + var firewallRequest = function(request, req, res, requestHandlerCallback) { + var securedAreaUriParts = request.uri.match(/^\/secure\/by-(digest)(\/qop-([^\/]*))?(\/.*)$/); + if (securedAreaUriParts) { + var authentifier = loadAuthentifier(securedAreaUriParts[1], { qop: securedAreaUriParts[2] }); + if (!authentifier) { + res.writeHead(501, 'HTTP authentication not implemented', { 'Content-Length': 0 }); + res.end(); + return; + } + authentifier.check(req, res, function(req, res) { + req.url = securedAreaUriParts[4]; + requestHandlerCallback(request, req, res); + }); + } else { + requestHandlerCallback(request, req, res); + } + }; + + var controlRequest = function(request, req, res) { + if (req.url == '/guzzle-server/perf') { + res.writeHead(200, 'OK', {'Content-Length': 16}); + res.end('Body of response'); + } else if (req.method == 'DELETE') { + if (req.url == '/guzzle-server/requests') { + // Clear the received requests + that.requests = []; + res.writeHead(200, 'OK', { 'Content-Length': 0 }); + res.end(); + if (that.log) { + console.log('Flushing requests'); + } + } else if (req.url == '/guzzle-server') { + // Shutdown the server + res.writeHead(200, 'OK', { 'Content-Length': 0, 'Connection': 'close' }); + res.end(); + if (that.log) { + console.log('Shutting down'); + } + that.server.close(); + } + } else if (req.method == 'GET') { + if (req.url === '/guzzle-server/requests') { + if (that.log) { + console.log('Sending received requests'); + } + // Get received requests + var body = JSON.stringify(that.requests); + res.writeHead(200, 'OK', { 'Content-Length': body.length }); + res.end(body); + } + } else if (req.method == 'PUT' && req.url == '/guzzle-server/responses') { + if (that.log) { + console.log('Adding responses...'); + } + if (!request.body) { + if (that.log) { + console.log('No response data was provided'); + } + res.writeHead(400, 'NO RESPONSES IN REQUEST', { 'Content-Length': 0 }); + } else { + that.responses = eval('(' + request.body + ')'); + for (var i = 0; i < that.responses.length; i++) { + if (that.responses[i].body) { + that.responses[i].body = new Buffer(that.responses[i].body, 'base64'); + } + } + if (that.log) { + console.log(that.responses); + } + res.writeHead(200, 'OK', { 'Content-Length': 0 }); + } + res.end(); + } + }; + + var receivedRequest = function(request, req, res) { + if (req.url.indexOf('/guzzle-server') === 0) { + controlRequest(request, req, res); + } else if (req.url.indexOf('/guzzle-server') == -1 && !that.responses.length) { + res.writeHead(500); + res.end('No responses in queue'); + } else { + if (that.log) { + console.log('Returning response from queue and adding request'); + } + that.requests.push(request); + var response = that.responses.shift(); + res.writeHead(response.status, response.reason, response.headers); + res.end(response.body); + } + }; + + this.start = function() { + + that.server = http.createServer(function(req, res) { + + var parts = url.parse(req.url, false); + var request = { + http_method: req.method, + scheme: parts.scheme, + uri: parts.pathname, + query_string: parts.query, + headers: req.headers, + version: req.httpVersion, + body: '' + }; + + // Receive each chunk of the request body + req.addListener('data', function(chunk) { + request.body += chunk; + }); + + // Called when the request completes + req.addListener('end', function() { + firewallRequest(request, req, res, receivedRequest); + }); + }); + + that.server.listen(this.port, '127.0.0.1'); + + if (this.log) { + console.log('Server running at http://127.0.0.1:8125/'); + } + }; +}; + +// Get the port from the arguments +port = process.argv.length >= 3 ? process.argv[2] : 8125; +log = process.argv.length >= 4 ? process.argv[3] : false; + +// Start the server +server = new GuzzleServer(port, log); +server.start(); diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/CoreTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/CoreTest.php new file mode 100644 index 00000000..49522f26 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/CoreTest.php @@ -0,0 +1,336 @@ +assertNull(Core::header([], 'Foo')); + $this->assertNull(Core::firstHeader([], 'Foo')); + } + + public function testChecksIfHasHeader() + { + $message = [ + 'headers' => [ + 'Foo' => ['Bar', 'Baz'], + 'foo' => ['hello'], + 'bar' => ['1'] + ] + ]; + $this->assertTrue(Core::hasHeader($message, 'Foo')); + $this->assertTrue(Core::hasHeader($message, 'foo')); + $this->assertTrue(Core::hasHeader($message, 'FoO')); + $this->assertTrue(Core::hasHeader($message, 'bar')); + $this->assertFalse(Core::hasHeader($message, 'barr')); + } + + public function testReturnsFirstHeaderWhenSimple() + { + $this->assertEquals('Bar', Core::firstHeader([ + 'headers' => ['Foo' => ['Bar', 'Baz']], + ], 'Foo')); + } + + public function testReturnsFirstHeaderWhenMultiplePerLine() + { + $this->assertEquals('Bar', Core::firstHeader([ + 'headers' => ['Foo' => ['Bar, Baz']], + ], 'Foo')); + } + + public function testExtractsCaseInsensitiveHeader() + { + $this->assertEquals( + 'hello', + Core::header(['headers' => ['foo' => ['hello']]], 'FoO') + ); + } + + public function testExtractsCaseInsensitiveHeaderLines() + { + $this->assertEquals( + ['a', 'b', 'c', 'd'], + Core::headerLines([ + 'headers' => [ + 'foo' => ['a', 'b'], + 'Foo' => ['c', 'd'] + ] + ], 'foo') + ); + } + + public function testExtractsHeaderLines() + { + $this->assertEquals( + ['bar', 'baz'], + Core::headerLines([ + 'headers' => [ + 'Foo' => ['bar', 'baz'], + ], + ], 'Foo') + ); + } + + public function testExtractsHeaderAsString() + { + $this->assertEquals( + 'bar, baz', + Core::header([ + 'headers' => [ + 'Foo' => ['bar', 'baz'], + ], + ], 'Foo', true) + ); + } + + public function testReturnsNullWhenHeaderNotFound() + { + $this->assertNull(Core::header(['headers' => []], 'Foo')); + } + + public function testRemovesHeaders() + { + $message = [ + 'headers' => [ + 'foo' => ['bar'], + 'Foo' => ['bam'], + 'baz' => ['123'], + ], + ]; + + $this->assertSame($message, Core::removeHeader($message, 'bam')); + $this->assertEquals([ + 'headers' => ['baz' => ['123']], + ], Core::removeHeader($message, 'foo')); + } + + public function testCreatesUrl() + { + $req = [ + 'scheme' => 'http', + 'headers' => ['host' => ['foo.com']], + 'uri' => '/', + ]; + + $this->assertEquals('http://foo.com/', Core::url($req)); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage No Host header was provided + */ + public function testEnsuresHostIsAvailableWhenCreatingUrls() + { + Core::url([]); + } + + public function testCreatesUrlWithQueryString() + { + $req = [ + 'scheme' => 'http', + 'headers' => ['host' => ['foo.com']], + 'uri' => '/', + 'query_string' => 'foo=baz', + ]; + + $this->assertEquals('http://foo.com/?foo=baz', Core::url($req)); + } + + public function testUsesUrlIfSet() + { + $req = ['url' => 'http://foo.com']; + $this->assertEquals('http://foo.com', Core::url($req)); + } + + public function testReturnsNullWhenNoBody() + { + $this->assertNull(Core::body([])); + } + + public function testReturnsStreamAsString() + { + $this->assertEquals( + 'foo', + Core::body(['body' => Stream::factory('foo')]) + ); + } + + public function testReturnsString() + { + $this->assertEquals('foo', Core::body(['body' => 'foo'])); + } + + public function testReturnsResourceContent() + { + $r = fopen('php://memory', 'w+'); + fwrite($r, 'foo'); + rewind($r); + $this->assertEquals('foo', Core::body(['body' => $r])); + fclose($r); + } + + public function testReturnsIteratorContent() + { + $a = new \ArrayIterator(['a', 'b', 'cd', '']); + $this->assertEquals('abcd', Core::body(['body' => $a])); + } + + public function testReturnsObjectToString() + { + $this->assertEquals('foo', Core::body(['body' => new StrClass])); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testEnsuresBodyIsValid() + { + Core::body(['body' => false]); + } + + public function testParsesHeadersFromLines() + { + $lines = ['Foo: bar', 'Foo: baz', 'Abc: 123', 'Def: a, b']; + $this->assertEquals([ + 'Foo' => ['bar', 'baz'], + 'Abc' => ['123'], + 'Def' => ['a, b'], + ], Core::headersFromLines($lines)); + } + + public function testParsesHeadersFromLinesWithMultipleLines() + { + $lines = ['Foo: bar', 'Foo: baz', 'Foo: 123']; + $this->assertEquals([ + 'Foo' => ['bar', 'baz', '123'], + ], Core::headersFromLines($lines)); + } + + public function testCreatesArrayCallFunctions() + { + $called = []; + $a = function ($a, $b) use (&$called) { + $called['a'] = func_get_args(); + }; + $b = function ($a, $b) use (&$called) { + $called['b'] = func_get_args(); + }; + $c = Core::callArray([$a, $b]); + $c(1, 2); + $this->assertEquals([1, 2], $called['a']); + $this->assertEquals([1, 2], $called['b']); + } + + public function testRewindsGuzzleStreams() + { + $str = Stream::factory('foo'); + $this->assertTrue(Core::rewindBody(['body' => $str])); + } + + public function testRewindsStreams() + { + $str = Stream::factory('foo')->detach(); + $this->assertTrue(Core::rewindBody(['body' => $str])); + } + + public function testRewindsIterators() + { + $iter = new \ArrayIterator(['foo']); + $this->assertTrue(Core::rewindBody(['body' => $iter])); + } + + public function testRewindsStrings() + { + $this->assertTrue(Core::rewindBody(['body' => 'hi'])); + } + + public function testRewindsToStrings() + { + $this->assertTrue(Core::rewindBody(['body' => new StrClass()])); + } + + public function typeProvider() + { + return [ + ['foo', 'string(3) "foo"'], + [true, 'bool(true)'], + [false, 'bool(false)'], + [10, 'int(10)'], + [1.0, 'float(1)'], + [new StrClass(), 'object(GuzzleHttp\Tests\Ring\StrClass)'], + [['foo'], 'array(1)'] + ]; + } + + /** + * @dataProvider typeProvider + */ + public function testDescribesType($input, $output) + { + $this->assertEquals($output, Core::describeType($input)); + } + + public function testDoesSleep() + { + $t = microtime(true); + $expected = $t + (100 / 1000); + Core::doSleep(['client' => ['delay' => 100]]); + $this->assertGreaterThanOrEqual($expected, microtime(true)); + } + + public function testProxiesFuture() + { + $f = new CompletedFutureArray(['status' => 200]); + $res = null; + $proxied = Core::proxy($f, function ($value) use (&$res) { + $value['foo'] = 'bar'; + $res = $value; + return $value; + }); + $this->assertNotSame($f, $proxied); + $this->assertEquals(200, $f->wait()['status']); + $this->assertArrayNotHasKey('foo', $f->wait()); + $this->assertEquals('bar', $proxied->wait()['foo']); + $this->assertEquals(200, $proxied->wait()['status']); + } + + public function testProxiesDeferredFuture() + { + $d = new Deferred(); + $f = new FutureArray($d->promise()); + $f2 = Core::proxy($f); + $d->resolve(['foo' => 'bar']); + $this->assertEquals('bar', $f['foo']); + $this->assertEquals('bar', $f2['foo']); + } + + public function testProxiesDeferredFutureFailure() + { + $d = new Deferred(); + $f = new FutureArray($d->promise()); + $f2 = Core::proxy($f); + $d->reject(new \Exception('foo')); + try { + $f2['hello?']; + $this->fail('did not throw'); + } catch (\Exception $e) { + $this->assertEquals('foo', $e->getMessage()); + } + + } +} + +final class StrClass +{ + public function __toString() + { + return 'foo'; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/CompletedFutureArrayTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/CompletedFutureArrayTest.php new file mode 100644 index 00000000..82d7efbf --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/CompletedFutureArrayTest.php @@ -0,0 +1,21 @@ + 'bar']); + $this->assertEquals('bar', $f['foo']); + $this->assertFalse(isset($f['baz'])); + $f['abc'] = '123'; + $this->assertTrue(isset($f['abc'])); + $this->assertEquals(['foo' => 'bar', 'abc' => '123'], iterator_to_array($f)); + $this->assertEquals(2, count($f)); + unset($f['abc']); + $this->assertEquals(1, count($f)); + $this->assertEquals(['foo' => 'bar'], iterator_to_array($f)); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/CompletedFutureValueTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/CompletedFutureValueTest.php new file mode 100644 index 00000000..6ded40df --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/CompletedFutureValueTest.php @@ -0,0 +1,46 @@ +assertEquals('hi', $f->wait()); + $f->cancel(); + + $a = null; + $f->then(function ($v) use (&$a) { + $a = $v; + }); + $this->assertSame('hi', $a); + } + + public function testThrows() + { + $ex = new \Exception('foo'); + $f = new CompletedFutureValue(null, $ex); + $f->cancel(); + try { + $f->wait(); + $this->fail('did not throw'); + } catch (\Exception $e) { + $this->assertSame($e, $ex); + } + } + + public function testMarksAsCancelled() + { + $ex = new CancelledFutureAccessException(); + $f = new CompletedFutureValue(null, $ex); + try { + $f->wait(); + $this->fail('did not throw'); + } catch (\Exception $e) { + $this->assertSame($e, $ex); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/FutureArrayTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/FutureArrayTest.php new file mode 100644 index 00000000..0e09f5af --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/FutureArrayTest.php @@ -0,0 +1,56 @@ +promise(), + function () use (&$c, $deferred) { + $c = true; + $deferred->resolve(['status' => 200]); + } + ); + $this->assertFalse($c); + $this->assertFalse($this->readAttribute($f, 'isRealized')); + $this->assertEquals(200, $f['status']); + $this->assertTrue($c); + } + + public function testActsLikeArray() + { + $deferred = new Deferred(); + $f = new FutureArray( + $deferred->promise(), + function () use (&$c, $deferred) { + $deferred->resolve(['status' => 200]); + } + ); + + $this->assertTrue(isset($f['status'])); + $this->assertEquals(200, $f['status']); + $this->assertEquals(['status' => 200], $f->wait()); + $this->assertEquals(1, count($f)); + $f['baz'] = 10; + $this->assertEquals(10, $f['baz']); + unset($f['baz']); + $this->assertFalse(isset($f['baz'])); + $this->assertEquals(['status' => 200], iterator_to_array($f)); + } + + /** + * @expectedException \RuntimeException + */ + public function testThrowsWhenAccessingInvalidProperty() + { + $deferred = new Deferred(); + $f = new FutureArray($deferred->promise(), function () {}); + $f->foo; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/FutureValueTest.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/FutureValueTest.php new file mode 100644 index 00000000..d59c543d --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/Future/FutureValueTest.php @@ -0,0 +1,109 @@ +promise(), + function () use ($deferred, &$called) { + $called++; + $deferred->resolve('foo'); + } + ); + + $this->assertEquals('foo', $f->wait()); + $this->assertEquals(1, $called); + $this->assertEquals('foo', $f->wait()); + $this->assertEquals(1, $called); + $f->cancel(); + $this->assertTrue($this->readAttribute($f, 'isRealized')); + } + + /** + * @expectedException \GuzzleHttp\Ring\Exception\CancelledFutureAccessException + */ + public function testThrowsWhenAccessingCancelled() + { + $f = new FutureValue( + (new Deferred())->promise(), + function () {}, + function () { return true; } + ); + $f->cancel(); + $f->wait(); + } + + /** + * @expectedException \OutOfBoundsException + */ + public function testThrowsWhenDerefFailure() + { + $called = false; + $deferred = new Deferred(); + $f = new FutureValue( + $deferred->promise(), + function () use(&$called) { + $called = true; + } + ); + $deferred->reject(new \OutOfBoundsException()); + $f->wait(); + $this->assertFalse($called); + } + + /** + * @expectedException \GuzzleHttp\Ring\Exception\RingException + * @expectedExceptionMessage Waiting did not resolve future + */ + public function testThrowsWhenDerefDoesNotResolve() + { + $deferred = new Deferred(); + $f = new FutureValue( + $deferred->promise(), + function () use(&$called) { + $called = true; + } + ); + $f->wait(); + } + + public function testThrowingCancelledFutureAccessExceptionCancels() + { + $deferred = new Deferred(); + $f = new FutureValue( + $deferred->promise(), + function () use ($deferred) { + throw new CancelledFutureAccessException(); + } + ); + try { + $f->wait(); + $this->fail('did not throw'); + } catch (CancelledFutureAccessException $e) {} + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage foo + */ + public function testThrowingExceptionInDerefMarksAsFailed() + { + $deferred = new Deferred(); + $f = new FutureValue( + $deferred->promise(), + function () { + throw new \Exception('foo'); + } + ); + $f->wait(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/bootstrap.php b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/bootstrap.php new file mode 100644 index 00000000..017610fe --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/ringphp/tests/bootstrap.php @@ -0,0 +1,11 @@ + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/Makefile b/modules/empikmarketplace/vendor/guzzlehttp/streams/Makefile new file mode 100644 index 00000000..f4d42849 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/Makefile @@ -0,0 +1,19 @@ +all: clean coverage + +release: tag + git push origin --tags + +tag: + chag tag --sign --debug CHANGELOG.rst + +test: + vendor/bin/phpunit + +coverage: + vendor/bin/phpunit --coverage-html=artifacts/coverage + +view-coverage: + open artifacts/coverage/index.html + +clean: + rm -rf artifacts/* diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/README.rst b/modules/empikmarketplace/vendor/guzzlehttp/streams/README.rst new file mode 100644 index 00000000..baff63b3 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/README.rst @@ -0,0 +1,36 @@ +============== +Guzzle Streams +============== + +Provides a simple abstraction over streams of data. + +This library is used in `Guzzle 5 `_, and is +(currently) compatible with the WIP PSR-7. + +Installation +============ + +This package can be installed easily using `Composer `_. +Simply add the following to the composer.json file at the root of your project: + +.. code-block:: javascript + + { + "require": { + "guzzlehttp/streams": "~3.0" + } + } + +Then install your dependencies using ``composer.phar install``. + +Documentation +============= + +The documentation for this package can be found on the main Guzzle website at +http://docs.guzzlephp.org/en/guzzle4/streams.html. + +Testing +======= + +This library is tested using PHPUnit. You'll need to install the dependencies +using `Composer `_ then run ``make test``. diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/composer.json b/modules/empikmarketplace/vendor/guzzlehttp/streams/composer.json new file mode 100644 index 00000000..6d703437 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/composer.json @@ -0,0 +1,28 @@ +{ + "name": "guzzlehttp/streams", + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": ["stream", "guzzle"], + "license": "MIT", + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "autoload": { + "psr-4": { "GuzzleHttp\\Stream\\": "src/" } + }, + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/phpunit.xml.dist b/modules/empikmarketplace/vendor/guzzlehttp/streams/phpunit.xml.dist new file mode 100644 index 00000000..6e758c19 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/phpunit.xml.dist @@ -0,0 +1,17 @@ + + + + + tests + + + + + src + + src/functions.php + + + + diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/AppendStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/AppendStream.php new file mode 100644 index 00000000..94bda717 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/AppendStream.php @@ -0,0 +1,220 @@ +addStream($stream); + } + } + + public function __toString() + { + try { + $this->seek(0); + return $this->getContents(); + } catch (\Exception $e) { + return ''; + } + } + + /** + * Add a stream to the AppendStream + * + * @param StreamInterface $stream Stream to append. Must be readable. + * + * @throws \InvalidArgumentException if the stream is not readable + */ + public function addStream(StreamInterface $stream) + { + if (!$stream->isReadable()) { + throw new \InvalidArgumentException('Each stream must be readable'); + } + + // The stream is only seekable if all streams are seekable + if (!$stream->isSeekable()) { + $this->seekable = false; + } + + $this->streams[] = $stream; + } + + public function getContents() + { + return Utils::copyToString($this); + } + + /** + * Closes each attached stream. + * + * {@inheritdoc} + */ + public function close() + { + $this->pos = $this->current = 0; + + foreach ($this->streams as $stream) { + $stream->close(); + } + + $this->streams = []; + } + + /** + * Detaches each attached stream + * + * {@inheritdoc} + */ + public function detach() + { + $this->close(); + $this->detached = true; + } + + public function attach($stream) + { + throw new CannotAttachException(); + } + + public function tell() + { + return $this->pos; + } + + /** + * Tries to calculate the size by adding the size of each stream. + * + * If any of the streams do not return a valid number, then the size of the + * append stream cannot be determined and null is returned. + * + * {@inheritdoc} + */ + public function getSize() + { + $size = 0; + + foreach ($this->streams as $stream) { + $s = $stream->getSize(); + if ($s === null) { + return null; + } + $size += $s; + } + + return $size; + } + + public function eof() + { + return !$this->streams || + ($this->current >= count($this->streams) - 1 && + $this->streams[$this->current]->eof()); + } + + /** + * Attempts to seek to the given position. Only supports SEEK_SET. + * + * {@inheritdoc} + */ + public function seek($offset, $whence = SEEK_SET) + { + if (!$this->seekable || $whence !== SEEK_SET) { + return false; + } + + $success = true; + $this->pos = $this->current = 0; + + // Rewind each stream + foreach ($this->streams as $stream) { + if (!$stream->seek(0)) { + $success = false; + } + } + + if (!$success) { + return false; + } + + // Seek to the actual position by reading from each stream + while ($this->pos < $offset && !$this->eof()) { + $this->read(min(8096, $offset - $this->pos)); + } + + return $this->pos == $offset; + } + + /** + * Reads from all of the appended streams until the length is met or EOF. + * + * {@inheritdoc} + */ + public function read($length) + { + $buffer = ''; + $total = count($this->streams) - 1; + $remaining = $length; + + while ($remaining > 0) { + // Progress to the next stream if needed. + if ($this->streams[$this->current]->eof()) { + if ($this->current == $total) { + break; + } + $this->current++; + } + $buffer .= $this->streams[$this->current]->read($remaining); + $remaining = $length - strlen($buffer); + } + + $this->pos += strlen($buffer); + + return $buffer; + } + + public function isReadable() + { + return true; + } + + public function isWritable() + { + return false; + } + + public function isSeekable() + { + return $this->seekable; + } + + public function write($string) + { + return false; + } + + public function getMetadata($key = null) + { + return $key ? null : []; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/AsyncReadStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/AsyncReadStream.php new file mode 100644 index 00000000..25ad9602 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/AsyncReadStream.php @@ -0,0 +1,207 @@ +isReadable() || !$buffer->isWritable()) { + throw new \InvalidArgumentException( + 'Buffer must be readable and writable' + ); + } + + if (isset($config['size'])) { + $this->size = $config['size']; + } + + static $callables = ['pump', 'drain']; + foreach ($callables as $check) { + if (isset($config[$check])) { + if (!is_callable($config[$check])) { + throw new \InvalidArgumentException( + $check . ' must be callable' + ); + } + $this->{$check} = $config[$check]; + } + } + + $this->hwm = $buffer->getMetadata('hwm'); + + // Cannot drain when there's no high water mark. + if ($this->hwm === null) { + $this->drain = null; + } + + $this->stream = $buffer; + } + + /** + * Factory method used to create new async stream and an underlying buffer + * if no buffer is provided. + * + * This function accepts the same options as AsyncReadStream::__construct, + * but added the following key value pairs: + * + * - buffer: (StreamInterface) Buffer used to buffer data. If none is + * provided, a default buffer is created. + * - hwm: (int) High water mark to use if a buffer is created on your + * behalf. + * - max_buffer: (int) If provided, wraps the utilized buffer in a + * DroppingStream decorator to ensure that buffer does not exceed a given + * length. When exceeded, the stream will begin dropping data. Set the + * max_buffer to 0, to use a NullStream which does not store data. + * - write: (callable) A function that is invoked when data is written + * to the underlying buffer. The function accepts the buffer as the first + * argument, and the data being written as the second. The function MUST + * return the number of bytes that were written or false to let writers + * know to slow down. + * - drain: (callable) See constructor documentation. + * - pump: (callable) See constructor documentation. + * + * @param array $options Associative array of options. + * + * @return array Returns an array containing the buffer used to buffer + * data, followed by the ready to use AsyncReadStream object. + */ + public static function create(array $options = []) + { + $maxBuffer = isset($options['max_buffer']) + ? $options['max_buffer'] + : null; + + if ($maxBuffer === 0) { + $buffer = new NullStream(); + } elseif (isset($options['buffer'])) { + $buffer = $options['buffer']; + } else { + $hwm = isset($options['hwm']) ? $options['hwm'] : 16384; + $buffer = new BufferStream($hwm); + } + + if ($maxBuffer > 0) { + $buffer = new DroppingStream($buffer, $options['max_buffer']); + } + + // Call the on_write callback if an on_write function was provided. + if (isset($options['write'])) { + $onWrite = $options['write']; + $buffer = FnStream::decorate($buffer, [ + 'write' => function ($string) use ($buffer, $onWrite) { + $result = $buffer->write($string); + $onWrite($buffer, $string); + return $result; + } + ]); + } + + return [$buffer, new self($buffer, $options)]; + } + + public function getSize() + { + return $this->size; + } + + public function isWritable() + { + return false; + } + + public function write($string) + { + return false; + } + + public function read($length) + { + if (!$this->needsDrain && $this->drain) { + $this->needsDrain = $this->stream->getSize() >= $this->hwm; + } + + $result = $this->stream->read($length); + + // If we need to drain, then drain when the buffer is empty. + if ($this->needsDrain && $this->stream->getSize() === 0) { + $this->needsDrain = false; + $drainFn = $this->drain; + $drainFn($this->stream); + } + + $resultLen = strlen($result); + + // If a pump was provided, the buffer is still open, and not enough + // data was given, then block until the data is provided. + if ($this->pump && $resultLen < $length) { + $pumpFn = $this->pump; + $result .= $pumpFn($length - $resultLen); + } + + return $result; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/BufferStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/BufferStream.php new file mode 100644 index 00000000..0fffbd63 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/BufferStream.php @@ -0,0 +1,138 @@ +hwm = $hwm; + } + + public function __toString() + { + return $this->getContents(); + } + + public function getContents() + { + $buffer = $this->buffer; + $this->buffer = ''; + + return $buffer; + } + + public function close() + { + $this->buffer = ''; + } + + public function detach() + { + $this->close(); + } + + public function attach($stream) + { + throw new CannotAttachException(); + } + + public function getSize() + { + return strlen($this->buffer); + } + + public function isReadable() + { + return true; + } + + public function isWritable() + { + return true; + } + + public function isSeekable() + { + return false; + } + + public function seek($offset, $whence = SEEK_SET) + { + return false; + } + + public function eof() + { + return strlen($this->buffer) === 0; + } + + public function tell() + { + return false; + } + + /** + * Reads data from the buffer. + */ + public function read($length) + { + $currentLength = strlen($this->buffer); + + if ($length >= $currentLength) { + // No need to slice the buffer because we don't have enough data. + $result = $this->buffer; + $this->buffer = ''; + } else { + // Slice up the result to provide a subset of the buffer. + $result = substr($this->buffer, 0, $length); + $this->buffer = substr($this->buffer, $length); + } + + return $result; + } + + /** + * Writes data to the buffer. + */ + public function write($string) + { + $this->buffer .= $string; + + if (strlen($this->buffer) >= $this->hwm) { + return false; + } + + return strlen($string); + } + + public function getMetadata($key = null) + { + if ($key == 'hwm') { + return $this->hwm; + } + + return $key ? null : []; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/CachingStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/CachingStream.php new file mode 100644 index 00000000..60bb9056 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/CachingStream.php @@ -0,0 +1,122 @@ +remoteStream = $stream; + $this->stream = $target ?: new Stream(fopen('php://temp', 'r+')); + } + + public function getSize() + { + return max($this->stream->getSize(), $this->remoteStream->getSize()); + } + + /** + * {@inheritdoc} + * @throws SeekException When seeking with SEEK_END or when seeking + * past the total size of the buffer stream + */ + public function seek($offset, $whence = SEEK_SET) + { + if ($whence == SEEK_SET) { + $byte = $offset; + } elseif ($whence == SEEK_CUR) { + $byte = $offset + $this->tell(); + } else { + return false; + } + + // You cannot skip ahead past where you've read from the remote stream + if ($byte > $this->stream->getSize()) { + throw new SeekException( + $this, + $byte, + sprintf('Cannot seek to byte %d when the buffered stream only' + . ' contains %d bytes', $byte, $this->stream->getSize()) + ); + } + + return $this->stream->seek($byte); + } + + public function read($length) + { + // Perform a regular read on any previously read data from the buffer + $data = $this->stream->read($length); + $remaining = $length - strlen($data); + + // More data was requested so read from the remote stream + if ($remaining) { + // If data was written to the buffer in a position that would have + // been filled from the remote stream, then we must skip bytes on + // the remote stream to emulate overwriting bytes from that + // position. This mimics the behavior of other PHP stream wrappers. + $remoteData = $this->remoteStream->read( + $remaining + $this->skipReadBytes + ); + + if ($this->skipReadBytes) { + $len = strlen($remoteData); + $remoteData = substr($remoteData, $this->skipReadBytes); + $this->skipReadBytes = max(0, $this->skipReadBytes - $len); + } + + $data .= $remoteData; + $this->stream->write($remoteData); + } + + return $data; + } + + public function write($string) + { + // When appending to the end of the currently read stream, you'll want + // to skip bytes from being read from the remote stream to emulate + // other stream wrappers. Basically replacing bytes of data of a fixed + // length. + $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell(); + if ($overflow > 0) { + $this->skipReadBytes += $overflow; + } + + return $this->stream->write($string); + } + + public function eof() + { + return $this->stream->eof() && $this->remoteStream->eof(); + } + + /** + * Close both the remote stream and buffer stream + */ + public function close() + { + $this->remoteStream->close() && $this->stream->close(); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/DroppingStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/DroppingStream.php new file mode 100644 index 00000000..56ee80c1 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/DroppingStream.php @@ -0,0 +1,42 @@ +stream = $stream; + $this->maxLength = $maxLength; + } + + public function write($string) + { + $diff = $this->maxLength - $this->stream->getSize(); + + // Begin returning false when the underlying stream is too large. + if ($diff <= 0) { + return false; + } + + // Write the stream or a subset of the stream if needed. + if (strlen($string) < $diff) { + return $this->stream->write($string); + } + + $this->stream->write(substr($string, 0, $diff)); + + return false; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/Exception/CannotAttachException.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/Exception/CannotAttachException.php new file mode 100644 index 00000000..e631b9fa --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/Exception/CannotAttachException.php @@ -0,0 +1,4 @@ +stream = $stream; + $msg = $msg ?: 'Could not seek the stream to position ' . $pos; + parent::__construct($msg); + } + + /** + * @return StreamInterface + */ + public function getStream() + { + return $this->stream; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/FnStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/FnStream.php new file mode 100644 index 00000000..6b5872d7 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/FnStream.php @@ -0,0 +1,147 @@ +methods = $methods; + + // Create the functions on the class + foreach ($methods as $name => $fn) { + $this->{'_fn_' . $name} = $fn; + } + } + + /** + * Lazily determine which methods are not implemented. + * @throws \BadMethodCallException + */ + public function __get($name) + { + throw new \BadMethodCallException(str_replace('_fn_', '', $name) + . '() is not implemented in the FnStream'); + } + + /** + * The close method is called on the underlying stream only if possible. + */ + public function __destruct() + { + if (isset($this->_fn_close)) { + call_user_func($this->_fn_close); + } + } + + /** + * Adds custom functionality to an underlying stream by intercepting + * specific method calls. + * + * @param StreamInterface $stream Stream to decorate + * @param array $methods Hash of method name to a closure + * + * @return FnStream + */ + public static function decorate(StreamInterface $stream, array $methods) + { + // If any of the required methods were not provided, then simply + // proxy to the decorated stream. + foreach (array_diff(self::$slots, array_keys($methods)) as $diff) { + $methods[$diff] = [$stream, $diff]; + } + + return new self($methods); + } + + public function __toString() + { + return call_user_func($this->_fn___toString); + } + + public function close() + { + return call_user_func($this->_fn_close); + } + + public function detach() + { + return call_user_func($this->_fn_detach); + } + + public function attach($stream) + { + return call_user_func($this->_fn_attach, $stream); + } + + public function getSize() + { + return call_user_func($this->_fn_getSize); + } + + public function tell() + { + return call_user_func($this->_fn_tell); + } + + public function eof() + { + return call_user_func($this->_fn_eof); + } + + public function isSeekable() + { + return call_user_func($this->_fn_isSeekable); + } + + public function seek($offset, $whence = SEEK_SET) + { + return call_user_func($this->_fn_seek, $offset, $whence); + } + + public function isWritable() + { + return call_user_func($this->_fn_isWritable); + } + + public function write($string) + { + return call_user_func($this->_fn_write, $string); + } + + public function isReadable() + { + return call_user_func($this->_fn_isReadable); + } + + public function read($length) + { + return call_user_func($this->_fn_read, $length); + } + + public function getContents() + { + return call_user_func($this->_fn_getContents); + } + + public function getMetadata($key = null) + { + return call_user_func($this->_fn_getMetadata, $key); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/GuzzleStreamWrapper.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/GuzzleStreamWrapper.php new file mode 100644 index 00000000..4d049a69 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/GuzzleStreamWrapper.php @@ -0,0 +1,117 @@ +isReadable()) { + $mode = $stream->isWritable() ? 'r+' : 'r'; + } elseif ($stream->isWritable()) { + $mode = 'w'; + } else { + throw new \InvalidArgumentException('The stream must be readable, ' + . 'writable, or both.'); + } + + return fopen('guzzle://stream', $mode, null, stream_context_create([ + 'guzzle' => ['stream' => $stream] + ])); + } + + /** + * Registers the stream wrapper if needed + */ + public static function register() + { + if (!in_array('guzzle', stream_get_wrappers())) { + stream_wrapper_register('guzzle', __CLASS__); + } + } + + public function stream_open($path, $mode, $options, &$opened_path) + { + $options = stream_context_get_options($this->context); + + if (!isset($options['guzzle']['stream'])) { + return false; + } + + $this->mode = $mode; + $this->stream = $options['guzzle']['stream']; + + return true; + } + + public function stream_read($count) + { + return $this->stream->read($count); + } + + public function stream_write($data) + { + return (int) $this->stream->write($data); + } + + public function stream_tell() + { + return $this->stream->tell(); + } + + public function stream_eof() + { + return $this->stream->eof(); + } + + public function stream_seek($offset, $whence) + { + return $this->stream->seek($offset, $whence); + } + + public function stream_stat() + { + static $modeMap = [ + 'r' => 33060, + 'r+' => 33206, + 'w' => 33188 + ]; + + return [ + 'dev' => 0, + 'ino' => 0, + 'mode' => $modeMap[$this->mode], + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => $this->stream->getSize() ?: 0, + 'atime' => 0, + 'mtime' => 0, + 'ctime' => 0, + 'blksize' => 0, + 'blocks' => 0 + ]; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/InflateStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/InflateStream.php new file mode 100644 index 00000000..978af210 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/InflateStream.php @@ -0,0 +1,27 @@ +stream = new Stream($resource); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/LazyOpenStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/LazyOpenStream.php new file mode 100644 index 00000000..6242ee7b --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/LazyOpenStream.php @@ -0,0 +1,37 @@ +filename = $filename; + $this->mode = $mode; + } + + /** + * Creates the underlying stream lazily when required. + * + * @return StreamInterface + */ + protected function createStream() + { + return Stream::factory(Utils::open($this->filename, $this->mode)); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/LimitStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/LimitStream.php new file mode 100644 index 00000000..e9fad985 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/LimitStream.php @@ -0,0 +1,161 @@ +stream = $stream; + $this->setLimit($limit); + $this->setOffset($offset); + } + + public function eof() + { + // Always return true if the underlying stream is EOF + if ($this->stream->eof()) { + return true; + } + + // No limit and the underlying stream is not at EOF + if ($this->limit == -1) { + return false; + } + + $tell = $this->stream->tell(); + if ($tell === false) { + return false; + } + + return $tell >= $this->offset + $this->limit; + } + + /** + * Returns the size of the limited subset of data + * {@inheritdoc} + */ + public function getSize() + { + if (null === ($length = $this->stream->getSize())) { + return null; + } elseif ($this->limit == -1) { + return $length - $this->offset; + } else { + return min($this->limit, $length - $this->offset); + } + } + + /** + * Allow for a bounded seek on the read limited stream + * {@inheritdoc} + */ + public function seek($offset, $whence = SEEK_SET) + { + if ($whence !== SEEK_SET || $offset < 0) { + return false; + } + + $offset += $this->offset; + + if ($this->limit !== -1) { + if ($offset > $this->offset + $this->limit) { + $offset = $this->offset + $this->limit; + } + } + + return $this->stream->seek($offset); + } + + /** + * Give a relative tell() + * {@inheritdoc} + */ + public function tell() + { + return $this->stream->tell() - $this->offset; + } + + /** + * Set the offset to start limiting from + * + * @param int $offset Offset to seek to and begin byte limiting from + * + * @return self + * @throws SeekException + */ + public function setOffset($offset) + { + $current = $this->stream->tell(); + + if ($current !== $offset) { + // If the stream cannot seek to the offset position, then read to it + if (!$this->stream->seek($offset)) { + if ($current > $offset) { + throw new SeekException($this, $offset); + } else { + $this->stream->read($offset - $current); + } + } + } + + $this->offset = $offset; + + return $this; + } + + /** + * Set the limit of bytes that the decorator allows to be read from the + * stream. + * + * @param int $limit Number of bytes to allow to be read from the stream. + * Use -1 for no limit. + * @return self + */ + public function setLimit($limit) + { + $this->limit = $limit; + + return $this; + } + + public function read($length) + { + if ($this->limit == -1) { + return $this->stream->read($length); + } + + // Check if the current position is less than the total allowed + // bytes + original offset + $remaining = ($this->offset + $this->limit) - $this->stream->tell(); + if ($remaining > 0) { + // Only return the amount of requested data, ensuring that the byte + // limit is not exceeded + return $this->stream->read(min($remaining, $length)); + } else { + return false; + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/MetadataStreamInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/MetadataStreamInterface.php new file mode 100644 index 00000000..c1433ad8 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/MetadataStreamInterface.php @@ -0,0 +1,11 @@ +stream->attach($stream); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/NullStream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/NullStream.php new file mode 100644 index 00000000..41ee7766 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/NullStream.php @@ -0,0 +1,78 @@ +source = $source; + $this->size = isset($options['size']) ? $options['size'] : null; + $this->metadata = isset($options['metadata']) ? $options['metadata'] : []; + $this->buffer = new BufferStream(); + } + + public function __toString() + { + return Utils::copyToString($this); + } + + public function close() + { + $this->detach(); + } + + public function detach() + { + $this->tellPos = false; + $this->source = null; + } + + public function attach($stream) + { + throw new CannotAttachException(); + } + + public function getSize() + { + return $this->size; + } + + public function tell() + { + return $this->tellPos; + } + + public function eof() + { + return !$this->source; + } + + public function isSeekable() + { + return false; + } + + public function seek($offset, $whence = SEEK_SET) + { + return false; + } + + public function isWritable() + { + return false; + } + + public function write($string) + { + return false; + } + + public function isReadable() + { + return true; + } + + public function read($length) + { + $data = $this->buffer->read($length); + $readLen = strlen($data); + $this->tellPos += $readLen; + $remaining = $length - $readLen; + + if ($remaining) { + $this->pump($remaining); + $data .= $this->buffer->read($remaining); + $this->tellPos += strlen($data) - $readLen; + } + + return $data; + } + + public function getContents() + { + $result = ''; + while (!$this->eof()) { + $result .= $this->read(1000000); + } + + return $result; + } + + public function getMetadata($key = null) + { + if (!$key) { + return $this->metadata; + } + + return isset($this->metadata[$key]) ? $this->metadata[$key] : null; + } + + private function pump($length) + { + if ($this->source) { + do { + $data = call_user_func($this->source, $length); + if ($data === false || $data === null) { + $this->source = null; + return; + } + $this->buffer->write($data); + $length -= strlen($data); + } while ($length > 0); + } + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/Stream.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/Stream.php new file mode 100644 index 00000000..7adbc5e3 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/Stream.php @@ -0,0 +1,261 @@ + [ + 'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true, + 'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, + 'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true, + 'x+t' => true, 'c+t' => true, 'a+' => true + ], + 'write' => [ + 'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true, + 'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true, + 'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true, + 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true + ] + ]; + + /** + * Create a new stream based on the input type. + * + * This factory accepts the same associative array of options as described + * in the constructor. + * + * @param resource|string|StreamInterface $resource Entity body data + * @param array $options Additional options + * + * @return Stream + * @throws \InvalidArgumentException if the $resource arg is not valid. + */ + public static function factory($resource = '', array $options = []) + { + $type = gettype($resource); + + if ($type == 'string') { + $stream = fopen('php://temp', 'r+'); + if ($resource !== '') { + fwrite($stream, $resource); + fseek($stream, 0); + } + return new self($stream, $options); + } + + if ($type == 'resource') { + return new self($resource, $options); + } + + if ($resource instanceof StreamInterface) { + return $resource; + } + + if ($type == 'object' && method_exists($resource, '__toString')) { + return self::factory((string) $resource, $options); + } + + if (is_callable($resource)) { + return new PumpStream($resource, $options); + } + + if ($resource instanceof \Iterator) { + return new PumpStream(function () use ($resource) { + if (!$resource->valid()) { + return false; + } + $result = $resource->current(); + $resource->next(); + return $result; + }, $options); + } + + throw new \InvalidArgumentException('Invalid resource type: ' . $type); + } + + /** + * This constructor accepts an associative array of options. + * + * - size: (int) If a read stream would otherwise have an indeterminate + * size, but the size is known due to foreknownledge, then you can + * provide that size, in bytes. + * - metadata: (array) Any additional metadata to return when the metadata + * of the stream is accessed. + * + * @param resource $stream Stream resource to wrap. + * @param array $options Associative array of options. + * + * @throws \InvalidArgumentException if the stream is not a stream resource + */ + public function __construct($stream, $options = []) + { + if (!is_resource($stream)) { + throw new \InvalidArgumentException('Stream must be a resource'); + } + + if (isset($options['size'])) { + $this->size = $options['size']; + } + + $this->customMetadata = isset($options['metadata']) + ? $options['metadata'] + : []; + + $this->attach($stream); + } + + /** + * Closes the stream when the destructed + */ + public function __destruct() + { + $this->close(); + } + + public function __toString() + { + if (!$this->stream) { + return ''; + } + + $this->seek(0); + + return (string) stream_get_contents($this->stream); + } + + public function getContents() + { + return $this->stream ? stream_get_contents($this->stream) : ''; + } + + public function close() + { + if (is_resource($this->stream)) { + fclose($this->stream); + } + + $this->detach(); + } + + public function detach() + { + $result = $this->stream; + $this->stream = $this->size = $this->uri = null; + $this->readable = $this->writable = $this->seekable = false; + + return $result; + } + + public function attach($stream) + { + $this->stream = $stream; + $meta = stream_get_meta_data($this->stream); + $this->seekable = $meta['seekable']; + $this->readable = isset(self::$readWriteHash['read'][$meta['mode']]); + $this->writable = isset(self::$readWriteHash['write'][$meta['mode']]); + $this->uri = $this->getMetadata('uri'); + } + + public function getSize() + { + if ($this->size !== null) { + return $this->size; + } + + if (!$this->stream) { + return null; + } + + // Clear the stat cache if the stream has a URI + if ($this->uri) { + clearstatcache(true, $this->uri); + } + + $stats = fstat($this->stream); + if (isset($stats['size'])) { + $this->size = $stats['size']; + return $this->size; + } + + return null; + } + + public function isReadable() + { + return $this->readable; + } + + public function isWritable() + { + return $this->writable; + } + + public function isSeekable() + { + return $this->seekable; + } + + public function eof() + { + return !$this->stream || feof($this->stream); + } + + public function tell() + { + return $this->stream ? ftell($this->stream) : false; + } + + public function setSize($size) + { + $this->size = $size; + + return $this; + } + + public function seek($offset, $whence = SEEK_SET) + { + return $this->seekable + ? fseek($this->stream, $offset, $whence) === 0 + : false; + } + + public function read($length) + { + return $this->readable ? fread($this->stream, $length) : false; + } + + public function write($string) + { + // We can't know the size after writing anything + $this->size = null; + + return $this->writable ? fwrite($this->stream, $string) : false; + } + + public function getMetadata($key = null) + { + if (!$this->stream) { + return $key ? null : []; + } elseif (!$key) { + return $this->customMetadata + stream_get_meta_data($this->stream); + } elseif (isset($this->customMetadata[$key])) { + return $this->customMetadata[$key]; + } + + $meta = stream_get_meta_data($this->stream); + + return isset($meta[$key]) ? $meta[$key] : null; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/StreamDecoratorTrait.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/StreamDecoratorTrait.php new file mode 100644 index 00000000..39c19c58 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/StreamDecoratorTrait.php @@ -0,0 +1,143 @@ +stream = $stream; + } + + /** + * Magic method used to create a new stream if streams are not added in + * the constructor of a decorator (e.g., LazyOpenStream). + */ + public function __get($name) + { + if ($name == 'stream') { + $this->stream = $this->createStream(); + return $this->stream; + } + + throw new \UnexpectedValueException("$name not found on class"); + } + + public function __toString() + { + try { + $this->seek(0); + return $this->getContents(); + } catch (\Exception $e) { + // Really, PHP? https://bugs.php.net/bug.php?id=53648 + trigger_error('StreamDecorator::__toString exception: ' + . (string) $e, E_USER_ERROR); + return ''; + } + } + + public function getContents() + { + return Utils::copyToString($this); + } + + /** + * Allow decorators to implement custom methods + * + * @param string $method Missing method name + * @param array $args Method arguments + * + * @return mixed + */ + public function __call($method, array $args) + { + $result = call_user_func_array(array($this->stream, $method), $args); + + // Always return the wrapped object if the result is a return $this + return $result === $this->stream ? $this : $result; + } + + public function close() + { + $this->stream->close(); + } + + public function getMetadata($key = null) + { + return $this->stream->getMetadata($key); + } + + public function detach() + { + return $this->stream->detach(); + } + + public function attach($stream) + { + throw new CannotAttachException(); + } + + public function getSize() + { + return $this->stream->getSize(); + } + + public function eof() + { + return $this->stream->eof(); + } + + public function tell() + { + return $this->stream->tell(); + } + + public function isReadable() + { + return $this->stream->isReadable(); + } + + public function isWritable() + { + return $this->stream->isWritable(); + } + + public function isSeekable() + { + return $this->stream->isSeekable(); + } + + public function seek($offset, $whence = SEEK_SET) + { + return $this->stream->seek($offset, $whence); + } + + public function read($length) + { + return $this->stream->read($length); + } + + public function write($string) + { + return $this->stream->write($string); + } + + /** + * Implement in subclasses to dynamically create streams when requested. + * + * @return StreamInterface + * @throws \BadMethodCallException + */ + protected function createStream() + { + throw new \BadMethodCallException('createStream() not implemented in ' + . get_class($this)); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/src/StreamInterface.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/StreamInterface.php new file mode 100644 index 00000000..fd19c6f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/src/StreamInterface.php @@ -0,0 +1,159 @@ +eof()) { + $buf = $stream->read(1048576); + if ($buf === false) { + break; + } + $buffer .= $buf; + } + return $buffer; + } + + $len = 0; + while (!$stream->eof() && $len < $maxLen) { + $buf = $stream->read($maxLen - $len); + if ($buf === false) { + break; + } + $buffer .= $buf; + $len = strlen($buffer); + } + + return $buffer; + } + + /** + * Copy the contents of a stream into another stream until the given number + * of bytes have been read. + * + * @param StreamInterface $source Stream to read from + * @param StreamInterface $dest Stream to write to + * @param int $maxLen Maximum number of bytes to read. Pass -1 + * to read the entire stream. + */ + public static function copyToStream( + StreamInterface $source, + StreamInterface $dest, + $maxLen = -1 + ) { + if ($maxLen === -1) { + while (!$source->eof()) { + if (!$dest->write($source->read(1048576))) { + break; + } + } + return; + } + + $bytes = 0; + while (!$source->eof()) { + $buf = $source->read($maxLen - $bytes); + if (!($len = strlen($buf))) { + break; + } + $bytes += $len; + $dest->write($buf); + if ($bytes == $maxLen) { + break; + } + } + } + + /** + * Calculate a hash of a Stream + * + * @param StreamInterface $stream Stream to calculate the hash for + * @param string $algo Hash algorithm (e.g. md5, crc32, etc) + * @param bool $rawOutput Whether or not to use raw output + * + * @return string Returns the hash of the stream + * @throws SeekException + */ + public static function hash( + StreamInterface $stream, + $algo, + $rawOutput = false + ) { + $pos = $stream->tell(); + + if ($pos > 0 && !$stream->seek(0)) { + throw new SeekException($stream); + } + + $ctx = hash_init($algo); + while (!$stream->eof()) { + hash_update($ctx, $stream->read(1048576)); + } + + $out = hash_final($ctx, (bool) $rawOutput); + $stream->seek($pos); + + return $out; + } + + /** + * Read a line from the stream up to the maximum allowed buffer length + * + * @param StreamInterface $stream Stream to read from + * @param int $maxLength Maximum buffer length + * + * @return string|bool + */ + public static function readline(StreamInterface $stream, $maxLength = null) + { + $buffer = ''; + $size = 0; + + while (!$stream->eof()) { + if (false === ($byte = $stream->read(1))) { + return $buffer; + } + $buffer .= $byte; + // Break when a new line is found or the max length - 1 is reached + if ($byte == PHP_EOL || ++$size == $maxLength - 1) { + break; + } + } + + return $buffer; + } + + /** + * Alias of GuzzleHttp\Stream\Stream::factory. + * + * @param mixed $resource Resource to create + * @param array $options Associative array of stream options defined in + * {@see \GuzzleHttp\Stream\Stream::__construct} + * + * @return StreamInterface + * + * @see GuzzleHttp\Stream\Stream::factory + * @see GuzzleHttp\Stream\Stream::__construct + */ + public static function create($resource, array $options = []) + { + return Stream::factory($resource, $options); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/AppendStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/AppendStreamTest.php new file mode 100644 index 00000000..78798d9f --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/AppendStreamTest.php @@ -0,0 +1,178 @@ +getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(false)); + $a->addStream($s); + } + + public function testValidatesSeekType() + { + $a = new AppendStream(); + $this->assertFalse($a->seek(100, SEEK_CUR)); + } + + public function testTriesToRewindOnSeek() + { + $a = new AppendStream(); + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable', 'seek', 'isSeekable']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); + $s->expects($this->once()) + ->method('isSeekable') + ->will($this->returnValue(true)); + $s->expects($this->once()) + ->method('seek') + ->will($this->returnValue(false)); + $a->addStream($s); + $this->assertFalse($a->seek(10)); + } + + public function testSeeksToPositionByReading() + { + $a = new AppendStream([ + Stream::factory('foo'), + Stream::factory('bar'), + Stream::factory('baz'), + ]); + + $this->assertTrue($a->seek(3)); + $this->assertEquals(3, $a->tell()); + $this->assertEquals('bar', $a->read(3)); + $a->seek(6); + $this->assertEquals(6, $a->tell()); + $this->assertEquals('baz', $a->read(3)); + } + + public function testDetachesEachStream() + { + $s1 = Stream::factory('foo'); + $s2 = Stream::factory('foo'); + $a = new AppendStream([$s1, $s2]); + $this->assertSame('foofoo', (string) $a); + $a->detach(); + $this->assertSame('', (string) $a); + $this->assertSame(0, $a->getSize()); + } + + public function testClosesEachStream() + { + $s1 = Stream::factory('foo'); + $a = new AppendStream([$s1]); + $a->close(); + $this->assertSame('', (string) $a); + } + + public function testIsNotWritable() + { + $a = new AppendStream([Stream::factory('foo')]); + $this->assertFalse($a->isWritable()); + $this->assertTrue($a->isSeekable()); + $this->assertTrue($a->isReadable()); + $this->assertFalse($a->write('foo')); + } + + public function testDoesNotNeedStreams() + { + $a = new AppendStream(); + $this->assertEquals('', (string) $a); + } + + public function testCanReadFromMultipleStreams() + { + $a = new AppendStream([ + Stream::factory('foo'), + Stream::factory('bar'), + Stream::factory('baz'), + ]); + $this->assertFalse($a->eof()); + $this->assertSame(0, $a->tell()); + $this->assertEquals('foo', $a->read(3)); + $this->assertEquals('bar', $a->read(3)); + $this->assertEquals('baz', $a->read(3)); + $this->assertTrue($a->eof()); + $this->assertSame(9, $a->tell()); + $this->assertEquals('foobarbaz', (string) $a); + } + + public function testCanDetermineSizeFromMultipleStreams() + { + $a = new AppendStream([ + Stream::factory('foo'), + Stream::factory('bar') + ]); + $this->assertEquals(6, $a->getSize()); + + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isSeekable', 'isReadable']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('isSeekable') + ->will($this->returnValue(null)); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); + $a->addStream($s); + $this->assertNull($a->getSize()); + } + + public function testCatchesExceptionsWhenCastingToString() + { + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['read', 'isReadable', 'eof']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('read') + ->will($this->throwException(new \RuntimeException('foo'))); + $s->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(true)); + $s->expects($this->any()) + ->method('eof') + ->will($this->returnValue(false)); + $a = new AppendStream([$s]); + $this->assertFalse($a->eof()); + $this->assertSame('', (string) $a); + } + + public function testCanDetach() + { + $s = new AppendStream(); + $s->detach(); + } + + public function testReturnsEmptyMetadata() + { + $s = new AppendStream(); + $this->assertEquals([], $s->getMetadata()); + $this->assertNull($s->getMetadata('foo')); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException + */ + public function testCannotAttach() + { + $p = new AppendStream(); + $p->attach('a'); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/AsyncReadStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/AsyncReadStreamTest.php new file mode 100644 index 00000000..8c789959 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/AsyncReadStreamTest.php @@ -0,0 +1,186 @@ + function () { return false; }] + )); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Buffer must be readable and writable + */ + public function testValidatesWritableBuffer() + { + new AsyncReadStream(FnStream::decorate( + Stream::factory(), + ['isWritable' => function () { return false; }] + )); + } + + public function testValidatesHwmMetadata() + { + $a = new AsyncReadStream(Stream::factory(), [ + 'drain' => function() {} + ]); + $this->assertNull($this->readAttribute($a, 'drain')); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage pump must be callable + */ + public function testValidatesPumpIsCallable() + { + new AsyncReadStream(new BufferStream(), ['pump' => true]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage drain must be callable + */ + public function testValidatesDrainIsCallable() + { + new AsyncReadStream(new BufferStream(), ['drain' => true]); + } + + public function testCanInitialize() + { + $buffer = new BufferStream(); + $a = new AsyncReadStream($buffer, [ + 'size' => 10, + 'drain' => function () {}, + 'pump' => function () {}, + ]); + $this->assertSame($buffer, $this->readAttribute($a, 'stream')); + $this->assertTrue(is_callable($this->readAttribute($a, 'drain'))); + $this->assertTrue(is_callable($this->readAttribute($a, 'pump'))); + $this->assertTrue($a->isReadable()); + $this->assertFalse($a->isSeekable()); + $this->assertFalse($a->isWritable()); + $this->assertFalse($a->write('foo')); + $this->assertEquals(10, $a->getSize()); + } + + public function testReadsFromBufferWithNoDrainOrPump() + { + $buffer = new BufferStream(); + $a = new AsyncReadStream($buffer); + $buffer->write('foo'); + $this->assertNull($a->getSize()); + $this->assertEquals('foo', $a->read(10)); + $this->assertEquals('', $a->read(10)); + } + + public function testCallsPumpForMoreDataWhenRequested() + { + $called = 0; + $buffer = new BufferStream(); + $a = new AsyncReadStream($buffer, [ + 'pump' => function ($size) use (&$called) { + $called++; + return str_repeat('.', $size); + } + ]); + $buffer->write('foobar'); + $this->assertEquals('foo', $a->read(3)); + $this->assertEquals(0, $called); + $this->assertEquals('bar.....', $a->read(8)); + $this->assertEquals(1, $called); + $this->assertEquals('..', $a->read(2)); + $this->assertEquals(2, $called); + } + + public function testCallsDrainWhenNeeded() + { + $called = 0; + $buffer = new BufferStream(5); + $a = new AsyncReadStream($buffer, [ + 'drain' => function (BufferStream $b) use (&$called, $buffer) { + $this->assertSame($b, $buffer); + $called++; + } + ]); + + $buffer->write('foobar'); + $this->assertEquals(6, $buffer->getSize()); + $this->assertEquals(0, $called); + + $a->read(3); + $this->assertTrue($this->readAttribute($a, 'needsDrain')); + $this->assertEquals(3, $buffer->getSize()); + $this->assertEquals(0, $called); + + $a->read(3); + $this->assertEquals(0, $buffer->getSize()); + $this->assertFalse($this->readAttribute($a, 'needsDrain')); + $this->assertEquals(1, $called); + } + + public function testCreatesBufferWithNoConfig() + { + list($buffer, $async) = AsyncReadStream::create(); + $this->assertInstanceOf('GuzzleHttp\Stream\BufferStream', $buffer); + $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async); + } + + public function testCreatesBufferWithSpecifiedBuffer() + { + $buf = new BufferStream(); + list($buffer, $async) = AsyncReadStream::create(['buffer' => $buf]); + $this->assertSame($buf, $buffer); + $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async); + } + + public function testCreatesNullStream() + { + list($buffer, $async) = AsyncReadStream::create(['max_buffer' => 0]); + $this->assertInstanceOf('GuzzleHttp\Stream\NullStream', $buffer); + $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async); + } + + public function testCreatesDroppingStream() + { + list($buffer, $async) = AsyncReadStream::create(['max_buffer' => 5]); + $this->assertInstanceOf('GuzzleHttp\Stream\DroppingStream', $buffer); + $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async); + $buffer->write('12345678910'); + $this->assertEquals(5, $buffer->getSize()); + } + + public function testCreatesOnWriteStream() + { + $c = 0; + $b = new BufferStream(); + list($buffer, $async) = AsyncReadStream::create([ + 'buffer' => $b, + 'write' => function (BufferStream $buf, $data) use (&$c, $b) { + $this->assertSame($buf, $b); + $this->assertEquals('foo', $data); + $c++; + } + ]); + $this->assertInstanceOf('GuzzleHttp\Stream\FnStream', $buffer); + $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async); + $this->assertEquals(0, $c); + $this->assertEquals(3, $buffer->write('foo')); + $this->assertEquals(1, $c); + $this->assertEquals(3, $buffer->write('foo')); + $this->assertEquals(2, $c); + $this->assertEquals('foofoo', (string) $buffer); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/BufferStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/BufferStreamTest.php new file mode 100644 index 00000000..f9bfea21 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/BufferStreamTest.php @@ -0,0 +1,69 @@ +assertTrue($b->isReadable()); + $this->assertTrue($b->isWritable()); + $this->assertFalse($b->isSeekable()); + $this->assertEquals(null, $b->getMetadata('foo')); + $this->assertEquals(10, $b->getMetadata('hwm')); + $this->assertEquals([], $b->getMetadata()); + } + + public function testRemovesReadDataFromBuffer() + { + $b = new BufferStream(); + $this->assertEquals(3, $b->write('foo')); + $this->assertEquals(3, $b->getSize()); + $this->assertFalse($b->eof()); + $this->assertEquals('foo', $b->read(10)); + $this->assertTrue($b->eof()); + $this->assertEquals('', $b->read(10)); + } + + public function testCanCastToStringOrGetContents() + { + $b = new BufferStream(); + $b->write('foo'); + $b->write('baz'); + $this->assertEquals('foo', $b->read(3)); + $b->write('bar'); + $this->assertEquals('bazbar', (string) $b); + $this->assertFalse($b->tell()); + } + + public function testDetachClearsBuffer() + { + $b = new BufferStream(); + $b->write('foo'); + $b->detach(); + $this->assertEquals(0, $b->tell()); + $this->assertTrue($b->eof()); + $this->assertEquals(3, $b->write('abc')); + $this->assertEquals('abc', $b->read(10)); + } + + public function testExceedingHighwaterMarkReturnsFalseButStillBuffers() + { + $b = new BufferStream(5); + $this->assertEquals(3, $b->write('hi ')); + $this->assertFalse($b->write('hello')); + $this->assertEquals('hi hello', (string) $b); + $this->assertEquals(4, $b->write('test')); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException + */ + public function testCannotAttach() + { + $p = new BufferStream(); + $p->attach('a'); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/CachingStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/CachingStreamTest.php new file mode 100644 index 00000000..ea969b3a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/CachingStreamTest.php @@ -0,0 +1,136 @@ +decorated = Stream::factory('testing'); + $this->body = new CachingStream($this->decorated); + } + + public function tearDown() + { + $this->decorated->close(); + $this->body->close(); + } + + public function testUsesRemoteSizeIfPossible() + { + $body = Stream::factory('test'); + $caching = new CachingStream($body); + $this->assertEquals(4, $caching->getSize()); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Cannot seek to byte 10 + */ + public function testCannotSeekPastWhatHasBeenRead() + { + $this->body->seek(10); + } + + public function testCannotUseSeekEnd() + { + $this->assertFalse($this->body->seek(2, SEEK_END)); + } + + public function testRewindUsesSeek() + { + $a = Stream::factory('foo'); + $d = $this->getMockBuilder('GuzzleHttp\Stream\CachingStream') + ->setMethods(array('seek')) + ->setConstructorArgs(array($a)) + ->getMock(); + $d->expects($this->once()) + ->method('seek') + ->with(0) + ->will($this->returnValue(true)); + $d->seek(0); + } + + public function testCanSeekToReadBytes() + { + $this->assertEquals('te', $this->body->read(2)); + $this->body->seek(0); + $this->assertEquals('test', $this->body->read(4)); + $this->assertEquals(4, $this->body->tell()); + $this->body->seek(2); + $this->assertEquals(2, $this->body->tell()); + $this->body->seek(2, SEEK_CUR); + $this->assertEquals(4, $this->body->tell()); + $this->assertEquals('ing', $this->body->read(3)); + } + + public function testWritesToBufferStream() + { + $this->body->read(2); + $this->body->write('hi'); + $this->body->seek(0); + $this->assertEquals('tehiing', (string) $this->body); + } + + public function testSkipsOverwrittenBytes() + { + $decorated = Stream::factory( + implode("\n", array_map(function ($n) { + return str_pad($n, 4, '0', STR_PAD_LEFT); + }, range(0, 25))) + ); + + $body = new CachingStream($decorated); + + $this->assertEquals("0000\n", Utils::readline($body)); + $this->assertEquals("0001\n", Utils::readline($body)); + // Write over part of the body yet to be read, so skip some bytes + $this->assertEquals(5, $body->write("TEST\n")); + $this->assertEquals(5, $this->readAttribute($body, 'skipReadBytes')); + // Read, which skips bytes, then reads + $this->assertEquals("0003\n", Utils::readline($body)); + $this->assertEquals(0, $this->readAttribute($body, 'skipReadBytes')); + $this->assertEquals("0004\n", Utils::readline($body)); + $this->assertEquals("0005\n", Utils::readline($body)); + + // Overwrite part of the cached body (so don't skip any bytes) + $body->seek(5); + $this->assertEquals(5, $body->write("ABCD\n")); + $this->assertEquals(0, $this->readAttribute($body, 'skipReadBytes')); + $this->assertEquals("TEST\n", Utils::readline($body)); + $this->assertEquals("0003\n", Utils::readline($body)); + $this->assertEquals("0004\n", Utils::readline($body)); + $this->assertEquals("0005\n", Utils::readline($body)); + $this->assertEquals("0006\n", Utils::readline($body)); + $this->assertEquals(5, $body->write("1234\n")); + $this->assertEquals(5, $this->readAttribute($body, 'skipReadBytes')); + + // Seek to 0 and ensure the overwritten bit is replaced + $body->seek(0); + $this->assertEquals("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", $body->read(50)); + + // Ensure that casting it to a string does not include the bit that was overwritten + $this->assertContains("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", (string) $body); + } + + public function testClosesBothStreams() + { + $s = fopen('php://temp', 'r'); + $a = Stream::factory($s); + $d = new CachingStream($a); + $d->close(); + $this->assertFalse(is_resource($s)); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/DroppingStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/DroppingStreamTest.php new file mode 100644 index 00000000..bb2cb220 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/DroppingStreamTest.php @@ -0,0 +1,26 @@ +assertEquals(3, $drop->write('hel')); + $this->assertFalse($drop->write('lo')); + $this->assertEquals(5, $drop->getSize()); + $this->assertEquals('hello', $drop->read(5)); + $this->assertEquals(0, $drop->getSize()); + $drop->write('12345678910'); + $this->assertEquals(5, $stream->getSize()); + $this->assertEquals(5, $drop->getSize()); + $this->assertEquals('12345', (string) $drop); + $this->assertEquals(0, $drop->getSize()); + $drop->write('hello'); + $this->assertFalse($drop->write('test')); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/Exception/SeekExceptionTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/Exception/SeekExceptionTest.php new file mode 100644 index 00000000..fd8cd1ad --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/Exception/SeekExceptionTest.php @@ -0,0 +1,16 @@ +assertSame($s, $e->getStream()); + $this->assertContains('10', $e->getMessage()); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/FnStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/FnStreamTest.php new file mode 100644 index 00000000..6cc336b9 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/FnStreamTest.php @@ -0,0 +1,89 @@ +seek(1); + } + + public function testProxiesToFunction() + { + $s = new FnStream([ + 'read' => function ($len) { + $this->assertEquals(3, $len); + return 'foo'; + } + ]); + + $this->assertEquals('foo', $s->read(3)); + } + + public function testCanCloseOnDestruct() + { + $called = false; + $s = new FnStream([ + 'close' => function () use (&$called) { + $called = true; + } + ]); + unset($s); + $this->assertTrue($called); + } + + public function testDoesNotRequireClose() + { + $s = new FnStream([]); + unset($s); + } + + public function testDecoratesStream() + { + $a = Stream::factory('foo'); + $b = FnStream::decorate($a, []); + $this->assertEquals(3, $b->getSize()); + $this->assertEquals($b->isWritable(), true); + $this->assertEquals($b->isReadable(), true); + $this->assertEquals($b->isSeekable(), true); + $this->assertEquals($b->read(3), 'foo'); + $this->assertEquals($b->tell(), 3); + $this->assertEquals($a->tell(), 3); + $this->assertEquals($b->eof(), true); + $this->assertEquals($a->eof(), true); + $b->seek(0); + $this->assertEquals('foo', (string) $b); + $b->seek(0); + $this->assertEquals('foo', $b->getContents()); + $this->assertEquals($a->getMetadata(), $b->getMetadata()); + $b->seek(0, SEEK_END); + $b->write('bar'); + $this->assertEquals('foobar', (string) $b); + $this->assertInternalType('resource', $b->detach()); + $b->close(); + } + + public function testDecoratesWithCustomizations() + { + $called = false; + $a = Stream::factory('foo'); + $b = FnStream::decorate($a, [ + 'read' => function ($len) use (&$called, $a) { + $called = true; + return $a->read($len); + } + ]); + $this->assertEquals('foo', $b->read(3)); + $this->assertTrue($called); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php new file mode 100644 index 00000000..33c3eccb --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php @@ -0,0 +1,99 @@ +assertSame('foo', fread($handle, 3)); + $this->assertSame(3, ftell($handle)); + $this->assertSame(3, fwrite($handle, 'bar')); + $this->assertSame(0, fseek($handle, 0)); + $this->assertSame('foobar', fread($handle, 6)); + $this->assertTrue(feof($handle)); + + // This fails on HHVM for some reason + if (!defined('HHVM_VERSION')) { + $this->assertEquals([ + 'dev' => 0, + 'ino' => 0, + 'mode' => 33206, + 'nlink' => 0, + 'uid' => 0, + 'gid' => 0, + 'rdev' => 0, + 'size' => 6, + 'atime' => 0, + 'mtime' => 0, + 'ctime' => 0, + 'blksize' => 0, + 'blocks' => 0, + 0 => 0, + 1 => 0, + 2 => 33206, + 3 => 0, + 4 => 0, + 5 => 0, + 6 => 0, + 7 => 6, + 8 => 0, + 9 => 0, + 10 => 0, + 11 => 0, + 12 => 0, + ], fstat($handle)); + } + + $this->assertTrue(fclose($handle)); + $this->assertSame('foobar', (string) $stream); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testValidatesStream() + { + $stream = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable', 'isWritable']) + ->getMockForAbstractClass(); + $stream->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(false)); + $stream->expects($this->once()) + ->method('isWritable') + ->will($this->returnValue(false)); + GuzzleStreamWrapper::getResource($stream); + } + + /** + * @expectedException \PHPUnit_Framework_Error_Warning + */ + public function testReturnsFalseWhenStreamDoesNotExist() + { + fopen('guzzle://foo', 'r'); + } + + public function testCanOpenReadonlyStream() + { + $stream = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isReadable', 'isWritable']) + ->getMockForAbstractClass(); + $stream->expects($this->once()) + ->method('isReadable') + ->will($this->returnValue(false)); + $stream->expects($this->once()) + ->method('isWritable') + ->will($this->returnValue(true)); + $r = GuzzleStreamWrapper::getResource($stream); + $this->assertInternalType('resource', $r); + fclose($r); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/InflateStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/InflateStreamTest.php new file mode 100644 index 00000000..ead9356a --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/InflateStreamTest.php @@ -0,0 +1,16 @@ +assertEquals('test', (string) $b); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/LazyOpenStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/LazyOpenStreamTest.php new file mode 100644 index 00000000..79e0078e --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/LazyOpenStreamTest.php @@ -0,0 +1,64 @@ +fname = tempnam('/tmp', 'tfile'); + + if (file_exists($this->fname)) { + unlink($this->fname); + } + } + + public function tearDown() + { + if (file_exists($this->fname)) { + unlink($this->fname); + } + } + + public function testOpensLazily() + { + $l = new LazyOpenStream($this->fname, 'w+'); + $l->write('foo'); + $this->assertInternalType('array', $l->getMetadata()); + $this->assertFileExists($this->fname); + $this->assertEquals('foo', file_get_contents($this->fname)); + $this->assertEquals('foo', (string) $l); + } + + public function testProxiesToFile() + { + file_put_contents($this->fname, 'foo'); + $l = new LazyOpenStream($this->fname, 'r'); + $this->assertEquals('foo', $l->read(4)); + $this->assertTrue($l->eof()); + $this->assertEquals(3, $l->tell()); + $this->assertTrue($l->isReadable()); + $this->assertTrue($l->isSeekable()); + $this->assertFalse($l->isWritable()); + $l->seek(1); + $this->assertEquals('oo', $l->getContents()); + $this->assertEquals('foo', (string) $l); + $this->assertEquals(3, $l->getSize()); + $this->assertInternalType('array', $l->getMetadata()); + $l->close(); + } + + public function testDetachesUnderlyingStream() + { + file_put_contents($this->fname, 'foo'); + $l = new LazyOpenStream($this->fname, 'r'); + $r = $l->detach(); + $this->assertInternalType('resource', $r); + fseek($r, 0); + $this->assertEquals('foo', stream_get_contents($r)); + fclose($r); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/LimitStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/LimitStreamTest.php new file mode 100644 index 00000000..efb1dc58 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/LimitStreamTest.php @@ -0,0 +1,133 @@ +decorated = Stream::factory(fopen(__FILE__, 'r')); + $this->body = new LimitStream($this->decorated, 10, 3); + } + + public function testReturnsSubset() + { + $body = new LimitStream(Stream::factory('foo'), -1, 1); + $this->assertEquals('oo', (string) $body); + $this->assertTrue($body->eof()); + $body->seek(0); + $this->assertFalse($body->eof()); + $this->assertEquals('oo', $body->read(100)); + $this->assertTrue($body->eof()); + } + + public function testReturnsSubsetWhenCastToString() + { + $body = Stream::factory('foo_baz_bar'); + $limited = new LimitStream($body, 3, 4); + $this->assertEquals('baz', (string) $limited); + } + + public function testReturnsSubsetOfEmptyBodyWhenCastToString() + { + $body = Stream::factory(''); + $limited = new LimitStream($body, 0, 10); + $this->assertEquals('', (string) $limited); + } + + public function testSeeksWhenConstructed() + { + $this->assertEquals(0, $this->body->tell()); + $this->assertEquals(3, $this->decorated->tell()); + } + + public function testAllowsBoundedSeek() + { + $this->assertEquals(true, $this->body->seek(100)); + $this->assertEquals(10, $this->body->tell()); + $this->assertEquals(13, $this->decorated->tell()); + $this->assertEquals(true, $this->body->seek(0)); + $this->assertEquals(0, $this->body->tell()); + $this->assertEquals(3, $this->decorated->tell()); + $this->assertEquals(false, $this->body->seek(-10)); + $this->assertEquals(0, $this->body->tell()); + $this->assertEquals(3, $this->decorated->tell()); + $this->assertEquals(true, $this->body->seek(5)); + $this->assertEquals(5, $this->body->tell()); + $this->assertEquals(8, $this->decorated->tell()); + $this->assertEquals(false, $this->body->seek(1000, SEEK_END)); + } + + public function testReadsOnlySubsetOfData() + { + $data = $this->body->read(100); + $this->assertEquals(10, strlen($data)); + $this->assertFalse($this->body->read(1000)); + + $this->body->setOffset(10); + $newData = $this->body->read(100); + $this->assertEquals(10, strlen($newData)); + $this->assertNotSame($data, $newData); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\SeekException + * @expectedExceptionMessage Could not seek the stream to position 2 + */ + public function testThrowsWhenCurrentGreaterThanOffsetSeek() + { + $a = Stream::factory('foo_bar'); + $b = new NoSeekStream($a); + $c = new LimitStream($b); + $a->getContents(); + $c->setOffset(2); + } + + public function testClaimsConsumedWhenReadLimitIsReached() + { + $this->assertFalse($this->body->eof()); + $this->body->read(1000); + $this->assertTrue($this->body->eof()); + } + + public function testContentLengthIsBounded() + { + $this->assertEquals(10, $this->body->getSize()); + } + + public function testGetContentsIsBasedOnSubset() + { + $body = new LimitStream(Stream::factory('foobazbar'), 3, 3); + $this->assertEquals('baz', $body->getContents()); + } + + public function testReturnsNullIfSizeCannotBeDetermined() + { + $a = new FnStream([ + 'getSize' => function () { return null; }, + 'tell' => function () { return 0; }, + ]); + $b = new LimitStream($a); + $this->assertNull($b->getSize()); + } + + public function testLengthLessOffsetWhenNoLimitSize() + { + $a = Stream::factory('foo_bar'); + $b = new LimitStream($a, -1, 4); + $this->assertEquals(3, $b->getSize()); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/NoSeekStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/NoSeekStreamTest.php new file mode 100644 index 00000000..21b7c6d2 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/NoSeekStreamTest.php @@ -0,0 +1,41 @@ +getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['isSeekable', 'seek']) + ->getMockForAbstractClass(); + $s->expects($this->never())->method('seek'); + $s->expects($this->never())->method('isSeekable'); + $wrapped = new NoSeekStream($s); + $this->assertFalse($wrapped->isSeekable()); + $this->assertFalse($wrapped->seek(2)); + } + + public function testHandlesClose() + { + $s = Stream::factory('foo'); + $wrapped = new NoSeekStream($s); + $wrapped->close(); + $this->assertFalse($wrapped->write('foo')); + } + + public function testCanAttach() + { + $s1 = Stream::factory('foo'); + $s2 = Stream::factory('bar'); + $wrapped = new NoSeekStream($s1); + $wrapped->attach($s2->detach()); + $this->assertEquals('bar', (string) $wrapped); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/NullStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/NullStreamTest.php new file mode 100644 index 00000000..8e414315 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/NullStreamTest.php @@ -0,0 +1,39 @@ +assertEquals('', $b->read(10)); + $this->assertEquals(4, $b->write('test')); + $this->assertEquals('', (string) $b); + $this->assertNull($b->getMetadata('a')); + $this->assertEquals([], $b->getMetadata()); + $this->assertEquals(0, $b->getSize()); + $this->assertEquals('', $b->getContents()); + $this->assertEquals(0, $b->tell()); + + $this->assertTrue($b->isReadable()); + $this->assertTrue($b->isWritable()); + $this->assertTrue($b->isSeekable()); + $this->assertFalse($b->seek(10)); + + $this->assertTrue($b->eof()); + $b->detach(); + $this->assertTrue($b->eof()); + $b->close(); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException + */ + public function testCannotAttach() + { + $p = new NullStream(); + $p->attach('a'); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/PumpStreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/PumpStreamTest.php new file mode 100644 index 00000000..2d20ce90 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/PumpStreamTest.php @@ -0,0 +1,77 @@ + ['foo' => 'bar'], + 'size' => 100 + ]); + + $this->assertEquals('bar', $p->getMetadata('foo')); + $this->assertEquals(['foo' => 'bar'], $p->getMetadata()); + $this->assertEquals(100, $p->getSize()); + } + + public function testCanReadFromCallable() + { + $p = Stream::factory(function ($size) { + return 'a'; + }); + $this->assertEquals('a', $p->read(1)); + $this->assertEquals(1, $p->tell()); + $this->assertEquals('aaaaa', $p->read(5)); + $this->assertEquals(6, $p->tell()); + } + + public function testStoresExcessDataInBuffer() + { + $called = []; + $p = Stream::factory(function ($size) use (&$called) { + $called[] = $size; + return 'abcdef'; + }); + $this->assertEquals('a', $p->read(1)); + $this->assertEquals('b', $p->read(1)); + $this->assertEquals('cdef', $p->read(4)); + $this->assertEquals('abcdefabc', $p->read(9)); + $this->assertEquals([1, 9, 3], $called); + } + + public function testInifiniteStreamWrappedInLimitStream() + { + $p = Stream::factory(function () { return 'a'; }); + $s = new LimitStream($p, 5); + $this->assertEquals('aaaaa', (string) $s); + } + + public function testDescribesCapabilities() + { + $p = Stream::factory(function () {}); + $this->assertTrue($p->isReadable()); + $this->assertFalse($p->isSeekable()); + $this->assertFalse($p->isWritable()); + $this->assertNull($p->getSize()); + $this->assertFalse($p->write('aa')); + $this->assertEquals('', $p->getContents()); + $this->assertEquals('', (string) $p); + $p->close(); + $this->assertEquals('', $p->read(10)); + $this->assertTrue($p->eof()); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException + */ + public function testCannotAttach() + { + $p = Stream::factory(function () {}); + $p->attach('a'); + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/StreamDecoratorTraitTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/StreamDecoratorTraitTest.php new file mode 100644 index 00000000..2ba79add --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/StreamDecoratorTraitTest.php @@ -0,0 +1,147 @@ +c = fopen('php://temp', 'r+'); + fwrite($this->c, 'foo'); + fseek($this->c, 0); + $this->a = Stream::factory($this->c); + $this->b = new Str($this->a); + } + + public function testCatchesExceptionsWhenCastingToString() + { + $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface') + ->setMethods(['read']) + ->getMockForAbstractClass(); + $s->expects($this->once()) + ->method('read') + ->will($this->throwException(new \Exception('foo'))); + $msg = ''; + set_error_handler(function ($errNo, $str) use (&$msg) { $msg = $str; }); + echo new Str($s); + restore_error_handler(); + $this->assertContains('foo', $msg); + } + + public function testToString() + { + $this->assertEquals('foo', (string) $this->b); + } + + public function testHasSize() + { + $this->assertEquals(3, $this->b->getSize()); + $this->assertSame($this->b, $this->b->setSize(2)); + $this->assertEquals(2, $this->b->getSize()); + } + + public function testReads() + { + $this->assertEquals('foo', $this->b->read(10)); + } + + public function testCheckMethods() + { + $this->assertEquals($this->a->isReadable(), $this->b->isReadable()); + $this->assertEquals($this->a->isWritable(), $this->b->isWritable()); + $this->assertEquals($this->a->isSeekable(), $this->b->isSeekable()); + } + + public function testSeeksAndTells() + { + $this->assertTrue($this->b->seek(1)); + $this->assertEquals(1, $this->a->tell()); + $this->assertEquals(1, $this->b->tell()); + $this->assertTrue($this->b->seek(0)); + $this->assertEquals(0, $this->a->tell()); + $this->assertEquals(0, $this->b->tell()); + $this->assertTrue($this->b->seek(0, SEEK_END)); + $this->assertEquals(3, $this->a->tell()); + $this->assertEquals(3, $this->b->tell()); + } + + public function testGetsContents() + { + $this->assertEquals('foo', $this->b->getContents()); + $this->assertEquals('', $this->b->getContents()); + $this->b->seek(1); + $this->assertEquals('oo', $this->b->getContents(1)); + } + + public function testCloses() + { + $this->b->close(); + $this->assertFalse(is_resource($this->c)); + } + + public function testDetaches() + { + $this->b->detach(); + $this->assertFalse($this->b->isReadable()); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException + */ + public function testCannotAttachByDefault() + { + $this->b->attach('a'); + } + + public function testWrapsMetadata() + { + $this->assertSame($this->b->getMetadata(), $this->a->getMetadata()); + $this->assertSame($this->b->getMetadata('uri'), $this->a->getMetadata('uri')); + } + + public function testWrapsWrites() + { + $this->b->seek(0, SEEK_END); + $this->b->write('foo'); + $this->assertEquals('foofoo', (string) $this->a); + } + + /** + * @expectedException \UnexpectedValueException + */ + public function testThrowsWithInvalidGetter() + { + $this->b->foo; + } + + /** + * @expectedException \BadMethodCallException + */ + public function testThrowsWhenGetterNotImplemented() + { + $s = new BadStream(); + $s->stream; + } +} + +class BadStream +{ + use StreamDecoratorTrait; + + public function __construct() {} +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/StreamTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/StreamTest.php new file mode 100644 index 00000000..2985bfbb --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/StreamTest.php @@ -0,0 +1,252 @@ +assertTrue($stream->isReadable()); + $this->assertTrue($stream->isWritable()); + $this->assertTrue($stream->isSeekable()); + $this->assertEquals('php://temp', $stream->getMetadata('uri')); + $this->assertInternalType('array', $stream->getMetadata()); + $this->assertEquals(4, $stream->getSize()); + $this->assertFalse($stream->eof()); + $stream->close(); + } + + public function testStreamClosesHandleOnDestruct() + { + $handle = fopen('php://temp', 'r'); + $stream = new Stream($handle); + unset($stream); + $this->assertFalse(is_resource($handle)); + } + + public function testConvertsToString() + { + $handle = fopen('php://temp', 'w+'); + fwrite($handle, 'data'); + $stream = new Stream($handle); + $this->assertEquals('data', (string) $stream); + $this->assertEquals('data', (string) $stream); + $stream->close(); + } + + public function testGetsContents() + { + $handle = fopen('php://temp', 'w+'); + fwrite($handle, 'data'); + $stream = new Stream($handle); + $this->assertEquals('', $stream->getContents()); + $stream->seek(0); + $this->assertEquals('data', $stream->getContents()); + $this->assertEquals('', $stream->getContents()); + } + + public function testChecksEof() + { + $handle = fopen('php://temp', 'w+'); + fwrite($handle, 'data'); + $stream = new Stream($handle); + $this->assertFalse($stream->eof()); + $stream->read(4); + $this->assertTrue($stream->eof()); + $stream->close(); + } + + public function testAllowsSettingManualSize() + { + $handle = fopen('php://temp', 'w+'); + fwrite($handle, 'data'); + $stream = new Stream($handle); + $stream->setSize(10); + $this->assertEquals(10, $stream->getSize()); + $stream->close(); + } + + public function testGetSize() + { + $size = filesize(__FILE__); + $handle = fopen(__FILE__, 'r'); + $stream = new Stream($handle); + $this->assertEquals($size, $stream->getSize()); + // Load from cache + $this->assertEquals($size, $stream->getSize()); + $stream->close(); + } + + public function testEnsuresSizeIsConsistent() + { + $h = fopen('php://temp', 'w+'); + $this->assertEquals(3, fwrite($h, 'foo')); + $stream = new Stream($h); + $this->assertEquals(3, $stream->getSize()); + $this->assertEquals(4, $stream->write('test')); + $this->assertEquals(7, $stream->getSize()); + $this->assertEquals(7, $stream->getSize()); + $stream->close(); + } + + public function testProvidesStreamPosition() + { + $handle = fopen('php://temp', 'w+'); + $stream = new Stream($handle); + $this->assertEquals(0, $stream->tell()); + $stream->write('foo'); + $this->assertEquals(3, $stream->tell()); + $stream->seek(1); + $this->assertEquals(1, $stream->tell()); + $this->assertSame(ftell($handle), $stream->tell()); + $stream->close(); + } + + public function testKeepsPositionOfResource() + { + $h = fopen(__FILE__, 'r'); + fseek($h, 10); + $stream = Stream::factory($h); + $this->assertEquals(10, $stream->tell()); + $stream->close(); + } + + public function testCanDetachAndAttachStream() + { + $r = fopen('php://temp', 'w+'); + $stream = new Stream($r); + $stream->write('foo'); + $this->assertTrue($stream->isReadable()); + $this->assertSame($r, $stream->detach()); + $this->assertNull($stream->detach()); + + $this->assertFalse($stream->isReadable()); + $this->assertFalse($stream->read(10)); + $this->assertFalse($stream->isWritable()); + $this->assertFalse($stream->write('bar')); + $this->assertFalse($stream->isSeekable()); + $this->assertFalse($stream->seek(10)); + $this->assertFalse($stream->tell()); + $this->assertTrue($stream->eof()); + $this->assertNull($stream->getSize()); + $this->assertSame('', (string) $stream); + $this->assertSame('', $stream->getContents()); + + $stream->attach($r); + $stream->seek(0); + $this->assertEquals('foo', $stream->getContents()); + $this->assertTrue($stream->isReadable()); + $this->assertTrue($stream->isWritable()); + $this->assertTrue($stream->isSeekable()); + + $stream->close(); + } + + public function testCloseClearProperties() + { + $handle = fopen('php://temp', 'r+'); + $stream = new Stream($handle); + $stream->close(); + + $this->assertEmpty($stream->getMetadata()); + $this->assertFalse($stream->isSeekable()); + $this->assertFalse($stream->isReadable()); + $this->assertFalse($stream->isWritable()); + $this->assertNull($stream->getSize()); + } + + public function testCreatesWithFactory() + { + $stream = Stream::factory('foo'); + $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $stream); + $this->assertEquals('foo', $stream->getContents()); + $stream->close(); + } + + public function testFactoryCreatesFromEmptyString() + { + $s = Stream::factory(); + $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s); + } + + public function testFactoryCreatesFromResource() + { + $r = fopen(__FILE__, 'r'); + $s = Stream::factory($r); + $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s); + $this->assertSame(file_get_contents(__FILE__), (string) $s); + } + + public function testFactoryCreatesFromObjectWithToString() + { + $r = new HasToString(); + $s = Stream::factory($r); + $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s); + $this->assertEquals('foo', (string) $s); + } + + public function testCreatePassesThrough() + { + $s = Stream::factory('foo'); + $this->assertSame($s, Stream::factory($s)); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testThrowsExceptionForUnknown() + { + Stream::factory(new \stdClass()); + } + + public function testReturnsCustomMetadata() + { + $s = Stream::factory('foo', ['metadata' => ['hwm' => 3]]); + $this->assertEquals(3, $s->getMetadata('hwm')); + $this->assertArrayHasKey('hwm', $s->getMetadata()); + } + + public function testCanSetSize() + { + $s = Stream::factory('', ['size' => 10]); + $this->assertEquals(10, $s->getSize()); + } + + public function testCanCreateIteratorBasedStream() + { + $a = new \ArrayIterator(['foo', 'bar', '123']); + $p = Stream::factory($a); + $this->assertInstanceOf('GuzzleHttp\Stream\PumpStream', $p); + $this->assertEquals('foo', $p->read(3)); + $this->assertFalse($p->eof()); + $this->assertEquals('b', $p->read(1)); + $this->assertEquals('a', $p->read(1)); + $this->assertEquals('r12', $p->read(3)); + $this->assertFalse($p->eof()); + $this->assertEquals('3', $p->getContents()); + $this->assertTrue($p->eof()); + $this->assertEquals(9, $p->tell()); + } +} + +class HasToString +{ + public function __toString() { + return 'foo'; + } +} diff --git a/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/UtilsTest.php b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/UtilsTest.php new file mode 100644 index 00000000..6e3e3b21 --- /dev/null +++ b/modules/empikmarketplace/vendor/guzzlehttp/streams/tests/UtilsTest.php @@ -0,0 +1,155 @@ +assertEquals('foobaz', Utils::copyToString($s)); + $s->seek(0); + $this->assertEquals('foo', Utils::copyToString($s, 3)); + $this->assertEquals('baz', Utils::copyToString($s, 3)); + $this->assertEquals('', Utils::copyToString($s)); + } + + public function testCopiesToStringStopsWhenReadFails() + { + $s1 = Stream::factory('foobaz'); + $s1 = FnStream::decorate($s1, [ + 'read' => function () { + return false; + } + ]); + $result = Utils::copyToString($s1); + $this->assertEquals('', $result); + } + + public function testCopiesToStream() + { + $s1 = Stream::factory('foobaz'); + $s2 = Stream::factory(''); + Utils::copyToStream($s1, $s2); + $this->assertEquals('foobaz', (string) $s2); + $s2 = Stream::factory(''); + $s1->seek(0); + Utils::copyToStream($s1, $s2, 3); + $this->assertEquals('foo', (string) $s2); + Utils::copyToStream($s1, $s2, 3); + $this->assertEquals('foobaz', (string) $s2); + } + + public function testStopsCopyToStreamWhenWriteFails() + { + $s1 = Stream::factory('foobaz'); + $s2 = Stream::factory(''); + $s2 = FnStream::decorate($s2, ['write' => function () { return 0; }]); + Utils::copyToStream($s1, $s2); + $this->assertEquals('', (string) $s2); + } + + public function testStopsCopyToSteamWhenWriteFailsWithMaxLen() + { + $s1 = Stream::factory('foobaz'); + $s2 = Stream::factory(''); + $s2 = FnStream::decorate($s2, ['write' => function () { return 0; }]); + Utils::copyToStream($s1, $s2, 10); + $this->assertEquals('', (string) $s2); + } + + public function testStopsCopyToSteamWhenReadFailsWithMaxLen() + { + $s1 = Stream::factory('foobaz'); + $s1 = FnStream::decorate($s1, ['read' => function () { return ''; }]); + $s2 = Stream::factory(''); + Utils::copyToStream($s1, $s2, 10); + $this->assertEquals('', (string) $s2); + } + + public function testReadsLines() + { + $s = Stream::factory("foo\nbaz\nbar"); + $this->assertEquals("foo\n", Utils::readline($s)); + $this->assertEquals("baz\n", Utils::readline($s)); + $this->assertEquals("bar", Utils::readline($s)); + } + + public function testReadsLinesUpToMaxLength() + { + $s = Stream::factory("12345\n"); + $this->assertEquals("123", Utils::readline($s, 4)); + $this->assertEquals("45\n", Utils::readline($s)); + } + + public function testReadsLineUntilFalseReturnedFromRead() + { + $s = $this->getMockBuilder('GuzzleHttp\Stream\Stream') + ->setMethods(['read', 'eof']) + ->disableOriginalConstructor() + ->getMock(); + $s->expects($this->exactly(2)) + ->method('read') + ->will($this->returnCallback(function () { + static $c = false; + if ($c) { + return false; + } + $c = true; + return 'h'; + })); + $s->expects($this->exactly(2)) + ->method('eof') + ->will($this->returnValue(false)); + $this->assertEquals("h", Utils::readline($s)); + } + + public function testCalculatesHash() + { + $s = Stream::factory('foobazbar'); + $this->assertEquals(md5('foobazbar'), Utils::hash($s, 'md5')); + } + + /** + * @expectedException \GuzzleHttp\Stream\Exception\SeekException + */ + public function testCalculatesHashThrowsWhenSeekFails() + { + $s = new NoSeekStream(Stream::factory('foobazbar')); + $s->read(2); + Utils::hash($s, 'md5'); + } + + public function testCalculatesHashSeeksToOriginalPosition() + { + $s = Stream::factory('foobazbar'); + $s->seek(4); + $this->assertEquals(md5('foobazbar'), Utils::hash($s, 'md5')); + $this->assertEquals(4, $s->tell()); + } + + public function testOpensFilesSuccessfully() + { + $r = Utils::open(__FILE__, 'r'); + $this->assertInternalType('resource', $r); + fclose($r); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Unable to open /path/to/does/not/exist using mode r + */ + public function testThrowsExceptionNotWarning() + { + Utils::open('/path/to/does/not/exist', 'r'); + } + + public function testProxiesToFactory() + { + $this->assertEquals('foo', (string) Utils::create('foo')); + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/.github/workflows/ci.yml b/modules/empikmarketplace/vendor/paragonie/random_compat/.github/workflows/ci.yml new file mode 100644 index 00000000..642d8ea9 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/.github/workflows/ci.yml @@ -0,0 +1,102 @@ +name: CI + +on: [push] + +jobs: + old: + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: ['ubuntu-16.04'] + php-versions: ['5.3', '5.4', '5.5', '5.6', '7.0'] + phpunit-versions: ['7.5.20'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl + ini-values: post_max_size=256M, max_execution_time=180 + tools: psalm, phpunit:${{ matrix.phpunit-versions }} + + - name: Install dependencies + run: composer self-update --1; composer install + + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + with: + memory_limit: 256M + + moderate: + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: ['ubuntu-latest'] + php-versions: ['7.1', '7.2', '7.3'] + phpunit-versions: ['latest'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl, sodium + ini-values: post_max_size=256M, max_execution_time=180 + tools: psalm, phpunit:${{ matrix.phpunit-versions }} + + - name: Install dependencies + run: composer install + + - name: Modernize dependencies + run: composer require --dev "phpunit/phpunit:>=4" + + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + timeout-minutes: 30 + with: + memory_limit: 256M + + modern: + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: ['ubuntu-latest'] + php-versions: ['7.4', '8.0'] + phpunit-versions: ['latest'] + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl, sodium + ini-values: post_max_size=256M, max_execution_time=180 + tools: psalm, phpunit:${{ matrix.phpunit-versions }} + + - name: Install dependencies + run: composer install + + - name: Modernize dependencies + run: composer require --dev "phpunit/phpunit:>=4" + + - name: PHPUnit tests + uses: php-actions/phpunit@v2 + timeout-minutes: 30 + with: + memory_limit: 256M + + - name: Install Psalm + run: rm composer.lock && composer require --dev vimeo/psalm:^4 + + - name: Static Analysis + run: vendor/bin/psalm diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/LICENSE b/modules/empikmarketplace/vendor/paragonie/random_compat/LICENSE new file mode 100644 index 00000000..45c7017d --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/composer.json b/modules/empikmarketplace/vendor/paragonie/random_compat/composer.json new file mode 100644 index 00000000..794e7fea --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/composer.json @@ -0,0 +1,38 @@ +{ + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "polyfill", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "autoload": { + "files": [ + "lib/random.php" + ] + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/modules/empikmarketplace/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey new file mode 100644 index 00000000..eb50ebfc --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm +pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p ++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc +-----END PUBLIC KEY----- diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/modules/empikmarketplace/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc new file mode 100644 index 00000000..6a1d7f30 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (MingW32) + +iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip +QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg +1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW +NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA +NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV +JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= +=B6+8 +-----END PGP SIGNATURE----- diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/byte_safe_strings.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/byte_safe_strings.php new file mode 100644 index 00000000..ef24488f --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/byte_safe_strings.php @@ -0,0 +1,195 @@ + RandomCompat_strlen($binary_string)) { + return ''; + } + + return (string) mb_substr( + (string) $binary_string, + (int) $start, + (int) $length, + '8bit' + ); + } + + } else { + + /** + * substr() implementation that isn't brittle to mbstring.func_overload + * + * This version just uses the default substr() + * + * @param string $binary_string + * @param int $start + * @param int|null $length (optional) + * + * @throws TypeError + * + * @return string + */ + function RandomCompat_substr($binary_string, $start, $length = null) + { + if (!is_string($binary_string)) { + throw new TypeError( + 'RandomCompat_substr(): First argument should be a string' + ); + } + + if (!is_int($start)) { + throw new TypeError( + 'RandomCompat_substr(): Second argument should be an integer' + ); + } + + if ($length !== null) { + if (!is_int($length)) { + throw new TypeError( + 'RandomCompat_substr(): Third argument should be an integer, or omitted' + ); + } + + return (string) substr( + (string )$binary_string, + (int) $start, + (int) $length + ); + } + + return (string) substr( + (string) $binary_string, + (int) $start + ); + } + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/cast_to_int.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/cast_to_int.php new file mode 100644 index 00000000..1b1bbfe8 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/cast_to_int.php @@ -0,0 +1,77 @@ + operators might accidentally let a float + * through. + * + * @param int|float $number The number we want to convert to an int + * @param bool $fail_open Set to true to not throw an exception + * + * @return float|int + * @psalm-suppress InvalidReturnType + * + * @throws TypeError + */ + function RandomCompat_intval($number, $fail_open = false) + { + if (is_int($number) || is_float($number)) { + $number += 0; + } elseif (is_numeric($number)) { + /** @psalm-suppress InvalidOperand */ + $number += 0; + } + /** @var int|float $number */ + + if ( + is_float($number) + && + $number > ~PHP_INT_MAX + && + $number < PHP_INT_MAX + ) { + $number = (int) $number; + } + + if (is_int($number)) { + return (int) $number; + } elseif (!$fail_open) { + throw new TypeError( + 'Expected an integer.' + ); + } + return $number; + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/error_polyfill.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/error_polyfill.php new file mode 100644 index 00000000..c02c5c8b --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/error_polyfill.php @@ -0,0 +1,49 @@ += 70000) { + return; +} + +if (!defined('RANDOM_COMPAT_READ_BUFFER')) { + define('RANDOM_COMPAT_READ_BUFFER', 8); +} + +$RandomCompatDIR = dirname(__FILE__); + +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'byte_safe_strings.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'cast_to_int.php'; +require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'error_polyfill.php'; + +if (!is_callable('random_bytes')) { + /** + * PHP 5.2.0 - 5.6.x way to implement random_bytes() + * + * We use conditional statements here to define the function in accordance + * to the operating environment. It's a micro-optimization. + * + * In order of preference: + * 1. Use libsodium if available. + * 2. fread() /dev/urandom if available (never on Windows) + * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM) + * 4. COM('CAPICOM.Utilities.1')->GetRandom() + * + * See RATIONALE.md for our reasoning behind this particular order + */ + if (extension_loaded('libsodium')) { + // See random_bytes_libsodium.php + if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) { + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium.php'; + } elseif (method_exists('Sodium', 'randombytes_buf')) { + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_libsodium_legacy.php'; + } + } + + /** + * Reading directly from /dev/urandom: + */ + if (DIRECTORY_SEPARATOR === '/') { + // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast + // way to exclude Windows. + $RandomCompatUrandom = true; + $RandomCompat_basedir = ini_get('open_basedir'); + + if (!empty($RandomCompat_basedir)) { + $RandomCompat_open_basedir = explode( + PATH_SEPARATOR, + strtolower($RandomCompat_basedir) + ); + $RandomCompatUrandom = (array() !== array_intersect( + array('/dev', '/dev/', '/dev/urandom'), + $RandomCompat_open_basedir + )); + $RandomCompat_open_basedir = null; + } + + if ( + !is_callable('random_bytes') + && + $RandomCompatUrandom + && + @is_readable('/dev/urandom') + ) { + // Error suppression on is_readable() in case of an open_basedir + // or safe_mode failure. All we care about is whether or not we + // can read it at this point. If the PHP environment is going to + // panic over trying to see if the file can be read in the first + // place, that is not helpful to us here. + + // See random_bytes_dev_urandom.php + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_dev_urandom.php'; + } + // Unset variables after use + $RandomCompat_basedir = null; + } else { + $RandomCompatUrandom = false; + } + + /** + * mcrypt_create_iv() + * + * We only want to use mcypt_create_iv() if: + * + * - random_bytes() hasn't already been defined + * - the mcrypt extensions is loaded + * - One of these two conditions is true: + * - We're on Windows (DIRECTORY_SEPARATOR !== '/') + * - We're not on Windows and /dev/urandom is readabale + * (i.e. we're not in a chroot jail) + * - Special case: + * - If we're not on Windows, but the PHP version is between + * 5.6.10 and 5.6.12, we don't want to use mcrypt. It will + * hang indefinitely. This is bad. + * - If we're on Windows, we want to use PHP >= 5.3.7 or else + * we get insufficient entropy errors. + */ + if ( + !is_callable('random_bytes') + && + // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be. + (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307) + && + // Prevent this code from hanging indefinitely on non-Windows; + // see https://bugs.php.net/bug.php?id=69833 + ( + DIRECTORY_SEPARATOR !== '/' || + (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613) + ) + && + extension_loaded('mcrypt') + ) { + // See random_bytes_mcrypt.php + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_mcrypt.php'; + } + $RandomCompatUrandom = null; + + /** + * This is a Windows-specific fallback, for when the mcrypt extension + * isn't loaded. + */ + if ( + !is_callable('random_bytes') + && + extension_loaded('com_dotnet') + && + class_exists('COM') + ) { + $RandomCompat_disabled_classes = preg_split( + '#\s*,\s*#', + strtolower(ini_get('disable_classes')) + ); + + if (!in_array('com', $RandomCompat_disabled_classes)) { + try { + $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1'); + /** @psalm-suppress TypeDoesNotContainType */ + if (is_callable(array($RandomCompatCOMtest, 'GetRandom'))) { + // See random_bytes_com_dotnet.php + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_com_dotnet.php'; + } + } catch (com_exception $e) { + // Don't try to use it. + } + } + $RandomCompat_disabled_classes = null; + $RandomCompatCOMtest = null; + } + + /** + * throw new Exception + */ + if (!is_callable('random_bytes')) { + /** + * We don't have any more options, so let's throw an exception right now + * and hope the developer won't let it fail silently. + * + * @param mixed $length + * @psalm-suppress InvalidReturnType + * @throws Exception + * @return string + */ + function random_bytes($length) + { + unset($length); // Suppress "variable not used" warnings. + throw new Exception( + 'There is no suitable CSPRNG installed on your system' + ); + return ''; + } + } +} + +if (!is_callable('random_int')) { + require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_int.php'; +} + +$RandomCompatDIR = null; diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php new file mode 100644 index 00000000..537d02b2 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php @@ -0,0 +1,91 @@ +GetRandom($bytes, 0)); + if (RandomCompat_strlen($buf) >= $bytes) { + /** + * Return our random entropy buffer here: + */ + return (string) RandomCompat_substr($buf, 0, $bytes); + } + ++$execCount; + } while ($execCount < $bytes); + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php new file mode 100644 index 00000000..c4e31ccb --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php @@ -0,0 +1,190 @@ + $st */ + $st = fstat($fp); + if (($st['mode'] & 0170000) !== 020000) { + fclose($fp); + $fp = false; + } + } + } + + if (is_resource($fp)) { + /** + * stream_set_read_buffer() does not exist in HHVM + * + * If we don't set the stream's read buffer to 0, PHP will + * internally buffer 8192 bytes, which can waste entropy + * + * stream_set_read_buffer returns 0 on success + */ + if (is_callable('stream_set_read_buffer')) { + stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER); + } + if (is_callable('stream_set_chunk_size')) { + stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER); + } + } + } + + try { + /** @var int $bytes */ + $bytes = RandomCompat_intval($bytes); + } catch (TypeError $ex) { + throw new TypeError( + 'random_bytes(): $bytes must be an integer' + ); + } + + if ($bytes < 1) { + throw new Error( + 'Length must be greater than 0' + ); + } + + /** + * This if() block only runs if we managed to open a file handle + * + * It does not belong in an else {} block, because the above + * if (empty($fp)) line is logic that should only be run once per + * page load. + */ + if (is_resource($fp)) { + /** + * @var int + */ + $remaining = $bytes; + + /** + * @var string|bool + */ + $buf = ''; + + /** + * We use fread() in a loop to protect against partial reads + */ + do { + /** + * @var string|bool + */ + $read = fread($fp, $remaining); + if (!is_string($read)) { + /** + * We cannot safely read from the file. Exit the + * do-while loop and trigger the exception condition + * + * @var string|bool + */ + $buf = false; + break; + } + /** + * Decrease the number of bytes returned from remaining + */ + $remaining -= RandomCompat_strlen($read); + /** + * @var string $buf + */ + $buf .= $read; + } while ($remaining > 0); + + /** + * Is our result valid? + * @var string|bool $buf + */ + if (is_string($buf)) { + if (RandomCompat_strlen($buf) === $bytes) { + /** + * Return our random entropy buffer here: + */ + return $buf; + } + } + } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Error reading from source device' + ); + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php new file mode 100644 index 00000000..2e562901 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php @@ -0,0 +1,91 @@ + 2147483647) { + $buf = ''; + for ($i = 0; $i < $bytes; $i += 1073741824) { + $n = ($bytes - $i) > 1073741824 + ? 1073741824 + : $bytes - $i; + $buf .= \Sodium\randombytes_buf($n); + } + } else { + /** @var string|bool $buf */ + $buf = \Sodium\randombytes_buf($bytes); + } + + if (is_string($buf)) { + if (RandomCompat_strlen($buf) === $bytes) { + return $buf; + } + } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php new file mode 100644 index 00000000..f78b2199 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php @@ -0,0 +1,93 @@ + 2147483647) { + for ($i = 0; $i < $bytes; $i += 1073741824) { + $n = ($bytes - $i) > 1073741824 + ? 1073741824 + : $bytes - $i; + $buf .= Sodium::randombytes_buf((int) $n); + } + } else { + $buf .= Sodium::randombytes_buf((int) $bytes); + } + + if (is_string($buf)) { + if (RandomCompat_strlen($buf) === $bytes) { + return $buf; + } + } + + /** + * If we reach here, PHP has failed us. + */ + throw new Exception( + 'Could not gather sufficient random data' + ); + } +} diff --git a/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php new file mode 100644 index 00000000..0b13fa73 --- /dev/null +++ b/modules/empikmarketplace/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php @@ -0,0 +1,79 @@ + operators might accidentally let a float + * through. + */ + + try { + /** @var int $min */ + $min = RandomCompat_intval($min); + } catch (TypeError $ex) { + throw new TypeError( + 'random_int(): $min must be an integer' + ); + } + + try { + /** @var int $max */ + $max = RandomCompat_intval($max); + } catch (TypeError $ex) { + throw new TypeError( + 'random_int(): $max must be an integer' + ); + } + + /** + * Now that we've verified our weak typing system has given us an integer, + * let's validate the logic then we can move forward with generating random + * integers along a given range. + */ + if ($min > $max) { + throw new Error( + 'Minimum value must be less than or equal to the maximum value' + ); + } + + if ($max === $min) { + return (int) $min; + } + + /** + * Initialize variables to 0 + * + * We want to store: + * $bytes => the number of random bytes we need + * $mask => an integer bitmask (for use with the &) operator + * so we can minimize the number of discards + */ + $attempts = $bits = $bytes = $mask = $valueShift = 0; + /** @var int $attempts */ + /** @var int $bits */ + /** @var int $bytes */ + /** @var int $mask */ + /** @var int $valueShift */ + + /** + * At this point, $range is a positive number greater than 0. It might + * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to + * a float and we will lose some precision. + * + * @var int|float $range + */ + $range = $max - $min; + + /** + * Test for integer overflow: + */ + if (!is_int($range)) { + + /** + * Still safely calculate wider ranges. + * Provided by @CodesInChaos, @oittaa + * + * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435 + * + * We use ~0 as a mask in this case because it generates all 1s + * + * @ref https://eval.in/400356 (32-bit) + * @ref http://3v4l.org/XX9r5 (64-bit) + */ + $bytes = PHP_INT_SIZE; + /** @var int $mask */ + $mask = ~0; + + } else { + + /** + * $bits is effectively ceil(log($range, 2)) without dealing with + * type juggling + */ + while ($range > 0) { + if ($bits % 8 === 0) { + ++$bytes; + } + ++$bits; + $range >>= 1; + /** @var int $mask */ + $mask = $mask << 1 | 1; + } + $valueShift = $min; + } + + /** @var int $val */ + $val = 0; + /** + * Now that we have our parameters set up, let's begin generating + * random integers until one falls between $min and $max + */ + /** @psalm-suppress RedundantCondition */ + do { + /** + * The rejection probability is at most 0.5, so this corresponds + * to a failure probability of 2^-128 for a working RNG + */ + if ($attempts > 128) { + throw new Exception( + 'random_int: RNG is broken - too many rejections' + ); + } + + /** + * Let's grab the necessary number of random bytes + */ + $randomByteString = random_bytes($bytes); + + /** + * Let's turn $randomByteString into an integer + * + * This uses bitwise operators (<< and |) to build an integer + * out of the values extracted from ord() + * + * Example: [9F] | [6D] | [32] | [0C] => + * 159 + 27904 + 3276800 + 201326592 => + * 204631455 + */ + $val &= 0; + for ($i = 0; $i < $bytes; ++$i) { + $val |= ord($randomByteString[$i]) << ($i * 8); + } + /** @var int $val */ + + /** + * Apply mask + */ + $val &= $mask; + $val += $valueShift; + + ++$attempts; + /** + * If $val overflows to a floating point number, + * ... or is larger than $max, + * ... or smaller than $min, + * then try again. + */ + } while (!is_int($val) || $val > $max || $val < $min); + + return (int) $val; + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/.gitignore b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/.gitignore new file mode 100644 index 00000000..f69ea8a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/.gitignore @@ -0,0 +1,282 @@ +# Created by https://www.gitignore.io/api/vim,vuejs,emacs,linux,macos,windows,phpstorm,composer,sublimetext,visualstudiocode +# Edit at https://www.gitignore.io/?templates=vim,vuejs,emacs,linux,macos,windows,phpstorm,composer,sublimetext,visualstudiocode + +### Composer ### +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +# composer.lock + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### PhpStorm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +# JetBrains templates +**___jb_tmp___ + +### PhpStorm Patch ### +.idea + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +### Vuejs ### +# Recommended template: Node.gitignore + +node_modules/ +npm-debug.log +yarn-error.log + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/vim,vuejs,emacs,linux,macos,windows,phpstorm,composer,sublimetext,visualstudiocode + +# CS Fixer +.php_cs.cache diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/LICENSE b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/LICENSE new file mode 100644 index 00000000..859074ba --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/LICENSE @@ -0,0 +1,170 @@ +Academic Free License (“AFL”) v. 3.0 + +This Academic Free License (the "License") applies to any original work of +authorship (the "Original Work") whose owner (the "Licensor") has placed the +following licensing notice adjacent to the copyright notice for the Original +Work: + + Licensed under the Academic Free License version 3.0 + +1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, +non-exclusive, sublicensable license, for the duration of the copyright, to do +the following: + + a) to reproduce the Original Work in copies, either alone or as part of a + collective work; + + b) to translate, adapt, alter, transform, modify, or arrange the Original + Work, thereby creating derivative works ("Derivative Works") based upon + the Original Work; + + c) to distribute or communicate copies of the Original Work and + Derivative Works to the public, under any license of your choice that + does not contradict the terms and conditions, including Licensor’s + reserved rights and remedies, in this Academic Free License; + d) to perform the Original Work publicly; and + e) to display the Original Work publicly. + +2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, +non-exclusive, sublicensable license, under patent claims owned or controlled +by the Licensor that are embodied in the Original Work as furnished by the +Licensor, for the duration of the patents, to make, use, sell, offer for sale, +have made, and import the Original Work and Derivative Works. + +3) Grant of Source Code License. The term "Source Code" means the preferred +form of the Original Work for making modifications to it and all available +documentation describing how to modify the Original Work. Licensor agrees to +provide a machine-readable copy of the Source Code of the Original Work along +with each copy of the Original Work that Licensor distributes. Licensor +reserves the right to satisfy this obligation by placing a machine-readable +copy of the Source Code in an information repository reasonably calculated to +permit inexpensive and convenient access by You for as long as Licensor +continues to distribute the Original Work. + +4) Exclusions From License Grant. Neither the names of Licensor, nor the names +of any contributors to the Original Work, nor any of their trademarks or +service marks, may be used to endorse or promote products derived from this +Original Work without express prior permission of the Licensor. Except as +expressly stated herein, nothing in this License grants any license to +Licensor’s trademarks, copyrights, patents, trade secrets or any other +intellectual property. No patent license is granted to make, use, sell, offer +for sale, have made, or import embodiments of any patent claims other than the +licensed claims defined in Section 2. No license is granted to the trademarks +of Licensor even if such marks are included in the Original Work. Nothing in +this License shall be interpreted to prohibit Licensor from licensing under +terms different from this License any Original Work that Licensor otherwise +would have a right to license. + +5) External Deployment. The term "External Deployment" means the use, +distribution, or communication of the Original Work or Derivative Works in any +way such that the Original Work or Derivative Works may be used by anyone +other than You, whether those works are distributed or communicated to those +persons or made available as an application intended for use over a network. +As an express condition for the grants of license hereunder, You must treat +any External Deployment by You of the Original Work or a Derivative Work as a +distribution under section 1(c). + +6) Attribution Rights. You must retain, in the Source Code of any Derivative +Works that You create, all copyright, patent, or trademark notices from the +Source Code of the Original Work, as well as any notices of licensing and any +descriptive text identified therein as an "Attribution Notice." You must cause +the Source Code for any Derivative Works that You create to carry a prominent +Attribution Notice reasonably calculated to inform recipients that You have +modified the Original Work. + +7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that +the copyright in and to the Original Work and the patent rights granted herein +by Licensor are owned by the Licensor or are sublicensed to You under the +terms of this License with the permission of the contributor(s) of those +copyrights and patent rights. Except as expressly stated in the immediately +preceding sentence, the Original Work is provided under this License on an "AS +IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without +limitation, the warranties of non-infringement, merchantability or fitness for +a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK +IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this +License. No license to the Original Work is granted by this License except +under this disclaimer. + +8) Limitation of Liability. Under no circumstances and under no legal theory, +whether in tort (including negligence), contract, or otherwise, shall the +Licensor be liable to anyone for any indirect, special, incidental, or +consequential damages of any character arising as a result of this License or +the use of the Original Work including, without limitation, damages for loss +of goodwill, work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses. This limitation of liability shall not +apply to the extent applicable law prohibits such limitation. + +9) Acceptance and Termination. If, at any time, You expressly assented to this +License, that assent indicates your clear and irrevocable acceptance of this +License and all of its terms and conditions. If You distribute or communicate +copies of the Original Work or a Derivative Work, You must make a reasonable +effort under the circumstances to obtain the express assent of recipients to +the terms of this License. This License conditions your rights to undertake +the activities listed in Section 1, including your right to create Derivative +Works based upon the Original Work, and doing so without honoring these terms +and conditions is prohibited by copyright law and international treaty. +Nothing in this License is intended to affect copyright exceptions and +limitations (including “fair use” or “fair dealing”). This License shall +terminate immediately and You may no longer exercise any of the rights granted +to You by this License upon your failure to honor the conditions in Section +1(c). + +10) Termination for Patent Action. This License shall terminate automatically +and You may no longer exercise any of the rights granted to You by this +License as of the date You commence an action, including a cross-claim or +counterclaim, against Licensor or any licensee alleging that the Original Work +infringes a patent. This termination provision shall not apply for an action +alleging patent infringement by combinations of the Original Work with other +software or hardware. + +11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this +License may be brought only in the courts of a jurisdiction wherein the +Licensor resides or in which Licensor conducts its primary business, and under +the laws of that jurisdiction excluding its conflict-of-law provisions. The +application of the United Nations Convention on Contracts for the +International Sale of Goods is expressly excluded. Any use of the Original +Work outside the scope of this License or after its termination shall be +subject to the requirements and penalties of copyright or patent law in the +appropriate jurisdiction. This section shall survive the termination of this +License. + +12) Attorneys’ Fees. In any action to enforce the terms of this License or +seeking damages relating thereto, the prevailing party shall be entitled to +recover its costs and expenses, including, without limitation, reasonable +attorneys' fees and costs incurred in connection with such action, including +any appeal of such action. This section shall survive the termination of this +License. + +13) Miscellaneous. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent necessary +to make it enforceable. + +14) Definition of "You" in This License. "You" throughout this License, +whether in upper or lower case, means an individual or a legal entity +exercising rights under, and complying with all of the terms of, this License. +For legal entities, "You" includes any entity that controls, is controlled by, +or is under common control with you. For purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the direction or +management of such entity, whether by contract or otherwise, or (ii) ownership +of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial +ownership of such entity. + +15) Right to Use. You may use the Original Work in all ways not otherwise +restricted or conditioned by this License or by law, and Licensor promises not +to interfere with or be responsible for such uses by You. + +16) Modification of This License. This License is Copyright © 2005 Lawrence +Rosen. Permission is granted to copy, distribute, or communicate this License +without modification. Nothing in this License permits You to modify this +License as applied to the Original Work or to Derivative Works. However, You +may modify the text of this License and copy, distribute or communicate your +modified version (the "Modified License") and apply it to other original works +of authorship subject to the following conditions: (i) You may not indicate in +any way that your Modified License is the "Academic Free License" or "AFL" and +you may not use those names in the name of your Modified License; (ii) You +must replace the notice specified in the first paragraph above with the notice +"Licensed under " or with a notice of your own +that is not confusingly similar to the notice in this License; and (iii) You +may not claim that your original works are open source software unless your +Modified License has been approved by Open Source Initiative (OSI) and You +comply with its license review and certification process. \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/README.md b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/README.md new file mode 100644 index 00000000..5699fdd4 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/README.md @@ -0,0 +1,30 @@ +# PrestaShop Cache Directory Provider for Modules + +This repository provides the cache directory for PrestaShop modules. + +## Pre-requisites + +You should install this library only on a PrestaShop environment and with PHP 5.6.0 minimum. + +## Installation + +``` +composer require prestashop/module-lib-cache-directory-provider +``` + +When this project is successfully added to your dependencies, you can add the new CacheDirectoryProvider to your module and use it. + +## Usage + +To use this library, it's simple : +``` + $cacheDirectoryProvider = new CacheDirectoryProvider( + _PS_VERSION_, + _PS_ROOT_DIR_, + _PS_MODE_DEV_ + ); +``` +With the getPath() function, you will retrieve the cache path of your module : +``` + $cacheDirectoryProvider->getPath(); +``` diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/composer.json b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/composer.json new file mode 100644 index 00000000..b7c11f80 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/composer.json @@ -0,0 +1,34 @@ +{ + "name": "prestashop/module-lib-cache-directory-provider", + "description": "Cache directory provider to use on prestashop modules", + "keywords": ["prestashop", "modules", "composer", "package"], + "license": "AFL-3.0", + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "type": "project", + "config": { + "platform": { + "php": "5.6.0" + } + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibCacheDirectoryProvider\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/composer.lock b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/composer.lock new file mode 100644 index 00000000..6e26ee2e --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/composer.lock @@ -0,0 +1,1435 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "12d5fefbc2bcdbc61e0e5edb8b86a500", + "packages": [], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "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-10T14:09:06+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "451c3cd1418cf640de218914901e51b064abb093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-03-05T15:02:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" + }, + "require-dev": { + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-xdebug": "^2.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-04-02T07:44:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "abandoned": true, + "time": "2017-12-04T08:55:13+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-02-01T05:50:59+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true, + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-11-26T07:53:53+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "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" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-02-18T15:18:39+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "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" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.44", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "4152e36b0f305c2a57aa0233dee56ec27bca4f06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4152e36b0f305c2a57aa0233dee56ec27bca4f06", + "reference": "4152e36b0f305c2a57aa0233dee56ec27bca4f06", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-08-26T06:32:27+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-07-08T17:02:28+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.6.0" + }, + "platform-dev": [], + "platform-overrides": { + "php": "5.6.0" + }, + "plugin-api-version": "1.1.0" +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/src/Cache/CacheDirectoryProvider.php b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/src/Cache/CacheDirectoryProvider.php new file mode 100644 index 00000000..1faf565d --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/src/Cache/CacheDirectoryProvider.php @@ -0,0 +1,98 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ + +namespace PrestaShop\ModuleLibCacheDirectoryProvider\Cache; + +/** + * Class responsible for returning cache directory path. + */ +class CacheDirectoryProvider +{ + /** + * @var string PrestaShop version + */ + private $psVersion; + + /** + * @var string PrestaShop path + */ + private $psPath; + + /** + * @var bool PrestaShop Debug Mode + */ + private $psIsDebugMode; + + /** + * @param string $psVersion + * @param string $psPath + * @param bool $psIsDebugMode + */ + public function __construct($psVersion, $psPath, $psIsDebugMode) + { + $this->psVersion = $psVersion; + $this->psPath = $psPath; + $this->psIsDebugMode = $psIsDebugMode; + } + + /** + * @return string + */ + public function getPath() + { + if (defined('_PS_CACHE_DIR_')) { + return constant('_PS_CACHE_DIR_'); + } + + $path = '/var/cache/' . $this->getEnvName(); + + if (version_compare($this->psVersion, '1.7.0.0', '<')) { + $path = '/cache'; + } elseif (version_compare($this->psVersion, '1.7.4.0', '<')) { + $path = '/app/cache/' . $this->getEnvName(); + } + + return $this->psPath . $path; + } + + /** + * @return bool + */ + public function isWritable() + { + return is_writable($this->getPath()); + } + + /** + * @return bool + */ + public function isReadable() + { + return is_readable($this->getPath()); + } + + /** + * @return string + */ + private function getEnvName() + { + return $this->psIsDebugMode ? 'dev' : 'prod'; + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/tests/Unit/Cache/CacheDirectoryProviderTest.php b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/tests/Unit/Cache/CacheDirectoryProviderTest.php new file mode 100644 index 00000000..8d6669ff --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/tests/Unit/Cache/CacheDirectoryProviderTest.php @@ -0,0 +1,48 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ + +namespace Tests\Unit\Cache; + +use PHPUnit\Framework\TestCase; +use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider; + +class CacheDirectoryProviderTest extends TestCase +{ + public function testItIsReturnValidPathForVersionLessThan17() + { + $cacheDirectory = new CacheDirectoryProvider('1.6.1.0', __DIR__, true); + + $this->assertSame(__DIR__ . '/cache', $cacheDirectory->getPath()); + } + + public function testItIsReturnValidPathForVersionLessThan174() + { + $cacheDirectory = new CacheDirectoryProvider('1.7.0.0', __DIR__, true); + + $this->assertSame(__DIR__ . '/app/cache/dev', $cacheDirectory->getPath()); + } + + public function testItIsReturnValidPathForVersionGreaterThanEq174() + { + $cacheDirectory = new CacheDirectoryProvider('1.7.4.0', __DIR__, true); + + $this->assertSame(__DIR__ . '/var/cache/dev', $cacheDirectory->getPath()); + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/tests/Unit/phpunit.xml b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/tests/Unit/phpunit.xml new file mode 100644 index 00000000..e11b811b --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-cache-directory-provider/tests/Unit/phpunit.xml @@ -0,0 +1,9 @@ + + + + . + + + diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/.gitignore b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/.gitignore new file mode 100644 index 00000000..f69ea8a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/.gitignore @@ -0,0 +1,282 @@ +# Created by https://www.gitignore.io/api/vim,vuejs,emacs,linux,macos,windows,phpstorm,composer,sublimetext,visualstudiocode +# Edit at https://www.gitignore.io/?templates=vim,vuejs,emacs,linux,macos,windows,phpstorm,composer,sublimetext,visualstudiocode + +### Composer ### +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +# composer.lock + +### Emacs ### +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + + +### Linux ### + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### PhpStorm ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +# JetBrains templates +**___jb_tmp___ + +### PhpStorm Patch ### +.idea + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/sonarlint + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +### Vim ### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history + +### Vuejs ### +# Recommended template: Node.gitignore + +node_modules/ +npm-debug.log +yarn-error.log + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/vim,vuejs,emacs,linux,macos,windows,phpstorm,composer,sublimetext,visualstudiocode + +# CS Fixer +.php_cs.cache diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/LICENSE b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/LICENSE new file mode 100644 index 00000000..859074ba --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/LICENSE @@ -0,0 +1,170 @@ +Academic Free License (“AFL”) v. 3.0 + +This Academic Free License (the "License") applies to any original work of +authorship (the "Original Work") whose owner (the "Licensor") has placed the +following licensing notice adjacent to the copyright notice for the Original +Work: + + Licensed under the Academic Free License version 3.0 + +1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, +non-exclusive, sublicensable license, for the duration of the copyright, to do +the following: + + a) to reproduce the Original Work in copies, either alone or as part of a + collective work; + + b) to translate, adapt, alter, transform, modify, or arrange the Original + Work, thereby creating derivative works ("Derivative Works") based upon + the Original Work; + + c) to distribute or communicate copies of the Original Work and + Derivative Works to the public, under any license of your choice that + does not contradict the terms and conditions, including Licensor’s + reserved rights and remedies, in this Academic Free License; + d) to perform the Original Work publicly; and + e) to display the Original Work publicly. + +2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, +non-exclusive, sublicensable license, under patent claims owned or controlled +by the Licensor that are embodied in the Original Work as furnished by the +Licensor, for the duration of the patents, to make, use, sell, offer for sale, +have made, and import the Original Work and Derivative Works. + +3) Grant of Source Code License. The term "Source Code" means the preferred +form of the Original Work for making modifications to it and all available +documentation describing how to modify the Original Work. Licensor agrees to +provide a machine-readable copy of the Source Code of the Original Work along +with each copy of the Original Work that Licensor distributes. Licensor +reserves the right to satisfy this obligation by placing a machine-readable +copy of the Source Code in an information repository reasonably calculated to +permit inexpensive and convenient access by You for as long as Licensor +continues to distribute the Original Work. + +4) Exclusions From License Grant. Neither the names of Licensor, nor the names +of any contributors to the Original Work, nor any of their trademarks or +service marks, may be used to endorse or promote products derived from this +Original Work without express prior permission of the Licensor. Except as +expressly stated herein, nothing in this License grants any license to +Licensor’s trademarks, copyrights, patents, trade secrets or any other +intellectual property. No patent license is granted to make, use, sell, offer +for sale, have made, or import embodiments of any patent claims other than the +licensed claims defined in Section 2. No license is granted to the trademarks +of Licensor even if such marks are included in the Original Work. Nothing in +this License shall be interpreted to prohibit Licensor from licensing under +terms different from this License any Original Work that Licensor otherwise +would have a right to license. + +5) External Deployment. The term "External Deployment" means the use, +distribution, or communication of the Original Work or Derivative Works in any +way such that the Original Work or Derivative Works may be used by anyone +other than You, whether those works are distributed or communicated to those +persons or made available as an application intended for use over a network. +As an express condition for the grants of license hereunder, You must treat +any External Deployment by You of the Original Work or a Derivative Work as a +distribution under section 1(c). + +6) Attribution Rights. You must retain, in the Source Code of any Derivative +Works that You create, all copyright, patent, or trademark notices from the +Source Code of the Original Work, as well as any notices of licensing and any +descriptive text identified therein as an "Attribution Notice." You must cause +the Source Code for any Derivative Works that You create to carry a prominent +Attribution Notice reasonably calculated to inform recipients that You have +modified the Original Work. + +7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that +the copyright in and to the Original Work and the patent rights granted herein +by Licensor are owned by the Licensor or are sublicensed to You under the +terms of this License with the permission of the contributor(s) of those +copyrights and patent rights. Except as expressly stated in the immediately +preceding sentence, the Original Work is provided under this License on an "AS +IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without +limitation, the warranties of non-infringement, merchantability or fitness for +a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK +IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this +License. No license to the Original Work is granted by this License except +under this disclaimer. + +8) Limitation of Liability. Under no circumstances and under no legal theory, +whether in tort (including negligence), contract, or otherwise, shall the +Licensor be liable to anyone for any indirect, special, incidental, or +consequential damages of any character arising as a result of this License or +the use of the Original Work including, without limitation, damages for loss +of goodwill, work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses. This limitation of liability shall not +apply to the extent applicable law prohibits such limitation. + +9) Acceptance and Termination. If, at any time, You expressly assented to this +License, that assent indicates your clear and irrevocable acceptance of this +License and all of its terms and conditions. If You distribute or communicate +copies of the Original Work or a Derivative Work, You must make a reasonable +effort under the circumstances to obtain the express assent of recipients to +the terms of this License. This License conditions your rights to undertake +the activities listed in Section 1, including your right to create Derivative +Works based upon the Original Work, and doing so without honoring these terms +and conditions is prohibited by copyright law and international treaty. +Nothing in this License is intended to affect copyright exceptions and +limitations (including “fair use” or “fair dealing”). This License shall +terminate immediately and You may no longer exercise any of the rights granted +to You by this License upon your failure to honor the conditions in Section +1(c). + +10) Termination for Patent Action. This License shall terminate automatically +and You may no longer exercise any of the rights granted to You by this +License as of the date You commence an action, including a cross-claim or +counterclaim, against Licensor or any licensee alleging that the Original Work +infringes a patent. This termination provision shall not apply for an action +alleging patent infringement by combinations of the Original Work with other +software or hardware. + +11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this +License may be brought only in the courts of a jurisdiction wherein the +Licensor resides or in which Licensor conducts its primary business, and under +the laws of that jurisdiction excluding its conflict-of-law provisions. The +application of the United Nations Convention on Contracts for the +International Sale of Goods is expressly excluded. Any use of the Original +Work outside the scope of this License or after its termination shall be +subject to the requirements and penalties of copyright or patent law in the +appropriate jurisdiction. This section shall survive the termination of this +License. + +12) Attorneys’ Fees. In any action to enforce the terms of this License or +seeking damages relating thereto, the prevailing party shall be entitled to +recover its costs and expenses, including, without limitation, reasonable +attorneys' fees and costs incurred in connection with such action, including +any appeal of such action. This section shall survive the termination of this +License. + +13) Miscellaneous. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent necessary +to make it enforceable. + +14) Definition of "You" in This License. "You" throughout this License, +whether in upper or lower case, means an individual or a legal entity +exercising rights under, and complying with all of the terms of, this License. +For legal entities, "You" includes any entity that controls, is controlled by, +or is under common control with you. For purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the direction or +management of such entity, whether by contract or otherwise, or (ii) ownership +of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial +ownership of such entity. + +15) Right to Use. You may use the Original Work in all ways not otherwise +restricted or conditioned by this License or by law, and Licensor promises not +to interfere with or be responsible for such uses by You. + +16) Modification of This License. This License is Copyright © 2005 Lawrence +Rosen. Permission is granted to copy, distribute, or communicate this License +without modification. Nothing in this License permits You to modify this +License as applied to the Original Work or to Derivative Works. However, You +may modify the text of this License and copy, distribute or communicate your +modified version (the "Modified License") and apply it to other original works +of authorship subject to the following conditions: (i) You may not indicate in +any way that your Modified License is the "Academic Free License" or "AFL" and +you may not use those names in the name of your Modified License; (ii) You +must replace the notice specified in the first paragraph above with the notice +"Licensed under " or with a notice of your own +that is not confusingly similar to the notice in this License; and (iii) You +may not claim that your original works are open source software unless your +Modified License has been approved by Open Source Initiative (OSI) and You +comply with its license review and certification process. \ No newline at end of file diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/README.md b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/README.md new file mode 100644 index 00000000..5e5f1dc7 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/README.md @@ -0,0 +1,60 @@ +# PrestaShop Service Container for Modules + +This repository includes the service container from Symfony that you can use in your PrestaShop Module. + +## Pre-requisites + +You should install this library only on a PrestaShop environment and with PHP 5.6.0 minimum. + +## Installation + +``` +composer require prestashop/module-lib-service-container +``` + +When this project is successfully added to your dependencies, you can add the new ServiceContainer to your module and use it. + +## Usage + +To use this library, it's simple : + - First, declare your new service Container in your root module PHP file (like mymodule.php at your root project folder) : +``` + /** + * @var ServiceContainer + */ + private $serviceContainer; +``` +- And instantiate it in the constructor with the module name and its local path : +``` +$this->serviceContainer = new ServiceContainer($this->name, $this->getLocalPath()); +``` +- You can add a new function on your root module PHP file, like getService, to retrieve your service name in the new service container : +``` + /** + * @param string $serviceName + * + * @return mixed + */ + public function getService($serviceName) + { + return $this->serviceContainer->getService($serviceName); + } +``` +- Then, you have to declare your service in the services.yml file. You must declare your services in the config/ folder. +We split the services in two folders in the config : /front and /admin folders. So the tree should be like : +``` +/mymodule + /config + /front + services.yml + /admin + services.yml + common.yml +``` +- Of course, you can include a common file, with common services that are use in front and admin project by an import in the services.yml file : +``` +imports: + - { resource: ../common.yml } +``` +Now you can add your services in the services.yml like you were in a Symfony project ;) + diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/composer.json b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/composer.json new file mode 100644 index 00000000..fad5d868 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/composer.json @@ -0,0 +1,39 @@ +{ + "name": "prestashop/module-lib-service-container", + "description": "Service container to use on prestashop modules", + "keywords": ["prestashop", "modules", "composer", "package"], + "license": "AFL-3.0", + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "type": "library", + "config": { + "platform": { + "php": "5.6.0" + } + }, + "require": { + "php": ">=5.6.0", + "symfony/config": "^3.4", + "symfony/dependency-injection": "^3.4", + "prestashop/module-lib-cache-directory-provider": "^1.0", + "symfony/expression-language": "^3.4", + "symfony/yaml": "^3.4" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibServiceContainer\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/composer.lock b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/composer.lock new file mode 100644 index 00000000..551c0a1c --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/composer.lock @@ -0,0 +1,2120 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "3d9e2b16b071da09348fd794950db28c", + "packages": [ + { + "name": "paragonie/random_compat", + "version": "v2.0.19", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/446fc9faa5c2a9ddf65eb7121c0af7e857295241", + "reference": "446fc9faa5c2a9ddf65eb7121c0af7e857295241", + "shasum": "" + }, + "require": { + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "autoload": { + "files": [ + "lib/random.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2020-10-15T10:06:57+00:00" + }, + { + "name": "prestashop/module-lib-cache-directory-provider", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PrestaShopCorp/module-lib-cache-directory-provider.git", + "reference": "34a577b66a7e52ae16d6f40efd1db17290bad453" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PrestaShopCorp/module-lib-cache-directory-provider/zipball/34a577b66a7e52ae16d6f40efd1db17290bad453", + "reference": "34a577b66a7e52ae16d6f40efd1db17290bad453", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "~5.7" + }, + "type": "project", + "autoload": { + "psr-4": { + "PrestaShop\\ModuleLibCacheDirectoryProvider\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "AFL-3.0" + ], + "authors": [ + { + "name": "PrestaShop SA", + "email": "contact@prestashop.com" + } + ], + "description": "Cache directory provider to use on prestashop modules", + "keywords": [ + "composer", + "modules", + "package", + "prestashop" + ], + "time": "2020-09-08T14:13:23+00:00" + }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "time": "2016-08-06T20:24:11+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "psr/simple-cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "symfony/cache", + "version": "v3.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "01f4cc9de5aa1a49cce75280680c8a78907bb55e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/01f4cc9de5aa1a49cce75280680c8a78907bb55e", + "reference": "01f4cc9de5aa1a49cce75280680c8a78907bb55e", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "symfony/polyfill-apcu": "~1.1" + }, + "conflict": { + "symfony/var-dumper": "<3.3" + }, + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "time": "2020-09-02T16:06:40+00:00" + }, + { + "name": "symfony/config", + "version": "v3.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "d061a451ff6bc170c5454f4ac9b41ad2179e3960" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/d061a451ff6bc170c5454f4ac9b41ad2179e3960", + "reference": "d061a451ff6bc170c5454f4ac9b41ad2179e3960", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/filesystem": "~2.8|~3.0|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3", + "symfony/finder": "<3.3" + }, + "require-dev": { + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0", + "symfony/finder": "~3.3|~4.0", + "symfony/yaml": "~3.0|~4.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "time": "2020-09-02T16:06:40+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v3.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "4199685e602129feb82b14279e774af05a4f5dc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/4199685e602129feb82b14279e774af05a4f5dc2", + "reference": "4199685e602129feb82b14279e774af05a4f5dc2", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "time": "2020-09-07T12:07:49+00:00" + }, + { + "name": "symfony/expression-language", + "version": "v3.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "a993849ec82056e976e8cfcfa22ea8f3c47fad19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/a993849ec82056e976e8cfcfa22ea8f3c47fad19", + "reference": "a993849ec82056e976e8cfcfa22ea8f3c47fad19", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ExpressionLanguage Component", + "homepage": "https://symfony.com", + "time": "2020-09-02T16:06:40+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v3.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "495646f13d051cc5a8f77a68b68313dc854080aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/495646f13d051cc5a8f77a68b68313dc854080aa", + "reference": "495646f13d051cc5a8f77a68b68313dc854080aa", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2020-09-02T16:06:40+00:00" + }, + { + "name": "symfony/polyfill-apcu", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-apcu.git", + "reference": "f1d94a98e364f4b84252331a40cb7987b847e241" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/f1d94a98e364f4b84252331a40cb7987b847e241", + "reference": "f1d94a98e364f4b84252331a40cb7987b847e241", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Apcu\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "apcu", + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "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": "2020-07-14T12:35:20+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", + "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "ec3c2ac4d881a4684c1f0317d2107f1a4152bad9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ec3c2ac4d881a4684c1f0317d2107f1a4152bad9", + "reference": "ec3c2ac4d881a4684c1f0317d2107f1a4152bad9", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2020-09-18T15:58:55+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "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-10T14:09:06+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.10.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "451c3cd1418cf640de218914901e51b064abb093" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", + "reference": "451c3cd1418cf640de218914901e51b064abb093", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5 || ^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-03-05T15:02:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" + }, + "require-dev": { + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-xdebug": "^2.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-04-02T07:44:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "abandoned": true, + "time": "2017-12-04T08:55:13+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-02-01T05:50:59+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "abandoned": true, + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-11-26T07:53:53+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "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" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-02-18T15:18:39+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-07-08T17:02:28+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.6.0" + }, + "platform-dev": [], + "platform-overrides": { + "php": "5.6.0" + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/src/DependencyInjection/ContainerProvider.php b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/src/DependencyInjection/ContainerProvider.php new file mode 100644 index 00000000..5f565228 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/src/DependencyInjection/ContainerProvider.php @@ -0,0 +1,100 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ + +namespace PrestaShop\ModuleLibServiceContainer\DependencyInjection; + +use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class ContainerProvider +{ + /** + * @var string Module Name + */ + private $moduleName; + + /** + * @var string Module Local Path + */ + private $moduleLocalPath; + + /** + * @var CacheDirectoryProvider + */ + private $cacheDirectory; + + /** + * @param string $moduleName + * @param string $moduleLocalPath + * @param CacheDirectoryProvider $cacheDirectory + */ + public function __construct($moduleName, $moduleLocalPath, CacheDirectoryProvider $cacheDirectory) + { + $this->moduleName = $moduleName; + $this->moduleLocalPath = $moduleLocalPath; + $this->cacheDirectory = $cacheDirectory; + } + + /** + * @param string $containerName + * + * @return ContainerInterface + */ + public function get($containerName) + { + $containerClassName = ucfirst($this->moduleName) + . ucfirst($containerName) + . 'Container' + ; + $containerFilePath = $this->cacheDirectory->getPath() . '/' . $containerClassName . '.php'; + $containerConfigCache = new ConfigCache($containerFilePath, _PS_MODE_DEV_); + + if ($containerConfigCache->isFresh()) { + require_once $containerFilePath; + + return new $containerClassName(); + } + + $containerBuilder = new ContainerBuilder(); + $containerBuilder->set( + $this->moduleName . '.cache.directory', + $this->cacheDirectory + ); + $moduleConfigPath = $this->moduleLocalPath + . 'config/' + . $containerName + ; + $loader = new YamlFileLoader($containerBuilder, new FileLocator($moduleConfigPath)); + $loader->load('services.yml'); + $containerBuilder->compile(); + $dumper = new PhpDumper($containerBuilder); + $containerConfigCache->write( + $dumper->dump(['class' => $containerClassName]), + $containerBuilder->getResources() + ); + + return $containerBuilder; + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/src/DependencyInjection/ServiceContainer.php b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/src/DependencyInjection/ServiceContainer.php new file mode 100644 index 00000000..10dbf4b8 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/src/DependencyInjection/ServiceContainer.php @@ -0,0 +1,81 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ + +namespace PrestaShop\ModuleLibServiceContainer\DependencyInjection; + +use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider; +use Symfony\Component\DependencyInjection\ContainerInterface; + +class ServiceContainer +{ + /** + * @var string Module Name + */ + private $moduleName; + + /** + * @var string Module Local Path + */ + private $moduleLocalPath; + + /** + * @var ContainerInterface + */ + private $container; + + /** + * @param string $moduleName + * @param string $moduleLocalPath + */ + public function __construct($moduleName, $moduleLocalPath) + { + $this->moduleName = $moduleName; + $this->moduleLocalPath = $moduleLocalPath; + } + + /** + * @param string $serviceName + * + * @return object|null + */ + public function getService($serviceName) + { + if (null === $this->container) { + $this->initContainer(); + } + + return $this->container->get($serviceName); + } + + /** + * Instantiate a new ContainerProvider + */ + private function initContainer() + { + $cacheDirectory = new CacheDirectoryProvider( + _PS_VERSION_, + _PS_ROOT_DIR_, + _PS_MODE_DEV_ + ); + $containerProvider = new ContainerProvider($this->moduleName, $this->moduleLocalPath, $cacheDirectory); + + $this->container = $containerProvider->get(defined('_PS_ADMIN_DIR_') || defined('PS_INSTALLATION_IN_PROGRESS') || PHP_SAPI === 'cli' ? 'admin' : 'front'); + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/DependencyInjection/ContainerProviderTest.php b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/DependencyInjection/ContainerProviderTest.php new file mode 100644 index 00000000..d51ad011 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/DependencyInjection/ContainerProviderTest.php @@ -0,0 +1,36 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ +namespace Tests\Unit\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider; +use PrestaShop\ModuleLibServiceContainer\DependencyInjection\ContainerProvider; + +class ContainerProviderTest extends TestCase +{ + public function testItIsReturnValidInstance() + { + /** @var CacheDirectoryProvider $cacheDirectory */ + $cacheDirectory = $this->createMock(CacheDirectoryProvider::class); + $containerProvider = new ContainerProvider('test', __DIR__, $cacheDirectory); + + $this->assertInstanceOf(ContainerProvider::class, $containerProvider); + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/DependencyInjection/ServiceContainerTest.php b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/DependencyInjection/ServiceContainerTest.php new file mode 100644 index 00000000..5aff9eb2 --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/DependencyInjection/ServiceContainerTest.php @@ -0,0 +1,33 @@ + + * @copyright Since 2007 PrestaShop SA and Contributors + * @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0) + */ +namespace Tests\Unit\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use PrestaShop\ModuleLibServiceContainer\DependencyInjection\ServiceContainer; + +class ServiceContainerTest extends TestCase +{ + public function testItIsReturnValidInstance() + { + $serviceContainer = new ServiceContainer('test', __DIR__); + + $this->assertInstanceOf(ServiceContainer::class, $serviceContainer); + } +} diff --git a/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/phpunit.xml b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/phpunit.xml new file mode 100644 index 00000000..e11b811b --- /dev/null +++ b/modules/empikmarketplace/vendor/prestashop/module-lib-service-container/tests/Unit/phpunit.xml @@ -0,0 +1,9 @@ + + + + . + + + diff --git a/modules/empikmarketplace/vendor/psr/cache/CHANGELOG.md b/modules/empikmarketplace/vendor/psr/cache/CHANGELOG.md new file mode 100644 index 00000000..58ddab05 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/cache/CHANGELOG.md @@ -0,0 +1,16 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 1.0.1 - 2016-08-06 + +### Fixed + +- Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr +- Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr +- Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell +- For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell + +## 1.0.0 - 2015-12-11 + +Initial stable release; reflects accepted PSR-6 specification diff --git a/modules/empikmarketplace/vendor/psr/cache/LICENSE.txt b/modules/empikmarketplace/vendor/psr/cache/LICENSE.txt new file mode 100644 index 00000000..b1c2c97b --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/cache/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2015 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/psr/cache/README.md b/modules/empikmarketplace/vendor/psr/cache/README.md new file mode 100644 index 00000000..c8706cee --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/cache/README.md @@ -0,0 +1,9 @@ +PSR Cache +========= + +This repository holds all interfaces defined by +[PSR-6](http://www.php-fig.org/psr/psr-6/). + +Note that this is not a Cache implementation of its own. It is merely an +interface that describes a Cache implementation. See the specification for more +details. diff --git a/modules/empikmarketplace/vendor/psr/cache/composer.json b/modules/empikmarketplace/vendor/psr/cache/composer.json new file mode 100644 index 00000000..e828fec9 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/cache/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/cache", + "description": "Common interface for caching libraries", + "keywords": ["psr", "psr-6", "cache"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/modules/empikmarketplace/vendor/psr/cache/src/CacheException.php b/modules/empikmarketplace/vendor/psr/cache/src/CacheException.php new file mode 100644 index 00000000..e27f22f8 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/cache/src/CacheException.php @@ -0,0 +1,10 @@ +=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/modules/empikmarketplace/vendor/psr/container/src/ContainerExceptionInterface.php b/modules/empikmarketplace/vendor/psr/container/src/ContainerExceptionInterface.php new file mode 100644 index 00000000..d35c6b4d --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/container/src/ContainerExceptionInterface.php @@ -0,0 +1,13 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param mixed[] $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/modules/empikmarketplace/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/modules/empikmarketplace/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 00000000..67f852d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/modules/empikmarketplace/vendor/psr/log/Psr/Log/LoggerInterface.php b/modules/empikmarketplace/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 00000000..2206cfde --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,125 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/modules/empikmarketplace/vendor/psr/log/Psr/Log/NullLogger.php b/modules/empikmarketplace/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 00000000..c8f7293b --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,30 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + * + * @throws \Psr\Log\InvalidArgumentException + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/modules/empikmarketplace/vendor/psr/log/Psr/Log/Test/DummyTest.php b/modules/empikmarketplace/vendor/psr/log/Psr/Log/Test/DummyTest.php new file mode 100644 index 00000000..9638c110 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/Psr/Log/Test/DummyTest.php @@ -0,0 +1,18 @@ + ". + * + * Example ->error('Foo') would yield "error Foo". + * + * @return string[] + */ + abstract public function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $closed = fopen('php://memory', 'r'); + fclose($closed); + + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); + } +} diff --git a/modules/empikmarketplace/vendor/psr/log/Psr/Log/Test/TestLogger.php b/modules/empikmarketplace/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 00000000..1be32304 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,147 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } +} diff --git a/modules/empikmarketplace/vendor/psr/log/README.md b/modules/empikmarketplace/vendor/psr/log/README.md new file mode 100644 index 00000000..a9f20c43 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/README.md @@ -0,0 +1,58 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Installation +------------ + +```bash +composer require psr/log +``` + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + try { + $this->doSomethingElse(); + } catch (Exception $exception) { + $this->logger->error('Oh no!', array('exception' => $exception)); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/modules/empikmarketplace/vendor/psr/log/composer.json b/modules/empikmarketplace/vendor/psr/log/composer.json new file mode 100644 index 00000000..ca056953 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + } +} diff --git a/modules/empikmarketplace/vendor/psr/simple-cache/.editorconfig b/modules/empikmarketplace/vendor/psr/simple-cache/.editorconfig new file mode 100644 index 00000000..48542cbb --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/simple-cache/.editorconfig @@ -0,0 +1,12 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/modules/empikmarketplace/vendor/psr/simple-cache/LICENSE.md b/modules/empikmarketplace/vendor/psr/simple-cache/LICENSE.md new file mode 100644 index 00000000..e49a7c85 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/simple-cache/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2016 PHP Framework Interoperability Group + +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/psr/simple-cache/README.md b/modules/empikmarketplace/vendor/psr/simple-cache/README.md new file mode 100644 index 00000000..43641d17 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/simple-cache/README.md @@ -0,0 +1,8 @@ +PHP FIG Simple Cache PSR +======================== + +This repository holds all interfaces related to PSR-16. + +Note that this is not a cache implementation of its own. It is merely an interface that describes a cache implementation. See [the specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) for more details. + +You can find implementations of the specification by looking for packages providing the [psr/simple-cache-implementation](https://packagist.org/providers/psr/simple-cache-implementation) virtual package. diff --git a/modules/empikmarketplace/vendor/psr/simple-cache/composer.json b/modules/empikmarketplace/vendor/psr/simple-cache/composer.json new file mode 100644 index 00000000..2978fa55 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/simple-cache/composer.json @@ -0,0 +1,25 @@ +{ + "name": "psr/simple-cache", + "description": "Common interfaces for simple caching", + "keywords": ["psr", "psr-16", "cache", "simple-cache", "caching"], + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/modules/empikmarketplace/vendor/psr/simple-cache/src/CacheException.php b/modules/empikmarketplace/vendor/psr/simple-cache/src/CacheException.php new file mode 100644 index 00000000..eba53815 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/simple-cache/src/CacheException.php @@ -0,0 +1,10 @@ + value pairs. Cache keys that do not exist or are stale will have $default as value. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if $keys is neither an array nor a Traversable, + * or if any of the $keys are not a legal value. + */ + public function getMultiple($keys, $default = null); + + /** + * Persists a set of key => value pairs in the cache, with an optional TTL. + * + * @param iterable $values A list of key => value pairs for a multiple-set operation. + * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and + * the driver supports TTL then the library may set a default value + * for it or let the driver take care of that. + * + * @return bool True on success and false on failure. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if $values is neither an array nor a Traversable, + * or if any of the $values are not a legal value. + */ + public function setMultiple($values, $ttl = null); + + /** + * Deletes multiple cache items in a single operation. + * + * @param iterable $keys A list of string-based keys to be deleted. + * + * @return bool True if the items were successfully removed. False if there was an error. + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if $keys is neither an array nor a Traversable, + * or if any of the $keys are not a legal value. + */ + public function deleteMultiple($keys); + + /** + * Determines whether an item is present in the cache. + * + * NOTE: It is recommended that has() is only to be used for cache warming type purposes + * and not to be used within your live applications operations for get/set, as this method + * is subject to a race condition where your has() will return true and immediately after, + * another script can remove it making the state of your app out of date. + * + * @param string $key The cache item key. + * + * @return bool + * + * @throws \Psr\SimpleCache\InvalidArgumentException + * MUST be thrown if the $key string is not a legal value. + */ + public function has($key); +} diff --git a/modules/empikmarketplace/vendor/psr/simple-cache/src/InvalidArgumentException.php b/modules/empikmarketplace/vendor/psr/simple-cache/src/InvalidArgumentException.php new file mode 100644 index 00000000..6a9524a2 --- /dev/null +++ b/modules/empikmarketplace/vendor/psr/simple-cache/src/InvalidArgumentException.php @@ -0,0 +1,13 @@ +otherwise(function (OverflowException|UnderflowException $e) { + echo 'Error: ' . $e->getMessage() . PHP_EOL; + }); + ``` + + * Feature: Support intersection types (PHP 8.1+). + (#195 by @bzikarsky) + + ```php + $promise->otherwise(function (OverflowException&CacheException $e) { + echo 'Error: ' . $e->getMessage() . PHP_EOL; + }); + ``` + + * Improve test suite, use GitHub actions for continuous integration (CI), + update to PHPUnit 9, and add full core team to the license. + (#174, #183, #186, and #201 by @SimonFrings and #211 by @clue) + +* 2.8.0 (2020-05-12) + + * Mark `FulfilledPromise`, `RejectedPromise` and `LazyPromise` as deprecated for Promise v2 (and remove for Promise v3). + (#143 and #165 by @clue) + + ```php + // deprecated + $fulfilled = new React\Promise\FulfilledPromise($value); + $rejected = new React\Promise\RejectedPromise($reason); + + // recommended alternatives + $fulfilled = React\Promise\resolve($value); + $rejected = React\Promise\reject($reason); + ``` + + * Fix: Fix checking whether cancellable promise is an object and avoid possible warning. + (#168 by @smscr and @jsor) + + * Improve documentation and add docblocks to functions and interfaces. + (#135 by @CharlotteDunois) + + * Add `.gitattributes` to exclude dev files from exports. + (#154 by @reedy) + + * Improve test suite, run tests on PHP 7.4 and update PHPUnit test setup. + (#163 by @clue) + +* 2.7.1 (2018-01-07) + + * Fix: file_exists warning when resolving with long strings. + (#130 by @sbesselsen) + * Improve performance by prefixing all global functions calls with \ to skip the look up and resolve process and go straight to the global function. + (#133 by @WyriHaximus) + +* 2.7.0 (2018-06-13) + + * Feature: Improve memory consumption for pending promises by using static internal callbacks without binding to self. + (#124 by @clue) + +* 2.6.0 (2018-06-11) + + * Feature: Significantly improve memory consumption and performance by only passing resolver args + to resolver and canceller if callback requires them. Also use static callbacks without + binding to promise, clean up canceller function reference when they are no longer + needed and hide resolver and canceller references from call stack on PHP 7+. + (#113, #115, #116, #117, #118, #119 and #123 by @clue) + + These changes combined mean that rejecting promises with an `Exception` should + no longer cause any internal circular references which could cause some unexpected + memory growth in previous versions. By explicitly avoiding and explicitly + cleaning up said references, we can avoid relying on PHP's circular garbage collector + to kick in which significantly improves performance when rejecting many promises. + + * Mark legacy progress support / notification API as deprecated + (#112 by @clue) + + * Recommend rejecting promises by throwing an exception + (#114 by @jsor) + + * Improve documentation to properly instantiate LazyPromise + (#121 by @holtkamp) + + * Follower cancellation propagation was originally planned for this release + but has been reverted for now and is planned for a future release. + (#99 by @jsor and #122 by @clue) + +* 2.5.1 (2017-03-25) + + * Fix circular references when resolving with a promise which follows + itself (#94). + +* 2.5.0 (2016-12-22) + + * Revert automatic cancellation of pending collection promises once the + output promise resolves. This was introduced in 42d86b7 (PR #36, released + in [v2.3.0](https://github.com/reactphp/promise/releases/tag/v2.3.0)) and + was both unintended and backward incompatible. + + If you need automatic cancellation, you can use something like: + + ```php + function allAndCancel(array $promises) + { + return \React\Promise\all($promises) + ->always(function() use ($promises) { + foreach ($promises as $promise) { + if ($promise instanceof \React\Promise\CancellablePromiseInterface) { + $promise->cancel(); + } + } + }); + } + ``` + * `all()` and `map()` functions now preserve the order of the array (#77). + * Fix circular references when resolving a promise with itself (#71). + +* 2.4.1 (2016-05-03) + + * Fix `some()` not cancelling pending promises when too much input promises + reject (16ff799). + +* 2.4.0 (2016-03-31) + + * Support foreign thenables in `resolve()`. + Any object that provides a `then()` method is now assimilated to a trusted + promise that follows the state of this thenable (#52). + * Fix `some()` and `any()` for input arrays containing not enough items + (#34). + +* 2.3.0 (2016-03-24) + + * Allow cancellation of promises returned by functions working on promise + collections (#36). + * Handle `\Throwable` in the same way as `\Exception` (#51 by @joshdifabio). + +* 2.2.2 (2016-02-26) + + * Fix cancellation handlers called multiple times (#47 by @clue). + +* 2.2.1 (2015-07-03) + + * Fix stack error when resolving a promise in its own fulfillment or + rejection handlers. + +* 2.2.0 (2014-12-30) + + * Introduce new `ExtendedPromiseInterface` implemented by all promises. + * Add new `done()` method (part of the `ExtendedPromiseInterface`). + * Add new `otherwise()` method (part of the `ExtendedPromiseInterface`). + * Add new `always()` method (part of the `ExtendedPromiseInterface`). + * Add new `progress()` method (part of the `ExtendedPromiseInterface`). + * Rename `Deferred::progress` to `Deferred::notify` to avoid confusion with + `ExtendedPromiseInterface::progress` (a `Deferred::progress` alias is + still available for backward compatibility) + * `resolve()` now always returns a `ExtendedPromiseInterface`. + +* 2.1.0 (2014-10-15) + + * Introduce new `CancellablePromiseInterface` implemented by all promises. + * Add new `cancel()` method (part of the `CancellablePromiseInterface`). + +* 2.0.0 (2013-12-10) + + New major release. The goal is to streamline the API and to make it more + compliant with other promise libraries and especially with the new upcoming + [ES6 promises specification](https://github.com/domenic/promises-unwrapping/). + + * Add standalone Promise class. + * Add new `race()` function. + * BC break: Bump minimum PHP version to PHP 5.4. + * BC break: Remove `ResolverInterface` and `PromiseInterface` from + `Deferred`. + * BC break: Change signature of `PromiseInterface`. + * BC break: Remove `When` and `Util` classes and move static methods to + functions. + * BC break: `FulfilledPromise` and `RejectedPromise` now throw an exception + when initialized with a promise instead of a value/reason. + * BC break: `Deferred::resolve()` and `Deferred::reject()` no longer return + a promise. diff --git a/modules/empikmarketplace/vendor/react/promise/LICENSE b/modules/empikmarketplace/vendor/react/promise/LICENSE new file mode 100644 index 00000000..21c1357b --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/LICENSE @@ -0,0 +1,24 @@ +The MIT License (MIT) + +Copyright (c) 2012 Jan Sorgalla, Christian Lück, Cees-Jan Kiewiet, Chris Boden + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/react/promise/README.md b/modules/empikmarketplace/vendor/react/promise/README.md new file mode 100644 index 00000000..d904a1d8 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/README.md @@ -0,0 +1,874 @@ +Promise +======= + +A lightweight implementation of +[CommonJS Promises/A](http://wiki.commonjs.org/wiki/Promises/A) for PHP. + +[![CI status](https://github.com/reactphp/promise/workflows/CI/badge.svg?branch=2.x)](https://github.com/reactphp/promise/actions) + +Table of Contents +----------------- + +1. [Introduction](#introduction) +2. [Concepts](#concepts) + * [Deferred](#deferred) + * [Promise](#promise-1) +3. [API](#api) + * [Deferred](#deferred-1) + * [Deferred::promise()](#deferredpromise) + * [Deferred::resolve()](#deferredresolve) + * [Deferred::reject()](#deferredreject) + * [Deferred::notify()](#deferrednotify) + * [PromiseInterface](#promiseinterface) + * [PromiseInterface::then()](#promiseinterfacethen) + * [ExtendedPromiseInterface](#extendedpromiseinterface) + * [ExtendedPromiseInterface::done()](#extendedpromiseinterfacedone) + * [ExtendedPromiseInterface::otherwise()](#extendedpromiseinterfaceotherwise) + * [ExtendedPromiseInterface::always()](#extendedpromiseinterfacealways) + * [ExtendedPromiseInterface::progress()](#extendedpromiseinterfaceprogress) + * [CancellablePromiseInterface](#cancellablepromiseinterface) + * [CancellablePromiseInterface::cancel()](#cancellablepromiseinterfacecancel) + * [Promise](#promise-2) + * [FulfilledPromise](#fulfilledpromise) + * [RejectedPromise](#rejectedpromise) + * [LazyPromise](#lazypromise) + * [Functions](#functions) + * [resolve()](#resolve) + * [reject()](#reject) + * [all()](#all) + * [race()](#race) + * [any()](#any) + * [some()](#some) + * [map()](#map) + * [reduce()](#reduce) + * [PromisorInterface](#promisorinterface) +4. [Examples](#examples) + * [How to use Deferred](#how-to-use-deferred) + * [How promise forwarding works](#how-promise-forwarding-works) + * [Resolution forwarding](#resolution-forwarding) + * [Rejection forwarding](#rejection-forwarding) + * [Mixed resolution and rejection forwarding](#mixed-resolution-and-rejection-forwarding) + * [Progress event forwarding](#progress-event-forwarding) + * [done() vs. then()](#done-vs-then) +5. [Install](#install) +6. [Credits](#credits) +7. [License](#license) + +Introduction +------------ + +Promise is a library implementing +[CommonJS Promises/A](http://wiki.commonjs.org/wiki/Promises/A) for PHP. + +It also provides several other useful promise-related concepts, such as joining +multiple promises and mapping and reducing collections of promises. + +If you've never heard about promises before, +[read this first](https://gist.github.com/3889970). + +Concepts +-------- + +### Deferred + +A **Deferred** represents a computation or unit of work that may not have +completed yet. Typically (but not always), that computation will be something +that executes asynchronously and completes at some point in the future. + +### Promise + +While a deferred represents the computation itself, a **Promise** represents +the result of that computation. Thus, each deferred has a promise that acts as +a placeholder for its actual result. + +API +--- + +### Deferred + +A deferred represents an operation whose resolution is pending. It has separate +promise and resolver parts. + +```php +$deferred = new React\Promise\Deferred(); + +$promise = $deferred->promise(); + +$deferred->resolve(mixed $value = null); +$deferred->reject(mixed $reason = null); +$deferred->notify(mixed $update = null); +``` + +The `promise` method returns the promise of the deferred. + +The `resolve` and `reject` methods control the state of the deferred. + +The deprecated `notify` method is for progress notification. + +The constructor of the `Deferred` accepts an optional `$canceller` argument. +See [Promise](#promise-2) for more information. + +#### Deferred::promise() + +```php +$promise = $deferred->promise(); +``` + +Returns the promise of the deferred, which you can hand out to others while +keeping the authority to modify its state to yourself. + +#### Deferred::resolve() + +```php +$deferred->resolve(mixed $value = null); +``` + +Resolves the promise returned by `promise()`. All consumers are notified by +having `$onFulfilled` (which they registered via `$promise->then()`) called with +`$value`. + +If `$value` itself is a promise, the promise will transition to the state of +this promise once it is resolved. + +#### Deferred::reject() + +```php +$deferred->reject(mixed $reason = null); +``` + +Rejects the promise returned by `promise()`, signalling that the deferred's +computation failed. +All consumers are notified by having `$onRejected` (which they registered via +`$promise->then()`) called with `$reason`. + +If `$reason` itself is a promise, the promise will be rejected with the outcome +of this promise regardless whether it fulfills or rejects. + +#### Deferred::notify() + +> Deprecated in v2.6.0: Progress support is deprecated and should not be used anymore. + +```php +$deferred->notify(mixed $update = null); +``` + +Triggers progress notifications, to indicate to consumers that the computation +is making progress toward its result. + +All consumers are notified by having `$onProgress` (which they registered via +`$promise->then()`) called with `$update`. + +### PromiseInterface + +The promise interface provides the common interface for all promise +implementations. + +A promise represents an eventual outcome, which is either fulfillment (success) +and an associated value, or rejection (failure) and an associated reason. + +Once in the fulfilled or rejected state, a promise becomes immutable. +Neither its state nor its result (or error) can be modified. + +#### Implementations + +* [Promise](#promise-2) +* [FulfilledPromise](#fulfilledpromise) (deprecated) +* [RejectedPromise](#rejectedpromise) (deprecated) +* [LazyPromise](#lazypromise) (deprecated) + +#### PromiseInterface::then() + +```php +$transformedPromise = $promise->then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null); +``` + +Transforms a promise's value by applying a function to the promise's fulfillment +or rejection value. Returns a new promise for the transformed result. + +The `then()` method registers new fulfilled, rejection and progress handlers +with a promise (all parameters are optional): + + * `$onFulfilled` will be invoked once the promise is fulfilled and passed + the result as the first argument. + * `$onRejected` will be invoked once the promise is rejected and passed the + reason as the first argument. + * `$onProgress` (deprecated) will be invoked whenever the producer of the promise + triggers progress notifications and passed a single argument (whatever it + wants) to indicate progress. + +It returns a new promise that will fulfill with the return value of either +`$onFulfilled` or `$onRejected`, whichever is called, or will reject with +the thrown exception if either throws. + +A promise makes the following guarantees about handlers registered in +the same call to `then()`: + + 1. Only one of `$onFulfilled` or `$onRejected` will be called, + never both. + 2. `$onFulfilled` and `$onRejected` will never be called more + than once. + 3. `$onProgress` (deprecated) may be called multiple times. + +#### See also + +* [resolve()](#resolve) - Creating a resolved promise +* [reject()](#reject) - Creating a rejected promise +* [ExtendedPromiseInterface::done()](#extendedpromiseinterfacedone) +* [done() vs. then()](#done-vs-then) + +### ExtendedPromiseInterface + +The ExtendedPromiseInterface extends the PromiseInterface with useful shortcut +and utility methods which are not part of the Promises/A specification. + +#### Implementations + +* [Promise](#promise-1) +* [FulfilledPromise](#fulfilledpromise) (deprecated) +* [RejectedPromise](#rejectedpromise) (deprecated) +* [LazyPromise](#lazypromise) (deprecated) + +#### ExtendedPromiseInterface::done() + +```php +$promise->done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null); +``` + +Consumes the promise's ultimate value if the promise fulfills, or handles the +ultimate error. + +It will cause a fatal error if either `$onFulfilled` or `$onRejected` throw or +return a rejected promise. + +Since the purpose of `done()` is consumption rather than transformation, +`done()` always returns `null`. + +#### See also + +* [PromiseInterface::then()](#promiseinterfacethen) +* [done() vs. then()](#done-vs-then) + +#### ExtendedPromiseInterface::otherwise() + +```php +$promise->otherwise(callable $onRejected); +``` + +Registers a rejection handler for promise. It is a shortcut for: + +```php +$promise->then(null, $onRejected); +``` + +Additionally, you can type hint the `$reason` argument of `$onRejected` to catch +only specific errors. + +```php +$promise + ->otherwise(function (\RuntimeException $reason) { + // Only catch \RuntimeException instances + // All other types of errors will propagate automatically + }) + ->otherwise(function ($reason) { + // Catch other errors + )}; +``` + +#### ExtendedPromiseInterface::always() + +```php +$newPromise = $promise->always(callable $onFulfilledOrRejected); +``` + +Allows you to execute "cleanup" type tasks in a promise chain. + +It arranges for `$onFulfilledOrRejected` to be called, with no arguments, +when the promise is either fulfilled or rejected. + +* If `$promise` fulfills, and `$onFulfilledOrRejected` returns successfully, + `$newPromise` will fulfill with the same value as `$promise`. +* If `$promise` fulfills, and `$onFulfilledOrRejected` throws or returns a + rejected promise, `$newPromise` will reject with the thrown exception or + rejected promise's reason. +* If `$promise` rejects, and `$onFulfilledOrRejected` returns successfully, + `$newPromise` will reject with the same reason as `$promise`. +* If `$promise` rejects, and `$onFulfilledOrRejected` throws or returns a + rejected promise, `$newPromise` will reject with the thrown exception or + rejected promise's reason. + +`always()` behaves similarly to the synchronous finally statement. When combined +with `otherwise()`, `always()` allows you to write code that is similar to the familiar +synchronous catch/finally pair. + +Consider the following synchronous code: + +```php +try { + return doSomething(); +} catch(\Exception $e) { + return handleError($e); +} finally { + cleanup(); +} +``` + +Similar asynchronous code (with `doSomething()` that returns a promise) can be +written: + +```php +return doSomething() + ->otherwise('handleError') + ->always('cleanup'); +``` + +#### ExtendedPromiseInterface::progress() + +> Deprecated in v2.6.0: Progress support is deprecated and should not be used anymore. + +```php +$promise->progress(callable $onProgress); +``` + +Registers a handler for progress updates from promise. It is a shortcut for: + +```php +$promise->then(null, null, $onProgress); +``` + +### CancellablePromiseInterface + +A cancellable promise provides a mechanism for consumers to notify the creator +of the promise that they are not longer interested in the result of an +operation. + +#### CancellablePromiseInterface::cancel() + +``` php +$promise->cancel(); +``` + +The `cancel()` method notifies the creator of the promise that there is no +further interest in the results of the operation. + +Once a promise is settled (either fulfilled or rejected), calling `cancel()` on +a promise has no effect. + +#### Implementations + +* [Promise](#promise-1) +* [FulfilledPromise](#fulfilledpromise) (deprecated) +* [RejectedPromise](#rejectedpromise) (deprecated) +* [LazyPromise](#lazypromise) (deprecated) + +### Promise + +Creates a promise whose state is controlled by the functions passed to +`$resolver`. + +```php +$resolver = function (callable $resolve, callable $reject, callable $notify) { + // Do some work, possibly asynchronously, and then + // resolve or reject. You can notify of progress events (deprecated) + // along the way if you want/need. + + $resolve($awesomeResult); + // or throw new Exception('Promise rejected'); + // or $resolve($anotherPromise); + // or $reject($nastyError); + // or $notify($progressNotification); +}; + +$canceller = function () { + // Cancel/abort any running operations like network connections, streams etc. + + // Reject promise by throwing an exception + throw new Exception('Promise cancelled'); +}; + +$promise = new React\Promise\Promise($resolver, $canceller); +``` + +The promise constructor receives a resolver function and an optional canceller +function which both will be called with 3 arguments: + + * `$resolve($value)` - Primary function that seals the fate of the + returned promise. Accepts either a non-promise value, or another promise. + When called with a non-promise value, fulfills promise with that value. + When called with another promise, e.g. `$resolve($otherPromise)`, promise's + fate will be equivalent to that of `$otherPromise`. + * `$reject($reason)` - Function that rejects the promise. It is recommended to + just throw an exception instead of using `$reject()`. + * `$notify($update)` - Deprecated function that issues progress events for the promise. + +If the resolver or canceller throw an exception, the promise will be rejected +with that thrown exception as the rejection reason. + +The resolver function will be called immediately, the canceller function only +once all consumers called the `cancel()` method of the promise. + +### FulfilledPromise + +> Deprecated in v2.8.0: External usage of `FulfilledPromise` is deprecated, use `resolve()` instead. + +Creates a already fulfilled promise. + +```php +$promise = React\Promise\FulfilledPromise($value); +``` + +Note, that `$value` **cannot** be a promise. It's recommended to use +[resolve()](#resolve) for creating resolved promises. + +### RejectedPromise + +> Deprecated in v2.8.0: External usage of `RejectedPromise` is deprecated, use `reject()` instead. + +Creates a already rejected promise. + +```php +$promise = React\Promise\RejectedPromise($reason); +``` + +Note, that `$reason` **cannot** be a promise. It's recommended to use +[reject()](#reject) for creating rejected promises. + +### LazyPromise + +> Deprecated in v2.8.0: LazyPromise is deprecated and should not be used anymore. + +Creates a promise which will be lazily initialized by `$factory` once a consumer +calls the `then()` method. + +```php +$factory = function () { + $deferred = new React\Promise\Deferred(); + + // Do some heavy stuff here and resolve the deferred once completed + + return $deferred->promise(); +}; + +$promise = new React\Promise\LazyPromise($factory); + +// $factory will only be executed once we call then() +$promise->then(function ($value) { +}); +``` + +### Functions + +Useful functions for creating, joining, mapping and reducing collections of +promises. + +All functions working on promise collections (like `all()`, `race()`, `some()` +etc.) support cancellation. This means, if you call `cancel()` on the returned +promise, all promises in the collection are cancelled. If the collection itself +is a promise which resolves to an array, this promise is also cancelled. + +#### resolve() + +```php +$promise = React\Promise\resolve(mixed $promiseOrValue); +``` + +Creates a promise for the supplied `$promiseOrValue`. + +If `$promiseOrValue` is a value, it will be the resolution value of the +returned promise. + +If `$promiseOrValue` is a thenable (any object that provides a `then()` method), +a trusted promise that follows the state of the thenable is returned. + +If `$promiseOrValue` is a promise, it will be returned as is. + +Note: The promise returned is always a promise implementing +[ExtendedPromiseInterface](#extendedpromiseinterface). If you pass in a custom +promise which only implements [PromiseInterface](#promiseinterface), this +promise will be assimilated to a extended promise following `$promiseOrValue`. + +#### reject() + +```php +$promise = React\Promise\reject(mixed $promiseOrValue); +``` + +Creates a rejected promise for the supplied `$promiseOrValue`. + +If `$promiseOrValue` is a value, it will be the rejection value of the +returned promise. + +If `$promiseOrValue` is a promise, its completion value will be the rejected +value of the returned promise. + +This can be useful in situations where you need to reject a promise without +throwing an exception. For example, it allows you to propagate a rejection with +the value of another promise. + +#### all() + +```php +$promise = React\Promise\all(array|React\Promise\PromiseInterface $promisesOrValues); +``` + +Returns a promise that will resolve only once all the items in +`$promisesOrValues` have resolved. The resolution value of the returned promise +will be an array containing the resolution values of each of the items in +`$promisesOrValues`. + +#### race() + +```php +$promise = React\Promise\race(array|React\Promise\PromiseInterface $promisesOrValues); +``` + +Initiates a competitive race that allows one winner. Returns a promise which is +resolved in the same way the first settled promise resolves. + +#### any() + +```php +$promise = React\Promise\any(array|React\Promise\PromiseInterface $promisesOrValues); +``` + +Returns a promise that will resolve when any one of the items in +`$promisesOrValues` resolves. The resolution value of the returned promise +will be the resolution value of the triggering item. + +The returned promise will only reject if *all* items in `$promisesOrValues` are +rejected. The rejection value will be an array of all rejection reasons. + +The returned promise will also reject with a `React\Promise\Exception\LengthException` +if `$promisesOrValues` contains 0 items. + +#### some() + +```php +$promise = React\Promise\some(array|React\Promise\PromiseInterface $promisesOrValues, integer $howMany); +``` + +Returns a promise that will resolve when `$howMany` of the supplied items in +`$promisesOrValues` resolve. The resolution value of the returned promise +will be an array of length `$howMany` containing the resolution values of the +triggering items. + +The returned promise will reject if it becomes impossible for `$howMany` items +to resolve (that is, when `(count($promisesOrValues) - $howMany) + 1` items +reject). The rejection value will be an array of +`(count($promisesOrValues) - $howMany) + 1` rejection reasons. + +The returned promise will also reject with a `React\Promise\Exception\LengthException` +if `$promisesOrValues` contains less items than `$howMany`. + +#### map() + +```php +$promise = React\Promise\map(array|React\Promise\PromiseInterface $promisesOrValues, callable $mapFunc); +``` + +Traditional map function, similar to `array_map()`, but allows input to contain +promises and/or values, and `$mapFunc` may return either a value or a promise. + +The map function receives each item as argument, where item is a fully resolved +value of a promise or value in `$promisesOrValues`. + +#### reduce() + +```php +$promise = React\Promise\reduce(array|React\Promise\PromiseInterface $promisesOrValues, callable $reduceFunc , $initialValue = null); +``` + +Traditional reduce function, similar to `array_reduce()`, but input may contain +promises and/or values, and `$reduceFunc` may return either a value or a +promise, *and* `$initialValue` may be a promise or a value for the starting +value. + +### PromisorInterface + +The `React\Promise\PromisorInterface` provides a common interface for objects +that provide a promise. `React\Promise\Deferred` implements it, but since it +is part of the public API anyone can implement it. + +Examples +-------- + +### How to use Deferred + +```php +function getAwesomeResultPromise() +{ + $deferred = new React\Promise\Deferred(); + + // Execute a Node.js-style function using the callback pattern + computeAwesomeResultAsynchronously(function ($error, $result) use ($deferred) { + if ($error) { + $deferred->reject($error); + } else { + $deferred->resolve($result); + } + }); + + // Return the promise + return $deferred->promise(); +} + +getAwesomeResultPromise() + ->then( + function ($value) { + // Deferred resolved, do something with $value + }, + function ($reason) { + // Deferred rejected, do something with $reason + }, + function ($update) { + // Progress notification triggered, do something with $update + } + ); +``` + +### How promise forwarding works + +A few simple examples to show how the mechanics of Promises/A forwarding works. +These examples are contrived, of course, and in real usage, promise chains will +typically be spread across several function calls, or even several levels of +your application architecture. + +#### Resolution forwarding + +Resolved promises forward resolution values to the next promise. +The first promise, `$deferred->promise()`, will resolve with the value passed +to `$deferred->resolve()` below. + +Each call to `then()` returns a new promise that will resolve with the return +value of the previous handler. This creates a promise "pipeline". + +```php +$deferred = new React\Promise\Deferred(); + +$deferred->promise() + ->then(function ($x) { + // $x will be the value passed to $deferred->resolve() below + // and returns a *new promise* for $x + 1 + return $x + 1; + }) + ->then(function ($x) { + // $x === 2 + // This handler receives the return value of the + // previous handler. + return $x + 1; + }) + ->then(function ($x) { + // $x === 3 + // This handler receives the return value of the + // previous handler. + return $x + 1; + }) + ->then(function ($x) { + // $x === 4 + // This handler receives the return value of the + // previous handler. + echo 'Resolve ' . $x; + }); + +$deferred->resolve(1); // Prints "Resolve 4" +``` + +#### Rejection forwarding + +Rejected promises behave similarly, and also work similarly to try/catch: +When you catch an exception, you must rethrow for it to propagate. + +Similarly, when you handle a rejected promise, to propagate the rejection, +"rethrow" it by either returning a rejected promise, or actually throwing +(since promise translates thrown exceptions into rejections) + +```php +$deferred = new React\Promise\Deferred(); + +$deferred->promise() + ->then(function ($x) { + throw new \Exception($x + 1); + }) + ->otherwise(function (\Exception $x) { + // Propagate the rejection + throw $x; + }) + ->otherwise(function (\Exception $x) { + // Can also propagate by returning another rejection + return React\Promise\reject( + new \Exception($x->getMessage() + 1) + ); + }) + ->otherwise(function ($x) { + echo 'Reject ' . $x->getMessage(); // 3 + }); + +$deferred->resolve(1); // Prints "Reject 3" +``` + +#### Mixed resolution and rejection forwarding + +Just like try/catch, you can choose to propagate or not. Mixing resolutions and +rejections will still forward handler results in a predictable way. + +```php +$deferred = new React\Promise\Deferred(); + +$deferred->promise() + ->then(function ($x) { + return $x + 1; + }) + ->then(function ($x) { + throw new \Exception($x + 1); + }) + ->otherwise(function (\Exception $x) { + // Handle the rejection, and don't propagate. + // This is like catch without a rethrow + return $x->getMessage() + 1; + }) + ->then(function ($x) { + echo 'Mixed ' . $x; // 4 + }); + +$deferred->resolve(1); // Prints "Mixed 4" +``` + +#### Progress event forwarding + +> Deprecated in v2.6.0: Progress support is deprecated and should not be used anymore. + +In the same way as resolution and rejection handlers, your progress handler +**MUST** return a progress event to be propagated to the next link in the chain. +If you return nothing, `null` will be propagated. + +Also in the same way as resolutions and rejections, if you don't register a +progress handler, the update will be propagated through. + +If your progress handler throws an exception, the exception will be propagated +to the next link in the chain. The best thing to do is to ensure your progress +handlers do not throw exceptions. + +This gives you the opportunity to transform progress events at each step in the +chain so that they are meaningful to the next step. It also allows you to choose +not to transform them, and simply let them propagate untransformed, by not +registering a progress handler. + +```php +$deferred = new React\Promise\Deferred(); + +$deferred->promise() + ->progress(function ($update) { + return $update + 1; + }) + ->progress(function ($update) { + echo 'Progress ' . $update; // 2 + }); + +$deferred->notify(1); // Prints "Progress 2" +``` + +### done() vs. then() + +The golden rule is: + + Either return your promise, or call done() on it. + +At a first glance, `then()` and `done()` seem very similar. However, there are +important distinctions. + +The intent of `then()` is to transform a promise's value and to pass or return +a new promise for the transformed value along to other parts of your code. + +The intent of `done()` is to consume a promise's value, transferring +responsibility for the value to your code. + +In addition to transforming a value, `then()` allows you to recover from, or +propagate intermediate errors. Any errors that are not handled will be caught +by the promise machinery and used to reject the promise returned by `then()`. + +Calling `done()` transfers all responsibility for errors to your code. If an +error (either a thrown exception or returned rejection) escapes the +`$onFulfilled` or `$onRejected` callbacks you provide to done, it will be +rethrown in an uncatchable way causing a fatal error. + +```php +function getJsonResult() +{ + return queryApi() + ->then( + // Transform API results to an object + function ($jsonResultString) { + return json_decode($jsonResultString); + }, + // Transform API errors to an exception + function ($jsonErrorString) { + $object = json_decode($jsonErrorString); + throw new ApiErrorException($object->errorMessage); + } + ); +} + +// Here we provide no rejection handler. If the promise returned has been +// rejected, the ApiErrorException will be thrown +getJsonResult() + ->done( + // Consume transformed object + function ($jsonResultObject) { + // Do something with $jsonResultObject + } + ); + +// Here we provide a rejection handler which will either throw while debugging +// or log the exception +getJsonResult() + ->done( + function ($jsonResultObject) { + // Do something with $jsonResultObject + }, + function (ApiErrorException $exception) { + if (isDebug()) { + throw $exception; + } else { + logException($exception); + } + } + ); +``` + +Note that if a rejection value is not an instance of `\Exception`, it will be +wrapped in an exception of the type `React\Promise\UnhandledRejectionException`. + +You can get the original rejection reason by calling `$exception->getReason()`. + +Install +------- + +The recommended way to install this library is [through Composer](https://getcomposer.org). +[New to Composer?](https://getcomposer.org/doc/00-intro.md) + +This project follows [SemVer](https://semver.org/). +This will install the latest supported version: + +```bash +$ composer require react/promise:^2.9 +``` + +See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. + +This project aims to run on any platform and thus does not require any PHP +extensions and supports running on legacy PHP 5.4 through current PHP 8+ and HHVM. +It's *highly recommended to use the latest supported PHP version* for this project. + +Credits +------- + +Promise is a port of [when.js](https://github.com/cujojs/when) +by [Brian Cavalier](https://github.com/briancavalier). + +Also, large parts of the documentation have been ported from the when.js +[Wiki](https://github.com/cujojs/when/wiki) and the +[API docs](https://github.com/cujojs/when/blob/master/docs/api.md). + +License +------- + +Released under the [MIT](LICENSE) license. diff --git a/modules/empikmarketplace/vendor/react/promise/composer.json b/modules/empikmarketplace/vendor/react/promise/composer.json new file mode 100644 index 00000000..f933f153 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/composer.json @@ -0,0 +1,48 @@ +{ + "name": "react/promise", + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "license": "MIT", + "authors": [ + { + "name": "Jan Sorgalla", + "homepage": "https://sorgalla.com/", + "email": "jsorgalla@gmail.com" + }, + { + "name": "Christian Lück", + "homepage": "https://clue.engineering/", + "email": "christian@clue.engineering" + }, + { + "name": "Cees-Jan Kiewiet", + "homepage": "https://wyrihaximus.net/", + "email": "reactphp@ceesjankiewiet.nl" + }, + { + "name": "Chris Boden", + "homepage": "https://cboden.dev/", + "email": "cboden@gmail.com" + } + ], + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + }, + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": ["src/functions_include.php"] + }, + "autoload-dev": { + "psr-4": { + "React\\Promise\\": ["tests", "tests/fixtures"] + } + }, + "keywords": [ + "promise", + "promises" + ] +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/CancellablePromiseInterface.php b/modules/empikmarketplace/vendor/react/promise/src/CancellablePromiseInterface.php new file mode 100644 index 00000000..6b3a8c65 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/CancellablePromiseInterface.php @@ -0,0 +1,17 @@ +started) { + return; + } + + $this->started = true; + $this->drain(); + } + + public function enqueue($cancellable) + { + if (!\is_object($cancellable) || !\method_exists($cancellable, 'then') || !\method_exists($cancellable, 'cancel')) { + return; + } + + $length = \array_push($this->queue, $cancellable); + + if ($this->started && 1 === $length) { + $this->drain(); + } + } + + private function drain() + { + for ($i = key($this->queue); isset($this->queue[$i]); $i++) { + $cancellable = $this->queue[$i]; + + $exception = null; + + try { + $cancellable->cancel(); + } catch (\Throwable $exception) { + } catch (\Exception $exception) { + } + + unset($this->queue[$i]); + + if ($exception) { + throw $exception; + } + } + + $this->queue = []; + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/Deferred.php b/modules/empikmarketplace/vendor/react/promise/src/Deferred.php new file mode 100644 index 00000000..3ca034b8 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/Deferred.php @@ -0,0 +1,65 @@ +canceller = $canceller; + } + + public function promise() + { + if (null === $this->promise) { + $this->promise = new Promise(function ($resolve, $reject, $notify) { + $this->resolveCallback = $resolve; + $this->rejectCallback = $reject; + $this->notifyCallback = $notify; + }, $this->canceller); + $this->canceller = null; + } + + return $this->promise; + } + + public function resolve($value = null) + { + $this->promise(); + + \call_user_func($this->resolveCallback, $value); + } + + public function reject($reason = null) + { + $this->promise(); + + \call_user_func($this->rejectCallback, $reason); + } + + /** + * @deprecated 2.6.0 Progress support is deprecated and should not be used anymore. + * @param mixed $update + */ + public function notify($update = null) + { + $this->promise(); + + \call_user_func($this->notifyCallback, $update); + } + + /** + * @deprecated 2.2.0 + * @see Deferred::notify() + */ + public function progress($update = null) + { + $this->notify($update); + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/Exception/LengthException.php b/modules/empikmarketplace/vendor/react/promise/src/Exception/LengthException.php new file mode 100644 index 00000000..775c48db --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/Exception/LengthException.php @@ -0,0 +1,7 @@ +then(null, $onRejected); + * ``` + * + * Additionally, you can type hint the `$reason` argument of `$onRejected` to catch + * only specific errors. + * + * @param callable $onRejected + * @return ExtendedPromiseInterface + */ + public function otherwise(callable $onRejected); + + /** + * Allows you to execute "cleanup" type tasks in a promise chain. + * + * It arranges for `$onFulfilledOrRejected` to be called, with no arguments, + * when the promise is either fulfilled or rejected. + * + * * If `$promise` fulfills, and `$onFulfilledOrRejected` returns successfully, + * `$newPromise` will fulfill with the same value as `$promise`. + * * If `$promise` fulfills, and `$onFulfilledOrRejected` throws or returns a + * rejected promise, `$newPromise` will reject with the thrown exception or + * rejected promise's reason. + * * If `$promise` rejects, and `$onFulfilledOrRejected` returns successfully, + * `$newPromise` will reject with the same reason as `$promise`. + * * If `$promise` rejects, and `$onFulfilledOrRejected` throws or returns a + * rejected promise, `$newPromise` will reject with the thrown exception or + * rejected promise's reason. + * + * `always()` behaves similarly to the synchronous finally statement. When combined + * with `otherwise()`, `always()` allows you to write code that is similar to the familiar + * synchronous catch/finally pair. + * + * Consider the following synchronous code: + * + * ```php + * try { + * return doSomething(); + * } catch(\Exception $e) { + * return handleError($e); + * } finally { + * cleanup(); + * } + * ``` + * + * Similar asynchronous code (with `doSomething()` that returns a promise) can be + * written: + * + * ```php + * return doSomething() + * ->otherwise('handleError') + * ->always('cleanup'); + * ``` + * + * @param callable $onFulfilledOrRejected + * @return ExtendedPromiseInterface + */ + public function always(callable $onFulfilledOrRejected); + + /** + * Registers a handler for progress updates from promise. It is a shortcut for: + * + * ```php + * $promise->then(null, null, $onProgress); + * ``` + * + * @param callable $onProgress + * @return ExtendedPromiseInterface + * @deprecated 2.6.0 Progress support is deprecated and should not be used anymore. + */ + public function progress(callable $onProgress); +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/FulfilledPromise.php b/modules/empikmarketplace/vendor/react/promise/src/FulfilledPromise.php new file mode 100644 index 00000000..14727527 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/FulfilledPromise.php @@ -0,0 +1,71 @@ +value = $value; + } + + public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + if (null === $onFulfilled) { + return $this; + } + + try { + return resolve($onFulfilled($this->value)); + } catch (\Throwable $exception) { + return new RejectedPromise($exception); + } catch (\Exception $exception) { + return new RejectedPromise($exception); + } + } + + public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + if (null === $onFulfilled) { + return; + } + + $result = $onFulfilled($this->value); + + if ($result instanceof ExtendedPromiseInterface) { + $result->done(); + } + } + + public function otherwise(callable $onRejected) + { + return $this; + } + + public function always(callable $onFulfilledOrRejected) + { + return $this->then(function ($value) use ($onFulfilledOrRejected) { + return resolve($onFulfilledOrRejected())->then(function () use ($value) { + return $value; + }); + }); + } + + public function progress(callable $onProgress) + { + return $this; + } + + public function cancel() + { + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/LazyPromise.php b/modules/empikmarketplace/vendor/react/promise/src/LazyPromise.php new file mode 100644 index 00000000..bbe9293e --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/LazyPromise.php @@ -0,0 +1,66 @@ +factory = $factory; + } + + public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + return $this->promise()->then($onFulfilled, $onRejected, $onProgress); + } + + public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + return $this->promise()->done($onFulfilled, $onRejected, $onProgress); + } + + public function otherwise(callable $onRejected) + { + return $this->promise()->otherwise($onRejected); + } + + public function always(callable $onFulfilledOrRejected) + { + return $this->promise()->always($onFulfilledOrRejected); + } + + public function progress(callable $onProgress) + { + return $this->promise()->progress($onProgress); + } + + public function cancel() + { + return $this->promise()->cancel(); + } + + /** + * @internal + * @see Promise::settle() + */ + public function promise() + { + if (null === $this->promise) { + try { + $this->promise = resolve(\call_user_func($this->factory)); + } catch (\Throwable $exception) { + $this->promise = new RejectedPromise($exception); + } catch (\Exception $exception) { + $this->promise = new RejectedPromise($exception); + } + } + + return $this->promise; + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/Promise.php b/modules/empikmarketplace/vendor/react/promise/src/Promise.php new file mode 100644 index 00000000..33759e6f --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/Promise.php @@ -0,0 +1,256 @@ +canceller = $canceller; + + // Explicitly overwrite arguments with null values before invoking + // resolver function. This ensure that these arguments do not show up + // in the stack trace in PHP 7+ only. + $cb = $resolver; + $resolver = $canceller = null; + $this->call($cb); + } + + public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + if (null !== $this->result) { + return $this->result->then($onFulfilled, $onRejected, $onProgress); + } + + if (null === $this->canceller) { + return new static($this->resolver($onFulfilled, $onRejected, $onProgress)); + } + + // This promise has a canceller, so we create a new child promise which + // has a canceller that invokes the parent canceller if all other + // followers are also cancelled. We keep a reference to this promise + // instance for the static canceller function and clear this to avoid + // keeping a cyclic reference between parent and follower. + $parent = $this; + ++$parent->requiredCancelRequests; + + return new static( + $this->resolver($onFulfilled, $onRejected, $onProgress), + static function () use (&$parent) { + if (++$parent->cancelRequests >= $parent->requiredCancelRequests) { + $parent->cancel(); + } + + $parent = null; + } + ); + } + + public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + if (null !== $this->result) { + return $this->result->done($onFulfilled, $onRejected, $onProgress); + } + + $this->handlers[] = static function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected) { + $promise + ->done($onFulfilled, $onRejected); + }; + + if ($onProgress) { + $this->progressHandlers[] = $onProgress; + } + } + + public function otherwise(callable $onRejected) + { + return $this->then(null, static function ($reason) use ($onRejected) { + if (!_checkTypehint($onRejected, $reason)) { + return new RejectedPromise($reason); + } + + return $onRejected($reason); + }); + } + + public function always(callable $onFulfilledOrRejected) + { + return $this->then(static function ($value) use ($onFulfilledOrRejected) { + return resolve($onFulfilledOrRejected())->then(function () use ($value) { + return $value; + }); + }, static function ($reason) use ($onFulfilledOrRejected) { + return resolve($onFulfilledOrRejected())->then(function () use ($reason) { + return new RejectedPromise($reason); + }); + }); + } + + public function progress(callable $onProgress) + { + return $this->then(null, null, $onProgress); + } + + public function cancel() + { + if (null === $this->canceller || null !== $this->result) { + return; + } + + $canceller = $this->canceller; + $this->canceller = null; + + $this->call($canceller); + } + + private function resolver(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + return function ($resolve, $reject, $notify) use ($onFulfilled, $onRejected, $onProgress) { + if ($onProgress) { + $progressHandler = static function ($update) use ($notify, $onProgress) { + try { + $notify($onProgress($update)); + } catch (\Throwable $e) { + $notify($e); + } catch (\Exception $e) { + $notify($e); + } + }; + } else { + $progressHandler = $notify; + } + + $this->handlers[] = static function (ExtendedPromiseInterface $promise) use ($onFulfilled, $onRejected, $resolve, $reject, $progressHandler) { + $promise + ->then($onFulfilled, $onRejected) + ->done($resolve, $reject, $progressHandler); + }; + + $this->progressHandlers[] = $progressHandler; + }; + } + + private function reject($reason = null) + { + if (null !== $this->result) { + return; + } + + $this->settle(reject($reason)); + } + + private function settle(ExtendedPromiseInterface $promise) + { + $promise = $this->unwrap($promise); + + if ($promise === $this) { + $promise = new RejectedPromise( + new \LogicException('Cannot resolve a promise with itself.') + ); + } + + $handlers = $this->handlers; + + $this->progressHandlers = $this->handlers = []; + $this->result = $promise; + $this->canceller = null; + + foreach ($handlers as $handler) { + $handler($promise); + } + } + + private function unwrap($promise) + { + $promise = $this->extract($promise); + + while ($promise instanceof self && null !== $promise->result) { + $promise = $this->extract($promise->result); + } + + return $promise; + } + + private function extract($promise) + { + if ($promise instanceof LazyPromise) { + $promise = $promise->promise(); + } + + return $promise; + } + + private function call(callable $cb) + { + // Explicitly overwrite argument with null value. This ensure that this + // argument does not show up in the stack trace in PHP 7+ only. + $callback = $cb; + $cb = null; + + // Use reflection to inspect number of arguments expected by this callback. + // We did some careful benchmarking here: Using reflection to avoid unneeded + // function arguments is actually faster than blindly passing them. + // Also, this helps avoiding unnecessary function arguments in the call stack + // if the callback creates an Exception (creating garbage cycles). + if (\is_array($callback)) { + $ref = new \ReflectionMethod($callback[0], $callback[1]); + } elseif (\is_object($callback) && !$callback instanceof \Closure) { + $ref = new \ReflectionMethod($callback, '__invoke'); + } else { + $ref = new \ReflectionFunction($callback); + } + $args = $ref->getNumberOfParameters(); + + try { + if ($args === 0) { + $callback(); + } else { + // Keep references to this promise instance for the static resolve/reject functions. + // By using static callbacks that are not bound to this instance + // and passing the target promise instance by reference, we can + // still execute its resolving logic and still clear this + // reference when settling the promise. This helps avoiding + // garbage cycles if any callback creates an Exception. + // These assumptions are covered by the test suite, so if you ever feel like + // refactoring this, go ahead, any alternative suggestions are welcome! + $target =& $this; + $progressHandlers =& $this->progressHandlers; + + $callback( + static function ($value = null) use (&$target) { + if ($target !== null) { + $target->settle(resolve($value)); + $target = null; + } + }, + static function ($reason = null) use (&$target) { + if ($target !== null) { + $target->reject($reason); + $target = null; + } + }, + static function ($update = null) use (&$progressHandlers) { + foreach ($progressHandlers as $handler) { + $handler($update); + } + } + ); + } + } catch (\Throwable $e) { + $target = null; + $this->reject($e); + } catch (\Exception $e) { + $target = null; + $this->reject($e); + } + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/PromiseInterface.php b/modules/empikmarketplace/vendor/react/promise/src/PromiseInterface.php new file mode 100644 index 00000000..edcb0077 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/PromiseInterface.php @@ -0,0 +1,41 @@ +reason = $reason; + } + + public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + if (null === $onRejected) { + return $this; + } + + try { + return resolve($onRejected($this->reason)); + } catch (\Throwable $exception) { + return new RejectedPromise($exception); + } catch (\Exception $exception) { + return new RejectedPromise($exception); + } + } + + public function done(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null) + { + if (null === $onRejected) { + throw UnhandledRejectionException::resolve($this->reason); + } + + $result = $onRejected($this->reason); + + if ($result instanceof self) { + throw UnhandledRejectionException::resolve($result->reason); + } + + if ($result instanceof ExtendedPromiseInterface) { + $result->done(); + } + } + + public function otherwise(callable $onRejected) + { + if (!_checkTypehint($onRejected, $this->reason)) { + return $this; + } + + return $this->then(null, $onRejected); + } + + public function always(callable $onFulfilledOrRejected) + { + return $this->then(null, function ($reason) use ($onFulfilledOrRejected) { + return resolve($onFulfilledOrRejected())->then(function () use ($reason) { + return new RejectedPromise($reason); + }); + }); + } + + public function progress(callable $onProgress) + { + return $this; + } + + public function cancel() + { + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/UnhandledRejectionException.php b/modules/empikmarketplace/vendor/react/promise/src/UnhandledRejectionException.php new file mode 100644 index 00000000..e7fe2f7a --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/UnhandledRejectionException.php @@ -0,0 +1,31 @@ +reason = $reason; + + $message = \sprintf('Unhandled Rejection: %s', \json_encode($reason)); + + parent::__construct($message, 0); + } + + public function getReason() + { + return $this->reason; + } +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/functions.php b/modules/empikmarketplace/vendor/react/promise/src/functions.php new file mode 100644 index 00000000..429f0e73 --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/functions.php @@ -0,0 +1,407 @@ +then($resolve, $reject, $notify); + }, $canceller); + } + + return new FulfilledPromise($promiseOrValue); +} + +/** + * Creates a rejected promise for the supplied `$promiseOrValue`. + * + * If `$promiseOrValue` is a value, it will be the rejection value of the + * returned promise. + * + * If `$promiseOrValue` is a promise, its completion value will be the rejected + * value of the returned promise. + * + * This can be useful in situations where you need to reject a promise without + * throwing an exception. For example, it allows you to propagate a rejection with + * the value of another promise. + * + * @param mixed $promiseOrValue + * @return PromiseInterface + */ +function reject($promiseOrValue = null) +{ + if ($promiseOrValue instanceof PromiseInterface) { + return resolve($promiseOrValue)->then(function ($value) { + return new RejectedPromise($value); + }); + } + + return new RejectedPromise($promiseOrValue); +} + +/** + * Returns a promise that will resolve only once all the items in + * `$promisesOrValues` have resolved. The resolution value of the returned promise + * will be an array containing the resolution values of each of the items in + * `$promisesOrValues`. + * + * @param array $promisesOrValues + * @return PromiseInterface + */ +function all($promisesOrValues) +{ + return map($promisesOrValues, function ($val) { + return $val; + }); +} + +/** + * Initiates a competitive race that allows one winner. Returns a promise which is + * resolved in the same way the first settled promise resolves. + * + * The returned promise will become **infinitely pending** if `$promisesOrValues` + * contains 0 items. + * + * @param array $promisesOrValues + * @return PromiseInterface + */ +function race($promisesOrValues) +{ + $cancellationQueue = new CancellationQueue(); + $cancellationQueue->enqueue($promisesOrValues); + + return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $cancellationQueue) { + resolve($promisesOrValues) + ->done(function ($array) use ($cancellationQueue, $resolve, $reject, $notify) { + if (!is_array($array) || !$array) { + $resolve(); + return; + } + + foreach ($array as $promiseOrValue) { + $cancellationQueue->enqueue($promiseOrValue); + + resolve($promiseOrValue) + ->done($resolve, $reject, $notify); + } + }, $reject, $notify); + }, $cancellationQueue); +} + +/** + * Returns a promise that will resolve when any one of the items in + * `$promisesOrValues` resolves. The resolution value of the returned promise + * will be the resolution value of the triggering item. + * + * The returned promise will only reject if *all* items in `$promisesOrValues` are + * rejected. The rejection value will be an array of all rejection reasons. + * + * The returned promise will also reject with a `React\Promise\Exception\LengthException` + * if `$promisesOrValues` contains 0 items. + * + * @param array $promisesOrValues + * @return PromiseInterface + */ +function any($promisesOrValues) +{ + return some($promisesOrValues, 1) + ->then(function ($val) { + return \array_shift($val); + }); +} + +/** + * Returns a promise that will resolve when `$howMany` of the supplied items in + * `$promisesOrValues` resolve. The resolution value of the returned promise + * will be an array of length `$howMany` containing the resolution values of the + * triggering items. + * + * The returned promise will reject if it becomes impossible for `$howMany` items + * to resolve (that is, when `(count($promisesOrValues) - $howMany) + 1` items + * reject). The rejection value will be an array of + * `(count($promisesOrValues) - $howMany) + 1` rejection reasons. + * + * The returned promise will also reject with a `React\Promise\Exception\LengthException` + * if `$promisesOrValues` contains less items than `$howMany`. + * + * @param array $promisesOrValues + * @param int $howMany + * @return PromiseInterface + */ +function some($promisesOrValues, $howMany) +{ + $cancellationQueue = new CancellationQueue(); + $cancellationQueue->enqueue($promisesOrValues); + + return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $howMany, $cancellationQueue) { + resolve($promisesOrValues) + ->done(function ($array) use ($howMany, $cancellationQueue, $resolve, $reject, $notify) { + if (!\is_array($array) || $howMany < 1) { + $resolve([]); + return; + } + + $len = \count($array); + + if ($len < $howMany) { + throw new Exception\LengthException( + \sprintf( + 'Input array must contain at least %d item%s but contains only %s item%s.', + $howMany, + 1 === $howMany ? '' : 's', + $len, + 1 === $len ? '' : 's' + ) + ); + } + + $toResolve = $howMany; + $toReject = ($len - $toResolve) + 1; + $values = []; + $reasons = []; + + foreach ($array as $i => $promiseOrValue) { + $fulfiller = function ($val) use ($i, &$values, &$toResolve, $toReject, $resolve) { + if ($toResolve < 1 || $toReject < 1) { + return; + } + + $values[$i] = $val; + + if (0 === --$toResolve) { + $resolve($values); + } + }; + + $rejecter = function ($reason) use ($i, &$reasons, &$toReject, $toResolve, $reject) { + if ($toResolve < 1 || $toReject < 1) { + return; + } + + $reasons[$i] = $reason; + + if (0 === --$toReject) { + $reject($reasons); + } + }; + + $cancellationQueue->enqueue($promiseOrValue); + + resolve($promiseOrValue) + ->done($fulfiller, $rejecter, $notify); + } + }, $reject, $notify); + }, $cancellationQueue); +} + +/** + * Traditional map function, similar to `array_map()`, but allows input to contain + * promises and/or values, and `$mapFunc` may return either a value or a promise. + * + * The map function receives each item as argument, where item is a fully resolved + * value of a promise or value in `$promisesOrValues`. + * + * @param array $promisesOrValues + * @param callable $mapFunc + * @return PromiseInterface + */ +function map($promisesOrValues, callable $mapFunc) +{ + $cancellationQueue = new CancellationQueue(); + $cancellationQueue->enqueue($promisesOrValues); + + return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $mapFunc, $cancellationQueue) { + resolve($promisesOrValues) + ->done(function ($array) use ($mapFunc, $cancellationQueue, $resolve, $reject, $notify) { + if (!\is_array($array) || !$array) { + $resolve([]); + return; + } + + $toResolve = \count($array); + $values = []; + + foreach ($array as $i => $promiseOrValue) { + $cancellationQueue->enqueue($promiseOrValue); + $values[$i] = null; + + resolve($promiseOrValue) + ->then($mapFunc) + ->done( + function ($mapped) use ($i, &$values, &$toResolve, $resolve) { + $values[$i] = $mapped; + + if (0 === --$toResolve) { + $resolve($values); + } + }, + $reject, + $notify + ); + } + }, $reject, $notify); + }, $cancellationQueue); +} + +/** + * Traditional reduce function, similar to `array_reduce()`, but input may contain + * promises and/or values, and `$reduceFunc` may return either a value or a + * promise, *and* `$initialValue` may be a promise or a value for the starting + * value. + * + * @param array $promisesOrValues + * @param callable $reduceFunc + * @param mixed $initialValue + * @return PromiseInterface + */ +function reduce($promisesOrValues, callable $reduceFunc, $initialValue = null) +{ + $cancellationQueue = new CancellationQueue(); + $cancellationQueue->enqueue($promisesOrValues); + + return new Promise(function ($resolve, $reject, $notify) use ($promisesOrValues, $reduceFunc, $initialValue, $cancellationQueue) { + resolve($promisesOrValues) + ->done(function ($array) use ($reduceFunc, $initialValue, $cancellationQueue, $resolve, $reject, $notify) { + if (!\is_array($array)) { + $array = []; + } + + $total = \count($array); + $i = 0; + + // Wrap the supplied $reduceFunc with one that handles promises and then + // delegates to the supplied. + $wrappedReduceFunc = function ($current, $val) use ($reduceFunc, $cancellationQueue, $total, &$i) { + $cancellationQueue->enqueue($val); + + return $current + ->then(function ($c) use ($reduceFunc, $total, &$i, $val) { + return resolve($val) + ->then(function ($value) use ($reduceFunc, $total, &$i, $c) { + return $reduceFunc($c, $value, $i++, $total); + }); + }); + }; + + $cancellationQueue->enqueue($initialValue); + + \array_reduce($array, $wrappedReduceFunc, resolve($initialValue)) + ->done($resolve, $reject, $notify); + }, $reject, $notify); + }, $cancellationQueue); +} + +/** + * @internal + */ +function _checkTypehint(callable $callback, $object) +{ + if (!\is_object($object)) { + return true; + } + + if (\is_array($callback)) { + $callbackReflection = new \ReflectionMethod($callback[0], $callback[1]); + } elseif (\is_object($callback) && !$callback instanceof \Closure) { + $callbackReflection = new \ReflectionMethod($callback, '__invoke'); + } else { + $callbackReflection = new \ReflectionFunction($callback); + } + + $parameters = $callbackReflection->getParameters(); + + if (!isset($parameters[0])) { + return true; + } + + $expectedException = $parameters[0]; + + // PHP before v8 used an easy API: + if (\PHP_VERSION_ID < 70100 || \defined('HHVM_VERSION')) { + if (!$expectedException->getClass()) { + return true; + } + + return $expectedException->getClass()->isInstance($object); + } + + // Extract the type of the argument and handle different possibilities + $type = $expectedException->getType(); + + $isTypeUnion = true; + $types = []; + + switch (true) { + case $type === null: + break; + case $type instanceof \ReflectionNamedType: + $types = [$type]; + break; + case $type instanceof \ReflectionIntersectionType: + $isTypeUnion = false; + case $type instanceof \ReflectionUnionType; + $types = $type->getTypes(); + break; + default: + throw new \LogicException('Unexpected return value of ReflectionParameter::getType'); + } + + // If there is no type restriction, it matches + if (empty($types)) { + return true; + } + + foreach ($types as $type) { + if (!$type instanceof \ReflectionNamedType) { + throw new \LogicException('This implementation does not support groups of intersection or union types'); + } + + // A named-type can be either a class-name or a built-in type like string, int, array, etc. + $matches = ($type->isBuiltin() && \gettype($object) === $type->getName()) + || (new \ReflectionClass($type->getName()))->isInstance($object); + + + // If we look for a single match (union), we can return early on match + // If we look for a full match (intersection), we can return early on mismatch + if ($matches) { + if ($isTypeUnion) { + return true; + } + } else { + if (!$isTypeUnion) { + return false; + } + } + } + + // If we look for a single match (union) and did not return early, we matched no type and are false + // If we look for a full match (intersection) and did not return early, we matched all types and are true + return $isTypeUnion ? false : true; +} diff --git a/modules/empikmarketplace/vendor/react/promise/src/functions_include.php b/modules/empikmarketplace/vendor/react/promise/src/functions_include.php new file mode 100644 index 00000000..bd0c54fd --- /dev/null +++ b/modules/empikmarketplace/vendor/react/promise/src/functions_include.php @@ -0,0 +1,5 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\AbstractTrait; + +/** + * @author Nicolas Grekas + */ +abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface +{ + /** + * @internal + */ + const NS_SEPARATOR = ':'; + + use AbstractTrait; + + private static $apcuSupported; + private static $phpFilesSupported; + + private $createCacheItem; + private $mergeByLifetime; + + /** + * @param string $namespace + * @param int $defaultLifetime + */ + protected function __construct($namespace = '', $defaultLifetime = 0) + { + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; + if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { + throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); + } + $this->createCacheItem = \Closure::bind( + static function ($key, $value, $isHit) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $value; + $item->isHit = $isHit; + + return $item; + }, + null, + CacheItem::class + ); + $getId = function ($key) { return $this->getId((string) $key); }; + $this->mergeByLifetime = \Closure::bind( + static function ($deferred, $namespace, &$expiredIds) use ($getId, $defaultLifetime) { + $byLifetime = []; + $now = time(); + $expiredIds = []; + + foreach ($deferred as $key => $item) { + if (null === $item->expiry) { + $byLifetime[0 < $defaultLifetime ? $defaultLifetime : 0][$getId($key)] = $item->value; + } elseif (0 === $item->expiry) { + $byLifetime[0][$getId($key)] = $item->value; + } elseif ($item->expiry > $now) { + $byLifetime[$item->expiry - $now][$getId($key)] = $item->value; + } else { + $expiredIds[] = $getId($key); + } + } + + return $byLifetime; + }, + null, + CacheItem::class + ); + } + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string $version + * @param string $directory + * + * @return AdapterInterface + */ + public static function createSystemCache($namespace, $defaultLifetime, $version, $directory, LoggerInterface $logger = null) + { + if (null === self::$apcuSupported) { + self::$apcuSupported = ApcuAdapter::isSupported(); + } + + if (!self::$apcuSupported && null === self::$phpFilesSupported) { + self::$phpFilesSupported = PhpFilesAdapter::isSupported(); + } + + if (self::$phpFilesSupported) { + $opcache = new PhpFilesAdapter($namespace, $defaultLifetime, $directory); + if (null !== $logger) { + $opcache->setLogger($logger); + } + + return $opcache; + } + + $fs = new FilesystemAdapter($namespace, $defaultLifetime, $directory); + if (null !== $logger) { + $fs->setLogger($logger); + } + if (!self::$apcuSupported || (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { + return $fs; + } + + $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version); + if (null !== $logger) { + $apcu->setLogger($logger); + } + + return new ChainAdapter([$apcu, $fs]); + } + + public static function createConnection($dsn, array $options = []) + { + if (!\is_string($dsn)) { + throw new InvalidArgumentException(sprintf('The "%s()" method expect argument #1 to be string, "%s" given.', __METHOD__, \gettype($dsn))); + } + if (0 === strpos($dsn, 'redis://')) { + return RedisAdapter::createConnection($dsn, $options); + } + if (0 === strpos($dsn, 'memcached://')) { + return MemcachedAdapter::createConnection($dsn, $options); + } + + throw new InvalidArgumentException(sprintf('Unsupported DSN: "%s".', $dsn)); + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + if ($this->deferred) { + $this->commit(); + } + $id = $this->getId($key); + + $f = $this->createCacheItem; + $isHit = false; + $value = null; + + try { + foreach ($this->doFetch([$id]) as $value) { + $isHit = true; + } + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]); + } + + return $f($key, $value, $isHit); + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + if ($this->deferred) { + $this->commit(); + } + $ids = []; + + foreach ($keys as $key) { + $ids[] = $this->getId($key); + } + try { + $items = $this->doFetch($ids); + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => $keys, 'exception' => $e]); + $items = []; + } + $ids = array_combine($ids, $keys); + + return $this->generateItems($items, $ids); + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + if (!$item instanceof CacheItem) { + return false; + } + $this->deferred[$item->getKey()] = $item; + + return $this->commit(); + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + if (!$item instanceof CacheItem) { + return false; + } + $this->deferred[$item->getKey()] = $item; + + return true; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + $ok = true; + $byLifetime = $this->mergeByLifetime; + $byLifetime = $byLifetime($this->deferred, $this->namespace, $expiredIds); + $retry = $this->deferred = []; + + if ($expiredIds) { + $this->doDelete($expiredIds); + } + foreach ($byLifetime as $lifetime => $values) { + try { + $e = $this->doSave($values, $lifetime); + } catch (\Exception $e) { + } + if (true === $e || [] === $e) { + continue; + } + if (\is_array($e) || 1 === \count($values)) { + foreach (\is_array($e) ? $e : array_keys($values) as $id) { + $ok = false; + $v = $values[$id]; + $type = \is_object($v) ? \get_class($v) : \gettype($v); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]); + } + } else { + foreach ($values as $id => $v) { + $retry[$lifetime][] = $id; + } + } + } + + // When bulk-save failed, retry each item individually + foreach ($retry as $lifetime => $ids) { + foreach ($ids as $id) { + try { + $v = $byLifetime[$lifetime][$id]; + $e = $this->doSave([$id => $v], $lifetime); + } catch (\Exception $e) { + } + if (true === $e || [] === $e) { + continue; + } + $ok = false; + $type = \is_object($v) ? \get_class($v) : \gettype($v); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]); + } + } + + return $ok; + } + + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + if ($this->deferred) { + $this->commit(); + } + } + + private function generateItems($items, &$keys) + { + $f = $this->createCacheItem; + + try { + foreach ($items as $id => $value) { + if (!isset($keys[$id])) { + $id = key($keys); + } + $key = $keys[$id]; + unset($keys[$id]); + yield $key => $f($key, $value, true); + } + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => array_values($keys), 'exception' => $e]); + } + + foreach ($keys as $key) { + yield $key => $f($key, null, false); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/AdapterInterface.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/AdapterInterface.php new file mode 100644 index 00000000..85fe0768 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/AdapterInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\CacheItem; + +/** + * Interface for adapters managing instances of Symfony's CacheItem. + * + * @author Kévin Dunglas + */ +interface AdapterInterface extends CacheItemPoolInterface +{ + /** + * {@inheritdoc} + * + * @return CacheItem + */ + public function getItem($key); + + /** + * {@inheritdoc} + * + * @return \Traversable|CacheItem[] + */ + public function getItems(array $keys = []); +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/ApcuAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ApcuAdapter.php new file mode 100644 index 00000000..50554ed6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ApcuAdapter.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Symfony\Component\Cache\Traits\ApcuTrait; + +class ApcuAdapter extends AbstractAdapter +{ + use ApcuTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string|null $version + * + * @throws CacheException if APCu is not enabled + */ + public function __construct($namespace = '', $defaultLifetime = 0, $version = null) + { + $this->init($namespace, $defaultLifetime, $version); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/ArrayAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ArrayAdapter.php new file mode 100644 index 00000000..33f55a86 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ArrayAdapter.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Psr\Log\LoggerAwareInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\ArrayTrait; + +/** + * @author Nicolas Grekas + */ +class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface +{ + use ArrayTrait; + + private $createCacheItem; + private $defaultLifetime; + + /** + * @param int $defaultLifetime + * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise + */ + public function __construct($defaultLifetime = 0, $storeSerialized = true) + { + $this->defaultLifetime = $defaultLifetime; + $this->storeSerialized = $storeSerialized; + $this->createCacheItem = \Closure::bind( + static function ($key, $value, $isHit) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $value; + $item->isHit = $isHit; + + return $item; + }, + null, + CacheItem::class + ); + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + $isHit = $this->hasItem($key); + try { + if (!$isHit) { + $this->values[$key] = $value = null; + } elseif (!$this->storeSerialized) { + $value = $this->values[$key]; + } elseif ('b:0;' === $value = $this->values[$key]) { + $value = false; + } elseif (false === $value = unserialize($value)) { + $this->values[$key] = $value = null; + $isHit = false; + } + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]); + $this->values[$key] = $value = null; + $isHit = false; + } + $f = $this->createCacheItem; + + return $f($key, $value, $isHit); + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + foreach ($keys as $key) { + CacheItem::validateKey($key); + } + + return $this->generateItems($keys, time(), $this->createCacheItem); + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + foreach ($keys as $key) { + $this->deleteItem($key); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + if (!$item instanceof CacheItem) { + return false; + } + $item = (array) $item; + $key = $item["\0*\0key"]; + $value = $item["\0*\0value"]; + $expiry = $item["\0*\0expiry"]; + + if (0 === $expiry) { + $expiry = \PHP_INT_MAX; + } + + if (null !== $expiry && $expiry <= time()) { + $this->deleteItem($key); + + return true; + } + if ($this->storeSerialized) { + try { + $value = serialize($value); + } catch (\Exception $e) { + $type = \is_object($value) ? \get_class($value) : \gettype($value); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]); + + return false; + } + } + if (null === $expiry && 0 < $this->defaultLifetime) { + $expiry = time() + $this->defaultLifetime; + } + + $this->values[$key] = $value; + $this->expiries[$key] = null !== $expiry ? $expiry : \PHP_INT_MAX; + + return true; + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + return $this->save($item); + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/ChainAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ChainAdapter.php new file mode 100644 index 00000000..fdb28846 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ChainAdapter.php @@ -0,0 +1,272 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; + +/** + * Chains several adapters together. + * + * Cached items are fetched from the first adapter having them in its data store. + * They are saved and deleted in all adapters at once. + * + * @author Kévin Dunglas + */ +class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableInterface +{ + private $adapters = []; + private $adapterCount; + private $syncItem; + + /** + * @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items + * @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones + */ + public function __construct(array $adapters, $defaultLifetime = 0) + { + if (!$adapters) { + throw new InvalidArgumentException('At least one adapter must be specified.'); + } + + foreach ($adapters as $adapter) { + if (!$adapter instanceof CacheItemPoolInterface) { + throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($adapter), CacheItemPoolInterface::class)); + } + if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && $adapter instanceof ApcuAdapter && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { + continue; // skip putting APCu in the chain when the backend is disabled + } + + if ($adapter instanceof AdapterInterface) { + $this->adapters[] = $adapter; + } else { + $this->adapters[] = new ProxyAdapter($adapter); + } + } + $this->adapterCount = \count($this->adapters); + + $this->syncItem = \Closure::bind( + static function ($sourceItem, $item) use ($defaultLifetime) { + $item->value = $sourceItem->value; + $item->isHit = $sourceItem->isHit; + + if (0 < $defaultLifetime) { + $item->expiresAfter($defaultLifetime); + } + + return $item; + }, + null, + CacheItem::class + ); + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + $syncItem = $this->syncItem; + $misses = []; + + foreach ($this->adapters as $i => $adapter) { + $item = $adapter->getItem($key); + + if ($item->isHit()) { + while (0 <= --$i) { + $this->adapters[$i]->save($syncItem($item, $misses[$i])); + } + + return $item; + } + + $misses[$i] = $item; + } + + return $item; + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + return $this->generateItems($this->adapters[0]->getItems($keys), 0); + } + + private function generateItems($items, $adapterIndex) + { + $missing = []; + $misses = []; + $nextAdapterIndex = $adapterIndex + 1; + $nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null; + + foreach ($items as $k => $item) { + if (!$nextAdapter || $item->isHit()) { + yield $k => $item; + } else { + $missing[] = $k; + $misses[$k] = $item; + } + } + + if ($missing) { + $syncItem = $this->syncItem; + $adapter = $this->adapters[$adapterIndex]; + $items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex); + + foreach ($items as $k => $item) { + if ($item->isHit()) { + $adapter->save($syncItem($item, $misses[$k])); + } + + yield $k => $item; + } + } + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + foreach ($this->adapters as $adapter) { + if ($adapter->hasItem($key)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $cleared = true; + $i = $this->adapterCount; + + while ($i--) { + $cleared = $this->adapters[$i]->clear() && $cleared; + } + + return $cleared; + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + $deleted = true; + $i = $this->adapterCount; + + while ($i--) { + $deleted = $this->adapters[$i]->deleteItem($key) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + $deleted = true; + $i = $this->adapterCount; + + while ($i--) { + $deleted = $this->adapters[$i]->deleteItems($keys) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + $saved = true; + $i = $this->adapterCount; + + while ($i--) { + $saved = $this->adapters[$i]->save($item) && $saved; + } + + return $saved; + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + $saved = true; + $i = $this->adapterCount; + + while ($i--) { + $saved = $this->adapters[$i]->saveDeferred($item) && $saved; + } + + return $saved; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + $committed = true; + $i = $this->adapterCount; + + while ($i--) { + $committed = $this->adapters[$i]->commit() && $committed; + } + + return $committed; + } + + /** + * {@inheritdoc} + */ + public function prune() + { + $pruned = true; + + foreach ($this->adapters as $adapter) { + if ($adapter instanceof PruneableInterface) { + $pruned = $adapter->prune() && $pruned; + } + } + + return $pruned; + } + + /** + * {@inheritdoc} + */ + public function reset() + { + foreach ($this->adapters as $adapter) { + if ($adapter instanceof ResettableInterface) { + $adapter->reset(); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/DoctrineAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/DoctrineAdapter.php new file mode 100644 index 00000000..8081d7dc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/DoctrineAdapter.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Doctrine\Common\Cache\CacheProvider; +use Symfony\Component\Cache\Traits\DoctrineTrait; + +class DoctrineAdapter extends AbstractAdapter +{ + use DoctrineTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + */ + public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0) + { + parent::__construct('', $defaultLifetime); + $this->provider = $provider; + $provider->setNamespace($namespace); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/FilesystemAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/FilesystemAdapter.php new file mode 100644 index 00000000..d071964e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/FilesystemAdapter.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\FilesystemTrait; + +class FilesystemAdapter extends AbstractAdapter implements PruneableInterface +{ + use FilesystemTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string|null $directory + */ + public function __construct($namespace = '', $defaultLifetime = 0, $directory = null) + { + parent::__construct('', $defaultLifetime); + $this->init($namespace, $directory); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/MemcachedAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/MemcachedAdapter.php new file mode 100644 index 00000000..5637141a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/MemcachedAdapter.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Symfony\Component\Cache\Traits\MemcachedTrait; + +class MemcachedAdapter extends AbstractAdapter +{ + use MemcachedTrait; + + protected $maxIdLength = 250; + + /** + * Using a MemcachedAdapter with a TagAwareAdapter for storing tags is discouraged. + * Using a RedisAdapter is recommended instead. If you cannot do otherwise, be aware that: + * - the Memcached::OPT_BINARY_PROTOCOL must be enabled + * (that's the default when using MemcachedAdapter::createConnection()); + * - tags eviction by Memcached's LRU algorithm will break by-tags invalidation; + * your Memcached memory should be large enough to never trigger LRU. + * + * Using a MemcachedAdapter as a pure items store is fine. + */ + public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0) + { + $this->init($client, $namespace, $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/NullAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/NullAdapter.php new file mode 100644 index 00000000..c81a1cd6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/NullAdapter.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Symfony\Component\Cache\CacheItem; + +/** + * @author Titouan Galopin + */ +class NullAdapter implements AdapterInterface +{ + private $createCacheItem; + + public function __construct() + { + $this->createCacheItem = \Closure::bind( + function ($key) { + $item = new CacheItem(); + $item->key = $key; + $item->isHit = false; + + return $item; + }, + $this, + CacheItem::class + ); + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + $f = $this->createCacheItem; + + return $f($key); + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + return $this->generateItems($keys); + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return false; + } + + private function generateItems(array $keys) + { + $f = $this->createCacheItem; + + foreach ($keys as $key) { + yield $key => $f($key); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/PdoAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/PdoAdapter.php new file mode 100644 index 00000000..59038679 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/PdoAdapter.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Doctrine\DBAL\Connection; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\PdoTrait; + +class PdoAdapter extends AbstractAdapter implements PruneableInterface +{ + use PdoTrait; + + protected $maxIdLength = 255; + + /** + * You can either pass an existing database connection as PDO instance or + * a Doctrine DBAL Connection or a DSN string that will be used to + * lazy-connect to the database when the cache is actually used. + * + * List of available options: + * * db_table: The name of the table [default: cache_items] + * * db_id_col: The column where to store the cache id [default: item_id] + * * db_data_col: The column where to store the cache data [default: item_data] + * * db_lifetime_col: The column where to store the lifetime [default: item_lifetime] + * * db_time_col: The column where to store the timestamp [default: item_time] + * * db_username: The username when lazy-connect [default: ''] + * * db_password: The password when lazy-connect [default: ''] + * * db_connection_options: An array of driver-specific connection options [default: []] + * + * @param \PDO|Connection|string $connOrDsn A \PDO or Connection instance or DSN string or null + * @param string $namespace + * @param int $defaultLifetime + * @param array $options An associative array of options + * + * @throws InvalidArgumentException When first argument is not PDO nor Connection nor string + * @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION + * @throws InvalidArgumentException When namespace contains invalid characters + */ + public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = []) + { + $this->init($connOrDsn, $namespace, $defaultLifetime, $options); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/PhpArrayAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/PhpArrayAdapter.php new file mode 100644 index 00000000..47a259c1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/PhpArrayAdapter.php @@ -0,0 +1,309 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\PhpArrayTrait; + +/** + * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0. + * Warmed up items are read-only and run-time discovered items are cached using a fallback adapter. + * + * @author Titouan Galopin + * @author Nicolas Grekas + */ +class PhpArrayAdapter implements AdapterInterface, PruneableInterface, ResettableInterface +{ + use PhpArrayTrait; + + private $createCacheItem; + + /** + * @param string $file The PHP file were values are cached + * @param AdapterInterface $fallbackPool A pool to fallback on when an item is not hit + */ + public function __construct($file, AdapterInterface $fallbackPool) + { + $this->file = $file; + $this->pool = $fallbackPool; + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); + $this->createCacheItem = \Closure::bind( + static function ($key, $value, $isHit) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $value; + $item->isHit = $isHit; + + return $item; + }, + null, + CacheItem::class + ); + } + + /** + * This adapter should only be used on PHP 7.0+ to take advantage of how PHP + * stores arrays in its latest versions. This factory method decorates the given + * fallback pool with this adapter only if the current PHP version is supported. + * + * @param string $file The PHP file were values are cached + * @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit + * + * @return CacheItemPoolInterface + */ + public static function create($file, CacheItemPoolInterface $fallbackPool) + { + if (\PHP_VERSION_ID >= 70000) { + if (!$fallbackPool instanceof AdapterInterface) { + $fallbackPool = new ProxyAdapter($fallbackPool); + } + + return new static($file, $fallbackPool); + } + + return $fallbackPool; + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + if (!isset($this->values[$key])) { + return $this->pool->getItem($key); + } + + $value = $this->values[$key]; + $isHit = true; + + if ('N;' === $value) { + $value = null; + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { + try { + $e = null; + $value = unserialize($value); + } catch (\Error $e) { + } catch (\Exception $e) { + } + if (null !== $e) { + $value = null; + $isHit = false; + } + } + + $f = $this->createCacheItem; + + return $f($key, $value, $isHit); + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + foreach ($keys as $key) { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + } + if (null === $this->values) { + $this->initialize(); + } + + return $this->generateItems($keys); + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + + return isset($this->values[$key]) || $this->pool->hasItem($key); + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + + return !isset($this->values[$key]) && $this->pool->deleteItem($key); + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + $deleted = true; + $fallbackKeys = []; + + foreach ($keys as $key) { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + + if (isset($this->values[$key])) { + $deleted = false; + } else { + $fallbackKeys[] = $key; + } + } + if (null === $this->values) { + $this->initialize(); + } + + if ($fallbackKeys) { + $deleted = $this->pool->deleteItems($fallbackKeys) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + if (null === $this->values) { + $this->initialize(); + } + + return !isset($this->values[$item->getKey()]) && $this->pool->save($item); + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + if (null === $this->values) { + $this->initialize(); + } + + return !isset($this->values[$item->getKey()]) && $this->pool->saveDeferred($item); + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return $this->pool->commit(); + } + + /** + * @return \Generator + */ + private function generateItems(array $keys) + { + $f = $this->createCacheItem; + $fallbackKeys = []; + + foreach ($keys as $key) { + if (isset($this->values[$key])) { + $value = $this->values[$key]; + + if ('N;' === $value) { + yield $key => $f($key, null, true); + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { + try { + yield $key => $f($key, unserialize($value), true); + } catch (\Error $e) { + yield $key => $f($key, null, false); + } catch (\Exception $e) { + yield $key => $f($key, null, false); + } + } else { + yield $key => $f($key, $value, true); + } + } else { + $fallbackKeys[] = $key; + } + } + + if ($fallbackKeys) { + foreach ($this->pool->getItems($fallbackKeys) as $key => $item) { + yield $key => $item; + } + } + } + + /** + * @throws \ReflectionException When $class is not found and is required + * + * @internal to be removed in Symfony 5.0 + */ + public static function throwOnRequiredClass($class) + { + $e = new \ReflectionException("Class $class does not exist"); + $trace = debug_backtrace(); + $autoloadFrame = [ + 'function' => 'spl_autoload_call', + 'args' => [$class], + ]; + + if (\PHP_VERSION_ID >= 80000 && isset($trace[1])) { + $callerFrame = $trace[1]; + } elseif (false !== $i = array_search($autoloadFrame, $trace, true)) { + $callerFrame = $trace[++$i]; + } else { + throw $e; + } + + if (isset($callerFrame['function']) && !isset($callerFrame['class'])) { + switch ($callerFrame['function']) { + case 'get_class_methods': + case 'get_class_vars': + case 'get_parent_class': + case 'is_a': + case 'is_subclass_of': + case 'class_exists': + case 'class_implements': + case 'class_parents': + case 'trait_exists': + case 'defined': + case 'interface_exists': + case 'method_exists': + case 'property_exists': + case 'is_callable': + return; + } + } + + throw $e; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/PhpFilesAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/PhpFilesAdapter.php new file mode 100644 index 00000000..b56143c2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/PhpFilesAdapter.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Symfony\Component\Cache\Exception\CacheException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\PhpFilesTrait; + +class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface +{ + use PhpFilesTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string|null $directory + * + * @throws CacheException if OPcache is not enabled + */ + public function __construct($namespace = '', $defaultLifetime = 0, $directory = null) + { + if (!static::isSupported()) { + throw new CacheException('OPcache is not enabled.'); + } + parent::__construct('', $defaultLifetime); + $this->init($namespace, $directory); + + $e = new \Exception(); + $this->includeHandler = function () use ($e) { throw $e; }; + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/ProxyAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ProxyAdapter.php new file mode 100644 index 00000000..c89a760e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/ProxyAdapter.php @@ -0,0 +1,199 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\ProxyTrait; + +/** + * @author Nicolas Grekas + */ +class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableInterface +{ + use ProxyTrait; + + private $namespace; + private $namespaceLen; + private $createCacheItem; + private $poolHash; + private $defaultLifetime; + + /** + * @param string $namespace + * @param int $defaultLifetime + */ + public function __construct(CacheItemPoolInterface $pool, $namespace = '', $defaultLifetime = 0) + { + $this->pool = $pool; + $this->poolHash = $poolHash = spl_object_hash($pool); + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace); + $this->namespaceLen = \strlen($namespace); + $this->defaultLifetime = $defaultLifetime; + $this->createCacheItem = \Closure::bind( + static function ($key, $innerItem) use ($poolHash) { + $item = new CacheItem(); + $item->key = $key; + $item->poolHash = $poolHash; + + if (null !== $innerItem) { + $item->value = $innerItem->get(); + $item->isHit = $innerItem->isHit(); + $item->innerItem = $innerItem; + $innerItem->set(null); + } + + return $item; + }, + null, + CacheItem::class + ); + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + $f = $this->createCacheItem; + $item = $this->pool->getItem($this->getId($key)); + + return $f($key, $item); + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + if ($this->namespaceLen) { + foreach ($keys as $i => $key) { + $keys[$i] = $this->getId($key); + } + } + + return $this->generateItems($this->pool->getItems($keys)); + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + return $this->pool->hasItem($this->getId($key)); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + return $this->pool->deleteItem($this->getId($key)); + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + if ($this->namespaceLen) { + foreach ($keys as $i => $key) { + $keys[$i] = $this->getId($key); + } + } + + return $this->pool->deleteItems($keys); + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + return $this->doSave($item, __FUNCTION__); + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + return $this->doSave($item, __FUNCTION__); + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return $this->pool->commit(); + } + + private function doSave(CacheItemInterface $item, $method) + { + if (!$item instanceof CacheItem) { + return false; + } + $item = (array) $item; + $expiry = $item["\0*\0expiry"]; + if (null === $expiry && 0 < $this->defaultLifetime) { + $expiry = time() + $this->defaultLifetime; + } + + if ($item["\0*\0poolHash"] === $this->poolHash && $item["\0*\0innerItem"]) { + $innerItem = $item["\0*\0innerItem"]; + } elseif ($this->pool instanceof AdapterInterface) { + // this is an optimization specific for AdapterInterface implementations + // so we can save a round-trip to the backend by just creating a new item + $f = $this->createCacheItem; + $innerItem = $f($this->namespace.$item["\0*\0key"], null); + } else { + $innerItem = $this->pool->getItem($this->namespace.$item["\0*\0key"]); + } + + $innerItem->set($item["\0*\0value"]); + $innerItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null); + + return $this->pool->$method($innerItem); + } + + private function generateItems($items) + { + $f = $this->createCacheItem; + + foreach ($items as $key => $item) { + if ($this->namespaceLen) { + $key = substr($key, $this->namespaceLen); + } + + yield $key => $f($key, $item); + } + } + + private function getId($key) + { + CacheItem::validateKey($key); + + return $this->namespace.$key; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/RedisAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/RedisAdapter.php new file mode 100644 index 00000000..c1e17997 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/RedisAdapter.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Symfony\Component\Cache\Traits\RedisTrait; + +class RedisAdapter extends AbstractAdapter +{ + use RedisTrait; + + /** + * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient The redis client + * @param string $namespace The default namespace + * @param int $defaultLifetime The default lifetime + */ + public function __construct($redisClient, $namespace = '', $defaultLifetime = 0) + { + $this->init($redisClient, $namespace, $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php new file mode 100644 index 00000000..d3d0ede6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\ProxyTrait; + +/** + * @author Nicolas Grekas + */ +class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface +{ + /** + * @internal + */ + const NS_SEPARATOR = '_'; + + use ProxyTrait; + + private $miss; + + public function __construct(CacheInterface $pool, $namespace = '', $defaultLifetime = 0) + { + parent::__construct($namespace, $defaultLifetime); + + $this->pool = $pool; + $this->miss = new \stdClass(); + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + foreach ($this->pool->getMultiple($ids, $this->miss) as $key => $value) { + if ($this->miss !== $value) { + yield $key => $value; + } + } + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return $this->pool->has($id); + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + return $this->pool->deleteMultiple($ids); + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + return $this->pool->setMultiple($values, 0 === $lifetime ? null : $lifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/TagAwareAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TagAwareAdapter.php new file mode 100644 index 00000000..febe5090 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TagAwareAdapter.php @@ -0,0 +1,393 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\InvalidArgumentException; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\ProxyTrait; + +/** + * @author Nicolas Grekas + */ +class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, ResettableInterface +{ + const TAGS_PREFIX = "\0tags\0"; + + use ProxyTrait; + + private $deferred = []; + private $createCacheItem; + private $setCacheItemTags; + private $getTagsByKey; + private $invalidateTags; + private $tags; + private $knownTagVersions = []; + private $knownTagVersionsTtl; + + public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, $knownTagVersionsTtl = 0.15) + { + $this->pool = $itemsPool; + $this->tags = $tagsPool ?: $itemsPool; + $this->knownTagVersionsTtl = $knownTagVersionsTtl; + $this->createCacheItem = \Closure::bind( + static function ($key, $value, CacheItem $protoItem) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $value; + $item->expiry = $protoItem->expiry; + $item->poolHash = $protoItem->poolHash; + + return $item; + }, + null, + CacheItem::class + ); + $this->setCacheItemTags = \Closure::bind( + static function (CacheItem $item, $key, array &$itemTags) { + if (!$item->isHit) { + return $item; + } + if (isset($itemTags[$key])) { + foreach ($itemTags[$key] as $tag => $version) { + $item->prevTags[$tag] = $tag; + } + unset($itemTags[$key]); + } else { + $item->value = null; + $item->isHit = false; + } + + return $item; + }, + null, + CacheItem::class + ); + $this->getTagsByKey = \Closure::bind( + static function ($deferred) { + $tagsByKey = []; + foreach ($deferred as $key => $item) { + $tagsByKey[$key] = $item->tags; + } + + return $tagsByKey; + }, + null, + CacheItem::class + ); + $this->invalidateTags = \Closure::bind( + static function (AdapterInterface $tagsAdapter, array $tags) { + foreach ($tags as $v) { + $v->expiry = 0; + $tagsAdapter->saveDeferred($v); + } + + return $tagsAdapter->commit(); + }, + null, + CacheItem::class + ); + } + + /** + * {@inheritdoc} + */ + public function invalidateTags(array $tags) + { + $ok = true; + $tagsByKey = []; + $invalidatedTags = []; + foreach ($tags as $tag) { + CacheItem::validateKey($tag); + $invalidatedTags[$tag] = 0; + } + + if ($this->deferred) { + $items = $this->deferred; + foreach ($items as $key => $item) { + if (!$this->pool->saveDeferred($item)) { + unset($this->deferred[$key]); + $ok = false; + } + } + + $f = $this->getTagsByKey; + $tagsByKey = $f($items); + $this->deferred = []; + } + + $tagVersions = $this->getTagVersions($tagsByKey, $invalidatedTags); + $f = $this->createCacheItem; + + foreach ($tagsByKey as $key => $tags) { + $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key])); + } + $ok = $this->pool->commit() && $ok; + + if ($invalidatedTags) { + $f = $this->invalidateTags; + $ok = $f($this->tags, $invalidatedTags) && $ok; + } + + return $ok; + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + if ($this->deferred) { + $this->commit(); + } + if (!$this->pool->hasItem($key)) { + return false; + } + + $itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key); + + if (!$itemTags->isHit()) { + return false; + } + + if (!$itemTags = $itemTags->get()) { + return true; + } + + foreach ($this->getTagVersions([$itemTags]) as $tag => $version) { + if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) { + return false; + } + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + foreach ($this->getItems([$key]) as $item) { + return $item; + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + if ($this->deferred) { + $this->commit(); + } + $tagKeys = []; + + foreach ($keys as $key) { + if ('' !== $key && \is_string($key)) { + $key = static::TAGS_PREFIX.$key; + $tagKeys[$key] = $key; + } + } + + try { + $items = $this->pool->getItems($tagKeys + $keys); + } catch (InvalidArgumentException $e) { + $this->pool->getItems($keys); // Should throw an exception + + throw $e; + } + + return $this->generateItems($items, $tagKeys); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $this->deferred = []; + + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + return $this->deleteItems([$key]); + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + foreach ($keys as $key) { + if ('' !== $key && \is_string($key)) { + $keys[] = static::TAGS_PREFIX.$key; + } + } + + return $this->pool->deleteItems($keys); + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + if (!$item instanceof CacheItem) { + return false; + } + $this->deferred[$item->getKey()] = $item; + + return $this->commit(); + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + if (!$item instanceof CacheItem) { + return false; + } + $this->deferred[$item->getKey()] = $item; + + return true; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return $this->invalidateTags([]); + } + + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + $this->commit(); + } + + private function generateItems($items, array $tagKeys) + { + $bufferedItems = $itemTags = []; + $f = $this->setCacheItemTags; + + foreach ($items as $key => $item) { + if (!$tagKeys) { + yield $key => $f($item, static::TAGS_PREFIX.$key, $itemTags); + continue; + } + if (!isset($tagKeys[$key])) { + $bufferedItems[$key] = $item; + continue; + } + + unset($tagKeys[$key]); + + if ($item->isHit()) { + $itemTags[$key] = $item->get() ?: []; + } + + if (!$tagKeys) { + $tagVersions = $this->getTagVersions($itemTags); + + foreach ($itemTags as $key => $tags) { + foreach ($tags as $tag => $version) { + if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) { + unset($itemTags[$key]); + continue 2; + } + } + } + $tagVersions = $tagKeys = null; + + foreach ($bufferedItems as $key => $item) { + yield $key => $f($item, static::TAGS_PREFIX.$key, $itemTags); + } + $bufferedItems = null; + } + } + } + + private function getTagVersions(array $tagsByKey, array &$invalidatedTags = []) + { + $tagVersions = $invalidatedTags; + + foreach ($tagsByKey as $tags) { + $tagVersions += $tags; + } + + if (!$tagVersions) { + return []; + } + + if (!$fetchTagVersions = 1 !== \func_num_args()) { + foreach ($tagsByKey as $tags) { + foreach ($tags as $tag => $version) { + if ($tagVersions[$tag] > $version) { + $tagVersions[$tag] = $version; + } + } + } + } + + $now = microtime(true); + $tags = []; + foreach ($tagVersions as $tag => $version) { + $tags[$tag.static::TAGS_PREFIX] = $tag; + if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) { + $fetchTagVersions = true; + continue; + } + $version -= $this->knownTagVersions[$tag][1]; + if ((0 !== $version && 1 !== $version) || $now - $this->knownTagVersions[$tag][0] >= $this->knownTagVersionsTtl) { + // reuse previously fetched tag versions up to the ttl, unless we are storing items or a potential miss arises + $fetchTagVersions = true; + } else { + $this->knownTagVersions[$tag][1] += $version; + } + } + + if (!$fetchTagVersions) { + return $tagVersions; + } + + foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) { + $tagVersions[$tag = $tags[$tag]] = $version->get() ?: 0; + if (isset($invalidatedTags[$tag])) { + $invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]); + } + $this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]]; + } + + return $tagVersions; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php new file mode 100644 index 00000000..340048c1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TagAwareAdapterInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\InvalidArgumentException; + +/** + * Interface for invalidating cached items using tags. + * + * @author Nicolas Grekas + */ +interface TagAwareAdapterInterface extends AdapterInterface +{ + /** + * Invalidates cached items using tags. + * + * @param string[] $tags An array of tags to invalidate + * + * @return bool True on success + * + * @throws InvalidArgumentException When $tags is not valid + */ + public function invalidateTags(array $tags); +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/TraceableAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TraceableAdapter.php new file mode 100644 index 00000000..cc855c13 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TraceableAdapter.php @@ -0,0 +1,229 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +use Psr\Cache\CacheItemInterface; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; + +/** + * An adapter that collects data about all cache calls. + * + * @author Aaron Scherer + * @author Tobias Nyholm + * @author Nicolas Grekas + */ +class TraceableAdapter implements AdapterInterface, PruneableInterface, ResettableInterface +{ + protected $pool; + private $calls = []; + + public function __construct(AdapterInterface $pool) + { + $this->pool = $pool; + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + $event = $this->start(__FUNCTION__); + try { + $item = $this->pool->getItem($key); + } finally { + $event->end = microtime(true); + } + if ($event->result[$key] = $item->isHit()) { + ++$event->hits; + } else { + ++$event->misses; + } + + return $item; + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$key] = $this->pool->hasItem($key); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$key] = $this->pool->deleteItem($key); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$item->getKey()] = $this->pool->save($item); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$item->getKey()] = $this->pool->saveDeferred($item); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + $event = $this->start(__FUNCTION__); + try { + $result = $this->pool->getItems($keys); + } finally { + $event->end = microtime(true); + } + $f = function () use ($result, $event) { + $event->result = []; + foreach ($result as $key => $item) { + if ($event->result[$key] = $item->isHit()) { + ++$event->hits; + } else { + ++$event->misses; + } + yield $key => $item; + } + }; + + return $f(); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $event = $this->start(__FUNCTION__); + try { + return $event->result = $this->pool->clear(); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + $event = $this->start(__FUNCTION__); + $event->result['keys'] = $keys; + try { + return $event->result['result'] = $this->pool->deleteItems($keys); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function commit() + { + $event = $this->start(__FUNCTION__); + try { + return $event->result = $this->pool->commit(); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function prune() + { + if (!$this->pool instanceof PruneableInterface) { + return false; + } + $event = $this->start(__FUNCTION__); + try { + return $event->result = $this->pool->prune(); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function reset() + { + if ($this->pool instanceof ResettableInterface) { + $this->pool->reset(); + } + + $this->clearCalls(); + } + + public function getCalls() + { + return $this->calls; + } + + public function clearCalls() + { + $this->calls = []; + } + + protected function start($name) + { + $this->calls[] = $event = new TraceableAdapterEvent(); + $event->name = $name; + $event->start = microtime(true); + + return $event; + } +} + +class TraceableAdapterEvent +{ + public $name; + public $start; + public $end; + public $result; + public $hits = 0; + public $misses = 0; +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php new file mode 100644 index 00000000..de68955d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Adapter/TraceableTagAwareAdapter.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Adapter; + +/** + * @author Robin Chalas + */ +class TraceableTagAwareAdapter extends TraceableAdapter implements TagAwareAdapterInterface +{ + public function __construct(TagAwareAdapterInterface $pool) + { + parent::__construct($pool); + } + + /** + * {@inheritdoc} + */ + public function invalidateTags(array $tags) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result = $this->pool->invalidateTags($tags); + } finally { + $event->end = microtime(true); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/CHANGELOG.md b/modules/empikmarketplace/vendor/symfony/cache/CHANGELOG.md new file mode 100644 index 00000000..11c1b936 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/CHANGELOG.md @@ -0,0 +1,36 @@ +CHANGELOG +========= + +3.4.0 +----- + + * added using options from Memcached DSN + * added PruneableInterface so PSR-6 or PSR-16 cache implementations can declare support for manual stale cache pruning + * added prune logic to FilesystemTrait, PhpFilesTrait, PdoTrait, TagAwareAdapter and ChainTrait + * now FilesystemAdapter, PhpFilesAdapter, FilesystemCache, PhpFilesCache, PdoAdapter, PdoCache, ChainAdapter, and + ChainCache implement PruneableInterface and support manual stale cache pruning + +3.3.0 +----- + + * [EXPERIMENTAL] added CacheItem::getPreviousTags() to get bound tags coming from the pool storage if any + * added PSR-16 "Simple Cache" implementations for all existing PSR-6 adapters + * added Psr6Cache and SimpleCacheAdapter for bidirectional interoperability between PSR-6 and PSR-16 + * added MemcachedAdapter (PSR-6) and MemcachedCache (PSR-16) + * added TraceableAdapter (PSR-6) and TraceableCache (PSR-16) + +3.2.0 +----- + + * added TagAwareAdapter for tags-based invalidation + * added PdoAdapter with PDO and Doctrine DBAL support + * added PhpArrayAdapter and PhpFilesAdapter for OPcache-backed shared memory storage (PHP 7+ only) + * added NullAdapter + +3.1.0 +----- + + * added the component with strict PSR-6 implementations + * added ApcuAdapter, ArrayAdapter, FilesystemAdapter and RedisAdapter + * added AbstractAdapter, ChainAdapter and ProxyAdapter + * added DoctrineAdapter and DoctrineProvider for bidirectional interoperability with Doctrine Cache diff --git a/modules/empikmarketplace/vendor/symfony/cache/CacheItem.php b/modules/empikmarketplace/vendor/symfony/cache/CacheItem.php new file mode 100644 index 00000000..7ae6568c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/CacheItem.php @@ -0,0 +1,192 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache; + +use Psr\Cache\CacheItemInterface; +use Psr\Log\LoggerInterface; +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas + */ +final class CacheItem implements CacheItemInterface +{ + protected $key; + protected $value; + protected $isHit = false; + protected $expiry; + protected $tags = []; + protected $prevTags = []; + protected $innerItem; + protected $poolHash; + + /** + * {@inheritdoc} + */ + public function getKey() + { + return $this->key; + } + + /** + * {@inheritdoc} + */ + public function get() + { + return $this->value; + } + + /** + * {@inheritdoc} + */ + public function isHit() + { + return $this->isHit; + } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function set($value) + { + $this->value = $value; + + return $this; + } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function expiresAt($expiration) + { + if (null === $expiration) { + $this->expiry = null; + } elseif ($expiration instanceof \DateTimeInterface) { + $this->expiry = (int) $expiration->format('U'); + } else { + throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given.', \is_object($expiration) ? \get_class($expiration) : \gettype($expiration))); + } + + return $this; + } + + /** + * {@inheritdoc} + * + * @return $this + */ + public function expiresAfter($time) + { + if (null === $time) { + $this->expiry = null; + } elseif ($time instanceof \DateInterval) { + $this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U'); + } elseif (\is_int($time)) { + $this->expiry = $time + time(); + } else { + throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($time) ? \get_class($time) : \gettype($time))); + } + + return $this; + } + + /** + * Adds a tag to a cache item. + * + * @param string|string[] $tags A tag or array of tags + * + * @return $this + * + * @throws InvalidArgumentException When $tag is not valid + */ + public function tag($tags) + { + if (!\is_array($tags)) { + $tags = [$tags]; + } + foreach ($tags as $tag) { + if (!\is_string($tag)) { + throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given.', \is_object($tag) ? \get_class($tag) : \gettype($tag))); + } + if (isset($this->tags[$tag])) { + continue; + } + if ('' === $tag) { + throw new InvalidArgumentException('Cache tag length must be greater than zero.'); + } + if (false !== strpbrk($tag, '{}()/\@:')) { + throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:.', $tag)); + } + $this->tags[$tag] = $tag; + } + + return $this; + } + + /** + * Returns the list of tags bound to the value coming from the pool storage if any. + * + * @return array + */ + public function getPreviousTags() + { + return $this->prevTags; + } + + /** + * Validates a cache key according to PSR-6. + * + * @param string $key The key to validate + * + * @return string + * + * @throws InvalidArgumentException When $key is not valid + */ + public static function validateKey($key) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if ('' === $key) { + throw new InvalidArgumentException('Cache key length must be greater than zero.'); + } + if (false !== strpbrk($key, '{}()/\@:')) { + throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:.', $key)); + } + + return $key; + } + + /** + * Internal logging helper. + * + * @internal + */ + public static function log(LoggerInterface $logger = null, $message, $context = []) + { + if ($logger) { + $logger->warning($message, $context); + } else { + $replace = []; + foreach ($context as $k => $v) { + if (is_scalar($v)) { + $replace['{'.$k.'}'] = $v; + } + } + @trigger_error(strtr($message, $replace), \E_USER_WARNING); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/DataCollector/CacheDataCollector.php b/modules/empikmarketplace/vendor/symfony/cache/DataCollector/CacheDataCollector.php new file mode 100644 index 00000000..c9e87d5c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/DataCollector/CacheDataCollector.php @@ -0,0 +1,188 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\DataCollector; + +use Symfony\Component\Cache\Adapter\TraceableAdapter; +use Symfony\Component\Cache\Adapter\TraceableAdapterEvent; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface; + +/** + * @author Aaron Scherer + * @author Tobias Nyholm + */ +class CacheDataCollector extends DataCollector implements LateDataCollectorInterface +{ + /** + * @var TraceableAdapter[] + */ + private $instances = []; + + /** + * @param string $name + */ + public function addInstance($name, TraceableAdapter $instance) + { + $this->instances[$name] = $instance; + } + + /** + * {@inheritdoc} + */ + public function collect(Request $request, Response $response, \Exception $exception = null) + { + $empty = ['calls' => [], 'config' => [], 'options' => [], 'statistics' => []]; + $this->data = ['instances' => $empty, 'total' => $empty]; + foreach ($this->instances as $name => $instance) { + $this->data['instances']['calls'][$name] = $instance->getCalls(); + } + + $this->data['instances']['statistics'] = $this->calculateStatistics(); + $this->data['total']['statistics'] = $this->calculateTotalStatistics(); + } + + public function reset() + { + $this->data = []; + foreach ($this->instances as $instance) { + $instance->clearCalls(); + } + } + + public function lateCollect() + { + $this->data = $this->cloneVar($this->data); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'cache'; + } + + /** + * Method returns amount of logged Cache reads: "get" calls. + * + * @return array + */ + public function getStatistics() + { + return $this->data['instances']['statistics']; + } + + /** + * Method returns the statistic totals. + * + * @return array + */ + public function getTotals() + { + return $this->data['total']['statistics']; + } + + /** + * Method returns all logged Cache call objects. + * + * @return mixed + */ + public function getCalls() + { + return $this->data['instances']['calls']; + } + + /** + * @return array + */ + private function calculateStatistics() + { + $statistics = []; + foreach ($this->data['instances']['calls'] as $name => $calls) { + $statistics[$name] = [ + 'calls' => 0, + 'time' => 0, + 'reads' => 0, + 'writes' => 0, + 'deletes' => 0, + 'hits' => 0, + 'misses' => 0, + ]; + /** @var TraceableAdapterEvent $call */ + foreach ($calls as $call) { + ++$statistics[$name]['calls']; + $statistics[$name]['time'] += $call->end - $call->start; + if ('getItem' === $call->name) { + ++$statistics[$name]['reads']; + if ($call->hits) { + ++$statistics[$name]['hits']; + } else { + ++$statistics[$name]['misses']; + } + } elseif ('getItems' === $call->name) { + $statistics[$name]['reads'] += $call->hits + $call->misses; + $statistics[$name]['hits'] += $call->hits; + $statistics[$name]['misses'] += $call->misses; + } elseif ('hasItem' === $call->name) { + ++$statistics[$name]['reads']; + if (false === $call->result) { + ++$statistics[$name]['misses']; + } else { + ++$statistics[$name]['hits']; + } + } elseif ('save' === $call->name) { + ++$statistics[$name]['writes']; + } elseif ('deleteItem' === $call->name) { + ++$statistics[$name]['deletes']; + } + } + if ($statistics[$name]['reads']) { + $statistics[$name]['hit_read_ratio'] = round(100 * $statistics[$name]['hits'] / $statistics[$name]['reads'], 2); + } else { + $statistics[$name]['hit_read_ratio'] = null; + } + } + + return $statistics; + } + + /** + * @return array + */ + private function calculateTotalStatistics() + { + $statistics = $this->getStatistics(); + $totals = [ + 'calls' => 0, + 'time' => 0, + 'reads' => 0, + 'writes' => 0, + 'deletes' => 0, + 'hits' => 0, + 'misses' => 0, + ]; + foreach ($statistics as $name => $values) { + foreach ($totals as $key => $value) { + $totals[$key] += $statistics[$name][$key]; + } + } + if ($totals['reads']) { + $totals['hit_read_ratio'] = round(100 * $totals['hits'] / $totals['reads'], 2); + } else { + $totals['hit_read_ratio'] = null; + } + + return $totals; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/DoctrineProvider.php b/modules/empikmarketplace/vendor/symfony/cache/DoctrineProvider.php new file mode 100644 index 00000000..4c5cd0cb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/DoctrineProvider.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache; + +use Doctrine\Common\Cache\CacheProvider; +use Psr\Cache\CacheItemPoolInterface; + +/** + * @author Nicolas Grekas + */ +class DoctrineProvider extends CacheProvider implements PruneableInterface, ResettableInterface +{ + private $pool; + + public function __construct(CacheItemPoolInterface $pool) + { + $this->pool = $pool; + } + + /** + * {@inheritdoc} + */ + public function prune() + { + return $this->pool instanceof PruneableInterface && $this->pool->prune(); + } + + /** + * {@inheritdoc} + */ + public function reset() + { + if ($this->pool instanceof ResettableInterface) { + $this->pool->reset(); + } + $this->setNamespace($this->getNamespace()); + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $item = $this->pool->getItem(rawurlencode($id)); + + return $item->isHit() ? $item->get() : false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return $this->pool->hasItem(rawurlencode($id)); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $item = $this->pool->getItem(rawurlencode($id)); + + if (0 < $lifeTime) { + $item->expiresAfter($lifeTime); + } + + return $this->pool->save($item->set($data)); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->pool->deleteItem(rawurlencode($id)); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + return null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Exception/CacheException.php b/modules/empikmarketplace/vendor/symfony/cache/Exception/CacheException.php new file mode 100644 index 00000000..e87b2db8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Exception/CacheException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Exception; + +use Psr\Cache\CacheException as Psr6CacheInterface; +use Psr\SimpleCache\CacheException as SimpleCacheInterface; + +class CacheException extends \Exception implements Psr6CacheInterface, SimpleCacheInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Exception/InvalidArgumentException.php b/modules/empikmarketplace/vendor/symfony/cache/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..828bf3ed --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Exception; + +use Psr\Cache\InvalidArgumentException as Psr6CacheInterface; +use Psr\SimpleCache\InvalidArgumentException as SimpleCacheInterface; + +class InvalidArgumentException extends \InvalidArgumentException implements Psr6CacheInterface, SimpleCacheInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/LICENSE b/modules/empikmarketplace/vendor/symfony/cache/LICENSE new file mode 100644 index 00000000..a7ec7080 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016-2020 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/cache/PruneableInterface.php b/modules/empikmarketplace/vendor/symfony/cache/PruneableInterface.php new file mode 100644 index 00000000..42615253 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/PruneableInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache; + +/** + * Interface extends psr-6 and psr-16 caches to allow for pruning (deletion) of all expired cache items. + */ +interface PruneableInterface +{ + /** + * @return bool + */ + public function prune(); +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/README.md b/modules/empikmarketplace/vendor/symfony/cache/README.md new file mode 100644 index 00000000..c4ab7520 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/README.md @@ -0,0 +1,18 @@ +Symfony PSR-6 implementation for caching +======================================== + +This component provides an extended [PSR-6](http://www.php-fig.org/psr/psr-6/) +implementation for adding cache to your applications. It is designed to have a +low overhead so that caching is fastest. It ships with a few caching adapters +for the most widespread and suited to caching backends. It also provides a +`doctrine/cache` proxy adapter to cover more advanced caching needs and a proxy +adapter for greater interoperability between PSR-6 implementations. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/cache.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/modules/empikmarketplace/vendor/symfony/cache/ResettableInterface.php b/modules/empikmarketplace/vendor/symfony/cache/ResettableInterface.php new file mode 100644 index 00000000..6be72861 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/ResettableInterface.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache; + +/** + * Resets a pool's local state. + */ +interface ResettableInterface +{ + public function reset(); +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/AbstractCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/AbstractCache.php new file mode 100644 index 00000000..baedb737 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/AbstractCache.php @@ -0,0 +1,190 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\Log\LoggerAwareInterface; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\AbstractTrait; + +/** + * @author Nicolas Grekas + */ +abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface +{ + /** + * @internal + */ + const NS_SEPARATOR = ':'; + + use AbstractTrait { + deleteItems as private; + AbstractTrait::deleteItem as delete; + AbstractTrait::hasItem as has; + } + + private $defaultLifetime; + + /** + * @param string $namespace + * @param int $defaultLifetime + */ + protected function __construct($namespace = '', $defaultLifetime = 0) + { + $this->defaultLifetime = max(0, (int) $defaultLifetime); + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; + if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { + throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); + } + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + $id = $this->getId($key); + + try { + foreach ($this->doFetch([$id]) as $value) { + return $value; + } + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]); + } + + return $default; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + CacheItem::validateKey($key); + + return $this->setMultiple([$key => $value], $ttl); + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + $ids = []; + + foreach ($keys as $key) { + $ids[] = $this->getId($key); + } + try { + $values = $this->doFetch($ids); + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => $keys, 'exception' => $e]); + $values = []; + } + $ids = array_combine($ids, $keys); + + return $this->generateValues($values, $ids, $default); + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); + } + $valuesById = []; + + foreach ($values as $key => $value) { + if (\is_int($key)) { + $key = (string) $key; + } + $valuesById[$this->getId($key)] = $value; + } + if (false === $ttl = $this->normalizeTtl($ttl)) { + return $this->doDelete(array_keys($valuesById)); + } + + try { + $e = $this->doSave($valuesById, $ttl); + } catch (\Exception $e) { + } + if (true === $e || [] === $e) { + return true; + } + $keys = []; + foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) { + $keys[] = substr($id, \strlen($this->namespace)); + } + CacheItem::log($this->logger, 'Failed to save values', ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]); + + return false; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + + return $this->deleteItems($keys); + } + + private function normalizeTtl($ttl) + { + if (null === $ttl) { + return $this->defaultLifetime; + } + if ($ttl instanceof \DateInterval) { + $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U'); + } + if (\is_int($ttl)) { + return 0 < $ttl ? $ttl : false; + } + + throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl))); + } + + private function generateValues($values, &$keys, $default) + { + try { + foreach ($values as $id => $value) { + if (!isset($keys[$id])) { + $id = key($keys); + } + $key = $keys[$id]; + unset($keys[$id]); + yield $key => $value; + } + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => array_values($keys), 'exception' => $e]); + } + + foreach ($keys as $key) { + yield $key => $default; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/ApcuCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/ApcuCache.php new file mode 100644 index 00000000..e583b443 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/ApcuCache.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Symfony\Component\Cache\Traits\ApcuTrait; + +class ApcuCache extends AbstractCache +{ + use ApcuTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string|null $version + */ + public function __construct($namespace = '', $defaultLifetime = 0, $version = null) + { + $this->init($namespace, $defaultLifetime, $version); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/ArrayCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/ArrayCache.php new file mode 100644 index 00000000..6013f0ad --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/ArrayCache.php @@ -0,0 +1,148 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\Log\LoggerAwareInterface; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\ArrayTrait; + +/** + * @author Nicolas Grekas + */ +class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInterface +{ + use ArrayTrait { + ArrayTrait::deleteItem as delete; + ArrayTrait::hasItem as has; + } + + private $defaultLifetime; + + /** + * @param int $defaultLifetime + * @param bool $storeSerialized Disabling serialization can lead to cache corruptions when storing mutable values but increases performance otherwise + */ + public function __construct($defaultLifetime = 0, $storeSerialized = true) + { + $this->defaultLifetime = (int) $defaultLifetime; + $this->storeSerialized = $storeSerialized; + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + foreach ($this->getMultiple([$key], $default) as $v) { + return $v; + } + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + foreach ($keys as $key) { + CacheItem::validateKey($key); + } + + return $this->generateItems($keys, time(), function ($k, $v, $hit) use ($default) { return $hit ? $v : $default; }); + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if (!\is_array($keys) && !$keys instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + foreach ($keys as $key) { + $this->delete($key); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + CacheItem::validateKey($key); + + return $this->setMultiple([$key => $value], $ttl); + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); + } + $valuesArray = []; + + foreach ($values as $key => $value) { + \is_int($key) || CacheItem::validateKey($key); + $valuesArray[$key] = $value; + } + if (false === $ttl = $this->normalizeTtl($ttl)) { + return $this->deleteMultiple(array_keys($valuesArray)); + } + if ($this->storeSerialized) { + foreach ($valuesArray as $key => $value) { + try { + $valuesArray[$key] = serialize($value); + } catch (\Exception $e) { + $type = \is_object($value) ? \get_class($value) : \gettype($value); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]); + + return false; + } + } + } + $expiry = 0 < $ttl ? time() + $ttl : \PHP_INT_MAX; + + foreach ($valuesArray as $key => $value) { + $this->values[$key] = $value; + $this->expiries[$key] = $expiry; + } + + return true; + } + + private function normalizeTtl($ttl) + { + if (null === $ttl) { + return $this->defaultLifetime; + } + if ($ttl instanceof \DateInterval) { + $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U'); + } + if (\is_int($ttl)) { + return 0 < $ttl ? $ttl : false; + } + + throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl))); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/ChainCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/ChainCache.php new file mode 100644 index 00000000..2e6c7277 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/ChainCache.php @@ -0,0 +1,252 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; + +/** + * Chains several caches together. + * + * Cached items are fetched from the first cache having them in its data store. + * They are saved and deleted in all caches at once. + * + * @author Nicolas Grekas + */ +class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface +{ + private $miss; + private $caches = []; + private $defaultLifetime; + private $cacheCount; + + /** + * @param CacheInterface[] $caches The ordered list of caches used to fetch cached items + * @param int $defaultLifetime The lifetime of items propagated from lower caches to upper ones + */ + public function __construct(array $caches, $defaultLifetime = 0) + { + if (!$caches) { + throw new InvalidArgumentException('At least one cache must be specified.'); + } + + foreach ($caches as $cache) { + if (!$cache instanceof CacheInterface) { + throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class)); + } + } + + $this->miss = new \stdClass(); + $this->caches = array_values($caches); + $this->cacheCount = \count($this->caches); + $this->defaultLifetime = 0 < $defaultLifetime ? (int) $defaultLifetime : null; + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + $miss = null !== $default && \is_object($default) ? $default : $this->miss; + + foreach ($this->caches as $i => $cache) { + $value = $cache->get($key, $miss); + + if ($miss !== $value) { + while (0 <= --$i) { + $this->caches[$i]->set($key, $value, $this->defaultLifetime); + } + + return $value; + } + } + + return $default; + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + $miss = null !== $default && \is_object($default) ? $default : $this->miss; + + return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default); + } + + private function generateItems($values, $cacheIndex, $miss, $default) + { + $missing = []; + $nextCacheIndex = $cacheIndex + 1; + $nextCache = isset($this->caches[$nextCacheIndex]) ? $this->caches[$nextCacheIndex] : null; + + foreach ($values as $k => $value) { + if ($miss !== $value) { + yield $k => $value; + } elseif (!$nextCache) { + yield $k => $default; + } else { + $missing[] = $k; + } + } + + if ($missing) { + $cache = $this->caches[$cacheIndex]; + $values = $this->generateItems($nextCache->getMultiple($missing, $miss), $nextCacheIndex, $miss, $default); + + foreach ($values as $k => $value) { + if ($miss !== $value) { + $cache->set($k, $value, $this->defaultLifetime); + yield $k => $value; + } else { + yield $k => $default; + } + } + } + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + foreach ($this->caches as $cache) { + if ($cache->has($key)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $cleared = true; + $i = $this->cacheCount; + + while ($i--) { + $cleared = $this->caches[$i]->clear() && $cleared; + } + + return $cleared; + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + $deleted = true; + $i = $this->cacheCount; + + while ($i--) { + $deleted = $this->caches[$i]->delete($key) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } + $deleted = true; + $i = $this->cacheCount; + + while ($i--) { + $deleted = $this->caches[$i]->deleteMultiple($keys) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + $saved = true; + $i = $this->cacheCount; + + while ($i--) { + $saved = $this->caches[$i]->set($key, $value, $ttl) && $saved; + } + + return $saved; + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if ($values instanceof \Traversable) { + $valuesIterator = $values; + $values = function () use ($valuesIterator, &$values) { + $generatedValues = []; + + foreach ($valuesIterator as $key => $value) { + yield $key => $value; + $generatedValues[$key] = $value; + } + + $values = $generatedValues; + }; + $values = $values(); + } + $saved = true; + $i = $this->cacheCount; + + while ($i--) { + $saved = $this->caches[$i]->setMultiple($values, $ttl) && $saved; + } + + return $saved; + } + + /** + * {@inheritdoc} + */ + public function prune() + { + $pruned = true; + + foreach ($this->caches as $cache) { + if ($cache instanceof PruneableInterface) { + $pruned = $cache->prune() && $pruned; + } + } + + return $pruned; + } + + /** + * {@inheritdoc} + */ + public function reset() + { + foreach ($this->caches as $cache) { + if ($cache instanceof ResettableInterface) { + $cache->reset(); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/DoctrineCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/DoctrineCache.php new file mode 100644 index 00000000..ea1a4eda --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/DoctrineCache.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Doctrine\Common\Cache\CacheProvider; +use Symfony\Component\Cache\Traits\DoctrineTrait; + +class DoctrineCache extends AbstractCache +{ + use DoctrineTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + */ + public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0) + { + parent::__construct('', $defaultLifetime); + $this->provider = $provider; + $provider->setNamespace($namespace); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/FilesystemCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/FilesystemCache.php new file mode 100644 index 00000000..ccd57953 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/FilesystemCache.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\FilesystemTrait; + +class FilesystemCache extends AbstractCache implements PruneableInterface +{ + use FilesystemTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string|null $directory + */ + public function __construct($namespace = '', $defaultLifetime = 0, $directory = null) + { + parent::__construct('', $defaultLifetime); + $this->init($namespace, $directory); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/MemcachedCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/MemcachedCache.php new file mode 100644 index 00000000..94a9f297 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/MemcachedCache.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Symfony\Component\Cache\Traits\MemcachedTrait; + +class MemcachedCache extends AbstractCache +{ + use MemcachedTrait; + + protected $maxIdLength = 250; + + /** + * @param string $namespace + * @param int $defaultLifetime + */ + public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0) + { + $this->init($client, $namespace, $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/NullCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/NullCache.php new file mode 100644 index 00000000..fa986aeb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/NullCache.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\SimpleCache\CacheInterface; + +/** + * @author Nicolas Grekas + */ +class NullCache implements CacheInterface +{ + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + return $default; + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + foreach ($keys as $key) { + yield $key => $default; + } + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + return true; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/PdoCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/PdoCache.php new file mode 100644 index 00000000..c92e049a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/PdoCache.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\PdoTrait; + +class PdoCache extends AbstractCache implements PruneableInterface +{ + use PdoTrait; + + protected $maxIdLength = 255; + + /** + * You can either pass an existing database connection as PDO instance or + * a Doctrine DBAL Connection or a DSN string that will be used to + * lazy-connect to the database when the cache is actually used. + * + * List of available options: + * * db_table: The name of the table [default: cache_items] + * * db_id_col: The column where to store the cache id [default: item_id] + * * db_data_col: The column where to store the cache data [default: item_data] + * * db_lifetime_col: The column where to store the lifetime [default: item_lifetime] + * * db_time_col: The column where to store the timestamp [default: item_time] + * * db_username: The username when lazy-connect [default: ''] + * * db_password: The password when lazy-connect [default: ''] + * * db_connection_options: An array of driver-specific connection options [default: []] + * + * @param \PDO|Connection|string $connOrDsn A \PDO or Connection instance or DSN string or null + * @param string $namespace + * @param int $defaultLifetime + * @param array $options An associative array of options + * + * @throws InvalidArgumentException When first argument is not PDO nor Connection nor string + * @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION + * @throws InvalidArgumentException When namespace contains invalid characters + */ + public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = []) + { + $this->init($connOrDsn, $namespace, $defaultLifetime, $options); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/PhpArrayCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/PhpArrayCache.php new file mode 100644 index 00000000..7bb25ff8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/PhpArrayCache.php @@ -0,0 +1,259 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\PhpArrayTrait; + +/** + * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0. + * Warmed up items are read-only and run-time discovered items are cached using a fallback adapter. + * + * @author Titouan Galopin + * @author Nicolas Grekas + */ +class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInterface +{ + use PhpArrayTrait; + + /** + * @param string $file The PHP file were values are cached + * @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit + */ + public function __construct($file, CacheInterface $fallbackPool) + { + $this->file = $file; + $this->pool = $fallbackPool; + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); + } + + /** + * This adapter should only be used on PHP 7.0+ to take advantage of how PHP + * stores arrays in its latest versions. This factory method decorates the given + * fallback pool with this adapter only if the current PHP version is supported. + * + * @param string $file The PHP file were values are cached + * @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit + * + * @return CacheInterface + */ + public static function create($file, CacheInterface $fallbackPool) + { + if (\PHP_VERSION_ID >= 70000) { + return new static($file, $fallbackPool); + } + + return $fallbackPool; + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + if (!isset($this->values[$key])) { + return $this->pool->get($key, $default); + } + + $value = $this->values[$key]; + + if ('N;' === $value) { + $value = null; + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { + try { + $e = null; + $value = unserialize($value); + } catch (\Error $e) { + } catch (\Exception $e) { + } + if (null !== $e) { + return $default; + } + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + foreach ($keys as $key) { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + } + if (null === $this->values) { + $this->initialize(); + } + + return $this->generateItems($keys, $default); + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + + return isset($this->values[$key]) || $this->pool->has($key); + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + + return !isset($this->values[$key]) && $this->pool->delete($key); + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if (!\is_array($keys) && !$keys instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + + $deleted = true; + $fallbackKeys = []; + + foreach ($keys as $key) { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + + if (isset($this->values[$key])) { + $deleted = false; + } else { + $fallbackKeys[] = $key; + } + } + if (null === $this->values) { + $this->initialize(); + } + + if ($fallbackKeys) { + $deleted = $this->pool->deleteMultiple($fallbackKeys) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + if (null === $this->values) { + $this->initialize(); + } + + return !isset($this->values[$key]) && $this->pool->set($key, $value, $ttl); + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + if (!\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); + } + + $saved = true; + $fallbackValues = []; + + foreach ($values as $key => $value) { + if (!\is_string($key) && !\is_int($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); + } + + if (isset($this->values[$key])) { + $saved = false; + } else { + $fallbackValues[$key] = $value; + } + } + + if ($fallbackValues) { + $saved = $this->pool->setMultiple($fallbackValues, $ttl) && $saved; + } + + return $saved; + } + + private function generateItems(array $keys, $default) + { + $fallbackKeys = []; + + foreach ($keys as $key) { + if (isset($this->values[$key])) { + $value = $this->values[$key]; + + if ('N;' === $value) { + yield $key => null; + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { + try { + yield $key => unserialize($value); + } catch (\Error $e) { + yield $key => $default; + } catch (\Exception $e) { + yield $key => $default; + } + } else { + yield $key => $value; + } + } else { + $fallbackKeys[] = $key; + } + } + + if ($fallbackKeys) { + foreach ($this->pool->getMultiple($fallbackKeys, $default) as $key => $item) { + yield $key => $item; + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/PhpFilesCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/PhpFilesCache.php new file mode 100644 index 00000000..50c19034 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/PhpFilesCache.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Symfony\Component\Cache\Exception\CacheException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Traits\PhpFilesTrait; + +class PhpFilesCache extends AbstractCache implements PruneableInterface +{ + use PhpFilesTrait; + + /** + * @param string $namespace + * @param int $defaultLifetime + * @param string|null $directory + * + * @throws CacheException if OPcache is not enabled + */ + public function __construct($namespace = '', $defaultLifetime = 0, $directory = null) + { + if (!static::isSupported()) { + throw new CacheException('OPcache is not enabled.'); + } + parent::__construct('', $defaultLifetime); + $this->init($namespace, $directory); + + $e = new \Exception(); + $this->includeHandler = function () use ($e) { throw $e; }; + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/Psr6Cache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/Psr6Cache.php new file mode 100644 index 00000000..6b3de205 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/Psr6Cache.php @@ -0,0 +1,241 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\Cache\CacheException as Psr6CacheException; +use Psr\Cache\CacheItemPoolInterface; +use Psr\SimpleCache\CacheException as SimpleCacheException; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\ProxyTrait; + +/** + * @author Nicolas Grekas + */ +class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterface +{ + use ProxyTrait; + + private $createCacheItem; + private $cacheItemPrototype; + + public function __construct(CacheItemPoolInterface $pool) + { + $this->pool = $pool; + + if (!$pool instanceof AdapterInterface) { + return; + } + $cacheItemPrototype = &$this->cacheItemPrototype; + $createCacheItem = \Closure::bind( + static function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) { + $item = clone $cacheItemPrototype; + $item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key); + $item->value = $value; + $item->isHit = false; + + return $item; + }, + null, + CacheItem::class + ); + $this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) { + if (null === $this->cacheItemPrototype) { + $this->get($allowInt && \is_int($key) ? (string) $key : $key); + } + $this->createCacheItem = $createCacheItem; + + return $createCacheItem($key, $value, $allowInt); + }; + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + try { + $item = $this->pool->getItem($key); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + if (null === $this->cacheItemPrototype) { + $this->cacheItemPrototype = clone $item; + $this->cacheItemPrototype->set(null); + } + + return $item->isHit() ? $item->get() : $default; + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + try { + if (null !== $f = $this->createCacheItem) { + $item = $f($key, $value); + } else { + $item = $this->pool->getItem($key)->set($value); + } + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + if (null !== $ttl) { + $item->expiresAfter($ttl); + } + + return $this->pool->save($item); + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + try { + return $this->pool->deleteItem($key); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function clear() + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + + try { + $items = $this->pool->getItems($keys); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + $values = []; + + foreach ($items as $key => $item) { + $values[$key] = $item->isHit() ? $item->get() : $default; + } + + return $values; + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + $valuesIsArray = \is_array($values); + if (!$valuesIsArray && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); + } + $items = []; + + try { + if (null !== $f = $this->createCacheItem) { + $valuesIsArray = false; + foreach ($values as $key => $value) { + $items[$key] = $f($key, $value, true); + } + } elseif ($valuesIsArray) { + $items = []; + foreach ($values as $key => $value) { + $items[] = (string) $key; + } + $items = $this->pool->getItems($items); + } else { + foreach ($values as $key => $value) { + if (\is_int($key)) { + $key = (string) $key; + } + $items[$key] = $this->pool->getItem($key)->set($value); + } + } + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + $ok = true; + + foreach ($items as $key => $item) { + if ($valuesIsArray) { + $item->set($values[$key]); + } + if (null !== $ttl) { + $item->expiresAfter($ttl); + } + $ok = $this->pool->saveDeferred($item) && $ok; + } + + return $this->pool->commit() && $ok; + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + if ($keys instanceof \Traversable) { + $keys = iterator_to_array($keys, false); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); + } + + try { + return $this->pool->deleteItems($keys); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + try { + return $this->pool->hasItem($key); + } catch (SimpleCacheException $e) { + throw $e; + } catch (Psr6CacheException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/RedisCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/RedisCache.php new file mode 100644 index 00000000..e82c0627 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/RedisCache.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Symfony\Component\Cache\Traits\RedisTrait; + +class RedisCache extends AbstractCache +{ + use RedisTrait; + + /** + * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient + * @param string $namespace + * @param int $defaultLifetime + */ + public function __construct($redisClient, $namespace = '', $defaultLifetime = 0) + { + $this->init($redisClient, $namespace, $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Simple/TraceableCache.php b/modules/empikmarketplace/vendor/symfony/cache/Simple/TraceableCache.php new file mode 100644 index 00000000..61b22963 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Simple/TraceableCache.php @@ -0,0 +1,241 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Simple; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; + +/** + * An adapter that collects data about all cache calls. + * + * @author Nicolas Grekas + */ +class TraceableCache implements CacheInterface, PruneableInterface, ResettableInterface +{ + private $pool; + private $miss; + private $calls = []; + + public function __construct(CacheInterface $pool) + { + $this->pool = $pool; + $this->miss = new \stdClass(); + } + + /** + * {@inheritdoc} + */ + public function get($key, $default = null) + { + $miss = null !== $default && \is_object($default) ? $default : $this->miss; + $event = $this->start(__FUNCTION__); + try { + $value = $this->pool->get($key, $miss); + } finally { + $event->end = microtime(true); + } + if ($event->result[$key] = $miss !== $value) { + ++$event->hits; + } else { + ++$event->misses; + $value = $default; + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function has($key) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$key] = $this->pool->has($key); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function delete($key) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$key] = $this->pool->delete($key); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function set($key, $value, $ttl = null) + { + $event = $this->start(__FUNCTION__); + try { + return $event->result[$key] = $this->pool->set($key, $value, $ttl); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function setMultiple($values, $ttl = null) + { + $event = $this->start(__FUNCTION__); + $event->result['keys'] = []; + + if ($values instanceof \Traversable) { + $values = function () use ($values, $event) { + foreach ($values as $k => $v) { + $event->result['keys'][] = $k; + yield $k => $v; + } + }; + $values = $values(); + } elseif (\is_array($values)) { + $event->result['keys'] = array_keys($values); + } + + try { + return $event->result['result'] = $this->pool->setMultiple($values, $ttl); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function getMultiple($keys, $default = null) + { + $miss = null !== $default && \is_object($default) ? $default : $this->miss; + $event = $this->start(__FUNCTION__); + try { + $result = $this->pool->getMultiple($keys, $miss); + } finally { + $event->end = microtime(true); + } + $f = function () use ($result, $event, $miss, $default) { + $event->result = []; + foreach ($result as $key => $value) { + if ($event->result[$key] = $miss !== $value) { + ++$event->hits; + } else { + ++$event->misses; + $value = $default; + } + yield $key => $value; + } + }; + + return $f(); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $event = $this->start(__FUNCTION__); + try { + return $event->result = $this->pool->clear(); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple($keys) + { + $event = $this->start(__FUNCTION__); + if ($keys instanceof \Traversable) { + $keys = $event->result['keys'] = iterator_to_array($keys, false); + } else { + $event->result['keys'] = $keys; + } + try { + return $event->result['result'] = $this->pool->deleteMultiple($keys); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function prune() + { + if (!$this->pool instanceof PruneableInterface) { + return false; + } + $event = $this->start(__FUNCTION__); + try { + return $event->result = $this->pool->prune(); + } finally { + $event->end = microtime(true); + } + } + + /** + * {@inheritdoc} + */ + public function reset() + { + if (!$this->pool instanceof ResettableInterface) { + return; + } + $event = $this->start(__FUNCTION__); + try { + $this->pool->reset(); + } finally { + $event->end = microtime(true); + } + } + + public function getCalls() + { + try { + return $this->calls; + } finally { + $this->calls = []; + } + } + + private function start($name) + { + $this->calls[] = $event = new TraceableCacheEvent(); + $event->name = $name; + $event->start = microtime(true); + + return $event; + } +} + +class TraceableCacheEvent +{ + public $name; + public $start; + public $end; + public $result; + public $hits = 0; + public $misses = 0; +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php new file mode 100644 index 00000000..0e8ed001 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\RedisAdapter; + +abstract class AbstractRedisAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testExpiration' => 'Testing expiration slows down the test suite', + 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', + 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', + ]; + + protected static $redis; + + public function createCachePool($defaultLifetime = 0) + { + return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); + } + + public static function setUpBeforeClass() + { + if (!\extension_loaded('redis')) { + self::markTestSkipped('Extension redis required.'); + } + try { + (new \Redis())->connect(getenv('REDIS_HOST')); + } catch (\Exception $e) { + self::markTestSkipped($e->getMessage()); + } + } + + public static function tearDownAfterClass() + { + self::$redis = null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php new file mode 100644 index 00000000..5758a286 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Cache\IntegrationTests\CachePoolTest; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\PruneableInterface; + +abstract class AdapterTestCase extends CachePoolTest +{ + protected function setUp() + { + parent::setUp(); + + if (!\array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && \defined('HHVM_VERSION')) { + $this->skippedTests['testDeferredSaveWithoutCommit'] = 'Destructors are called late on HHVM.'; + } + + if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) { + $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; + } + } + + public function testDefaultLifeTime() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createCachePool(2); + + $item = $cache->getItem('key.dlt'); + $item->set('value'); + $cache->save($item); + sleep(1); + + $item = $cache->getItem('key.dlt'); + $this->assertTrue($item->isHit()); + + sleep(2); + $item = $cache->getItem('key.dlt'); + $this->assertFalse($item->isHit()); + } + + public function testExpiration() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createCachePool(); + $cache->save($cache->getItem('k1')->set('v1')->expiresAfter(2)); + $cache->save($cache->getItem('k2')->set('v2')->expiresAfter(366 * 86400)); + + sleep(3); + $item = $cache->getItem('k1'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit() is false."); + + $item = $cache->getItem('k2'); + $this->assertTrue($item->isHit()); + $this->assertSame('v2', $item->get()); + } + + public function testNotUnserializable() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createCachePool(); + + $item = $cache->getItem('foo'); + $cache->save($item->set(new NotUnserializable())); + + $item = $cache->getItem('foo'); + $this->assertFalse($item->isHit()); + + foreach ($cache->getItems(['foo']) as $item) { + } + $cache->save($item->set(new NotUnserializable())); + + foreach ($cache->getItems(['foo']) as $item) { + } + $this->assertFalse($item->isHit()); + } + + public function testPrune() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + if (!method_exists($this, 'isPruned')) { + $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); + } + + /** @var PruneableInterface|CacheItemPoolInterface $cache */ + $cache = $this->createCachePool(); + + $doSet = function ($name, $value, \DateInterval $expiresAfter = null) use ($cache) { + $item = $cache->getItem($name); + $item->set($value); + + if ($expiresAfter) { + $item->expiresAfter($expiresAfter); + } + + $cache->save($item); + }; + + $doSet('foo', 'foo-val', new \DateInterval('PT05S')); + $doSet('bar', 'bar-val', new \DateInterval('PT10S')); + $doSet('baz', 'baz-val', new \DateInterval('PT15S')); + $doSet('qux', 'qux-val', new \DateInterval('PT20S')); + + sleep(30); + $cache->prune(); + $this->assertTrue($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'bar')); + $this->assertTrue($this->isPruned($cache, 'baz')); + $this->assertTrue($this->isPruned($cache, 'qux')); + + $doSet('foo', 'foo-val'); + $doSet('bar', 'bar-val', new \DateInterval('PT20S')); + $doSet('baz', 'baz-val', new \DateInterval('PT40S')); + $doSet('qux', 'qux-val', new \DateInterval('PT80S')); + + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertFalse($this->isPruned($cache, 'bar')); + $this->assertFalse($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'bar')); + $this->assertFalse($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'qux')); + } +} + +class NotUnserializable implements \Serializable +{ + public function serialize() + { + return serialize(123); + } + + public function unserialize($ser) + { + throw new \Exception(__CLASS__); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php new file mode 100644 index 00000000..f55a1b9b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Log\NullLogger; +use Symfony\Component\Cache\Adapter\ApcuAdapter; + +class ApcuAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testExpiration' => 'Testing expiration slows down the test suite', + 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', + 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', + ]; + + public function createCachePool($defaultLifetime = 0) + { + if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN)) { + $this->markTestSkipped('APCu extension is required.'); + } + if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { + if ('testWithCliSapi' !== $this->getName()) { + $this->markTestSkipped('apc.enable_cli=1 is required.'); + } + } + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Fails transiently on Windows.'); + } + + return new ApcuAdapter(str_replace('\\', '.', __CLASS__), $defaultLifetime); + } + + public function testUnserializable() + { + $pool = $this->createCachePool(); + + $item = $pool->getItem('foo'); + $item->set(function () {}); + + $this->assertFalse($pool->save($item)); + + $item = $pool->getItem('foo'); + $this->assertFalse($item->isHit()); + } + + public function testVersion() + { + $namespace = str_replace('\\', '.', static::class); + + $pool1 = new ApcuAdapter($namespace, 0, 'p1'); + + $item = $pool1->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertTrue($pool1->save($item->set('bar'))); + + $item = $pool1->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + + $pool2 = new ApcuAdapter($namespace, 0, 'p2'); + + $item = $pool2->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get()); + + $item = $pool1->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get()); + } + + public function testNamespace() + { + $namespace = str_replace('\\', '.', static::class); + + $pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1'); + + $item = $pool1->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertTrue($pool1->save($item->set('bar'))); + + $item = $pool1->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + + $pool2 = new ApcuAdapter($namespace.'_2', 0, 'p1'); + + $item = $pool2->getItem('foo'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get()); + + $item = $pool1->getItem('foo'); + $this->assertTrue($item->isHit()); + $this->assertSame('bar', $item->get()); + } + + public function testWithCliSapi() + { + try { + // disable PHPUnit error handler to mimic a production environment + $isCalled = false; + set_error_handler(function () use (&$isCalled) { + $isCalled = true; + }); + $pool = new ApcuAdapter(str_replace('\\', '.', __CLASS__)); + $pool->setLogger(new NullLogger()); + + $item = $pool->getItem('foo'); + $item->isHit(); + $pool->save($item->set('bar')); + $this->assertFalse($isCalled); + } finally { + restore_error_handler(); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php new file mode 100644 index 00000000..e6adc9d0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\ArrayAdapter; + +/** + * @group time-sensitive + */ +class ArrayAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', + 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', + ]; + + public function createCachePool($defaultLifetime = 0) + { + return new ArrayAdapter($defaultLifetime); + } + + public function testGetValuesHitAndMiss() + { + /** @var ArrayAdapter $cache */ + $cache = $this->createCachePool(); + + // Hit + $item = $cache->getItem('foo'); + $item->set('4711'); + $cache->save($item); + + $fooItem = $cache->getItem('foo'); + $this->assertTrue($fooItem->isHit()); + $this->assertEquals('4711', $fooItem->get()); + + // Miss (should be present as NULL in $values) + $cache->getItem('bar'); + + $values = $cache->getValues(); + + $this->assertCount(2, $values); + $this->assertArrayHasKey('foo', $values); + $this->assertSame(serialize('4711'), $values['foo']); + $this->assertArrayHasKey('bar', $values); + $this->assertNull($values['bar']); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php new file mode 100644 index 00000000..be811d6f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php @@ -0,0 +1,233 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use PHPUnit\Framework\MockObject\MockObject; +use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\ChainAdapter; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter; + +/** + * @author Kévin Dunglas + * @group time-sensitive + */ +class ChainAdapterTest extends AdapterTestCase +{ + public function createCachePool($defaultLifetime = 0) + { + return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime); + } + + public function testEmptyAdaptersException() + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('At least one adapter must be specified.'); + new ChainAdapter([]); + } + + public function testInvalidAdapterException() + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The class "stdClass" does not implement'); + new ChainAdapter([new \stdClass()]); + } + + public function testPrune() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = new ChainAdapter([ + $this->getPruneableMock(), + $this->getNonPruneableMock(), + $this->getPruneableMock(), + ]); + $this->assertTrue($cache->prune()); + + $cache = new ChainAdapter([ + $this->getPruneableMock(), + $this->getFailingPruneableMock(), + $this->getPruneableMock(), + ]); + $this->assertFalse($cache->prune()); + } + + public function testMultipleCachesExpirationWhenCommonTtlIsNotSet() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $adapter1 = new ArrayAdapter(4); + $adapter2 = new ArrayAdapter(2); + + $cache = new ChainAdapter([$adapter1, $adapter2]); + + $cache->save($cache->getItem('key')->set('value')); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertFalse($item->isHit()); + + $adapter2->save($adapter2->getItem('key1')->set('value1')); + + $item = $cache->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + $item = $adapter2->getItem('key1'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertFalse($item->isHit()); + } + + public function testMultipleCachesExpirationWhenCommonTtlIsSet() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $adapter1 = new ArrayAdapter(4); + $adapter2 = new ArrayAdapter(2); + + $cache = new ChainAdapter([$adapter1, $adapter2], 6); + + $cache->save($cache->getItem('key')->set('value')); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertFalse($item->isHit()); + + $adapter2->save($adapter2->getItem('key1')->set('value1')); + + $item = $cache->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + $item = $adapter2->getItem('key1'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertFalse($item->isHit()); + } + + /** + * @return MockObject|PruneableCacheInterface + */ + private function getPruneableMock() + { + $pruneable = $this + ->getMockBuilder(PruneableCacheInterface::class) + ->getMock(); + + $pruneable + ->expects($this->atLeastOnce()) + ->method('prune') + ->willReturn(true); + + return $pruneable; + } + + /** + * @return MockObject|PruneableCacheInterface + */ + private function getFailingPruneableMock() + { + $pruneable = $this + ->getMockBuilder(PruneableCacheInterface::class) + ->getMock(); + + $pruneable + ->expects($this->atLeastOnce()) + ->method('prune') + ->willReturn(false); + + return $pruneable; + } + + /** + * @return MockObject|AdapterInterface + */ + private function getNonPruneableMock() + { + return $this + ->getMockBuilder(AdapterInterface::class) + ->getMock(); + } +} + +interface PruneableCacheInterface extends PruneableInterface, AdapterInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php new file mode 100644 index 00000000..8f520cb5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\DoctrineAdapter; +use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; + +/** + * @group time-sensitive + */ +class DoctrineAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayCache is not.', + 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayCache is not.', + 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', + ]; + + public function createCachePool($defaultLifetime = 0) + { + return new DoctrineAdapter(new ArrayCache($defaultLifetime), '', $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php new file mode 100644 index 00000000..fa830682 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; + +/** + * @group time-sensitive + */ +class FilesystemAdapterTest extends AdapterTestCase +{ + public function createCachePool($defaultLifetime = 0) + { + return new FilesystemAdapter('', $defaultLifetime); + } + + public static function tearDownAfterClass() + { + self::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + + public static function rmdir($dir) + { + if (!file_exists($dir)) { + return; + } + if (!$dir || 0 !== strpos(\dirname($dir), sys_get_temp_dir())) { + throw new \Exception(__METHOD__."() operates only on subdirs of system's temp dir"); + } + $children = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($children as $child) { + if ($child->isDir()) { + rmdir($child); + } else { + unlink($child); + } + } + rmdir($dir); + } + + protected function isPruned(CacheItemPoolInterface $cache, $name) + { + $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); + $getFileMethod->setAccessible(true); + + return !file_exists($getFileMethod->invoke($cache, $name)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php new file mode 100644 index 00000000..536e2c2d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Cache\Adapter\AbstractAdapter; + +class MaxIdLengthAdapterTest extends TestCase +{ + public function testLongKey() + { + $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) + ->setConstructorArgs([str_repeat('-', 10)]) + ->setMethods(['doHave', 'doFetch', 'doDelete', 'doSave', 'doClear']) + ->getMock(); + + $cache->expects($this->exactly(2)) + ->method('doHave') + ->withConsecutive( + [$this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')], + [$this->equalTo('----------:---------------------------------------')] + ); + + $cache->hasItem(str_repeat('-', 40)); + $cache->hasItem(str_repeat('-', 39)); + } + + public function testLongKeyVersioning() + { + $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) + ->setConstructorArgs([str_repeat('-', 26)]) + ->getMock(); + + $cache + ->method('doFetch') + ->willReturn(['2:']); + + $reflectionClass = new \ReflectionClass(AbstractAdapter::class); + + $reflectionMethod = $reflectionClass->getMethod('getId'); + $reflectionMethod->setAccessible(true); + + // No versioning enabled + $this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); + + $reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($cache, true); + + // Versioning enabled + $this->assertEquals('--------------------------:2:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); + } + + public function testTooLongNamespace() + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Namespace must be 26 chars max, 40 given ("----------------------------------------")'); + $this->getMockBuilder(MaxIdLengthAdapter::class) + ->setConstructorArgs([str_repeat('-', 40)]) + ->getMock(); + } +} + +abstract class MaxIdLengthAdapter extends AbstractAdapter +{ + protected $maxIdLength = 50; + + public function __construct($ns) + { + parent::__construct($ns); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php new file mode 100644 index 00000000..a9a397dd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php @@ -0,0 +1,204 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Adapter\MemcachedAdapter; + +class MemcachedAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', + 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', + ]; + + protected static $client; + + public static function setUpBeforeClass() + { + if (!MemcachedAdapter::isSupported()) { + self::markTestSkipped('Extension memcached >=2.2.0 required.'); + } + self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); + self::$client->get('foo'); + $code = self::$client->getResultCode(); + + if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) { + self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage())); + } + } + + public function createCachePool($defaultLifetime = 0) + { + $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')) : self::$client; + + return new MemcachedAdapter($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); + } + + public function testOptions() + { + $client = MemcachedAdapter::createConnection([], [ + 'libketama_compatible' => false, + 'distribution' => 'modula', + 'compression' => true, + 'serializer' => 'php', + 'hash' => 'md5', + ]); + + $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); + $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); + $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); + $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); + $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION)); + } + + /** + * @dataProvider provideBadOptions + */ + public function testBadOptions($name, $value) + { + if (\PHP_VERSION_ID < 80000) { + $this->expectException('ErrorException'); + $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); + } else { + $this->expectException('Error'); + $this->expectExceptionMessage('Undefined constant Memcached::'); + } + + MemcachedAdapter::createConnection([], [$name => $value]); + } + + public function provideBadOptions() + { + return [ + ['foo', 'bar'], + ['hash', 'zyx'], + ['serializer', 'zyx'], + ['distribution', 'zyx'], + ]; + } + + public function testDefaultOptions() + { + $this->assertTrue(MemcachedAdapter::isSupported()); + + $client = MemcachedAdapter::createConnection([]); + + $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); + $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); + $this->assertSame(1, $client->getOption(\Memcached::OPT_TCP_NODELAY)); + $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); + } + + public function testOptionSerializer() + { + $this->expectException('Symfony\Component\Cache\Exception\CacheException'); + $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + if (!\Memcached::HAVE_JSON) { + $this->markTestSkipped('Memcached::HAVE_JSON required'); + } + + new MemcachedAdapter(MemcachedAdapter::createConnection([], ['serializer' => 'json'])); + } + + /** + * @dataProvider provideServersSetting + */ + public function testServersSetting($dsn, $host, $port) + { + $client1 = MemcachedAdapter::createConnection($dsn); + $client2 = MemcachedAdapter::createConnection([$dsn]); + $client3 = MemcachedAdapter::createConnection([[$host, $port]]); + $expect = [ + 'host' => $host, + 'port' => $port, + ]; + + $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; + $this->assertSame([$expect], array_map($f, $client1->getServerList())); + $this->assertSame([$expect], array_map($f, $client2->getServerList())); + $this->assertSame([$expect], array_map($f, $client3->getServerList())); + } + + public function provideServersSetting() + { + yield [ + 'memcached://127.0.0.1/50', + '127.0.0.1', + 11211, + ]; + yield [ + 'memcached://localhost:11222?weight=25', + 'localhost', + 11222, + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ + 'memcached://user:password@127.0.0.1?weight=50', + '127.0.0.1', + 11211, + ]; + } + yield [ + 'memcached:///var/run/memcached.sock?weight=25', + '/var/run/memcached.sock', + 0, + ]; + yield [ + 'memcached:///var/local/run/memcached.socket?weight=25', + '/var/local/run/memcached.socket', + 0, + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ + 'memcached://user:password@/var/local/run/memcached.socket?weight=25', + '/var/local/run/memcached.socket', + 0, + ]; + } + } + + /** + * @dataProvider provideDsnWithOptions + */ + public function testDsnWithOptions($dsn, array $options, array $expectedOptions) + { + $client = MemcachedAdapter::createConnection($dsn, $options); + + foreach ($expectedOptions as $option => $expect) { + $this->assertSame($expect, $client->getOption($option)); + } + } + + public function provideDsnWithOptions() + { + if (!class_exists('\Memcached')) { + self::markTestSkipped('Extension memcached required.'); + } + + yield [ + 'memcached://localhost:11222?retry_timeout=10', + [\Memcached::OPT_RETRY_TIMEOUT => 8], + [\Memcached::OPT_RETRY_TIMEOUT => 10], + ]; + yield [ + 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2', + [\Memcached::OPT_RETRY_TIMEOUT => 8], + [\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8], + ]; + } + + public function testClear() + { + $this->assertTrue($this->createCachePool()->clear()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php new file mode 100644 index 00000000..c2714033 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\ProxyAdapter; + +/** + * @group time-sensitive + */ +class NamespacedProxyAdapterTest extends ProxyAdapterTest +{ + public function createCachePool($defaultLifetime = 0) + { + return new ProxyAdapter(new ArrayAdapter($defaultLifetime), 'foo', $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php new file mode 100644 index 00000000..b771fa0e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use PHPUnit\Framework\TestCase; +use Psr\Cache\CacheItemInterface; +use Symfony\Component\Cache\Adapter\NullAdapter; + +/** + * @group time-sensitive + */ +class NullAdapterTest extends TestCase +{ + public function createCachePool() + { + return new NullAdapter(); + } + + public function testGetItem() + { + $adapter = $this->createCachePool(); + + $item = $adapter->getItem('key'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit is false."); + } + + public function testHasItem() + { + $this->assertFalse($this->createCachePool()->hasItem('key')); + } + + public function testGetItems() + { + $adapter = $this->createCachePool(); + + $keys = ['foo', 'bar', 'baz', 'biz']; + + /** @var CacheItemInterface[] $items */ + $items = $adapter->getItems($keys); + $count = 0; + + foreach ($items as $key => $item) { + $itemKey = $item->getKey(); + + $this->assertEquals($itemKey, $key, 'Keys must be preserved when fetching multiple items'); + $this->assertContains($key, $keys, 'Cache key can not change.'); + $this->assertFalse($item->isHit()); + + // Remove $key for $keys + foreach ($keys as $k => $v) { + if ($v === $key) { + unset($keys[$k]); + } + } + + ++$count; + } + + $this->assertSame(4, $count); + } + + public function testIsHit() + { + $adapter = $this->createCachePool(); + + $item = $adapter->getItem('key'); + $this->assertFalse($item->isHit()); + } + + public function testClear() + { + $this->assertTrue($this->createCachePool()->clear()); + } + + public function testDeleteItem() + { + $this->assertTrue($this->createCachePool()->deleteItem('key')); + } + + public function testDeleteItems() + { + $this->assertTrue($this->createCachePool()->deleteItems(['key', 'foo', 'bar'])); + } + + public function testSave() + { + $adapter = $this->createCachePool(); + + $item = $adapter->getItem('key'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit is false."); + + $this->assertFalse($adapter->save($item)); + } + + public function testDeferredSave() + { + $adapter = $this->createCachePool(); + + $item = $adapter->getItem('key'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit is false."); + + $this->assertFalse($adapter->saveDeferred($item)); + } + + public function testCommit() + { + $adapter = $this->createCachePool(); + + $item = $adapter->getItem('key'); + $this->assertFalse($item->isHit()); + $this->assertNull($item->get(), "Item's value must be null when isHit is false."); + + $this->assertFalse($adapter->saveDeferred($item)); + $this->assertFalse($this->createCachePool()->commit()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php new file mode 100644 index 00000000..dd2a9118 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\PdoAdapter; +use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; + +/** + * @group time-sensitive + */ +class PdoAdapterTest extends AdapterTestCase +{ + use PdoPruneableTrait; + + protected static $dbFile; + + public static function setUpBeforeClass() + { + if (!\extension_loaded('pdo_sqlite')) { + self::markTestSkipped('Extension pdo_sqlite required.'); + } + + self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); + + $pool = new PdoAdapter('sqlite:'.self::$dbFile); + $pool->createTable(); + } + + public static function tearDownAfterClass() + { + @unlink(self::$dbFile); + } + + public function createCachePool($defaultLifetime = 0) + { + return new PdoAdapter('sqlite:'.self::$dbFile, 'ns', $defaultLifetime); + } + + public function testCleanupExpiredItems() + { + $pdo = new \PDO('sqlite:'.self::$dbFile); + + $getCacheItemCount = function () use ($pdo) { + return (int) $pdo->query('SELECT COUNT(*) FROM cache_items')->fetch(\PDO::FETCH_COLUMN); + }; + + $this->assertSame(0, $getCacheItemCount()); + + $cache = $this->createCachePool(); + + $item = $cache->getItem('some_nice_key'); + $item->expiresAfter(1); + $item->set(1); + + $cache->save($item); + $this->assertSame(1, $getCacheItemCount()); + + sleep(2); + + $newItem = $cache->getItem($item->getKey()); + $this->assertFalse($newItem->isHit()); + $this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php new file mode 100644 index 00000000..aa53958c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Doctrine\DBAL\DriverManager; +use Symfony\Component\Cache\Adapter\PdoAdapter; +use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; + +/** + * @group time-sensitive + */ +class PdoDbalAdapterTest extends AdapterTestCase +{ + use PdoPruneableTrait; + + protected static $dbFile; + + public static function setUpBeforeClass() + { + if (!\extension_loaded('pdo_sqlite')) { + self::markTestSkipped('Extension pdo_sqlite required.'); + } + + self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); + + $pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); + $pool->createTable(); + } + + public static function tearDownAfterClass() + { + @unlink(self::$dbFile); + } + + public function createCachePool($defaultLifetime = 0) + { + return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php new file mode 100644 index 00000000..f88a7187 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemInterface; +use Symfony\Component\Cache\Adapter\NullAdapter; +use Symfony\Component\Cache\Adapter\PhpArrayAdapter; + +/** + * @group time-sensitive + */ +class PhpArrayAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testBasicUsage' => 'PhpArrayAdapter is read-only.', + 'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.', + 'testClear' => 'PhpArrayAdapter is read-only.', + 'testClearWithDeferredItems' => 'PhpArrayAdapter is read-only.', + 'testDeleteItem' => 'PhpArrayAdapter is read-only.', + 'testSaveExpired' => 'PhpArrayAdapter is read-only.', + 'testSaveWithoutExpire' => 'PhpArrayAdapter is read-only.', + 'testDeferredSave' => 'PhpArrayAdapter is read-only.', + 'testDeferredSaveWithoutCommit' => 'PhpArrayAdapter is read-only.', + 'testDeleteItems' => 'PhpArrayAdapter is read-only.', + 'testDeleteDeferredItem' => 'PhpArrayAdapter is read-only.', + 'testCommit' => 'PhpArrayAdapter is read-only.', + 'testSaveDeferredWhenChangingValues' => 'PhpArrayAdapter is read-only.', + 'testSaveDeferredOverwrite' => 'PhpArrayAdapter is read-only.', + 'testIsHitDeferred' => 'PhpArrayAdapter is read-only.', + + 'testExpiresAt' => 'PhpArrayAdapter does not support expiration.', + 'testExpiresAtWithNull' => 'PhpArrayAdapter does not support expiration.', + 'testExpiresAfterWithNull' => 'PhpArrayAdapter does not support expiration.', + 'testDeferredExpired' => 'PhpArrayAdapter does not support expiration.', + 'testExpiration' => 'PhpArrayAdapter does not support expiration.', + + 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + + 'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.', + 'testPrune' => 'PhpArrayAdapter just proxies', + ]; + + protected static $file; + + public static function setUpBeforeClass() + { + self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; + } + + protected function tearDown() + { + $this->createCachePool()->clear(); + + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { + FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + } + + public function createCachePool() + { + return new PhpArrayAdapterWrapper(self::$file, new NullAdapter()); + } + + public function testStore() + { + $arrayWithRefs = []; + $arrayWithRefs[0] = 123; + $arrayWithRefs[1] = &$arrayWithRefs[0]; + + $object = (object) [ + 'foo' => 'bar', + 'foo2' => 'bar2', + ]; + + $expected = [ + 'null' => null, + 'serializedString' => serialize($object), + 'arrayWithRefs' => $arrayWithRefs, + 'object' => $object, + 'arrayWithObject' => ['bar' => $object], + ]; + + $adapter = $this->createCachePool(); + $adapter->warmUp($expected); + + foreach ($expected as $key => $value) { + $this->assertSame(serialize($value), serialize($adapter->getItem($key)->get()), 'Warm up should create a PHP file that OPCache can load in memory'); + } + } + + public function testStoredFile() + { + $expected = [ + 'integer' => 42, + 'float' => 42.42, + 'boolean' => true, + 'array_simple' => ['foo', 'bar'], + 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], + ]; + + $adapter = $this->createCachePool(); + $adapter->warmUp($expected); + + $values = eval(substr(file_get_contents(self::$file), 6)); + + $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); + } +} + +class PhpArrayAdapterWrapper extends PhpArrayAdapter +{ + public function save(CacheItemInterface $item) + { + \call_user_func(\Closure::bind(function () use ($item) { + $this->values[$item->getKey()] = $item->get(); + $this->warmUp($this->values); + $this->values = eval(substr(file_get_contents($this->file), 6)); + }, $this, PhpArrayAdapter::class)); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php new file mode 100644 index 00000000..0bfd5c39 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\PhpArrayAdapter; + +/** + * @group time-sensitive + */ +class PhpArrayAdapterWithFallbackTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', + 'testPrune' => 'PhpArrayAdapter just proxies', + ]; + + protected static $file; + + public static function setUpBeforeClass() + { + self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; + } + + protected function tearDown() + { + $this->createCachePool()->clear(); + + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { + FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + } + + public function createCachePool($defaultLifetime = 0) + { + return new PhpArrayAdapter(self::$file, new FilesystemAdapter('php-array-fallback', $defaultLifetime)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php new file mode 100644 index 00000000..247160d5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\PhpFilesAdapter; + +/** + * @group time-sensitive + */ +class PhpFilesAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testDefaultLifeTime' => 'PhpFilesAdapter does not allow configuring a default lifetime.', + ]; + + public function createCachePool() + { + if (!PhpFilesAdapter::isSupported()) { + $this->markTestSkipped('OPcache extension is not enabled.'); + } + + return new PhpFilesAdapter('sf-cache'); + } + + public static function tearDownAfterClass() + { + FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + + protected function isPruned(CacheItemPoolInterface $cache, $name) + { + $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); + $getFileMethod->setAccessible(true); + + return !file_exists($getFileMethod->invoke($cache, $name)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php new file mode 100644 index 00000000..6aadbf26 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Predis\Connection\StreamConnection; +use Symfony\Component\Cache\Adapter\RedisAdapter; + +class PredisAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + parent::setUpBeforeClass(); + self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]); + } + + public function testCreateConnection() + { + $redisHost = getenv('REDIS_HOST'); + + $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', ['class' => \Predis\Client::class, 'timeout' => 3]); + $this->assertInstanceOf(\Predis\Client::class, $redis); + + $connection = $redis->getConnection(); + $this->assertInstanceOf(StreamConnection::class, $connection); + + $params = [ + 'scheme' => 'tcp', + 'host' => $redisHost, + 'path' => '', + 'dbindex' => '1', + 'port' => 6379, + 'class' => 'Predis\Client', + 'timeout' => 3, + 'persistent' => 0, + 'persistent_id' => null, + 'read_timeout' => 0, + 'retry_interval' => 0, + 'lazy' => false, + 'database' => '1', + 'password' => null, + ]; + $this->assertSame($params, $connection->getParameters()->toArray()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php new file mode 100644 index 00000000..1afabaf1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +class PredisClusterAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + parent::setUpBeforeClass(); + self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]); + } + + public static function tearDownAfterClass() + { + self::$redis = null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php new file mode 100644 index 00000000..5b09919e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + self::$redis = new \Predis\Client(explode(' ', $hosts), ['cluster' => 'redis']); + } + + public static function tearDownAfterClass() + { + self::$redis = null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php new file mode 100644 index 00000000..810cb31a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Psr\Cache\CacheItemInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\ProxyAdapter; +use Symfony\Component\Cache\CacheItem; + +/** + * @group time-sensitive + */ +class ProxyAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', + 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', + 'testPrune' => 'ProxyAdapter just proxies', + ]; + + public function createCachePool($defaultLifetime = 0) + { + return new ProxyAdapter(new ArrayAdapter(), '', $defaultLifetime); + } + + public function testProxyfiedItem() + { + $this->expectException('Exception'); + $this->expectExceptionMessage('OK bar'); + $item = new CacheItem(); + $pool = new ProxyAdapter(new TestingArrayAdapter($item)); + + $proxyItem = $pool->getItem('foo'); + + $this->assertNotSame($item, $proxyItem); + $pool->save($proxyItem->set('bar')); + } +} + +class TestingArrayAdapter extends ArrayAdapter +{ + private $item; + + public function __construct(CacheItemInterface $item) + { + $this->item = $item; + } + + public function getItem($key) + { + return $this->item; + } + + public function save(CacheItemInterface $item) + { + if ($item === $this->item) { + throw new \Exception('OK '.$item->get()); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php new file mode 100644 index 00000000..6ec6321a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Adapter\RedisAdapter; +use Symfony\Component\Cache\Traits\RedisProxy; + +class RedisAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + parent::setUpBeforeClass(); + self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]); + } + + public function createCachePool($defaultLifetime = 0) + { + $adapter = parent::createCachePool($defaultLifetime); + $this->assertInstanceOf(RedisProxy::class, self::$redis); + + return $adapter; + } + + public function testCreateConnection() + { + $redisHost = getenv('REDIS_HOST'); + + $redis = RedisAdapter::createConnection('redis://'.$redisHost); + $this->assertInstanceOf(\Redis::class, $redis); + $this->assertTrue($redis->isConnected()); + $this->assertSame(0, $redis->getDbNum()); + + $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2'); + $this->assertSame(2, $redis->getDbNum()); + + $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]); + $this->assertEquals(3, $redis->getTimeout()); + + $redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4'); + $this->assertEquals(4, $redis->getTimeout()); + + $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); + $this->assertEquals(5, $redis->getReadTimeout()); + } + + /** + * @dataProvider provideFailedCreateConnection + */ + public function testFailedCreateConnection($dsn) + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Redis connection '); + RedisAdapter::createConnection($dsn); + } + + public function provideFailedCreateConnection() + { + return [ + ['redis://localhost:1234'], + ['redis://foo@localhost'], + ['redis://localhost/123'], + ]; + } + + /** + * @dataProvider provideInvalidCreateConnection + */ + public function testInvalidCreateConnection($dsn) + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid Redis DSN'); + RedisAdapter::createConnection($dsn); + } + + public function provideInvalidCreateConnection() + { + return [ + ['foo://localhost'], + ['redis://'], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php new file mode 100644 index 00000000..bd9def32 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +class RedisArrayAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + parent::setupBeforeClass(); + if (!class_exists('RedisArray')) { + self::markTestSkipped('The RedisArray class is required.'); + } + self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php new file mode 100644 index 00000000..9c339d2d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +class RedisClusterAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + if (!class_exists('RedisCluster')) { + self::markTestSkipped('The RedisCluster class is required.'); + } + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + + self::$redis = new \RedisCluster(null, explode(' ', $hosts)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php new file mode 100644 index 00000000..d8470a2e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; +use Symfony\Component\Cache\Simple\ArrayCache; +use Symfony\Component\Cache\Simple\FilesystemCache; + +/** + * @group time-sensitive + */ +class SimpleCacheAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testPrune' => 'SimpleCache just proxies', + ]; + + public function createCachePool($defaultLifetime = 0) + { + return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime); + } + + public function testValidCacheKeyWithNamespace() + { + $cache = new SimpleCacheAdapter(new ArrayCache(), 'some_namespace', 0); + $item = $cache->getItem('my_key'); + $item->set('someValue'); + $cache->save($item); + + $this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php new file mode 100644 index 00000000..11907a03 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php @@ -0,0 +1,338 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Cache\CacheItemInterface; +use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\TagAwareAdapter; + +/** + * @group time-sensitive + */ +class TagAwareAdapterTest extends AdapterTestCase +{ + public function createCachePool($defaultLifetime = 0) + { + return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime)); + } + + public static function tearDownAfterClass() + { + FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + + public function testInvalidTag() + { + $this->expectException('Psr\Cache\InvalidArgumentException'); + $pool = $this->createCachePool(); + $item = $pool->getItem('foo'); + $item->tag(':'); + } + + public function testInvalidateTags() + { + $pool = $this->createCachePool(); + + $i0 = $pool->getItem('i0'); + $i1 = $pool->getItem('i1'); + $i2 = $pool->getItem('i2'); + $i3 = $pool->getItem('i3'); + $foo = $pool->getItem('foo'); + + $pool->save($i0->tag('bar')); + $pool->save($i1->tag('foo')); + $pool->save($i2->tag('foo')->tag('bar')); + $pool->save($i3->tag('foo')->tag('baz')); + $pool->save($foo); + + $pool->invalidateTags(['bar']); + + $this->assertFalse($pool->getItem('i0')->isHit()); + $this->assertTrue($pool->getItem('i1')->isHit()); + $this->assertFalse($pool->getItem('i2')->isHit()); + $this->assertTrue($pool->getItem('i3')->isHit()); + $this->assertTrue($pool->getItem('foo')->isHit()); + + $pool->invalidateTags(['foo']); + + $this->assertFalse($pool->getItem('i1')->isHit()); + $this->assertFalse($pool->getItem('i3')->isHit()); + $this->assertTrue($pool->getItem('foo')->isHit()); + + $anotherPoolInstance = $this->createCachePool(); + + $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit()); + $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit()); + $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit()); + } + + public function testInvalidateCommits() + { + $pool1 = $this->createCachePool(); + + $foo = $pool1->getItem('foo'); + $foo->tag('tag'); + + $pool1->saveDeferred($foo->set('foo')); + $pool1->invalidateTags(['tag']); + + $pool2 = $this->createCachePool(); + $foo = $pool2->getItem('foo'); + + $this->assertTrue($foo->isHit()); + } + + public function testTagsAreCleanedOnSave() + { + $pool = $this->createCachePool(); + + $i = $pool->getItem('k'); + $pool->save($i->tag('foo')); + + $i = $pool->getItem('k'); + $pool->save($i->tag('bar')); + + $pool->invalidateTags(['foo']); + $this->assertTrue($pool->getItem('k')->isHit()); + } + + public function testTagsAreCleanedOnDelete() + { + $pool = $this->createCachePool(); + + $i = $pool->getItem('k'); + $pool->save($i->tag('foo')); + $pool->deleteItem('k'); + + $pool->save($pool->getItem('k')); + $pool->invalidateTags(['foo']); + + $this->assertTrue($pool->getItem('k')->isHit()); + } + + public function testTagItemExpiry() + { + $pool = $this->createCachePool(10); + + $item = $pool->getItem('foo'); + $item->tag(['baz']); + $item->expiresAfter(100); + + $pool->save($item); + $pool->invalidateTags(['baz']); + $this->assertFalse($pool->getItem('foo')->isHit()); + + sleep(20); + + $this->assertFalse($pool->getItem('foo')->isHit()); + } + + public function testGetPreviousTags() + { + $pool = $this->createCachePool(); + + $i = $pool->getItem('k'); + $pool->save($i->tag('foo')); + + $i = $pool->getItem('k'); + $this->assertSame(['foo' => 'foo'], $i->getPreviousTags()); + } + + public function testPrune() + { + $cache = new TagAwareAdapter($this->getPruneableMock()); + $this->assertTrue($cache->prune()); + + $cache = new TagAwareAdapter($this->getNonPruneableMock()); + $this->assertFalse($cache->prune()); + + $cache = new TagAwareAdapter($this->getFailingPruneableMock()); + $this->assertFalse($cache->prune()); + } + + public function testKnownTagVersionsTtl() + { + $itemsPool = new FilesystemAdapter('', 10); + $tagsPool = $this + ->getMockBuilder(AdapterInterface::class) + ->getMock(); + + $pool = new TagAwareAdapter($itemsPool, $tagsPool, 10); + + $item = $pool->getItem('foo'); + $item->tag(['baz']); + $item->expiresAfter(100); + + $tag = $this->getMockBuilder(CacheItemInterface::class)->getMock(); + $tag->expects(self::exactly(2))->method('get')->willReturn(10); + + $tagsPool->expects(self::exactly(2))->method('getItems')->willReturn([ + 'baz'.TagAwareAdapter::TAGS_PREFIX => $tag, + ]); + + $pool->save($item); + $this->assertTrue($pool->getItem('foo')->isHit()); + $this->assertTrue($pool->getItem('foo')->isHit()); + + sleep(20); + + $this->assertTrue($pool->getItem('foo')->isHit()); + + sleep(5); + + $this->assertTrue($pool->getItem('foo')->isHit()); + } + + public function testTagEntryIsCreatedForItemWithoutTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $adapter = new FilesystemAdapter(); + $this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey)); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testInvalidateTagsWithArrayAdapter() + { + $adapter = new TagAwareAdapter(new ArrayAdapter()); + + $item = $adapter->getItem('foo'); + + $this->assertFalse($item->isHit()); + + $item->tag('bar'); + $item->expiresAfter(100); + $adapter->save($item); + + $this->assertTrue($adapter->getItem('foo')->isHit()); + + $adapter->invalidateTags(['bar']); + + $this->assertFalse($adapter->getItem('foo')->isHit()); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + + /** + * @return MockObject|PruneableCacheInterface + */ + private function getPruneableMock() + { + $pruneable = $this + ->getMockBuilder(PruneableCacheInterface::class) + ->getMock(); + + $pruneable + ->expects($this->atLeastOnce()) + ->method('prune') + ->willReturn(true); + + return $pruneable; + } + + /** + * @return MockObject|PruneableCacheInterface + */ + private function getFailingPruneableMock() + { + $pruneable = $this + ->getMockBuilder(PruneableCacheInterface::class) + ->getMock(); + + $pruneable + ->expects($this->atLeastOnce()) + ->method('prune') + ->willReturn(false); + + return $pruneable; + } + + /** + * @return MockObject|AdapterInterface + */ + private function getNonPruneableMock() + { + return $this + ->getMockBuilder(AdapterInterface::class) + ->getMock(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php new file mode 100644 index 00000000..b11c1f28 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php @@ -0,0 +1,38 @@ +getItem('foo'); + $item->tag(['tag1', 'tag2']); + $item->set('bar'); + $cache->save($item); + + $this->assertSame('bar', $cache->getItem('foo')->get()); + } + + public function dataProvider() + { + return [ + [new ArrayAdapter()], + // also testing with a non-AdapterInterface implementation + // because the ProxyAdapter behaves slightly different for those + [new ExternalAdapter()], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php new file mode 100644 index 00000000..35eba7d7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php @@ -0,0 +1,191 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\TraceableAdapter; + +/** + * @group time-sensitive + */ +class TraceableAdapterTest extends AdapterTestCase +{ + protected $skippedTests = [ + 'testPrune' => 'TraceableAdapter just proxies', + ]; + + public function createCachePool($defaultLifetime = 0) + { + return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime)); + } + + public function testGetItemMissTrace() + { + $pool = $this->createCachePool(); + $pool->getItem('k'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('getItem', $call->name); + $this->assertSame(['k' => false], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(1, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testGetItemHitTrace() + { + $pool = $this->createCachePool(); + $item = $pool->getItem('k')->set('foo'); + $pool->save($item); + $pool->getItem('k'); + $calls = $pool->getCalls(); + $this->assertCount(3, $calls); + + $call = $calls[2]; + $this->assertSame(1, $call->hits); + $this->assertSame(0, $call->misses); + } + + public function testGetItemsMissTrace() + { + $pool = $this->createCachePool(); + $arg = ['k0', 'k1']; + $items = $pool->getItems($arg); + foreach ($items as $item) { + } + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('getItems', $call->name); + $this->assertSame(['k0' => false, 'k1' => false], $call->result); + $this->assertSame(2, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testHasItemMissTrace() + { + $pool = $this->createCachePool(); + $pool->hasItem('k'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('hasItem', $call->name); + $this->assertSame(['k' => false], $call->result); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testHasItemHitTrace() + { + $pool = $this->createCachePool(); + $item = $pool->getItem('k')->set('foo'); + $pool->save($item); + $pool->hasItem('k'); + $calls = $pool->getCalls(); + $this->assertCount(3, $calls); + + $call = $calls[2]; + $this->assertSame('hasItem', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testDeleteItemTrace() + { + $pool = $this->createCachePool(); + $pool->deleteItem('k'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('deleteItem', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testDeleteItemsTrace() + { + $pool = $this->createCachePool(); + $arg = ['k0', 'k1']; + $pool->deleteItems($arg); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('deleteItems', $call->name); + $this->assertSame(['keys' => $arg, 'result' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testSaveTrace() + { + $pool = $this->createCachePool(); + $item = $pool->getItem('k')->set('foo'); + $pool->save($item); + $calls = $pool->getCalls(); + $this->assertCount(2, $calls); + + $call = $calls[1]; + $this->assertSame('save', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testSaveDeferredTrace() + { + $pool = $this->createCachePool(); + $item = $pool->getItem('k')->set('foo'); + $pool->saveDeferred($item); + $calls = $pool->getCalls(); + $this->assertCount(2, $calls); + + $call = $calls[1]; + $this->assertSame('saveDeferred', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testCommitTrace() + { + $pool = $this->createCachePool(); + $pool->commit(); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('commit', $call->name); + $this->assertTrue($call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php new file mode 100644 index 00000000..5cd4185c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Adapter\TagAwareAdapter; +use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter; + +/** + * @group time-sensitive + */ +class TraceableTagAwareAdapterTest extends TraceableAdapterTest +{ + public function testInvalidateTags() + { + $pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter())); + $pool->invalidateTags(['foo']); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('invalidateTags', $call->name); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/CacheItemTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/CacheItemTest.php new file mode 100644 index 00000000..28c681d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/CacheItemTest.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Cache\CacheItem; + +class CacheItemTest extends TestCase +{ + public function testValidKey() + { + $this->assertSame('foo', CacheItem::validateKey('foo')); + } + + /** + * @dataProvider provideInvalidKey + */ + public function testInvalidKey($key) + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Cache key'); + CacheItem::validateKey($key); + } + + public function provideInvalidKey() + { + return [ + [''], + ['{'], + ['}'], + ['('], + [')'], + ['/'], + ['\\'], + ['@'], + [':'], + [true], + [null], + [1], + [1.1], + [[[]]], + [new \Exception('foo')], + ]; + } + + public function testTag() + { + $item = new CacheItem(); + + $this->assertSame($item, $item->tag('foo')); + $this->assertSame($item, $item->tag(['bar', 'baz'])); + + \call_user_func(\Closure::bind(function () use ($item) { + $this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->tags); + }, $this, CacheItem::class)); + } + + /** + * @dataProvider provideInvalidKey + */ + public function testInvalidTag($tag) + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Cache tag'); + $item = new CacheItem(); + $item->tag($tag); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/DoctrineProviderTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/DoctrineProviderTest.php new file mode 100644 index 00000000..91a5516a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/DoctrineProviderTest.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests; + +use Doctrine\Common\Cache\CacheProvider; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\Cache\DoctrineProvider; + +class DoctrineProviderTest extends TestCase +{ + public function testProvider() + { + $pool = new ArrayAdapter(); + $cache = new DoctrineProvider($pool); + + $this->assertInstanceOf(CacheProvider::class, $cache); + + $key = '{}()/\@:'; + + $this->assertTrue($cache->delete($key)); + $this->assertFalse($cache->contains($key)); + + $this->assertTrue($cache->save($key, 'bar')); + $this->assertTrue($cache->contains($key)); + $this->assertSame('bar', $cache->fetch($key)); + + $this->assertTrue($cache->delete($key)); + $this->assertFalse($cache->fetch($key)); + $this->assertTrue($cache->save($key, 'bar')); + + $cache->flushAll(); + $this->assertFalse($cache->fetch($key)); + $this->assertFalse($cache->contains($key)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php new file mode 100644 index 00000000..13b4f330 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php @@ -0,0 +1,52 @@ +doContains($id) ? $this->data[$id][0] : false; + } + + protected function doContains($id) + { + if (!isset($this->data[$id])) { + return false; + } + + $expiry = $this->data[$id][1]; + + return !$expiry || time() < $expiry || !$this->doDelete($id); + } + + protected function doSave($id, $data, $lifeTime = 0) + { + $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false]; + + return true; + } + + protected function doDelete($id) + { + unset($this->data[$id]); + + return true; + } + + protected function doFlush() + { + $this->data = []; + + return true; + } + + protected function doGetStats() + { + return null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php new file mode 100644 index 00000000..be1f9901 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Fixtures; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; + +/** + * Adapter not implementing the {@see \Symfony\Component\Cache\Adapter\AdapterInterface}. + * + * @author Kévin Dunglas + */ +class ExternalAdapter implements CacheItemPoolInterface +{ + private $cache; + + public function __construct($defaultLifetime = 0) + { + $this->cache = new ArrayAdapter($defaultLifetime); + } + + public function getItem($key) + { + return $this->cache->getItem($key); + } + + public function getItems(array $keys = []) + { + return $this->cache->getItems($keys); + } + + public function hasItem($key) + { + return $this->cache->hasItem($key); + } + + public function clear() + { + return $this->cache->clear(); + } + + public function deleteItem($key) + { + return $this->cache->deleteItem($key); + } + + public function deleteItems(array $keys) + { + return $this->cache->deleteItems($keys); + } + + public function save(CacheItemInterface $item) + { + return $this->cache->save($item); + } + + public function saveDeferred(CacheItemInterface $item) + { + return $this->cache->saveDeferred($item); + } + + public function commit() + { + return $this->cache->commit(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php new file mode 100644 index 00000000..7a6cabe8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\RedisCache; + +abstract class AbstractRedisCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testSetTtl' => 'Testing expiration slows down the test suite', + 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', + 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', + ]; + + protected static $redis; + + public function createSimpleCache($defaultLifetime = 0) + { + return new RedisCache(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); + } + + public static function setUpBeforeClass() + { + if (!\extension_loaded('redis')) { + self::markTestSkipped('Extension redis required.'); + } + try { + (new \Redis())->connect(getenv('REDIS_HOST')); + } catch (\Exception $e) { + self::markTestSkipped($e->getMessage()); + } + } + + public static function tearDownAfterClass() + { + self::$redis = null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php new file mode 100644 index 00000000..fad0c043 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\ApcuCache; + +class ApcuCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testSetTtl' => 'Testing expiration slows down the test suite', + 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', + 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', + ]; + + public function createSimpleCache($defaultLifetime = 0) + { + if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { + $this->markTestSkipped('APCu extension is required.'); + } + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Fails transiently on Windows.'); + } + + return new ApcuCache(str_replace('\\', '.', __CLASS__), $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php new file mode 100644 index 00000000..26c3e14d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\ArrayCache; + +/** + * @group time-sensitive + */ +class ArrayCacheTest extends CacheTestCase +{ + public function createSimpleCache($defaultLifetime = 0) + { + return new ArrayCache($defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/CacheTestCase.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/CacheTestCase.php new file mode 100644 index 00000000..ff9944a3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/CacheTestCase.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Cache\IntegrationTests\SimpleCacheTest; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\PruneableInterface; + +abstract class CacheTestCase extends SimpleCacheTest +{ + protected function setUp() + { + parent::setUp(); + + if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createSimpleCache() instanceof PruneableInterface) { + $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; + } + } + + public static function validKeys() + { + if (\defined('HHVM_VERSION')) { + return parent::validKeys(); + } + + return array_merge(parent::validKeys(), [["a\0b"]]); + } + + public function testDefaultLifeTime() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createSimpleCache(2); + $cache->clear(); + + $cache->set('key.dlt', 'value'); + sleep(1); + + $this->assertSame('value', $cache->get('key.dlt')); + + sleep(2); + $this->assertNull($cache->get('key.dlt')); + + $cache->clear(); + } + + public function testNotUnserializable() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = $this->createSimpleCache(); + $cache->clear(); + + $cache->set('foo', new NotUnserializable()); + + $this->assertNull($cache->get('foo')); + + $cache->setMultiple(['foo' => new NotUnserializable()]); + + foreach ($cache->getMultiple(['foo']) as $value) { + } + $this->assertNull($value); + + $cache->clear(); + } + + public function testPrune() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + if (!method_exists($this, 'isPruned')) { + $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); + } + + /** @var PruneableInterface|CacheInterface $cache */ + $cache = $this->createSimpleCache(); + $cache->clear(); + + $cache->set('foo', 'foo-val', new \DateInterval('PT05S')); + $cache->set('bar', 'bar-val', new \DateInterval('PT10S')); + $cache->set('baz', 'baz-val', new \DateInterval('PT15S')); + $cache->set('qux', 'qux-val', new \DateInterval('PT20S')); + + sleep(30); + $cache->prune(); + $this->assertTrue($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'bar')); + $this->assertTrue($this->isPruned($cache, 'baz')); + $this->assertTrue($this->isPruned($cache, 'qux')); + + $cache->set('foo', 'foo-val'); + $cache->set('bar', 'bar-val', new \DateInterval('PT20S')); + $cache->set('baz', 'baz-val', new \DateInterval('PT40S')); + $cache->set('qux', 'qux-val', new \DateInterval('PT80S')); + + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertFalse($this->isPruned($cache, 'bar')); + $this->assertFalse($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'bar')); + $this->assertFalse($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'baz')); + $this->assertFalse($this->isPruned($cache, 'qux')); + + sleep(30); + $cache->prune(); + $this->assertFalse($this->isPruned($cache, 'foo')); + $this->assertTrue($this->isPruned($cache, 'qux')); + + $cache->clear(); + } +} + +class NotUnserializable implements \Serializable +{ + public function serialize() + { + return serialize(123); + } + + public function unserialize($ser) + { + throw new \Exception(__CLASS__); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php new file mode 100644 index 00000000..f216bc1f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use PHPUnit\Framework\MockObject\MockObject; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\Simple\ArrayCache; +use Symfony\Component\Cache\Simple\ChainCache; +use Symfony\Component\Cache\Simple\FilesystemCache; + +/** + * @group time-sensitive + */ +class ChainCacheTest extends CacheTestCase +{ + public function createSimpleCache($defaultLifetime = 0) + { + return new ChainCache([new ArrayCache($defaultLifetime), new FilesystemCache('', $defaultLifetime)], $defaultLifetime); + } + + public function testEmptyCachesException() + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('At least one cache must be specified.'); + new ChainCache([]); + } + + public function testInvalidCacheException() + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The class "stdClass" does not implement'); + new ChainCache([new \stdClass()]); + } + + public function testPrune() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $cache = new ChainCache([ + $this->getPruneableMock(), + $this->getNonPruneableMock(), + $this->getPruneableMock(), + ]); + $this->assertTrue($cache->prune()); + + $cache = new ChainCache([ + $this->getPruneableMock(), + $this->getFailingPruneableMock(), + $this->getPruneableMock(), + ]); + $this->assertFalse($cache->prune()); + } + + /** + * @return MockObject|PruneableCacheInterface + */ + private function getPruneableMock() + { + $pruneable = $this + ->getMockBuilder(PruneableCacheInterface::class) + ->getMock(); + + $pruneable + ->expects($this->atLeastOnce()) + ->method('prune') + ->willReturn(true); + + return $pruneable; + } + + /** + * @return MockObject|PruneableCacheInterface + */ + private function getFailingPruneableMock() + { + $pruneable = $this + ->getMockBuilder(PruneableCacheInterface::class) + ->getMock(); + + $pruneable + ->expects($this->atLeastOnce()) + ->method('prune') + ->willReturn(false); + + return $pruneable; + } + + /** + * @return MockObject|CacheInterface + */ + private function getNonPruneableMock() + { + return $this + ->getMockBuilder(CacheInterface::class) + ->getMock(); + } +} + +interface PruneableCacheInterface extends PruneableInterface, CacheInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php new file mode 100644 index 00000000..af4331d6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\DoctrineCache; +use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; + +/** + * @group time-sensitive + */ +class DoctrineCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testObjectDoesNotChangeInCache' => 'ArrayCache does not use serialize/unserialize', + 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', + ]; + + public function createSimpleCache($defaultLifetime = 0) + { + return new DoctrineCache(new ArrayCache($defaultLifetime), '', $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php new file mode 100644 index 00000000..620305a5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Simple\FilesystemCache; + +/** + * @group time-sensitive + */ +class FilesystemCacheTest extends CacheTestCase +{ + public function createSimpleCache($defaultLifetime = 0) + { + return new FilesystemCache('', $defaultLifetime); + } + + protected function isPruned(CacheInterface $cache, $name) + { + $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); + $getFileMethod->setAccessible(true); + + return !file_exists($getFileMethod->invoke($cache, $name)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php new file mode 100644 index 00000000..6df682e9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php @@ -0,0 +1,178 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Simple\MemcachedCache; + +class MemcachedCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testSetTtl' => 'Testing expiration slows down the test suite', + 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', + 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', + ]; + + protected static $client; + + public static function setUpBeforeClass() + { + if (!MemcachedCache::isSupported()) { + self::markTestSkipped('Extension memcached >=2.2.0 required.'); + } + self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')); + self::$client->get('foo'); + $code = self::$client->getResultCode(); + + if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) { + self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage())); + } + } + + public function createSimpleCache($defaultLifetime = 0) + { + $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]) : self::$client; + + return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); + } + + public function testCreatePersistentConnectionShouldNotDupServerList() + { + $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); + $this->assertCount(1, $instance->getServerList()); + + $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); + $this->assertCount(1, $instance->getServerList()); + } + + public function testOptions() + { + $client = MemcachedCache::createConnection([], [ + 'libketama_compatible' => false, + 'distribution' => 'modula', + 'compression' => true, + 'serializer' => 'php', + 'hash' => 'md5', + ]); + + $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); + $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); + $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); + $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); + $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION)); + } + + /** + * @dataProvider provideBadOptions + */ + public function testBadOptions($name, $value) + { + if (\PHP_VERSION_ID < 80000) { + $this->expectException('ErrorException'); + $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); + } else { + $this->expectException('Error'); + $this->expectExceptionMessage('Undefined constant Memcached::'); + } + + MemcachedCache::createConnection([], [$name => $value]); + } + + public function provideBadOptions() + { + return [ + ['foo', 'bar'], + ['hash', 'zyx'], + ['serializer', 'zyx'], + ['distribution', 'zyx'], + ]; + } + + public function testDefaultOptions() + { + $this->assertTrue(MemcachedCache::isSupported()); + + $client = MemcachedCache::createConnection([]); + + $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); + $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); + $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); + } + + public function testOptionSerializer() + { + $this->expectException('Symfony\Component\Cache\Exception\CacheException'); + $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + if (!\Memcached::HAVE_JSON) { + $this->markTestSkipped('Memcached::HAVE_JSON required'); + } + + new MemcachedCache(MemcachedCache::createConnection([], ['serializer' => 'json'])); + } + + /** + * @dataProvider provideServersSetting + */ + public function testServersSetting($dsn, $host, $port) + { + $client1 = MemcachedCache::createConnection($dsn); + $client2 = MemcachedCache::createConnection([$dsn]); + $client3 = MemcachedCache::createConnection([[$host, $port]]); + $expect = [ + 'host' => $host, + 'port' => $port, + ]; + + $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; + $this->assertSame([$expect], array_map($f, $client1->getServerList())); + $this->assertSame([$expect], array_map($f, $client2->getServerList())); + $this->assertSame([$expect], array_map($f, $client3->getServerList())); + } + + public function provideServersSetting() + { + yield [ + 'memcached://127.0.0.1/50', + '127.0.0.1', + 11211, + ]; + yield [ + 'memcached://localhost:11222?weight=25', + 'localhost', + 11222, + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ + 'memcached://user:password@127.0.0.1?weight=50', + '127.0.0.1', + 11211, + ]; + } + yield [ + 'memcached:///var/run/memcached.sock?weight=25', + '/var/run/memcached.sock', + 0, + ]; + yield [ + 'memcached:///var/local/run/memcached.socket?weight=25', + '/var/local/run/memcached.socket', + 0, + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ + 'memcached://user:password@/var/local/run/memcached.socket?weight=25', + '/var/local/run/memcached.socket', + 0, + ]; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php new file mode 100644 index 00000000..13865a60 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Simple\MemcachedCache; + +class MemcachedCacheTextModeTest extends MemcachedCacheTest +{ + public function createSimpleCache($defaultLifetime = 0) + { + $client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); + + return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/NullCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/NullCacheTest.php new file mode 100644 index 00000000..31f42c32 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/NullCacheTest.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Cache\Simple\NullCache; + +/** + * @group time-sensitive + */ +class NullCacheTest extends TestCase +{ + public function createCachePool() + { + return new NullCache(); + } + + public function testGetItem() + { + $cache = $this->createCachePool(); + + $this->assertNull($cache->get('key')); + } + + public function testHas() + { + $this->assertFalse($this->createCachePool()->has('key')); + } + + public function testGetMultiple() + { + $cache = $this->createCachePool(); + + $keys = ['foo', 'bar', 'baz', 'biz']; + + $default = new \stdClass(); + $items = $cache->getMultiple($keys, $default); + $count = 0; + + foreach ($items as $key => $item) { + $this->assertContains($key, $keys, 'Cache key can not change.'); + $this->assertSame($default, $item); + + // Remove $key for $keys + foreach ($keys as $k => $v) { + if ($v === $key) { + unset($keys[$k]); + } + } + + ++$count; + } + + $this->assertSame(4, $count); + } + + public function testClear() + { + $this->assertTrue($this->createCachePool()->clear()); + } + + public function testDelete() + { + $this->assertTrue($this->createCachePool()->delete('key')); + } + + public function testDeleteMultiple() + { + $this->assertTrue($this->createCachePool()->deleteMultiple(['key', 'foo', 'bar'])); + } + + public function testSet() + { + $cache = $this->createCachePool(); + + $this->assertFalse($cache->set('key', 'val')); + $this->assertNull($cache->get('key')); + } + + public function testSetMultiple() + { + $cache = $this->createCachePool(); + + $this->assertFalse($cache->setMultiple(['key' => 'val'])); + $this->assertNull($cache->get('key')); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php new file mode 100644 index 00000000..f5a26341 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\PdoCache; +use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; + +/** + * @group time-sensitive + */ +class PdoCacheTest extends CacheTestCase +{ + use PdoPruneableTrait; + + protected static $dbFile; + + public static function setUpBeforeClass() + { + if (!\extension_loaded('pdo_sqlite')) { + self::markTestSkipped('Extension pdo_sqlite required.'); + } + + self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); + + $pool = new PdoCache('sqlite:'.self::$dbFile); + $pool->createTable(); + } + + public static function tearDownAfterClass() + { + @unlink(self::$dbFile); + } + + public function createSimpleCache($defaultLifetime = 0) + { + return new PdoCache('sqlite:'.self::$dbFile, 'ns', $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php new file mode 100644 index 00000000..4da2b603 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Doctrine\DBAL\DriverManager; +use Symfony\Component\Cache\Simple\PdoCache; +use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; + +/** + * @group time-sensitive + */ +class PdoDbalCacheTest extends CacheTestCase +{ + use PdoPruneableTrait; + + protected static $dbFile; + + public static function setUpBeforeClass() + { + if (!\extension_loaded('pdo_sqlite')) { + self::markTestSkipped('Extension pdo_sqlite required.'); + } + + self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); + + $pool = new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); + $pool->createTable(); + } + + public static function tearDownAfterClass() + { + @unlink(self::$dbFile); + } + + public function createSimpleCache($defaultLifetime = 0) + { + return new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php new file mode 100644 index 00000000..bcd7dea5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\NullCache; +use Symfony\Component\Cache\Simple\PhpArrayCache; +use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; + +/** + * @group time-sensitive + */ +class PhpArrayCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testBasicUsageWithLongKey' => 'PhpArrayCache does no writes', + + 'testDelete' => 'PhpArrayCache does no writes', + 'testDeleteMultiple' => 'PhpArrayCache does no writes', + 'testDeleteMultipleGenerator' => 'PhpArrayCache does no writes', + + 'testSetTtl' => 'PhpArrayCache does no expiration', + 'testSetMultipleTtl' => 'PhpArrayCache does no expiration', + 'testSetExpiredTtl' => 'PhpArrayCache does no expiration', + 'testSetMultipleExpiredTtl' => 'PhpArrayCache does no expiration', + + 'testGetInvalidKeys' => 'PhpArrayCache does no validation', + 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', + 'testSetInvalidKeys' => 'PhpArrayCache does no validation', + 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', + 'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation', + 'testSetInvalidTtl' => 'PhpArrayCache does no validation', + 'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation', + 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', + 'testHasInvalidKeys' => 'PhpArrayCache does no validation', + 'testSetValidData' => 'PhpArrayCache does no validation', + + 'testDefaultLifeTime' => 'PhpArrayCache does not allow configuring a default lifetime.', + 'testPrune' => 'PhpArrayCache just proxies', + ]; + + protected static $file; + + public static function setUpBeforeClass() + { + self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; + } + + protected function tearDown() + { + $this->createSimpleCache()->clear(); + + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { + FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + } + + public function createSimpleCache() + { + return new PhpArrayCacheWrapper(self::$file, new NullCache()); + } + + public function testStore() + { + $arrayWithRefs = []; + $arrayWithRefs[0] = 123; + $arrayWithRefs[1] = &$arrayWithRefs[0]; + + $object = (object) [ + 'foo' => 'bar', + 'foo2' => 'bar2', + ]; + + $expected = [ + 'null' => null, + 'serializedString' => serialize($object), + 'arrayWithRefs' => $arrayWithRefs, + 'object' => $object, + 'arrayWithObject' => ['bar' => $object], + ]; + + $cache = new PhpArrayCache(self::$file, new NullCache()); + $cache->warmUp($expected); + + foreach ($expected as $key => $value) { + $this->assertSame(serialize($value), serialize($cache->get($key)), 'Warm up should create a PHP file that OPCache can load in memory'); + } + } + + public function testStoredFile() + { + $expected = [ + 'integer' => 42, + 'float' => 42.42, + 'boolean' => true, + 'array_simple' => ['foo', 'bar'], + 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], + ]; + + $cache = new PhpArrayCache(self::$file, new NullCache()); + $cache->warmUp($expected); + + $values = eval(substr(file_get_contents(self::$file), 6)); + + $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); + } +} + +class PhpArrayCacheWrapper extends PhpArrayCache +{ + public function set($key, $value, $ttl = null) + { + \call_user_func(\Closure::bind(function () use ($key, $value) { + $this->values[$key] = $value; + $this->warmUp($this->values); + $this->values = eval(substr(file_get_contents($this->file), 6)); + }, $this, PhpArrayCache::class)); + + return true; + } + + public function setMultiple($values, $ttl = null) + { + if (!\is_array($values) && !$values instanceof \Traversable) { + return parent::setMultiple($values, $ttl); + } + \call_user_func(\Closure::bind(function () use ($values) { + foreach ($values as $key => $value) { + $this->values[$key] = $value; + } + $this->warmUp($this->values); + $this->values = eval(substr(file_get_contents($this->file), 6)); + }, $this, PhpArrayCache::class)); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php new file mode 100644 index 00000000..b08c1604 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\FilesystemCache; +use Symfony\Component\Cache\Simple\PhpArrayCache; +use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; + +/** + * @group time-sensitive + */ +class PhpArrayCacheWithFallbackTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testGetInvalidKeys' => 'PhpArrayCache does no validation', + 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', + 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', + 'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation', + //'testSetValidData' => 'PhpArrayCache does no validation', + 'testSetInvalidKeys' => 'PhpArrayCache does no validation', + 'testSetInvalidTtl' => 'PhpArrayCache does no validation', + 'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation', + 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', + 'testHasInvalidKeys' => 'PhpArrayCache does no validation', + 'testPrune' => 'PhpArrayCache just proxies', + ]; + + protected static $file; + + public static function setUpBeforeClass() + { + self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; + } + + protected function tearDown() + { + $this->createSimpleCache()->clear(); + + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { + FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); + } + } + + public function createSimpleCache($defaultLifetime = 0) + { + return new PhpArrayCache(self::$file, new FilesystemCache('php-array-fallback', $defaultLifetime)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php new file mode 100644 index 00000000..936f29a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Simple\PhpFilesCache; + +/** + * @group time-sensitive + */ +class PhpFilesCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testDefaultLifeTime' => 'PhpFilesCache does not allow configuring a default lifetime.', + ]; + + public function createSimpleCache() + { + if (!PhpFilesCache::isSupported()) { + $this->markTestSkipped('OPcache extension is not enabled.'); + } + + return new PhpFilesCache('sf-cache'); + } + + protected function isPruned(CacheInterface $cache, $name) + { + $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); + $getFileMethod->setAccessible(true); + + return !file_exists($getFileMethod->invoke($cache, $name)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php new file mode 100644 index 00000000..1bc75c90 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\Simple\Psr6Cache; + +/** + * @group time-sensitive + */ +class Psr6CacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testPrune' => 'Psr6Cache just proxies', + ]; + + public function createSimpleCache($defaultLifetime = 0) + { + return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php new file mode 100644 index 00000000..ec5e4c06 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +class RedisArrayCacheTest extends AbstractRedisCacheTest +{ + public static function setUpBeforeClass() + { + parent::setupBeforeClass(); + if (!class_exists('RedisArray')) { + self::markTestSkipped('The RedisArray class is required.'); + } + self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php new file mode 100644 index 00000000..8e3f6088 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\RedisCache; + +class RedisCacheTest extends AbstractRedisCacheTest +{ + public static function setUpBeforeClass() + { + parent::setupBeforeClass(); + self::$redis = RedisCache::createConnection('redis://'.getenv('REDIS_HOST')); + } + + public function testCreateConnection() + { + $redisHost = getenv('REDIS_HOST'); + + $redis = RedisCache::createConnection('redis://'.$redisHost); + $this->assertInstanceOf(\Redis::class, $redis); + $this->assertTrue($redis->isConnected()); + $this->assertSame(0, $redis->getDbNum()); + + $redis = RedisCache::createConnection('redis://'.$redisHost.'/2'); + $this->assertSame(2, $redis->getDbNum()); + + $redis = RedisCache::createConnection('redis://'.$redisHost, ['timeout' => 3]); + $this->assertEquals(3, $redis->getTimeout()); + + $redis = RedisCache::createConnection('redis://'.$redisHost.'?timeout=4'); + $this->assertEquals(4, $redis->getTimeout()); + + $redis = RedisCache::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); + $this->assertEquals(5, $redis->getReadTimeout()); + } + + /** + * @dataProvider provideFailedCreateConnection + */ + public function testFailedCreateConnection($dsn) + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Redis connection '); + RedisCache::createConnection($dsn); + } + + public function provideFailedCreateConnection() + { + return [ + ['redis://localhost:1234'], + ['redis://foo@localhost'], + ['redis://localhost/123'], + ]; + } + + /** + * @dataProvider provideInvalidCreateConnection + */ + public function testInvalidCreateConnection($dsn) + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid Redis DSN'); + RedisCache::createConnection($dsn); + } + + public function provideInvalidCreateConnection() + { + return [ + ['foo://localhost'], + ['redis://'], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php new file mode 100644 index 00000000..6b7f8039 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +class RedisClusterCacheTest extends AbstractRedisCacheTest +{ + public static function setUpBeforeClass() + { + if (!class_exists('RedisCluster')) { + self::markTestSkipped('The RedisCluster class is required.'); + } + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + + self::$redis = new \RedisCluster(null, explode(' ', $hosts)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php new file mode 100644 index 00000000..e684caf3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Simple\FilesystemCache; +use Symfony\Component\Cache\Simple\TraceableCache; + +/** + * @group time-sensitive + */ +class TraceableCacheTest extends CacheTestCase +{ + protected $skippedTests = [ + 'testPrune' => 'TraceableCache just proxies', + ]; + + public function createSimpleCache($defaultLifetime = 0) + { + return new TraceableCache(new FilesystemCache('', $defaultLifetime)); + } + + public function testGetMissTrace() + { + $pool = $this->createSimpleCache(); + $pool->get('k'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('get', $call->name); + $this->assertSame(['k' => false], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(1, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testGetHitTrace() + { + $pool = $this->createSimpleCache(); + $pool->set('k', 'foo'); + $pool->get('k'); + $calls = $pool->getCalls(); + $this->assertCount(2, $calls); + + $call = $calls[1]; + $this->assertSame(1, $call->hits); + $this->assertSame(0, $call->misses); + } + + public function testGetMultipleMissTrace() + { + $pool = $this->createSimpleCache(); + $pool->set('k1', 123); + $values = $pool->getMultiple(['k0', 'k1']); + foreach ($values as $value) { + } + $calls = $pool->getCalls(); + $this->assertCount(2, $calls); + + $call = $calls[1]; + $this->assertSame('getMultiple', $call->name); + $this->assertSame(['k1' => true, 'k0' => false], $call->result); + $this->assertSame(1, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testHasMissTrace() + { + $pool = $this->createSimpleCache(); + $pool->has('k'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('has', $call->name); + $this->assertSame(['k' => false], $call->result); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testHasHitTrace() + { + $pool = $this->createSimpleCache(); + $pool->set('k', 'foo'); + $pool->has('k'); + $calls = $pool->getCalls(); + $this->assertCount(2, $calls); + + $call = $calls[1]; + $this->assertSame('has', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testDeleteTrace() + { + $pool = $this->createSimpleCache(); + $pool->delete('k'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('delete', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testDeleteMultipleTrace() + { + $pool = $this->createSimpleCache(); + $arg = ['k0', 'k1']; + $pool->deleteMultiple($arg); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('deleteMultiple', $call->name); + $this->assertSame(['keys' => $arg, 'result' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testTraceSetTrace() + { + $pool = $this->createSimpleCache(); + $pool->set('k', 'foo'); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('set', $call->name); + $this->assertSame(['k' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } + + public function testSetMultipleTrace() + { + $pool = $this->createSimpleCache(); + $pool->setMultiple(['k' => 'foo']); + $calls = $pool->getCalls(); + $this->assertCount(1, $calls); + + $call = $calls[0]; + $this->assertSame('setMultiple', $call->name); + $this->assertSame(['keys' => ['k'], 'result' => true], $call->result); + $this->assertSame(0, $call->hits); + $this->assertSame(0, $call->misses); + $this->assertNotEmpty($call->start); + $this->assertNotEmpty($call->end); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php new file mode 100644 index 00000000..c405de70 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Traits; + +trait PdoPruneableTrait +{ + protected function isPruned($cache, $name) + { + $o = new \ReflectionObject($cache); + + if (!$o->hasMethod('getConnection')) { + self::fail('Cache does not have "getConnection()" method.'); + } + + $getPdoConn = $o->getMethod('getConnection'); + $getPdoConn->setAccessible(true); + + /** @var \Doctrine\DBAL\Statement|\PDOStatement $select */ + $select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id'); + $select->bindValue(':id', sprintf('%%%s', $name)); + $result = $select->execute(); + + return 1 !== (int) (\is_object($result) ? $result->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/AbstractTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/AbstractTrait.php new file mode 100644 index 00000000..dc291e10 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/AbstractTrait.php @@ -0,0 +1,268 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\Cache\CacheItem; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait AbstractTrait +{ + use LoggerAwareTrait; + + private $namespace; + private $namespaceVersion = ''; + private $versioningIsEnabled = false; + private $deferred = []; + + /** + * @var int|null The maximum length to enforce for identifiers or null when no limit applies + */ + protected $maxIdLength; + + /** + * Fetches several cache items. + * + * @param array $ids The cache identifiers to fetch + * + * @return array|\Traversable The corresponding values found in the cache + */ + abstract protected function doFetch(array $ids); + + /** + * Confirms if the cache contains specified cache item. + * + * @param string $id The identifier for which to check existence + * + * @return bool True if item exists in the cache, false otherwise + */ + abstract protected function doHave($id); + + /** + * Deletes all items in the pool. + * + * @param string $namespace The prefix used for all identifiers managed by this pool + * + * @return bool True if the pool was successfully cleared, false otherwise + */ + abstract protected function doClear($namespace); + + /** + * Removes multiple items from the pool. + * + * @param array $ids An array of identifiers that should be removed from the pool + * + * @return bool True if the items were successfully removed, false otherwise + */ + abstract protected function doDelete(array $ids); + + /** + * Persists several cache items immediately. + * + * @param array $values The values to cache, indexed by their cache identifier + * @param int $lifetime The lifetime of the cached values, 0 for persisting until manual cleaning + * + * @return array|bool The identifiers that failed to be cached or a boolean stating if caching succeeded or not + */ + abstract protected function doSave(array $values, $lifetime); + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + $id = $this->getId($key); + + if (isset($this->deferred[$key])) { + $this->commit(); + } + + try { + return $this->doHave($id); + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', ['key' => $key, 'exception' => $e]); + + return false; + } + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $this->deferred = []; + if ($cleared = $this->versioningIsEnabled) { + $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5); + try { + $cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0); + } catch (\Exception $e) { + $cleared = false; + } + if ($cleared = true === $cleared || [] === $cleared) { + $this->namespaceVersion = $namespaceVersion; + } + } + + try { + return $this->doClear($this->namespace) || $cleared; + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to clear the cache', ['exception' => $e]); + + return false; + } + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + return $this->deleteItems([$key]); + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + $ids = []; + + foreach ($keys as $key) { + $ids[$key] = $this->getId($key); + unset($this->deferred[$key]); + } + + try { + if ($this->doDelete($ids)) { + return true; + } + } catch (\Exception $e) { + } + + $ok = true; + + // When bulk-delete failed, retry each item individually + foreach ($ids as $key => $id) { + try { + $e = null; + if ($this->doDelete([$id])) { + continue; + } + } catch (\Exception $e) { + } + CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]); + $ok = false; + } + + return $ok; + } + + /** + * Enables/disables versioning of items. + * + * When versioning is enabled, clearing the cache is atomic and doesn't require listing existing keys to proceed, + * but old keys may need garbage collection and extra round-trips to the back-end are required. + * + * Calling this method also clears the memoized namespace version and thus forces a resynchonization of it. + * + * @param bool $enable + * + * @return bool the previous state of versioning + */ + public function enableVersioning($enable = true) + { + $wasEnabled = $this->versioningIsEnabled; + $this->versioningIsEnabled = (bool) $enable; + $this->namespaceVersion = ''; + + return $wasEnabled; + } + + /** + * {@inheritdoc} + */ + public function reset() + { + if ($this->deferred) { + $this->commit(); + } + $this->namespaceVersion = ''; + } + + /** + * Like the native unserialize() function but throws an exception if anything goes wrong. + * + * @param string $value + * + * @return mixed + * + * @throws \Exception + */ + protected static function unserialize($value) + { + if ('b:0;' === $value) { + return false; + } + $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback'); + try { + if (false !== $value = unserialize($value)) { + return $value; + } + throw new \DomainException('Failed to unserialize cached value.'); + } catch (\Error $e) { + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); + } finally { + ini_set('unserialize_callback_func', $unserializeCallbackHandler); + } + } + + private function getId($key) + { + CacheItem::validateKey($key); + + if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { + $this->namespaceVersion = '1'.static::NS_SEPARATOR; + try { + foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) { + $this->namespaceVersion = $v; + } + if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) { + $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::NS_SEPARATOR, 5); + $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0); + } + } catch (\Exception $e) { + } + } + + if (null === $this->maxIdLength) { + return $this->namespace.$this->namespaceVersion.$key; + } + if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { + $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 22)); + } + + return $id; + } + + /** + * @internal + */ + public static function handleUnserializeCallback($class) + { + throw new \DomainException('Class not found: '.$class); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/ApcuTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/ApcuTrait.php new file mode 100644 index 00000000..2f47f8e6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/ApcuTrait.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\CacheException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait ApcuTrait +{ + public static function isSupported() + { + return \function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN); + } + + private function init($namespace, $defaultLifetime, $version) + { + if (!static::isSupported()) { + throw new CacheException('APCu is not enabled.'); + } + if ('cli' === \PHP_SAPI) { + ini_set('apc.use_request_time', 0); + } + parent::__construct($namespace, $defaultLifetime); + + if (null !== $version) { + CacheItem::validateKey($version); + + if (!apcu_exists($version.'@'.$namespace)) { + $this->doClear($namespace); + apcu_add($version.'@'.$namespace, null); + } + } + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + try { + foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) { + if (null !== $v || $ok) { + yield $k => $v; + } + } + } catch (\Error $e) { + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); + } + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return apcu_exists($id); + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== \PHP_SAPI || filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) + ? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY)) + : apcu_clear_cache(); + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + foreach ($ids as $id) { + apcu_delete($id); + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + try { + if (false === $failures = apcu_store($values, null, $lifetime)) { + $failures = $values; + } + + return array_keys($failures); + } catch (\Error $e) { + } catch (\Exception $e) { + } + + if (1 === \count($values)) { + // Workaround https://github.com/krakjoe/apcu/issues/170 + apcu_delete(key($values)); + } + + throw $e; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/ArrayTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/ArrayTrait.php new file mode 100644 index 00000000..0a60968e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/ArrayTrait.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\Cache\CacheItem; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait ArrayTrait +{ + use LoggerAwareTrait; + + private $storeSerialized; + private $values = []; + private $expiries = []; + + /** + * Returns all cached values, with cache miss as null. + * + * @return array + */ + public function getValues() + { + return $this->values; + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + CacheItem::validateKey($key); + + return isset($this->expiries[$key]) && ($this->expiries[$key] > time() || !$this->deleteItem($key)); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $this->values = $this->expiries = []; + + return true; + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + CacheItem::validateKey($key); + + unset($this->values[$key], $this->expiries[$key]); + + return true; + } + + /** + * {@inheritdoc} + */ + public function reset() + { + $this->clear(); + } + + private function generateItems(array $keys, $now, $f) + { + foreach ($keys as $i => $key) { + try { + if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) { + $this->values[$key] = $value = null; + } elseif (!$this->storeSerialized) { + $value = $this->values[$key]; + } elseif ('b:0;' === $value = $this->values[$key]) { + $value = false; + } elseif (false === $value = unserialize($value)) { + $this->values[$key] = $value = null; + $isHit = false; + } + } catch (\Exception $e) { + CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]); + $this->values[$key] = $value = null; + $isHit = false; + } + unset($keys[$i]); + + yield $key => $f($key, $value, $isHit); + } + + foreach ($keys as $key) { + yield $key => $f($key, null, false); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/DoctrineTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/DoctrineTrait.php new file mode 100644 index 00000000..48623e67 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/DoctrineTrait.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait DoctrineTrait +{ + private $provider; + + /** + * {@inheritdoc} + */ + public function reset() + { + parent::reset(); + $this->provider->setNamespace($this->provider->getNamespace()); + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + $unserializeCallbackHandler = ini_set('unserialize_callback_func', parent::class.'::handleUnserializeCallback'); + try { + return $this->provider->fetchMultiple($ids); + } catch (\Error $e) { + $trace = $e->getTrace(); + + if (isset($trace[0]['function']) && !isset($trace[0]['class'])) { + switch ($trace[0]['function']) { + case 'unserialize': + case 'apcu_fetch': + case 'apc_fetch': + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); + } + } + + throw $e; + } finally { + ini_set('unserialize_callback_func', $unserializeCallbackHandler); + } + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return $this->provider->contains($id); + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + $namespace = $this->provider->getNamespace(); + + return isset($namespace[0]) + ? $this->provider->deleteAll() + : $this->provider->flushAll(); + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + $ok = true; + foreach ($ids as $id) { + $ok = $this->provider->delete($id) && $ok; + } + + return $ok; + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + return $this->provider->saveMultiple($values, $lifetime); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/FilesystemCommonTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/FilesystemCommonTrait.php new file mode 100644 index 00000000..8071a382 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/FilesystemCommonTrait.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait FilesystemCommonTrait +{ + private $directory; + private $tmp; + + private function init($namespace, $directory) + { + if (!isset($directory[0])) { + $directory = sys_get_temp_dir().'/symfony-cache'; + } else { + $directory = realpath($directory) ?: $directory; + } + if (isset($namespace[0])) { + if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { + throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); + } + $directory .= \DIRECTORY_SEPARATOR.$namespace; + } + if (!file_exists($directory)) { + @mkdir($directory, 0777, true); + } + $directory .= \DIRECTORY_SEPARATOR; + // On Windows the whole path is limited to 258 chars + if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) { + throw new InvalidArgumentException(sprintf('Cache directory too long (%s).', $directory)); + } + + $this->directory = $directory; + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + $ok = true; + + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS)) as $file) { + $ok = ($file->isDir() || @unlink($file) || !file_exists($file)) && $ok; + } + + return $ok; + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + $ok = true; + + foreach ($ids as $id) { + $file = $this->getFile($id); + $ok = (!file_exists($file) || @unlink($file) || !file_exists($file)) && $ok; + } + + return $ok; + } + + private function write($file, $data, $expiresAt = null) + { + set_error_handler(__CLASS__.'::throwError'); + try { + if (null === $this->tmp) { + $this->tmp = $this->directory.uniqid('', true); + } + file_put_contents($this->tmp, $data); + + if (null !== $expiresAt) { + touch($this->tmp, $expiresAt); + } + + return rename($this->tmp, $file); + } finally { + restore_error_handler(); + } + } + + private function getFile($id, $mkdir = false) + { + $hash = str_replace('/', '-', base64_encode(hash('sha256', static::class.$id, true))); + $dir = $this->directory.strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR); + + if ($mkdir && !file_exists($dir)) { + @mkdir($dir, 0777, true); + } + + return $dir.substr($hash, 2, 20); + } + + /** + * @internal + */ + public static function throwError($type, $message, $file, $line) + { + throw new \ErrorException($message, 0, $type, $file, $line); + } + + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + + public function __destruct() + { + if (method_exists(parent::class, '__destruct')) { + parent::__destruct(); + } + if (null !== $this->tmp && file_exists($this->tmp)) { + unlink($this->tmp); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/FilesystemTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/FilesystemTrait.php new file mode 100644 index 00000000..9d7f5578 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/FilesystemTrait.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\Exception\CacheException; + +/** + * @author Nicolas Grekas + * @author Rob Frawley 2nd + * + * @internal + */ +trait FilesystemTrait +{ + use FilesystemCommonTrait; + + /** + * @return bool + */ + public function prune() + { + $time = time(); + $pruned = true; + + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + if (!$h = @fopen($file, 'rb')) { + continue; + } + + if (($expiresAt = (int) fgets($h)) && $time >= $expiresAt) { + fclose($h); + $pruned = @unlink($file) && !file_exists($file) && $pruned; + } else { + fclose($h); + } + } + + return $pruned; + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + $values = []; + $now = time(); + + foreach ($ids as $id) { + $file = $this->getFile($id); + if (!file_exists($file) || !$h = @fopen($file, 'rb')) { + continue; + } + if (($expiresAt = (int) fgets($h)) && $now >= $expiresAt) { + fclose($h); + @unlink($file); + } else { + $i = rawurldecode(rtrim(fgets($h))); + $value = stream_get_contents($h); + fclose($h); + if ($i === $id) { + $values[$id] = parent::unserialize($value); + } + } + } + + return $values; + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + $file = $this->getFile($id); + + return file_exists($file) && (@filemtime($file) > time() || $this->doFetch([$id])); + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + $ok = true; + $expiresAt = $lifetime ? (time() + $lifetime) : 0; + + foreach ($values as $id => $value) { + $ok = $this->write($this->getFile($id, true), $expiresAt."\n".rawurlencode($id)."\n".serialize($value), $expiresAt) && $ok; + } + + if (!$ok && !is_writable($this->directory)) { + throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); + } + + return $ok; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/MemcachedTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/MemcachedTrait.php new file mode 100644 index 00000000..34d0208e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/MemcachedTrait.php @@ -0,0 +1,297 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\Exception\CacheException; +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @author Rob Frawley 2nd + * @author Nicolas Grekas + * + * @internal + */ +trait MemcachedTrait +{ + private static $defaultClientOptions = [ + 'persistent_id' => null, + 'username' => null, + 'password' => null, + \Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP, + ]; + + private $client; + private $lazyClient; + + public static function isSupported() + { + return \extension_loaded('memcached') && version_compare(phpversion('memcached'), '2.2.0', '>='); + } + + private function init(\Memcached $client, $namespace, $defaultLifetime) + { + if (!static::isSupported()) { + throw new CacheException('Memcached >= 2.2.0 is required.'); + } + if ('Memcached' === \get_class($client)) { + $opt = $client->getOption(\Memcached::OPT_SERIALIZER); + if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { + throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + } + $this->maxIdLength -= \strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); + $this->client = $client; + } else { + $this->lazyClient = $client; + } + + parent::__construct($namespace, $defaultLifetime); + $this->enableVersioning(); + } + + /** + * Creates a Memcached instance. + * + * By default, the binary protocol, no block, and libketama compatible options are enabled. + * + * Examples for servers: + * - 'memcached://user:pass@localhost?weight=33' + * - [['localhost', 11211, 33]] + * + * @param array[]|string|string[] $servers An array of servers, a DSN, or an array of DSNs + * @param array $options An array of options + * + * @return \Memcached + * + * @throws \ErrorException When invalid options or servers are provided + */ + public static function createConnection($servers, array $options = []) + { + if (\is_string($servers)) { + $servers = [$servers]; + } elseif (!\is_array($servers)) { + throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, "%s" given.', \gettype($servers))); + } + if (!static::isSupported()) { + throw new CacheException('Memcached >= 2.2.0 is required.'); + } + set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); }); + try { + $options += static::$defaultClientOptions; + $client = new \Memcached($options['persistent_id']); + $username = $options['username']; + $password = $options['password']; + + // parse any DSN in $servers + foreach ($servers as $i => $dsn) { + if (\is_array($dsn)) { + continue; + } + if (0 !== strpos($dsn, 'memcached://')) { + throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s" does not start with "memcached://".', $dsn)); + } + $params = preg_replace_callback('#^memcached://(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) { + if (!empty($m[1])) { + list($username, $password) = explode(':', $m[1], 2) + [1 => null]; + } + + return 'file://'; + }, $dsn); + if (false === $params = parse_url($params)) { + throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); + } + if (!isset($params['host']) && !isset($params['path'])) { + throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); + } + if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) { + $params['weight'] = $m[1]; + $params['path'] = substr($params['path'], 0, -\strlen($m[0])); + } + $params += [ + 'host' => isset($params['host']) ? $params['host'] : $params['path'], + 'port' => isset($params['host']) ? 11211 : null, + 'weight' => 0, + ]; + if (isset($params['query'])) { + parse_str($params['query'], $query); + $params += $query; + $options = $query + $options; + } + + $servers[$i] = [$params['host'], $params['port'], $params['weight']]; + } + + // set client's options + unset($options['persistent_id'], $options['username'], $options['password'], $options['weight'], $options['lazy']); + $options = array_change_key_case($options, \CASE_UPPER); + $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + $client->setOption(\Memcached::OPT_NO_BLOCK, true); + $client->setOption(\Memcached::OPT_TCP_NODELAY, true); + if (!\array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !\array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) { + $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true); + } + foreach ($options as $name => $value) { + if (\is_int($name)) { + continue; + } + if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) { + $value = \constant('Memcached::'.$name.'_'.strtoupper($value)); + } + $opt = \constant('Memcached::OPT_'.$name); + + unset($options[$name]); + $options[$opt] = $value; + } + $client->setOptions($options); + + // set client's servers, taking care of persistent connections + if (!$client->isPristine()) { + $oldServers = []; + foreach ($client->getServerList() as $server) { + $oldServers[] = [$server['host'], $server['port']]; + } + + $newServers = []; + foreach ($servers as $server) { + if (1 < \count($server)) { + $server = array_values($server); + unset($server[2]); + $server[1] = (int) $server[1]; + } + $newServers[] = $server; + } + + if ($oldServers !== $newServers) { + $client->resetServerList(); + $client->addServers($servers); + } + } else { + $client->addServers($servers); + } + + if (null !== $username || null !== $password) { + if (!method_exists($client, 'setSaslAuthData')) { + trigger_error('Missing SASL support: the memcached extension must be compiled with --enable-memcached-sasl.'); + } + $client->setSaslAuthData($username, $password); + } + + return $client; + } finally { + restore_error_handler(); + } + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + if ($lifetime && $lifetime > 30 * 86400) { + $lifetime += time(); + } + + $encodedValues = []; + foreach ($values as $key => $value) { + $encodedValues[rawurlencode($key)] = $value; + } + + return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)); + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback'); + try { + $encodedIds = array_map('rawurlencode', $ids); + + $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds)); + + $result = []; + foreach ($encodedResult as $key => $value) { + $result[rawurldecode($key)] = $value; + } + + return $result; + } catch (\Error $e) { + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); + } finally { + ini_set('unserialize_callback_func', $unserializeCallbackHandler); + } + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return false !== $this->getClient()->get(rawurlencode($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode()); + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + $ok = true; + $encodedIds = array_map('rawurlencode', $ids); + foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) { + if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) { + $ok = false; + break; + } + } + + return $ok; + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + return '' === $namespace && $this->getClient()->flush(); + } + + private function checkResultCode($result) + { + $code = $this->client->getResultCode(); + + if (\Memcached::RES_SUCCESS === $code || \Memcached::RES_NOTFOUND === $code) { + return $result; + } + + throw new CacheException('MemcachedAdapter client error: '.strtolower($this->client->getResultMessage())); + } + + /** + * @return \Memcached + */ + private function getClient() + { + if ($this->client) { + return $this->client; + } + + $opt = $this->lazyClient->getOption(\Memcached::OPT_SERIALIZER); + if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { + throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); + } + if ('' !== $prefix = (string) $this->lazyClient->getOption(\Memcached::OPT_PREFIX_KEY)) { + throw new CacheException(sprintf('MemcachedAdapter: "prefix_key" option must be empty when using proxified connections, "%s" given.', $prefix)); + } + + return $this->client = $this->lazyClient; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/PdoTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/PdoTrait.php new file mode 100644 index 00000000..917e8dd1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/PdoTrait.php @@ -0,0 +1,435 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Doctrine\DBAL\Connection; +use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver\ServerInfoAwareConnection; +use Doctrine\DBAL\Schema\Schema; +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @internal + */ +trait PdoTrait +{ + private $conn; + private $dsn; + private $driver; + private $serverVersion; + private $table = 'cache_items'; + private $idCol = 'item_id'; + private $dataCol = 'item_data'; + private $lifetimeCol = 'item_lifetime'; + private $timeCol = 'item_time'; + private $username = ''; + private $password = ''; + private $connectionOptions = []; + private $namespace; + + private function init($connOrDsn, $namespace, $defaultLifetime, array $options) + { + if (isset($namespace[0]) && preg_match('#[^-+.A-Za-z0-9]#', $namespace, $match)) { + throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.', $match[0])); + } + + if ($connOrDsn instanceof \PDO) { + if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) { + throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__)); + } + + $this->conn = $connOrDsn; + } elseif ($connOrDsn instanceof Connection) { + $this->conn = $connOrDsn; + } elseif (\is_string($connOrDsn)) { + $this->dsn = $connOrDsn; + } else { + throw new InvalidArgumentException(sprintf('"%s" requires PDO or Doctrine\DBAL\Connection instance or DSN string as first argument, "%s" given.', __CLASS__, \is_object($connOrDsn) ? \get_class($connOrDsn) : \gettype($connOrDsn))); + } + + $this->table = isset($options['db_table']) ? $options['db_table'] : $this->table; + $this->idCol = isset($options['db_id_col']) ? $options['db_id_col'] : $this->idCol; + $this->dataCol = isset($options['db_data_col']) ? $options['db_data_col'] : $this->dataCol; + $this->lifetimeCol = isset($options['db_lifetime_col']) ? $options['db_lifetime_col'] : $this->lifetimeCol; + $this->timeCol = isset($options['db_time_col']) ? $options['db_time_col'] : $this->timeCol; + $this->username = isset($options['db_username']) ? $options['db_username'] : $this->username; + $this->password = isset($options['db_password']) ? $options['db_password'] : $this->password; + $this->connectionOptions = isset($options['db_connection_options']) ? $options['db_connection_options'] : $this->connectionOptions; + $this->namespace = $namespace; + + parent::__construct($namespace, $defaultLifetime); + } + + /** + * Creates the table to store cache items which can be called once for setup. + * + * Cache ID are saved in a column of maximum length 255. Cache data is + * saved in a BLOB. + * + * @throws \PDOException When the table already exists + * @throws DBALException When the table already exists + * @throws \DomainException When an unsupported PDO driver is used + */ + public function createTable() + { + // connect if we are not yet + $conn = $this->getConnection(); + + if ($conn instanceof Connection) { + $types = [ + 'mysql' => 'binary', + 'sqlite' => 'text', + 'pgsql' => 'string', + 'oci' => 'string', + 'sqlsrv' => 'string', + ]; + if (!isset($types[$this->driver])) { + throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver)); + } + + $schema = new Schema(); + $table = $schema->createTable($this->table); + $table->addColumn($this->idCol, $types[$this->driver], ['length' => 255]); + $table->addColumn($this->dataCol, 'blob', ['length' => 16777215]); + $table->addColumn($this->lifetimeCol, 'integer', ['unsigned' => true, 'notnull' => false]); + $table->addColumn($this->timeCol, 'integer', ['unsigned' => true]); + $table->setPrimaryKey([$this->idCol]); + + foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) { + if (method_exists($conn, 'executeStatement')) { + $conn->executeStatement($sql); + } else { + $conn->exec($sql); + } + } + + return; + } + + switch ($this->driver) { + case 'mysql': + // We use varbinary for the ID column because it prevents unwanted conversions: + // - character set conversions between server and client + // - trailing space removal + // - case-insensitivity + // - language processing like é == e + $sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(255) NOT NULL PRIMARY KEY, $this->dataCol MEDIUMBLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB"; + break; + case 'sqlite': + $sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)"; + break; + case 'pgsql': + $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)"; + break; + case 'oci': + $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR2(255) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)"; + break; + case 'sqlsrv': + $sql = "CREATE TABLE $this->table ($this->idCol VARCHAR(255) NOT NULL PRIMARY KEY, $this->dataCol VARBINARY(MAX) NOT NULL, $this->lifetimeCol INTEGER, $this->timeCol INTEGER NOT NULL)"; + break; + default: + throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver)); + } + + if (method_exists($conn, 'executeStatement')) { + $conn->executeStatement($sql); + } else { + $conn->exec($sql); + } + } + + /** + * {@inheritdoc} + */ + public function prune() + { + $deleteSql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= :time"; + + if ('' !== $this->namespace) { + $deleteSql .= " AND $this->idCol LIKE :namespace"; + } + + $delete = $this->getConnection()->prepare($deleteSql); + $delete->bindValue(':time', time(), \PDO::PARAM_INT); + + if ('' !== $this->namespace) { + $delete->bindValue(':namespace', sprintf('%s%%', $this->namespace), \PDO::PARAM_STR); + } + + return $delete->execute(); + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + $now = time(); + $expired = []; + + $sql = str_pad('', (\count($ids) << 1) - 1, '?,'); + $sql = "SELECT $this->idCol, CASE WHEN $this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ? THEN $this->dataCol ELSE NULL END FROM $this->table WHERE $this->idCol IN ($sql)"; + $stmt = $this->getConnection()->prepare($sql); + $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT); + foreach ($ids as $id) { + $stmt->bindValue(++$i, $id); + } + $result = $stmt->execute(); + + if (\is_object($result)) { + $result = $result->iterateNumeric(); + } else { + $stmt->setFetchMode(\PDO::FETCH_NUM); + $result = $stmt; + } + + foreach ($result as $row) { + if (null === $row[1]) { + $expired[] = $row[0]; + } else { + yield $row[0] => parent::unserialize(\is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]); + } + } + + if ($expired) { + $sql = str_pad('', (\count($expired) << 1) - 1, '?,'); + $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= ? AND $this->idCol IN ($sql)"; + $stmt = $this->getConnection()->prepare($sql); + $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT); + foreach ($expired as $id) { + $stmt->bindValue(++$i, $id); + } + $stmt->execute(); + } + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + $sql = "SELECT 1 FROM $this->table WHERE $this->idCol = :id AND ($this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > :time)"; + $stmt = $this->getConnection()->prepare($sql); + + $stmt->bindValue(':id', $id); + $stmt->bindValue(':time', time(), \PDO::PARAM_INT); + $result = $stmt->execute(); + + return (bool) (\is_object($result) ? $result->fetchOne() : $stmt->fetchColumn()); + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + $conn = $this->getConnection(); + + if ('' === $namespace) { + if ('sqlite' === $this->driver) { + $sql = "DELETE FROM $this->table"; + } else { + $sql = "TRUNCATE TABLE $this->table"; + } + } else { + $sql = "DELETE FROM $this->table WHERE $this->idCol LIKE '$namespace%'"; + } + + if (method_exists($conn, 'executeStatement')) { + $conn->executeStatement($sql); + } else { + $conn->exec($sql); + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + $sql = str_pad('', (\count($ids) << 1) - 1, '?,'); + $sql = "DELETE FROM $this->table WHERE $this->idCol IN ($sql)"; + $stmt = $this->getConnection()->prepare($sql); + $stmt->execute(array_values($ids)); + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + $serialized = []; + $failed = []; + + foreach ($values as $id => $value) { + try { + $serialized[$id] = serialize($value); + } catch (\Exception $e) { + $failed[] = $id; + } + } + + if (!$serialized) { + return $failed; + } + + $conn = $this->getConnection(); + $driver = $this->driver; + $insertSql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)"; + + switch (true) { + case 'mysql' === $driver: + $sql = $insertSql." ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)"; + break; + case 'oci' === $driver: + // DUAL is Oracle specific dummy table + $sql = "MERGE INTO $this->table USING DUAL ON ($this->idCol = ?) ". + "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". + "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?"; + break; + case 'sqlsrv' === $driver && version_compare($this->getServerVersion(), '10', '>='): + // MERGE is only available since SQL Server 2008 and must be terminated by semicolon + // It also requires HOLDLOCK according to http://weblogs.sqlteam.com/dang/archive/2009/01/31/UPSERT-Race-Condition-With-MERGE.aspx + $sql = "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = ?) ". + "WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (?, ?, ?, ?) ". + "WHEN MATCHED THEN UPDATE SET $this->dataCol = ?, $this->lifetimeCol = ?, $this->timeCol = ?;"; + break; + case 'sqlite' === $driver: + $sql = 'INSERT OR REPLACE'.substr($insertSql, 6); + break; + case 'pgsql' === $driver && version_compare($this->getServerVersion(), '9.5', '>='): + $sql = $insertSql." ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (EXCLUDED.$this->dataCol, EXCLUDED.$this->lifetimeCol, EXCLUDED.$this->timeCol)"; + break; + default: + $driver = null; + $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time WHERE $this->idCol = :id"; + break; + } + + $now = time(); + $lifetime = $lifetime ?: null; + $stmt = $conn->prepare($sql); + + if ('sqlsrv' === $driver || 'oci' === $driver) { + $stmt->bindParam(1, $id); + $stmt->bindParam(2, $id); + $stmt->bindParam(3, $data, \PDO::PARAM_LOB); + $stmt->bindValue(4, $lifetime, \PDO::PARAM_INT); + $stmt->bindValue(5, $now, \PDO::PARAM_INT); + $stmt->bindParam(6, $data, \PDO::PARAM_LOB); + $stmt->bindValue(7, $lifetime, \PDO::PARAM_INT); + $stmt->bindValue(8, $now, \PDO::PARAM_INT); + } else { + $stmt->bindParam(':id', $id); + $stmt->bindParam(':data', $data, \PDO::PARAM_LOB); + $stmt->bindValue(':lifetime', $lifetime, \PDO::PARAM_INT); + $stmt->bindValue(':time', $now, \PDO::PARAM_INT); + } + if (null === $driver) { + $insertStmt = $conn->prepare($insertSql); + + $insertStmt->bindParam(':id', $id); + $insertStmt->bindParam(':data', $data, \PDO::PARAM_LOB); + $insertStmt->bindValue(':lifetime', $lifetime, \PDO::PARAM_INT); + $insertStmt->bindValue(':time', $now, \PDO::PARAM_INT); + } + + foreach ($serialized as $id => $data) { + $result = $stmt->execute(); + + if (null === $driver && !(\is_object($result) ? $result->rowCount() : $stmt->rowCount())) { + try { + $insertStmt->execute(); + } catch (DBALException $e) { + } catch (\PDOException $e) { + // A concurrent write won, let it be + } + } + } + + return $failed; + } + + /** + * @return \PDO|Connection + */ + private function getConnection() + { + if (null === $this->conn) { + $this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions); + $this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + } + if (null === $this->driver) { + if ($this->conn instanceof \PDO) { + $this->driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME); + } else { + $driver = $this->conn->getDriver(); + + switch (true) { + case $driver instanceof \Doctrine\DBAL\Driver\AbstractMySQLDriver: + case $driver instanceof \Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\Mysqli\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOMySql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\MySQL\Driver: + $this->driver = 'mysql'; + break; + case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLite\Driver: + $this->driver = 'sqlite'; + break; + case $driver instanceof \Doctrine\DBAL\Driver\PDOPgSql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\PgSQL\Driver: + $this->driver = 'pgsql'; + break; + case $driver instanceof \Doctrine\DBAL\Driver\OCI8\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOOracle\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\OCI\Driver: + $this->driver = 'oci'; + break; + case $driver instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlsrv\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLSrv\Driver: + $this->driver = 'sqlsrv'; + break; + default: + $this->driver = \get_class($driver); + break; + } + } + } + + return $this->conn; + } + + /** + * @return string + */ + private function getServerVersion() + { + if (null === $this->serverVersion) { + $conn = $this->conn instanceof \PDO ? $this->conn : $this->conn->getWrappedConnection(); + if ($conn instanceof \PDO) { + $this->serverVersion = $conn->getAttribute(\PDO::ATTR_SERVER_VERSION); + } elseif ($conn instanceof ServerInfoAwareConnection) { + $this->serverVersion = $conn->getServerVersion(); + } else { + $this->serverVersion = '0'; + } + } + + return $this->serverVersion; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/PhpArrayTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/PhpArrayTrait.php new file mode 100644 index 00000000..972c7512 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/PhpArrayTrait.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\CacheItem; +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @author Titouan Galopin + * @author Nicolas Grekas + * + * @internal + */ +trait PhpArrayTrait +{ + use ProxyTrait; + + private $file; + private $values; + private $zendDetectUnicode; + + private static $valuesCache = []; + + /** + * Store an array of cached values. + * + * @param array $values The cached values + */ + public function warmUp(array $values) + { + if (file_exists($this->file)) { + if (!is_file($this->file)) { + throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file)); + } + + if (!is_writable($this->file)) { + throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file)); + } + } else { + $directory = \dirname($this->file); + + if (!is_dir($directory) && !@mkdir($directory, 0777, true)) { + throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory)); + } + + if (!is_writable($directory)) { + throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory)); + } + } + + $dump = <<<'EOF' + $value) { + CacheItem::validateKey(\is_int($key) ? (string) $key : $key); + + if (null === $value || \is_object($value)) { + try { + $value = serialize($value); + } catch (\Exception $e) { + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, \get_class($value)), 0, $e); + } + } elseif (\is_array($value)) { + try { + $serialized = serialize($value); + $unserialized = unserialize($serialized); + } catch (\Exception $e) { + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable array value.', $key), 0, $e); + } + // Store arrays serialized if they contain any objects or references + if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) { + $value = $serialized; + } + } elseif (\is_string($value)) { + // Serialize strings if they could be confused with serialized objects or arrays + if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { + $value = serialize($value); + } + } elseif (!is_scalar($value)) { + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, \gettype($value))); + } + + $dump .= var_export($key, true).' => '.var_export($value, true).",\n"; + } + + $dump .= "\n];\n"; + $dump = str_replace("' . \"\\0\" . '", "\0", $dump); + + $tmpFile = uniqid($this->file, true); + + file_put_contents($tmpFile, $dump); + @chmod($tmpFile, 0666 & ~umask()); + unset($serialized, $unserialized, $value, $dump); + + @rename($tmpFile, $this->file); + unset(self::$valuesCache[$this->file]); + + $this->initialize(); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + $this->values = []; + + $cleared = @unlink($this->file) || !file_exists($this->file); + unset(self::$valuesCache[$this->file]); + + return $this->pool->clear() && $cleared; + } + + /** + * Load the cache file. + */ + private function initialize() + { + if (isset(self::$valuesCache[$this->file])) { + $this->values = self::$valuesCache[$this->file]; + + return; + } + + if ($this->zendDetectUnicode) { + $zmb = ini_set('zend.detect_unicode', 0); + } + try { + $this->values = self::$valuesCache[$this->file] = file_exists($this->file) ? (include $this->file ?: []) : []; + } finally { + if ($this->zendDetectUnicode) { + ini_set('zend.detect_unicode', $zmb); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/PhpFilesTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/PhpFilesTrait.php new file mode 100644 index 00000000..2668b26c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/PhpFilesTrait.php @@ -0,0 +1,158 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\Exception\CacheException; +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @author Piotr Stankowski + * @author Nicolas Grekas + * @author Rob Frawley 2nd + * + * @internal + */ +trait PhpFilesTrait +{ + use FilesystemCommonTrait; + + private $includeHandler; + private $zendDetectUnicode; + + public static function isSupported() + { + return \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN); + } + + /** + * @return bool + */ + public function prune() + { + $time = time(); + $pruned = true; + $allowCompile = 'cli' !== \PHP_SAPI || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN); + + set_error_handler($this->includeHandler); + try { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { + list($expiresAt) = include $file; + + if ($time >= $expiresAt) { + $pruned = @unlink($file) && !file_exists($file) && $pruned; + + if ($allowCompile) { + @opcache_invalidate($file, true); + } + } + } + } finally { + restore_error_handler(); + } + + return $pruned; + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + $values = []; + $now = time(); + + if ($this->zendDetectUnicode) { + $zmb = ini_set('zend.detect_unicode', 0); + } + set_error_handler($this->includeHandler); + try { + foreach ($ids as $id) { + try { + $file = $this->getFile($id); + list($expiresAt, $values[$id]) = include $file; + if ($now >= $expiresAt) { + unset($values[$id]); + } + } catch (\Exception $e) { + continue; + } + } + } finally { + restore_error_handler(); + if ($this->zendDetectUnicode) { + ini_set('zend.detect_unicode', $zmb); + } + } + + foreach ($values as $id => $value) { + if ('N;' === $value) { + $values[$id] = null; + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { + $values[$id] = parent::unserialize($value); + } + } + + return $values; + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return (bool) $this->doFetch([$id]); + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + $ok = true; + $data = [$lifetime ? time() + $lifetime : \PHP_INT_MAX, '']; + $allowCompile = 'cli' !== \PHP_SAPI || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN); + + foreach ($values as $key => $value) { + if (null === $value || \is_object($value)) { + $value = serialize($value); + } elseif (\is_array($value)) { + $serialized = serialize($value); + $unserialized = parent::unserialize($serialized); + // Store arrays serialized if they contain any objects or references + if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) { + $value = $serialized; + } + } elseif (\is_string($value)) { + // Serialize strings if they could be confused with serialized objects or arrays + if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { + $value = serialize($value); + } + } elseif (!is_scalar($value)) { + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, \gettype($value))); + } + + $data[1] = $value; + $file = $this->getFile($key, true); + $ok = $this->write($file, 'directory)) { + throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); + } + + return $ok; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/ProxyTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/ProxyTrait.php new file mode 100644 index 00000000..d9e085b9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/ProxyTrait.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Symfony\Component\Cache\PruneableInterface; +use Symfony\Component\Cache\ResettableInterface; + +/** + * @author Nicolas Grekas + * + * @internal + */ +trait ProxyTrait +{ + private $pool; + + /** + * {@inheritdoc} + */ + public function prune() + { + return $this->pool instanceof PruneableInterface && $this->pool->prune(); + } + + /** + * {@inheritdoc} + */ + public function reset() + { + if ($this->pool instanceof ResettableInterface) { + $this->pool->reset(); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/RedisProxy.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/RedisProxy.php new file mode 100644 index 00000000..98ea3aba --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/RedisProxy.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class RedisProxy +{ + private $redis; + private $initializer; + private $ready = false; + + public function __construct(\Redis $redis, \Closure $initializer) + { + $this->redis = $redis; + $this->initializer = $initializer; + } + + public function __call($method, array $args) + { + $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis); + + return \call_user_func_array([$this->redis, $method], $args); + } + + public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null) + { + $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis); + + return $this->redis->hscan($strKey, $iIterator, $strPattern, $iCount); + } + + public function scan(&$iIterator, $strPattern = null, $iCount = null) + { + $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis); + + return $this->redis->scan($iIterator, $strPattern, $iCount); + } + + public function sscan($strKey, &$iIterator, $strPattern = null, $iCount = null) + { + $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis); + + return $this->redis->sscan($strKey, $iIterator, $strPattern, $iCount); + } + + public function zscan($strKey, &$iIterator, $strPattern = null, $iCount = null) + { + $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis); + + return $this->redis->zscan($strKey, $iIterator, $strPattern, $iCount); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/Traits/RedisTrait.php b/modules/empikmarketplace/vendor/symfony/cache/Traits/RedisTrait.php new file mode 100644 index 00000000..a30d6d3f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/Traits/RedisTrait.php @@ -0,0 +1,382 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Traits; + +use Predis\Connection\Aggregate\ClusterInterface; +use Predis\Connection\Aggregate\RedisCluster; +use Predis\Connection\Factory; +use Predis\Response\Status; +use Symfony\Component\Cache\Exception\CacheException; +use Symfony\Component\Cache\Exception\InvalidArgumentException; + +/** + * @author Aurimas Niekis + * @author Nicolas Grekas + * + * @internal + */ +trait RedisTrait +{ + private static $defaultConnectionOptions = [ + 'class' => null, + 'persistent' => 0, + 'persistent_id' => null, + 'timeout' => 30, + 'read_timeout' => 0, + 'retry_interval' => 0, + 'lazy' => false, + ]; + private $redis; + + /** + * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient + */ + private function init($redisClient, $namespace = '', $defaultLifetime = 0) + { + parent::__construct($namespace, $defaultLifetime); + + if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { + throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); + } + if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy) { + throw new InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, "%s" given.', __METHOD__, \is_object($redisClient) ? \get_class($redisClient) : \gettype($redisClient))); + } + $this->redis = $redisClient; + } + + /** + * Creates a Redis connection using a DSN configuration. + * + * Example DSN: + * - redis://localhost + * - redis://example.com:1234 + * - redis://secret@example.com/13 + * - redis:///var/run/redis.sock + * - redis://secret@/var/run/redis.sock/13 + * + * @param string $dsn + * @param array $options See self::$defaultConnectionOptions + * + * @throws InvalidArgumentException when the DSN is invalid + * + * @return \Redis|\Predis\Client According to the "class" option + */ + public static function createConnection($dsn, array $options = []) + { + if (0 !== strpos($dsn, 'redis://')) { + throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s" does not start with "redis://".', $dsn)); + } + $params = preg_replace_callback('#^redis://(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) { + if (isset($m[1])) { + $auth = $m[1]; + } + + return 'file://'; + }, $dsn); + if (false === $params = parse_url($params)) { + throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); + } + if (!isset($params['host']) && !isset($params['path'])) { + throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); + } + if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) { + $params['dbindex'] = $m[1]; + $params['path'] = substr($params['path'], 0, -\strlen($m[0])); + } + if (isset($params['host'])) { + $scheme = 'tcp'; + } else { + $scheme = 'unix'; + } + $params += [ + 'host' => isset($params['host']) ? $params['host'] : $params['path'], + 'port' => isset($params['host']) ? 6379 : null, + 'dbindex' => 0, + ]; + if (isset($params['query'])) { + parse_str($params['query'], $query); + $params += $query; + } + $params += $options + self::$defaultConnectionOptions; + if (null === $params['class'] && !\extension_loaded('redis') && !class_exists(\Predis\Client::class)) { + throw new CacheException(sprintf('Cannot find the "redis" extension, and "predis/predis" is not installed: "%s".', $dsn)); + } + $class = null === $params['class'] ? (\extension_loaded('redis') ? \Redis::class : \Predis\Client::class) : $params['class']; + + if (is_a($class, \Redis::class, true)) { + $connect = $params['persistent'] || $params['persistent_id'] ? 'pconnect' : 'connect'; + $redis = new $class(); + + $initializer = function ($redis) use ($connect, $params, $dsn, $auth) { + try { + @$redis->{$connect}($params['host'], $params['port'], $params['timeout'], $params['persistent_id'], $params['retry_interval']); + + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); + $isConnected = $redis->isConnected(); + restore_error_handler(); + if (!$isConnected) { + $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error, $error) ? sprintf(' (%s)', $error[1]) : ''; + throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$error.'.'); + } + + if ((null !== $auth && !$redis->auth($auth)) + || ($params['dbindex'] && !$redis->select($params['dbindex'])) + || ($params['read_timeout'] && !$redis->setOption(\Redis::OPT_READ_TIMEOUT, $params['read_timeout'])) + ) { + $e = preg_replace('/^ERR /', '', $redis->getLastError()); + throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e.'.'); + } + } catch (\RedisException $e) { + throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage()); + } + + return true; + }; + + if ($params['lazy']) { + $redis = new RedisProxy($redis, $initializer); + } else { + $initializer($redis); + } + } elseif (is_a($class, \Predis\Client::class, true)) { + $params['scheme'] = $scheme; + $params['database'] = $params['dbindex'] ?: null; + $params['password'] = $auth; + $redis = new $class((new Factory())->create($params)); + } elseif (class_exists($class, false)) { + throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis" or "Predis\Client".', $class)); + } else { + throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); + } + + return $redis; + } + + /** + * {@inheritdoc} + */ + protected function doFetch(array $ids) + { + if (!$ids) { + return []; + } + + $result = []; + + if ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface) { + $values = $this->pipeline(function () use ($ids) { + foreach ($ids as $id) { + yield 'get' => [$id]; + } + }); + } else { + $values = $this->redis->mget($ids); + + if (!\is_array($values) || \count($values) !== \count($ids)) { + return []; + } + + $values = array_combine($ids, $values); + } + + foreach ($values as $id => $v) { + if ($v) { + $result[$id] = parent::unserialize($v); + } + } + + return $result; + } + + /** + * {@inheritdoc} + */ + protected function doHave($id) + { + return (bool) $this->redis->exists($id); + } + + /** + * {@inheritdoc} + */ + protected function doClear($namespace) + { + $cleared = true; + $hosts = [$this->redis]; + $evalArgs = [[$namespace], 0]; + + if ($this->redis instanceof \Predis\Client) { + $evalArgs = [0, $namespace]; + + $connection = $this->redis->getConnection(); + if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) { + $hosts = []; + foreach ($connection as $c) { + $hosts[] = new \Predis\Client($c); + } + } + } elseif ($this->redis instanceof \RedisArray) { + $hosts = []; + foreach ($this->redis->_hosts() as $host) { + $hosts[] = $this->redis->_instance($host); + } + } elseif ($this->redis instanceof \RedisCluster) { + $hosts = []; + foreach ($this->redis->_masters() as $host) { + $hosts[] = $h = new \Redis(); + $h->connect($host[0], $host[1]); + } + } + foreach ($hosts as $host) { + if (!isset($namespace[0])) { + $cleared = $host->flushDb() && $cleared; + continue; + } + + $info = $host->info('Server'); + $info = isset($info['Server']) ? $info['Server'] : $info; + + if (!version_compare($info['redis_version'], '2.8', '>=')) { + // As documented in Redis documentation (http://redis.io/commands/keys) using KEYS + // can hang your server when it is executed against large databases (millions of items). + // Whenever you hit this scale, you should really consider upgrading to Redis 2.8 or above. + $cleared = $host->eval("local keys=redis.call('KEYS',ARGV[1]..'*') for i=1,#keys,5000 do redis.call('DEL',unpack(keys,i,math.min(i+4999,#keys))) end return 1", $evalArgs[0], $evalArgs[1]) && $cleared; + continue; + } + + $cursor = null; + do { + $keys = $host instanceof \Predis\Client ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000); + if (isset($keys[1]) && \is_array($keys[1])) { + $cursor = $keys[0]; + $keys = $keys[1]; + } + if ($keys) { + $this->doDelete($keys); + } + } while ($cursor = (int) $cursor); + } + + return $cleared; + } + + /** + * {@inheritdoc} + */ + protected function doDelete(array $ids) + { + if (!$ids) { + return true; + } + + if ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface) { + $this->pipeline(function () use ($ids) { + foreach ($ids as $id) { + yield 'del' => [$id]; + } + })->rewind(); + } else { + $this->redis->del($ids); + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doSave(array $values, $lifetime) + { + $serialized = []; + $failed = []; + + foreach ($values as $id => $value) { + try { + $serialized[$id] = serialize($value); + } catch (\Exception $e) { + $failed[] = $id; + } + } + + if (!$serialized) { + return $failed; + } + + $results = $this->pipeline(function () use ($serialized, $lifetime) { + foreach ($serialized as $id => $value) { + if (0 >= $lifetime) { + yield 'set' => [$id, $value]; + } else { + yield 'setEx' => [$id, $lifetime, $value]; + } + } + }); + foreach ($results as $id => $result) { + if (true !== $result && (!$result instanceof Status || $result !== Status::get('OK'))) { + $failed[] = $id; + } + } + + return $failed; + } + + private function pipeline(\Closure $generator) + { + $ids = []; + + if ($this->redis instanceof \RedisCluster || ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof RedisCluster)) { + // phpredis & predis don't support pipelining with RedisCluster + // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining + // see https://github.com/nrk/predis/issues/267#issuecomment-123781423 + $results = []; + foreach ($generator() as $command => $args) { + $results[] = \call_user_func_array([$this->redis, $command], $args); + $ids[] = $args[0]; + } + } elseif ($this->redis instanceof \Predis\Client) { + $results = $this->redis->pipeline(function ($redis) use ($generator, &$ids) { + foreach ($generator() as $command => $args) { + \call_user_func_array([$redis, $command], $args); + $ids[] = $args[0]; + } + }); + } elseif ($this->redis instanceof \RedisArray) { + $connections = $results = $ids = []; + foreach ($generator() as $command => $args) { + if (!isset($connections[$h = $this->redis->_target($args[0])])) { + $connections[$h] = [$this->redis->_instance($h), -1]; + $connections[$h][0]->multi(\Redis::PIPELINE); + } + \call_user_func_array([$connections[$h][0], $command], $args); + $results[] = [$h, ++$connections[$h][1]]; + $ids[] = $args[0]; + } + foreach ($connections as $h => $c) { + $connections[$h] = $c[0]->exec(); + } + foreach ($results as $k => list($h, $c)) { + $results[$k] = $connections[$h][$c]; + } + } else { + $this->redis->multi(\Redis::PIPELINE); + foreach ($generator() as $command => $args) { + \call_user_func_array([$this->redis, $command], $args); + $ids[] = $args[0]; + } + $results = $this->redis->exec(); + } + + foreach ($ids as $k => $id) { + yield $id => $results[$k]; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/composer.json b/modules/empikmarketplace/vendor/symfony/cache/composer.json new file mode 100644 index 00000000..f412e4f1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/composer.json @@ -0,0 +1,45 @@ +{ + "name": "symfony/cache", + "type": "library", + "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "keywords": ["caching", "psr6"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "provide": { + "psr/cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/cache": "~1.0", + "psr/log": "~1.0", + "psr/simple-cache": "^1.0", + "symfony/polyfill-apcu": "~1.1" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" + }, + "conflict": { + "symfony/var-dumper": "<3.3" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Cache\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/modules/empikmarketplace/vendor/symfony/cache/phpunit.xml.dist b/modules/empikmarketplace/vendor/symfony/cache/phpunit.xml.dist new file mode 100644 index 00000000..c35458ca --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/cache/phpunit.xml.dist @@ -0,0 +1,50 @@ + + + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + + + + + + + + Cache\IntegrationTests + Doctrine\Common\Cache + Symfony\Component\Cache + Symfony\Component\Cache\Tests\Fixtures + Symfony\Component\Cache\Traits + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/config/.gitignore b/modules/empikmarketplace/vendor/symfony/config/.gitignore new file mode 100644 index 00000000..c49a5d8d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/modules/empikmarketplace/vendor/symfony/config/CHANGELOG.md b/modules/empikmarketplace/vendor/symfony/config/CHANGELOG.md new file mode 100644 index 00000000..6cb610c4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/CHANGELOG.md @@ -0,0 +1,78 @@ +CHANGELOG +========= + +3.4.0 +----- + + * added `setDeprecated()` method to indicate a deprecated node + * added `XmlUtils::parse()` method to parse an XML string + * deprecated `ConfigCachePass` + +3.3.0 +----- + + * added `ReflectionClassResource` class + * added second `$exists` constructor argument to `ClassExistenceResource` + * made `ClassExistenceResource` work with interfaces and traits + * added `ConfigCachePass` (originally in FrameworkBundle) + * added `castToArray()` helper to turn any config value into an array + +3.0.0 +----- + + * removed `ReferenceDumper` class + * removed the `ResourceInterface::isFresh()` method + * removed `BCResourceInterfaceChecker` class + * removed `ResourceInterface::getResource()` method + +2.8.0 +----- + +The edge case of defining just one value for nodes of type Enum is now allowed: + +```php +$rootNode + ->children() + ->enumNode('variable') + ->values(['value']) + ->end() + ->end() +; +``` + +Before: `InvalidArgumentException` (variable must contain at least two +distinct elements). +After: the code will work as expected and it will restrict the values of the +`variable` option to just `value`. + + * deprecated the `ResourceInterface::isFresh()` method. If you implement custom resource types and they + can be validated that way, make them implement the new `SelfCheckingResourceInterface`. + * deprecated the getResource() method in ResourceInterface. You can still call this method + on concrete classes implementing the interface, but it does not make sense at the interface + level as you need to know about the particular type of resource at hand to understand the + semantics of the returned value. + +2.7.0 +----- + + * added `ConfigCacheInterface`, `ConfigCacheFactoryInterface` and a basic `ConfigCacheFactory` + implementation to delegate creation of ConfigCache instances + +2.2.0 +----- + + * added `ArrayNodeDefinition::canBeEnabled()` and `ArrayNodeDefinition::canBeDisabled()` + to ease configuration when some sections are respectively disabled / enabled + by default. + * added a `normalizeKeys()` method for array nodes (to avoid key normalization) + * added numerical type handling for config definitions + * added convenience methods for optional configuration sections to `ArrayNodeDefinition` + * added a utils class for XML manipulations + +2.1.0 +----- + + * added a way to add documentation on configuration + * implemented `Serializable` on resources + * `LoaderResolverInterface` is now used instead of `LoaderResolver` for type + hinting diff --git a/modules/empikmarketplace/vendor/symfony/config/ConfigCache.php b/modules/empikmarketplace/vendor/symfony/config/ConfigCache.php new file mode 100644 index 00000000..b2a39076 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ConfigCache.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +use Symfony\Component\Config\Resource\SelfCheckingResourceChecker; + +/** + * ConfigCache caches arbitrary content in files on disk. + * + * When in debug mode, those metadata resources that implement + * \Symfony\Component\Config\Resource\SelfCheckingResourceInterface will + * be used to check cache freshness. + * + * @author Fabien Potencier + * @author Matthias Pigulla + */ +class ConfigCache extends ResourceCheckerConfigCache +{ + private $debug; + + /** + * @param string $file The absolute cache path + * @param bool $debug Whether debugging is enabled or not + */ + public function __construct($file, $debug) + { + $this->debug = (bool) $debug; + + $checkers = []; + if (true === $this->debug) { + $checkers = [new SelfCheckingResourceChecker()]; + } + + parent::__construct($file, $checkers); + } + + /** + * Checks if the cache is still fresh. + * + * This implementation always returns true when debug is off and the + * cache file exists. + * + * @return bool true if the cache is fresh, false otherwise + */ + public function isFresh() + { + if (!$this->debug && is_file($this->getPath())) { + return true; + } + + return parent::isFresh(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/ConfigCacheFactory.php b/modules/empikmarketplace/vendor/symfony/config/ConfigCacheFactory.php new file mode 100644 index 00000000..7903cca9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ConfigCacheFactory.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +/** + * Basic implementation of ConfigCacheFactoryInterface that + * creates an instance of the default ConfigCache. + * + * This factory and/or cache do not support cache validation + * by means of ResourceChecker instances (that is, service-based). + * + * @author Matthias Pigulla + */ +class ConfigCacheFactory implements ConfigCacheFactoryInterface +{ + private $debug; + + /** + * @param bool $debug The debug flag to pass to ConfigCache + */ + public function __construct($debug) + { + $this->debug = $debug; + } + + /** + * {@inheritdoc} + */ + public function cache($file, $callback) + { + if (!\is_callable($callback)) { + throw new \InvalidArgumentException(sprintf('Invalid type for callback argument. Expected callable, but got "%s".', \gettype($callback))); + } + + $cache = new ConfigCache($file, $this->debug); + if (!$cache->isFresh()) { + \call_user_func($callback, $cache); + } + + return $cache; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/ConfigCacheFactoryInterface.php b/modules/empikmarketplace/vendor/symfony/config/ConfigCacheFactoryInterface.php new file mode 100644 index 00000000..8e80142b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ConfigCacheFactoryInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +/** + * Interface for a ConfigCache factory. This factory creates + * an instance of ConfigCacheInterface and initializes the + * cache if necessary. + * + * @author Matthias Pigulla + */ +interface ConfigCacheFactoryInterface +{ + /** + * Creates a cache instance and (re-)initializes it if necessary. + * + * @param string $file The absolute cache file path + * @param callable $callable The callable to be executed when the cache needs to be filled (i. e. is not fresh). The cache will be passed as the only parameter to this callback + * + * @return ConfigCacheInterface The cache instance + */ + public function cache($file, $callable); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/ConfigCacheInterface.php b/modules/empikmarketplace/vendor/symfony/config/ConfigCacheInterface.php new file mode 100644 index 00000000..7c47ad70 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ConfigCacheInterface.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * Interface for ConfigCache. + * + * @author Matthias Pigulla + */ +interface ConfigCacheInterface +{ + /** + * Gets the cache file path. + * + * @return string The cache file path + */ + public function getPath(); + + /** + * Checks if the cache is still fresh. + * + * This check should take the metadata passed to the write() method into consideration. + * + * @return bool Whether the cache is still fresh + */ + public function isFresh(); + + /** + * Writes the given content into the cache file. Metadata will be stored + * independently and can be used to check cache freshness at a later time. + * + * @param string $content The content to write into the cache + * @param ResourceInterface[]|null $metadata An array of ResourceInterface instances + * + * @throws \RuntimeException When the cache file cannot be written + */ + public function write($content, array $metadata = null); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/ArrayNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/ArrayNode.php new file mode 100644 index 00000000..59a0af87 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/ArrayNode.php @@ -0,0 +1,379 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; +use Symfony\Component\Config\Definition\Exception\UnsetKeyException; + +/** + * Represents an Array node in the config tree. + * + * @author Johannes M. Schmitt + */ +class ArrayNode extends BaseNode implements PrototypeNodeInterface +{ + protected $xmlRemappings = []; + protected $children = []; + protected $allowFalse = false; + protected $allowNewKeys = true; + protected $addIfNotSet = false; + protected $performDeepMerging = true; + protected $ignoreExtraKeys = false; + protected $removeExtraKeys = true; + protected $normalizeKeys = true; + + public function setNormalizeKeys($normalizeKeys) + { + $this->normalizeKeys = (bool) $normalizeKeys; + } + + /** + * {@inheritdoc} + * + * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML. + * After running this method, all keys are normalized to foo_bar. + * + * If you have a mixed key like foo-bar_moo, it will not be altered. + * The key will also not be altered if the target key already exists. + */ + protected function preNormalize($value) + { + if (!$this->normalizeKeys || !\is_array($value)) { + return $value; + } + + $normalized = []; + + foreach ($value as $k => $v) { + if (false !== strpos($k, '-') && false === strpos($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) { + $normalized[$normalizedKey] = $v; + } else { + $normalized[$k] = $v; + } + } + + return $normalized; + } + + /** + * Retrieves the children of this node. + * + * @return array The children + */ + public function getChildren() + { + return $this->children; + } + + /** + * Sets the xml remappings that should be performed. + * + * @param array $remappings An array of the form [[string, string]] + */ + public function setXmlRemappings(array $remappings) + { + $this->xmlRemappings = $remappings; + } + + /** + * Gets the xml remappings that should be performed. + * + * @return array an array of the form [[string, string]] + */ + public function getXmlRemappings() + { + return $this->xmlRemappings; + } + + /** + * Sets whether to add default values for this array if it has not been + * defined in any of the configuration files. + * + * @param bool $boolean + */ + public function setAddIfNotSet($boolean) + { + $this->addIfNotSet = (bool) $boolean; + } + + /** + * Sets whether false is allowed as value indicating that the array should be unset. + * + * @param bool $allow + */ + public function setAllowFalse($allow) + { + $this->allowFalse = (bool) $allow; + } + + /** + * Sets whether new keys can be defined in subsequent configurations. + * + * @param bool $allow + */ + public function setAllowNewKeys($allow) + { + $this->allowNewKeys = (bool) $allow; + } + + /** + * Sets if deep merging should occur. + * + * @param bool $boolean + */ + public function setPerformDeepMerging($boolean) + { + $this->performDeepMerging = (bool) $boolean; + } + + /** + * Whether extra keys should just be ignored without an exception. + * + * @param bool $boolean To allow extra keys + * @param bool $remove To remove extra keys + */ + public function setIgnoreExtraKeys($boolean, $remove = true) + { + $this->ignoreExtraKeys = (bool) $boolean; + $this->removeExtraKeys = $this->ignoreExtraKeys && $remove; + } + + /** + * {@inheritdoc} + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + public function hasDefaultValue() + { + return $this->addIfNotSet; + } + + /** + * {@inheritdoc} + */ + public function getDefaultValue() + { + if (!$this->hasDefaultValue()) { + throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath())); + } + + $defaults = []; + foreach ($this->children as $name => $child) { + if ($child->hasDefaultValue()) { + $defaults[$name] = $child->getDefaultValue(); + } + } + + return $defaults; + } + + /** + * Adds a child node. + * + * @throws \InvalidArgumentException when the child node has no name + * @throws \InvalidArgumentException when the child node's name is not unique + */ + public function addChild(NodeInterface $node) + { + $name = $node->getName(); + if (!\strlen($name)) { + throw new \InvalidArgumentException('Child nodes must be named.'); + } + if (isset($this->children[$name])) { + throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name)); + } + + $this->children[$name] = $node; + } + + /** + * Finalizes the value of this node. + * + * @param mixed $value + * + * @return mixed The finalised value + * + * @throws UnsetKeyException + * @throws InvalidConfigurationException if the node doesn't have enough children + */ + protected function finalizeValue($value) + { + if (false === $value) { + throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: "%s".', $this->getPath(), json_encode($value))); + } + + foreach ($this->children as $name => $child) { + if (!\array_key_exists($name, $value)) { + if ($child->isRequired()) { + $ex = new InvalidConfigurationException(sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath())); + $ex->setPath($this->getPath()); + + throw $ex; + } + + if ($child->hasDefaultValue()) { + $value[$name] = $child->getDefaultValue(); + } + + continue; + } + + if ($child->isDeprecated()) { + @trigger_error($child->getDeprecationMessage($name, $this->getPath()), \E_USER_DEPRECATED); + } + + try { + $value[$name] = $child->finalize($value[$name]); + } catch (UnsetKeyException $e) { + unset($value[$name]); + } + } + + return $value; + } + + /** + * Validates the type of the value. + * + * @param mixed $value + * + * @throws InvalidTypeException + */ + protected function validateType($value) + { + if (!\is_array($value) && (!$this->allowFalse || false !== $value)) { + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected array, but got %s', $this->getPath(), \gettype($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + + throw $ex; + } + } + + /** + * Normalizes the value. + * + * @param mixed $value The value to normalize + * + * @return mixed The normalized value + * + * @throws InvalidConfigurationException + */ + protected function normalizeValue($value) + { + if (false === $value) { + return $value; + } + + $value = $this->remapXml($value); + + $normalized = []; + foreach ($value as $name => $val) { + if (isset($this->children[$name])) { + try { + $normalized[$name] = $this->children[$name]->normalize($val); + } catch (UnsetKeyException $e) { + } + unset($value[$name]); + } elseif (!$this->removeExtraKeys) { + $normalized[$name] = $val; + } + } + + // if extra fields are present, throw exception + if (\count($value) && !$this->ignoreExtraKeys) { + $ex = new InvalidConfigurationException(sprintf('Unrecognized option%s "%s" under "%s"', 1 === \count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath())); + $ex->setPath($this->getPath()); + + throw $ex; + } + + return $normalized; + } + + /** + * Remaps multiple singular values to a single plural value. + * + * @param array $value The source values + * + * @return array The remapped values + */ + protected function remapXml($value) + { + foreach ($this->xmlRemappings as list($singular, $plural)) { + if (!isset($value[$singular])) { + continue; + } + + $value[$plural] = Processor::normalizeConfig($value, $singular, $plural); + unset($value[$singular]); + } + + return $value; + } + + /** + * Merges values together. + * + * @param mixed $leftSide The left side to merge + * @param mixed $rightSide The right side to merge + * + * @return mixed The merged values + * + * @throws InvalidConfigurationException + * @throws \RuntimeException + */ + protected function mergeValues($leftSide, $rightSide) + { + if (false === $rightSide) { + // if this is still false after the last config has been merged the + // finalization pass will take care of removing this key entirely + return false; + } + + if (false === $leftSide || !$this->performDeepMerging) { + return $rightSide; + } + + foreach ($rightSide as $k => $v) { + // no conflict + if (!\array_key_exists($k, $leftSide)) { + if (!$this->allowNewKeys) { + $ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file. If you are trying to overwrite an element, make sure you redefine it with the same name.', $this->getPath())); + $ex->setPath($this->getPath()); + + throw $ex; + } + + $leftSide[$k] = $v; + continue; + } + + if (!isset($this->children[$k])) { + throw new \RuntimeException('merge() expects a normalized config array.'); + } + + $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v); + } + + return $leftSide; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/BaseNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/BaseNode.php new file mode 100644 index 00000000..10bcb49c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/BaseNode.php @@ -0,0 +1,381 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * The base node class. + * + * @author Johannes M. Schmitt + */ +abstract class BaseNode implements NodeInterface +{ + protected $name; + protected $parent; + protected $normalizationClosures = []; + protected $finalValidationClosures = []; + protected $allowOverwrite = true; + protected $required = false; + protected $deprecationMessage = null; + protected $equivalentValues = []; + protected $attributes = []; + + /** + * @param string|null $name The name of the node + * @param NodeInterface|null $parent The parent of this node + * + * @throws \InvalidArgumentException if the name contains a period + */ + public function __construct($name, NodeInterface $parent = null) + { + if (false !== strpos($name = (string) $name, '.')) { + throw new \InvalidArgumentException('The name must not contain ".".'); + } + + $this->name = $name; + $this->parent = $parent; + } + + /** + * @param string $key + */ + public function setAttribute($key, $value) + { + $this->attributes[$key] = $value; + } + + /** + * @param string $key + * + * @return mixed + */ + public function getAttribute($key, $default = null) + { + return isset($this->attributes[$key]) ? $this->attributes[$key] : $default; + } + + /** + * @param string $key + * + * @return bool + */ + public function hasAttribute($key) + { + return isset($this->attributes[$key]); + } + + /** + * @return array + */ + public function getAttributes() + { + return $this->attributes; + } + + public function setAttributes(array $attributes) + { + $this->attributes = $attributes; + } + + /** + * @param string $key + */ + public function removeAttribute($key) + { + unset($this->attributes[$key]); + } + + /** + * Sets an info message. + * + * @param string $info + */ + public function setInfo($info) + { + $this->setAttribute('info', $info); + } + + /** + * Returns info message. + * + * @return string|null The info text + */ + public function getInfo() + { + return $this->getAttribute('info'); + } + + /** + * Sets the example configuration for this node. + * + * @param string|array $example + */ + public function setExample($example) + { + $this->setAttribute('example', $example); + } + + /** + * Retrieves the example configuration for this node. + * + * @return string|array|null The example + */ + public function getExample() + { + return $this->getAttribute('example'); + } + + /** + * Adds an equivalent value. + * + * @param mixed $originalValue + * @param mixed $equivalentValue + */ + public function addEquivalentValue($originalValue, $equivalentValue) + { + $this->equivalentValues[] = [$originalValue, $equivalentValue]; + } + + /** + * Set this node as required. + * + * @param bool $boolean Required node + */ + public function setRequired($boolean) + { + $this->required = (bool) $boolean; + } + + /** + * Sets this node as deprecated. + * + * You can use %node% and %path% placeholders in your message to display, + * respectively, the node name and its complete path. + * + * @param string|null $message Deprecated message + */ + public function setDeprecated($message) + { + $this->deprecationMessage = $message; + } + + /** + * Sets if this node can be overridden. + * + * @param bool $allow + */ + public function setAllowOverwrite($allow) + { + $this->allowOverwrite = (bool) $allow; + } + + /** + * Sets the closures used for normalization. + * + * @param \Closure[] $closures An array of Closures used for normalization + */ + public function setNormalizationClosures(array $closures) + { + $this->normalizationClosures = $closures; + } + + /** + * Sets the closures used for final validation. + * + * @param \Closure[] $closures An array of Closures used for final validation + */ + public function setFinalValidationClosures(array $closures) + { + $this->finalValidationClosures = $closures; + } + + /** + * {@inheritdoc} + */ + public function isRequired() + { + return $this->required; + } + + /** + * Checks if this node is deprecated. + * + * @return bool + */ + public function isDeprecated() + { + return null !== $this->deprecationMessage; + } + + /** + * Returns the deprecated message. + * + * @param string $node the configuration node name + * @param string $path the path of the node + * + * @return string + */ + public function getDeprecationMessage($node, $path) + { + return strtr($this->deprecationMessage, ['%node%' => $node, '%path%' => $path]); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function getPath() + { + $path = $this->name; + + if (null !== $this->parent) { + $path = $this->parent->getPath().'.'.$path; + } + + return $path; + } + + /** + * {@inheritdoc} + */ + final public function merge($leftSide, $rightSide) + { + if (!$this->allowOverwrite) { + throw new ForbiddenOverwriteException(sprintf('Configuration path "%s" cannot be overwritten. You have to define all options for this path, and any of its sub-paths in one configuration section.', $this->getPath())); + } + + $this->validateType($leftSide); + $this->validateType($rightSide); + + return $this->mergeValues($leftSide, $rightSide); + } + + /** + * {@inheritdoc} + */ + final public function normalize($value) + { + $value = $this->preNormalize($value); + + // run custom normalization closures + foreach ($this->normalizationClosures as $closure) { + $value = $closure($value); + } + + // replace value with their equivalent + foreach ($this->equivalentValues as $data) { + if ($data[0] === $value) { + $value = $data[1]; + } + } + + // validate type + $this->validateType($value); + + // normalize value + return $this->normalizeValue($value); + } + + /** + * Normalizes the value before any other normalization is applied. + * + * @param mixed $value + * + * @return mixed The normalized array value + */ + protected function preNormalize($value) + { + return $value; + } + + /** + * Returns parent node for this node. + * + * @return NodeInterface|null + */ + public function getParent() + { + return $this->parent; + } + + /** + * {@inheritdoc} + */ + final public function finalize($value) + { + $this->validateType($value); + + $value = $this->finalizeValue($value); + + // Perform validation on the final value if a closure has been set. + // The closure is also allowed to return another value. + foreach ($this->finalValidationClosures as $closure) { + try { + $value = $closure($value); + } catch (Exception $e) { + throw $e; + } catch (\Exception $e) { + throw new InvalidConfigurationException(sprintf('Invalid configuration for path "%s": ', $this->getPath()).$e->getMessage(), $e->getCode(), $e); + } + } + + return $value; + } + + /** + * Validates the type of a Node. + * + * @param mixed $value The value to validate + * + * @throws InvalidTypeException when the value is invalid + */ + abstract protected function validateType($value); + + /** + * Normalizes the value. + * + * @param mixed $value The value to normalize + * + * @return mixed The normalized value + */ + abstract protected function normalizeValue($value); + + /** + * Merges two values together. + * + * @param mixed $leftSide + * @param mixed $rightSide + * + * @return mixed The merged value + */ + abstract protected function mergeValues($leftSide, $rightSide); + + /** + * Finalizes a value. + * + * @param mixed $value The value to finalize + * + * @return mixed The finalized value + */ + abstract protected function finalizeValue($value); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/BooleanNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/BooleanNode.php new file mode 100644 index 00000000..85f467b6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/BooleanNode.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * This node represents a Boolean value in the config tree. + * + * @author Johannes M. Schmitt + */ +class BooleanNode extends ScalarNode +{ + /** + * {@inheritdoc} + */ + protected function validateType($value) + { + if (!\is_bool($value)) { + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected boolean, but got %s.', $this->getPath(), \gettype($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + + throw $ex; + } + } + + /** + * {@inheritdoc} + */ + protected function isValueEmpty($value) + { + // a boolean value cannot be empty + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php new file mode 100644 index 00000000..da4ebf62 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ArrayNodeDefinition.php @@ -0,0 +1,522 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +use Symfony\Component\Config\Definition\PrototypedArrayNode; + +/** + * This class provides a fluent interface for defining an array node. + * + * @author Johannes M. Schmitt + */ +class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface +{ + protected $performDeepMerging = true; + protected $ignoreExtraKeys = false; + protected $removeExtraKeys = true; + protected $children = []; + protected $prototype; + protected $atLeastOne = false; + protected $allowNewKeys = true; + protected $key; + protected $removeKeyItem; + protected $addDefaults = false; + protected $addDefaultChildren = false; + protected $nodeBuilder; + protected $normalizeKeys = true; + + /** + * {@inheritdoc} + */ + public function __construct($name, NodeParentInterface $parent = null) + { + parent::__construct($name, $parent); + + $this->nullEquivalent = []; + $this->trueEquivalent = []; + } + + /** + * {@inheritdoc} + */ + public function setBuilder(NodeBuilder $builder) + { + $this->nodeBuilder = $builder; + } + + /** + * {@inheritdoc} + */ + public function children() + { + return $this->getNodeBuilder(); + } + + /** + * Sets a prototype for child nodes. + * + * @param string $type The type of node + * + * @return NodeDefinition + */ + public function prototype($type) + { + return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this); + } + + /** + * @return VariableNodeDefinition + */ + public function variablePrototype() + { + return $this->prototype('variable'); + } + + /** + * @return ScalarNodeDefinition + */ + public function scalarPrototype() + { + return $this->prototype('scalar'); + } + + /** + * @return BooleanNodeDefinition + */ + public function booleanPrototype() + { + return $this->prototype('boolean'); + } + + /** + * @return IntegerNodeDefinition + */ + public function integerPrototype() + { + return $this->prototype('integer'); + } + + /** + * @return FloatNodeDefinition + */ + public function floatPrototype() + { + return $this->prototype('float'); + } + + /** + * @return ArrayNodeDefinition + */ + public function arrayPrototype() + { + return $this->prototype('array'); + } + + /** + * @return EnumNodeDefinition + */ + public function enumPrototype() + { + return $this->prototype('enum'); + } + + /** + * Adds the default value if the node is not set in the configuration. + * + * This method is applicable to concrete nodes only (not to prototype nodes). + * If this function has been called and the node is not set during the finalization + * phase, it's default value will be derived from its children default values. + * + * @return $this + */ + public function addDefaultsIfNotSet() + { + $this->addDefaults = true; + + return $this; + } + + /** + * Adds children with a default value when none are defined. + * + * This method is applicable to prototype nodes only. + * + * @param int|string|array|null $children The number of children|The child name|The children names to be added + * + * @return $this + */ + public function addDefaultChildrenIfNoneSet($children = null) + { + $this->addDefaultChildren = $children; + + return $this; + } + + /** + * Requires the node to have at least one element. + * + * This method is applicable to prototype nodes only. + * + * @return $this + */ + public function requiresAtLeastOneElement() + { + $this->atLeastOne = true; + + return $this; + } + + /** + * Disallows adding news keys in a subsequent configuration. + * + * If used all keys have to be defined in the same configuration file. + * + * @return $this + */ + public function disallowNewKeysInSubsequentConfigs() + { + $this->allowNewKeys = false; + + return $this; + } + + /** + * Sets a normalization rule for XML configurations. + * + * @param string $singular The key to remap + * @param string $plural The plural of the key for irregular plurals + * + * @return $this + */ + public function fixXmlConfig($singular, $plural = null) + { + $this->normalization()->remap($singular, $plural); + + return $this; + } + + /** + * Sets the attribute which value is to be used as key. + * + * This is useful when you have an indexed array that should be an + * associative array. You can select an item from within the array + * to be the key of the particular item. For example, if "id" is the + * "key", then: + * + * [ + * ['id' => 'my_name', 'foo' => 'bar'], + * ]; + * + * becomes + * + * [ + * 'my_name' => ['foo' => 'bar'], + * ]; + * + * If you'd like "'id' => 'my_name'" to still be present in the resulting + * array, then you can set the second argument of this method to false. + * + * This method is applicable to prototype nodes only. + * + * @param string $name The name of the key + * @param bool $removeKeyItem Whether or not the key item should be removed + * + * @return $this + */ + public function useAttributeAsKey($name, $removeKeyItem = true) + { + $this->key = $name; + $this->removeKeyItem = $removeKeyItem; + + return $this; + } + + /** + * Sets whether the node can be unset. + * + * @param bool $allow + * + * @return $this + */ + public function canBeUnset($allow = true) + { + $this->merge()->allowUnset($allow); + + return $this; + } + + /** + * Adds an "enabled" boolean to enable the current section. + * + * By default, the section is disabled. If any configuration is specified then + * the node will be automatically enabled: + * + * enableableArrayNode: {enabled: true, ...} # The config is enabled & default values get overridden + * enableableArrayNode: ~ # The config is enabled & use the default values + * enableableArrayNode: true # The config is enabled & use the default values + * enableableArrayNode: {other: value, ...} # The config is enabled & default values get overridden + * enableableArrayNode: {enabled: false, ...} # The config is disabled + * enableableArrayNode: false # The config is disabled + * + * @return $this + */ + public function canBeEnabled() + { + $this + ->addDefaultsIfNotSet() + ->treatFalseLike(['enabled' => false]) + ->treatTrueLike(['enabled' => true]) + ->treatNullLike(['enabled' => true]) + ->beforeNormalization() + ->ifArray() + ->then(function ($v) { + $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true; + + return $v; + }) + ->end() + ->children() + ->booleanNode('enabled') + ->defaultFalse() + ; + + return $this; + } + + /** + * Adds an "enabled" boolean to enable the current section. + * + * By default, the section is enabled. + * + * @return $this + */ + public function canBeDisabled() + { + $this + ->addDefaultsIfNotSet() + ->treatFalseLike(['enabled' => false]) + ->treatTrueLike(['enabled' => true]) + ->treatNullLike(['enabled' => true]) + ->children() + ->booleanNode('enabled') + ->defaultTrue() + ; + + return $this; + } + + /** + * Disables the deep merging of the node. + * + * @return $this + */ + public function performNoDeepMerging() + { + $this->performDeepMerging = false; + + return $this; + } + + /** + * Allows extra config keys to be specified under an array without + * throwing an exception. + * + * Those config values are ignored and removed from the resulting + * array. This should be used only in special cases where you want + * to send an entire configuration array through a special tree that + * processes only part of the array. + * + * @param bool $remove Whether to remove the extra keys + * + * @return $this + */ + public function ignoreExtraKeys($remove = true) + { + $this->ignoreExtraKeys = true; + $this->removeExtraKeys = $remove; + + return $this; + } + + /** + * Sets key normalization. + * + * @param bool $bool Whether to enable key normalization + * + * @return $this + */ + public function normalizeKeys($bool) + { + $this->normalizeKeys = (bool) $bool; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function append(NodeDefinition $node) + { + $this->children[$node->name] = $node->setParent($this); + + return $this; + } + + /** + * Returns a node builder to be used to add children and prototype. + * + * @return NodeBuilder The node builder + */ + protected function getNodeBuilder() + { + if (null === $this->nodeBuilder) { + $this->nodeBuilder = new NodeBuilder(); + } + + return $this->nodeBuilder->setParent($this); + } + + /** + * {@inheritdoc} + */ + protected function createNode() + { + if (null === $this->prototype) { + $node = new ArrayNode($this->name, $this->parent); + + $this->validateConcreteNode($node); + + $node->setAddIfNotSet($this->addDefaults); + + foreach ($this->children as $child) { + $child->parent = $node; + $node->addChild($child->getNode()); + } + } else { + $node = new PrototypedArrayNode($this->name, $this->parent); + + $this->validatePrototypeNode($node); + + if (null !== $this->key) { + $node->setKeyAttribute($this->key, $this->removeKeyItem); + } + + if (false === $this->allowEmptyValue) { + @trigger_error(sprintf('Using %s::cannotBeEmpty() at path "%s" has no effect, consider requiresAtLeastOneElement() instead. In 4.0 both methods will behave the same.', __CLASS__, $node->getPath()), \E_USER_DEPRECATED); + } + + if (true === $this->atLeastOne) { + $node->setMinNumberOfElements(1); + } + + if ($this->default) { + $node->setDefaultValue($this->defaultValue); + } + + if (false !== $this->addDefaultChildren) { + $node->setAddChildrenIfNoneSet($this->addDefaultChildren); + if ($this->prototype instanceof static && null === $this->prototype->prototype) { + $this->prototype->addDefaultsIfNotSet(); + } + } + + $this->prototype->parent = $node; + $node->setPrototype($this->prototype->getNode()); + } + + $node->setAllowNewKeys($this->allowNewKeys); + $node->addEquivalentValue(null, $this->nullEquivalent); + $node->addEquivalentValue(true, $this->trueEquivalent); + $node->addEquivalentValue(false, $this->falseEquivalent); + $node->setPerformDeepMerging($this->performDeepMerging); + $node->setRequired($this->required); + $node->setDeprecated($this->deprecationMessage); + $node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys); + $node->setNormalizeKeys($this->normalizeKeys); + + if (null !== $this->normalization) { + $node->setNormalizationClosures($this->normalization->before); + $node->setXmlRemappings($this->normalization->remappings); + } + + if (null !== $this->merge) { + $node->setAllowOverwrite($this->merge->allowOverwrite); + $node->setAllowFalse($this->merge->allowFalse); + } + + if (null !== $this->validation) { + $node->setFinalValidationClosures($this->validation->rules); + } + + return $node; + } + + /** + * Validate the configuration of a concrete node. + * + * @throws InvalidDefinitionException + */ + protected function validateConcreteNode(ArrayNode $node) + { + $path = $node->getPath(); + + if (null !== $this->key) { + throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s".', $path)); + } + + if (false === $this->allowEmptyValue) { + @trigger_error(sprintf('->cannotBeEmpty() is not applicable to concrete nodes at path "%s". In 4.0 it will throw an exception.', $path), \E_USER_DEPRECATED); + } + + if (true === $this->atLeastOne) { + throw new InvalidDefinitionException(sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s".', $path)); + } + + if ($this->default) { + throw new InvalidDefinitionException(sprintf('->defaultValue() is not applicable to concrete nodes at path "%s".', $path)); + } + + if (false !== $this->addDefaultChildren) { + throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s".', $path)); + } + } + + /** + * Validate the configuration of a prototype node. + * + * @throws InvalidDefinitionException + */ + protected function validatePrototypeNode(PrototypedArrayNode $node) + { + $path = $node->getPath(); + + if ($this->addDefaults) { + throw new InvalidDefinitionException(sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s".', $path)); + } + + if (false !== $this->addDefaultChildren) { + if ($this->default) { + throw new InvalidDefinitionException(sprintf('A default value and default children might not be used together at path "%s".', $path)); + } + + if (null !== $this->key && (null === $this->addDefaultChildren || \is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) { + throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s".', $path)); + } + + if (null === $this->key && (\is_string($this->addDefaultChildren) || \is_array($this->addDefaultChildren))) { + throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s".', $path)); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php new file mode 100644 index 00000000..28e56579 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/BooleanNodeDefinition.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\BooleanNode; +use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; + +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +class BooleanNodeDefinition extends ScalarNodeDefinition +{ + /** + * {@inheritdoc} + */ + public function __construct($name, NodeParentInterface $parent = null) + { + parent::__construct($name, $parent); + + $this->nullEquivalent = true; + } + + /** + * Instantiate a Node. + * + * @return BooleanNode The node + */ + protected function instantiateNode() + { + return new BooleanNode($this->name, $this->parent); + } + + /** + * {@inheritdoc} + * + * @throws InvalidDefinitionException + */ + public function cannotBeEmpty() + { + throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to BooleanNodeDefinition.'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php new file mode 100644 index 00000000..817906f5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/EnumNodeDefinition.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\EnumNode; + +/** + * Enum Node Definition. + * + * @author Johannes M. Schmitt + */ +class EnumNodeDefinition extends ScalarNodeDefinition +{ + private $values; + + /** + * @return $this + */ + public function values(array $values) + { + $values = array_unique($values); + + if (empty($values)) { + throw new \InvalidArgumentException('->values() must be called with at least one value.'); + } + + $this->values = $values; + + return $this; + } + + /** + * Instantiate a Node. + * + * @return EnumNode The node + * + * @throws \RuntimeException + */ + protected function instantiateNode() + { + if (null === $this->values) { + throw new \RuntimeException('You must call ->values() on enum nodes.'); + } + + return new EnumNode($this->name, $this->parent, $this->values); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ExprBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ExprBuilder.php new file mode 100644 index 00000000..5db229dc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ExprBuilder.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\Exception\UnsetKeyException; + +/** + * This class builds an if expression. + * + * @author Johannes M. Schmitt + * @author Christophe Coevoet + */ +class ExprBuilder +{ + protected $node; + public $ifPart; + public $thenPart; + + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + + /** + * Marks the expression as being always used. + * + * @return $this + */ + public function always(\Closure $then = null) + { + $this->ifPart = function ($v) { return true; }; + + if (null !== $then) { + $this->thenPart = $then; + } + + return $this; + } + + /** + * Sets a closure to use as tests. + * + * The default one tests if the value is true. + * + * @return $this + */ + public function ifTrue(\Closure $closure = null) + { + if (null === $closure) { + $closure = function ($v) { return true === $v; }; + } + + $this->ifPart = $closure; + + return $this; + } + + /** + * Tests if the value is a string. + * + * @return $this + */ + public function ifString() + { + $this->ifPart = function ($v) { return \is_string($v); }; + + return $this; + } + + /** + * Tests if the value is null. + * + * @return $this + */ + public function ifNull() + { + $this->ifPart = function ($v) { return null === $v; }; + + return $this; + } + + /** + * Tests if the value is empty. + * + * @return ExprBuilder + */ + public function ifEmpty() + { + $this->ifPart = function ($v) { return empty($v); }; + + return $this; + } + + /** + * Tests if the value is an array. + * + * @return $this + */ + public function ifArray() + { + $this->ifPart = function ($v) { return \is_array($v); }; + + return $this; + } + + /** + * Tests if the value is in an array. + * + * @return $this + */ + public function ifInArray(array $array) + { + $this->ifPart = function ($v) use ($array) { return \in_array($v, $array, true); }; + + return $this; + } + + /** + * Tests if the value is not in an array. + * + * @return $this + */ + public function ifNotInArray(array $array) + { + $this->ifPart = function ($v) use ($array) { return !\in_array($v, $array, true); }; + + return $this; + } + + /** + * Transforms variables of any type into an array. + * + * @return $this + */ + public function castToArray() + { + $this->ifPart = function ($v) { return !\is_array($v); }; + $this->thenPart = function ($v) { return [$v]; }; + + return $this; + } + + /** + * Sets the closure to run if the test pass. + * + * @return $this + */ + public function then(\Closure $closure) + { + $this->thenPart = $closure; + + return $this; + } + + /** + * Sets a closure returning an empty array. + * + * @return $this + */ + public function thenEmptyArray() + { + $this->thenPart = function ($v) { return []; }; + + return $this; + } + + /** + * Sets a closure marking the value as invalid at processing time. + * + * if you want to add the value of the node in your message just use a %s placeholder. + * + * @param string $message + * + * @return $this + * + * @throws \InvalidArgumentException + */ + public function thenInvalid($message) + { + $this->thenPart = function ($v) use ($message) { throw new \InvalidArgumentException(sprintf($message, json_encode($v))); }; + + return $this; + } + + /** + * Sets a closure unsetting this key of the array at processing time. + * + * @return $this + * + * @throws UnsetKeyException + */ + public function thenUnset() + { + $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key.'); }; + + return $this; + } + + /** + * Returns the related node. + * + * @return NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition + * + * @throws \RuntimeException + */ + public function end() + { + if (null === $this->ifPart) { + throw new \RuntimeException('You must specify an if part.'); + } + if (null === $this->thenPart) { + throw new \RuntimeException('You must specify a then part.'); + } + + return $this->node; + } + + /** + * Builds the expressions. + * + * @param ExprBuilder[] $expressions An array of ExprBuilder instances to build + * + * @return array + */ + public static function buildExpressions(array $expressions) + { + foreach ($expressions as $k => $expr) { + if ($expr instanceof self) { + $if = $expr->ifPart; + $then = $expr->thenPart; + $expressions[$k] = function ($v) use ($if, $then) { + return $if($v) ? $then($v) : $v; + }; + } + } + + return $expressions; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php new file mode 100644 index 00000000..c0bed462 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/FloatNodeDefinition.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\FloatNode; + +/** + * This class provides a fluent interface for defining a float node. + * + * @author Jeanmonod David + */ +class FloatNodeDefinition extends NumericNodeDefinition +{ + /** + * Instantiates a Node. + * + * @return FloatNode The node + */ + protected function instantiateNode() + { + return new FloatNode($this->name, $this->parent, $this->min, $this->max); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php new file mode 100644 index 00000000..f6c3c147 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/IntegerNodeDefinition.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\IntegerNode; + +/** + * This class provides a fluent interface for defining an integer node. + * + * @author Jeanmonod David + */ +class IntegerNodeDefinition extends NumericNodeDefinition +{ + /** + * Instantiates a Node. + * + * @return IntegerNode The node + */ + protected function instantiateNode() + { + return new IntegerNode($this->name, $this->parent, $this->min, $this->max); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/MergeBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/MergeBuilder.php new file mode 100644 index 00000000..105e2d64 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/MergeBuilder.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * This class builds merge conditions. + * + * @author Johannes M. Schmitt + */ +class MergeBuilder +{ + protected $node; + public $allowFalse = false; + public $allowOverwrite = true; + + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + + /** + * Sets whether the node can be unset. + * + * @param bool $allow + * + * @return $this + */ + public function allowUnset($allow = true) + { + $this->allowFalse = $allow; + + return $this; + } + + /** + * Sets whether the node can be overwritten. + * + * @param bool $deny Whether the overwriting is forbidden or not + * + * @return $this + */ + public function denyOverwrite($deny = true) + { + $this->allowOverwrite = !$deny; + + return $this; + } + + /** + * Returns the related node. + * + * @return NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition + */ + public function end() + { + return $this->node; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeBuilder.php new file mode 100644 index 00000000..2809cb6c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeBuilder.php @@ -0,0 +1,238 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * This class provides a fluent interface for building a node. + * + * @author Johannes M. Schmitt + */ +class NodeBuilder implements NodeParentInterface +{ + protected $parent; + protected $nodeMapping; + + public function __construct() + { + $this->nodeMapping = [ + 'variable' => VariableNodeDefinition::class, + 'scalar' => ScalarNodeDefinition::class, + 'boolean' => BooleanNodeDefinition::class, + 'integer' => IntegerNodeDefinition::class, + 'float' => FloatNodeDefinition::class, + 'array' => ArrayNodeDefinition::class, + 'enum' => EnumNodeDefinition::class, + ]; + } + + /** + * Set the parent node. + * + * @return $this + */ + public function setParent(ParentNodeDefinitionInterface $parent = null) + { + $this->parent = $parent; + + return $this; + } + + /** + * Creates a child array node. + * + * @param string $name The name of the node + * + * @return ArrayNodeDefinition The child node + */ + public function arrayNode($name) + { + return $this->node($name, 'array'); + } + + /** + * Creates a child scalar node. + * + * @param string $name The name of the node + * + * @return ScalarNodeDefinition The child node + */ + public function scalarNode($name) + { + return $this->node($name, 'scalar'); + } + + /** + * Creates a child Boolean node. + * + * @param string $name The name of the node + * + * @return BooleanNodeDefinition The child node + */ + public function booleanNode($name) + { + return $this->node($name, 'boolean'); + } + + /** + * Creates a child integer node. + * + * @param string $name The name of the node + * + * @return IntegerNodeDefinition The child node + */ + public function integerNode($name) + { + return $this->node($name, 'integer'); + } + + /** + * Creates a child float node. + * + * @param string $name The name of the node + * + * @return FloatNodeDefinition The child node + */ + public function floatNode($name) + { + return $this->node($name, 'float'); + } + + /** + * Creates a child EnumNode. + * + * @param string $name + * + * @return EnumNodeDefinition + */ + public function enumNode($name) + { + return $this->node($name, 'enum'); + } + + /** + * Creates a child variable node. + * + * @param string $name The name of the node + * + * @return VariableNodeDefinition The builder of the child node + */ + public function variableNode($name) + { + return $this->node($name, 'variable'); + } + + /** + * Returns the parent node. + * + * @return NodeDefinition&ParentNodeDefinitionInterface The parent node + */ + public function end() + { + return $this->parent; + } + + /** + * Creates a child node. + * + * @param string|null $name The name of the node + * @param string $type The type of the node + * + * @return NodeDefinition The child node + * + * @throws \RuntimeException When the node type is not registered + * @throws \RuntimeException When the node class is not found + */ + public function node($name, $type) + { + $class = $this->getNodeClass($type); + + $node = new $class($name); + + $this->append($node); + + return $node; + } + + /** + * Appends a node definition. + * + * Usage: + * + * $node = new ArrayNodeDefinition('name') + * ->children() + * ->scalarNode('foo')->end() + * ->scalarNode('baz')->end() + * ->append($this->getBarNodeDefinition()) + * ->end() + * ; + * + * @return $this + */ + public function append(NodeDefinition $node) + { + if ($node instanceof ParentNodeDefinitionInterface) { + $builder = clone $this; + $builder->setParent(null); + $node->setBuilder($builder); + } + + if (null !== $this->parent) { + $this->parent->append($node); + // Make this builder the node parent to allow for a fluid interface + $node->setParent($this); + } + + return $this; + } + + /** + * Adds or overrides a node Type. + * + * @param string $type The name of the type + * @param string $class The fully qualified name the node definition class + * + * @return $this + */ + public function setNodeClass($type, $class) + { + $this->nodeMapping[strtolower($type)] = $class; + + return $this; + } + + /** + * Returns the class name of the node definition. + * + * @param string $type The node type + * + * @return string The node definition class name + * + * @throws \RuntimeException When the node type is not registered + * @throws \RuntimeException When the node class is not found + */ + protected function getNodeClass($type) + { + $type = strtolower($type); + + if (!isset($this->nodeMapping[$type])) { + throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type)); + } + + $class = $this->nodeMapping[$type]; + + if (!class_exists($class)) { + throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class)); + } + + return $class; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeDefinition.php new file mode 100644 index 00000000..cc245d74 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeDefinition.php @@ -0,0 +1,353 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +use Symfony\Component\Config\Definition\NodeInterface; + +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +abstract class NodeDefinition implements NodeParentInterface +{ + protected $name; + protected $normalization; + protected $validation; + protected $defaultValue; + protected $default = false; + protected $required = false; + protected $deprecationMessage = null; + protected $merge; + protected $allowEmptyValue = true; + protected $nullEquivalent; + protected $trueEquivalent = true; + protected $falseEquivalent = false; + protected $parent; + protected $attributes = []; + + /** + * @param string|null $name The name of the node + * @param NodeParentInterface|null $parent The parent + */ + public function __construct($name, NodeParentInterface $parent = null) + { + $this->parent = $parent; + $this->name = $name; + } + + /** + * Sets the parent node. + * + * @return $this + */ + public function setParent(NodeParentInterface $parent) + { + $this->parent = $parent; + + return $this; + } + + /** + * Sets info message. + * + * @param string $info The info text + * + * @return $this + */ + public function info($info) + { + return $this->attribute('info', $info); + } + + /** + * Sets example configuration. + * + * @param string|array $example + * + * @return $this + */ + public function example($example) + { + return $this->attribute('example', $example); + } + + /** + * Sets an attribute on the node. + * + * @param string $key + * @param mixed $value + * + * @return $this + */ + public function attribute($key, $value) + { + $this->attributes[$key] = $value; + + return $this; + } + + /** + * Returns the parent node. + * + * @return NodeParentInterface|NodeBuilder|NodeDefinition|ArrayNodeDefinition|VariableNodeDefinition|null The builder of the parent node + */ + public function end() + { + return $this->parent; + } + + /** + * Creates the node. + * + * @param bool $forceRootNode Whether to force this node as the root node + * + * @return NodeInterface + */ + public function getNode($forceRootNode = false) + { + if ($forceRootNode) { + $this->parent = null; + } + + if (null !== $this->normalization) { + $this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before); + } + + if (null !== $this->validation) { + $this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules); + } + + $node = $this->createNode(); + $node->setAttributes($this->attributes); + + return $node; + } + + /** + * Sets the default value. + * + * @param mixed $value The default value + * + * @return $this + */ + public function defaultValue($value) + { + $this->default = true; + $this->defaultValue = $value; + + return $this; + } + + /** + * Sets the node as required. + * + * @return $this + */ + public function isRequired() + { + $this->required = true; + + return $this; + } + + /** + * Sets the node as deprecated. + * + * You can use %node% and %path% placeholders in your message to display, + * respectively, the node name and its complete path. + * + * @param string $message Deprecation message + * + * @return $this + */ + public function setDeprecated($message = 'The child node "%node%" at path "%path%" is deprecated.') + { + $this->deprecationMessage = $message; + + return $this; + } + + /** + * Sets the equivalent value used when the node contains null. + * + * @param mixed $value + * + * @return $this + */ + public function treatNullLike($value) + { + $this->nullEquivalent = $value; + + return $this; + } + + /** + * Sets the equivalent value used when the node contains true. + * + * @param mixed $value + * + * @return $this + */ + public function treatTrueLike($value) + { + $this->trueEquivalent = $value; + + return $this; + } + + /** + * Sets the equivalent value used when the node contains false. + * + * @param mixed $value + * + * @return $this + */ + public function treatFalseLike($value) + { + $this->falseEquivalent = $value; + + return $this; + } + + /** + * Sets null as the default value. + * + * @return $this + */ + public function defaultNull() + { + return $this->defaultValue(null); + } + + /** + * Sets true as the default value. + * + * @return $this + */ + public function defaultTrue() + { + return $this->defaultValue(true); + } + + /** + * Sets false as the default value. + * + * @return $this + */ + public function defaultFalse() + { + return $this->defaultValue(false); + } + + /** + * Sets an expression to run before the normalization. + * + * @return ExprBuilder + */ + public function beforeNormalization() + { + return $this->normalization()->before(); + } + + /** + * Denies the node value being empty. + * + * @return $this + */ + public function cannotBeEmpty() + { + $this->allowEmptyValue = false; + + return $this; + } + + /** + * Sets an expression to run for the validation. + * + * The expression receives the value of the node and must return it. It can + * modify it. + * An exception should be thrown when the node is not valid. + * + * @return ExprBuilder + */ + public function validate() + { + return $this->validation()->rule(); + } + + /** + * Sets whether the node can be overwritten. + * + * @param bool $deny Whether the overwriting is forbidden or not + * + * @return $this + */ + public function cannotBeOverwritten($deny = true) + { + $this->merge()->denyOverwrite($deny); + + return $this; + } + + /** + * Gets the builder for validation rules. + * + * @return ValidationBuilder + */ + protected function validation() + { + if (null === $this->validation) { + $this->validation = new ValidationBuilder($this); + } + + return $this->validation; + } + + /** + * Gets the builder for merging rules. + * + * @return MergeBuilder + */ + protected function merge() + { + if (null === $this->merge) { + $this->merge = new MergeBuilder($this); + } + + return $this->merge; + } + + /** + * Gets the builder for normalization rules. + * + * @return NormalizationBuilder + */ + protected function normalization() + { + if (null === $this->normalization) { + $this->normalization = new NormalizationBuilder($this); + } + + return $this->normalization; + } + + /** + * Instantiate and configure the node according to this definition. + * + * @return NodeInterface The node instance + * + * @throws InvalidDefinitionException When the definition is invalid + */ + abstract protected function createNode(); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeParentInterface.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeParentInterface.php new file mode 100644 index 00000000..305e9931 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NodeParentInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * An interface that must be implemented by all node parents. + * + * @author Victor Berchet + */ +interface NodeParentInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php new file mode 100644 index 00000000..d3cdca90 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NormalizationBuilder.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * This class builds normalization conditions. + * + * @author Johannes M. Schmitt + */ +class NormalizationBuilder +{ + protected $node; + public $before = []; + public $remappings = []; + + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + + /** + * Registers a key to remap to its plural form. + * + * @param string $key The key to remap + * @param string $plural The plural of the key in case of irregular plural + * + * @return $this + */ + public function remap($key, $plural = null) + { + $this->remappings[] = [$key, null === $plural ? $key.'s' : $plural]; + + return $this; + } + + /** + * Registers a closure to run before the normalization or an expression builder to build it if null is provided. + * + * @return ExprBuilder|$this + */ + public function before(\Closure $closure = null) + { + if (null !== $closure) { + $this->before[] = $closure; + + return $this; + } + + return $this->before[] = new ExprBuilder($this->node); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php new file mode 100644 index 00000000..390b1136 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/NumericNodeDefinition.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; + +/** + * Abstract class that contains common code of integer and float node definitions. + * + * @author David Jeanmonod + */ +abstract class NumericNodeDefinition extends ScalarNodeDefinition +{ + protected $min; + protected $max; + + /** + * Ensures that the value is smaller than the given reference. + * + * @param mixed $max + * + * @return $this + * + * @throws \InvalidArgumentException when the constraint is inconsistent + */ + public function max($max) + { + if (isset($this->min) && $this->min > $max) { + throw new \InvalidArgumentException(sprintf('You cannot define a max(%s) as you already have a min(%s).', $max, $this->min)); + } + $this->max = $max; + + return $this; + } + + /** + * Ensures that the value is bigger than the given reference. + * + * @param mixed $min + * + * @return $this + * + * @throws \InvalidArgumentException when the constraint is inconsistent + */ + public function min($min) + { + if (isset($this->max) && $this->max < $min) { + throw new \InvalidArgumentException(sprintf('You cannot define a min(%s) as you already have a max(%s).', $min, $this->max)); + } + $this->min = $min; + + return $this; + } + + /** + * {@inheritdoc} + * + * @throws InvalidDefinitionException + */ + public function cannotBeEmpty() + { + throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to NumericNodeDefinition.'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php new file mode 100644 index 00000000..1bf2ad4b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ParentNodeDefinitionInterface.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * An interface that must be implemented by nodes which can have children. + * + * @author Victor Berchet + */ +interface ParentNodeDefinitionInterface +{ + /** + * Returns a builder to add children nodes. + * + * @return NodeBuilder + */ + public function children(); + + /** + * Appends a node definition. + * + * Usage: + * + * $node = $parentNode + * ->children() + * ->scalarNode('foo')->end() + * ->scalarNode('baz')->end() + * ->append($this->getBarNodeDefinition()) + * ->end() + * ; + * + * @return $this + */ + public function append(NodeDefinition $node); + + /** + * Sets a custom children builder. + */ + public function setBuilder(NodeBuilder $builder); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php new file mode 100644 index 00000000..6170555c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ScalarNodeDefinition.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\ScalarNode; + +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +class ScalarNodeDefinition extends VariableNodeDefinition +{ + /** + * Instantiate a Node. + * + * @return ScalarNode The node + */ + protected function instantiateNode() + { + return new ScalarNode($this->name, $this->parent); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/TreeBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/TreeBuilder.php new file mode 100644 index 00000000..384477c5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/TreeBuilder.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\NodeInterface; + +/** + * This is the entry class for building a config tree. + * + * @author Johannes M. Schmitt + */ +class TreeBuilder implements NodeParentInterface +{ + protected $tree; + protected $root; + + /** + * @deprecated since 3.4. To be removed in 4.0 + */ + protected $builder; + + /** + * Creates the root node. + * + * @param string $name The name of the root node + * @param string $type The type of the root node + * @param NodeBuilder $builder A custom node builder instance + * + * @return ArrayNodeDefinition|NodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array') + * + * @throws \RuntimeException When the node type is not supported + */ + public function root($name, $type = 'array', NodeBuilder $builder = null) + { + $builder = $builder ?: new NodeBuilder(); + + return $this->root = $builder->node($name, $type)->setParent($this); + } + + /** + * Builds the tree. + * + * @return NodeInterface + * + * @throws \RuntimeException + */ + public function buildTree() + { + if (null === $this->root) { + throw new \RuntimeException('The configuration tree has no root node.'); + } + if (null !== $this->tree) { + return $this->tree; + } + + return $this->tree = $this->root->getNode(true); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ValidationBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ValidationBuilder.php new file mode 100644 index 00000000..4efc726c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/ValidationBuilder.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +/** + * This class builds validation conditions. + * + * @author Christophe Coevoet + */ +class ValidationBuilder +{ + protected $node; + public $rules = []; + + public function __construct(NodeDefinition $node) + { + $this->node = $node; + } + + /** + * Registers a closure to run as normalization or an expression builder to build it if null is provided. + * + * @return ExprBuilder|$this + */ + public function rule(\Closure $closure = null) + { + if (null !== $closure) { + $this->rules[] = $closure; + + return $this; + } + + return $this->rules[] = new ExprBuilder($this->node); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php new file mode 100644 index 00000000..26565e17 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Builder/VariableNodeDefinition.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Builder; + +use Symfony\Component\Config\Definition\VariableNode; + +/** + * This class provides a fluent interface for defining a node. + * + * @author Johannes M. Schmitt + */ +class VariableNodeDefinition extends NodeDefinition +{ + /** + * Instantiate a Node. + * + * @return VariableNode The node + */ + protected function instantiateNode() + { + return new VariableNode($this->name, $this->parent); + } + + /** + * {@inheritdoc} + */ + protected function createNode() + { + $node = $this->instantiateNode(); + + if (null !== $this->normalization) { + $node->setNormalizationClosures($this->normalization->before); + } + + if (null !== $this->merge) { + $node->setAllowOverwrite($this->merge->allowOverwrite); + } + + if (true === $this->default) { + $node->setDefaultValue($this->defaultValue); + } + + $node->setAllowEmptyValue($this->allowEmptyValue); + $node->addEquivalentValue(null, $this->nullEquivalent); + $node->addEquivalentValue(true, $this->trueEquivalent); + $node->addEquivalentValue(false, $this->falseEquivalent); + $node->setRequired($this->required); + $node->setDeprecated($this->deprecationMessage); + + if (null !== $this->validation) { + $node->setFinalValidationClosures($this->validation->rules); + } + + return $node; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/ConfigurationInterface.php b/modules/empikmarketplace/vendor/symfony/config/Definition/ConfigurationInterface.php new file mode 100644 index 00000000..d6456edb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/ConfigurationInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +/** + * Configuration interface. + * + * @author Victor Berchet + */ +interface ConfigurationInterface +{ + /** + * Generates the configuration tree builder. + * + * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder + */ + public function getConfigTreeBuilder(); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php new file mode 100644 index 00000000..7f863990 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Dumper/XmlReferenceDumper.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Dumper; + +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\EnumNode; +use Symfony\Component\Config\Definition\NodeInterface; +use Symfony\Component\Config\Definition\PrototypedArrayNode; + +/** + * Dumps a XML reference configuration for the given configuration/node instance. + * + * @author Wouter J + */ +class XmlReferenceDumper +{ + private $reference; + + public function dump(ConfigurationInterface $configuration, $namespace = null) + { + return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree(), $namespace); + } + + public function dumpNode(NodeInterface $node, $namespace = null) + { + $this->reference = ''; + $this->writeNode($node, 0, true, $namespace); + $ref = $this->reference; + $this->reference = null; + + return $ref; + } + + /** + * @param int $depth + * @param bool $root If the node is the root node + * @param string $namespace The namespace of the node + */ + private function writeNode(NodeInterface $node, $depth = 0, $root = false, $namespace = null) + { + $rootName = ($root ? 'config' : $node->getName()); + $rootNamespace = ($namespace ?: ($root ? 'http://example.org/schema/dic/'.$node->getName() : null)); + + // xml remapping + if ($node->getParent()) { + $remapping = array_filter($node->getParent()->getXmlRemappings(), function ($mapping) use ($rootName) { + return $rootName === $mapping[1]; + }); + + if (\count($remapping)) { + list($singular) = current($remapping); + $rootName = $singular; + } + } + $rootName = str_replace('_', '-', $rootName); + + $rootAttributes = []; + $rootAttributeComments = []; + $rootChildren = []; + $rootComments = []; + + if ($node instanceof ArrayNode) { + $children = $node->getChildren(); + + // comments about the root node + if ($rootInfo = $node->getInfo()) { + $rootComments[] = $rootInfo; + } + + if ($rootNamespace) { + $rootComments[] = 'Namespace: '.$rootNamespace; + } + + // render prototyped nodes + if ($node instanceof PrototypedArrayNode) { + $prototype = $node->getPrototype(); + + $info = 'prototype'; + if (null !== $prototype->getInfo()) { + $info .= ': '.$prototype->getInfo(); + } + array_unshift($rootComments, $info); + + if ($key = $node->getKeyAttribute()) { + $rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key; + } + + if ($prototype instanceof PrototypedArrayNode) { + $prototype->setName($key); + $children = [$key => $prototype]; + } elseif ($prototype instanceof ArrayNode) { + $children = $prototype->getChildren(); + } else { + if ($prototype->hasDefaultValue()) { + $prototypeValue = $prototype->getDefaultValue(); + } else { + switch (\get_class($prototype)) { + case 'Symfony\Component\Config\Definition\ScalarNode': + $prototypeValue = 'scalar value'; + break; + + case 'Symfony\Component\Config\Definition\FloatNode': + case 'Symfony\Component\Config\Definition\IntegerNode': + $prototypeValue = 'numeric value'; + break; + + case 'Symfony\Component\Config\Definition\BooleanNode': + $prototypeValue = 'true|false'; + break; + + case 'Symfony\Component\Config\Definition\EnumNode': + $prototypeValue = implode('|', array_map('json_encode', $prototype->getValues())); + break; + + default: + $prototypeValue = 'value'; + } + } + } + } + + // get attributes and elements + foreach ($children as $child) { + if (!$child instanceof ArrayNode) { + // get attributes + + // metadata + $name = str_replace('_', '-', $child->getName()); + $value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world + + // comments + $comments = []; + if ($info = $child->getInfo()) { + $comments[] = $info; + } + + if ($example = $child->getExample()) { + $comments[] = 'Example: '.$example; + } + + if ($child->isRequired()) { + $comments[] = 'Required'; + } + + if ($child->isDeprecated()) { + $comments[] = sprintf('Deprecated (%s)', $child->getDeprecationMessage($child->getName(), $node->getPath())); + } + + if ($child instanceof EnumNode) { + $comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues())); + } + + if (\count($comments)) { + $rootAttributeComments[$name] = implode(";\n", $comments); + } + + // default values + if ($child->hasDefaultValue()) { + $value = $child->getDefaultValue(); + } + + // append attribute + $rootAttributes[$name] = $value; + } else { + // get elements + $rootChildren[] = $child; + } + } + } + + // render comments + + // root node comment + if (\count($rootComments)) { + foreach ($rootComments as $comment) { + $this->writeLine('', $depth); + } + } + + // attribute comments + if (\count($rootAttributeComments)) { + foreach ($rootAttributeComments as $attrName => $comment) { + $commentDepth = $depth + 4 + \strlen($attrName) + 2; + $commentLines = explode("\n", $comment); + $multiline = (\count($commentLines) > 1); + $comment = implode(\PHP_EOL.str_repeat(' ', $commentDepth), $commentLines); + + if ($multiline) { + $this->writeLine('', $depth); + } else { + $this->writeLine('', $depth); + } + } + } + + // render start tag + attributes + $rootIsVariablePrototype = isset($prototypeValue); + $rootIsEmptyTag = (0 === \count($rootChildren) && !$rootIsVariablePrototype); + $rootOpenTag = '<'.$rootName; + if (1 >= ($attributesCount = \count($rootAttributes))) { + if (1 === $attributesCount) { + $rootOpenTag .= sprintf(' %s="%s"', current(array_keys($rootAttributes)), $this->writeValue(current($rootAttributes))); + } + + $rootOpenTag .= $rootIsEmptyTag ? ' />' : '>'; + + if ($rootIsVariablePrototype) { + $rootOpenTag .= $prototypeValue.''; + } + + $this->writeLine($rootOpenTag, $depth); + } else { + $this->writeLine($rootOpenTag, $depth); + + $i = 1; + + foreach ($rootAttributes as $attrName => $attrValue) { + $attr = sprintf('%s="%s"', $attrName, $this->writeValue($attrValue)); + + $this->writeLine($attr, $depth + 4); + + if ($attributesCount === $i++) { + $this->writeLine($rootIsEmptyTag ? '/>' : '>', $depth); + + if ($rootIsVariablePrototype) { + $rootOpenTag .= $prototypeValue.''; + } + } + } + } + + // render children tags + foreach ($rootChildren as $child) { + $this->writeLine(''); + $this->writeNode($child, $depth + 4); + } + + // render end tag + if (!$rootIsEmptyTag && !$rootIsVariablePrototype) { + $this->writeLine(''); + + $rootEndTag = ''; + $this->writeLine($rootEndTag, $depth); + } + } + + /** + * Outputs a single config reference line. + * + * @param string $text + * @param int $indent + */ + private function writeLine($text, $indent = 0) + { + $indent = \strlen($text) + $indent; + $format = '%'.$indent.'s'; + + $this->reference .= sprintf($format, $text).\PHP_EOL; + } + + /** + * Renders the string conversion of the value. + * + * @param mixed $value + * + * @return string + */ + private function writeValue($value) + { + if ('%%%%not_defined%%%%' === $value) { + return ''; + } + + if (\is_string($value) || is_numeric($value)) { + return $value; + } + + if (false === $value) { + return 'false'; + } + + if (true === $value) { + return 'true'; + } + + if (null === $value) { + return 'null'; + } + + if (empty($value)) { + return ''; + } + + if (\is_array($value)) { + return implode(',', $value); + } + + return ''; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php new file mode 100644 index 00000000..ba355394 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Dumper/YamlReferenceDumper.php @@ -0,0 +1,252 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Dumper; + +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\EnumNode; +use Symfony\Component\Config\Definition\NodeInterface; +use Symfony\Component\Config\Definition\PrototypedArrayNode; +use Symfony\Component\Config\Definition\ScalarNode; +use Symfony\Component\Yaml\Inline; + +/** + * Dumps a Yaml reference configuration for the given configuration/node instance. + * + * @author Kevin Bond + */ +class YamlReferenceDumper +{ + private $reference; + + public function dump(ConfigurationInterface $configuration) + { + return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree()); + } + + public function dumpAtPath(ConfigurationInterface $configuration, $path) + { + $rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree(); + + foreach (explode('.', $path) as $step) { + if (!$node instanceof ArrayNode) { + throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path)); + } + + /** @var NodeInterface[] $children */ + $children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren(); + + foreach ($children as $child) { + if ($child->getName() === $step) { + $node = $child; + + continue 2; + } + } + + throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s".', $rootNode->getName(), $path)); + } + + return $this->dumpNode($node); + } + + public function dumpNode(NodeInterface $node) + { + $this->reference = ''; + $this->writeNode($node); + $ref = $this->reference; + $this->reference = null; + + return $ref; + } + + /** + * @param int $depth + * @param bool $prototypedArray + */ + private function writeNode(NodeInterface $node, NodeInterface $parentNode = null, $depth = 0, $prototypedArray = false) + { + $comments = []; + $default = ''; + $defaultArray = null; + $children = null; + $example = $node->getExample(); + + // defaults + if ($node instanceof ArrayNode) { + $children = $node->getChildren(); + + if ($node instanceof PrototypedArrayNode) { + $children = $this->getPrototypeChildren($node); + } + + if (!$children) { + if ($node->hasDefaultValue() && \count($defaultArray = $node->getDefaultValue())) { + $default = ''; + } elseif (!\is_array($example)) { + $default = '[]'; + } + } + } elseif ($node instanceof EnumNode) { + $comments[] = 'One of '.implode('; ', array_map('json_encode', $node->getValues())); + $default = $node->hasDefaultValue() ? Inline::dump($node->getDefaultValue()) : '~'; + } else { + $default = '~'; + + if ($node->hasDefaultValue()) { + $default = $node->getDefaultValue(); + + if (\is_array($default)) { + if (\count($defaultArray = $node->getDefaultValue())) { + $default = ''; + } elseif (!\is_array($example)) { + $default = '[]'; + } + } else { + $default = Inline::dump($default); + } + } + } + + // required? + if ($node->isRequired()) { + $comments[] = 'Required'; + } + + // deprecated? + if ($node->isDeprecated()) { + $comments[] = sprintf('Deprecated (%s)', $node->getDeprecationMessage($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath())); + } + + // example + if ($example && !\is_array($example)) { + $comments[] = 'Example: '.$example; + } + + $default = '' != (string) $default ? ' '.$default : ''; + $comments = \count($comments) ? '# '.implode(', ', $comments) : ''; + + $key = $prototypedArray ? '-' : $node->getName().':'; + $text = rtrim(sprintf('%-21s%s %s', $key, $default, $comments), ' '); + + if ($info = $node->getInfo()) { + $this->writeLine(''); + // indenting multi-line info + $info = str_replace("\n", sprintf("\n%".($depth * 4).'s# ', ' '), $info); + $this->writeLine('# '.$info, $depth * 4); + } + + $this->writeLine($text, $depth * 4); + + // output defaults + if ($defaultArray) { + $this->writeLine(''); + + $message = \count($defaultArray) > 1 ? 'Defaults' : 'Default'; + + $this->writeLine('# '.$message.':', $depth * 4 + 4); + + $this->writeArray($defaultArray, $depth + 1); + } + + if (\is_array($example)) { + $this->writeLine(''); + + $message = \count($example) > 1 ? 'Examples' : 'Example'; + + $this->writeLine('# '.$message.':', $depth * 4 + 4); + + $this->writeArray($example, $depth + 1); + } + + if ($children) { + foreach ($children as $childNode) { + $this->writeNode($childNode, $node, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute()); + } + } + } + + /** + * Outputs a single config reference line. + * + * @param string $text + * @param int $indent + */ + private function writeLine($text, $indent = 0) + { + $indent = \strlen($text) + $indent; + $format = '%'.$indent.'s'; + + $this->reference .= sprintf($format, $text)."\n"; + } + + private function writeArray(array $array, $depth) + { + $isIndexed = array_values($array) === $array; + + foreach ($array as $key => $value) { + if (\is_array($value)) { + $val = ''; + } else { + $val = $value; + } + + if ($isIndexed) { + $this->writeLine('- '.$val, $depth * 4); + } else { + $this->writeLine(sprintf('%-20s %s', $key.':', $val), $depth * 4); + } + + if (\is_array($value)) { + $this->writeArray($value, $depth + 1); + } + } + } + + /** + * @return array + */ + private function getPrototypeChildren(PrototypedArrayNode $node) + { + $prototype = $node->getPrototype(); + $key = $node->getKeyAttribute(); + + // Do not expand prototype if it isn't an array node nor uses attribute as key + if (!$key && !$prototype instanceof ArrayNode) { + return $node->getChildren(); + } + + if ($prototype instanceof ArrayNode) { + $keyNode = new ArrayNode($key, $node); + $children = $prototype->getChildren(); + + if ($prototype instanceof PrototypedArrayNode && $prototype->getKeyAttribute()) { + $children = $this->getPrototypeChildren($prototype); + } + + // add children + foreach ($children as $childNode) { + $keyNode->addChild($childNode); + } + } else { + $keyNode = new ScalarNode($key, $node); + } + + $info = 'Prototype'; + if (null !== $prototype->getInfo()) { + $info .= ': '.$prototype->getInfo(); + } + $keyNode->setInfo($info); + + return [$key => $keyNode]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/EnumNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/EnumNode.php new file mode 100644 index 00000000..15c8db3e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/EnumNode.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; + +/** + * Node which only allows a finite set of values. + * + * @author Johannes M. Schmitt + */ +class EnumNode extends ScalarNode +{ + private $values; + + public function __construct($name, NodeInterface $parent = null, array $values = []) + { + $values = array_unique($values); + if (empty($values)) { + throw new \InvalidArgumentException('$values must contain at least one element.'); + } + + parent::__construct($name, $parent); + $this->values = $values; + } + + public function getValues() + { + return $this->values; + } + + protected function finalizeValue($value) + { + $value = parent::finalizeValue($value); + + if (!\in_array($value, $this->values, true)) { + $ex = new InvalidConfigurationException(sprintf('The value %s is not allowed for path "%s". Permissible values: %s', json_encode($value), $this->getPath(), implode(', ', array_map('json_encode', $this->values)))); + $ex->setPath($this->getPath()); + + throw $ex; + } + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php new file mode 100644 index 00000000..48dd9325 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/DuplicateKeyException.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * This exception is thrown whenever the key of an array is not unique. This can + * only be the case if the configuration is coming from an XML file. + * + * @author Johannes M. Schmitt + */ +class DuplicateKeyException extends InvalidConfigurationException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/Exception.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/Exception.php new file mode 100644 index 00000000..8933a492 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/Exception.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * Base exception for all configuration exceptions. + * + * @author Johannes M. Schmitt + */ +class Exception extends \RuntimeException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php new file mode 100644 index 00000000..726c07fb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/ForbiddenOverwriteException.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * This exception is thrown when a configuration path is overwritten from a + * subsequent configuration file, but the entry node specifically forbids this. + * + * @author Johannes M. Schmitt + */ +class ForbiddenOverwriteException extends InvalidConfigurationException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php new file mode 100644 index 00000000..3dbc57b1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidConfigurationException.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * A very general exception which can be thrown whenever non of the more specific + * exceptions is suitable. + * + * @author Johannes M. Schmitt + */ +class InvalidConfigurationException extends Exception +{ + private $path; + private $containsHints = false; + + public function setPath($path) + { + $this->path = $path; + } + + public function getPath() + { + return $this->path; + } + + /** + * Adds extra information that is suffixed to the original exception message. + * + * @param string $hint + */ + public function addHint($hint) + { + if (!$this->containsHints) { + $this->message .= "\nHint: ".$hint; + $this->containsHints = true; + } else { + $this->message .= ', '.$hint; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php new file mode 100644 index 00000000..98310dae --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidDefinitionException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * Thrown when an error is detected in a node Definition. + * + * @author Victor Berchet + */ +class InvalidDefinitionException extends Exception +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidTypeException.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidTypeException.php new file mode 100644 index 00000000..d7ca8c9d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/InvalidTypeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * This exception is thrown if an invalid type is encountered. + * + * @author Johannes M. Schmitt + */ +class InvalidTypeException extends InvalidConfigurationException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/UnsetKeyException.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/UnsetKeyException.php new file mode 100644 index 00000000..863181a3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Exception/UnsetKeyException.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition\Exception; + +/** + * This exception is usually not encountered by the end-user, but only used + * internally to signal the parent scope to unset a key. + * + * @author Johannes M. Schmitt + */ +class UnsetKeyException extends Exception +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/FloatNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/FloatNode.php new file mode 100644 index 00000000..9eb87899 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/FloatNode.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * This node represents a float value in the config tree. + * + * @author Jeanmonod David + */ +class FloatNode extends NumericNode +{ + /** + * {@inheritdoc} + */ + protected function validateType($value) + { + // Integers are also accepted, we just cast them + if (\is_int($value)) { + $value = (float) $value; + } + + if (!\is_float($value)) { + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected float, but got %s.', $this->getPath(), \gettype($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + + throw $ex; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/IntegerNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/IntegerNode.php new file mode 100644 index 00000000..8ec068a8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/IntegerNode.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * This node represents an integer value in the config tree. + * + * @author Jeanmonod David + */ +class IntegerNode extends NumericNode +{ + /** + * {@inheritdoc} + */ + protected function validateType($value) + { + if (!\is_int($value)) { + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected int, but got %s.', $this->getPath(), \gettype($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + + throw $ex; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/NodeInterface.php b/modules/empikmarketplace/vendor/symfony/config/Definition/NodeInterface.php new file mode 100644 index 00000000..45f1f681 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/NodeInterface.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * Common Interface among all nodes. + * + * In most cases, it is better to inherit from BaseNode instead of implementing + * this interface yourself. + * + * @author Johannes M. Schmitt + */ +interface NodeInterface +{ + /** + * Returns the name of the node. + * + * @return string The name of the node + */ + public function getName(); + + /** + * Returns the path of the node. + * + * @return string The node path + */ + public function getPath(); + + /** + * Returns true when the node is required. + * + * @return bool If the node is required + */ + public function isRequired(); + + /** + * Returns true when the node has a default value. + * + * @return bool If the node has a default value + */ + public function hasDefaultValue(); + + /** + * Returns the default value of the node. + * + * @return mixed The default value + * + * @throws \RuntimeException if the node has no default value + */ + public function getDefaultValue(); + + /** + * Normalizes a value. + * + * @param mixed $value The value to normalize + * + * @return mixed The normalized value + * + * @throws InvalidTypeException if the value type is invalid + */ + public function normalize($value); + + /** + * Merges two values together. + * + * @param mixed $leftSide + * @param mixed $rightSide + * + * @return mixed The merged value + * + * @throws ForbiddenOverwriteException if the configuration path cannot be overwritten + * @throws InvalidTypeException if the value type is invalid + */ + public function merge($leftSide, $rightSide); + + /** + * Finalizes a value. + * + * @param mixed $value The value to finalize + * + * @return mixed The finalized value + * + * @throws InvalidTypeException if the value type is invalid + * @throws InvalidConfigurationException if the value is invalid configuration + */ + public function finalize($value); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/NumericNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/NumericNode.php new file mode 100644 index 00000000..439935e4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/NumericNode.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; + +/** + * This node represents a numeric value in the config tree. + * + * @author David Jeanmonod + */ +class NumericNode extends ScalarNode +{ + protected $min; + protected $max; + + public function __construct($name, NodeInterface $parent = null, $min = null, $max = null) + { + parent::__construct($name, $parent); + $this->min = $min; + $this->max = $max; + } + + /** + * {@inheritdoc} + */ + protected function finalizeValue($value) + { + $value = parent::finalizeValue($value); + + $errorMsg = null; + if (isset($this->min) && $value < $this->min) { + $errorMsg = sprintf('The value %s is too small for path "%s". Should be greater than or equal to %s', $value, $this->getPath(), $this->min); + } + if (isset($this->max) && $value > $this->max) { + $errorMsg = sprintf('The value %s is too big for path "%s". Should be less than or equal to %s', $value, $this->getPath(), $this->max); + } + if (isset($errorMsg)) { + $ex = new InvalidConfigurationException($errorMsg); + $ex->setPath($this->getPath()); + throw $ex; + } + + return $value; + } + + /** + * {@inheritdoc} + */ + protected function isValueEmpty($value) + { + // a numeric value cannot be empty + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/Processor.php b/modules/empikmarketplace/vendor/symfony/config/Definition/Processor.php new file mode 100644 index 00000000..0a935eeb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/Processor.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +/** + * This class is the entry point for config normalization/merging/finalization. + * + * @author Johannes M. Schmitt + */ +class Processor +{ + /** + * Processes an array of configurations. + * + * @param NodeInterface $configTree The node tree describing the configuration + * @param array $configs An array of configuration items to process + * + * @return array The processed configuration + */ + public function process(NodeInterface $configTree, array $configs) + { + $currentConfig = []; + foreach ($configs as $config) { + $config = $configTree->normalize($config); + $currentConfig = $configTree->merge($currentConfig, $config); + } + + return $configTree->finalize($currentConfig); + } + + /** + * Processes an array of configurations. + * + * @param ConfigurationInterface $configuration The configuration class + * @param array $configs An array of configuration items to process + * + * @return array The processed configuration + */ + public function processConfiguration(ConfigurationInterface $configuration, array $configs) + { + return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs); + } + + /** + * Normalizes a configuration entry. + * + * This method returns a normalize configuration array for a given key + * to remove the differences due to the original format (YAML and XML mainly). + * + * Here is an example. + * + * The configuration in XML: + * + * twig.extension.foo + * twig.extension.bar + * + * And the same configuration in YAML: + * + * extensions: ['twig.extension.foo', 'twig.extension.bar'] + * + * @param array $config A config array + * @param string $key The key to normalize + * @param string $plural The plural form of the key if it is irregular + * + * @return array + */ + public static function normalizeConfig($config, $key, $plural = null) + { + if (null === $plural) { + $plural = $key.'s'; + } + + if (isset($config[$plural])) { + return $config[$plural]; + } + + if (isset($config[$key])) { + if (\is_string($config[$key]) || !\is_int(key($config[$key]))) { + // only one + return [$config[$key]]; + } + + return $config[$key]; + } + + return []; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/PrototypeNodeInterface.php b/modules/empikmarketplace/vendor/symfony/config/Definition/PrototypeNodeInterface.php new file mode 100644 index 00000000..8bbb84d4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/PrototypeNodeInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +/** + * This interface must be implemented by nodes which can be used as prototypes. + * + * @author Johannes M. Schmitt + */ +interface PrototypeNodeInterface extends NodeInterface +{ + /** + * Sets the name of the node. + * + * @param string $name The name of the node + */ + public function setName($name); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/PrototypedArrayNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/PrototypedArrayNode.php new file mode 100644 index 00000000..d18a109a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/PrototypedArrayNode.php @@ -0,0 +1,377 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\DuplicateKeyException; +use Symfony\Component\Config\Definition\Exception\Exception; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\Config\Definition\Exception\UnsetKeyException; + +/** + * Represents a prototyped Array node in the config tree. + * + * @author Johannes M. Schmitt + */ +class PrototypedArrayNode extends ArrayNode +{ + protected $prototype; + protected $keyAttribute; + protected $removeKeyAttribute = false; + protected $minNumberOfElements = 0; + protected $defaultValue = []; + protected $defaultChildren; + /** + * @var NodeInterface[] An array of the prototypes of the simplified value children + */ + private $valuePrototypes = []; + + /** + * Sets the minimum number of elements that a prototype based node must + * contain. By default this is zero, meaning no elements. + * + * @param int $number + */ + public function setMinNumberOfElements($number) + { + $this->minNumberOfElements = $number; + } + + /** + * Sets the attribute which value is to be used as key. + * + * This is useful when you have an indexed array that should be an + * associative array. You can select an item from within the array + * to be the key of the particular item. For example, if "id" is the + * "key", then: + * + * [ + * ['id' => 'my_name', 'foo' => 'bar'], + * ]; + * + * becomes + * + * [ + * 'my_name' => ['foo' => 'bar'], + * ]; + * + * If you'd like "'id' => 'my_name'" to still be present in the resulting + * array, then you can set the second argument of this method to false. + * + * @param string $attribute The name of the attribute which value is to be used as a key + * @param bool $remove Whether or not to remove the key + */ + public function setKeyAttribute($attribute, $remove = true) + { + $this->keyAttribute = $attribute; + $this->removeKeyAttribute = $remove; + } + + /** + * Retrieves the name of the attribute which value should be used as key. + * + * @return string|null The name of the attribute + */ + public function getKeyAttribute() + { + return $this->keyAttribute; + } + + /** + * Sets the default value of this node. + * + * @param string $value + * + * @throws \InvalidArgumentException if the default value is not an array + */ + public function setDefaultValue($value) + { + if (!\is_array($value)) { + throw new \InvalidArgumentException($this->getPath().': the default value of an array node has to be an array.'); + } + + $this->defaultValue = $value; + } + + /** + * {@inheritdoc} + */ + public function hasDefaultValue() + { + return true; + } + + /** + * Adds default children when none are set. + * + * @param int|string|array|null $children The number of children|The child name|The children names to be added + */ + public function setAddChildrenIfNoneSet($children = ['defaults']) + { + if (null === $children) { + $this->defaultChildren = ['defaults']; + } else { + $this->defaultChildren = \is_int($children) && $children > 0 ? range(1, $children) : (array) $children; + } + } + + /** + * {@inheritdoc} + * + * The default value could be either explicited or derived from the prototype + * default value. + */ + public function getDefaultValue() + { + if (null !== $this->defaultChildren) { + $default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : []; + $defaults = []; + foreach (array_values($this->defaultChildren) as $i => $name) { + $defaults[null === $this->keyAttribute ? $i : $name] = $default; + } + + return $defaults; + } + + return $this->defaultValue; + } + + /** + * Sets the node prototype. + */ + public function setPrototype(PrototypeNodeInterface $node) + { + $this->prototype = $node; + } + + /** + * Retrieves the prototype. + * + * @return PrototypeNodeInterface The prototype + */ + public function getPrototype() + { + return $this->prototype; + } + + /** + * Disable adding concrete children for prototyped nodes. + * + * @throws Exception + */ + public function addChild(NodeInterface $node) + { + throw new Exception('A prototyped array node can not have concrete children.'); + } + + /** + * Finalizes the value of this node. + * + * @param mixed $value + * + * @return mixed The finalized value + * + * @throws UnsetKeyException + * @throws InvalidConfigurationException if the node doesn't have enough children + */ + protected function finalizeValue($value) + { + if (false === $value) { + throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: "%s".', $this->getPath(), json_encode($value))); + } + + foreach ($value as $k => $v) { + $prototype = $this->getPrototypeForChild($k); + try { + $value[$k] = $prototype->finalize($v); + } catch (UnsetKeyException $e) { + unset($value[$k]); + } + } + + if (\count($value) < $this->minNumberOfElements) { + $ex = new InvalidConfigurationException(sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements)); + $ex->setPath($this->getPath()); + + throw $ex; + } + + return $value; + } + + /** + * Normalizes the value. + * + * @param mixed $value The value to normalize + * + * @return mixed The normalized value + * + * @throws InvalidConfigurationException + * @throws DuplicateKeyException + */ + protected function normalizeValue($value) + { + if (false === $value) { + return $value; + } + + $value = $this->remapXml($value); + + $isAssoc = array_keys($value) !== range(0, \count($value) - 1); + $normalized = []; + foreach ($value as $k => $v) { + if (null !== $this->keyAttribute && \is_array($v)) { + if (!isset($v[$this->keyAttribute]) && \is_int($k) && !$isAssoc) { + $ex = new InvalidConfigurationException(sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath())); + $ex->setPath($this->getPath()); + + throw $ex; + } elseif (isset($v[$this->keyAttribute])) { + $k = $v[$this->keyAttribute]; + + // remove the key attribute when required + if ($this->removeKeyAttribute) { + unset($v[$this->keyAttribute]); + } + + // if only "value" is left + if (array_keys($v) === ['value']) { + $v = $v['value']; + if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && \array_key_exists('value', $children)) { + $valuePrototype = current($this->valuePrototypes) ?: clone $children['value']; + $valuePrototype->parent = $this; + $originalClosures = $this->prototype->normalizationClosures; + if (\is_array($originalClosures)) { + $valuePrototypeClosures = $valuePrototype->normalizationClosures; + $valuePrototype->normalizationClosures = \is_array($valuePrototypeClosures) ? array_merge($originalClosures, $valuePrototypeClosures) : $originalClosures; + } + $this->valuePrototypes[$k] = $valuePrototype; + } + } + } + + if (\array_key_exists($k, $normalized)) { + $ex = new DuplicateKeyException(sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath())); + $ex->setPath($this->getPath()); + + throw $ex; + } + } + + $prototype = $this->getPrototypeForChild($k); + if (null !== $this->keyAttribute || $isAssoc) { + $normalized[$k] = $prototype->normalize($v); + } else { + $normalized[] = $prototype->normalize($v); + } + } + + return $normalized; + } + + /** + * Merges values together. + * + * @param mixed $leftSide The left side to merge + * @param mixed $rightSide The right side to merge + * + * @return mixed The merged values + * + * @throws InvalidConfigurationException + * @throws \RuntimeException + */ + protected function mergeValues($leftSide, $rightSide) + { + if (false === $rightSide) { + // if this is still false after the last config has been merged the + // finalization pass will take care of removing this key entirely + return false; + } + + if (false === $leftSide || !$this->performDeepMerging) { + return $rightSide; + } + + foreach ($rightSide as $k => $v) { + // prototype, and key is irrelevant, append the element + if (null === $this->keyAttribute) { + $leftSide[] = $v; + continue; + } + + // no conflict + if (!\array_key_exists($k, $leftSide)) { + if (!$this->allowNewKeys) { + $ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file.', $this->getPath())); + $ex->setPath($this->getPath()); + + throw $ex; + } + + $leftSide[$k] = $v; + continue; + } + + $prototype = $this->getPrototypeForChild($k); + $leftSide[$k] = $prototype->merge($leftSide[$k], $v); + } + + return $leftSide; + } + + /** + * Returns a prototype for the child node that is associated to $key in the value array. + * For general child nodes, this will be $this->prototype. + * But if $this->removeKeyAttribute is true and there are only two keys in the child node: + * one is same as this->keyAttribute and the other is 'value', then the prototype will be different. + * + * For example, assume $this->keyAttribute is 'name' and the value array is as follows: + * + * [ + * [ + * 'name' => 'name001', + * 'value' => 'value001' + * ] + * ] + * + * Now, the key is 0 and the child node is: + * + * [ + * 'name' => 'name001', + * 'value' => 'value001' + * ] + * + * When normalizing the value array, the 'name' element will removed from the child node + * and its value becomes the new key of the child node: + * + * [ + * 'name001' => ['value' => 'value001'] + * ] + * + * Now only 'value' element is left in the child node which can be further simplified into a string: + * + * ['name001' => 'value001'] + * + * Now, the key becomes 'name001' and the child node becomes 'value001' and + * the prototype of child node 'name001' should be a ScalarNode instead of an ArrayNode instance. + * + * @param string $key The key of the child node + * + * @return mixed The prototype instance + */ + private function getPrototypeForChild($key) + { + $prototype = isset($this->valuePrototypes[$key]) ? $this->valuePrototypes[$key] : $this->prototype; + $prototype->setName($key); + + return $prototype; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/ScalarNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/ScalarNode.php new file mode 100644 index 00000000..53c1ed29 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/ScalarNode.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidTypeException; + +/** + * This node represents a scalar value in the config tree. + * + * The following values are considered scalars: + * * booleans + * * strings + * * null + * * integers + * * floats + * + * @author Johannes M. Schmitt + */ +class ScalarNode extends VariableNode +{ + /** + * {@inheritdoc} + */ + protected function validateType($value) + { + if (!is_scalar($value) && null !== $value) { + $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected scalar, but got %s.', $this->getPath(), \gettype($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + + throw $ex; + } + } + + /** + * {@inheritdoc} + */ + protected function isValueEmpty($value) + { + return null === $value || '' === $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Definition/VariableNode.php b/modules/empikmarketplace/vendor/symfony/config/Definition/VariableNode.php new file mode 100644 index 00000000..1a3442d9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Definition/VariableNode.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Definition; + +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; + +/** + * This node represents a value of variable type in the config tree. + * + * This node is intended for values of arbitrary type. + * Any PHP type is accepted as a value. + * + * @author Jeremy Mikola + */ +class VariableNode extends BaseNode implements PrototypeNodeInterface +{ + protected $defaultValueSet = false; + protected $defaultValue; + protected $allowEmptyValue = true; + + public function setDefaultValue($value) + { + $this->defaultValueSet = true; + $this->defaultValue = $value; + } + + /** + * {@inheritdoc} + */ + public function hasDefaultValue() + { + return $this->defaultValueSet; + } + + /** + * {@inheritdoc} + */ + public function getDefaultValue() + { + $v = $this->defaultValue; + + return $v instanceof \Closure ? $v() : $v; + } + + /** + * Sets if this node is allowed to have an empty value. + * + * @param bool $boolean True if this entity will accept empty values + */ + public function setAllowEmptyValue($boolean) + { + $this->allowEmptyValue = (bool) $boolean; + } + + /** + * {@inheritdoc} + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * {@inheritdoc} + */ + protected function validateType($value) + { + } + + /** + * {@inheritdoc} + */ + protected function finalizeValue($value) + { + if (!$this->allowEmptyValue && $this->isValueEmpty($value)) { + $ex = new InvalidConfigurationException(sprintf('The path "%s" cannot contain an empty value, but got %s.', $this->getPath(), json_encode($value))); + if ($hint = $this->getInfo()) { + $ex->addHint($hint); + } + $ex->setPath($this->getPath()); + + throw $ex; + } + + return $value; + } + + /** + * {@inheritdoc} + */ + protected function normalizeValue($value) + { + return $value; + } + + /** + * {@inheritdoc} + */ + protected function mergeValues($leftSide, $rightSide) + { + return $rightSide; + } + + /** + * Evaluates if the given value is to be treated as empty. + * + * By default, PHP's empty() function is used to test for emptiness. This + * method may be overridden by subtypes to better match their understanding + * of empty data. + * + * @param mixed $value + * + * @return bool + */ + protected function isValueEmpty($value) + { + return empty($value); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/DependencyInjection/ConfigCachePass.php b/modules/empikmarketplace/vendor/symfony/config/DependencyInjection/ConfigCachePass.php new file mode 100644 index 00000000..30df15be --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/DependencyInjection/ConfigCachePass.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\DependencyInjection; + +@trigger_error(sprintf('The %s class is deprecated since Symfony 3.4 and will be removed in 4.0. Use tagged iterator arguments instead.', ConfigCachePass::class), \E_USER_DEPRECATED); + +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Adds services tagged config_cache.resource_checker to the config_cache_factory service, ordering them by priority. + * + * @author Matthias Pigulla + * @author Benjamin Klotz + * + * @deprecated since version 3.4, to be removed in 4.0. Use tagged iterator arguments instead. + */ +class ConfigCachePass implements CompilerPassInterface +{ + use PriorityTaggedServiceTrait; + + private $factoryServiceId; + private $resourceCheckerTag; + + public function __construct($factoryServiceId = 'config_cache_factory', $resourceCheckerTag = 'config_cache.resource_checker') + { + $this->factoryServiceId = $factoryServiceId; + $this->resourceCheckerTag = $resourceCheckerTag; + } + + public function process(ContainerBuilder $container) + { + $resourceCheckers = $this->findAndSortTaggedServices($this->resourceCheckerTag, $container); + + if (empty($resourceCheckers)) { + return; + } + + $container->getDefinition($this->factoryServiceId)->replaceArgument(0, new IteratorArgument($resourceCheckers)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php b/modules/empikmarketplace/vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php new file mode 100644 index 00000000..6a3b01cf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Exception/FileLoaderImportCircularReferenceException.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Exception; + +/** + * Exception class for when a circular reference is detected when importing resources. + * + * @author Fabien Potencier + */ +class FileLoaderImportCircularReferenceException extends FileLoaderLoadException +{ + public function __construct(array $resources, $code = null, $previous = null) + { + $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]); + + \Exception::__construct($message, $code, $previous); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Exception/FileLoaderLoadException.php b/modules/empikmarketplace/vendor/symfony/config/Exception/FileLoaderLoadException.php new file mode 100644 index 00000000..82d90eb3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Exception/FileLoaderLoadException.php @@ -0,0 +1,109 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Exception; + +/** + * Exception class for when a resource cannot be loaded or imported. + * + * @author Ryan Weaver + */ +class FileLoaderLoadException extends \Exception +{ + /** + * @param string $resource The resource that could not be imported + * @param string $sourceResource The original resource importing the new resource + * @param int $code The error code + * @param \Exception $previous A previous exception + * @param string $type The type of resource + */ + public function __construct($resource, $sourceResource = null, $code = null, $previous = null, $type = null) + { + $message = ''; + if ($previous) { + // Include the previous exception, to help the user see what might be the underlying cause + + // Trim the trailing period of the previous message. We only want 1 period remove so no rtrim... + if ('.' === substr($previous->getMessage(), -1)) { + $trimmedMessage = substr($previous->getMessage(), 0, -1); + $message .= sprintf('%s', $trimmedMessage).' in '; + } else { + $message .= sprintf('%s', $previous->getMessage()).' in '; + } + $message .= $resource.' '; + + // show tweaked trace to complete the human readable sentence + if (null === $sourceResource) { + $message .= sprintf('(which is loaded in resource "%s")', $this->varToString($resource)); + } else { + $message .= sprintf('(which is being imported from "%s")', $this->varToString($sourceResource)); + } + $message .= '.'; + + // if there's no previous message, present it the default way + } elseif (null === $sourceResource) { + $message .= sprintf('Cannot load resource "%s".', $this->varToString($resource)); + } else { + $message .= sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource)); + } + + // Is the resource located inside a bundle? + if ('@' === $resource[0]) { + $parts = explode(\DIRECTORY_SEPARATOR, $resource); + $bundle = substr($parts[0], 1); + $message .= sprintf(' Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle); + $message .= sprintf(' If the bundle is registered, make sure the bundle path "%s" is not empty.', $resource); + } elseif (null !== $type) { + // maybe there is no loader for this specific type + if ('annotation' === $type) { + $message .= ' Make sure annotations are installed and enabled.'; + } else { + $message .= sprintf(' Make sure there is a loader supporting the "%s" type.', $type); + } + } + + parent::__construct($message, $code, $previous); + } + + protected function varToString($var) + { + if (\is_object($var)) { + return sprintf('Object(%s)', \get_class($var)); + } + + if (\is_array($var)) { + $a = []; + foreach ($var as $k => $v) { + $a[] = sprintf('%s => %s', $k, $this->varToString($v)); + } + + return sprintf('Array(%s)', implode(', ', $a)); + } + + if (\is_resource($var)) { + return sprintf('Resource(%s)', get_resource_type($var)); + } + + if (null === $var) { + return 'null'; + } + + if (false === $var) { + return 'false'; + } + + if (true === $var) { + return 'true'; + } + + return (string) $var; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php b/modules/empikmarketplace/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php new file mode 100644 index 00000000..648cf0e7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Exception/FileLocatorFileNotFoundException.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Exception; + +/** + * File locator exception if a file does not exist. + * + * @author Leo Feyer + */ +class FileLocatorFileNotFoundException extends \InvalidArgumentException +{ + private $paths; + + public function __construct($message = '', $code = 0, $previous = null, array $paths = []) + { + parent::__construct($message, $code, $previous); + + $this->paths = $paths; + } + + public function getPaths() + { + return $this->paths; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/FileLocator.php b/modules/empikmarketplace/vendor/symfony/config/FileLocator.php new file mode 100644 index 00000000..5f315ba7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/FileLocator.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; + +/** + * FileLocator uses an array of pre-defined paths to find files. + * + * @author Fabien Potencier + */ +class FileLocator implements FileLocatorInterface +{ + protected $paths; + + /** + * @param string|array $paths A path or an array of paths where to look for resources + */ + public function __construct($paths = []) + { + $this->paths = (array) $paths; + } + + /** + * {@inheritdoc} + */ + public function locate($name, $currentPath = null, $first = true) + { + if ('' == $name) { + throw new \InvalidArgumentException('An empty file name is not valid to be located.'); + } + + if ($this->isAbsolutePath($name)) { + if (!file_exists($name)) { + throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist.', $name), 0, null, [$name]); + } + + return $name; + } + + $paths = $this->paths; + + if (null !== $currentPath) { + array_unshift($paths, $currentPath); + } + + $paths = array_unique($paths); + $filepaths = $notfound = []; + + foreach ($paths as $path) { + if (@file_exists($file = $path.\DIRECTORY_SEPARATOR.$name)) { + if (true === $first) { + return $file; + } + $filepaths[] = $file; + } else { + $notfound[] = $file; + } + } + + if (!$filepaths) { + throw new FileLocatorFileNotFoundException(sprintf('The file "%s" does not exist (in: "%s").', $name, implode('", "', $paths)), 0, null, $notfound); + } + + return $filepaths; + } + + /** + * Returns whether the file path is an absolute path. + * + * @param string $file A file path + * + * @return bool + */ + private function isAbsolutePath($file) + { + if ('/' === $file[0] || '\\' === $file[0] + || (\strlen($file) > 3 && ctype_alpha($file[0]) + && ':' === $file[1] + && ('\\' === $file[2] || '/' === $file[2]) + ) + || null !== parse_url($file, \PHP_URL_SCHEME) + ) { + return true; + } + + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/FileLocatorInterface.php b/modules/empikmarketplace/vendor/symfony/config/FileLocatorInterface.php new file mode 100644 index 00000000..cf3c2e59 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/FileLocatorInterface.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; + +/** + * @author Fabien Potencier + */ +interface FileLocatorInterface +{ + /** + * Returns a full path for a given file name. + * + * @param string $name The file name to locate + * @param string|null $currentPath The current path + * @param bool $first Whether to return the first occurrence or an array of filenames + * + * @return string|array The full path to the file or an array of file paths + * + * @throws \InvalidArgumentException If $name is empty + * @throws FileLocatorFileNotFoundException If a file is not found + */ + public function locate($name, $currentPath = null, $first = true); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/LICENSE b/modules/empikmarketplace/vendor/symfony/config/LICENSE new file mode 100644 index 00000000..9e936ec0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2020 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/DelegatingLoader.php b/modules/empikmarketplace/vendor/symfony/config/Loader/DelegatingLoader.php new file mode 100644 index 00000000..452e81c5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/DelegatingLoader.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +use Symfony\Component\Config\Exception\FileLoaderLoadException; + +/** + * DelegatingLoader delegates loading to other loaders using a loader resolver. + * + * This loader acts as an array of LoaderInterface objects - each having + * a chance to load a given resource (handled by the resolver) + * + * @author Fabien Potencier + */ +class DelegatingLoader extends Loader +{ + public function __construct(LoaderResolverInterface $resolver) + { + $this->resolver = $resolver; + } + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + if (false === $loader = $this->resolver->resolve($resource, $type)) { + throw new FileLoaderLoadException($resource, null, null, null, $type); + } + + return $loader->load($resource, $type); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return false !== $this->resolver->resolve($resource, $type); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/FileLoader.php b/modules/empikmarketplace/vendor/symfony/config/Loader/FileLoader.php new file mode 100644 index 00000000..2f1d471b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/FileLoader.php @@ -0,0 +1,174 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException; +use Symfony\Component\Config\Exception\FileLoaderLoadException; +use Symfony\Component\Config\Exception\FileLocatorFileNotFoundException; +use Symfony\Component\Config\FileLocatorInterface; +use Symfony\Component\Config\Resource\FileExistenceResource; +use Symfony\Component\Config\Resource\GlobResource; + +/** + * FileLoader is the abstract class used by all built-in loaders that are file based. + * + * @author Fabien Potencier + */ +abstract class FileLoader extends Loader +{ + protected static $loading = []; + + protected $locator; + + private $currentDir; + + public function __construct(FileLocatorInterface $locator) + { + $this->locator = $locator; + } + + /** + * Sets the current directory. + * + * @param string $dir + */ + public function setCurrentDir($dir) + { + $this->currentDir = $dir; + } + + /** + * Returns the file locator used by this loader. + * + * @return FileLocatorInterface + */ + public function getLocator() + { + return $this->locator; + } + + /** + * Imports a resource. + * + * @param mixed $resource A Resource + * @param string|null $type The resource type or null if unknown + * @param bool $ignoreErrors Whether to ignore import errors or not + * @param string|null $sourceResource The original resource importing the new resource + * + * @return mixed + * + * @throws FileLoaderLoadException + * @throws FileLoaderImportCircularReferenceException + * @throws FileLocatorFileNotFoundException + */ + public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null) + { + if (\is_string($resource) && \strlen($resource) !== $i = strcspn($resource, '*?{[')) { + $ret = []; + $isSubpath = 0 !== $i && false !== strpos(substr($resource, 0, $i), '/'); + foreach ($this->glob($resource, false, $_, $ignoreErrors || !$isSubpath) as $path => $info) { + if (null !== $res = $this->doImport($path, 'glob' === $type ? null : $type, $ignoreErrors, $sourceResource)) { + $ret[] = $res; + } + $isSubpath = true; + } + + if ($isSubpath) { + return isset($ret[1]) ? $ret : (isset($ret[0]) ? $ret[0] : null); + } + } + + return $this->doImport($resource, $type, $ignoreErrors, $sourceResource); + } + + /** + * @internal + */ + protected function glob($pattern, $recursive, &$resource = null, $ignoreErrors = false) + { + if (\strlen($pattern) === $i = strcspn($pattern, '*?{[')) { + $prefix = $pattern; + $pattern = ''; + } elseif (0 === $i || false === strpos(substr($pattern, 0, $i), '/')) { + $prefix = '.'; + $pattern = '/'.$pattern; + } else { + $prefix = \dirname(substr($pattern, 0, 1 + $i)); + $pattern = substr($pattern, \strlen($prefix)); + } + + try { + $prefix = $this->locator->locate($prefix, $this->currentDir, true); + } catch (FileLocatorFileNotFoundException $e) { + if (!$ignoreErrors) { + throw $e; + } + + $resource = []; + foreach ($e->getPaths() as $path) { + $resource[] = new FileExistenceResource($path); + } + + return; + } + $resource = new GlobResource($prefix, $pattern, $recursive); + + foreach ($resource as $path => $info) { + yield $path => $info; + } + } + + private function doImport($resource, $type = null, $ignoreErrors = false, $sourceResource = null) + { + try { + $loader = $this->resolve($resource, $type); + + if ($loader instanceof self && null !== $this->currentDir) { + $resource = $loader->getLocator()->locate($resource, $this->currentDir, false); + } + + $resources = \is_array($resource) ? $resource : [$resource]; + for ($i = 0; $i < $resourcesCount = \count($resources); ++$i) { + if (isset(self::$loading[$resources[$i]])) { + if ($i == $resourcesCount - 1) { + throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading)); + } + } else { + $resource = $resources[$i]; + break; + } + } + self::$loading[$resource] = true; + + try { + $ret = $loader->load($resource, $type); + } finally { + unset(self::$loading[$resource]); + } + + return $ret; + } catch (FileLoaderImportCircularReferenceException $e) { + throw $e; + } catch (\Exception $e) { + if (!$ignoreErrors) { + // prevent embedded imports from nesting multiple exceptions + if ($e instanceof FileLoaderLoadException) { + throw $e; + } + + throw new FileLoaderLoadException($resource, $sourceResource, null, $e, $type); + } + } + + return null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/GlobFileLoader.php b/modules/empikmarketplace/vendor/symfony/config/Loader/GlobFileLoader.php new file mode 100644 index 00000000..f432b45b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/GlobFileLoader.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Fabien Potencier + */ +class GlobFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + return $this->import($resource); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return 'glob' === $type; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/Loader.php b/modules/empikmarketplace/vendor/symfony/config/Loader/Loader.php new file mode 100644 index 00000000..d2f2ec90 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/Loader.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +use Symfony\Component\Config\Exception\FileLoaderLoadException; + +/** + * Loader is the abstract class used by all built-in loaders. + * + * @author Fabien Potencier + */ +abstract class Loader implements LoaderInterface +{ + protected $resolver; + + /** + * {@inheritdoc} + */ + public function getResolver() + { + return $this->resolver; + } + + /** + * {@inheritdoc} + */ + public function setResolver(LoaderResolverInterface $resolver) + { + $this->resolver = $resolver; + } + + /** + * Imports a resource. + * + * @param mixed $resource A resource + * @param string|null $type The resource type or null if unknown + * + * @return mixed + */ + public function import($resource, $type = null) + { + return $this->resolve($resource, $type)->load($resource, $type); + } + + /** + * Finds a loader able to load an imported resource. + * + * @param mixed $resource A resource + * @param string|null $type The resource type or null if unknown + * + * @return $this|LoaderInterface + * + * @throws FileLoaderLoadException If no loader is found + */ + public function resolve($resource, $type = null) + { + if ($this->supports($resource, $type)) { + return $this; + } + + $loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type); + + if (false === $loader) { + throw new FileLoaderLoadException($resource, null, null, null, $type); + } + + return $loader; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderInterface.php b/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderInterface.php new file mode 100644 index 00000000..dfca9dd2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderInterface.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +/** + * LoaderInterface is the interface implemented by all loader classes. + * + * @author Fabien Potencier + */ +interface LoaderInterface +{ + /** + * Loads a resource. + * + * @param mixed $resource The resource + * @param string|null $type The resource type or null if unknown + * + * @throws \Exception If something went wrong + */ + public function load($resource, $type = null); + + /** + * Returns whether this class supports the given resource. + * + * @param mixed $resource A resource + * @param string|null $type The resource type or null if unknown + * + * @return bool True if this class supports the given resource, false otherwise + */ + public function supports($resource, $type = null); + + /** + * Gets the loader resolver. + * + * @return LoaderResolverInterface A LoaderResolverInterface instance + */ + public function getResolver(); + + /** + * Sets the loader resolver. + */ + public function setResolver(LoaderResolverInterface $resolver); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderResolver.php b/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderResolver.php new file mode 100644 index 00000000..c99efda4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderResolver.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +/** + * LoaderResolver selects a loader for a given resource. + * + * A resource can be anything (e.g. a full path to a config file or a Closure). + * Each loader determines whether it can load a resource and how. + * + * @author Fabien Potencier + */ +class LoaderResolver implements LoaderResolverInterface +{ + /** + * @var LoaderInterface[] An array of LoaderInterface objects + */ + private $loaders = []; + + /** + * @param LoaderInterface[] $loaders An array of loaders + */ + public function __construct(array $loaders = []) + { + foreach ($loaders as $loader) { + $this->addLoader($loader); + } + } + + /** + * {@inheritdoc} + */ + public function resolve($resource, $type = null) + { + foreach ($this->loaders as $loader) { + if ($loader->supports($resource, $type)) { + return $loader; + } + } + + return false; + } + + public function addLoader(LoaderInterface $loader) + { + $this->loaders[] = $loader; + $loader->setResolver($this); + } + + /** + * Returns the registered loaders. + * + * @return LoaderInterface[] An array of LoaderInterface instances + */ + public function getLoaders() + { + return $this->loaders; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderResolverInterface.php b/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderResolverInterface.php new file mode 100644 index 00000000..40f1a1a6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Loader/LoaderResolverInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Loader; + +/** + * LoaderResolverInterface selects a loader for a given resource. + * + * @author Fabien Potencier + */ +interface LoaderResolverInterface +{ + /** + * Returns a loader able to load the resource. + * + * @param mixed $resource A resource + * @param string|null $type The resource type or null if unknown + * + * @return LoaderInterface|false The loader or false if none is able to load the resource + */ + public function resolve($resource, $type = null); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/README.md b/modules/empikmarketplace/vendor/symfony/config/README.md new file mode 100644 index 00000000..0bbde552 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/README.md @@ -0,0 +1,15 @@ +Config Component +================ + +The Config component provides several classes to help you find, load, combine, +autofill and validate configuration values of any kind, whatever their source +may be (YAML, XML, INI files, or for instance a database). + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/config.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/ClassExistenceResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/ClassExistenceResource.php new file mode 100644 index 00000000..f58d2a6d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/ClassExistenceResource.php @@ -0,0 +1,238 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * ClassExistenceResource represents a class existence. + * Freshness is only evaluated against resource existence. + * + * The resource must be a fully-qualified class name. + * + * @author Fabien Potencier + */ +class ClassExistenceResource implements SelfCheckingResourceInterface, \Serializable +{ + private $resource; + private $exists; + + private static $autoloadLevel = 0; + private static $autoloadedClass; + private static $existsCache = []; + + /** + * @param string $resource The fully-qualified class name + * @param bool|null $exists Boolean when the existency check has already been done + */ + public function __construct($resource, $exists = null) + { + $this->resource = $resource; + if (null !== $exists) { + $this->exists = [(bool) $exists, null]; + } + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->resource; + } + + /** + * @return string The file path to the resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * {@inheritdoc} + * + * @throws \ReflectionException when a parent class/interface/trait is not found + */ + public function isFresh($timestamp) + { + $loaded = class_exists($this->resource, false) || interface_exists($this->resource, false) || trait_exists($this->resource, false); + + if (null !== $exists = &self::$existsCache[$this->resource]) { + if ($loaded) { + $exists = [true, null]; + } elseif (0 >= $timestamp && !$exists[0] && null !== $exists[1]) { + throw new \ReflectionException($exists[1]); + } + } elseif ([false, null] === $exists = [$loaded, null]) { + if (!self::$autoloadLevel++) { + spl_autoload_register(__CLASS__.'::throwOnRequiredClass'); + } + $autoloadedClass = self::$autoloadedClass; + self::$autoloadedClass = ltrim($this->resource, '\\'); + + try { + $exists[0] = class_exists($this->resource) || interface_exists($this->resource, false) || trait_exists($this->resource, false); + } catch (\Exception $e) { + $exists[1] = $e->getMessage(); + + try { + self::throwOnRequiredClass($this->resource, $e); + } catch (\ReflectionException $e) { + if (0 >= $timestamp) { + throw $e; + } + } + } catch (\Throwable $e) { + $exists[1] = $e->getMessage(); + + throw $e; + } finally { + self::$autoloadedClass = $autoloadedClass; + if (!--self::$autoloadLevel) { + spl_autoload_unregister(__CLASS__.'::throwOnRequiredClass'); + } + } + } + + if (null === $this->exists) { + $this->exists = $exists; + } + + return $this->exists[0] xor !$exists[0]; + } + + /** + * @internal + */ + public function serialize() + { + if (null === $this->exists) { + $this->isFresh(0); + } + + return serialize([$this->resource, $this->exists]); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + list($this->resource, $this->exists) = unserialize($serialized); + + if (\is_bool($this->exists)) { + $this->exists = [$this->exists, null]; + } + } + + /** + * Throws a reflection exception when the passed class does not exist but is required. + * + * A class is considered "not required" when it's loaded as part of a "class_exists" or similar check. + * + * This function can be used as an autoload function to throw a reflection + * exception if the class was not found by previous autoload functions. + * + * A previous exception can be passed. In this case, the class is considered as being + * required totally, so if it doesn't exist, a reflection exception is always thrown. + * If it exists, the previous exception is rethrown. + * + * @throws \ReflectionException + * + * @internal + */ + public static function throwOnRequiredClass($class, \Exception $previous = null) + { + // If the passed class is the resource being checked, we shouldn't throw. + if (null === $previous && self::$autoloadedClass === $class) { + return; + } + + if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) { + if (null !== $previous) { + throw $previous; + } + + return; + } + + if ($previous instanceof \ReflectionException) { + throw $previous; + } + + $message = sprintf('Class "%s" not found.', $class); + + if (self::$autoloadedClass !== $class) { + $message = substr_replace($message, sprintf(' while loading "%s"', self::$autoloadedClass), -1, 0); + } + + if (null !== $previous) { + $message = $previous->getMessage(); + } + + $e = new \ReflectionException($message, 0, $previous); + + if (null !== $previous) { + throw $e; + } + + $trace = debug_backtrace(); + $autoloadFrame = [ + 'function' => 'spl_autoload_call', + 'args' => [$class], + ]; + + if (\PHP_VERSION_ID >= 80000 && isset($trace[1])) { + $callerFrame = $trace[1]; + $i = 2; + } elseif (false !== $i = array_search($autoloadFrame, $trace, true)) { + $callerFrame = $trace[++$i]; + } else { + throw $e; + } + + if (isset($callerFrame['function']) && !isset($callerFrame['class'])) { + switch ($callerFrame['function']) { + case 'get_class_methods': + case 'get_class_vars': + case 'get_parent_class': + case 'is_a': + case 'is_subclass_of': + case 'class_exists': + case 'class_implements': + case 'class_parents': + case 'trait_exists': + case 'defined': + case 'interface_exists': + case 'method_exists': + case 'property_exists': + case 'is_callable': + return; + } + + $props = [ + 'file' => isset($callerFrame['file']) ? $callerFrame['file'] : null, + 'line' => isset($callerFrame['line']) ? $callerFrame['line'] : null, + 'trace' => \array_slice($trace, 1 + $i), + ]; + + foreach ($props as $p => $v) { + if (null !== $v) { + $r = new \ReflectionProperty('Exception', $p); + $r->setAccessible(true); + $r->setValue($e, $v); + } + } + } + + throw $e; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/ComposerResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/ComposerResource.php new file mode 100644 index 00000000..9fb304be --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/ComposerResource.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * ComposerResource tracks the PHP version and Composer dependencies. + * + * @author Nicolas Grekas + */ +class ComposerResource implements SelfCheckingResourceInterface, \Serializable +{ + private $vendors; + + private static $runtimeVendors; + + public function __construct() + { + self::refresh(); + $this->vendors = self::$runtimeVendors; + } + + public function getVendors() + { + return array_keys($this->vendors); + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return __CLASS__; + } + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + self::refresh(); + + return array_values(self::$runtimeVendors) === array_values($this->vendors); + } + + /** + * @internal + */ + public function serialize() + { + return serialize($this->vendors); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + $this->vendors = unserialize($serialized); + } + + private static function refresh() + { + self::$runtimeVendors = []; + + foreach (get_declared_classes() as $class) { + if ('C' === $class[0] && 0 === strpos($class, 'ComposerAutoloaderInit')) { + $r = new \ReflectionClass($class); + $v = \dirname(\dirname($r->getFileName())); + if (file_exists($v.'/composer/installed.json')) { + self::$runtimeVendors[$v] = @filemtime($v.'/composer/installed.json'); + } + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/DirectoryResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/DirectoryResource.php new file mode 100644 index 00000000..e79b19ec --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/DirectoryResource.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * DirectoryResource represents a resources stored in a subdirectory tree. + * + * @author Fabien Potencier + */ +class DirectoryResource implements SelfCheckingResourceInterface, \Serializable +{ + private $resource; + private $pattern; + + /** + * @param string $resource The file path to the resource + * @param string|null $pattern A pattern to restrict monitored files + * + * @throws \InvalidArgumentException + */ + public function __construct($resource, $pattern = null) + { + $this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false); + $this->pattern = $pattern; + + if (false === $this->resource || !is_dir($this->resource)) { + throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist.', $resource)); + } + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return md5(serialize([$this->resource, $this->pattern])); + } + + /** + * @return string The file path to the resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * Returns the pattern to restrict monitored files. + * + * @return string|null + */ + public function getPattern() + { + return $this->pattern; + } + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + if (!is_dir($this->resource)) { + return false; + } + + if ($timestamp < filemtime($this->resource)) { + return false; + } + + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { + // if regex filtering is enabled only check matching files + if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) { + continue; + } + + // always monitor directories for changes, except the .. entries + // (otherwise deleted files wouldn't get detected) + if ($file->isDir() && '/..' === substr($file, -3)) { + continue; + } + + // for broken links + try { + $fileMTime = $file->getMTime(); + } catch (\RuntimeException $e) { + continue; + } + + // early return if a file's mtime exceeds the passed timestamp + if ($timestamp < $fileMTime) { + return false; + } + } + + return true; + } + + /** + * @internal + */ + public function serialize() + { + return serialize([$this->resource, $this->pattern]); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + list($this->resource, $this->pattern) = unserialize($serialized); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/FileExistenceResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/FileExistenceResource.php new file mode 100644 index 00000000..34047651 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/FileExistenceResource.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * FileExistenceResource represents a resource stored on the filesystem. + * Freshness is only evaluated against resource creation or deletion. + * + * The resource can be a file or a directory. + * + * @author Charles-Henri Bruyand + */ +class FileExistenceResource implements SelfCheckingResourceInterface, \Serializable +{ + private $resource; + + private $exists; + + /** + * @param string $resource The file path to the resource + */ + public function __construct($resource) + { + $this->resource = (string) $resource; + $this->exists = file_exists($resource); + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->resource; + } + + /** + * @return string The file path to the resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + return file_exists($this->resource) === $this->exists; + } + + /** + * @internal + */ + public function serialize() + { + return serialize([$this->resource, $this->exists]); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + list($this->resource, $this->exists) = unserialize($serialized); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/FileResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/FileResource.php new file mode 100644 index 00000000..bee06237 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/FileResource.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * FileResource represents a resource stored on the filesystem. + * + * The resource can be a file or a directory. + * + * @author Fabien Potencier + */ +class FileResource implements SelfCheckingResourceInterface, \Serializable +{ + /** + * @var string|false + */ + private $resource; + + /** + * @param string $resource The file path to the resource + * + * @throws \InvalidArgumentException + */ + public function __construct($resource) + { + $this->resource = realpath($resource) ?: (file_exists($resource) ? $resource : false); + + if (false === $this->resource) { + throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $resource)); + } + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return $this->resource; + } + + /** + * @return string The canonicalized, absolute path to the resource + */ + public function getResource() + { + return $this->resource; + } + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + return false !== ($filemtime = @filemtime($this->resource)) && $filemtime <= $timestamp; + } + + /** + * @internal + */ + public function serialize() + { + return serialize($this->resource); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + $this->resource = unserialize($serialized); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/GlobResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/GlobResource.php new file mode 100644 index 00000000..1aa3bcf6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/GlobResource.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +use Symfony\Component\Finder\Finder; +use Symfony\Component\Finder\Glob; + +/** + * GlobResource represents a set of resources stored on the filesystem. + * + * Only existence/removal is tracked (not mtimes.) + * + * @author Nicolas Grekas + */ +class GlobResource implements \IteratorAggregate, SelfCheckingResourceInterface, \Serializable +{ + private $prefix; + private $pattern; + private $recursive; + private $hash; + + /** + * @param string $prefix A directory prefix + * @param string $pattern A glob pattern + * @param bool $recursive Whether directories should be scanned recursively or not + * + * @throws \InvalidArgumentException + */ + public function __construct($prefix, $pattern, $recursive) + { + $this->prefix = realpath($prefix) ?: (file_exists($prefix) ? $prefix : false); + $this->pattern = $pattern; + $this->recursive = $recursive; + + if (false === $this->prefix) { + throw new \InvalidArgumentException(sprintf('The path "%s" does not exist.', $prefix)); + } + } + + public function getPrefix() + { + return $this->prefix; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return 'glob.'.$this->prefix.$this->pattern.(int) $this->recursive; + } + + /** + * {@inheritdoc} + */ + public function isFresh($timestamp) + { + $hash = $this->computeHash(); + + if (null === $this->hash) { + $this->hash = $hash; + } + + return $this->hash === $hash; + } + + /** + * @internal + */ + public function serialize() + { + if (null === $this->hash) { + $this->hash = $this->computeHash(); + } + + return serialize([$this->prefix, $this->pattern, $this->recursive, $this->hash]); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + list($this->prefix, $this->pattern, $this->recursive, $this->hash) = unserialize($serialized); + } + + public function getIterator() + { + if (!file_exists($this->prefix) || (!$this->recursive && '' === $this->pattern)) { + return; + } + + if (0 !== strpos($this->prefix, 'phar://') && false === strpos($this->pattern, '/**/') && (\defined('GLOB_BRACE') || false === strpos($this->pattern, '{'))) { + $paths = glob($this->prefix.$this->pattern, \GLOB_NOSORT | (\defined('GLOB_BRACE') ? \GLOB_BRACE : 0)); + sort($paths); + foreach ($paths as $path) { + if ($this->recursive && is_dir($path)) { + $files = iterator_to_array(new \RecursiveIteratorIterator( + new \RecursiveCallbackFilterIterator( + new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), + function (\SplFileInfo $file) { return '.' !== $file->getBasename()[0]; } + ), + \RecursiveIteratorIterator::LEAVES_ONLY + )); + uasort($files, function (\SplFileInfo $a, \SplFileInfo $b) { + return (string) $a > (string) $b ? 1 : -1; + }); + + foreach ($files as $path => $info) { + if ($info->isFile()) { + yield $path => $info; + } + } + } elseif (is_file($path)) { + yield $path => new \SplFileInfo($path); + } + } + + return; + } + + if (!class_exists(Finder::class)) { + throw new \LogicException(sprintf('Extended glob pattern "%s" cannot be used as the Finder component is not installed.', $this->pattern)); + } + + $finder = new Finder(); + $regex = Glob::toRegex($this->pattern); + if ($this->recursive) { + $regex = substr_replace($regex, '(/|$)', -2, 1); + } + + $prefixLen = \strlen($this->prefix); + foreach ($finder->followLinks()->sortByName()->in($this->prefix) as $path => $info) { + if (preg_match($regex, substr('\\' === \DIRECTORY_SEPARATOR ? str_replace('\\', '/', $path) : $path, $prefixLen)) && $info->isFile()) { + yield $path => $info; + } + } + } + + private function computeHash() + { + $hash = hash_init('md5'); + + foreach ($this->getIterator() as $path => $info) { + hash_update($hash, $path."\n"); + } + + return hash_final($hash); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/ReflectionClassResource.php b/modules/empikmarketplace/vendor/symfony/config/Resource/ReflectionClassResource.php new file mode 100644 index 00000000..79b21fbf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/ReflectionClassResource.php @@ -0,0 +1,256 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * @author Nicolas Grekas + */ +class ReflectionClassResource implements SelfCheckingResourceInterface, \Serializable +{ + private $files = []; + private $className; + private $classReflector; + private $excludedVendors = []; + private $hash; + + public function __construct(\ReflectionClass $classReflector, $excludedVendors = []) + { + $this->className = $classReflector->name; + $this->classReflector = $classReflector; + $this->excludedVendors = $excludedVendors; + } + + public function isFresh($timestamp) + { + if (null === $this->hash) { + $this->hash = $this->computeHash(); + $this->loadFiles($this->classReflector); + } + + foreach ($this->files as $file => $v) { + if (false === $filemtime = @filemtime($file)) { + return false; + } + + if ($filemtime > $timestamp) { + return $this->hash === $this->computeHash(); + } + } + + return true; + } + + public function __toString() + { + return 'reflection.'.$this->className; + } + + /** + * @internal + */ + public function serialize() + { + if (null === $this->hash) { + $this->hash = $this->computeHash(); + $this->loadFiles($this->classReflector); + } + + return serialize([$this->files, $this->className, $this->hash]); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + list($this->files, $this->className, $this->hash) = unserialize($serialized); + } + + private function loadFiles(\ReflectionClass $class) + { + foreach ($class->getInterfaces() as $v) { + $this->loadFiles($v); + } + do { + $file = $class->getFileName(); + if (false !== $file && file_exists($file)) { + foreach ($this->excludedVendors as $vendor) { + if (0 === strpos($file, $vendor) && false !== strpbrk(substr($file, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { + $file = false; + break; + } + } + if ($file) { + $this->files[$file] = null; + } + } + foreach ($class->getTraits() as $v) { + $this->loadFiles($v); + } + } while ($class = $class->getParentClass()); + } + + private function computeHash() + { + if (null === $this->classReflector) { + try { + $this->classReflector = new \ReflectionClass($this->className); + } catch (\ReflectionException $e) { + // the class does not exist anymore + return false; + } + } + $hash = hash_init('md5'); + + foreach ($this->generateSignature($this->classReflector) as $info) { + hash_update($hash, $info); + } + + return hash_final($hash); + } + + private function generateSignature(\ReflectionClass $class) + { + yield $class->getDocComment(); + yield (int) $class->isFinal(); + yield (int) $class->isAbstract(); + + if ($class->isTrait()) { + yield print_r(class_uses($class->name), true); + } else { + yield print_r(class_parents($class->name), true); + yield print_r(class_implements($class->name), true); + yield print_r($class->getConstants(), true); + } + + if (!$class->isInterface()) { + $defaults = $class->getDefaultProperties(); + + foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $p) { + yield $p->getDocComment(); + yield $p->isDefault() ? '' : ''; + yield $p->isPublic() ? 'public' : 'protected'; + yield $p->isStatic() ? 'static' : ''; + yield '$'.$p->name; + yield print_r(isset($defaults[$p->name]) && !\is_object($defaults[$p->name]) ? $defaults[$p->name] : null, true); + } + } + + if (\defined('HHVM_VERSION')) { + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { + // workaround HHVM bug with variadics, see https://github.com/facebook/hhvm/issues/5762 + yield preg_replace('/^ @@.*/m', '', new ReflectionMethodHhvmWrapper($m->class, $m->name)); + } + } else { + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $m) { + $defaults = []; + $parametersWithUndefinedConstants = []; + foreach ($m->getParameters() as $p) { + if (!$p->isDefaultValueAvailable()) { + $defaults[$p->name] = null; + + continue; + } + + if (!$p->isDefaultValueConstant() || \defined($p->getDefaultValueConstantName())) { + $defaults[$p->name] = $p->getDefaultValue(); + + continue; + } + + $defaults[$p->name] = $p->getDefaultValueConstantName(); + $parametersWithUndefinedConstants[$p->name] = true; + } + + if (!$parametersWithUndefinedConstants) { + yield preg_replace('/^ @@.*/m', '', $m); + } else { + $t = \PHP_VERSION_ID >= 70000 ? $m->getReturnType() : ''; + $stack = [ + $m->getDocComment(), + $m->getName(), + $m->isAbstract(), + $m->isFinal(), + $m->isStatic(), + $m->isPublic(), + $m->isPrivate(), + $m->isProtected(), + $m->returnsReference(), + $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t, + ]; + + foreach ($m->getParameters() as $p) { + if (!isset($parametersWithUndefinedConstants[$p->name])) { + $stack[] = (string) $p; + } else { + $t = \PHP_VERSION_ID >= 70000 ? $p->getType() : ''; + $stack[] = $p->isOptional(); + $stack[] = $t instanceof \ReflectionNamedType ? ((string) $t->allowsNull()).$t->getName() : (string) $t; + $stack[] = $p->isPassedByReference(); + $stack[] = \PHP_VERSION_ID >= 50600 ? $p->isVariadic() : ''; + $stack[] = $p->getName(); + } + } + + yield implode(',', $stack); + } + + yield print_r($defaults, true); + } + } + + if ($class->isAbstract() || $class->isInterface() || $class->isTrait()) { + return; + } + + if (interface_exists(EventSubscriberInterface::class, false) && $class->isSubclassOf(EventSubscriberInterface::class)) { + yield EventSubscriberInterface::class; + yield print_r(\call_user_func([$class->name, 'getSubscribedEvents']), true); + } + + if (interface_exists(ServiceSubscriberInterface::class, false) && $class->isSubclassOf(ServiceSubscriberInterface::class)) { + yield ServiceSubscriberInterface::class; + yield print_r(\call_user_func([$class->name, 'getSubscribedServices']), true); + } + } +} + +/** + * @internal + */ +class ReflectionMethodHhvmWrapper extends \ReflectionMethod +{ + public function getParameters() + { + $params = []; + + foreach (parent::getParameters() as $i => $p) { + $params[] = new ReflectionParameterHhvmWrapper([$this->class, $this->name], $i); + } + + return $params; + } +} + +/** + * @internal + */ +class ReflectionParameterHhvmWrapper extends \ReflectionParameter +{ + public function getDefaultValue() + { + return [$this->isVariadic(), $this->isDefaultValueAvailable() ? parent::getDefaultValue() : null]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/ResourceInterface.php b/modules/empikmarketplace/vendor/symfony/config/Resource/ResourceInterface.php new file mode 100644 index 00000000..d98fd427 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/ResourceInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * ResourceInterface is the interface that must be implemented by all Resource classes. + * + * @author Fabien Potencier + */ +interface ResourceInterface +{ + /** + * Returns a string representation of the Resource. + * + * This method is necessary to allow for resource de-duplication, for example by means + * of array_unique(). The string returned need not have a particular meaning, but has + * to be identical for different ResourceInterface instances referring to the same + * resource; and it should be unlikely to collide with that of other, unrelated + * resource instances. + * + * @return string A string representation unique to the underlying Resource + */ + public function __toString(); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php b/modules/empikmarketplace/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php new file mode 100644 index 00000000..d72203bc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/SelfCheckingResourceChecker.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +use Symfony\Component\Config\ResourceCheckerInterface; + +/** + * Resource checker for instances of SelfCheckingResourceInterface. + * + * As these resources perform the actual check themselves, we can provide + * this class as a standard way of validating them. + * + * @author Matthias Pigulla + */ +class SelfCheckingResourceChecker implements ResourceCheckerInterface +{ + public function supports(ResourceInterface $metadata) + { + return $metadata instanceof SelfCheckingResourceInterface; + } + + public function isFresh(ResourceInterface $resource, $timestamp) + { + /* @var SelfCheckingResourceInterface $resource */ + return $resource->isFresh($timestamp); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php b/modules/empikmarketplace/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php new file mode 100644 index 00000000..b3260f2b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Resource/SelfCheckingResourceInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Resource; + +/** + * Interface for Resources that can check for freshness autonomously, + * without special support from external services. + * + * @author Matthias Pigulla + */ +interface SelfCheckingResourceInterface extends ResourceInterface +{ + /** + * Returns true if the resource has not been updated since the given timestamp. + * + * @param int $timestamp The last time the resource was loaded + * + * @return bool True if the resource has not been updated, false otherwise + */ + public function isFresh($timestamp); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerConfigCache.php b/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerConfigCache.php new file mode 100644 index 00000000..0538f3f4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerConfigCache.php @@ -0,0 +1,183 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; + +/** + * ResourceCheckerConfigCache uses instances of ResourceCheckerInterface + * to check whether cached data is still fresh. + * + * @author Matthias Pigulla + */ +class ResourceCheckerConfigCache implements ConfigCacheInterface +{ + /** + * @var string + */ + private $file; + + /** + * @var iterable|ResourceCheckerInterface[] + */ + private $resourceCheckers; + + /** + * @param string $file The absolute cache path + * @param iterable|ResourceCheckerInterface[] $resourceCheckers The ResourceCheckers to use for the freshness check + */ + public function __construct($file, $resourceCheckers = []) + { + $this->file = $file; + $this->resourceCheckers = $resourceCheckers; + } + + /** + * {@inheritdoc} + */ + public function getPath() + { + return $this->file; + } + + /** + * Checks if the cache is still fresh. + * + * This implementation will make a decision solely based on the ResourceCheckers + * passed in the constructor. + * + * The first ResourceChecker that supports a given resource is considered authoritative. + * Resources with no matching ResourceChecker will silently be ignored and considered fresh. + * + * @return bool true if the cache is fresh, false otherwise + */ + public function isFresh() + { + if (!is_file($this->file)) { + return false; + } + + if ($this->resourceCheckers instanceof \Traversable && !$this->resourceCheckers instanceof \Countable) { + $this->resourceCheckers = iterator_to_array($this->resourceCheckers); + } + + if (!\count($this->resourceCheckers)) { + return true; // shortcut - if we don't have any checkers we don't need to bother with the meta file at all + } + + $metadata = $this->getMetaFile(); + + if (!is_file($metadata)) { + return false; + } + + $meta = $this->safelyUnserialize($metadata); + + if (false === $meta) { + return false; + } + + $time = filemtime($this->file); + + foreach ($meta as $resource) { + /* @var ResourceInterface $resource */ + foreach ($this->resourceCheckers as $checker) { + if (!$checker->supports($resource)) { + continue; // next checker + } + if ($checker->isFresh($resource, $time)) { + break; // no need to further check this resource + } + + return false; // cache is stale + } + // no suitable checker found, ignore this resource + } + + return true; + } + + /** + * Writes cache. + * + * @param string $content The content to write in the cache + * @param ResourceInterface[] $metadata An array of metadata + * + * @throws \RuntimeException When cache file can't be written + */ + public function write($content, array $metadata = null) + { + $mode = 0666; + $umask = umask(); + $filesystem = new Filesystem(); + $filesystem->dumpFile($this->file, $content); + try { + $filesystem->chmod($this->file, $mode, $umask); + } catch (IOException $e) { + // discard chmod failure (some filesystem may not support it) + } + + if (null !== $metadata) { + $filesystem->dumpFile($this->getMetaFile(), serialize($metadata)); + try { + $filesystem->chmod($this->getMetaFile(), $mode, $umask); + } catch (IOException $e) { + // discard chmod failure (some filesystem may not support it) + } + } + + if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) { + @opcache_invalidate($this->file, true); + } + } + + /** + * Gets the meta file path. + * + * @return string The meta file path + */ + private function getMetaFile() + { + return $this->file.'.meta'; + } + + private function safelyUnserialize($file) + { + $e = null; + $meta = false; + $content = file_get_contents($file); + $signalingException = new \UnexpectedValueException(); + $prevUnserializeHandler = ini_set('unserialize_callback_func', ''); + $prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) use (&$prevErrorHandler, $signalingException) { + if (__FILE__ === $file) { + throw $signalingException; + } + + return $prevErrorHandler ? $prevErrorHandler($type, $msg, $file, $line, $context) : false; + }); + + try { + $meta = unserialize($content); + } catch (\Error $e) { + } catch (\Exception $e) { + } + restore_error_handler(); + ini_set('unserialize_callback_func', $prevUnserializeHandler); + if (null !== $e && $e !== $signalingException) { + throw $e; + } + + return $meta; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php b/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php new file mode 100644 index 00000000..c00fa7db --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +/** + * A ConfigCacheFactory implementation that validates the + * cache with an arbitrary set of ResourceCheckers. + * + * @author Matthias Pigulla + */ +class ResourceCheckerConfigCacheFactory implements ConfigCacheFactoryInterface +{ + private $resourceCheckers = []; + + /** + * @param iterable|ResourceCheckerInterface[] $resourceCheckers + */ + public function __construct($resourceCheckers = []) + { + $this->resourceCheckers = $resourceCheckers; + } + + /** + * {@inheritdoc} + */ + public function cache($file, $callback) + { + if (!\is_callable($callback)) { + throw new \InvalidArgumentException(sprintf('Invalid type for callback argument. Expected callable, but got "%s".', \gettype($callback))); + } + + $cache = new ResourceCheckerConfigCache($file, $this->resourceCheckers); + if (!$cache->isFresh()) { + \call_user_func($callback, $cache); + } + + return $cache; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerInterface.php b/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerInterface.php new file mode 100644 index 00000000..612d7778 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/ResourceCheckerInterface.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * Interface for ResourceCheckers. + * + * When a ResourceCheckerConfigCache instance is checked for freshness, all its associated + * metadata resources are passed to ResourceCheckers. The ResourceCheckers + * can then inspect the resources and decide whether the cache can be considered + * fresh or not. + * + * @author Matthias Pigulla + * @author Benjamin Klotz + */ +interface ResourceCheckerInterface +{ + /** + * Queries the ResourceChecker whether it can validate a given + * resource or not. + * + * @param ResourceInterface $metadata The resource to be checked for freshness + * + * @return bool True if the ResourceChecker can handle this resource type, false if not + */ + public function supports(ResourceInterface $metadata); + + /** + * Validates the resource. + * + * @param ResourceInterface $resource The resource to be validated + * @param int $timestamp The timestamp at which the cache associated with this resource was created + * + * @return bool True if the resource has not changed since the given timestamp, false otherwise + */ + public function isFresh(ResourceInterface $resource, $timestamp); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/ConfigCacheFactoryTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/ConfigCacheFactoryTest.php new file mode 100644 index 00000000..6190b9b4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/ConfigCacheFactoryTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\ConfigCacheFactory; + +class ConfigCacheFactoryTest extends TestCase +{ + public function testCacheWithInvalidCallback() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Invalid type for callback argument. Expected callable, but got "object".'); + $cacheFactory = new ConfigCacheFactory(true); + + $cacheFactory->cache('file', new \stdClass()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/ConfigCacheTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/ConfigCacheTest.php new file mode 100644 index 00000000..95a58817 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/ConfigCacheTest.php @@ -0,0 +1,99 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\ConfigCache; +use Symfony\Component\Config\Tests\Resource\ResourceStub; + +class ConfigCacheTest extends TestCase +{ + private $cacheFile = null; + + protected function setUp() + { + $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_'); + } + + protected function tearDown() + { + $files = [$this->cacheFile, $this->cacheFile.'.meta']; + + foreach ($files as $file) { + if (file_exists($file)) { + @unlink($file); + } + } + } + + /** + * @dataProvider debugModes + */ + public function testCacheIsNotValidIfNothingHasBeenCached($debug) + { + unlink($this->cacheFile); // remove tempnam() side effect + $cache = new ConfigCache($this->cacheFile, $debug); + + $this->assertFalse($cache->isFresh()); + } + + public function testIsAlwaysFreshInProduction() + { + $staleResource = new ResourceStub(); + $staleResource->setFresh(false); + + $cache = new ConfigCache($this->cacheFile, false); + $cache->write('', [$staleResource]); + + $this->assertTrue($cache->isFresh()); + } + + /** + * @dataProvider debugModes + */ + public function testIsFreshWhenNoResourceProvided($debug) + { + $cache = new ConfigCache($this->cacheFile, $debug); + $cache->write('', []); + $this->assertTrue($cache->isFresh()); + } + + public function testFreshResourceInDebug() + { + $freshResource = new ResourceStub(); + $freshResource->setFresh(true); + + $cache = new ConfigCache($this->cacheFile, true); + $cache->write('', [$freshResource]); + + $this->assertTrue($cache->isFresh()); + } + + public function testStaleResourceInDebug() + { + $staleResource = new ResourceStub(); + $staleResource->setFresh(false); + + $cache = new ConfigCache($this->cacheFile, true); + $cache->write('', [$staleResource]); + + $this->assertFalse($cache->isFresh()); + } + + public function debugModes() + { + return [ + [true], + [false], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/ArrayNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/ArrayNodeTest.php new file mode 100644 index 00000000..f726e8dd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/ArrayNodeTest.php @@ -0,0 +1,237 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; +use Symfony\Component\Config\Definition\ScalarNode; + +class ArrayNodeTest extends TestCase +{ + public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $node = new ArrayNode('root'); + $node->normalize(false); + } + + public function testExceptionThrownOnUnrecognizedChild() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('Unrecognized option "foo" under "root"'); + $node = new ArrayNode('root'); + $node->normalize(['foo' => 'bar']); + } + + public function ignoreAndRemoveMatrixProvider() + { + $unrecognizedOptionException = new InvalidConfigurationException('Unrecognized option "foo" under "root"'); + + return [ + [true, true, [], 'no exception is thrown for an unrecognized child if the ignoreExtraKeys option is set to true'], + [true, false, ['foo' => 'bar'], 'extra keys are not removed when ignoreExtraKeys second option is set to false'], + [false, true, $unrecognizedOptionException], + [false, false, $unrecognizedOptionException], + ]; + } + + /** + * @dataProvider ignoreAndRemoveMatrixProvider + */ + public function testIgnoreAndRemoveBehaviors($ignore, $remove, $expected, $message = '') + { + if ($expected instanceof \Exception) { + $this->expectException(\get_class($expected)); + $this->expectExceptionMessage($expected->getMessage()); + } + $node = new ArrayNode('root'); + $node->setIgnoreExtraKeys($ignore, $remove); + $result = $node->normalize(['foo' => 'bar']); + $this->assertSame($expected, $result, $message); + } + + /** + * @dataProvider getPreNormalizationTests + */ + public function testPreNormalize($denormalized, $normalized) + { + $node = new ArrayNode('foo'); + + $r = new \ReflectionMethod($node, 'preNormalize'); + $r->setAccessible(true); + + $this->assertSame($normalized, $r->invoke($node, $denormalized)); + } + + public function getPreNormalizationTests() + { + return [ + [ + ['foo-bar' => 'foo'], + ['foo_bar' => 'foo'], + ], + [ + ['foo-bar_moo' => 'foo'], + ['foo-bar_moo' => 'foo'], + ], + [ + ['anything-with-dash-and-no-underscore' => 'first', 'no_dash' => 'second'], + ['anything_with_dash_and_no_underscore' => 'first', 'no_dash' => 'second'], + ], + [ + ['foo-bar' => null, 'foo_bar' => 'foo'], + ['foo-bar' => null, 'foo_bar' => 'foo'], + ], + ]; + } + + /** + * @dataProvider getZeroNamedNodeExamplesData + */ + public function testNodeNameCanBeZero($denormalized, $normalized) + { + $zeroNode = new ArrayNode(0); + $zeroNode->addChild(new ScalarNode('name')); + $fiveNode = new ArrayNode(5); + $fiveNode->addChild(new ScalarNode(0)); + $fiveNode->addChild(new ScalarNode('new_key')); + $rootNode = new ArrayNode('root'); + $rootNode->addChild($zeroNode); + $rootNode->addChild($fiveNode); + $rootNode->addChild(new ScalarNode('string_key')); + $r = new \ReflectionMethod($rootNode, 'normalizeValue'); + $r->setAccessible(true); + + $this->assertSame($normalized, $r->invoke($rootNode, $denormalized)); + } + + public function getZeroNamedNodeExamplesData() + { + return [ + [ + [ + 0 => [ + 'name' => 'something', + ], + 5 => [ + 0 => 'this won\'t work too', + 'new_key' => 'some other value', + ], + 'string_key' => 'just value', + ], + [ + 0 => [ + 'name' => 'something', + ], + 5 => [ + 0 => 'this won\'t work too', + 'new_key' => 'some other value', + ], + 'string_key' => 'just value', + ], + ], + ]; + } + + /** + * @dataProvider getPreNormalizedNormalizedOrderedData + */ + public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized) + { + $scalar1 = new ScalarNode('1'); + $scalar2 = new ScalarNode('2'); + $scalar3 = new ScalarNode('3'); + $node = new ArrayNode('foo'); + $node->addChild($scalar1); + $node->addChild($scalar3); + $node->addChild($scalar2); + + $r = new \ReflectionMethod($node, 'normalizeValue'); + $r->setAccessible(true); + + $this->assertSame($normalized, $r->invoke($node, $prenormalized)); + } + + public function getPreNormalizedNormalizedOrderedData() + { + return [ + [ + ['2' => 'two', '1' => 'one', '3' => 'three'], + ['2' => 'two', '1' => 'one', '3' => 'three'], + ], + ]; + } + + public function testAddChildEmptyName() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Child nodes must be named.'); + $node = new ArrayNode('root'); + + $childNode = new ArrayNode(''); + $node->addChild($childNode); + } + + public function testAddChildNameAlreadyExists() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('A child node named "foo" already exists.'); + $node = new ArrayNode('root'); + + $childNode = new ArrayNode('foo'); + $node->addChild($childNode); + + $childNodeWithSameName = new ArrayNode('foo'); + $node->addChild($childNodeWithSameName); + } + + public function testGetDefaultValueWithoutDefaultValue() + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('The node at path "foo" has no default value.'); + $node = new ArrayNode('foo'); + $node->getDefaultValue(); + } + + public function testSetDeprecated() + { + $childNode = new ArrayNode('foo'); + $childNode->setDeprecated('"%node%" is deprecated'); + + $this->assertTrue($childNode->isDeprecated()); + $this->assertSame('"foo" is deprecated', $childNode->getDeprecationMessage($childNode->getName(), $childNode->getPath())); + + $node = new ArrayNode('root'); + $node->addChild($childNode); + + $deprecationTriggered = false; + $deprecationHandler = function ($level, $message, $file, $line) use (&$prevErrorHandler, &$deprecationTriggered) { + if (\E_USER_DEPRECATED === $level) { + return $deprecationTriggered = true; + } + + return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false; + }; + + $prevErrorHandler = set_error_handler($deprecationHandler); + $node->finalize([]); + restore_error_handler(); + + $this->assertFalse($deprecationTriggered, '->finalize() should not trigger if the deprecated node is not set'); + + $prevErrorHandler = set_error_handler($deprecationHandler); + $node->finalize(['foo' => []]); + restore_error_handler(); + $this->assertTrue($deprecationTriggered, '->finalize() should trigger if the deprecated node is set'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/BooleanNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/BooleanNodeTest.php new file mode 100644 index 00000000..8552eeba --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/BooleanNodeTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\BooleanNode; + +class BooleanNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new BooleanNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + /** + * @dataProvider getValidValues + * + * @param bool $value + */ + public function testValidNonEmptyValues($value) + { + $node = new BooleanNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidValues() + { + return [ + [false], + [true], + ]; + } + + /** + * @dataProvider getInvalidValues + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $node = new BooleanNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return [ + [null], + [''], + ['foo'], + [0], + [1], + [0.0], + [0.1], + [[]], + [['foo' => 'bar']], + [new \stdClass()], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php new file mode 100644 index 00000000..1123b415 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php @@ -0,0 +1,362 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; +use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition; +use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException; +use Symfony\Component\Config\Definition\Processor; + +class ArrayNodeDefinitionTest extends TestCase +{ + public function testAppendingSomeNode() + { + $parent = new ArrayNodeDefinition('root'); + $child = new ScalarNodeDefinition('child'); + + $parent + ->children() + ->scalarNode('foo')->end() + ->scalarNode('bar')->end() + ->end() + ->append($child); + + $this->assertCount(3, $this->getField($parent, 'children')); + $this->assertContains($child, $this->getField($parent, 'children')); + } + + /** + * @dataProvider providePrototypeNodeSpecificCalls + */ + public function testPrototypeNodeSpecificOption($method, $args) + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidDefinitionException'); + $node = new ArrayNodeDefinition('root'); + + \call_user_func_array([$node, $method], $args); + + $node->getNode(); + } + + public function providePrototypeNodeSpecificCalls() + { + return [ + ['defaultValue', [[]]], + ['addDefaultChildrenIfNoneSet', []], + ['requiresAtLeastOneElement', []], + ['useAttributeAsKey', ['foo']], + ]; + } + + public function testConcreteNodeSpecificOption() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidDefinitionException'); + $node = new ArrayNodeDefinition('root'); + $node + ->addDefaultsIfNotSet() + ->prototype('array') + ; + $node->getNode(); + } + + public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidDefinitionException'); + $node = new ArrayNodeDefinition('root'); + $node + ->defaultValue([]) + ->addDefaultChildrenIfNoneSet('foo') + ->prototype('array') + ; + $node->getNode(); + } + + public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren() + { + $node = new ArrayNodeDefinition('root'); + $node + ->addDefaultChildrenIfNoneSet() + ->prototype('array') + ; + $tree = $node->getNode(); + $this->assertEquals([[]], $tree->getDefaultValue()); + } + + /** + * @dataProvider providePrototypedArrayNodeDefaults + */ + public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults) + { + $node = new ArrayNodeDefinition('root'); + $node + ->addDefaultChildrenIfNoneSet($args) + ->prototype('array') + ; + + try { + $tree = $node->getNode(); + $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey); + $this->assertEquals($defaults, $tree->getDefaultValue()); + } catch (InvalidDefinitionException $e) { + $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey); + } + + $node = new ArrayNodeDefinition('root'); + $node + ->useAttributeAsKey('attr') + ->addDefaultChildrenIfNoneSet($args) + ->prototype('array') + ; + + try { + $tree = $node->getNode(); + $this->assertFalse($shouldThrowWhenUsingAttrAsKey); + $this->assertEquals($defaults, $tree->getDefaultValue()); + } catch (InvalidDefinitionException $e) { + $this->assertTrue($shouldThrowWhenUsingAttrAsKey); + } + } + + public function providePrototypedArrayNodeDefaults() + { + return [ + [null, true, false, [[]]], + [2, true, false, [[], []]], + ['2', false, true, ['2' => []]], + ['foo', false, true, ['foo' => []]], + [['foo'], false, true, ['foo' => []]], + [['foo', 'bar'], false, true, ['foo' => [], 'bar' => []]], + ]; + } + + public function testNestedPrototypedArrayNodes() + { + $nodeDefinition = new ArrayNodeDefinition('root'); + $nodeDefinition + ->addDefaultChildrenIfNoneSet() + ->prototype('array') + ->prototype('array') + ; + $node = $nodeDefinition->getNode(); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node); + $this->assertInstanceOf('Symfony\Component\Config\Definition\PrototypedArrayNode', $node->getPrototype()); + } + + public function testEnabledNodeDefaults() + { + $node = new ArrayNodeDefinition('root'); + $node + ->canBeEnabled() + ->children() + ->scalarNode('foo')->defaultValue('bar')->end() + ; + + $this->assertEquals(['enabled' => false, 'foo' => 'bar'], $node->getNode()->getDefaultValue()); + } + + /** + * @dataProvider getEnableableNodeFixtures + */ + public function testTrueEnableEnabledNode($expected, $config, $message) + { + $processor = new Processor(); + $node = new ArrayNodeDefinition('root'); + $node + ->canBeEnabled() + ->children() + ->scalarNode('foo')->defaultValue('bar')->end() + ; + + $this->assertEquals( + $expected, + $processor->process($node->getNode(), $config), + $message + ); + } + + public function testCanBeDisabled() + { + $node = new ArrayNodeDefinition('root'); + $node->canBeDisabled(); + + $this->assertTrue($this->getField($node, 'addDefaults')); + $this->assertEquals(['enabled' => false], $this->getField($node, 'falseEquivalent')); + $this->assertEquals(['enabled' => true], $this->getField($node, 'trueEquivalent')); + $this->assertEquals(['enabled' => true], $this->getField($node, 'nullEquivalent')); + + $nodeChildren = $this->getField($node, 'children'); + $this->assertArrayHasKey('enabled', $nodeChildren); + + $enabledNode = $nodeChildren['enabled']; + $this->assertTrue($this->getField($enabledNode, 'default')); + $this->assertTrue($this->getField($enabledNode, 'defaultValue')); + } + + public function testIgnoreExtraKeys() + { + $node = new ArrayNodeDefinition('root'); + + $this->assertFalse($this->getField($node, 'ignoreExtraKeys')); + + $result = $node->ignoreExtraKeys(); + + $this->assertEquals($node, $result); + $this->assertTrue($this->getField($node, 'ignoreExtraKeys')); + } + + public function testNormalizeKeys() + { + $node = new ArrayNodeDefinition('root'); + + $this->assertTrue($this->getField($node, 'normalizeKeys')); + + $result = $node->normalizeKeys(false); + + $this->assertEquals($node, $result); + $this->assertFalse($this->getField($node, 'normalizeKeys')); + } + + public function testUnsetChild() + { + $node = new ArrayNodeDefinition('root'); + $node + ->children() + ->scalarNode('value') + ->beforeNormalization() + ->ifTrue(function ($value) { + return empty($value); + }) + ->thenUnset() + ->end() + ->end() + ->end() + ; + + $this->assertSame([], $node->getNode()->normalize(['value' => null])); + } + + public function testPrototypeVariable() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('variable'), $node->variablePrototype()); + } + + public function testPrototypeScalar() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('scalar'), $node->scalarPrototype()); + } + + public function testPrototypeBoolean() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('boolean'), $node->booleanPrototype()); + } + + public function testPrototypeInteger() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('integer'), $node->integerPrototype()); + } + + public function testPrototypeFloat() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('float'), $node->floatPrototype()); + } + + public function testPrototypeArray() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('array'), $node->arrayPrototype()); + } + + public function testPrototypeEnum() + { + $node = new ArrayNodeDefinition('root'); + $this->assertEquals($node->prototype('enum'), $node->enumPrototype()); + } + + public function getEnableableNodeFixtures() + { + return [ + [['enabled' => true, 'foo' => 'bar'], [true], 'true enables an enableable node'], + [['enabled' => true, 'foo' => 'bar'], [null], 'null enables an enableable node'], + [['enabled' => true, 'foo' => 'bar'], [['enabled' => true]], 'An enableable node can be enabled'], + [['enabled' => true, 'foo' => 'baz'], [['foo' => 'baz']], 'any configuration enables an enableable node'], + [['enabled' => false, 'foo' => 'baz'], [['foo' => 'baz', 'enabled' => false]], 'An enableable node can be disabled'], + [['enabled' => false, 'foo' => 'bar'], [false], 'false disables an enableable node'], + ]; + } + + public function testRequiresAtLeastOneElement() + { + $node = new ArrayNodeDefinition('root'); + $node + ->requiresAtLeastOneElement() + ->integerPrototype(); + + $node->getNode()->finalize([1]); + + $this->addToAssertionCount(1); + } + + /** + * @group legacy + * @expectedDeprecation Using Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition::cannotBeEmpty() at path "root" has no effect, consider requiresAtLeastOneElement() instead. In 4.0 both methods will behave the same. + */ + public function testCannotBeEmpty() + { + $node = new ArrayNodeDefinition('root'); + $node + ->cannotBeEmpty() + ->integerPrototype(); + + $node->getNode()->finalize([]); + } + + public function testSetDeprecated() + { + $node = new ArrayNodeDefinition('root'); + $node + ->children() + ->arrayNode('foo')->setDeprecated('The "%path%" node is deprecated.')->end() + ->end() + ; + $deprecatedNode = $node->getNode()->getChildren()['foo']; + + $this->assertTrue($deprecatedNode->isDeprecated()); + $this->assertSame('The "root.foo" node is deprecated.', $deprecatedNode->getDeprecationMessage($deprecatedNode->getName(), $deprecatedNode->getPath())); + } + + /** + * @group legacy + * @expectedDeprecation ->cannotBeEmpty() is not applicable to concrete nodes at path "root". In 4.0 it will throw an exception. + */ + public function testCannotBeEmptyOnConcreteNode() + { + $node = new ArrayNodeDefinition('root'); + $node->cannotBeEmpty(); + + $node->getNode()->finalize([]); + } + + protected function getField($object, $field) + { + $reflection = new \ReflectionProperty($object, $field); + $reflection->setAccessible(true); + + return $reflection->getValue($object); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/BooleanNodeDefinitionTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/BooleanNodeDefinitionTest.php new file mode 100644 index 00000000..6f568a2d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/BooleanNodeDefinitionTest.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition; + +class BooleanNodeDefinitionTest extends TestCase +{ + public function testCannotBeEmptyThrowsAnException() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidDefinitionException'); + $this->expectExceptionMessage('->cannotBeEmpty() is not applicable to BooleanNodeDefinition.'); + $def = new BooleanNodeDefinition('foo'); + $def->cannotBeEmpty(); + } + + public function testSetDeprecated() + { + $def = new BooleanNodeDefinition('foo'); + $def->setDeprecated('The "%path%" node is deprecated.'); + + $node = $def->getNode(); + + $this->assertTrue($node->isDeprecated()); + $this->assertSame('The "foo" node is deprecated.', $node->getDeprecationMessage($node->getName(), $node->getPath())); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php new file mode 100644 index 00000000..2e43a135 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/EnumNodeDefinitionTest.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\EnumNodeDefinition; + +class EnumNodeDefinitionTest extends TestCase +{ + public function testWithOneValue() + { + $def = new EnumNodeDefinition('foo'); + $def->values(['foo']); + + $node = $def->getNode(); + $this->assertEquals(['foo'], $node->getValues()); + } + + public function testWithOneDistinctValue() + { + $def = new EnumNodeDefinition('foo'); + $def->values(['foo', 'foo']); + + $node = $def->getNode(); + $this->assertEquals(['foo'], $node->getValues()); + } + + public function testNoValuesPassed() + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('You must call ->values() on enum nodes.'); + $def = new EnumNodeDefinition('foo'); + $def->getNode(); + } + + public function testWithNoValues() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('->values() must be called with at least one value.'); + $def = new EnumNodeDefinition('foo'); + $def->values([]); + } + + public function testGetNode() + { + $def = new EnumNodeDefinition('foo'); + $def->values(['foo', 'bar']); + + $node = $def->getNode(); + $this->assertEquals(['foo', 'bar'], $node->getValues()); + } + + public function testSetDeprecated() + { + $def = new EnumNodeDefinition('foo'); + $def->values(['foo', 'bar']); + $def->setDeprecated('The "%path%" node is deprecated.'); + + $node = $def->getNode(); + + $this->assertTrue($node->isDeprecated()); + $this->assertSame('The "foo" node is deprecated.', $def->getNode()->getDeprecationMessage($node->getName(), $node->getPath())); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.php new file mode 100644 index 00000000..2dfb7a0a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/ExprBuilderTest.php @@ -0,0 +1,264 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +class ExprBuilderTest extends TestCase +{ + public function testAlwaysExpression() + { + $test = $this->getTestBuilder() + ->always($this->returnClosure('new_value')) + ->end(); + + $this->assertFinalizedValueIs('new_value', $test); + } + + public function testIfTrueExpression() + { + $test = $this->getTestBuilder() + ->ifTrue() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, ['key' => true]); + + $test = $this->getTestBuilder() + ->ifTrue(function ($v) { return true; }) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifTrue(function ($v) { return false; }) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfStringExpression() + { + $test = $this->getTestBuilder() + ->ifString() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifString() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs(45, $test, ['key' => 45]); + } + + public function testIfNullExpression() + { + $test = $this->getTestBuilder() + ->ifNull() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, ['key' => null]); + + $test = $this->getTestBuilder() + ->ifNull() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfEmptyExpression() + { + $test = $this->getTestBuilder() + ->ifEmpty() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, ['key' => []]); + + $test = $this->getTestBuilder() + ->ifEmpty() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfArrayExpression() + { + $test = $this->getTestBuilder() + ->ifArray() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test, ['key' => []]); + + $test = $this->getTestBuilder() + ->ifArray() + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfInArrayExpression() + { + $test = $this->getTestBuilder() + ->ifInArray(['foo', 'bar', 'value']) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifInArray(['foo', 'bar']) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('value', $test); + } + + public function testIfNotInArrayExpression() + { + $test = $this->getTestBuilder() + ->ifNotInArray(['foo', 'bar']) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + + $test = $this->getTestBuilder() + ->ifNotInArray(['foo', 'bar', 'value_from_config']) + ->then($this->returnClosure('new_value')) + ->end(); + $this->assertFinalizedValueIs('new_value', $test); + } + + public function testThenEmptyArrayExpression() + { + $test = $this->getTestBuilder() + ->ifString() + ->thenEmptyArray() + ->end(); + $this->assertFinalizedValueIs([], $test); + } + + /** + * @dataProvider castToArrayValues + */ + public function testCastToArrayExpression($configValue, $expectedValue) + { + $test = $this->getTestBuilder() + ->castToArray() + ->end(); + $this->assertFinalizedValueIs($expectedValue, $test, ['key' => $configValue]); + } + + public function castToArrayValues() + { + yield ['value', ['value']]; + yield [-3.14, [-3.14]]; + yield [null, [null]]; + yield [['value'], ['value']]; + } + + public function testThenInvalid() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $test = $this->getTestBuilder() + ->ifString() + ->thenInvalid('Invalid value') + ->end(); + $this->finalizeTestBuilder($test); + } + + public function testThenUnsetExpression() + { + $test = $this->getTestBuilder() + ->ifString() + ->thenUnset() + ->end(); + $this->assertEquals([], $this->finalizeTestBuilder($test)); + } + + public function testEndIfPartNotSpecified() + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('You must specify an if part.'); + $this->getTestBuilder()->end(); + } + + public function testEndThenPartNotSpecified() + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessage('You must specify a then part.'); + $builder = $this->getTestBuilder(); + $builder->ifPart = 'test'; + $builder->end(); + } + + /** + * Create a test treebuilder with a variable node, and init the validation. + * + * @return TreeBuilder + */ + protected function getTestBuilder() + { + $builder = new TreeBuilder(); + + return $builder + ->root('test') + ->children() + ->variableNode('key') + ->validate() + ; + } + + /** + * Close the validation process and finalize with the given config. + * + * @param TreeBuilder $testBuilder The tree builder to finalize + * @param array $config The config you want to use for the finalization, if nothing provided + * a simple ['key'=>'value'] will be used + * + * @return array The finalized config values + */ + protected function finalizeTestBuilder($testBuilder, $config = null) + { + return $testBuilder + ->end() + ->end() + ->end() + ->buildTree() + ->finalize(null === $config ? ['key' => 'value'] : $config) + ; + } + + /** + * Return a closure that will return the given value. + * + * @param mixed $val The value that the closure must return + * + * @return \Closure + */ + protected function returnClosure($val) + { + return function ($v) use ($val) { + return $val; + }; + } + + /** + * Assert that the given test builder, will return the given value. + * + * @param mixed $value The value to test + * @param TreeBuilder $treeBuilder The tree builder to finalize + * @param mixed $config The config values that new to be finalized + */ + protected function assertFinalizedValueIs($value, $treeBuilder, $config = null) + { + $this->assertEquals(['key' => $value], $this->finalizeTestBuilder($treeBuilder, $config)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php new file mode 100644 index 00000000..46518c65 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/NodeBuilderTest.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder; +use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition; + +class NodeBuilderTest extends TestCase +{ + public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType() + { + $this->expectException('RuntimeException'); + $builder = new BaseNodeBuilder(); + $builder->node('', 'foobar'); + } + + public function testThrowsAnExceptionWhenTheNodeClassIsNotFound() + { + $this->expectException('RuntimeException'); + $builder = new BaseNodeBuilder(); + $builder + ->setNodeClass('noclasstype', '\\foo\\bar\\noclass') + ->node('', 'noclasstype'); + } + + public function testAddingANewNodeType() + { + $class = SomeNodeDefinition::class; + + $builder = new BaseNodeBuilder(); + $node = $builder + ->setNodeClass('newtype', $class) + ->node('', 'newtype'); + + $this->assertInstanceOf($class, $node); + } + + public function testOverridingAnExistingNodeType() + { + $class = SomeNodeDefinition::class; + + $builder = new BaseNodeBuilder(); + $node = $builder + ->setNodeClass('variable', $class) + ->node('', 'variable'); + + $this->assertInstanceOf($class, $node); + } + + public function testNodeTypesAreNotCaseSensitive() + { + $builder = new BaseNodeBuilder(); + + $node1 = $builder->node('', 'VaRiAbLe'); + $node2 = $builder->node('', 'variable'); + + $this->assertInstanceOf(\get_class($node1), $node2); + + $builder->setNodeClass('CuStOm', SomeNodeDefinition::class); + + $node1 = $builder->node('', 'CUSTOM'); + $node2 = $builder->node('', 'custom'); + + $this->assertInstanceOf(\get_class($node1), $node2); + } + + public function testNumericNodeCreation() + { + $builder = new BaseNodeBuilder(); + + $node = $builder->integerNode('foo')->min(3)->max(5); + $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition', $node); + + $node = $builder->floatNode('bar')->min(3.0)->max(5.0); + $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\FloatNodeDefinition', $node); + } +} + +class SomeNodeDefinition extends BaseVariableNodeDefinition +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php new file mode 100644 index 00000000..aa938bba --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/NumericNodeDefinitionTest.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\FloatNodeDefinition; +use Symfony\Component\Config\Definition\Builder\IntegerNodeDefinition; + +class NumericNodeDefinitionTest extends TestCase +{ + public function testIncoherentMinAssertion() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('You cannot define a min(4) as you already have a max(3)'); + $def = new IntegerNodeDefinition('foo'); + $def->max(3)->min(4); + } + + public function testIncoherentMaxAssertion() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('You cannot define a max(2) as you already have a min(3)'); + $node = new IntegerNodeDefinition('foo'); + $node->min(3)->max(2); + } + + public function testIntegerMinAssertion() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('The value 4 is too small for path "foo". Should be greater than or equal to 5'); + $def = new IntegerNodeDefinition('foo'); + $def->min(5)->getNode()->finalize(4); + } + + public function testIntegerMaxAssertion() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('The value 4 is too big for path "foo". Should be less than or equal to 3'); + $def = new IntegerNodeDefinition('foo'); + $def->max(3)->getNode()->finalize(4); + } + + public function testIntegerValidMinMaxAssertion() + { + $def = new IntegerNodeDefinition('foo'); + $node = $def->min(3)->max(7)->getNode(); + $this->assertEquals(4, $node->finalize(4)); + } + + public function testFloatMinAssertion() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('The value 400 is too small for path "foo". Should be greater than or equal to 500'); + $def = new FloatNodeDefinition('foo'); + $def->min(5E2)->getNode()->finalize(4e2); + } + + public function testFloatMaxAssertion() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('The value 4.3 is too big for path "foo". Should be less than or equal to 0.3'); + $def = new FloatNodeDefinition('foo'); + $def->max(0.3)->getNode()->finalize(4.3); + } + + public function testFloatValidMinMaxAssertion() + { + $def = new FloatNodeDefinition('foo'); + $node = $def->min(3.0)->max(7e2)->getNode(); + $this->assertEquals(4.5, $node->finalize(4.5)); + } + + public function testCannotBeEmptyThrowsAnException() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidDefinitionException'); + $this->expectExceptionMessage('->cannotBeEmpty() is not applicable to NumericNodeDefinition.'); + $def = new IntegerNodeDefinition('foo'); + $def->cannotBeEmpty(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.php new file mode 100644 index 00000000..53c9c256 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Builder/TreeBuilderTest.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Builder; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder as CustomNodeBuilder; + +class TreeBuilderTest extends TestCase +{ + public function testUsingACustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('custom', 'array', new CustomNodeBuilder()); + + $nodeBuilder = $root->children(); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder', $nodeBuilder); + + $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children(); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\NodeBuilder', $nodeBuilder); + } + + public function testOverrideABuiltInNodeType() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->variableNode('variable'); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\VariableNodeDefinition', $definition); + } + + public function testAddANodeType() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->barNode('variable'); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\Builder\BarNodeDefinition', $definition); + } + + public function testCreateABuiltInNodeTypeWithACustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('builtin', 'array', new CustomNodeBuilder()); + + $definition = $root->children()->booleanNode('boolean'); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition', $definition); + } + + public function testPrototypedArrayNodeUseTheCustomNodeBuilder() + { + $builder = new TreeBuilder(); + $root = $builder->root('override', 'array', new CustomNodeBuilder()); + + $root->prototype('bar')->end(); + + $this->assertInstanceOf('Symfony\Component\Config\Tests\Fixtures\BarNode', $root->getNode(true)->getPrototype()); + } + + public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren() + { + $builder = new TreeBuilder(); + + $builder->root('propagation') + ->children() + ->setNodeClass('extended', 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition') + ->node('foo', 'extended')->end() + ->arrayNode('child') + ->children() + ->node('foo', 'extended') + ->end() + ->end() + ->end() + ->end(); + + $node = $builder->buildTree(); + $children = $node->getChildren(); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\BooleanNode', $children['foo']); + + $childChildren = $children['child']->getChildren(); + + $this->assertInstanceOf('Symfony\Component\Config\Definition\BooleanNode', $childChildren['foo']); + } + + public function testDefinitionInfoGetsTransferredToNode() + { + $builder = new TreeBuilder(); + + $builder->root('test')->info('root info') + ->children() + ->node('child', 'variable')->info('child info')->defaultValue('default') + ->end() + ->end(); + + $tree = $builder->buildTree(); + $children = $tree->getChildren(); + + $this->assertEquals('root info', $tree->getInfo()); + $this->assertEquals('child info', $children['child']->getInfo()); + } + + public function testDefinitionExampleGetsTransferredToNode() + { + $builder = new TreeBuilder(); + + $builder->root('test') + ->example(['key' => 'value']) + ->children() + ->node('child', 'variable')->info('child info')->defaultValue('default')->example('example') + ->end() + ->end(); + + $tree = $builder->buildTree(); + $children = $tree->getChildren(); + + $this->assertIsArray($tree->getExample()); + $this->assertEquals('example', $children['child']->getExample()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.php new file mode 100644 index 00000000..1bd60215 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Dumper/XmlReferenceDumperTest.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Dumper\XmlReferenceDumper; +use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration; + +class XmlReferenceDumperTest extends TestCase +{ + public function testDumper() + { + $configuration = new ExampleConfiguration(); + + $dumper = new XmlReferenceDumper(); + $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); + } + + public function testNamespaceDumper() + { + $configuration = new ExampleConfiguration(); + + $dumper = new XmlReferenceDumper(); + $this->assertEquals(str_replace('http://example.org/schema/dic/acme_root', 'http://symfony.com/schema/dic/symfony', $this->getConfigurationAsString()), $dumper->dump($configuration, 'http://symfony.com/schema/dic/symfony')); + } + + private function getConfigurationAsString() + { + return str_replace("\n", \PHP_EOL, <<<'EOL' + + + + + + + + + + + + + + scalar value + + + scalar value + + + + + + + + + + + + + + + + + + + + + + + + +EOL + ); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php new file mode 100644 index 00000000..3cb9121b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -0,0 +1,143 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper; +use Symfony\Component\Config\Tests\Fixtures\Configuration\ExampleConfiguration; + +class YamlReferenceDumperTest extends TestCase +{ + public function testDumper() + { + $configuration = new ExampleConfiguration(); + + $dumper = new YamlReferenceDumper(); + + $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); + } + + public function provideDumpAtPath() + { + return [ + 'Regular node' => ['scalar_true', << ['array', << ['array.child2', << ['cms_pages.page', << ['cms_pages.page.locale', <<assertSame(trim($expected), trim($dumper->dumpAtPath($configuration, $path))); + } + + private function getConfigurationAsString() + { + return <<<'EOL' +acme_root: + boolean: true + scalar_empty: ~ + scalar_null: null + scalar_true: true + scalar_false: false + scalar_default: default + scalar_array_empty: [] + scalar_array_defaults: + + # Defaults: + - elem1 + - elem2 + scalar_required: ~ # Required + scalar_deprecated: ~ # Deprecated (The child node "scalar_deprecated" at path "acme_root" is deprecated.) + scalar_deprecated_with_message: ~ # Deprecated (Deprecation custom message for "scalar_deprecated_with_message" at "acme_root") + node_with_a_looong_name: ~ + enum_with_default: this # One of "this"; "that" + enum: ~ # One of "this"; "that" + + # some info + array: + child1: ~ + child2: ~ + + # this is a long + # multi-line info text + # which should be indented + child3: ~ # Example: example setting + scalar_prototyped: [] + parameters: + + # Prototype: Parameter name + name: ~ + connections: + + # Prototype + - + user: ~ + pass: ~ + cms_pages: + + # Prototype + page: + + # Prototype + locale: + title: ~ # Required + path: ~ # Required + pipou: + + # Prototype + name: [] + +EOL; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/EnumNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/EnumNodeTest.php new file mode 100644 index 00000000..fa89eea2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/EnumNodeTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\EnumNode; + +class EnumNodeTest extends TestCase +{ + public function testFinalizeValue() + { + $node = new EnumNode('foo', null, ['foo', 'bar']); + $this->assertSame('foo', $node->finalize('foo')); + } + + public function testConstructionWithNoValues() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('$values must contain at least one element.'); + new EnumNode('foo', null, []); + } + + public function testConstructionWithOneValue() + { + $node = new EnumNode('foo', null, ['foo']); + $this->assertSame('foo', $node->finalize('foo')); + } + + public function testConstructionWithOneDistinctValue() + { + $node = new EnumNode('foo', null, ['foo', 'foo']); + $this->assertSame('foo', $node->finalize('foo')); + } + + public function testFinalizeWithInvalidValue() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('The value "foobar" is not allowed for path "foo". Permissible values: "foo", "bar"'); + $node = new EnumNode('foo', null, ['foo', 'bar']); + $node->finalize('foobar'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/FinalizationTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/FinalizationTest.php new file mode 100644 index 00000000..be68a27c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/FinalizationTest.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\NodeInterface; +use Symfony\Component\Config\Definition\Processor; + +class FinalizationTest extends TestCase +{ + public function testUnsetKeyWithDeepHierarchy() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('config', 'array') + ->children() + ->node('level1', 'array') + ->canBeUnset() + ->children() + ->node('level2', 'array') + ->canBeUnset() + ->children() + ->node('somevalue', 'scalar')->end() + ->node('anothervalue', 'scalar')->end() + ->end() + ->end() + ->node('level1_scalar', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = [ + 'level1' => [ + 'level2' => [ + 'somevalue' => 'foo', + 'anothervalue' => 'bar', + ], + 'level1_scalar' => 'foo', + ], + ]; + + $b = [ + 'level1' => [ + 'level2' => false, + ], + ]; + + $this->assertEquals([ + 'level1' => [ + 'level1_scalar' => 'foo', + ], + ], $this->process($tree, [$a, $b])); + } + + protected function process(NodeInterface $tree, array $configs) + { + $processor = new Processor(); + + return $processor->process($tree, $configs); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/FloatNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/FloatNodeTest.php new file mode 100644 index 00000000..fed9f013 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/FloatNodeTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\FloatNode; + +class FloatNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new FloatNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + /** + * @dataProvider getValidValues + * + * @param int $value + */ + public function testValidNonEmptyValues($value) + { + $node = new FloatNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidValues() + { + return [ + [1798.0], + [-678.987], + [12.56E45], + [0.0], + // Integer are accepted too, they will be cast + [17], + [-10], + [0], + ]; + } + + /** + * @dataProvider getInvalidValues + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $node = new FloatNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return [ + [null], + [''], + ['foo'], + [true], + [false], + [[]], + [['foo' => 'bar']], + [new \stdClass()], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/IntegerNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/IntegerNodeTest.php new file mode 100644 index 00000000..3fb1b771 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/IntegerNodeTest.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\IntegerNode; + +class IntegerNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new IntegerNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + /** + * @dataProvider getValidValues + * + * @param int $value + */ + public function testValidNonEmptyValues($value) + { + $node = new IntegerNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidValues() + { + return [ + [1798], + [-678], + [0], + ]; + } + + /** + * @dataProvider getInvalidValues + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $node = new IntegerNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return [ + [null], + [''], + ['foo'], + [true], + [false], + [0.0], + [0.1], + [[]], + [['foo' => 'bar']], + [new \stdClass()], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/MergeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/MergeTest.php new file mode 100644 index 00000000..8fee2635 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/MergeTest.php @@ -0,0 +1,192 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; + +class MergeTest extends TestCase +{ + public function testForbiddenOverwrite() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException'); + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('foo', 'scalar') + ->cannotBeOverwritten() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = [ + 'foo' => 'bar', + ]; + + $b = [ + 'foo' => 'moo', + ]; + + $tree->merge($a, $b); + } + + public function testUnsetKey() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('foo', 'scalar')->end() + ->node('bar', 'scalar')->end() + ->node('unsettable', 'array') + ->canBeUnset() + ->children() + ->node('foo', 'scalar')->end() + ->node('bar', 'scalar')->end() + ->end() + ->end() + ->node('unsetted', 'array') + ->canBeUnset() + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = [ + 'foo' => 'bar', + 'unsettable' => [ + 'foo' => 'a', + 'bar' => 'b', + ], + 'unsetted' => false, + ]; + + $b = [ + 'foo' => 'moo', + 'bar' => 'b', + 'unsettable' => false, + 'unsetted' => ['a', 'b'], + ]; + + $this->assertEquals([ + 'foo' => 'moo', + 'bar' => 'b', + 'unsettable' => false, + 'unsetted' => ['a', 'b'], + ], $tree->merge($a, $b)); + } + + public function testDoesNotAllowNewKeysInSubsequentConfigs() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $tb = new TreeBuilder(); + $tree = $tb + ->root('config', 'array') + ->children() + ->node('test', 'array') + ->disallowNewKeysInSubsequentConfigs() + ->useAttributeAsKey('key') + ->prototype('array') + ->children() + ->node('value', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree(); + + $a = [ + 'test' => [ + 'a' => ['value' => 'foo'], + ], + ]; + + $b = [ + 'test' => [ + 'b' => ['value' => 'foo'], + ], + ]; + + $tree->merge($a, $b); + } + + public function testPerformsNoDeepMerging() + { + $tb = new TreeBuilder(); + + $tree = $tb + ->root('config', 'array') + ->children() + ->node('no_deep_merging', 'array') + ->performNoDeepMerging() + ->children() + ->node('foo', 'scalar')->end() + ->node('bar', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = [ + 'no_deep_merging' => [ + 'foo' => 'a', + 'bar' => 'b', + ], + ]; + + $b = [ + 'no_deep_merging' => [ + 'c' => 'd', + ], + ]; + + $this->assertEquals([ + 'no_deep_merging' => [ + 'c' => 'd', + ], + ], $tree->merge($a, $b)); + } + + public function testPrototypeWithoutAKeyAttribute() + { + $tb = new TreeBuilder(); + + $tree = $tb + ->root('config', 'array') + ->children() + ->arrayNode('append_elements') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $a = [ + 'append_elements' => ['a', 'b'], + ]; + + $b = [ + 'append_elements' => ['c', 'd'], + ]; + + $this->assertEquals(['append_elements' => ['a', 'b', 'c', 'd']], $tree->merge($a, $b)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/NormalizationTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/NormalizationTest.php new file mode 100644 index 00000000..200a9859 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/NormalizationTest.php @@ -0,0 +1,228 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\NodeInterface; + +class NormalizationTest extends TestCase +{ + /** + * @dataProvider getEncoderTests + */ + public function testNormalizeEncoders($denormalized) + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root_name', 'array') + ->fixXmlConfig('encoder') + ->children() + ->node('encoders', 'array') + ->useAttributeAsKey('class') + ->prototype('array') + ->beforeNormalization()->ifString()->then(function ($v) { return ['algorithm' => $v]; })->end() + ->children() + ->node('algorithm', 'scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $normalized = [ + 'encoders' => [ + 'foo' => ['algorithm' => 'plaintext'], + ], + ]; + + $this->assertNormalized($tree, $denormalized, $normalized); + } + + public function getEncoderTests() + { + $configs = []; + + // XML + $configs[] = [ + 'encoder' => [ + ['class' => 'foo', 'algorithm' => 'plaintext'], + ], + ]; + + // XML when only one element of this type + $configs[] = [ + 'encoder' => ['class' => 'foo', 'algorithm' => 'plaintext'], + ]; + + // YAML/PHP + $configs[] = [ + 'encoders' => [ + ['class' => 'foo', 'algorithm' => 'plaintext'], + ], + ]; + + // YAML/PHP + $configs[] = [ + 'encoders' => [ + 'foo' => 'plaintext', + ], + ]; + + // YAML/PHP + $configs[] = [ + 'encoders' => [ + 'foo' => ['algorithm' => 'plaintext'], + ], + ]; + + return array_map(function ($v) { + return [$v]; + }, $configs); + } + + /** + * @dataProvider getAnonymousKeysTests + */ + public function testAnonymousKeysArray($denormalized) + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('logout', 'array') + ->fixXmlConfig('handler') + ->children() + ->node('handlers', 'array') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $normalized = ['logout' => ['handlers' => ['a', 'b', 'c']]]; + + $this->assertNormalized($tree, $denormalized, $normalized); + } + + public function getAnonymousKeysTests() + { + $configs = []; + + $configs[] = [ + 'logout' => [ + 'handlers' => ['a', 'b', 'c'], + ], + ]; + + $configs[] = [ + 'logout' => [ + 'handler' => ['a', 'b', 'c'], + ], + ]; + + return array_map(function ($v) { return [$v]; }, $configs); + } + + /** + * @dataProvider getNumericKeysTests + */ + public function testNumericKeysAsAttributes($denormalized) + { + $normalized = [ + 'thing' => [42 => ['foo', 'bar'], 1337 => ['baz', 'qux']], + ]; + + $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, $normalized); + } + + public function getNumericKeysTests() + { + $configs = []; + + $configs[] = [ + 'thing' => [ + 42 => ['foo', 'bar'], 1337 => ['baz', 'qux'], + ], + ]; + + $configs[] = [ + 'thing' => [ + ['foo', 'bar', 'id' => 42], ['baz', 'qux', 'id' => 1337], + ], + ]; + + return array_map(function ($v) { return [$v]; }, $configs); + } + + public function testNonAssociativeArrayThrowsExceptionIfAttributeNotSet() + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $this->expectExceptionMessage('The attribute "id" must be set for path "root.thing".'); + $denormalized = [ + 'thing' => [ + ['foo', 'bar'], ['baz', 'qux'], + ], + ]; + + $this->assertNormalized($this->getNumericKeysTestTree(), $denormalized, []); + } + + public function testAssociativeArrayPreserveKeys() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->prototype('array') + ->children() + ->node('foo', 'scalar')->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + $data = ['first' => ['foo' => 'bar']]; + + $this->assertNormalized($tree, $data, $data); + } + + public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized) + { + self::assertSame($normalized, $tree->normalize($denormalized)); + } + + private function getNumericKeysTestTree() + { + $tb = new TreeBuilder(); + $tree = $tb + ->root('root', 'array') + ->children() + ->node('thing', 'array') + ->useAttributeAsKey('id') + ->prototype('array') + ->prototype('scalar')->end() + ->end() + ->end() + ->end() + ->end() + ->buildTree() + ; + + return $tree; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php new file mode 100644 index 00000000..7a58ead8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/PrototypedArrayNodeTest.php @@ -0,0 +1,341 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\PrototypedArrayNode; +use Symfony\Component\Config\Definition\ScalarNode; +use Symfony\Component\Config\Definition\VariableNode; + +class PrototypedArrayNodeTest extends TestCase +{ + public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes() + { + $node = new PrototypedArrayNode('root'); + $prototype = new ArrayNode(null, $node); + $node->setPrototype($prototype); + $this->assertEmpty($node->getDefaultValue()); + } + + public function testGetDefaultValueReturnsDefaultValueForPrototypes() + { + $node = new PrototypedArrayNode('root'); + $prototype = new ArrayNode(null, $node); + $node->setPrototype($prototype); + $node->setDefaultValue(['test']); + $this->assertEquals(['test'], $node->getDefaultValue()); + } + + // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used + public function testRemappedKeysAreUnset() + { + $node = new ArrayNode('root'); + $mappingsNode = new PrototypedArrayNode('mappings'); + $node->addChild($mappingsNode); + + // each item under mappings is just a scalar + $prototype = new ScalarNode(null, $mappingsNode); + $mappingsNode->setPrototype($prototype); + + $remappings = []; + $remappings[] = ['mapping', 'mappings']; + $node->setXmlRemappings($remappings); + + $normalized = $node->normalize(['mapping' => ['foo', 'bar']]); + $this->assertEquals(['mappings' => ['foo', 'bar']], $normalized); + } + + /** + * Tests that when a key attribute is mapped, that key is removed from the array. + * + * + * + * + * The above should finally be mapped to an array that looks like this + * (because "id" is the key attribute). + * + * [ + * 'things' => [ + * 'option1' => 'foo', + * 'option2' => 'bar', + * ] + * ] + */ + public function testMappedAttributeKeyIsRemoved() + { + $node = new PrototypedArrayNode('root'); + $node->setKeyAttribute('id', true); + + // each item under the root is an array, with one scalar item + $prototype = new ArrayNode(null, $node); + $prototype->addChild(new ScalarNode('foo')); + $node->setPrototype($prototype); + + $children = []; + $children[] = ['id' => 'item_name', 'foo' => 'bar']; + $normalized = $node->normalize($children); + + $expected = []; + $expected['item_name'] = ['foo' => 'bar']; + $this->assertEquals($expected, $normalized); + } + + /** + * Tests the opposite of the testMappedAttributeKeyIsRemoved because + * the removal can be toggled with an option. + */ + public function testMappedAttributeKeyNotRemoved() + { + $node = new PrototypedArrayNode('root'); + $node->setKeyAttribute('id', false); + + // each item under the root is an array, with two scalar items + $prototype = new ArrayNode(null, $node); + $prototype->addChild(new ScalarNode('foo')); + $prototype->addChild(new ScalarNode('id')); // the key attribute will remain + $node->setPrototype($prototype); + + $children = []; + $children[] = ['id' => 'item_name', 'foo' => 'bar']; + $normalized = $node->normalize($children); + + $expected = []; + $expected['item_name'] = ['id' => 'item_name', 'foo' => 'bar']; + $this->assertEquals($expected, $normalized); + } + + public function testAddDefaultChildren() + { + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals([['foo' => 'bar']], $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet(); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(['defaults' => ['foo' => 'bar']], $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet('defaultkey'); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(['defaultkey' => ['foo' => 'bar']], $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet(['defaultkey']); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(['defaultkey' => ['foo' => 'bar']], $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setKeyAttribute('foobar'); + $node->setAddChildrenIfNoneSet(['dk1', 'dk2']); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals(['dk1' => ['foo' => 'bar'], 'dk2' => ['foo' => 'bar']], $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet([5, 6]); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals([0 => ['foo' => 'bar'], 1 => ['foo' => 'bar']], $node->getDefaultValue()); + + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(2); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals([['foo' => 'bar'], ['foo' => 'bar']], $node->getDefaultValue()); + } + + public function testDefaultChildrenWinsOverDefaultValue() + { + $node = $this->getPrototypeNodeWithDefaultChildren(); + $node->setAddChildrenIfNoneSet(); + $node->setDefaultValue(['bar' => 'foo']); + $this->assertTrue($node->hasDefaultValue()); + $this->assertEquals([['foo' => 'bar']], $node->getDefaultValue()); + } + + protected function getPrototypeNodeWithDefaultChildren() + { + $node = new PrototypedArrayNode('root'); + $prototype = new ArrayNode(null, $node); + $child = new ScalarNode('foo'); + $child->setDefaultValue('bar'); + $prototype->addChild($child); + $prototype->setAddIfNotSet(true); + $node->setPrototype($prototype); + + return $node; + } + + /** + * Tests that when a key attribute is mapped, that key is removed from the array. + * And if only 'value' element is left in the array, it will replace its wrapper array. + * + * + * + * + * The above should finally be mapped to an array that looks like this + * (because "id" is the key attribute). + * + * [ + * 'things' => [ + * 'option1' => 'value1' + * ] + * ] + * + * It's also possible to mix 'value-only' and 'non-value-only' elements in the array. + * + * + * + * + * The above should finally be mapped to an array as follows + * + * [ + * 'things' => [ + * 'option1' => 'value1', + * 'option2' => [ + * 'value' => 'value2', + * 'foo' => 'foo2' + * ] + * ] + * ] + * + * The 'value' element can also be ArrayNode: + * + * + * + * + * + * The above should be finally be mapped to an array as follows + * + * [ + * 'things' => [ + * 'option1' => [ + * 'foo' => 'foo1', + * 'bar' => 'bar1' + * ] + * ] + * ] + * + * If using VariableNode for value node, it's also possible to mix different types of value nodes: + * + * + * + * + * + * The above should be finally mapped to an array as follows + * + * [ + * 'things' => [ + * 'option1' => [ + * 'foo' => 'foo1', + * 'bar' => 'bar1' + * ], + * 'option2' => 'value2' + * ] + * ] + * + * @dataProvider getDataForKeyRemovedLeftValueOnly + */ + public function testMappedAttributeKeyIsRemovedLeftValueOnly($value, $children, $expected) + { + $node = new PrototypedArrayNode('root'); + $node->setKeyAttribute('id', true); + + // each item under the root is an array, with one scalar item + $prototype = new ArrayNode(null, $node); + $prototype->addChild(new ScalarNode('id')); + $prototype->addChild(new ScalarNode('foo')); + $prototype->addChild($value); + $node->setPrototype($prototype); + + $normalized = $node->normalize($children); + $this->assertEquals($expected, $normalized); + } + + public function getDataForKeyRemovedLeftValueOnly() + { + $scalarValue = new ScalarNode('value'); + + $arrayValue = new ArrayNode('value'); + $arrayValue->addChild(new ScalarNode('foo')); + $arrayValue->addChild(new ScalarNode('bar')); + + $variableValue = new VariableNode('value'); + + return [ + [ + $scalarValue, + [ + ['id' => 'option1', 'value' => 'value1'], + ], + ['option1' => 'value1'], + ], + + [ + $scalarValue, + [ + ['id' => 'option1', 'value' => 'value1'], + ['id' => 'option2', 'value' => 'value2', 'foo' => 'foo2'], + ], + [ + 'option1' => 'value1', + 'option2' => ['value' => 'value2', 'foo' => 'foo2'], + ], + ], + + [ + $arrayValue, + [ + [ + 'id' => 'option1', + 'value' => ['foo' => 'foo1', 'bar' => 'bar1'], + ], + ], + [ + 'option1' => ['foo' => 'foo1', 'bar' => 'bar1'], + ], + ], + + [$variableValue, + [ + [ + 'id' => 'option1', 'value' => ['foo' => 'foo1', 'bar' => 'bar1'], + ], + ['id' => 'option2', 'value' => 'value2'], + ], + [ + 'option1' => ['foo' => 'foo1', 'bar' => 'bar1'], + 'option2' => 'value2', + ], + ], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/ScalarNodeTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/ScalarNodeTest.php new file mode 100644 index 00000000..ac2d9376 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Definition/ScalarNodeTest.php @@ -0,0 +1,161 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Definition; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\ArrayNode; +use Symfony\Component\Config\Definition\ScalarNode; + +class ScalarNodeTest extends TestCase +{ + /** + * @dataProvider getValidValues + */ + public function testNormalize($value) + { + $node = new ScalarNode('test'); + $this->assertSame($value, $node->normalize($value)); + } + + public function getValidValues() + { + return [ + [false], + [true], + [null], + [''], + ['foo'], + [0], + [1], + [0.0], + [0.1], + ]; + } + + public function testSetDeprecated() + { + $childNode = new ScalarNode('foo'); + $childNode->setDeprecated('"%node%" is deprecated'); + + $this->assertTrue($childNode->isDeprecated()); + $this->assertSame('"foo" is deprecated', $childNode->getDeprecationMessage($childNode->getName(), $childNode->getPath())); + + $node = new ArrayNode('root'); + $node->addChild($childNode); + + $deprecationTriggered = 0; + $deprecationHandler = function ($level, $message, $file, $line) use (&$prevErrorHandler, &$deprecationTriggered) { + if (\E_USER_DEPRECATED === $level) { + return ++$deprecationTriggered; + } + + return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false; + }; + + $prevErrorHandler = set_error_handler($deprecationHandler); + $node->finalize([]); + restore_error_handler(); + $this->assertSame(0, $deprecationTriggered, '->finalize() should not trigger if the deprecated node is not set'); + + $prevErrorHandler = set_error_handler($deprecationHandler); + $node->finalize(['foo' => '']); + restore_error_handler(); + $this->assertSame(1, $deprecationTriggered, '->finalize() should trigger if the deprecated node is set'); + } + + /** + * @dataProvider getInvalidValues + */ + public function testNormalizeThrowsExceptionOnInvalidValues($value) + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $node = new ScalarNode('test'); + $node->normalize($value); + } + + public function getInvalidValues() + { + return [ + [[]], + [['foo' => 'bar']], + [new \stdClass()], + ]; + } + + public function testNormalizeThrowsExceptionWithoutHint() + { + $node = new ScalarNode('test'); + + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $this->expectExceptionMessage('Invalid type for path "test". Expected scalar, but got array.'); + + $node->normalize([]); + } + + public function testNormalizeThrowsExceptionWithErrorMessage() + { + $node = new ScalarNode('test'); + $node->setInfo('"the test value"'); + + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidTypeException'); + $this->expectExceptionMessage("Invalid type for path \"test\". Expected scalar, but got array.\nHint: \"the test value\""); + + $node->normalize([]); + } + + /** + * @dataProvider getValidNonEmptyValues + * + * @param mixed $value + */ + public function testValidNonEmptyValues($value) + { + $node = new ScalarNode('test'); + $node->setAllowEmptyValue(false); + + $this->assertSame($value, $node->finalize($value)); + } + + public function getValidNonEmptyValues() + { + return [ + [false], + [true], + ['foo'], + [0], + [1], + [0.0], + [0.1], + ]; + } + + /** + * @dataProvider getEmptyValues + * + * @param mixed $value + */ + public function testNotAllowedEmptyValuesThrowException($value) + { + $this->expectException('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException'); + $node = new ScalarNode('test'); + $node->setAllowEmptyValue(false); + $node->finalize($value); + } + + public function getEmptyValues() + { + return [ + [null], + [''], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/DependencyInjection/ConfigCachePassTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/DependencyInjection/ConfigCachePassTest.php new file mode 100644 index 00000000..c2b95195 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/DependencyInjection/ConfigCachePassTest.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\DependencyInjection\ConfigCachePass; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @group legacy + */ +class ConfigCachePassTest extends TestCase +{ + public function testThatCheckersAreProcessedInPriorityOrder() + { + $container = new ContainerBuilder(); + + $definition = $container->register('config_cache_factory')->addArgument(null); + $container->register('checker_2')->addTag('config_cache.resource_checker', ['priority' => 100]); + $container->register('checker_1')->addTag('config_cache.resource_checker', ['priority' => 200]); + $container->register('checker_3')->addTag('config_cache.resource_checker'); + + $pass = new ConfigCachePass(); + $pass->process($container); + + $expected = new IteratorArgument([ + new Reference('checker_1'), + new Reference('checker_2'), + new Reference('checker_3'), + ]); + $this->assertEquals($expected, $definition->getArgument(0)); + } + + public function testThatCheckersCanBeMissing() + { + $container = new ContainerBuilder(); + + $definitionsBefore = \count($container->getDefinitions()); + $aliasesBefore = \count($container->getAliases()); + + $pass = new ConfigCachePass(); + $pass->process($container); + + // the container is untouched (i.e. no new definitions or aliases) + $this->assertCount($definitionsBefore, $container->getDefinitions()); + $this->assertCount($aliasesBefore, $container->getAliases()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php new file mode 100644 index 00000000..8363084c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Exception/FileLoaderLoadExceptionTest.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Exception; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Exception\FileLoaderLoadException; + +class FileLoaderLoadExceptionTest extends TestCase +{ + public function testMessageCannotLoadResource() + { + $exception = new FileLoaderLoadException('resource', null); + $this->assertEquals('Cannot load resource "resource".', $exception->getMessage()); + } + + public function testMessageCannotLoadResourceWithType() + { + $exception = new FileLoaderLoadException('resource', null, null, null, 'foobar'); + $this->assertEquals('Cannot load resource "resource". Make sure there is a loader supporting the "foobar" type.', $exception->getMessage()); + } + + public function testMessageCannotLoadResourceWithAnnotationType() + { + $exception = new FileLoaderLoadException('resource', null, null, null, 'annotation'); + $this->assertEquals('Cannot load resource "resource". Make sure annotations are installed and enabled.', $exception->getMessage()); + } + + public function testMessageCannotImportResourceFromSource() + { + $exception = new FileLoaderLoadException('resource', 'sourceResource'); + $this->assertEquals('Cannot import resource "resource" from "sourceResource".', $exception->getMessage()); + } + + public function testMessageCannotImportBundleResource() + { + $exception = new FileLoaderLoadException('@resource', 'sourceResource'); + $this->assertEquals( + 'Cannot import resource "@resource" from "sourceResource". '. + 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '. + 'If the bundle is registered, make sure the bundle path "@resource" is not empty.', + $exception->getMessage() + ); + } + + public function testMessageHasPreviousErrorWithDotAndUnableToLoad() + { + $exception = new FileLoaderLoadException( + 'resource', + null, + null, + new \Exception('There was a previous error with an ending dot.') + ); + $this->assertEquals( + 'There was a previous error with an ending dot in resource (which is loaded in resource "resource").', + $exception->getMessage() + ); + } + + public function testMessageHasPreviousErrorWithoutDotAndUnableToLoad() + { + $exception = new FileLoaderLoadException( + 'resource', + null, + null, + new \Exception('There was a previous error with no ending dot') + ); + $this->assertEquals( + 'There was a previous error with no ending dot in resource (which is loaded in resource "resource").', + $exception->getMessage() + ); + } + + public function testMessageHasPreviousErrorAndUnableToLoadBundle() + { + $exception = new FileLoaderLoadException( + '@resource', + null, + null, + new \Exception('There was a previous error with an ending dot.') + ); + $this->assertEquals( + 'There was a previous error with an ending dot in @resource '. + '(which is loaded in resource "@resource"). '. + 'Make sure the "resource" bundle is correctly registered and loaded in the application kernel class. '. + 'If the bundle is registered, make sure the bundle path "@resource" is not empty.', + $exception->getMessage() + ); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/FileLocatorTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/FileLocatorTest.php new file mode 100644 index 00000000..e931916a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/FileLocatorTest.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; + +class FileLocatorTest extends TestCase +{ + /** + * @dataProvider getIsAbsolutePathTests + */ + public function testIsAbsolutePath($path) + { + $loader = new FileLocator([]); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('isAbsolutePath'); + $m->setAccessible(true); + + $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path'); + } + + public function getIsAbsolutePathTests() + { + return [ + ['/foo.xml'], + ['c:\\\\foo.xml'], + ['c:/foo.xml'], + ['\\server\\foo.xml'], + ['https://server/foo.xml'], + ['phar://server/foo.xml'], + ]; + } + + public function testLocate() + { + $loader = new FileLocator(__DIR__.'/Fixtures'); + + $this->assertEquals( + __DIR__.\DIRECTORY_SEPARATOR.'FileLocatorTest.php', + $loader->locate('FileLocatorTest.php', __DIR__), + '->locate() returns the absolute filename if the file exists in the given path' + ); + + $this->assertEquals( + __DIR__.'/Fixtures'.\DIRECTORY_SEPARATOR.'foo.xml', + $loader->locate('foo.xml', __DIR__), + '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor' + ); + + $this->assertEquals( + __DIR__.'/Fixtures'.\DIRECTORY_SEPARATOR.'foo.xml', + $loader->locate(__DIR__.'/Fixtures'.\DIRECTORY_SEPARATOR.'foo.xml', __DIR__), + '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor' + ); + + $loader = new FileLocator([__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again']); + + $this->assertEquals( + [__DIR__.'/Fixtures'.\DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.\DIRECTORY_SEPARATOR.'foo.xml'], + $loader->locate('foo.xml', __DIR__, false), + '->locate() returns an array of absolute filenames' + ); + + $this->assertEquals( + [__DIR__.'/Fixtures'.\DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.\DIRECTORY_SEPARATOR.'foo.xml'], + $loader->locate('foo.xml', __DIR__.'/Fixtures', false), + '->locate() returns an array of absolute filenames' + ); + + $loader = new FileLocator(__DIR__.'/Fixtures/Again'); + + $this->assertEquals( + [__DIR__.'/Fixtures'.\DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.\DIRECTORY_SEPARATOR.'foo.xml'], + $loader->locate('foo.xml', __DIR__.'/Fixtures', false), + '->locate() returns an array of absolute filenames' + ); + } + + public function testLocateThrowsAnExceptionIfTheFileDoesNotExists() + { + $this->expectException('Symfony\Component\Config\Exception\FileLocatorFileNotFoundException'); + $this->expectExceptionMessage('The file "foobar.xml" does not exist'); + $loader = new FileLocator([__DIR__.'/Fixtures']); + + $loader->locate('foobar.xml', __DIR__); + } + + public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath() + { + $this->expectException('Symfony\Component\Config\Exception\FileLocatorFileNotFoundException'); + $loader = new FileLocator([__DIR__.'/Fixtures']); + + $loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__); + } + + public function testLocateEmpty() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('An empty file name is not valid to be located.'); + $loader = new FileLocator([__DIR__.'/Fixtures']); + + $loader->locate(null, __DIR__); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Again/foo.xml b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Again/foo.xml new file mode 100644 index 00000000..e69de29b diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/BadFileName.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/BadFileName.php new file mode 100644 index 00000000..0f79bdd5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/BadFileName.php @@ -0,0 +1,9 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures; + +use Symfony\Component\Config\Definition\ArrayNode; + +class BarNode extends ArrayNode +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php new file mode 100644 index 00000000..b9c62e53 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/BarNodeDefinition.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures\Builder; + +use Symfony\Component\Config\Definition\Builder\NodeDefinition; +use Symfony\Component\Config\Tests\Fixtures\BarNode; + +class BarNodeDefinition extends NodeDefinition +{ + protected function createNode() + { + return new BarNode($this->name); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php new file mode 100644 index 00000000..22b8b32f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/NodeBuilder.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures\Builder; + +use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder; + +class NodeBuilder extends BaseNodeBuilder +{ + public function barNode($name) + { + return $this->node($name, 'bar'); + } + + protected function getNodeClass($type) + { + switch ($type) { + case 'variable': + return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; + case 'bar': + return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition'; + default: + return parent::getNodeClass($type); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php new file mode 100644 index 00000000..6126ed43 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Builder/VariableNodeDefinition.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures\Builder; + +use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition; + +class VariableNodeDefinition extends BaseVariableNodeDefinition +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php new file mode 100644 index 00000000..3f02700a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Configuration/ExampleConfiguration.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Fixtures\Configuration; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +class ExampleConfiguration implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('acme_root'); + + $rootNode + ->fixXmlConfig('parameter') + ->fixXmlConfig('connection') + ->fixXmlConfig('cms_page') + ->children() + ->booleanNode('boolean')->defaultTrue()->end() + ->scalarNode('scalar_empty')->end() + ->scalarNode('scalar_null')->defaultNull()->end() + ->scalarNode('scalar_true')->defaultTrue()->end() + ->scalarNode('scalar_false')->defaultFalse()->end() + ->scalarNode('scalar_default')->defaultValue('default')->end() + ->scalarNode('scalar_array_empty')->defaultValue([])->end() + ->scalarNode('scalar_array_defaults')->defaultValue(['elem1', 'elem2'])->end() + ->scalarNode('scalar_required')->isRequired()->end() + ->scalarNode('scalar_deprecated')->setDeprecated()->end() + ->scalarNode('scalar_deprecated_with_message')->setDeprecated('Deprecation custom message for "%node%" at "%path%"')->end() + ->scalarNode('node_with_a_looong_name')->end() + ->enumNode('enum_with_default')->values(['this', 'that'])->defaultValue('this')->end() + ->enumNode('enum')->values(['this', 'that'])->end() + ->arrayNode('array') + ->info('some info') + ->canBeUnset() + ->children() + ->scalarNode('child1')->end() + ->scalarNode('child2')->end() + ->scalarNode('child3') + ->info( + "this is a long\n". + "multi-line info text\n". + 'which should be indented' + ) + ->example('example setting') + ->end() + ->end() + ->end() + ->arrayNode('scalar_prototyped') + ->prototype('scalar')->end() + ->end() + ->arrayNode('parameters') + ->useAttributeAsKey('name') + ->prototype('scalar')->info('Parameter name')->end() + ->end() + ->arrayNode('connections') + ->prototype('array') + ->children() + ->scalarNode('user')->end() + ->scalarNode('pass')->end() + ->end() + ->end() + ->end() + ->arrayNode('cms_pages') + ->useAttributeAsKey('page') + ->prototype('array') + ->useAttributeAsKey('locale') + ->prototype('array') + ->children() + ->scalarNode('title')->isRequired()->end() + ->scalarNode('path')->isRequired()->end() + ->end() + ->end() + ->end() + ->end() + ->arrayNode('pipou') + ->useAttributeAsKey('name') + ->prototype('array') + ->prototype('array') + ->children() + ->scalarNode('didou') + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/ParseError.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/ParseError.php new file mode 100644 index 00000000..6bb22138 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/ParseError.php @@ -0,0 +1,7 @@ + +]> + diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/invalid.xml b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/invalid.xml new file mode 100644 index 00000000..a07af9fd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/invalid.xml @@ -0,0 +1,2 @@ + + diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/invalid_schema.xml b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/invalid_schema.xml new file mode 100644 index 00000000..e2725a2c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/invalid_schema.xml @@ -0,0 +1,2 @@ + + diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/not_readable.xml b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/not_readable.xml new file mode 100644 index 00000000..e69de29b diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/schema.xsd b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/schema.xsd new file mode 100644 index 00000000..e56820f6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/schema.xsd @@ -0,0 +1,9 @@ + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/valid.xml b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/valid.xml new file mode 100644 index 00000000..a96bb382 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/Util/valid.xml @@ -0,0 +1,3 @@ + + + diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/foo.xml b/modules/empikmarketplace/vendor/symfony/config/Tests/Fixtures/foo.xml new file mode 100644 index 00000000..e69de29b diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php new file mode 100644 index 00000000..38ae6ff7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/DelegatingLoaderTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\DelegatingLoader; +use Symfony\Component\Config\Loader\LoaderResolver; + +class DelegatingLoaderTest extends TestCase +{ + public function testConstructor() + { + new DelegatingLoader($resolver = new LoaderResolver()); + $this->assertTrue(true, '__construct() takes a loader resolver as its first argument'); + } + + public function testGetSetResolver() + { + $resolver = new LoaderResolver(); + $loader = new DelegatingLoader($resolver); + $this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader'); + $loader->setResolver($resolver = new LoaderResolver()); + $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader'); + } + + public function testSupports() + { + $loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader1->expects($this->once())->method('supports')->willReturn(true); + $loader = new DelegatingLoader(new LoaderResolver([$loader1])); + $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable'); + + $loader1 = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader1->expects($this->once())->method('supports')->willReturn(false); + $loader = new DelegatingLoader(new LoaderResolver([$loader1])); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable'); + } + + public function testLoad() + { + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader->expects($this->once())->method('supports')->willReturn(true); + $loader->expects($this->once())->method('load'); + $resolver = new LoaderResolver([$loader]); + $loader = new DelegatingLoader($resolver); + + $loader->load('foo'); + } + + public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded() + { + $this->expectException('Symfony\Component\Config\Exception\FileLoaderLoadException'); + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader->expects($this->once())->method('supports')->willReturn(false); + $resolver = new LoaderResolver([$loader]); + $loader = new DelegatingLoader($resolver); + + $loader->load('foo'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/FileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/FileLoaderTest.php new file mode 100644 index 00000000..b59ace46 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/FileLoaderTest.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Config\Loader\LoaderResolver; + +class FileLoaderTest extends TestCase +{ + public function testImportWithFileLocatorDelegation() + { + $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); + + $locatorMockForAdditionalLoader = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); + $locatorMockForAdditionalLoader->expects($this->any())->method('locate')->will($this->onConsecutiveCalls( + ['path/to/file1'], // Default + ['path/to/file1', 'path/to/file2'], // First is imported + ['path/to/file1', 'path/to/file2'], // Second is imported + ['path/to/file1'], // Exception + ['path/to/file1', 'path/to/file2'] // Exception + )); + + $fileLoader = new TestFileLoader($locatorMock); + $fileLoader->setSupports(false); + $fileLoader->setCurrentDir('.'); + + $additionalLoader = new TestFileLoader($locatorMockForAdditionalLoader); + $additionalLoader->setCurrentDir('.'); + + $fileLoader->setResolver($loaderResolver = new LoaderResolver([$fileLoader, $additionalLoader])); + + // Default case + $this->assertSame('path/to/file1', $fileLoader->import('my_resource')); + + // Check first file is imported if not already loading + $this->assertSame('path/to/file1', $fileLoader->import('my_resource')); + + // Check second file is imported if first is already loading + $fileLoader->addLoading('path/to/file1'); + $this->assertSame('path/to/file2', $fileLoader->import('my_resource')); + + // Check exception throws if first (and only available) file is already loading + try { + $fileLoader->import('my_resource'); + $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } + + // Check exception throws if all files are already loading + try { + $fileLoader->addLoading('path/to/file2'); + $fileLoader->import('my_resource'); + $this->fail('->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException', $e, '->import() throws a FileLoaderImportCircularReferenceException if the resource is already loading'); + } + } + + public function testImportWithGlobLikeResource() + { + $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); + $loader = new TestFileLoader($locatorMock); + + $this->assertSame('[foo]', $loader->import('[foo]')); + } + + public function testImportWithNoGlobMatch() + { + $locatorMock = $this->getMockBuilder('Symfony\Component\Config\FileLocatorInterface')->getMock(); + $loader = new TestFileLoader($locatorMock); + + $this->assertNull($loader->import('./*.abc')); + } + + public function testImportWithSimpleGlob() + { + $loader = new TestFileLoader(new FileLocator(__DIR__)); + + $this->assertSame(__FILE__, strtr($loader->import('FileLoaderTest.*'), '/', \DIRECTORY_SEPARATOR)); + } +} + +class TestFileLoader extends FileLoader +{ + private $supports = true; + + public function load($resource, $type = null) + { + return $resource; + } + + public function supports($resource, $type = null) + { + return $this->supports; + } + + public function addLoading($resource) + { + self::$loading[$resource] = true; + } + + public function removeLoading($resource) + { + unset(self::$loading[$resource]); + } + + public function clearLoading() + { + self::$loading = []; + } + + public function setSupports($supports) + { + $this->supports = $supports; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/LoaderResolverTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/LoaderResolverTest.php new file mode 100644 index 00000000..aabc2a60 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/LoaderResolverTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\LoaderResolver; + +class LoaderResolverTest extends TestCase +{ + public function testConstructor() + { + $resolver = new LoaderResolver([ + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(), + ]); + + $this->assertEquals([$loader], $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument'); + } + + public function testResolve() + { + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $resolver = new LoaderResolver([$loader]); + $this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource'); + + $loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $loader->expects($this->once())->method('supports')->willReturn(true); + $resolver = new LoaderResolver([$loader]); + $this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource'); + } + + public function testLoaders() + { + $resolver = new LoaderResolver(); + $resolver->addLoader($loader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock()); + + $this->assertEquals([$loader], $resolver->getLoaders(), 'addLoader() adds a loader'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/LoaderTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/LoaderTest.php new file mode 100644 index 00000000..79ddf00f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Loader/LoaderTest.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Loader\Loader; + +class LoaderTest extends TestCase +{ + public function testGetSetResolver() + { + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader'); + } + + public function testResolve() + { + $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('foo.xml') + ->willReturn($resolvedLoader); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader'); + $this->assertSame($resolvedLoader, $loader->resolve('foo.xml'), '->resolve() finds a loader'); + } + + public function testResolveWhenResolverCannotFindLoader() + { + $this->expectException('Symfony\Component\Config\Exception\FileLoaderLoadException'); + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('FOOBAR') + ->willReturn(false); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $loader->resolve('FOOBAR'); + } + + public function testImport() + { + $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $resolvedLoader->expects($this->once()) + ->method('load') + ->with('foo') + ->willReturn('yes'); + + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('foo') + ->willReturn($resolvedLoader); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertEquals('yes', $loader->import('foo')); + } + + public function testImportWithType() + { + $resolvedLoader = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderInterface')->getMock(); + $resolvedLoader->expects($this->once()) + ->method('load') + ->with('foo', 'bar') + ->willReturn('yes'); + + $resolver = $this->getMockBuilder('Symfony\Component\Config\Loader\LoaderResolverInterface')->getMock(); + $resolver->expects($this->once()) + ->method('resolve') + ->with('foo', 'bar') + ->willReturn($resolvedLoader); + + $loader = new ProjectLoader1(); + $loader->setResolver($resolver); + + $this->assertEquals('yes', $loader->import('foo', 'bar')); + } +} + +class ProjectLoader1 extends Loader +{ + public function load($resource, $type = null) + { + } + + public function supports($resource, $type = null) + { + return \is_string($resource) && 'foo' === pathinfo($resource, \PATHINFO_EXTENSION); + } + + public function getType() + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ClassExistenceResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ClassExistenceResourceTest.php new file mode 100644 index 00000000..8020a578 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ClassExistenceResourceTest.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\ClassExistenceResource; +use Symfony\Component\Config\Tests\Fixtures\BadFileName; +use Symfony\Component\Config\Tests\Fixtures\BadParent; +use Symfony\Component\Config\Tests\Fixtures\ParseError; +use Symfony\Component\Config\Tests\Fixtures\Resource\ConditionalClass; + +class ClassExistenceResourceTest extends TestCase +{ + public function testToString() + { + $res = new ClassExistenceResource('BarClass'); + $this->assertSame('BarClass', (string) $res); + } + + public function testGetResource() + { + $res = new ClassExistenceResource('BarClass'); + $this->assertSame('BarClass', $res->getResource()); + } + + public function testIsFreshWhenClassDoesNotExist() + { + $res = new ClassExistenceResource('Symfony\Component\Config\Tests\Fixtures\BarClass'); + + $this->assertTrue($res->isFresh(time())); + + eval(<<assertFalse($res->isFresh(time())); + } + + public function testIsFreshWhenClassExists() + { + $res = new ClassExistenceResource('Symfony\Component\Config\Tests\Resource\ClassExistenceResourceTest'); + + $this->assertTrue($res->isFresh(time())); + } + + public function testExistsKo() + { + spl_autoload_register($autoloader = function ($class) use (&$loadedClass) { $loadedClass = $class; }); + + try { + $res = new ClassExistenceResource('MissingFooClass'); + $this->assertTrue($res->isFresh(0)); + + $this->assertSame('MissingFooClass', $loadedClass); + + $loadedClass = 123; + + new ClassExistenceResource('MissingFooClass', false); + + $this->assertSame(123, $loadedClass); + } finally { + spl_autoload_unregister($autoloader); + } + } + + public function testBadParentWithTimestamp() + { + $res = new ClassExistenceResource(BadParent::class, false); + $this->assertTrue($res->isFresh(time())); + } + + public function testBadParentWithNoTimestamp() + { + $this->expectException('ReflectionException'); + $this->expectExceptionMessage('Class "Symfony\Component\Config\Tests\Fixtures\MissingParent" not found while loading "Symfony\Component\Config\Tests\Fixtures\BadParent".'); + + $res = new ClassExistenceResource(BadParent::class, false); + $res->isFresh(0); + } + + public function testBadFileName() + { + $this->expectException('ReflectionException'); + $this->expectExceptionMessage('Mismatch between file name and class name.'); + + $res = new ClassExistenceResource(BadFileName::class, false); + $res->isFresh(0); + } + + public function testBadFileNameBis() + { + $this->expectException('ReflectionException'); + $this->expectExceptionMessage('Mismatch between file name and class name.'); + + $res = new ClassExistenceResource(BadFileName::class, false); + $res->isFresh(0); + } + + public function testConditionalClass() + { + $res = new ClassExistenceResource(ConditionalClass::class, false); + + $this->assertFalse($res->isFresh(0)); + } + + /** + * @requires PHP 7 + */ + public function testParseError() + { + $this->expectException('ParseError'); + + $res = new ClassExistenceResource(ParseError::class, false); + $res->isFresh(0); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ComposerResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ComposerResourceTest.php new file mode 100644 index 00000000..6857c766 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ComposerResourceTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use Composer\Autoload\ClassLoader; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\ComposerResource; + +class ComposerResourceTest extends TestCase +{ + public function testGetVendor() + { + $res = new ComposerResource(); + + $r = new \ReflectionClass(ClassLoader::class); + $found = false; + + foreach ($res->getVendors() as $vendor) { + if ($vendor && 0 === strpos($r->getFileName(), $vendor)) { + $found = true; + break; + } + } + + $this->assertTrue($found); + } + + public function testSerializeUnserialize() + { + $res = new ComposerResource(); + $ser = unserialize(serialize($res)); + + $this->assertTrue($res->isFresh(0)); + $this->assertTrue($ser->isFresh(0)); + + $this->assertEquals($res, $ser); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php new file mode 100644 index 00000000..700df456 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/DirectoryResourceTest.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\DirectoryResource; + +class DirectoryResourceTest extends TestCase +{ + protected $directory; + + protected function setUp() + { + $this->directory = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'symfonyDirectoryIterator'; + if (!file_exists($this->directory)) { + mkdir($this->directory); + } + touch($this->directory.'/tmp.xml'); + } + + protected function tearDown() + { + if (!is_dir($this->directory)) { + return; + } + $this->removeDirectory($this->directory); + } + + protected function removeDirectory($directory) + { + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST); + foreach ($iterator as $path) { + if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) { + continue; + } + if ($path->isDir()) { + rmdir($path->__toString()); + } else { + unlink($path->__toString()); + } + } + rmdir($directory); + } + + public function testGetResource() + { + $resource = new DirectoryResource($this->directory); + $this->assertSame(realpath($this->directory), $resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testGetPattern() + { + $resource = new DirectoryResource($this->directory, 'bar'); + $this->assertEquals('bar', $resource->getPattern()); + } + + public function testResourceDoesNotExist() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The directory ".*" does not exist./'); + new DirectoryResource('/____foo/foobar'.mt_rand(1, 999999)); + } + + public function testIsFresh() + { + $resource = new DirectoryResource($this->directory); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated'); + } + + public function testIsFreshForDeletedResources() + { + $resource = new DirectoryResource($this->directory); + $this->removeDirectory($this->directory); + + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist'); + } + + public function testIsFreshUpdateFile() + { + $resource = new DirectoryResource($this->directory); + touch($this->directory.'/tmp.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified'); + } + + public function testIsFreshNewFile() + { + $resource = new DirectoryResource($this->directory); + touch($this->directory.'/new.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added'); + } + + public function testIsFreshNewFileWithDifferentPattern() + { + $resource = new DirectoryResource($this->directory, '/.xml$/'); + touch($this->directory.'/new.yaml', time() + 20); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file with a non-matching pattern is added'); + } + + public function testIsFreshDeleteFile() + { + $resource = new DirectoryResource($this->directory); + $time = time(); + sleep(1); + unlink($this->directory.'/tmp.xml'); + $this->assertFalse($resource->isFresh($time), '->isFresh() returns false if an existing file is removed'); + } + + public function testIsFreshDeleteDirectory() + { + $resource = new DirectoryResource($this->directory); + $this->removeDirectory($this->directory); + $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed'); + } + + public function testIsFreshCreateFileInSubdirectory() + { + $subdirectory = $this->directory.'/subdirectory'; + mkdir($subdirectory); + + $resource = new DirectoryResource($this->directory); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists'); + + touch($subdirectory.'/newfile.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added'); + } + + public function testIsFreshModifySubdirectory() + { + $resource = new DirectoryResource($this->directory); + + $subdirectory = $this->directory.'/subdirectory'; + mkdir($subdirectory); + touch($subdirectory, time() + 20); + + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)'); + } + + public function testFilterRegexListNoMatch() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($this->directory.'/new.bar', time() + 20); + $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created'); + } + + public function testFilterRegexListMatch() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($this->directory.'/new.xml', time() + 20); + $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created '); + } + + public function testSerializeUnserialize() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + unserialize(serialize($resource)); + + $this->assertSame(realpath($this->directory), $resource->getResource()); + $this->assertSame('/\.(foo|xml)$/', $resource->getPattern()); + } + + public function testResourcesWithDifferentPatternsAreDifferent() + { + $resourceA = new DirectoryResource($this->directory, '/.xml$/'); + $resourceB = new DirectoryResource($this->directory, '/.yaml$/'); + + $this->assertCount(2, array_unique([$resourceA, $resourceB])); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php new file mode 100644 index 00000000..ff7fc7b5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/FileExistenceResourceTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\FileExistenceResource; + +class FileExistenceResourceTest extends TestCase +{ + protected $resource; + protected $file; + protected $time; + + protected function setUp() + { + $this->file = realpath(sys_get_temp_dir()).'/tmp.xml'; + $this->time = time(); + $this->resource = new FileExistenceResource($this->file); + } + + protected function tearDown() + { + if (file_exists($this->file)) { + @unlink($this->file); + } + } + + public function testToString() + { + $this->assertSame($this->file, (string) $this->resource); + } + + public function testGetResource() + { + $this->assertSame($this->file, $this->resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testIsFreshWithExistingResource() + { + touch($this->file, $this->time); + $serialized = serialize(new FileExistenceResource($this->file)); + + $resource = unserialize($serialized); + $this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still present'); + + unlink($this->file); + $resource = unserialize($serialized); + $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been deleted'); + } + + public function testIsFreshWithAbsentResource() + { + $serialized = serialize(new FileExistenceResource($this->file)); + + $resource = unserialize($serialized); + $this->assertTrue($resource->isFresh($this->time), '->isFresh() returns true if the resource is still absent'); + + touch($this->file, $this->time); + $resource = unserialize($serialized); + $this->assertFalse($resource->isFresh($this->time), '->isFresh() returns false if the resource has been created'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/FileResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/FileResourceTest.php new file mode 100644 index 00000000..a84faa95 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/FileResourceTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\FileResource; + +class FileResourceTest extends TestCase +{ + protected $resource; + protected $file; + protected $time; + + protected function setUp() + { + $this->file = sys_get_temp_dir().'/tmp.xml'; + $this->time = time(); + touch($this->file, $this->time); + $this->resource = new FileResource($this->file); + } + + protected function tearDown() + { + if (file_exists($this->file)) { + @unlink($this->file); + } + } + + public function testGetResource() + { + $this->assertSame(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource'); + } + + public function testGetResourceWithScheme() + { + $resource = new FileResource('file://'.$this->file); + $this->assertSame('file://'.$this->file, $resource->getResource(), '->getResource() returns the path to the schemed resource'); + } + + public function testToString() + { + $this->assertSame(realpath($this->file), (string) $this->resource); + } + + public function testResourceDoesNotExist() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The file ".*" does not exist./'); + new FileResource('/____foo/foobar'.mt_rand(1, 999999)); + } + + public function testIsFresh() + { + $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second'); + $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated'); + } + + public function testIsFreshForDeletedResources() + { + unlink($this->file); + + $this->assertFalse($this->resource->isFresh($this->time), '->isFresh() returns false if the resource does not exist'); + } + + public function testSerializeUnserialize() + { + unserialize(serialize($this->resource)); + + $this->assertSame(realpath($this->file), $this->resource->getResource()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/GlobResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/GlobResourceTest.php new file mode 100644 index 00000000..cfbfd2b4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/GlobResourceTest.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\GlobResource; + +class GlobResourceTest extends TestCase +{ + protected function tearDown() + { + $dir = \dirname(__DIR__).'/Fixtures'; + @rmdir($dir.'/TmpGlob'); + @unlink($dir.'/TmpGlob'); + @unlink($dir.'/Resource/TmpGlob'); + touch($dir.'/Resource/.hiddenFile'); + } + + public function testIterator() + { + $dir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'; + $resource = new GlobResource($dir, '/Resource', true); + + $paths = iterator_to_array($resource); + + $file = $dir.'/Resource'.\DIRECTORY_SEPARATOR.'ConditionalClass.php'; + $this->assertEquals([$file => new \SplFileInfo($file)], $paths); + $this->assertInstanceOf('SplFileInfo', current($paths)); + $this->assertSame($dir, $resource->getPrefix()); + + $resource = new GlobResource($dir, '/**/Resource', true); + + $paths = iterator_to_array($resource); + + $file = $dir.\DIRECTORY_SEPARATOR.'Resource'.\DIRECTORY_SEPARATOR.'ConditionalClass.php'; + $this->assertEquals([$file => $file], $paths); + $this->assertInstanceOf('SplFileInfo', current($paths)); + $this->assertSame($dir, $resource->getPrefix()); + } + + public function testIsFreshNonRecursiveDetectsNewFile() + { + $dir = \dirname(__DIR__).'/Fixtures'; + $resource = new GlobResource($dir, '/*', false); + + $this->assertTrue($resource->isFresh(0)); + + mkdir($dir.'/TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + + rmdir($dir.'/TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + + touch($dir.'/TmpGlob'); + $this->assertFalse($resource->isFresh(0)); + + unlink($dir.'/TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + } + + public function testIsFreshNonRecursiveDetectsRemovedFile() + { + $dir = \dirname(__DIR__).'/Fixtures'; + $resource = new GlobResource($dir, '/*', false); + + touch($dir.'/TmpGlob'); + touch($dir.'/.TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + + unlink($dir.'/.TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + + unlink($dir.'/TmpGlob'); + $this->assertFalse($resource->isFresh(0)); + } + + public function testIsFreshRecursiveDetectsRemovedFile() + { + $dir = \dirname(__DIR__).'/Fixtures'; + $resource = new GlobResource($dir, '/*', true); + + touch($dir.'/Resource/TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + + unlink($dir.'/Resource/TmpGlob'); + $this->assertFalse($resource->isFresh(0)); + + touch($dir.'/Resource/TmpGlob'); + $this->assertTrue($resource->isFresh(0)); + + unlink($dir.'/Resource/.hiddenFile'); + $this->assertTrue($resource->isFresh(0)); + } + + public function testIsFreshRecursiveDetectsNewFile() + { + $dir = \dirname(__DIR__).'/Fixtures'; + $resource = new GlobResource($dir, '/*', true); + + $this->assertTrue($resource->isFresh(0)); + + touch($dir.'/Resource/TmpGlob'); + $this->assertFalse($resource->isFresh(0)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ReflectionClassResourceTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ReflectionClassResourceTest.php new file mode 100644 index 00000000..74ed6b3e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ReflectionClassResourceTest.php @@ -0,0 +1,223 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\ReflectionClassResource; +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +class ReflectionClassResourceTest extends TestCase +{ + public function testToString() + { + $res = new ReflectionClassResource(new \ReflectionClass('ErrorException')); + + $this->assertSame('reflection.ErrorException', (string) $res); + } + + public function testSerializeUnserialize() + { + $res = new ReflectionClassResource(new \ReflectionClass(DummyInterface::class)); + $ser = unserialize(serialize($res)); + + $this->assertTrue($res->isFresh(0)); + $this->assertTrue($ser->isFresh(0)); + + $this->assertSame((string) $res, (string) $ser); + } + + public function testIsFresh() + { + $res = new ReflectionClassResource(new \ReflectionClass(__CLASS__)); + $mtime = filemtime(__FILE__); + + $this->assertTrue($res->isFresh($mtime), '->isFresh() returns true if the resource has not changed in same second'); + $this->assertTrue($res->isFresh($mtime + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertTrue($res->isFresh($mtime - 86400), '->isFresh() returns true if the resource has not changed'); + } + + public function testIsFreshForDeletedResources() + { + $now = time(); + $tmp = sys_get_temp_dir().'/tmp.php'; + file_put_contents($tmp, 'assertTrue($res->isFresh($now)); + + unlink($tmp); + $this->assertFalse($res->isFresh($now), '->isFresh() returns false if the resource does not exist'); + } + + /** + * @dataProvider provideHashedSignature + */ + public function testHashedSignature($changeExpected, $changedLine, $changedCode, $setContext = null) + { + if ($setContext) { + $setContext(); + } + + $code = <<<'EOPHP' +/* 0*/ +/* 1*/ class %s extends ErrorException +/* 2*/ { +/* 3*/ const FOO = 123; +/* 4*/ +/* 5*/ public $pub = []; +/* 6*/ +/* 7*/ protected $prot; +/* 8*/ +/* 9*/ private $priv; +/*10*/ +/*11*/ public function pub($arg = null) {} +/*12*/ +/*13*/ protected function prot($a = []) {} +/*14*/ +/*15*/ private function priv() {} +/*16*/ +/*17*/ public function ccc($bar = A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC) {} +/*18*/ } +EOPHP; + + static $expectedSignature, $generateSignature; + + if (null === $expectedSignature) { + eval(sprintf($code, $class = 'Foo'.str_replace('.', '_', uniqid('', true)))); + $r = new \ReflectionClass(ReflectionClassResource::class); + $generateSignature = $r->getMethod('generateSignature'); + $generateSignature->setAccessible(true); + $generateSignature = $generateSignature->getClosure($r->newInstanceWithoutConstructor()); + $expectedSignature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class)))); + } + + $code = explode("\n", $code); + if (null !== $changedCode) { + $code[$changedLine] = $changedCode; + } + eval(sprintf(implode("\n", $code), $class = 'Foo'.str_replace('.', '_', uniqid('', true)))); + $signature = implode("\n", iterator_to_array($generateSignature(new \ReflectionClass($class)))); + + if ($changeExpected) { + $this->assertNotSame($expectedSignature, $signature); + } else { + $this->assertSame($expectedSignature, $signature); + } + } + + public function provideHashedSignature() + { + yield [0, 0, "// line change\n\n"]; + yield [1, 0, '/** class docblock */']; + yield [1, 1, 'abstract class %s']; + yield [1, 1, 'final class %s']; + yield [1, 1, 'class %s extends Exception']; + yield [1, 1, 'class %s implements '.DummyInterface::class]; + yield [1, 3, 'const FOO = 456;']; + yield [1, 3, 'const BAR = 123;']; + yield [1, 4, '/** pub docblock */']; + yield [1, 5, 'protected $pub = [];']; + yield [1, 5, 'public $pub = [123];']; + yield [1, 6, '/** prot docblock */']; + yield [1, 7, 'private $prot;']; + yield [0, 8, '/** priv docblock */']; + yield [0, 9, 'private $priv = 123;']; + yield [1, 10, '/** pub docblock */']; + if (\PHP_VERSION_ID >= 50600) { + yield [1, 11, 'public function pub(...$arg) {}']; + } + if (\PHP_VERSION_ID >= 70000) { + yield [1, 11, 'public function pub($arg = null): Foo {}']; + } + yield [0, 11, "public function pub(\$arg = null) {\nreturn 123;\n}"]; + yield [1, 12, '/** prot docblock */']; + yield [1, 13, 'protected function prot($a = [123]) {}']; + yield [0, 14, '/** priv docblock */']; + yield [0, 15, '']; + + if (\PHP_VERSION_ID >= 70400) { + // PHP7.4 typed properties without default value are + // undefined, make sure this doesn't throw an error + yield [1, 5, 'public array $pub;']; + yield [0, 7, 'protected int $prot;']; + yield [0, 9, 'private string $priv;']; + } + + yield [1, 17, 'public function ccc($bar = 187) {}']; + yield [1, 17, 'public function ccc($bar = ANOTHER_ONE_THAT_WILL_NEVER_BE_DEFINED_CCCCCCCCC) {}']; + yield [1, 17, null, static function () { \define('A_CONSTANT_THAT_FOR_SURE_WILL_NEVER_BE_DEFINED_CCCCCC', 'foo'); }]; + } + + public function testEventSubscriber() + { + $res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + + TestEventSubscriber::$subscribedEvents = [123]; + $this->assertFalse($res->isFresh(0)); + + $res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + } + + public function testServiceSubscriber() + { + $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + + TestServiceSubscriber::$subscribedServices = [123]; + $this->assertFalse($res->isFresh(0)); + + $res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class)); + $this->assertTrue($res->isFresh(0)); + } + + public function testIgnoresObjectsInSignature() + { + $res = new ReflectionClassResource(new \ReflectionClass(TestServiceWithStaticProperty::class)); + $this->assertTrue($res->isFresh(0)); + + TestServiceWithStaticProperty::$initializedObject = new TestServiceWithStaticProperty(); + $this->assertTrue($res->isFresh(0)); + } +} + +interface DummyInterface +{ +} + +class TestEventSubscriber implements EventSubscriberInterface +{ + public static $subscribedEvents = []; + + public static function getSubscribedEvents() + { + return self::$subscribedEvents; + } +} + +class TestServiceSubscriber implements ServiceSubscriberInterface +{ + public static $subscribedServices = []; + + public static function getSubscribedServices() + { + return self::$subscribedServices; + } +} + +class TestServiceWithStaticProperty +{ + public static $initializedObject; +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ResourceStub.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ResourceStub.php new file mode 100644 index 00000000..b01729cb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Resource/ResourceStub.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Resource; + +use Symfony\Component\Config\Resource\SelfCheckingResourceInterface; + +class ResourceStub implements SelfCheckingResourceInterface +{ + private $fresh = true; + + public function setFresh($isFresh) + { + $this->fresh = $isFresh; + } + + public function __toString() + { + return 'stub'; + } + + public function isFresh($timestamp) + { + return $this->fresh; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php new file mode 100644 index 00000000..9be53196 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/ResourceCheckerConfigCacheTest.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\ResourceCheckerConfigCache; +use Symfony\Component\Config\Tests\Resource\ResourceStub; + +class ResourceCheckerConfigCacheTest extends TestCase +{ + private $cacheFile = null; + + protected function setUp() + { + $this->cacheFile = tempnam(sys_get_temp_dir(), 'config_'); + } + + protected function tearDown() + { + $files = [$this->cacheFile, "{$this->cacheFile}.meta"]; + + foreach ($files as $file) { + if (file_exists($file)) { + @unlink($file); + } + } + } + + public function testGetPath() + { + $cache = new ResourceCheckerConfigCache($this->cacheFile); + + $this->assertSame($this->cacheFile, $cache->getPath()); + } + + public function testCacheIsNotFreshIfEmpty() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock() + ->expects($this->never())->method('supports'); + + /* If there is nothing in the cache, it needs to be filled (and thus it's not fresh). + It does not matter if you provide checkers or not. */ + + unlink($this->cacheFile); // remove tempnam() side effect + $cache = new ResourceCheckerConfigCache($this->cacheFile, [$checker]); + + $this->assertFalse($cache->isFresh()); + } + + public function testCacheIsFreshIfNoCheckerProvided() + { + /* For example in prod mode, you may choose not to run any checkers + at all. In that case, the cache should always be considered fresh. */ + $cache = new ResourceCheckerConfigCache($this->cacheFile); + $this->assertTrue($cache->isFresh()); + } + + public function testCacheIsFreshIfEmptyCheckerIteratorProvided() + { + $cache = new ResourceCheckerConfigCache($this->cacheFile, new \ArrayIterator([])); + $this->assertTrue($cache->isFresh()); + } + + public function testResourcesWithoutcheckersAreIgnoredAndConsideredFresh() + { + /* As in the previous test, but this time we have a resource. */ + $cache = new ResourceCheckerConfigCache($this->cacheFile); + $cache->write('', [new ResourceStub()]); + + $this->assertTrue($cache->isFresh()); // no (matching) ResourceChecker passed + } + + public function testIsFreshWithchecker() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + + $checker->expects($this->once()) + ->method('supports') + ->willReturn(true); + + $checker->expects($this->once()) + ->method('isFresh') + ->willReturn(true); + + $cache = new ResourceCheckerConfigCache($this->cacheFile, [$checker]); + $cache->write('', [new ResourceStub()]); + + $this->assertTrue($cache->isFresh()); + } + + public function testIsNotFreshWithchecker() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + + $checker->expects($this->once()) + ->method('supports') + ->willReturn(true); + + $checker->expects($this->once()) + ->method('isFresh') + ->willReturn(false); + + $cache = new ResourceCheckerConfigCache($this->cacheFile, [$checker]); + $cache->write('', [new ResourceStub()]); + + $this->assertFalse($cache->isFresh()); + } + + public function testCacheIsNotFreshWhenUnserializeFails() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + $cache = new ResourceCheckerConfigCache($this->cacheFile, [$checker]); + $cache->write('foo', [new FileResource(__FILE__)]); + + $metaFile = "{$this->cacheFile}.meta"; + file_put_contents($metaFile, str_replace('FileResource', 'ClassNotHere', file_get_contents($metaFile))); + + $this->assertFalse($cache->isFresh()); + } + + public function testCacheKeepsContent() + { + $cache = new ResourceCheckerConfigCache($this->cacheFile); + $cache->write('FOOBAR'); + + $this->assertSame('FOOBAR', file_get_contents($cache->getPath())); + } + + public function testCacheIsNotFreshIfNotExistsMetaFile() + { + $checker = $this->getMockBuilder('\Symfony\Component\Config\ResourceCheckerInterface')->getMock(); + $cache = new ResourceCheckerConfigCache($this->cacheFile, [$checker]); + $cache->write('foo', [new FileResource(__FILE__)]); + + $metaFile = "{$this->cacheFile}.meta"; + unlink($metaFile); + + $this->assertFalse($cache->isFresh()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Tests/Util/XmlUtilsTest.php b/modules/empikmarketplace/vendor/symfony/config/Tests/Util/XmlUtilsTest.php new file mode 100644 index 00000000..f0b77ae6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Tests/Util/XmlUtilsTest.php @@ -0,0 +1,240 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Util; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Util\XmlUtils; + +class XmlUtilsTest extends TestCase +{ + public function testLoadFile() + { + $fixtures = __DIR__.'/../Fixtures/Util/'; + + try { + XmlUtils::loadFile($fixtures); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertStringContainsString('is not a file', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'non_existing.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertStringContainsString('is not a file', $e->getMessage()); + } + + try { + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + chmod($fixtures.'not_readable.xml', 000); + XmlUtils::loadFile($fixtures.'not_readable.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + chmod($fixtures.'not_readable.xml', 0644); + $this->assertStringContainsString('is not readable', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertStringContainsString('ERROR ', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'document_type.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertStringContainsString('Document types are not allowed', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertStringContainsString('ERROR 1845', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertStringContainsString('XSD file or callable', $e->getMessage()); + } + + $mock = $this->getMockBuilder(Validator::class)->getMock(); + $mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true)); + + try { + XmlUtils::loadFile($fixtures.'valid.xml', [$mock, 'validate']); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertMatchesRegularExpression('/The XML file ".+" is not valid\./', $e->getMessage()); + } + + $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', [$mock, 'validate'])); + $this->assertSame([], libxml_get_errors()); + } + + public function testParseWithInvalidValidatorCallable() + { + $this->expectException('Symfony\Component\Config\Util\Exception\InvalidXmlException'); + $this->expectExceptionMessage('The XML is not valid'); + $fixtures = __DIR__.'/../Fixtures/Util/'; + + $mock = $this->getMockBuilder(Validator::class)->getMock(); + $mock->expects($this->once())->method('validate')->willReturn(false); + + XmlUtils::parse(file_get_contents($fixtures.'valid.xml'), [$mock, 'validate']); + } + + public function testLoadFileWithInternalErrorsEnabled() + { + $internalErrors = libxml_use_internal_errors(true); + + $this->assertSame([], libxml_get_errors()); + $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/invalid_schema.xml')); + $this->assertSame([], libxml_get_errors()); + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + } + + /** + * @dataProvider getDataForConvertDomToArray + */ + public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true) + { + $dom = new \DOMDocument(); + $dom->loadXML($root ? $xml : ''.$xml.''); + + $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix)); + } + + public function getDataForConvertDomToArray() + { + return [ + [null, ''], + ['bar', 'bar'], + [['bar' => 'foobar'], '', true], + [['foo' => null], ''], + [['foo' => 'bar'], 'bar'], + [['foo' => ['foo' => 'bar']], ''], + [['foo' => ['foo' => 0]], '0'], + [['foo' => ['foo' => 'bar']], 'bar'], + [['foo' => ['foo' => 'bar', 'value' => 'text']], 'text'], + [['foo' => ['attr' => 'bar', 'foo' => 'text']], 'text'], + [['foo' => ['bar', 'text']], 'bartext'], + [['foo' => [['foo' => 'bar'], ['foo' => 'text']]], ''], + [['foo' => ['foo' => ['bar', 'text']]], 'text'], + [['foo' => 'bar'], 'bar'], + [['foo' => 'text'], 'text'], + [['foo' => ['bar' => 'bar', 'value' => 'text']], 'text', false, false], + [['attr' => 1, 'b' => 'hello'], 'hello2', true], + ]; + } + + /** + * @dataProvider getDataForPhpize + */ + public function testPhpize($expected, $value) + { + $this->assertSame($expected, XmlUtils::phpize($value)); + } + + public function getDataForPhpize() + { + return [ + ['', ''], + [null, 'null'], + [true, 'true'], + [false, 'false'], + [null, 'Null'], + [true, 'True'], + [false, 'False'], + [0, '0'], + [1, '1'], + [-1, '-1'], + [0777, '0777'], + [255, '0xFF'], + [100.0, '1e2'], + [-120.0, '-1.2E2'], + [-10100.1, '-10100.1'], + ['-10,100.1', '-10,100.1'], + ['1234 5678 9101 1121 3141', '1234 5678 9101 1121 3141'], + ['1,2,3,4', '1,2,3,4'], + ['11,22,33,44', '11,22,33,44'], + ['11,222,333,4', '11,222,333,4'], + ['1,222,333,444', '1,222,333,444'], + ['11,222,333,444', '11,222,333,444'], + ['111,222,333,444', '111,222,333,444'], + ['1111,2222,3333,4444,5555', '1111,2222,3333,4444,5555'], + ['foo', 'foo'], + [6, '0b0110'], + ]; + } + + public function testLoadEmptyXmlFile() + { + $file = __DIR__.'/../Fixtures/foo.xml'; + + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage(sprintf('File "%s" does not contain valid XML, it is empty.', $file)); + + XmlUtils::loadFile($file); + } + + // test for issue https://github.com/symfony/symfony/issues/9731 + public function testLoadWrongEmptyXMLWithErrorHandler() + { + if (\LIBXML_VERSION < 20900) { + $originalDisableEntities = libxml_disable_entity_loader(false); + } + $errorReporting = error_reporting(-1); + + set_error_handler(function ($errno, $errstr) { + throw new \Exception($errstr, $errno); + }); + + $file = __DIR__.'/../Fixtures/foo.xml'; + try { + try { + XmlUtils::loadFile($file); + $this->fail('An exception should have been raised'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals(sprintf('File "%s" does not contain valid XML, it is empty.', $file), $e->getMessage()); + } + } finally { + restore_error_handler(); + error_reporting($errorReporting); + } + + if (\LIBXML_VERSION < 20900) { + $disableEntities = libxml_disable_entity_loader(true); + libxml_disable_entity_loader($disableEntities); + + libxml_disable_entity_loader($originalDisableEntities); + $this->assertFalse($disableEntities); + } + + // should not throw an exception + XmlUtils::loadFile(__DIR__.'/../Fixtures/Util/valid.xml', __DIR__.'/../Fixtures/Util/schema.xsd'); + } +} + +interface Validator +{ + public function validate(); +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Util/Exception/InvalidXmlException.php b/modules/empikmarketplace/vendor/symfony/config/Util/Exception/InvalidXmlException.php new file mode 100644 index 00000000..a335bbd2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Util/Exception/InvalidXmlException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Util\Exception; + +/** + * Exception class for when XML parsing with an XSD schema file path or a callable validator produces errors unrelated + * to the actual XML parsing. + * + * @author Ole Rößner + */ +class InvalidXmlException extends XmlParsingException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Util/Exception/XmlParsingException.php b/modules/empikmarketplace/vendor/symfony/config/Util/Exception/XmlParsingException.php new file mode 100644 index 00000000..9bceed66 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Util/Exception/XmlParsingException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Util\Exception; + +/** + * Exception class for when XML cannot be parsed properly. + * + * @author Ole Rößner + */ +class XmlParsingException extends \InvalidArgumentException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/config/Util/XmlUtils.php b/modules/empikmarketplace/vendor/symfony/config/Util/XmlUtils.php new file mode 100644 index 00000000..d833c428 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/Util/XmlUtils.php @@ -0,0 +1,284 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Util; + +use Symfony\Component\Config\Util\Exception\InvalidXmlException; +use Symfony\Component\Config\Util\Exception\XmlParsingException; + +/** + * XMLUtils is a bunch of utility methods to XML operations. + * + * This class contains static methods only and is not meant to be instantiated. + * + * @author Fabien Potencier + * @author Martin Hasoň + * @author Ole Rößner + */ +class XmlUtils +{ + /** + * This class should not be instantiated. + */ + private function __construct() + { + } + + /** + * Parses an XML string. + * + * @param string $content An XML string + * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation + * + * @return \DOMDocument + * + * @throws XmlParsingException When parsing of XML file returns error + * @throws InvalidXmlException When parsing of XML with schema or callable produces any errors unrelated to the XML parsing itself + * @throws \RuntimeException When DOM extension is missing + */ + public static function parse($content, $schemaOrCallable = null) + { + if (!\extension_loaded('dom')) { + throw new \RuntimeException('Extension DOM is required.'); + } + + $internalErrors = libxml_use_internal_errors(true); + if (\LIBXML_VERSION < 20900) { + $disableEntities = libxml_disable_entity_loader(true); + } + libxml_clear_errors(); + + $dom = new \DOMDocument(); + $dom->validateOnParse = true; + if (!$dom->loadXML($content, \LIBXML_NONET | (\defined('LIBXML_COMPACT') ? \LIBXML_COMPACT : 0))) { + if (\LIBXML_VERSION < 20900) { + libxml_disable_entity_loader($disableEntities); + } + + throw new XmlParsingException(implode("\n", static::getXmlErrors($internalErrors))); + } + + $dom->normalizeDocument(); + + libxml_use_internal_errors($internalErrors); + if (\LIBXML_VERSION < 20900) { + libxml_disable_entity_loader($disableEntities); + } + + foreach ($dom->childNodes as $child) { + if (\XML_DOCUMENT_TYPE_NODE === $child->nodeType) { + throw new XmlParsingException('Document types are not allowed.'); + } + } + + if (null !== $schemaOrCallable) { + $internalErrors = libxml_use_internal_errors(true); + libxml_clear_errors(); + + $e = null; + if (\is_callable($schemaOrCallable)) { + try { + $valid = \call_user_func($schemaOrCallable, $dom, $internalErrors); + } catch (\Exception $e) { + $valid = false; + } + } elseif (!\is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) { + $schemaSource = file_get_contents((string) $schemaOrCallable); + $valid = @$dom->schemaValidateSource($schemaSource); + } else { + libxml_use_internal_errors($internalErrors); + + throw new XmlParsingException('The schemaOrCallable argument has to be a valid path to XSD file or callable.'); + } + + if (!$valid) { + $messages = static::getXmlErrors($internalErrors); + if (empty($messages)) { + throw new InvalidXmlException('The XML is not valid.', 0, $e); + } + throw new XmlParsingException(implode("\n", $messages), 0, $e); + } + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + + return $dom; + } + + /** + * Loads an XML file. + * + * @param string $file An XML file path + * @param string|callable|null $schemaOrCallable An XSD schema file path, a callable, or null to disable validation + * + * @return \DOMDocument + * + * @throws \InvalidArgumentException When loading of XML file returns error + * @throws XmlParsingException When XML parsing returns any errors + * @throws \RuntimeException When DOM extension is missing + */ + public static function loadFile($file, $schemaOrCallable = null) + { + if (!is_file($file)) { + throw new \InvalidArgumentException(sprintf('Resource "%s" is not a file.', $file)); + } + + if (!is_readable($file)) { + throw new \InvalidArgumentException(sprintf('File "%s" is not readable.', $file)); + } + + $content = @file_get_contents($file); + + if ('' === trim($content)) { + throw new \InvalidArgumentException(sprintf('File "%s" does not contain valid XML, it is empty.', $file)); + } + + try { + return static::parse($content, $schemaOrCallable); + } catch (InvalidXmlException $e) { + throw new XmlParsingException(sprintf('The XML file "%s" is not valid.', $file), 0, $e->getPrevious()); + } + } + + /** + * Converts a \DOMElement object to a PHP array. + * + * The following rules applies during the conversion: + * + * * Each tag is converted to a key value or an array + * if there is more than one "value" + * + * * The content of a tag is set under a "value" key (bar) + * if the tag also has some nested tags + * + * * The attributes are converted to keys () + * + * * The nested-tags are converted to keys (bar) + * + * @param \DOMElement $element A \DOMElement instance + * @param bool $checkPrefix Check prefix in an element or an attribute name + * + * @return mixed + */ + public static function convertDomElementToArray(\DOMElement $element, $checkPrefix = true) + { + $prefix = (string) $element->prefix; + $empty = true; + $config = []; + foreach ($element->attributes as $name => $node) { + if ($checkPrefix && !\in_array((string) $node->prefix, ['', $prefix], true)) { + continue; + } + $config[$name] = static::phpize($node->value); + $empty = false; + } + + $nodeValue = false; + foreach ($element->childNodes as $node) { + if ($node instanceof \DOMText) { + if ('' !== trim($node->nodeValue)) { + $nodeValue = trim($node->nodeValue); + $empty = false; + } + } elseif ($checkPrefix && $prefix != (string) $node->prefix) { + continue; + } elseif (!$node instanceof \DOMComment) { + $value = static::convertDomElementToArray($node, $checkPrefix); + + $key = $node->localName; + if (isset($config[$key])) { + if (!\is_array($config[$key]) || !\is_int(key($config[$key]))) { + $config[$key] = [$config[$key]]; + } + $config[$key][] = $value; + } else { + $config[$key] = $value; + } + + $empty = false; + } + } + + if (false !== $nodeValue) { + $value = static::phpize($nodeValue); + if (\count($config)) { + $config['value'] = $value; + } else { + $config = $value; + } + } + + return !$empty ? $config : null; + } + + /** + * Converts an xml value to a PHP type. + * + * @param mixed $value + * + * @return mixed + */ + public static function phpize($value) + { + $value = (string) $value; + $lowercaseValue = strtolower($value); + + switch (true) { + case 'null' === $lowercaseValue: + return null; + case ctype_digit($value): + $raw = $value; + $cast = (int) $value; + + return '0' == $value[0] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw); + case isset($value[1]) && '-' === $value[0] && ctype_digit(substr($value, 1)): + $raw = $value; + $cast = (int) $value; + + return '0' == $value[1] ? octdec($value) : (((string) $raw === (string) $cast) ? $cast : $raw); + case 'true' === $lowercaseValue: + return true; + case 'false' === $lowercaseValue: + return false; + case isset($value[1]) && '0b' == $value[0].$value[1] && preg_match('/^0b[01]*$/', $value): + return bindec($value); + case is_numeric($value): + return '0x' === $value[0].$value[1] ? hexdec($value) : (float) $value; + case preg_match('/^0x[0-9a-f]++$/i', $value): + return hexdec($value); + case preg_match('/^[+-]?[0-9]+(\.[0-9]+)?$/', $value): + return (float) $value; + default: + return $value; + } + } + + protected static function getXmlErrors($internalErrors) + { + $errors = []; + foreach (libxml_get_errors() as $error) { + $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', + \LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', + $error->code, + trim($error->message), + $error->file ?: 'n/a', + $error->line, + $error->column + ); + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + + return $errors; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/config/composer.json b/modules/empikmarketplace/vendor/symfony/config/composer.json new file mode 100644 index 00000000..5088bdd8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/composer.json @@ -0,0 +1,43 @@ +{ + "name": "symfony/config", + "type": "library", + "description": "Symfony Config Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/filesystem": "~2.8|~3.0|~4.0", + "symfony/polyfill-ctype": "~1.8" + }, + "require-dev": { + "symfony/finder": "~3.3|~4.0", + "symfony/yaml": "~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0" + }, + "conflict": { + "symfony/finder": "<3.3", + "symfony/dependency-injection": "<3.3" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Config\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/modules/empikmarketplace/vendor/symfony/config/phpunit.xml.dist b/modules/empikmarketplace/vendor/symfony/config/phpunit.xml.dist new file mode 100644 index 00000000..1cfdb3cd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/config/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/.gitignore b/modules/empikmarketplace/vendor/symfony/dependency-injection/.gitignore new file mode 100644 index 00000000..c49a5d8d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Alias.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Alias.php new file mode 100644 index 00000000..de14c5ea --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Alias.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +class Alias +{ + private $id; + private $public; + private $private; + + /** + * @param string $id Alias identifier + * @param bool $public If this alias is public + */ + public function __construct($id, $public = true) + { + $this->id = (string) $id; + $this->public = $public; + $this->private = 2 > \func_num_args(); + } + + /** + * Checks if this DI Alias should be public or not. + * + * @return bool + */ + public function isPublic() + { + return $this->public; + } + + /** + * Sets if this Alias is public. + * + * @param bool $boolean If this Alias should be public + * + * @return $this + */ + public function setPublic($boolean) + { + $this->public = (bool) $boolean; + $this->private = false; + + return $this; + } + + /** + * Sets if this Alias is private. + * + * When set, the "private" state has a higher precedence than "public". + * In version 3.4, a "private" alias always remains publicly accessible, + * but triggers a deprecation notice when accessed from the container, + * so that the alias can be made really private in 4.0. + * + * @param bool $boolean + * + * @return $this + */ + public function setPrivate($boolean) + { + $this->private = (bool) $boolean; + + return $this; + } + + /** + * Whether this alias is private. + * + * @return bool + */ + public function isPrivate() + { + return $this->private; + } + + /** + * Returns the Id of this alias. + * + * @return string The alias id + */ + public function __toString() + { + return $this->id; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php new file mode 100644 index 00000000..b46eb77b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/ArgumentInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a complex argument containing nested values. + * + * @author Titouan Galopin + */ +interface ArgumentInterface +{ + /** + * @return array + */ + public function getValues(); + + public function setValues(array $values); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/BoundArgument.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/BoundArgument.php new file mode 100644 index 00000000..a2069844 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/BoundArgument.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * @author Guilhem Niot + */ +final class BoundArgument implements ArgumentInterface +{ + private static $sequence = 0; + + private $value; + private $identifier; + private $used; + + public function __construct($value) + { + $this->value = $value; + $this->identifier = ++self::$sequence; + } + + /** + * {@inheritdoc} + */ + public function getValues() + { + return [$this->value, $this->identifier, $this->used]; + } + + /** + * {@inheritdoc} + */ + public function setValues(array $values) + { + list($this->value, $this->identifier, $this->used) = $values; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/IteratorArgument.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/IteratorArgument.php new file mode 100644 index 00000000..2d796d2d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/IteratorArgument.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Represents a collection of values to lazily iterate over. + * + * @author Titouan Galopin + */ +class IteratorArgument implements ArgumentInterface +{ + private $values; + + /** + * @param Reference[] $values + */ + public function __construct(array $values) + { + $this->setValues($values); + } + + /** + * @return array The values to lazily iterate over + */ + public function getValues() + { + return $this->values; + } + + /** + * @param Reference[] $values The service references to lazily iterate over + */ + public function setValues(array $values) + { + foreach ($values as $k => $v) { + if (null !== $v && !$v instanceof Reference) { + throw new InvalidArgumentException(sprintf('An IteratorArgument must hold only Reference instances, "%s" given.', \is_object($v) ? \get_class($v) : \gettype($v))); + } + } + + $this->values = $values; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php new file mode 100644 index 00000000..b00a36c3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/RewindableGenerator.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * @internal + */ +class RewindableGenerator implements \IteratorAggregate, \Countable +{ + private $generator; + private $count; + + /** + * @param int|callable $count + */ + public function __construct(callable $generator, $count) + { + $this->generator = $generator; + $this->count = $count; + } + + public function getIterator() + { + $g = $this->generator; + + return $g(); + } + + public function count() + { + if (\is_callable($count = $this->count)) { + $this->count = $count(); + } + + return $this->count; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php new file mode 100644 index 00000000..6331affa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Represents a service wrapped in a memoizing closure. + * + * @author Nicolas Grekas + */ +class ServiceClosureArgument implements ArgumentInterface +{ + private $values; + + public function __construct(Reference $reference) + { + $this->values = [$reference]; + } + + /** + * {@inheritdoc} + */ + public function getValues() + { + return $this->values; + } + + /** + * {@inheritdoc} + */ + public function setValues(array $values) + { + if ([0] !== array_keys($values) || !($values[0] instanceof Reference || null === $values[0])) { + throw new InvalidArgumentException('A ServiceClosureArgument must hold one and only one Reference.'); + } + + $this->values = $values; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php new file mode 100644 index 00000000..f00e5339 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Argument; + +/** + * Represents a collection of services found by tag name to lazily iterate over. + * + * @author Roland Franssen + */ +class TaggedIteratorArgument extends IteratorArgument +{ + private $tag; + + /** + * @param string $tag + */ + public function __construct($tag) + { + parent::__construct([]); + + $this->tag = (string) $tag; + } + + public function getTag() + { + return $this->tag; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/CHANGELOG.md b/modules/empikmarketplace/vendor/symfony/dependency-injection/CHANGELOG.md new file mode 100644 index 00000000..a004161b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/CHANGELOG.md @@ -0,0 +1,116 @@ +CHANGELOG +========= + +3.4.0 +----- + + * moved the `ExtensionCompilerPass` to before-optimization passes with priority -1000 + * deprecated "public-by-default" definitions and aliases, the new default will be "private" in 4.0 + * added `EnvVarProcessorInterface` and corresponding "container.env_var_processor" tag for processing env vars + * added support for ignore-on-uninitialized references + * deprecated service auto-registration while autowiring + * deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method + * deprecated support for top-level anonymous services in XML + * deprecated case insensitivity of parameter names + * deprecated the `ResolveDefinitionTemplatesPass` class in favor of `ResolveChildDefinitionsPass` + * added `TaggedIteratorArgument` with YAML (`!tagged foo`) and XML (``) support + * deprecated `AutowireExceptionPass` and `AutowirePass::getAutowiringExceptions()`, use `Definition::addError()` and the `DefinitionErrorExceptionPass` instead + + +3.3.0 +----- + + * deprecated autowiring services based on the types they implement; + rename (or alias) your services to their FQCN id to make them autowirable + * added "ServiceSubscriberInterface" - to allow for per-class explicit service-locator definitions + * added "container.service_locator" tag for defining service-locator services + * added anonymous services support in YAML configuration files using the `!service` tag. + * added "TypedReference" and "ServiceClosureArgument" for creating service-locator services + * added `ServiceLocator` - a PSR-11 container holding a set of services to be lazily loaded + * added "instanceof" section for local interface-defined configs + * added prototype services for PSR4-based discovery and registration + * added `ContainerBuilder::getReflectionClass()` for retrieving and tracking reflection class info + * deprecated `ContainerBuilder::getClassResource()`, use `ContainerBuilder::getReflectionClass()` or `ContainerBuilder::addObjectResource()` instead + * added `ContainerBuilder::fileExists()` for checking and tracking file or directory existence + * deprecated autowiring-types, use aliases instead + * added support for omitting the factory class name in a service definition if the definition class is set + * deprecated case insensitivity of service identifiers + * added "iterator" argument type for lazy iteration over a set of values and services + * added file-wide configurable defaults for service attributes "public", "tags", + "autowire" and "autoconfigure" + * made the "class" attribute optional, using the "id" as fallback + * using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and + will not be supported anymore in 4.0 + * deprecated the `DefinitionDecorator` class in favor of `ChildDefinition` + * allow config files to be loaded using a glob pattern + * [BC BREAK] the `NullDumper` class is now final + +3.2.0 +----- + + * allowed to prioritize compiler passes by introducing a third argument to `PassConfig::addPass()`, to `Compiler::addPass` and to `ContainerBuilder::addCompilerPass()` + * added support for PHP constants in YAML configuration files + * deprecated the ability to set or unset a private service with the `Container::set()` method + * deprecated the ability to check for the existence of a private service with the `Container::has()` method + * deprecated the ability to request a private service with the `Container::get()` method + * deprecated support for generating a dumped `Container` without populating the method map + +3.0.0 +----- + + * removed all deprecated codes from 2.x versions + +2.8.0 +----- + + * deprecated the abstract ContainerAware class in favor of ContainerAwareTrait + * deprecated IntrospectableContainerInterface, to be merged with ContainerInterface in 3.0 + * allowed specifying a directory to recursively load all configuration files it contains + * deprecated the concept of scopes + * added `Definition::setShared()` and `Definition::isShared()` + * added ResettableContainerInterface to be able to reset the container to release memory on shutdown + * added a way to define the priority of service decoration + * added support for service autowiring + +2.7.0 +----- + + * deprecated synchronized services + +2.6.0 +----- + + * added new factory syntax and deprecated the old one + +2.5.0 +----- + +* added DecoratorServicePass and a way to override a service definition (Definition::setDecoratedService()) +* deprecated SimpleXMLElement class. + +2.4.0 +----- + + * added support for expressions in service definitions + * added ContainerAwareTrait to add default container aware behavior to a class + +2.2.0 +----- + + * added Extension::isConfigEnabled() to ease working with enableable configurations + * added an Extension base class with sensible defaults to be used in conjunction + with the Config component. + * added PrependExtensionInterface (to be able to allow extensions to prepend + application configuration settings for any Bundle) + +2.1.0 +----- + + * added IntrospectableContainerInterface (to be able to check if a service + has been initialized or not) + * added ConfigurationExtensionInterface + * added Definition::clearTag() + * component exceptions that inherit base SPL classes are now used exclusively + (this includes dumped containers) + * [BC BREAK] fixed unescaping of class arguments, method + ParameterBag::unescapeValue() was made public diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ChildDefinition.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ChildDefinition.php new file mode 100644 index 00000000..123b3874 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ChildDefinition.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; + +/** + * This definition extends another definition. + * + * @author Johannes M. Schmitt + */ +class ChildDefinition extends Definition +{ + private $parent; + + /** + * @param string $parent The id of Definition instance to decorate + */ + public function __construct($parent) + { + $this->parent = $parent; + $this->setPrivate(false); + } + + /** + * Returns the Definition to inherit from. + * + * @return string + */ + public function getParent() + { + return $this->parent; + } + + /** + * Sets the Definition to inherit from. + * + * @param string $parent + * + * @return $this + */ + public function setParent($parent) + { + $this->parent = $parent; + + return $this; + } + + /** + * Gets an argument to pass to the service constructor/factory method. + * + * If replaceArgument() has been used to replace an argument, this method + * will return the replacement value. + * + * @param int|string $index + * + * @return mixed The argument value + * + * @throws OutOfBoundsException When the argument does not exist + */ + public function getArgument($index) + { + if (\array_key_exists('index_'.$index, $this->arguments)) { + return $this->arguments['index_'.$index]; + } + + return parent::getArgument($index); + } + + /** + * You should always use this method when overwriting existing arguments + * of the parent definition. + * + * If you directly call setArguments() keep in mind that you must follow + * certain conventions when you want to overwrite the arguments of the + * parent definition, otherwise your arguments will only be appended. + * + * @param int|string $index + * @param mixed $value + * + * @return $this + * + * @throws InvalidArgumentException when $index isn't an integer + */ + public function replaceArgument($index, $value) + { + if (\is_int($index)) { + $this->arguments['index_'.$index] = $value; + } elseif (0 === strpos($index, '$')) { + $this->arguments[$index] = $value; + } else { + throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.'); + } + + return $this; + } + + /** + * @internal + */ + public function setAutoconfigured($autoconfigured) + { + throw new BadMethodCallException('A ChildDefinition cannot be autoconfigured.'); + } + + /** + * @internal + */ + public function setInstanceofConditionals(array $instanceof) + { + throw new BadMethodCallException('A ChildDefinition cannot have instanceof conditionals set on it.'); + } +} + +class_alias(ChildDefinition::class, DefinitionDecorator::class); diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php new file mode 100644 index 00000000..863bab47 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php @@ -0,0 +1,174 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Nicolas Grekas + */ +abstract class AbstractRecursivePass implements CompilerPassInterface +{ + /** + * @var ContainerBuilder + */ + protected $container; + protected $currentId; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + + try { + $this->processValue($container->getDefinitions(), true); + } finally { + $this->container = null; + } + } + + /** + * Processes a value found in a definition tree. + * + * @param mixed $value + * @param bool $isRoot + * + * @return mixed The processed value + */ + protected function processValue($value, $isRoot = false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + if ($isRoot) { + $this->currentId = $k; + } + if ($v !== $processedValue = $this->processValue($v, $isRoot)) { + $value[$k] = $processedValue; + } + } + } elseif ($value instanceof ArgumentInterface) { + $value->setValues($this->processValue($value->getValues())); + } elseif ($value instanceof Definition) { + $value->setArguments($this->processValue($value->getArguments())); + $value->setProperties($this->processValue($value->getProperties())); + $value->setMethodCalls($this->processValue($value->getMethodCalls())); + + $changes = $value->getChanges(); + if (isset($changes['factory'])) { + $value->setFactory($this->processValue($value->getFactory())); + } + if (isset($changes['configurator'])) { + $value->setConfigurator($this->processValue($value->getConfigurator())); + } + } + + return $value; + } + + /** + * @param bool $required + * + * @return \ReflectionFunctionAbstract|null + * + * @throws RuntimeException + */ + protected function getConstructor(Definition $definition, $required) + { + if ($definition->isSynthetic()) { + return null; + } + + if (\is_string($factory = $definition->getFactory())) { + if (!\function_exists($factory)) { + throw new RuntimeException(sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory)); + } + $r = new \ReflectionFunction($factory); + if (false !== $r->getFileName() && file_exists($r->getFileName())) { + $this->container->fileExists($r->getFileName()); + } + + return $r; + } + + if ($factory) { + list($class, $method) = $factory; + if ($class instanceof Reference) { + $class = $this->container->findDefinition((string) $class)->getClass(); + } elseif (null === $class) { + $class = $definition->getClass(); + } + if ('__construct' === $method) { + throw new RuntimeException(sprintf('Invalid service "%s": "__construct()" cannot be used as a factory method.', $this->currentId)); + } + + return $this->getReflectionMethod(new Definition($class), $method); + } + + $class = $definition->getClass(); + + try { + if (!$r = $this->container->getReflectionClass($class)) { + throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + } catch (\ReflectionException $e) { + throw new RuntimeException(sprintf('Invalid service "%s": ', $this->currentId).lcfirst($e->getMessage())); + } + if (!$r = $r->getConstructor()) { + if ($required) { + throw new RuntimeException(sprintf('Invalid service "%s": class%s has no constructor.', $this->currentId, sprintf($class !== $this->currentId ? ' "%s"' : '', $class))); + } + } elseif (!$r->isPublic()) { + throw new RuntimeException(sprintf('Invalid service "%s": ', $this->currentId).sprintf($class !== $this->currentId ? 'constructor of class "%s"' : 'its constructor', $class).' must be public.'); + } + + return $r; + } + + /** + * @param string $method + * + * @throws RuntimeException + * + * @return \ReflectionFunctionAbstract + */ + protected function getReflectionMethod(Definition $definition, $method) + { + if ('__construct' === $method) { + return $this->getConstructor($definition, true); + } + + if (!$class = $definition->getClass()) { + throw new RuntimeException(sprintf('Invalid service "%s": the class is not set.', $this->currentId)); + } + + if (!$r = $this->container->getReflectionClass($class)) { + throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class)); + } + + if (!$r->hasMethod($method)) { + throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method)); + } + + $r = $r->getMethod($method); + if (!$r->isPublic()) { + throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" must be public.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method)); + } + + return $r; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php new file mode 100644 index 00000000..bff9d420 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AnalyzeServiceReferencesPass.php @@ -0,0 +1,192 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ExpressionLanguage; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * Run this pass before passes that need to know more about the relation of + * your services. + * + * This class will populate the ServiceReferenceGraph with information. You can + * retrieve the graph in other passes from the compiler. + * + * @author Johannes M. Schmitt + */ +class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements RepeatablePassInterface +{ + private $graph; + private $currentDefinition; + private $onlyConstructorArguments; + private $hasProxyDumper; + private $lazy; + private $expressionLanguage; + private $byConstructor; + + /** + * @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls + */ + public function __construct($onlyConstructorArguments = false, $hasProxyDumper = true) + { + $this->onlyConstructorArguments = (bool) $onlyConstructorArguments; + $this->hasProxyDumper = (bool) $hasProxyDumper; + } + + /** + * {@inheritdoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + // no-op for BC + } + + /** + * Processes a ContainerBuilder object to populate the service reference graph. + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->graph = $container->getCompiler()->getServiceReferenceGraph(); + $this->graph->clear(); + $this->lazy = false; + $this->byConstructor = false; + + foreach ($container->getAliases() as $id => $alias) { + $targetId = $this->getDefinitionId((string) $alias); + $this->graph->connect($id, $alias, $targetId, $this->getDefinition($targetId), null); + } + + parent::process($container); + } + + protected function processValue($value, $isRoot = false) + { + $lazy = $this->lazy; + + if ($value instanceof ArgumentInterface) { + $this->lazy = true; + parent::processValue($value->getValues()); + $this->lazy = $lazy; + + return $value; + } + if ($value instanceof Expression) { + $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); + + return $value; + } + if ($value instanceof Reference) { + $targetId = $this->getDefinitionId((string) $value); + $targetDefinition = $this->getDefinition($targetId); + + $this->graph->connect( + $this->currentId, + $this->currentDefinition, + $targetId, + $targetDefinition, + $value, + $this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()), + ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(), + $this->byConstructor + ); + + return $value; + } + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($isRoot) { + if ($value->isSynthetic() || $value->isAbstract()) { + return $value; + } + $this->currentDefinition = $value; + } elseif ($this->currentDefinition === $value) { + return $value; + } + $this->lazy = false; + + $byConstructor = $this->byConstructor; + $this->byConstructor = $isRoot || $byConstructor; + $this->processValue($value->getFactory()); + $this->processValue($value->getArguments()); + $this->byConstructor = $byConstructor; + + if (!$this->onlyConstructorArguments) { + $this->processValue($value->getProperties()); + $this->processValue($value->getMethodCalls()); + $this->processValue($value->getConfigurator()); + } + $this->lazy = $lazy; + + return $value; + } + + /** + * Returns a service definition given the full name or an alias. + * + * @param string $id A full id or alias for a service definition + * + * @return Definition|null The definition related to the supplied id + */ + private function getDefinition($id) + { + return null === $id ? null : $this->container->getDefinition($id); + } + + private function getDefinitionId($id) + { + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if (!$this->container->hasDefinition($id)) { + return null; + } + + return $this->container->normalizeId($id); + } + + private function getExpressionLanguage() + { + if (null === $this->expressionLanguage) { + if (!class_exists(ExpressionLanguage::class)) { + throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { + if ('""' === substr_replace($arg, '', 1, -1)) { + $id = stripcslashes(substr($arg, 1, -1)); + $id = $this->getDefinitionId($id); + + $this->graph->connect( + $this->currentId, + $this->currentDefinition, + $id, + $this->getDefinition($id) + ); + } + + return sprintf('$this->get(%s)', $arg); + }); + } + + return $this->expressionLanguage; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php new file mode 100644 index 00000000..03420683 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutoAliasServicePass.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Sets a service to be an alias of another one, given a format pattern. + */ +class AutoAliasServicePass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->findTaggedServiceIds('auto_alias') as $serviceId => $tags) { + foreach ($tags as $tag) { + if (!isset($tag['format'])) { + throw new InvalidArgumentException(sprintf('Missing tag information "format" on auto_alias service "%s".', $serviceId)); + } + + $aliasId = $container->getParameterBag()->resolveValue($tag['format']); + if ($container->hasDefinition($aliasId) || $container->hasAlias($aliasId)) { + $container->setAlias($serviceId, new Alias($aliasId, true)); + } + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowireExceptionPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowireExceptionPass.php new file mode 100644 index 00000000..6a755025 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowireExceptionPass.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +@trigger_error('The '.__NAMESPACE__.'\AutowireExceptionPass class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the DefinitionErrorExceptionPass class instead.', \E_USER_DEPRECATED); + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Throws autowire exceptions from AutowirePass for definitions that still exist. + * + * @deprecated since version 3.4, will be removed in 4.0. + * + * @author Ryan Weaver + */ +class AutowireExceptionPass implements CompilerPassInterface +{ + private $autowirePass; + private $inlineServicePass; + + public function __construct(AutowirePass $autowirePass, InlineServiceDefinitionsPass $inlineServicePass) + { + $this->autowirePass = $autowirePass; + $this->inlineServicePass = $inlineServicePass; + } + + public function process(ContainerBuilder $container) + { + // the pass should only be run once + if (null === $this->autowirePass || null === $this->inlineServicePass) { + return; + } + + $inlinedIds = $this->inlineServicePass->getInlinedServiceIds(); + $exceptions = $this->autowirePass->getAutowiringExceptions(); + + // free up references + $this->autowirePass = null; + $this->inlineServicePass = null; + + foreach ($exceptions as $exception) { + if ($this->doesServiceExistInTheContainer($exception->getServiceId(), $container, $inlinedIds)) { + throw $exception; + } + } + } + + private function doesServiceExistInTheContainer($serviceId, ContainerBuilder $container, array $inlinedIds) + { + if ($container->hasDefinition($serviceId)) { + return true; + } + + // was the service inlined? Of so, does its parent service exist? + if (isset($inlinedIds[$serviceId])) { + foreach ($inlinedIds[$serviceId] as $parentId) { + if ($this->doesServiceExistInTheContainer($parentId, $container, $inlinedIds)) { + return true; + } + } + } + + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowirePass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowirePass.php new file mode 100644 index 00000000..b1dae2a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowirePass.php @@ -0,0 +1,580 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\Config\Resource\ClassExistenceResource; +use Symfony\Component\DependencyInjection\Config\AutowireServiceResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * Inspects existing service definitions and wires the autowired ones using the type hints of their classes. + * + * @author Kévin Dunglas + * @author Nicolas Grekas + */ +class AutowirePass extends AbstractRecursivePass +{ + private $definedTypes = []; + private $types; + private $ambiguousServiceTypes; + private $autowired = []; + private $lastFailure; + private $throwOnAutowiringException; + private $autowiringExceptions = []; + private $strictMode; + + /** + * @param bool $throwOnAutowireException Errors can be retrieved via Definition::getErrors() + */ + public function __construct($throwOnAutowireException = true) + { + $this->throwOnAutowiringException = $throwOnAutowireException; + } + + /** + * @deprecated since version 3.4, to be removed in 4.0. + * + * @return AutowiringFailedException[] + */ + public function getAutowiringExceptions() + { + @trigger_error('Calling AutowirePass::getAutowiringExceptions() is deprecated since Symfony 3.4 and will be removed in 4.0. Use Definition::getErrors() instead.', \E_USER_DEPRECATED); + + return $this->autowiringExceptions; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + // clear out any possibly stored exceptions from before + $this->autowiringExceptions = []; + $this->strictMode = $container->hasParameter('container.autowiring.strict_mode') && $container->getParameter('container.autowiring.strict_mode'); + + try { + parent::process($container); + } finally { + $this->definedTypes = []; + $this->types = null; + $this->ambiguousServiceTypes = null; + $this->autowired = []; + } + } + + /** + * Creates a resource to help know if this service has changed. + * + * @return AutowireServiceResource + * + * @deprecated since version 3.3, to be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead. + */ + public static function createResourceForClass(\ReflectionClass $reflectionClass) + { + @trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.', \E_USER_DEPRECATED); + + $metadata = []; + + foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) { + if (!$reflectionMethod->isStatic()) { + $metadata[$reflectionMethod->name] = self::getResourceMetadataForMethod($reflectionMethod); + } + } + + return new AutowireServiceResource($reflectionClass->name, $reflectionClass->getFileName(), $metadata); + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + try { + return $this->doProcessValue($value, $isRoot); + } catch (AutowiringFailedException $e) { + if ($this->throwOnAutowiringException) { + throw $e; + } + + $this->autowiringExceptions[] = $e; + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + + return parent::processValue($value, $isRoot); + } + } + + private function doProcessValue($value, $isRoot = false) + { + if ($value instanceof TypedReference) { + if ($ref = $this->getAutowiredReference($value, $value->getRequiringClass() ? sprintf('for "%s" in "%s"', $value->getType(), $value->getRequiringClass()) : '')) { + return $ref; + } + $this->container->log($this, $this->createTypeNotFoundMessage($value, 'it')); + } + $value = parent::processValue($value, $isRoot); + + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) { + $this->container->log($this, sprintf('Skipping service "%s": Class or interface "%s" cannot be loaded.', $this->currentId, $value->getClass())); + + return $value; + } + + $methodCalls = $value->getMethodCalls(); + + try { + $constructor = $this->getConstructor($value, false); + } catch (RuntimeException $e) { + throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e); + } + + if ($constructor) { + array_unshift($methodCalls, [$constructor, $value->getArguments()]); + } + + $methodCalls = $this->autowireCalls($reflectionClass, $methodCalls); + + if ($constructor) { + list(, $arguments) = array_shift($methodCalls); + + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + } + + if ($methodCalls !== $value->getMethodCalls()) { + $value->setMethodCalls($methodCalls); + } + + return $value; + } + + /** + * @return array + */ + private function autowireCalls(\ReflectionClass $reflectionClass, array $methodCalls) + { + foreach ($methodCalls as $i => $call) { + list($method, $arguments) = $call; + + if ($method instanceof \ReflectionFunctionAbstract) { + $reflectionMethod = $method; + } else { + $definition = new Definition($reflectionClass->name); + try { + $reflectionMethod = $this->getReflectionMethod($definition, $method); + } catch (RuntimeException $e) { + if ($definition->getFactory()) { + continue; + } + throw $e; + } + } + + $arguments = $this->autowireMethod($reflectionMethod, $arguments); + + if ($arguments !== $call[1]) { + $methodCalls[$i][1] = $arguments; + } + } + + return $methodCalls; + } + + /** + * Autowires the constructor or a method. + * + * @return array The autowired arguments + * + * @throws AutowiringFailedException + */ + private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments) + { + $class = $reflectionMethod instanceof \ReflectionMethod ? $reflectionMethod->class : $this->currentId; + $method = $reflectionMethod->name; + $parameters = $reflectionMethod->getParameters(); + if (method_exists('ReflectionMethod', 'isVariadic') && $reflectionMethod->isVariadic()) { + array_pop($parameters); + } + + foreach ($parameters as $index => $parameter) { + if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) { + continue; + } + + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true); + + if (!$type) { + if (isset($arguments[$index])) { + continue; + } + + // no default value? Then fail + if (!$parameter->isDefaultValueAvailable()) { + // For core classes, isDefaultValueAvailable() can + // be false when isOptional() returns true. If the + // argument *is* optional, allow it to be missing + if ($parameter->isOptional()) { + continue; + } + $type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false); + $type = $type ? sprintf('is type-hinted "%s"', $type) : 'has no type-hint'; + + throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type)); + } + + // specifically pass the default value + $arguments[$index] = $parameter->getDefaultValue(); + + continue; + } + + if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''), 'for '.sprintf('argument "$%s" of method "%s()"', $parameter->name, $class.'::'.$method))) { + $failureMessage = $this->createTypeNotFoundMessage($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method)); + + if ($parameter->isDefaultValueAvailable()) { + $value = $parameter->getDefaultValue(); + } elseif (!$parameter->allowsNull()) { + throw new AutowiringFailedException($this->currentId, $failureMessage); + } + $this->container->log($this, $failureMessage); + } + + $arguments[$index] = $value; + } + + if ($parameters && !isset($arguments[++$index])) { + while (0 <= --$index) { + $parameter = $parameters[$index]; + if (!$parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== $arguments[$index]) { + break; + } + unset($arguments[$index]); + } + } + + // it's possible index 1 was set, then index 0, then 2, etc + // make sure that we re-order so they're injected as expected + ksort($arguments); + + return $arguments; + } + + /** + * @return TypedReference|null A reference to the service matching the given type, if any + */ + private function getAutowiredReference(TypedReference $reference, $deprecationMessage) + { + $this->lastFailure = null; + $type = $reference->getType(); + + if ($type !== $this->container->normalizeId($reference) || ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract())) { + return $reference; + } + + if (null === $this->types) { + $this->populateAvailableTypes($this->strictMode); + } + + if (isset($this->definedTypes[$type])) { + return new TypedReference($this->types[$type], $type); + } + + if (!$this->strictMode && isset($this->types[$type])) { + $message = 'Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won\'t be supported in version 4.0.'; + if ($aliasSuggestion = $this->getAliasesSuggestionForType($type = $reference->getType(), $deprecationMessage)) { + $message .= ' '.$aliasSuggestion; + } else { + $message .= sprintf(' You should %s the "%s" service to "%s" instead.', isset($this->types[$this->types[$type]]) ? 'alias' : 'rename (or alias)', $this->types[$type], $type); + } + + @trigger_error($message, \E_USER_DEPRECATED); + + return new TypedReference($this->types[$type], $type); + } + + if (!$reference->canBeAutoregistered() || isset($this->types[$type]) || isset($this->ambiguousServiceTypes[$type])) { + return null; + } + + if (isset($this->autowired[$type])) { + return $this->autowired[$type] ? new TypedReference($this->autowired[$type], $type) : null; + } + + if (!$this->strictMode) { + return $this->createAutowiredDefinition($type); + } + + return null; + } + + /** + * Populates the list of available types. + */ + private function populateAvailableTypes($onlyAutowiringTypes = false) + { + $this->types = []; + if (!$onlyAutowiringTypes) { + $this->ambiguousServiceTypes = []; + } + + foreach ($this->container->getDefinitions() as $id => $definition) { + $this->populateAvailableType($id, $definition, $onlyAutowiringTypes); + } + } + + /** + * Populates the list of available types for a given definition. + * + * @param string $id + */ + private function populateAvailableType($id, Definition $definition, $onlyAutowiringTypes) + { + // Never use abstract services + if ($definition->isAbstract()) { + return; + } + + foreach ($definition->getAutowiringTypes(false) as $type) { + $this->definedTypes[$type] = true; + $this->types[$type] = $id; + unset($this->ambiguousServiceTypes[$type]); + } + + if ($onlyAutowiringTypes) { + return; + } + + if (preg_match('/^\d+_[^~]++~[._a-zA-Z\d]{7}$/', $id) || $definition->isDeprecated() || !$reflectionClass = $this->container->getReflectionClass($definition->getClass(), false)) { + return; + } + + foreach ($reflectionClass->getInterfaces() as $reflectionInterface) { + $this->set($reflectionInterface->name, $id); + } + + do { + $this->set($reflectionClass->name, $id); + } while ($reflectionClass = $reflectionClass->getParentClass()); + } + + /** + * Associates a type and a service id if applicable. + * + * @param string $type + * @param string $id + */ + private function set($type, $id) + { + if (isset($this->definedTypes[$type])) { + return; + } + + // is this already a type/class that is known to match multiple services? + if (isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type][] = $id; + + return; + } + + // check to make sure the type doesn't match multiple services + if (!isset($this->types[$type]) || $this->types[$type] === $id) { + $this->types[$type] = $id; + + return; + } + + // keep an array of all services matching this type + if (!isset($this->ambiguousServiceTypes[$type])) { + $this->ambiguousServiceTypes[$type] = [$this->types[$type]]; + unset($this->types[$type]); + } + $this->ambiguousServiceTypes[$type][] = $id; + } + + /** + * Registers a definition for the type if possible or throws an exception. + * + * @param string $type + * + * @return TypedReference|null A reference to the registered definition + */ + private function createAutowiredDefinition($type) + { + if (!($typeHint = $this->container->getReflectionClass($type, false)) || !$typeHint->isInstantiable()) { + return null; + } + + $currentId = $this->currentId; + $this->currentId = $type; + $this->autowired[$type] = $argumentId = sprintf('autowired.%s', $type); + $argumentDefinition = new Definition($type); + $argumentDefinition->setPublic(false); + $argumentDefinition->setAutowired(true); + + try { + $originalThrowSetting = $this->throwOnAutowiringException; + $this->throwOnAutowiringException = true; + $this->processValue($argumentDefinition, true); + $this->container->setDefinition($argumentId, $argumentDefinition); + } catch (AutowiringFailedException $e) { + $this->autowired[$type] = false; + $this->lastFailure = $e->getMessage(); + $this->container->log($this, $this->lastFailure); + + return null; + } finally { + $this->throwOnAutowiringException = $originalThrowSetting; + $this->currentId = $currentId; + } + + @trigger_error(sprintf('Relying on service auto-registration for type "%s" is deprecated since Symfony 3.4 and won\'t be supported in 4.0. Create a service named "%s" instead.', $type, $type), \E_USER_DEPRECATED); + + $this->container->log($this, sprintf('Type "%s" has been auto-registered for service "%s".', $type, $this->currentId)); + + return new TypedReference($argumentId, $type); + } + + private function createTypeNotFoundMessage(TypedReference $reference, $label) + { + $trackResources = $this->container->isTrackingResources(); + $this->container->setResourceTracking(false); + try { + if ($r = $this->container->getReflectionClass($type = $reference->getType(), false)) { + $alternatives = $this->createTypeAlternatives($reference); + } + } finally { + $this->container->setResourceTracking($trackResources); + } + + if (!$r) { + // either $type does not exist or a parent class does not exist + try { + $resource = new ClassExistenceResource($type, false); + // isFresh() will explode ONLY if a parent class/trait does not exist + $resource->isFresh(0); + $parentMsg = false; + } catch (\ReflectionException $e) { + $parentMsg = $e->getMessage(); + } + + $message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found'); + } else { + $message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists'; + $message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives); + + if ($r->isInterface() && !$alternatives) { + $message .= ' Did you create a class that implements this interface?'; + } + } + + $message = sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message); + + if (null !== $this->lastFailure) { + $message = $this->lastFailure."\n".$message; + $this->lastFailure = null; + } + + return $message; + } + + private function createTypeAlternatives(TypedReference $reference) + { + // try suggesting available aliases first + if ($message = $this->getAliasesSuggestionForType($type = $reference->getType())) { + return ' '.$message; + } + if (null === $this->ambiguousServiceTypes) { + $this->populateAvailableTypes(); + } + + if (isset($this->ambiguousServiceTypes[$type])) { + $message = sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type])); + } elseif (isset($this->types[$type])) { + $message = sprintf('the existing "%s" service', $this->types[$type]); + } elseif ($reference->getRequiringClass() && !$reference->canBeAutoregistered() && !$this->strictMode) { + return ' It cannot be auto-registered because it is from a different root namespace.'; + } else { + return ''; + } + + return sprintf(' You should maybe alias this %s to %s.', class_exists($type, false) ? 'class' : 'interface', $message); + } + + /** + * @deprecated since version 3.3, to be removed in 4.0. + */ + private static function getResourceMetadataForMethod(\ReflectionMethod $method) + { + $methodArgumentsMetadata = []; + foreach ($method->getParameters() as $parameter) { + try { + if (method_exists($parameter, 'getType')) { + $type = $parameter->getType(); + if ($type && !$type->isBuiltin()) { + $class = new \ReflectionClass($type instanceof \ReflectionNamedType ? $type->getName() : (string) $type); + } else { + $class = null; + } + } else { + $class = $parameter->getClass(); + } + } catch (\ReflectionException $e) { + // type-hint is against a non-existent class + $class = false; + } + + $isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic(); + $methodArgumentsMetadata[] = [ + 'class' => $class, + 'isOptional' => $parameter->isOptional(), + 'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null, + ]; + } + + return $methodArgumentsMetadata; + } + + private function getAliasesSuggestionForType($type, $extraContext = null) + { + $aliases = []; + foreach (class_parents($type) + class_implements($type) as $parent) { + if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) { + $aliases[] = $parent; + } + } + + $extraContext = $extraContext ? ' '.$extraContext : ''; + if (1 < $len = \count($aliases)) { + $message = sprintf('Try changing the type-hint%s to one of its parents: ', $extraContext); + for ($i = 0, --$len; $i < $len; ++$i) { + $message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]); + } + $message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]); + + return $message; + } + + if ($aliases) { + return sprintf('Try changing the type-hint%s to "%s" instead.', $extraContext, $aliases[0]); + } + + return null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php new file mode 100644 index 00000000..efb9df7b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Looks for definitions with autowiring enabled and registers their corresponding "@required" methods as setters. + * + * @author Nicolas Grekas + */ +class AutowireRequiredMethodsPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + $value = parent::processValue($value, $isRoot); + + if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) { + return $value; + } + if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) { + return $value; + } + + $alreadyCalledMethods = []; + + foreach ($value->getMethodCalls() as list($method)) { + $alreadyCalledMethods[strtolower($method)] = true; + } + + foreach ($reflectionClass->getMethods() as $reflectionMethod) { + $r = $reflectionMethod; + + if ($r->isConstructor() || isset($alreadyCalledMethods[strtolower($r->name)])) { + continue; + } + + while (true) { + if (false !== $doc = $r->getDocComment()) { + if (false !== stripos($doc, '@required') && preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) { + $value->addMethodCall($reflectionMethod->name); + break; + } + if (false === stripos($doc, '@inheritdoc') || !preg_match('#(?:^/\*\*|\n\s*+\*)\s*+(?:\{@inheritdoc\}|@inheritdoc)(?:\s|\*/$)#i', $doc)) { + break; + } + } + try { + $r = $r->getPrototype(); + } catch (\ReflectionException $e) { + break; // method has no prototype + } + } + } + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php new file mode 100644 index 00000000..30a6f524 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Checks if arguments of methods are properly configured. + * + * @author Kévin Dunglas + * @author Nicolas Grekas + */ +class CheckArgumentsValidityPass extends AbstractRecursivePass +{ + private $throwExceptions; + + public function __construct($throwExceptions = true) + { + $this->throwExceptions = $throwExceptions; + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + + $i = 0; + foreach ($value->getArguments() as $k => $v) { + if ($k !== $i++) { + if (!\is_int($k)) { + $msg = sprintf('Invalid constructor argument for service "%s": integer expected but found string "%s". Check your service definition.', $this->currentId, $k); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + + break; + } + + $msg = sprintf('Invalid constructor argument %d for service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $this->currentId, $i); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + } + } + + foreach ($value->getMethodCalls() as $methodCall) { + $i = 0; + foreach ($methodCall[1] as $k => $v) { + if ($k !== $i++) { + if (!\is_int($k)) { + $msg = sprintf('Invalid argument for method call "%s" of service "%s": integer expected but found string "%s". Check your service definition.', $methodCall[0], $this->currentId, $k); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + + break; + } + + $msg = sprintf('Invalid argument %d for method call "%s" of service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $methodCall[0], $this->currentId, $i); + $value->addError($msg); + if ($this->throwExceptions) { + throw new RuntimeException($msg); + } + } + } + } + + return null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php new file mode 100644 index 00000000..55d911c4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckCircularReferencesPass.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; + +/** + * Checks your services for circular references. + * + * References from method calls are ignored since we might be able to resolve + * these references depending on the order in which services are called. + * + * Circular reference from method calls will only be detected at run-time. + * + * @author Johannes M. Schmitt + */ +class CheckCircularReferencesPass implements CompilerPassInterface +{ + private $currentPath; + private $checkedNodes; + + /** + * Checks the ContainerBuilder object for circular references. + */ + public function process(ContainerBuilder $container) + { + $graph = $container->getCompiler()->getServiceReferenceGraph(); + + $this->checkedNodes = []; + foreach ($graph->getNodes() as $id => $node) { + $this->currentPath = [$id]; + + $this->checkOutEdges($node->getOutEdges()); + } + } + + /** + * Checks for circular references. + * + * @param ServiceReferenceGraphEdge[] $edges An array of Edges + * + * @throws ServiceCircularReferenceException when a circular reference is found + */ + private function checkOutEdges(array $edges) + { + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + + if (empty($this->checkedNodes[$id])) { + // Don't check circular references for lazy edges + if (!$node->getValue() || (!$edge->isLazy() && !$edge->isWeak())) { + $searchKey = array_search($id, $this->currentPath); + $this->currentPath[] = $id; + + if (false !== $searchKey) { + throw new ServiceCircularReferenceException($id, \array_slice($this->currentPath, $searchKey)); + } + + $this->checkOutEdges($node->getOutEdges()); + } + + $this->checkedNodes[$id] = true; + array_pop($this->currentPath); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php new file mode 100644 index 00000000..4b6d277f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckDefinitionValidityPass.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * This pass validates each definition individually only taking the information + * into account which is contained in the definition itself. + * + * Later passes can rely on the following, and specifically do not need to + * perform these checks themselves: + * + * - non synthetic, non abstract services always have a class set + * - synthetic services are always public + * + * @author Johannes M. Schmitt + */ +class CheckDefinitionValidityPass implements CompilerPassInterface +{ + /** + * Processes the ContainerBuilder to validate the Definition. + * + * @throws RuntimeException When the Definition is invalid + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + // synthetic service is public + if ($definition->isSynthetic() && !($definition->isPublic() || $definition->isPrivate())) { + throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id)); + } + + // non-synthetic, non-abstract service has class + if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) { + if ($definition->getFactory()) { + throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id)); + } + if (class_exists($id) || interface_exists($id, false)) { + if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) { + throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "%s" to get rid of this error.', $id, substr($id, 1))); + } + + throw new RuntimeException(sprintf('The definition for "%s" has no class attribute, and appears to reference a class or interface in the global namespace. Leaving out the "class" attribute is only allowed for namespaced classes. Please specify the class attribute explicitly to get rid of this error.', $id)); + } + + throw new RuntimeException(sprintf('The definition for "%s" has no class. If you intend to inject this service dynamically at runtime, please mark it as synthetic=true. If this is an abstract definition solely used by child definitions, please add abstract=true, otherwise specify a class to get rid of this error.', $id)); + } + + // tag attribute values must be scalars + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + foreach ($attributes as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new RuntimeException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $id, $name, $attribute)); + } + } + } + } + + if ($definition->isPublic() && !$definition->isPrivate()) { + $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); + if (null !== $usedEnvs) { + throw new EnvParameterException([$resolvedId], null, 'A service name ("%s") cannot contain dynamic values.'); + } + } + } + + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic() && !$alias->isPrivate()) { + $resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs); + if (null !== $usedEnvs) { + throw new EnvParameterException([$resolvedId], null, 'An alias name ("%s") cannot contain dynamic values.'); + } + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php new file mode 100644 index 00000000..77b35f18 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Checks that all references are pointing to a valid service. + * + * @author Johannes M. Schmitt + */ +class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Reference) { + return parent::processValue($value, $isRoot); + } + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior() && !$this->container->has($id = (string) $value)) { + throw new ServiceNotFoundException($id, $this->currentId); + } + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php new file mode 100644 index 00000000..8f2a3bdf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CheckReferenceValidityPass.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Checks the validity of references. + * + * The following checks are performed by this pass: + * - target definitions are not abstract + * + * @author Johannes M. Schmitt + */ +class CheckReferenceValidityPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if ($isRoot && $value instanceof Definition && ($value->isSynthetic() || $value->isAbstract())) { + return $value; + } + if ($value instanceof Reference && $this->container->hasDefinition((string) $value)) { + $targetDefinition = $this->container->getDefinition((string) $value); + + if ($targetDefinition->isAbstract()) { + throw new RuntimeException(sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $value)); + } + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/Compiler.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/Compiler.php new file mode 100644 index 00000000..0eb9d036 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/Compiler.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; + +/** + * This class is used to remove circular dependencies between individual passes. + * + * @author Johannes M. Schmitt + */ +class Compiler +{ + private $passConfig; + private $log = []; + private $loggingFormatter; + private $serviceReferenceGraph; + + public function __construct() + { + $this->passConfig = new PassConfig(); + $this->serviceReferenceGraph = new ServiceReferenceGraph(); + } + + /** + * Returns the PassConfig. + * + * @return PassConfig The PassConfig instance + */ + public function getPassConfig() + { + return $this->passConfig; + } + + /** + * Returns the ServiceReferenceGraph. + * + * @return ServiceReferenceGraph The ServiceReferenceGraph instance + */ + public function getServiceReferenceGraph() + { + return $this->serviceReferenceGraph; + } + + /** + * Returns the logging formatter which can be used by compilation passes. + * + * @return LoggingFormatter + * + * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead. + */ + public function getLoggingFormatter() + { + if (null === $this->loggingFormatter) { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', __METHOD__), \E_USER_DEPRECATED); + + $this->loggingFormatter = new LoggingFormatter(); + } + + return $this->loggingFormatter; + } + + /** + * Adds a pass to the PassConfig. + * + * @param CompilerPassInterface $pass A compiler pass + * @param string $type The type of the pass + */ + public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/) + { + if (\func_num_args() >= 3) { + $priority = func_get_arg(2); + } else { + if (__CLASS__ !== static::class) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), \E_USER_DEPRECATED); + } + } + + $priority = 0; + } + + $this->passConfig->addPass($pass, $type, $priority); + } + + /** + * Adds a log message. + * + * @param string $string The log message + * + * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead. + */ + public function addLogMessage($string) + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', __METHOD__), \E_USER_DEPRECATED); + + $this->log[] = $string; + } + + /** + * @final + */ + public function log(CompilerPassInterface $pass, $message) + { + if (false !== strpos($message, "\n")) { + $message = str_replace("\n", "\n".\get_class($pass).': ', trim($message)); + } + + $this->log[] = \get_class($pass).': '.$message; + } + + /** + * Returns the log. + * + * @return array Log array + */ + public function getLog() + { + return $this->log; + } + + /** + * Run the Compiler and process all Passes. + */ + public function compile(ContainerBuilder $container) + { + try { + foreach ($this->passConfig->getPasses() as $pass) { + $pass->process($container); + } + } catch (\Exception $e) { + $usedEnvs = []; + $prev = $e; + + do { + $msg = $prev->getMessage(); + + if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) { + $r = new \ReflectionProperty($prev, 'message'); + $r->setAccessible(true); + $r->setValue($prev, $resolvedMsg); + } + } while ($prev = $prev->getPrevious()); + + if ($usedEnvs) { + $e = new EnvParameterException($usedEnvs, $e); + } + + throw $e; + } finally { + $this->getServiceReferenceGraph()->clear(); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php new file mode 100644 index 00000000..30850060 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/CompilerPassInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Interface that must be implemented by compilation passes. + * + * @author Johannes M. Schmitt + */ +interface CompilerPassInterface +{ + /** + * You can modify the container here before it is dumped to PHP code. + */ + public function process(ContainerBuilder $container); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php new file mode 100644 index 00000000..bf5f9157 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/DecoratorServicePass.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Overwrites a service but keeps the overridden one. + * + * @author Christophe Coevoet + * @author Fabien Potencier + * @author Diego Saint Esteben + */ +class DecoratorServicePass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + $definitions = new \SplPriorityQueue(); + $order = \PHP_INT_MAX; + + foreach ($container->getDefinitions() as $id => $definition) { + if (!$decorated = $definition->getDecoratedService()) { + continue; + } + $definitions->insert([$id, $definition], [$decorated[2], --$order]); + } + $decoratingDefinitions = []; + + foreach ($definitions as list($id, $definition)) { + list($inner, $renamedId) = $definition->getDecoratedService(); + + $definition->setDecoratedService(null); + + if (!$renamedId) { + $renamedId = $id.'.inner'; + } + + // we create a new alias/service for the service we are replacing + // to be able to reference it in the new one + if ($container->hasAlias($inner)) { + $alias = $container->getAlias($inner); + $public = $alias->isPublic(); + $private = $alias->isPrivate(); + $container->setAlias($renamedId, new Alias($container->normalizeId($alias), false)); + } else { + $decoratedDefinition = $container->getDefinition($inner); + $public = $decoratedDefinition->isPublic(); + $private = $decoratedDefinition->isPrivate(); + $decoratedDefinition->setPublic(false); + $container->setDefinition($renamedId, $decoratedDefinition); + $decoratingDefinitions[$inner] = $decoratedDefinition; + } + + if (isset($decoratingDefinitions[$inner])) { + $decoratingDefinition = $decoratingDefinitions[$inner]; + $definition->setTags(array_merge($decoratingDefinition->getTags(), $definition->getTags())); + $autowiringTypes = $decoratingDefinition->getAutowiringTypes(false); + if ($types = array_merge($autowiringTypes, $definition->getAutowiringTypes(false))) { + $definition->setAutowiringTypes($types); + } + $decoratingDefinition->setTags([]); + if ($autowiringTypes) { + $decoratingDefinition->setAutowiringTypes([]); + } + $decoratingDefinitions[$inner] = $definition; + } + + $container->setAlias($inner, $id)->setPublic($public)->setPrivate($private); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php new file mode 100644 index 00000000..73b5d1d5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Throws an exception for any Definitions that have errors and still exist. + * + * @author Ryan Weaver + */ +class DefinitionErrorExceptionPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition || empty($value->getErrors())) { + return parent::processValue($value, $isRoot); + } + + // only show the first error so the user can focus on it + $errors = $value->getErrors(); + $message = reset($errors); + + throw new RuntimeException($message); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php new file mode 100644 index 00000000..27e50482 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ExtensionCompilerPass.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * A pass to automatically process extensions if they implement + * CompilerPassInterface. + * + * @author Wouter J + */ +class ExtensionCompilerPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getExtensions() as $extension) { + if (!$extension instanceof CompilerPassInterface) { + continue; + } + + $extension->process($container); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php new file mode 100644 index 00000000..67575c03 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Guilhem N. + * + * @deprecated since version 3.3, to be removed in 4.0. + */ +class FactoryReturnTypePass implements CompilerPassInterface +{ + private $resolveClassPass; + + public function __construct(ResolveClassPass $resolveClassPass = null) + { + if (null === $resolveClassPass) { + @trigger_error('The '.__CLASS__.' class is deprecated since Symfony 3.3 and will be removed in 4.0.', \E_USER_DEPRECATED); + } + $this->resolveClassPass = $resolveClassPass; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + // works only since php 7.0 and hhvm 3.11 + if (!method_exists(\ReflectionMethod::class, 'getReturnType')) { + return; + } + $resolveClassPassChanges = null !== $this->resolveClassPass ? $this->resolveClassPass->getChanges() : []; + + foreach ($container->getDefinitions() as $id => $definition) { + $this->updateDefinition($container, $id, $definition, $resolveClassPassChanges); + } + } + + private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = []) + { + // circular reference + if (isset($previous[$id])) { + return; + } + + $factory = $definition->getFactory(); + if (null === $factory || (!isset($resolveClassPassChanges[$id]) && null !== $definition->getClass())) { + return; + } + + $class = null; + if (\is_string($factory)) { + try { + $m = new \ReflectionFunction($factory); + if (false !== $m->getFileName() && file_exists($m->getFileName())) { + $container->fileExists($m->getFileName()); + } + } catch (\ReflectionException $e) { + return; + } + } else { + if ($factory[0] instanceof Reference) { + $previous[$id] = true; + $factoryId = $container->normalizeId($factory[0]); + $factoryDefinition = $container->findDefinition($factoryId); + $this->updateDefinition($container, $factoryId, $factoryDefinition, $resolveClassPassChanges, $previous); + $class = $factoryDefinition->getClass(); + } else { + $class = $factory[0]; + } + + if (!$m = $container->getReflectionClass($class, false)) { + return; + } + try { + $m = $m->getMethod($factory[1]); + } catch (\ReflectionException $e) { + return; + } + } + + $returnType = $m->getReturnType(); + if (null !== $returnType && !$returnType->isBuiltin()) { + $returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType; + if (null !== $class) { + $declaringClass = $m->getDeclaringClass()->getName(); + if ('self' === strtolower($returnType)) { + $returnType = $declaringClass; + } elseif ('parent' === strtolower($returnType)) { + $returnType = get_parent_class($declaringClass) ?: null; + } + } + + if (null !== $returnType && (!isset($resolveClassPassChanges[$id]) || $returnType !== $resolveClassPassChanges[$id])) { + @trigger_error(sprintf('Relying on its factory\'s return-type to define the class of service "%s" is deprecated since Symfony 3.3 and won\'t work in 4.0. Set the "class" attribute to "%s" on the service definition instead.', $id, $returnType), \E_USER_DEPRECATED); + } + $definition->setClass($returnType); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php new file mode 100644 index 00000000..9d8a02e7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/InlineServiceDefinitionsPass.php @@ -0,0 +1,153 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Inline service definitions where this is possible. + * + * @author Johannes M. Schmitt + */ +class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface +{ + private $cloningIds = []; + private $inlinedServiceIds = []; + + /** + * {@inheritdoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + // no-op for BC + } + + /** + * Returns an array of all services inlined by this pass. + * + * The key is the inlined service id and its value is the list of services it was inlined into. + * + * @deprecated since version 3.4, to be removed in 4.0. + * + * @return array + */ + public function getInlinedServiceIds() + { + @trigger_error('Calling InlineServiceDefinitionsPass::getInlinedServiceIds() is deprecated since Symfony 3.4 and will be removed in 4.0.', \E_USER_DEPRECATED); + + return $this->inlinedServiceIds; + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof ArgumentInterface) { + // Reference found in ArgumentInterface::getValues() are not inlineable + return $value; + } + + if ($value instanceof Definition && $this->cloningIds) { + if ($value->isShared()) { + return $value; + } + $value = clone $value; + } + + if (!$value instanceof Reference || !$this->container->hasDefinition($id = $this->container->normalizeId($value))) { + return parent::processValue($value, $isRoot); + } + + $definition = $this->container->getDefinition($id); + + if (!$this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) { + return $value; + } + + $this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId)); + $this->inlinedServiceIds[$id][] = $this->currentId; + + if ($definition->isShared()) { + return $definition; + } + + if (isset($this->cloningIds[$id])) { + $ids = array_keys($this->cloningIds); + $ids[] = $id; + + throw new ServiceCircularReferenceException($id, \array_slice($ids, array_search($id, $ids))); + } + + $this->cloningIds[$id] = true; + try { + return $this->processValue($definition); + } finally { + unset($this->cloningIds[$id]); + } + } + + /** + * Checks if the definition is inlineable. + * + * @return bool If the definition is inlineable + */ + private function isInlineableDefinition($id, Definition $definition, ServiceReferenceGraph $graph) + { + if ($definition->getErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic()) { + return false; + } + + if (!$definition->isShared()) { + return true; + } + + if ($definition->isPublic() || $definition->isPrivate()) { + return false; + } + + if (!$graph->hasNode($id)) { + return true; + } + + if ($this->currentId == $id) { + return false; + } + + $ids = []; + $isReferencedByConstructor = false; + foreach ($graph->getNode($id)->getInEdges() as $edge) { + $isReferencedByConstructor = $isReferencedByConstructor || $edge->isReferencedByConstructor(); + if ($edge->isWeak() || $edge->isLazy()) { + return false; + } + $ids[] = $edge->getSourceNode()->getId(); + } + + if (!$ids) { + return true; + } + + if (\count(array_unique($ids)) > 1) { + return false; + } + + if (\count($ids) > 1 && \is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) { + return false; + } + + return $this->container->getDefinition($ids[0])->isShared(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/LoggingFormatter.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/LoggingFormatter.php new file mode 100644 index 00000000..0d91f00f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/LoggingFormatter.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +@trigger_error('The '.__NAMESPACE__.'\LoggingFormatter class is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', \E_USER_DEPRECATED); + +/** + * Used to format logging messages during the compilation. + * + * @author Johannes M. Schmitt + * + * @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead. + */ +class LoggingFormatter +{ + public function formatRemoveService(CompilerPassInterface $pass, $id, $reason) + { + return $this->format($pass, sprintf('Removed service "%s"; reason: %s.', $id, $reason)); + } + + public function formatInlineService(CompilerPassInterface $pass, $id, $target) + { + return $this->format($pass, sprintf('Inlined service "%s" to "%s".', $id, $target)); + } + + public function formatUpdateReference(CompilerPassInterface $pass, $serviceId, $oldDestId, $newDestId) + { + return $this->format($pass, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $serviceId, $oldDestId, $newDestId)); + } + + public function formatResolveInheritance(CompilerPassInterface $pass, $childId, $parentId) + { + return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId)); + } + + public function formatUnusedAutowiringPatterns(CompilerPassInterface $pass, $id, array $patterns) + { + return $this->format($pass, sprintf('Autowiring\'s patterns "%s" for service "%s" don\'t match any method.', implode('", "', $patterns), $id)); + } + + public function format(CompilerPassInterface $pass, $message) + { + return sprintf('%s: %s', \get_class($pass), $message); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php new file mode 100644 index 00000000..caa1fd22 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/MergeExtensionConfigurationPass.php @@ -0,0 +1,206 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; + +/** + * Merges extension configs into the container builder. + * + * @author Fabien Potencier + */ +class MergeExtensionConfigurationPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $parameters = $container->getParameterBag()->all(); + $definitions = $container->getDefinitions(); + $aliases = $container->getAliases(); + $exprLangProviders = $container->getExpressionLanguageProviders(); + + foreach ($container->getExtensions() as $extension) { + if ($extension instanceof PrependExtensionInterface) { + $extension->prepend($container); + } + } + + foreach ($container->getExtensions() as $name => $extension) { + if (!$config = $container->getExtensionConfig($name)) { + // this extension was not called + continue; + } + $resolvingBag = $container->getParameterBag(); + if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) { + // create a dedicated bag so that we can track env vars per-extension + $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag); + } + $config = $resolvingBag->resolveValue($config); + + try { + $tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag); + $tmpContainer->setResourceTracking($container->isTrackingResources()); + $tmpContainer->addObjectResource($extension); + if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) { + $tmpContainer->addObjectResource($configuration); + } + + foreach ($exprLangProviders as $provider) { + $tmpContainer->addExpressionLanguageProvider($provider); + } + + $extension->load($config, $tmpContainer); + } catch (\Exception $e) { + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag); + } + + throw $e; + } + + if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) { + // don't keep track of env vars that are *overridden* when configs are merged + $resolvingBag->freezeAfterProcessing($extension, $tmpContainer); + } + + $container->merge($tmpContainer); + $container->getParameterBag()->add($parameters); + } + + $container->addDefinitions($definitions); + $container->addAliases($aliases); + } +} + +/** + * @internal + */ +class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag +{ + private $processedEnvPlaceholders; + + public function __construct(parent $parameterBag) + { + parent::__construct($parameterBag->all()); + $this->mergeEnvPlaceholders($parameterBag); + } + + public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container) + { + if (!$config = $extension->getProcessedConfigs()) { + // Extension::processConfiguration() wasn't called, we cannot know how configs were merged + return; + } + $this->processedEnvPlaceholders = []; + + // serialize config and container to catch env vars nested in object graphs + $config = serialize($config).serialize($container->getDefinitions()).serialize($container->getAliases()).serialize($container->getParameterBag()->all()); + + foreach (parent::getEnvPlaceholders() as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (false !== stripos($config, $placeholder)) { + $this->processedEnvPlaceholders[$env] = $placeholders; + break; + } + } + } + } + + /** + * {@inheritdoc} + */ + public function getEnvPlaceholders() + { + return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders(); + } +} + +/** + * A container builder preventing using methods that wouldn't have any effect from extensions. + * + * @internal + */ +class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder +{ + private $extensionClass; + + public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + + $this->extensionClass = \get_class($extension); + } + + /** + * {@inheritdoc} + */ + public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/) + { + throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', \get_class($pass), $this->extensionClass)); + } + + /** + * {@inheritdoc} + */ + public function registerExtension(ExtensionInterface $extension) + { + throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', \get_class($extension), $this->extensionClass)); + } + + /** + * {@inheritdoc} + */ + public function compile($resolveEnvPlaceholders = false) + { + throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass)); + } + + /** + * {@inheritdoc} + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (true !== $format || !\is_string($value)) { + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } + + $bag = $this->getParameterBag(); + $value = $bag->resolveValue($value); + + if (!$bag instanceof EnvPlaceholderParameterBag) { + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } + + foreach ($bag->getEnvPlaceholders() as $env => $placeholders) { + if (false === strpos($env, ':')) { + continue; + } + foreach ($placeholders as $placeholder) { + if (false !== stripos($value, $placeholder)) { + throw new RuntimeException(sprintf('Using a cast in "env(%s)" is incompatible with resolution at compile time in "%s". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.', $env, $this->extensionClass)); + } + } + } + + return parent::resolveEnvPlaceholders($value, $format, $usedEnvs); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/PassConfig.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/PassConfig.php new file mode 100644 index 00000000..d95b2198 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/PassConfig.php @@ -0,0 +1,282 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Compiler Pass Configuration. + * + * This class has a default configuration embedded. + * + * @author Johannes M. Schmitt + */ +class PassConfig +{ + const TYPE_AFTER_REMOVING = 'afterRemoving'; + const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization'; + const TYPE_BEFORE_REMOVING = 'beforeRemoving'; + const TYPE_OPTIMIZE = 'optimization'; + const TYPE_REMOVE = 'removing'; + + private $mergePass; + private $afterRemovingPasses = []; + private $beforeOptimizationPasses = []; + private $beforeRemovingPasses = []; + private $optimizationPasses; + private $removingPasses; + + public function __construct() + { + $this->mergePass = new MergeExtensionConfigurationPass(); + + $this->beforeOptimizationPasses = [ + 100 => [ + $resolveClassPass = new ResolveClassPass(), + new ResolveInstanceofConditionalsPass(), + new RegisterEnvVarProcessorsPass(), + ], + -1000 => [new ExtensionCompilerPass()], + ]; + + $this->optimizationPasses = [[ + new ResolveChildDefinitionsPass(), + new ServiceLocatorTagPass(), + new RegisterServiceSubscribersPass(), + new DecoratorServicePass(), + new ResolveParameterPlaceHoldersPass(false, false), + new ResolveFactoryClassPass(), + new FactoryReturnTypePass($resolveClassPass), + new CheckDefinitionValidityPass(), + new ResolveNamedArgumentsPass(), + new AutowireRequiredMethodsPass(), + new ResolveBindingsPass(), + new AutowirePass(false), + new ResolveTaggedIteratorArgumentPass(), + new ResolveServiceSubscribersPass(), + new ResolveReferencesToAliasesPass(), + new ResolveInvalidReferencesPass(), + new AnalyzeServiceReferencesPass(true), + new CheckCircularReferencesPass(), + new CheckReferenceValidityPass(), + new CheckArgumentsValidityPass(false), + ]]; + + $this->beforeRemovingPasses = [ + -100 => [ + new ResolvePrivatesPass(), + ], + ]; + + $this->removingPasses = [[ + new RemovePrivateAliasesPass(), + new ReplaceAliasByActualDefinitionPass(), + new RemoveAbstractDefinitionsPass(), + new RepeatedPass([ + new AnalyzeServiceReferencesPass(), + new InlineServiceDefinitionsPass(), + new AnalyzeServiceReferencesPass(), + new RemoveUnusedDefinitionsPass(), + ]), + new DefinitionErrorExceptionPass(), + new CheckExceptionOnInvalidReferenceBehaviorPass(), + new ResolveHotPathPass(), + ]]; + } + + /** + * Returns all passes in order to be processed. + * + * @return CompilerPassInterface[] + */ + public function getPasses() + { + return array_merge( + [$this->mergePass], + $this->getBeforeOptimizationPasses(), + $this->getOptimizationPasses(), + $this->getBeforeRemovingPasses(), + $this->getRemovingPasses(), + $this->getAfterRemovingPasses() + ); + } + + /** + * Adds a pass. + * + * @param CompilerPassInterface $pass A Compiler pass + * @param string $type The pass type + * + * @throws InvalidArgumentException when a pass type doesn't exist + */ + public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/) + { + if (\func_num_args() >= 3) { + $priority = func_get_arg(2); + } else { + if (__CLASS__ !== static::class) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), \E_USER_DEPRECATED); + } + } + + $priority = 0; + } + + $property = $type.'Passes'; + if (!isset($this->$property)) { + throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type)); + } + + $passes = &$this->$property; + + if (!isset($passes[$priority])) { + $passes[$priority] = []; + } + $passes[$priority][] = $pass; + } + + /** + * Gets all passes for the AfterRemoving pass. + * + * @return CompilerPassInterface[] + */ + public function getAfterRemovingPasses() + { + return $this->sortPasses($this->afterRemovingPasses); + } + + /** + * Gets all passes for the BeforeOptimization pass. + * + * @return CompilerPassInterface[] + */ + public function getBeforeOptimizationPasses() + { + return $this->sortPasses($this->beforeOptimizationPasses); + } + + /** + * Gets all passes for the BeforeRemoving pass. + * + * @return CompilerPassInterface[] + */ + public function getBeforeRemovingPasses() + { + return $this->sortPasses($this->beforeRemovingPasses); + } + + /** + * Gets all passes for the Optimization pass. + * + * @return CompilerPassInterface[] + */ + public function getOptimizationPasses() + { + return $this->sortPasses($this->optimizationPasses); + } + + /** + * Gets all passes for the Removing pass. + * + * @return CompilerPassInterface[] + */ + public function getRemovingPasses() + { + return $this->sortPasses($this->removingPasses); + } + + /** + * Gets the Merge pass. + * + * @return CompilerPassInterface + */ + public function getMergePass() + { + return $this->mergePass; + } + + public function setMergePass(CompilerPassInterface $pass) + { + $this->mergePass = $pass; + } + + /** + * Sets the AfterRemoving passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setAfterRemovingPasses(array $passes) + { + $this->afterRemovingPasses = [$passes]; + } + + /** + * Sets the BeforeOptimization passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setBeforeOptimizationPasses(array $passes) + { + $this->beforeOptimizationPasses = [$passes]; + } + + /** + * Sets the BeforeRemoving passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setBeforeRemovingPasses(array $passes) + { + $this->beforeRemovingPasses = [$passes]; + } + + /** + * Sets the Optimization passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setOptimizationPasses(array $passes) + { + $this->optimizationPasses = [$passes]; + } + + /** + * Sets the Removing passes. + * + * @param CompilerPassInterface[] $passes + */ + public function setRemovingPasses(array $passes) + { + $this->removingPasses = [$passes]; + } + + /** + * Sort passes by priority. + * + * @param array $passes CompilerPassInterface instances with their priority as key + * + * @return CompilerPassInterface[] + */ + private function sortPasses(array $passes) + { + if (0 === \count($passes)) { + return []; + } + + krsort($passes); + + // Flatten the array + return \call_user_func_array('array_merge', $passes); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php new file mode 100644 index 00000000..c7e12536 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Trait that allows a generic method to find and sort service by priority option in the tag. + * + * @author Iltar van der Berg + */ +trait PriorityTaggedServiceTrait +{ + /** + * Finds all services with the given tag name and order them by their priority. + * + * The order of additions must be respected for services having the same priority, + * and knowing that the \SplPriorityQueue class does not respect the FIFO method, + * we should not use that class. + * + * @see https://bugs.php.net/53710 + * @see https://bugs.php.net/60926 + * + * @param string $tagName + * + * @return Reference[] + */ + private function findAndSortTaggedServices($tagName, ContainerBuilder $container) + { + $services = []; + + foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) { + $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0; + $services[$priority][] = new Reference($serviceId); + } + + if ($services) { + krsort($services); + $services = \call_user_func_array('array_merge', $services); + } + + return $services; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php new file mode 100644 index 00000000..b4d0d055 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\EnvVarProcessor; +use Symfony\Component\DependencyInjection\EnvVarProcessorInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; + +/** + * Creates the container.env_var_processors_locator service. + * + * @author Nicolas Grekas + */ +class RegisterEnvVarProcessorsPass implements CompilerPassInterface +{ + private static $allowedTypes = ['array', 'bool', 'float', 'int', 'string']; + + public function process(ContainerBuilder $container) + { + $bag = $container->getParameterBag(); + $types = []; + $processors = []; + foreach ($container->findTaggedServiceIds('container.env_var_processor') as $id => $tags) { + if (!$r = $container->getReflectionClass($class = $container->getDefinition($id)->getClass())) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } elseif (!$r->isSubclassOf(EnvVarProcessorInterface::class)) { + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EnvVarProcessorInterface::class)); + } + foreach ($class::getProvidedTypes() as $prefix => $type) { + $processors[$prefix] = new ServiceClosureArgument(new Reference($id)); + $types[$prefix] = self::validateProvidedTypes($type, $class); + } + } + + if ($bag instanceof EnvPlaceholderParameterBag) { + foreach (EnvVarProcessor::getProvidedTypes() as $prefix => $type) { + if (!isset($types[$prefix])) { + $types[$prefix] = self::validateProvidedTypes($type, EnvVarProcessor::class); + } + } + $bag->setProvidedTypes($types); + } + + if ($processors) { + $container->register('container.env_var_processors_locator', ServiceLocator::class) + ->setPublic(true) + ->setArguments([$processors]) + ; + } + } + + private static function validateProvidedTypes($types, $class) + { + $types = explode('|', $types); + + foreach ($types as $type) { + if (!\in_array($type, self::$allowedTypes)) { + throw new InvalidArgumentException(sprintf('Invalid type "%s" returned by "%s::getProvidedTypes()", expected one of "%s".', $type, $class, implode('", "', self::$allowedTypes))); + } + } + + return $types; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php new file mode 100644 index 00000000..bf1387c0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * Compiler pass to register tagged services that require a service locator. + * + * @author Nicolas Grekas + */ +class RegisterServiceSubscribersPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) { + return parent::processValue($value, $isRoot); + } + + $serviceMap = []; + $autowire = $value->isAutowired(); + + foreach ($value->getTag('container.service_subscriber') as $attributes) { + if (!$attributes) { + $autowire = true; + continue; + } + ksort($attributes); + if ([] !== array_diff(array_keys($attributes), ['id', 'key'])) { + throw new InvalidArgumentException(sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', implode('", "', array_keys($attributes)), $this->currentId)); + } + if (!\array_key_exists('id', $attributes)) { + throw new InvalidArgumentException(sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId)); + } + if (!\array_key_exists('key', $attributes)) { + $attributes['key'] = $attributes['id']; + } + if (isset($serviceMap[$attributes['key']])) { + continue; + } + $serviceMap[$attributes['key']] = new Reference($attributes['id']); + } + $class = $value->getClass(); + + if (!$r = $this->container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId)); + } + if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) { + throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class)); + } + $class = $r->name; + + $subscriberMap = []; + $declaringClass = (new \ReflectionMethod($class, 'getSubscribedServices'))->class; + + foreach ($class::getSubscribedServices() as $key => $type) { + if (!\is_string($type) || !preg_match('/^\??[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $type)) { + throw new InvalidArgumentException(sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : \gettype($type))); + } + if ($optionalBehavior = '?' === $type[0]) { + $type = substr($type, 1); + $optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } + if (\is_int($key)) { + $key = $type; + } + if (!isset($serviceMap[$key])) { + if (!$autowire) { + throw new InvalidArgumentException(sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class)); + } + $serviceMap[$key] = new Reference($type); + } + + $subscriberMap[$key] = new TypedReference($this->container->normalizeId($serviceMap[$key]), $type, $declaringClass, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + unset($serviceMap[$key]); + } + + if ($serviceMap = array_keys($serviceMap)) { + $message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap))); + throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId)); + } + + $value->addTag('container.service_subscriber.locator', ['id' => (string) ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId)]); + + return parent::processValue($value); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php new file mode 100644 index 00000000..04b6852f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemoveAbstractDefinitionsPass.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Removes abstract Definitions. + */ +class RemoveAbstractDefinitionsPass implements CompilerPassInterface +{ + /** + * Removes abstract definitions from the ContainerBuilder. + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isAbstract()) { + $container->removeDefinition($id); + $container->log($this, sprintf('Removed service "%s"; reason: abstract.', $id)); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php new file mode 100644 index 00000000..03d9e1d8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemovePrivateAliasesPass.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Remove private aliases from the container. They were only used to establish + * dependencies between services, and these dependencies have been resolved in + * one of the previous passes. + * + * @author Johannes M. Schmitt + */ +class RemovePrivateAliasesPass implements CompilerPassInterface +{ + /** + * Removes private aliases from the ContainerBuilder. + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPublic() || $alias->isPrivate()) { + continue; + } + + $container->removeAlias($id); + $container->log($this, sprintf('Removed service "%s"; reason: private alias.', $id)); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php new file mode 100644 index 00000000..a1013f66 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RemoveUnusedDefinitionsPass.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Removes unused service definitions from the container. + * + * @author Johannes M. Schmitt + */ +class RemoveUnusedDefinitionsPass implements RepeatablePassInterface +{ + private $repeatedPass; + + /** + * {@inheritdoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + $this->repeatedPass = $repeatedPass; + } + + /** + * Processes the ContainerBuilder to remove unused definitions. + */ + public function process(ContainerBuilder $container) + { + $graph = $container->getCompiler()->getServiceReferenceGraph(); + + $hasChanged = false; + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPublic() || $definition->isPrivate()) { + continue; + } + + if ($graph->hasNode($id)) { + $edges = $graph->getNode($id)->getInEdges(); + $referencingAliases = []; + $sourceIds = []; + foreach ($edges as $edge) { + if ($edge->isWeak()) { + continue; + } + $node = $edge->getSourceNode(); + $sourceIds[] = $node->getId(); + + if ($node->isAlias()) { + $referencingAliases[] = $node->getValue(); + } + } + $isReferenced = (\count(array_unique($sourceIds)) - \count($referencingAliases)) > 0; + } else { + $referencingAliases = []; + $isReferenced = false; + } + + if (1 === \count($referencingAliases) && false === $isReferenced) { + $container->setDefinition((string) reset($referencingAliases), $definition); + $definition->setPublic(!$definition->isPrivate()); + $definition->setPrivate(reset($referencingAliases)->isPrivate()); + $container->removeDefinition($id); + $container->log($this, sprintf('Removed service "%s"; reason: replaces alias %s.', $id, reset($referencingAliases))); + } elseif (0 === \count($referencingAliases) && false === $isReferenced) { + $container->removeDefinition($id); + $container->resolveEnvPlaceholders(serialize($definition)); + $container->log($this, sprintf('Removed service "%s"; reason: unused.', $id)); + $hasChanged = true; + } + } + + if ($hasChanged) { + $this->repeatedPass->setRepeat(); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php new file mode 100644 index 00000000..2b88bfb9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RepeatablePassInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +/** + * Interface that must be implemented by passes that are run as part of an + * RepeatedPass. + * + * @author Johannes M. Schmitt + */ +interface RepeatablePassInterface extends CompilerPassInterface +{ + public function setRepeatedPass(RepeatedPass $repeatedPass); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RepeatedPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RepeatedPass.php new file mode 100644 index 00000000..3da1a0d5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/RepeatedPass.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * A pass that might be run repeatedly. + * + * @author Johannes M. Schmitt + */ +class RepeatedPass implements CompilerPassInterface +{ + /** + * @var bool + */ + private $repeat = false; + + private $passes; + + /** + * @param RepeatablePassInterface[] $passes An array of RepeatablePassInterface objects + * + * @throws InvalidArgumentException when the passes don't implement RepeatablePassInterface + */ + public function __construct(array $passes) + { + foreach ($passes as $pass) { + if (!$pass instanceof RepeatablePassInterface) { + throw new InvalidArgumentException('$passes must be an array of RepeatablePassInterface.'); + } + + $pass->setRepeatedPass($this); + } + + $this->passes = $passes; + } + + /** + * Process the repeatable passes that run more than once. + */ + public function process(ContainerBuilder $container) + { + do { + $this->repeat = false; + foreach ($this->passes as $pass) { + $pass->process($container); + } + } while ($this->repeat); + } + + /** + * Sets if the pass should repeat. + */ + public function setRepeat() + { + $this->repeat = true; + } + + /** + * Returns the passes. + * + * @return RepeatablePassInterface[] An array of RepeatablePassInterface objects + */ + public function getPasses() + { + return $this->passes; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php new file mode 100644 index 00000000..472bf941 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ReplaceAliasByActualDefinitionPass.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Replaces aliases with actual service definitions, effectively removing these + * aliases. + * + * @author Johannes M. Schmitt + */ +class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass +{ + private $replacements; + + /** + * Process the Container to replace aliases with service definitions. + * + * @throws InvalidArgumentException if the service definition does not exist + */ + public function process(ContainerBuilder $container) + { + // First collect all alias targets that need to be replaced + $seenAliasTargets = []; + $replacements = []; + foreach ($container->getAliases() as $definitionId => $target) { + $targetId = $container->normalizeId($target); + // Special case: leave this target alone + if ('service_container' === $targetId) { + continue; + } + // Check if target needs to be replaces + if (isset($replacements[$targetId])) { + $container->setAlias($definitionId, $replacements[$targetId])->setPublic($target->isPublic())->setPrivate($target->isPrivate()); + } + // No need to process the same target twice + if (isset($seenAliasTargets[$targetId])) { + continue; + } + // Process new target + $seenAliasTargets[$targetId] = true; + try { + $definition = $container->getDefinition($targetId); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $definitionId, $targetId), null, $e); + } + if ($definition->isPublic() || $definition->isPrivate()) { + continue; + } + // Remove private definition and schedule for replacement + $definition->setPublic(!$target->isPrivate()); + $definition->setPrivate($target->isPrivate()); + $container->setDefinition($definitionId, $definition); + $container->removeDefinition($targetId); + $replacements[$targetId] = $definitionId; + } + $this->replacements = $replacements; + + parent::process($container); + $this->replacements = []; + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Reference && isset($this->replacements[$referenceId = $this->container->normalizeId($value)])) { + // Perform the replacement + $newId = $this->replacements[$referenceId]; + $value = new Reference($newId, $value->getInvalidBehavior()); + $this->container->log($this, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId)); + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php new file mode 100644 index 00000000..065dbb4b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php @@ -0,0 +1,180 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * @author Guilhem Niot + */ +class ResolveBindingsPass extends AbstractRecursivePass +{ + private $usedBindings = []; + private $unusedBindings = []; + private $errorMessages = []; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $this->usedBindings = $container->getRemovedBindingIds(); + + try { + parent::process($container); + + foreach ($this->unusedBindings as list($key, $serviceId)) { + $message = sprintf('Unused binding "%s" in service "%s".', $key, $serviceId); + if ($this->errorMessages) { + $message .= sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : ''); + } + foreach ($this->errorMessages as $m) { + $message .= "\n - ".$m; + } + throw new InvalidArgumentException($message); + } + } finally { + $this->usedBindings = []; + $this->unusedBindings = []; + $this->errorMessages = []; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof TypedReference && $value->getType() === $this->container->normalizeId($value)) { + // Already checked + $bindings = $this->container->getDefinition($this->currentId)->getBindings(); + + if (isset($bindings[$value->getType()])) { + return $this->getBindingValue($bindings[$value->getType()]); + } + + return parent::processValue($value, $isRoot); + } + + if (!$value instanceof Definition || !$bindings = $value->getBindings()) { + return parent::processValue($value, $isRoot); + } + + foreach ($bindings as $key => $binding) { + list($bindingValue, $bindingId, $used) = $binding->getValues(); + if ($used) { + $this->usedBindings[$bindingId] = true; + unset($this->unusedBindings[$bindingId]); + } elseif (!isset($this->usedBindings[$bindingId])) { + $this->unusedBindings[$bindingId] = [$key, $this->currentId]; + } + + if (isset($key[0]) && '$' === $key[0]) { + continue; + } + + if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition) { + throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, an instance of "%s" or an instance of "%s", "%s" given.', $key, $this->currentId, Reference::class, Definition::class, \gettype($bindingValue))); + } + } + + if ($value->isAbstract()) { + return parent::processValue($value, $isRoot); + } + + $calls = $value->getMethodCalls(); + + try { + if ($constructor = $this->getConstructor($value, false)) { + $calls[] = [$constructor, $value->getArguments()]; + } + } catch (RuntimeException $e) { + $this->errorMessages[] = $e->getMessage(); + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + + return parent::processValue($value, $isRoot); + } + + foreach ($calls as $i => $call) { + list($method, $arguments) = $call; + + if ($method instanceof \ReflectionFunctionAbstract) { + $reflectionMethod = $method; + } else { + try { + $reflectionMethod = $this->getReflectionMethod($value, $method); + } catch (RuntimeException $e) { + if ($value->getFactory()) { + continue; + } + throw $e; + } + } + + foreach ($reflectionMethod->getParameters() as $key => $parameter) { + if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) { + continue; + } + + if (\array_key_exists('$'.$parameter->name, $bindings)) { + $arguments[$key] = $this->getBindingValue($bindings['$'.$parameter->name]); + + continue; + } + + $typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true); + + if (!isset($bindings[$typeHint])) { + continue; + } + + $arguments[$key] = $this->getBindingValue($bindings[$typeHint]); + } + + if ($arguments !== $call[1]) { + ksort($arguments); + $calls[$i][1] = $arguments; + } + } + + if ($constructor) { + list(, $arguments) = array_pop($calls); + + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + } + + if ($calls !== $value->getMethodCalls()) { + $value->setMethodCalls($calls); + } + + return parent::processValue($value, $isRoot); + } + + private function getBindingValue(BoundArgument $binding) + { + list($bindingValue, $bindingId) = $binding->getValues(); + + $this->usedBindings[$bindingId] = true; + unset($this->unusedBindings[$bindingId]); + + return $bindingValue; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php new file mode 100644 index 00000000..539395a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php @@ -0,0 +1,198 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ExceptionInterface; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; + +/** + * This replaces all ChildDefinition instances with their equivalent fully + * merged Definition instance. + * + * @author Johannes M. Schmitt + * @author Nicolas Grekas + */ +class ResolveChildDefinitionsPass extends AbstractRecursivePass +{ + private $currentPath; + + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + if ($isRoot) { + // yes, we are specifically fetching the definition from the + // container to ensure we are not operating on stale data + $value = $this->container->getDefinition($this->currentId); + } + if ($value instanceof ChildDefinition) { + $this->currentPath = []; + $value = $this->resolveDefinition($value); + if ($isRoot) { + $this->container->setDefinition($this->currentId, $value); + } + } + + return parent::processValue($value, $isRoot); + } + + /** + * Resolves the definition. + * + * @return Definition + * + * @throws RuntimeException When the definition is invalid + */ + private function resolveDefinition(ChildDefinition $definition) + { + try { + return $this->doResolveDefinition($definition); + } catch (ServiceCircularReferenceException $e) { + throw $e; + } catch (ExceptionInterface $e) { + $r = new \ReflectionProperty($e, 'message'); + $r->setAccessible(true); + $r->setValue($e, sprintf('Service "%s": %s', $this->currentId, $e->getMessage())); + + throw $e; + } + } + + private function doResolveDefinition(ChildDefinition $definition) + { + if (!$this->container->has($parent = $definition->getParent())) { + throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent)); + } + + $searchKey = array_search($parent, $this->currentPath); + $this->currentPath[] = $parent; + + if (false !== $searchKey) { + throw new ServiceCircularReferenceException($parent, \array_slice($this->currentPath, $searchKey)); + } + + $parentDef = $this->container->findDefinition($parent); + if ($parentDef instanceof ChildDefinition) { + $id = $this->currentId; + $this->currentId = $parent; + $parentDef = $this->resolveDefinition($parentDef); + $this->container->setDefinition($parent, $parentDef); + $this->currentId = $id; + } + + $this->container->log($this, sprintf('Resolving inheritance for "%s" (parent: %s).', $this->currentId, $parent)); + $def = new Definition(); + + // merge in parent definition + // purposely ignored attributes: abstract, shared, tags, autoconfigured + $def->setClass($parentDef->getClass()); + $def->setArguments($parentDef->getArguments()); + $def->setMethodCalls($parentDef->getMethodCalls()); + $def->setProperties($parentDef->getProperties()); + if ($parentDef->getAutowiringTypes(false)) { + $def->setAutowiringTypes($parentDef->getAutowiringTypes(false)); + } + if ($parentDef->isDeprecated()) { + $def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%')); + } + $def->setFactory($parentDef->getFactory()); + $def->setConfigurator($parentDef->getConfigurator()); + $def->setFile($parentDef->getFile()); + $def->setPublic($parentDef->isPublic()); + $def->setLazy($parentDef->isLazy()); + $def->setAutowired($parentDef->isAutowired()); + $def->setChanges($parentDef->getChanges()); + + $def->setBindings($definition->getBindings() + $parentDef->getBindings()); + + // overwrite with values specified in the decorator + $changes = $definition->getChanges(); + if (isset($changes['class'])) { + $def->setClass($definition->getClass()); + } + if (isset($changes['factory'])) { + $def->setFactory($definition->getFactory()); + } + if (isset($changes['configurator'])) { + $def->setConfigurator($definition->getConfigurator()); + } + if (isset($changes['file'])) { + $def->setFile($definition->getFile()); + } + if (isset($changes['public'])) { + $def->setPublic($definition->isPublic()); + } else { + $def->setPrivate($definition->isPrivate() || $parentDef->isPrivate()); + } + if (isset($changes['lazy'])) { + $def->setLazy($definition->isLazy()); + } + if (isset($changes['deprecated'])) { + $def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%')); + } + if (isset($changes['autowired'])) { + $def->setAutowired($definition->isAutowired()); + } + if (isset($changes['shared'])) { + $def->setShared($definition->isShared()); + } + if (isset($changes['decorated_service'])) { + $decoratedService = $definition->getDecoratedService(); + if (null === $decoratedService) { + $def->setDecoratedService($decoratedService); + } else { + $def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]); + } + } + + // merge arguments + foreach ($definition->getArguments() as $k => $v) { + if (is_numeric($k)) { + $def->addArgument($v); + } elseif (0 === strpos($k, 'index_')) { + $def->replaceArgument((int) substr($k, \strlen('index_')), $v); + } else { + $def->setArgument($k, $v); + } + } + + // merge properties + foreach ($definition->getProperties() as $k => $v) { + $def->setProperty($k, $v); + } + + // append method calls + if ($calls = $definition->getMethodCalls()) { + $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls)); + } + + // merge autowiring types + foreach ($definition->getAutowiringTypes(false) as $autowiringType) { + $def->addAutowiringType($autowiringType); + } + + // these attributes are always taken from the child + $def->setAbstract($definition->isAbstract()); + $def->setTags($definition->getTags()); + // autoconfigure is never taken from parent (on purpose) + // and it's not legal on an instanceof + $def->setAutoconfigured($definition->isAutoconfigured()); + + return $def; + } +} + +class_alias(ResolveChildDefinitionsPass::class, ResolveDefinitionTemplatesPass::class); diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php new file mode 100644 index 00000000..b1c1b4f8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas + */ +class ResolveClassPass implements CompilerPassInterface +{ + private $changes = []; + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isSynthetic() || null !== $definition->getClass()) { + continue; + } + if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) { + if ($definition instanceof ChildDefinition && !class_exists($id)) { + throw new InvalidArgumentException(sprintf('Service definition "%s" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id)); + } + $this->changes[strtolower($id)] = $id; + $definition->setClass($id); + } + } + } + + /** + * @internal + * + * @deprecated since 3.3, to be removed in 4.0. + */ + public function getChanges() + { + $changes = $this->changes; + $this->changes = []; + + return $changes; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php new file mode 100644 index 00000000..79fca8d5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveDefinitionTemplatesPass.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +@trigger_error('The '.__NAMESPACE__.'\ResolveDefinitionTemplatesPass class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the ResolveChildDefinitionsPass class instead.', \E_USER_DEPRECATED); + +class_exists(ResolveChildDefinitionsPass::class); + +if (false) { + /** + * This definition decorates another definition. + * + * @author Johannes M. Schmitt + * + * @deprecated The ResolveDefinitionTemplatesPass class is deprecated since version 3.4 and will be removed in 4.0. Use the ResolveChildDefinitionsPass class instead. + */ + class ResolveDefinitionTemplatesPass extends AbstractRecursivePass + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php new file mode 100644 index 00000000..9e1edd4d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Replaces env var placeholders by their current values. + */ +class ResolveEnvPlaceholdersPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (\is_string($value)) { + return $this->container->resolveEnvPlaceholders($value, true); + } + if ($value instanceof Definition) { + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->container->resolveEnvPlaceholders($value->getClass(), true)); + } + if (isset($changes['file'])) { + $value->setFile($this->container->resolveEnvPlaceholders($value->getFile(), true)); + } + } + + $value = parent::processValue($value, $isRoot); + + if ($value && \is_array($value) && !$isRoot) { + $value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value); + } + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php new file mode 100644 index 00000000..848da7f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * @author Maxime Steinhausser + */ +class ResolveFactoryClassPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Definition && \is_array($factory = $value->getFactory()) && null === $factory[0]) { + if (null === $class = $value->getClass()) { + throw new RuntimeException(sprintf('The "%s" service is defined to be created by a factory, but is missing the factory class. Did you forget to define the factory or service class?', $this->currentId)); + } + + $factory[0] = $class; + $value->setFactory($factory); + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php new file mode 100644 index 00000000..4e025113 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Propagate "container.hot_path" tags to referenced services. + * + * @author Nicolas Grekas + */ +class ResolveHotPathPass extends AbstractRecursivePass +{ + private $tagName; + private $resolvedIds = []; + + public function __construct($tagName = 'container.hot_path') + { + $this->tagName = $tagName; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + try { + parent::process($container); + $container->getDefinition('service_container')->clearTag($this->tagName); + } finally { + $this->resolvedIds = []; + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof ArgumentInterface) { + return $value; + } + if ($value instanceof Definition && $isRoot && (isset($this->resolvedIds[$this->currentId]) || !$value->hasTag($this->tagName) || $value->isDeprecated())) { + return $value->isDeprecated() ? $value->clearTag($this->tagName) : $value; + } + if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->has($id = $this->container->normalizeId($value))) { + $definition = $this->container->findDefinition($id); + if (!$definition->hasTag($this->tagName) && !$definition->isDeprecated()) { + $this->resolvedIds[$id] = true; + $definition->addTag($this->tagName); + parent::processValue($definition, false); + } + + return $value; + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php new file mode 100644 index 00000000..6268ed9e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Applies instanceof conditionals to definitions. + * + * @author Nicolas Grekas + */ +class ResolveInstanceofConditionalsPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) { + if ($definition->getArguments()) { + throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface)); + } + if ($definition->getMethodCalls()) { + throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface)); + } + } + + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition instanceof ChildDefinition) { + // don't apply "instanceof" to children: it will be applied to their parent + continue; + } + $container->setDefinition($id, $this->processDefinition($container, $id, $definition)); + } + } + + private function processDefinition(ContainerBuilder $container, $id, Definition $definition) + { + $instanceofConditionals = $definition->getInstanceofConditionals(); + $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : []; + if (!$instanceofConditionals && !$autoconfiguredInstanceof) { + return $definition; + } + + if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) { + return $definition; + } + + $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container); + + $definition->setInstanceofConditionals([]); + $parent = $shared = null; + $instanceofTags = []; + $reflectionClass = null; + + foreach ($conditionals as $interface => $instanceofDefs) { + if ($interface !== $class && !(null === $reflectionClass ? $reflectionClass = ($container->getReflectionClass($class, false) ?: false) : $reflectionClass)) { + continue; + } + + if ($interface !== $class && !is_subclass_of($class, $interface)) { + continue; + } + + foreach ($instanceofDefs as $key => $instanceofDef) { + /** @var ChildDefinition $instanceofDef */ + $instanceofDef = clone $instanceofDef; + $instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id); + $parent = 'instanceof.'.$interface.'.'.$key.'.'.$id; + $container->setDefinition($parent, $instanceofDef); + $instanceofTags[] = $instanceofDef->getTags(); + $instanceofDef->setTags([]); + + if (isset($instanceofDef->getChanges()['shared'])) { + $shared = $instanceofDef->isShared(); + } + } + } + + if ($parent) { + $bindings = $definition->getBindings(); + $abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition); + + // cast Definition to ChildDefinition + $definition->setBindings([]); + $definition = serialize($definition); + $definition = substr_replace($definition, '53', 2, 2); + $definition = substr_replace($definition, 'Child', 44, 0); + $definition = unserialize($definition); + $definition->setParent($parent); + + if (null !== $shared && !isset($definition->getChanges()['shared'])) { + $definition->setShared($shared); + } + + $i = \count($instanceofTags); + while (0 <= --$i) { + foreach ($instanceofTags[$i] as $k => $v) { + foreach ($v as $v) { + if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) { + continue; + } + $definition->addTag($k, $v); + } + } + } + + $definition->setBindings($bindings); + + // reset fields with "merge" behavior + $abstract + ->setBindings([]) + ->setArguments([]) + ->setMethodCalls([]) + ->setDecoratedService(null) + ->setTags([]) + ->setAbstract(true); + } + + return $definition; + } + + private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container) + { + // make each value an array of ChildDefinition + $conditionals = array_map(function ($childDef) { return [$childDef]; }, $autoconfiguredInstanceof); + + foreach ($instanceofConditionals as $interface => $instanceofDef) { + // make sure the interface/class exists (but don't validate automaticInstanceofConditionals) + if (!$container->getReflectionClass($interface)) { + throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface)); + } + + if (!isset($autoconfiguredInstanceof[$interface])) { + $conditionals[$interface] = []; + } + + $conditionals[$interface][] = $instanceofDef; + } + + return $conditionals; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php new file mode 100644 index 00000000..f1a1475a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveInvalidReferencesPass.php @@ -0,0 +1,111 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Emulates the invalid behavior if the reference is not found within the + * container. + * + * @author Johannes M. Schmitt + */ +class ResolveInvalidReferencesPass implements CompilerPassInterface +{ + private $container; + private $signalingException; + + /** + * Process the ContainerBuilder to resolve invalid references. + */ + public function process(ContainerBuilder $container) + { + $this->container = $container; + $this->signalingException = new RuntimeException('Invalid reference.'); + + try { + $this->processValue($container->getDefinitions(), 1); + } finally { + $this->container = $this->signalingException = null; + } + } + + /** + * Processes arguments to determine invalid references. + * + * @throws RuntimeException When an invalid reference is found + */ + private function processValue($value, $rootLevel = 0, $level = 0) + { + if ($value instanceof ServiceClosureArgument) { + $value->setValues($this->processValue($value->getValues(), 1, 1)); + } elseif ($value instanceof ArgumentInterface) { + $value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level)); + } elseif ($value instanceof Definition) { + if ($value->isSynthetic() || $value->isAbstract()) { + return $value; + } + $value->setArguments($this->processValue($value->getArguments(), 0)); + $value->setProperties($this->processValue($value->getProperties(), 1)); + $value->setMethodCalls($this->processValue($value->getMethodCalls(), 2)); + } elseif (\is_array($value)) { + $i = 0; + + foreach ($value as $k => $v) { + try { + if (false !== $i && $k !== $i++) { + $i = false; + } + if ($v !== $processedValue = $this->processValue($v, $rootLevel, 1 + $level)) { + $value[$k] = $processedValue; + } + } catch (RuntimeException $e) { + if ($rootLevel < $level || ($rootLevel && !$level)) { + unset($value[$k]); + } elseif ($rootLevel) { + throw $e; + } else { + $value[$k] = null; + } + } + } + + // Ensure numerically indexed arguments have sequential numeric keys. + if (false !== $i) { + $value = array_values($value); + } + } elseif ($value instanceof Reference) { + if ($this->container->has($value)) { + return $value; + } + $invalidBehavior = $value->getInvalidBehavior(); + + // resolve invalid behavior + if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) { + $value = null; + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) { + if (0 < $level || $rootLevel) { + throw $this->signalingException; + } + $value = null; + } + } + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php new file mode 100644 index 00000000..225014f1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Resolves named arguments to their corresponding numeric index. + * + * @author Kévin Dunglas + */ +class ResolveNamedArgumentsPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + + $calls = $value->getMethodCalls(); + $calls[] = ['__construct', $value->getArguments()]; + + foreach ($calls as $i => $call) { + list($method, $arguments) = $call; + $parameters = null; + $resolvedArguments = []; + + foreach ($arguments as $key => $argument) { + if (\is_int($key)) { + $resolvedArguments[$key] = $argument; + continue; + } + + if (null === $parameters) { + $r = $this->getReflectionMethod($value, $method); + $class = $r instanceof \ReflectionMethod ? $r->class : $this->currentId; + $method = $r->getName(); + $parameters = $r->getParameters(); + } + + if (isset($key[0]) && '$' === $key[0]) { + foreach ($parameters as $j => $p) { + if ($key === '$'.$p->name) { + $resolvedArguments[$j] = $argument; + + continue 2; + } + } + + throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument named "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key)); + } + + if (null !== $argument && !$argument instanceof Reference && !$argument instanceof Definition) { + throw new InvalidArgumentException(sprintf('Invalid service "%s": the value of argument "%s" of method "%s()" must be null, an instance of "%s" or an instance of "%s", "%s" given.', $this->currentId, $key, $class !== $this->currentId ? $class.'::'.$method : $method, Reference::class, Definition::class, \gettype($argument))); + } + + $typeFound = false; + foreach ($parameters as $j => $p) { + if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, true) === $key) { + $resolvedArguments[$j] = $argument; + $typeFound = true; + } + } + + if (!$typeFound) { + throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument type-hinted as "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key)); + } + } + + if ($resolvedArguments !== $call[1]) { + ksort($resolvedArguments); + $calls[$i][1] = $resolvedArguments; + } + } + + list(, $arguments) = array_pop($calls); + + if ($arguments !== $value->getArguments()) { + $value->setArguments($arguments); + } + if ($calls !== $value->getMethodCalls()) { + $value->setMethodCalls($calls); + } + + return parent::processValue($value, $isRoot); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php new file mode 100644 index 00000000..32eb6a3a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveParameterPlaceHoldersPass.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * Resolves all parameter placeholders "%somevalue%" to their real values. + * + * @author Johannes M. Schmitt + */ +class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass +{ + private $bag; + private $resolveArrays; + private $throwOnResolveException; + + public function __construct($resolveArrays = true, $throwOnResolveException = true) + { + $this->resolveArrays = $resolveArrays; + $this->throwOnResolveException = $throwOnResolveException; + } + + /** + * {@inheritdoc} + * + * @throws ParameterNotFoundException + */ + public function process(ContainerBuilder $container) + { + $this->bag = $container->getParameterBag(); + + try { + parent::process($container); + + $aliases = []; + foreach ($container->getAliases() as $name => $target) { + $this->currentId = $name; + $aliases[$this->bag->resolveValue($name)] = $target; + } + $container->setAliases($aliases); + } catch (ParameterNotFoundException $e) { + $e->setSourceId($this->currentId); + + throw $e; + } + + $this->bag->resolve(); + $this->bag = null; + } + + protected function processValue($value, $isRoot = false) + { + if (\is_string($value)) { + try { + $v = $this->bag->resolveValue($value); + } catch (ParameterNotFoundException $e) { + if ($this->throwOnResolveException) { + throw $e; + } + + $v = null; + $this->container->getDefinition($this->currentId)->addError($e->getMessage()); + } + + return $this->resolveArrays || !$v || !\is_array($v) ? $v : $value; + } + if ($value instanceof Definition) { + $value->setBindings($this->processValue($value->getBindings())); + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->bag->resolveValue($value->getClass())); + } + if (isset($changes['file'])) { + $value->setFile($this->bag->resolveValue($value->getFile())); + } + } + + $value = parent::processValue($value, $isRoot); + + if ($value && \is_array($value)) { + $value = array_combine($this->bag->resolveValue(array_keys($value)), $value); + } + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php new file mode 100644 index 00000000..1bd99345 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Nicolas Grekas + */ +class ResolvePrivatesPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition->isPrivate()) { + $definition->setPublic(false); + $definition->setPrivate(true); + } + } + + foreach ($container->getAliases() as $id => $alias) { + if ($alias->isPrivate()) { + $alias->setPublic(false); + $alias->setPrivate(true); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php new file mode 100644 index 00000000..2559dcf1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveReferencesToAliasesPass.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Replaces all references to aliases with references to the actual service. + * + * @author Johannes M. Schmitt + */ +class ResolveReferencesToAliasesPass extends AbstractRecursivePass +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + parent::process($container); + + foreach ($container->getAliases() as $id => $alias) { + $aliasId = $container->normalizeId($alias); + if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) { + $container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate()); + } + } + } + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Reference) { + $defId = $this->getDefinitionId($id = $this->container->normalizeId($value), $this->container); + + if ($defId !== $id) { + return new Reference($defId, $value->getInvalidBehavior()); + } + } + + return parent::processValue($value); + } + + /** + * Resolves an alias into a definition id. + * + * @param string $id The definition or alias id to resolve + * + * @return string The definition id with aliases resolved + */ + private function getDefinitionId($id, ContainerBuilder $container) + { + $seen = []; + while ($container->hasAlias($id)) { + if (isset($seen[$id])) { + throw new ServiceCircularReferenceException($id, array_merge(array_keys($seen), [$id])); + } + $seen[$id] = true; + $id = $container->normalizeId($container->getAlias($id)); + } + + return $id; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php new file mode 100644 index 00000000..ccc80a44 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Psr\Container\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Compiler pass to inject their service locator to service subscribers. + * + * @author Nicolas Grekas + */ +class ResolveServiceSubscribersPass extends AbstractRecursivePass +{ + private $serviceLocator; + + protected function processValue($value, $isRoot = false) + { + if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === $this->container->normalizeId($value)) { + return new Reference($this->serviceLocator); + } + + if (!$value instanceof Definition) { + return parent::processValue($value, $isRoot); + } + + $serviceLocator = $this->serviceLocator; + $this->serviceLocator = null; + + if ($value->hasTag('container.service_subscriber.locator')) { + $this->serviceLocator = $value->getTag('container.service_subscriber.locator')[0]['id']; + $value->clearTag('container.service_subscriber.locator'); + } + + try { + return parent::processValue($value); + } finally { + $this->serviceLocator = $serviceLocator; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php new file mode 100644 index 00000000..009cee9b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; + +/** + * Resolves all TaggedIteratorArgument arguments. + * + * @author Roland Franssen + */ +class ResolveTaggedIteratorArgumentPass extends AbstractRecursivePass +{ + use PriorityTaggedServiceTrait; + + /** + * {@inheritdoc} + */ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof TaggedIteratorArgument) { + return parent::processValue($value, $isRoot); + } + + $value->setValues($this->findAndSortTaggedServices($value->getTag(), $this->container)); + + return $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php new file mode 100644 index 00000000..a7427c5a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; + +/** + * Applies the "container.service_locator" tag by wrapping references into ServiceClosureArgument instances. + * + * @author Nicolas Grekas + */ +final class ServiceLocatorTagPass extends AbstractRecursivePass +{ + protected function processValue($value, $isRoot = false) + { + if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) { + return parent::processValue($value, $isRoot); + } + + if (!$value->getClass()) { + $value->setClass(ServiceLocator::class); + } + + $arguments = $value->getArguments(); + if (!isset($arguments[0]) || !\is_array($arguments[0])) { + throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId)); + } + + $i = 0; + + foreach ($arguments[0] as $k => $v) { + if ($v instanceof ServiceClosureArgument) { + continue; + } + if (!$v instanceof Reference) { + throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, \is_object($v) ? \get_class($v) : \gettype($v), $k)); + } + + if ($i === $k) { + unset($arguments[0][$k]); + + $k = (string) $v; + ++$i; + } elseif (\is_int($k)) { + $i = null; + } + $arguments[0][$k] = new ServiceClosureArgument($v); + } + ksort($arguments[0]); + + $value->setArguments($arguments); + + $id = 'service_locator.'.ContainerBuilder::hash($value); + + if ($isRoot) { + if ($id !== $this->currentId) { + $this->container->setAlias($id, new Alias($this->currentId, false)); + } + + return $value; + } + + $this->container->setDefinition($id, $value->setPublic(false)); + + return new Reference($id); + } + + /** + * @param Reference[] $refMap + * @param string|null $callerId + * + * @return Reference + */ + public static function register(ContainerBuilder $container, array $refMap, $callerId = null) + { + foreach ($refMap as $id => $ref) { + if (!$ref instanceof Reference) { + throw new InvalidArgumentException(sprintf('Invalid service locator definition: only services can be referenced, "%s" found for key "%s". Inject parameter values using constructors instead.', \is_object($ref) ? \get_class($ref) : \gettype($ref), $id)); + } + $refMap[$id] = new ServiceClosureArgument($ref); + } + ksort($refMap); + + $locator = (new Definition(ServiceLocator::class)) + ->addArgument($refMap) + ->setPublic(false) + ->addTag('container.service_locator'); + + if (null !== $callerId && $container->hasDefinition($callerId)) { + $locator->setBindings($container->getDefinition($callerId)->getBindings()); + } + + if (!$container->hasDefinition($id = 'service_locator.'.ContainerBuilder::hash($locator))) { + $container->setDefinition($id, $locator); + } + + if (null !== $callerId) { + $locatorId = $id; + // Locators are shared when they hold the exact same list of factories; + // to have them specialized per consumer service, we use a cloning factory + // to derivate customized instances from the prototype one. + $container->register($id .= '.'.$callerId, ServiceLocator::class) + ->setPublic(false) + ->setFactory([new Reference($locatorId), 'withContext']) + ->addArgument($callerId) + ->addArgument(new Reference('service_container')); + } + + return new Reference($id); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php new file mode 100644 index 00000000..e419e297 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraph.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * This is a directed graph of your services. + * + * This information can be used by your compiler passes instead of collecting + * it themselves which improves performance quite a lot. + * + * @author Johannes M. Schmitt + * + * @final since version 3.4 + */ +class ServiceReferenceGraph +{ + /** + * @var ServiceReferenceGraphNode[] + */ + private $nodes = []; + + /** + * Checks if the graph has a specific node. + * + * @param string $id Id to check + * + * @return bool + */ + public function hasNode($id) + { + return isset($this->nodes[$id]); + } + + /** + * Gets a node by identifier. + * + * @param string $id The id to retrieve + * + * @return ServiceReferenceGraphNode + * + * @throws InvalidArgumentException if no node matches the supplied identifier + */ + public function getNode($id) + { + if (!isset($this->nodes[$id])) { + throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id)); + } + + return $this->nodes[$id]; + } + + /** + * Returns all nodes. + * + * @return ServiceReferenceGraphNode[] + */ + public function getNodes() + { + return $this->nodes; + } + + /** + * Clears all nodes. + */ + public function clear() + { + foreach ($this->nodes as $node) { + $node->clear(); + } + $this->nodes = []; + } + + /** + * Connects 2 nodes together in the Graph. + * + * @param string $sourceId + * @param mixed $sourceValue + * @param string $destId + * @param mixed $destValue + * @param string $reference + */ + public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null/*, bool $lazy = false, bool $weak = false, bool $byConstructor = false*/) + { + $lazy = \func_num_args() >= 6 ? func_get_arg(5) : false; + $weak = \func_num_args() >= 7 ? func_get_arg(6) : false; + $byConstructor = \func_num_args() >= 8 ? func_get_arg(7) : false; + + if (null === $sourceId || null === $destId) { + return; + } + + $sourceNode = $this->createNode($sourceId, $sourceValue); + $destNode = $this->createNode($destId, $destValue); + $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor); + + $sourceNode->addOutEdge($edge); + $destNode->addInEdge($edge); + } + + /** + * Creates a graph node. + * + * @param string $id + * @param mixed $value + * + * @return ServiceReferenceGraphNode + */ + private function createNode($id, $value) + { + if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) { + return $this->nodes[$id]; + } + + return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php new file mode 100644 index 00000000..911e7a5f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphEdge.php @@ -0,0 +1,105 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +/** + * Represents an edge in your service graph. + * + * Value is typically a reference. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraphEdge +{ + private $sourceNode; + private $destNode; + private $value; + private $lazy; + private $weak; + private $byConstructor; + + /** + * @param mixed $value + * @param bool $lazy + * @param bool $weak + * @param bool $byConstructor + */ + public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, $lazy = false, $weak = false, $byConstructor = false) + { + $this->sourceNode = $sourceNode; + $this->destNode = $destNode; + $this->value = $value; + $this->lazy = $lazy; + $this->weak = $weak; + $this->byConstructor = $byConstructor; + } + + /** + * Returns the value of the edge. + * + * @return string + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns the source node. + * + * @return ServiceReferenceGraphNode + */ + public function getSourceNode() + { + return $this->sourceNode; + } + + /** + * Returns the destination node. + * + * @return ServiceReferenceGraphNode + */ + public function getDestNode() + { + return $this->destNode; + } + + /** + * Returns true if the edge is lazy, meaning it's a dependency not requiring direct instantiation. + * + * @return bool + */ + public function isLazy() + { + return $this->lazy; + } + + /** + * Returns true if the edge is weak, meaning it shouldn't prevent removing the target service. + * + * @return bool + */ + public function isWeak() + { + return $this->weak; + } + + /** + * Returns true if the edge links with a constructor argument. + * + * @return bool + */ + public function isReferencedByConstructor() + { + return $this->byConstructor; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php new file mode 100644 index 00000000..50140b5f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Compiler/ServiceReferenceGraphNode.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Compiler; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Definition; + +/** + * Represents a node in your service graph. + * + * Value is typically a definition, or an alias. + * + * @author Johannes M. Schmitt + */ +class ServiceReferenceGraphNode +{ + private $id; + private $inEdges = []; + private $outEdges = []; + private $value; + + /** + * @param string $id The node identifier + * @param mixed $value The node value + */ + public function __construct($id, $value) + { + $this->id = $id; + $this->value = $value; + } + + public function addInEdge(ServiceReferenceGraphEdge $edge) + { + $this->inEdges[] = $edge; + } + + public function addOutEdge(ServiceReferenceGraphEdge $edge) + { + $this->outEdges[] = $edge; + } + + /** + * Checks if the value of this node is an Alias. + * + * @return bool True if the value is an Alias instance + */ + public function isAlias() + { + return $this->value instanceof Alias; + } + + /** + * Checks if the value of this node is a Definition. + * + * @return bool True if the value is a Definition instance + */ + public function isDefinition() + { + return $this->value instanceof Definition; + } + + /** + * Returns the identifier. + * + * @return string + */ + public function getId() + { + return $this->id; + } + + /** + * Returns the in edges. + * + * @return ServiceReferenceGraphEdge[] + */ + public function getInEdges() + { + return $this->inEdges; + } + + /** + * Returns the out edges. + * + * @return ServiceReferenceGraphEdge[] + */ + public function getOutEdges() + { + return $this->outEdges; + } + + /** + * Returns the value of this Node. + * + * @return mixed The value + */ + public function getValue() + { + return $this->value; + } + + /** + * Clears all edges. + */ + public function clear() + { + $this->inEdges = $this->outEdges = []; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/AutowireServiceResource.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/AutowireServiceResource.php new file mode 100644 index 00000000..68c1e3f6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/AutowireServiceResource.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Config; + +@trigger_error('The '.__NAMESPACE__.'\AutowireServiceResource class is deprecated since Symfony 3.3 and will be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.', \E_USER_DEPRECATED); + +use Symfony\Component\Config\Resource\SelfCheckingResourceInterface; +use Symfony\Component\DependencyInjection\Compiler\AutowirePass; + +/** + * @deprecated since version 3.3, to be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead. + */ +class AutowireServiceResource implements SelfCheckingResourceInterface, \Serializable +{ + private $class; + private $filePath; + private $autowiringMetadata = []; + + public function __construct($class, $path, array $autowiringMetadata) + { + $this->class = $class; + $this->filePath = $path; + $this->autowiringMetadata = $autowiringMetadata; + } + + public function isFresh($timestamp) + { + if (!file_exists($this->filePath)) { + return false; + } + + // has the file *not* been modified? Definitely fresh + if (@filemtime($this->filePath) <= $timestamp) { + return true; + } + + try { + $reflectionClass = new \ReflectionClass($this->class); + } catch (\ReflectionException $e) { + // the class does not exist anymore! + return false; + } + + return (array) $this === (array) AutowirePass::createResourceForClass($reflectionClass); + } + + public function __toString() + { + return 'service.autowire.'.$this->class; + } + + /** + * @internal + */ + public function serialize() + { + return serialize([$this->class, $this->filePath, $this->autowiringMetadata]); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + if (\PHP_VERSION_ID >= 70000) { + list($this->class, $this->filePath, $this->autowiringMetadata) = unserialize($serialized, ['allowed_classes' => false]); + } else { + list($this->class, $this->filePath, $this->autowiringMetadata) = unserialize($serialized); + } + } + + /** + * @deprecated Implemented for compatibility with Symfony 2.8 + */ + public function getResource() + { + return $this->filePath; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php new file mode 100644 index 00000000..7560c335 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/ContainerParametersResource.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; + +/** + * Tracks container parameters. + * + * @author Maxime Steinhausser + */ +class ContainerParametersResource implements ResourceInterface, \Serializable +{ + private $parameters; + + /** + * @param array $parameters The container parameters to track + */ + public function __construct(array $parameters) + { + $this->parameters = $parameters; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return 'container_parameters_'.md5(serialize($this->parameters)); + } + + /** + * @internal + */ + public function serialize() + { + return serialize($this->parameters); + } + + /** + * @internal + */ + public function unserialize($serialized) + { + $this->parameters = unserialize($serialized); + } + + /** + * @return array Tracked parameters + */ + public function getParameters() + { + return $this->parameters; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php new file mode 100644 index 00000000..6ed77e3f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Config; + +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Config\ResourceCheckerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * @author Maxime Steinhausser + */ +class ContainerParametersResourceChecker implements ResourceCheckerInterface +{ + /** @var ContainerInterface */ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function supports(ResourceInterface $metadata) + { + return $metadata instanceof ContainerParametersResource; + } + + /** + * {@inheritdoc} + */ + public function isFresh(ResourceInterface $resource, $timestamp) + { + foreach ($resource->getParameters() as $key => $value) { + if (!$this->container->hasParameter($key) || $this->container->getParameter($key) !== $value) { + return false; + } + } + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Container.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Container.php new file mode 100644 index 00000000..e9d53023 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Container.php @@ -0,0 +1,526 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; + +/** + * Container is a dependency injection container. + * + * It gives access to object instances (services). + * Services and parameters are simple key/pair stores. + * The container can have four possible behaviors when a service + * does not exist (or is not initialized for the last case): + * + * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default) + * * NULL_ON_INVALID_REFERENCE: Returns null + * * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference + * (for instance, ignore a setter if the service does not exist) + * * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class Container implements ResettableContainerInterface +{ + protected $parameterBag; + protected $services = []; + protected $fileMap = []; + protected $methodMap = []; + protected $aliases = []; + protected $loading = []; + protected $resolving = []; + protected $syntheticIds = []; + + /** + * @internal + */ + protected $privates = []; + + /** + * @internal + */ + protected $normalizedIds = []; + + private $underscoreMap = ['_' => '', '.' => '_', '\\' => '_']; + private $envCache = []; + private $compiled = false; + private $getEnv; + + public function __construct(ParameterBagInterface $parameterBag = null) + { + $this->parameterBag = $parameterBag ?: new EnvPlaceholderParameterBag(); + } + + /** + * Compiles the container. + * + * This method does two things: + * + * * Parameter values are resolved; + * * The parameter bag is frozen. + */ + public function compile() + { + $this->parameterBag->resolve(); + + $this->parameterBag = new FrozenParameterBag($this->parameterBag->all()); + + $this->compiled = true; + } + + /** + * Returns true if the container is compiled. + * + * @return bool + */ + public function isCompiled() + { + return $this->compiled; + } + + /** + * Returns true if the container parameter bag are frozen. + * + * @deprecated since version 3.3, to be removed in 4.0. + * + * @return bool true if the container parameter bag are frozen, false otherwise + */ + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), \E_USER_DEPRECATED); + + return $this->parameterBag instanceof FrozenParameterBag; + } + + /** + * Gets the service container parameter bag. + * + * @return ParameterBagInterface A ParameterBagInterface instance + */ + public function getParameterBag() + { + return $this->parameterBag; + } + + /** + * Gets a parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws InvalidArgumentException if the parameter is not defined + */ + public function getParameter($name) + { + return $this->parameterBag->get($name); + } + + /** + * Checks if a parameter exists. + * + * @param string $name The parameter name + * + * @return bool The presence of parameter in container + */ + public function hasParameter($name) + { + return $this->parameterBag->has($name); + } + + /** + * Sets a parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + */ + public function setParameter($name, $value) + { + $this->parameterBag->set($name, $value); + } + + /** + * Sets a service. + * + * Setting a synthetic service to null resets it: has() returns false and get() + * behaves in the same way as if the service was never created. + * + * @param string $id The service identifier + * @param object|null $service The service instance + */ + public function set($id, $service) + { + // Runs the internal initializer; used by the dumped container to include always-needed files + if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) { + $initialize = $this->privates['service_container']; + unset($this->privates['service_container']); + $initialize(); + } + + $id = $this->normalizeId($id); + + if ('service_container' === $id) { + throw new InvalidArgumentException('You cannot set service "service_container".'); + } + + if (isset($this->privates[$id]) || !(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) { + if (!isset($this->privates[$id]) && !isset($this->getRemovedIds()[$id])) { + // no-op + } elseif (null === $service) { + @trigger_error(sprintf('The "%s" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED); + unset($this->privates[$id]); + } else { + @trigger_error(sprintf('The "%s" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED); + } + } elseif (isset($this->services[$id])) { + if (null === $service) { + @trigger_error(sprintf('The "%s" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), \E_USER_DEPRECATED); + } else { + @trigger_error(sprintf('The "%s" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), \E_USER_DEPRECATED); + } + } + + if (isset($this->aliases[$id])) { + unset($this->aliases[$id]); + } + + if (null === $service) { + unset($this->services[$id]); + + return; + } + + $this->services[$id] = $service; + } + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return bool true if the service is defined, false otherwise + */ + public function has($id) + { + for ($i = 2;;) { + if (isset($this->privates[$id])) { + @trigger_error(sprintf('The "%s" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.', $id), \E_USER_DEPRECATED); + } + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + if (isset($this->services[$id])) { + return true; + } + if ('service_container' === $id) { + return true; + } + + if (isset($this->fileMap[$id]) || isset($this->methodMap[$id])) { + return true; + } + + if (--$i && $id !== $normalizedId = $this->normalizeId($id)) { + $id = $normalizedId; + continue; + } + + // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, + // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) + if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service')) { + @trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED); + + return true; + } + + return false; + } + } + + /** + * Gets a service. + * + * If a service is defined both through a set() method and + * with a get{$id}Service() method, the former has always precedence. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object|null The associated service + * + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * @throws \Exception if an exception has been thrown when the service has been resolved + * + * @see Reference + */ + public function get($id, $invalidBehavior = /* self::EXCEPTION_ON_INVALID_REFERENCE */ 1) + { + // Attempt to retrieve the service by checking first aliases then + // available services. Service IDs are case insensitive, however since + // this method can be called thousands of times during a request, avoid + // calling $this->normalizeId($id) unless necessary. + for ($i = 2;;) { + if (isset($this->privates[$id])) { + @trigger_error(sprintf('The "%s" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.', $id), \E_USER_DEPRECATED); + } + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + + // Re-use shared service instance if it exists. + if (isset($this->services[$id])) { + return $this->services[$id]; + } + if ('service_container' === $id) { + return $this; + } + + if (isset($this->loading[$id])) { + throw new ServiceCircularReferenceException($id, array_merge(array_keys($this->loading), [$id])); + } + + $this->loading[$id] = true; + + try { + if (isset($this->fileMap[$id])) { + return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]); + } elseif (isset($this->methodMap[$id])) { + return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}(); + } elseif (--$i && $id !== $normalizedId = $this->normalizeId($id)) { + unset($this->loading[$id]); + $id = $normalizedId; + continue; + } elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) { + // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, + // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) + @trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED); + + return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$method}(); + } + + break; + } catch (\Exception $e) { + unset($this->services[$id]); + + throw $e; + } finally { + unset($this->loading[$id]); + } + } + + if (/* self::EXCEPTION_ON_INVALID_REFERENCE */ 1 === $invalidBehavior) { + if (!$id) { + throw new ServiceNotFoundException($id); + } + if (isset($this->syntheticIds[$id])) { + throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.', $id)); + } + if (isset($this->getRemovedIds()[$id])) { + throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.', $id)); + } + + $alternatives = []; + foreach ($this->getServiceIds() as $knownId) { + $lev = levenshtein($id, $knownId); + if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) { + $alternatives[] = $knownId; + } + } + + throw new ServiceNotFoundException($id, null, null, $alternatives); + } + } + + /** + * Returns true if the given service has actually been initialized. + * + * @param string $id The service identifier + * + * @return bool true if service has already been initialized, false otherwise + */ + public function initialized($id) + { + $id = $this->normalizeId($id); + + if (isset($this->privates[$id])) { + @trigger_error(sprintf('Checking for the initialization of the "%s" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0.', $id), \E_USER_DEPRECATED); + } + + if (isset($this->aliases[$id])) { + $id = $this->aliases[$id]; + } + + if ('service_container' === $id) { + return false; + } + + return isset($this->services[$id]); + } + + /** + * {@inheritdoc} + */ + public function reset() + { + $this->services = []; + } + + /** + * Gets all service ids. + * + * @return string[] An array of all defined service ids + */ + public function getServiceIds() + { + $ids = []; + + if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class) { + // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder, + // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper) + @trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', \E_USER_DEPRECATED); + + foreach (get_class_methods($this) as $method) { + if (preg_match('/^get(.+)Service$/', $method, $match)) { + $ids[] = self::underscore($match[1]); + } + } + } + $ids[] = 'service_container'; + + return array_map('strval', array_unique(array_merge($ids, array_keys($this->methodMap), array_keys($this->fileMap), array_keys($this->aliases), array_keys($this->services)))); + } + + /** + * Gets service ids that existed at compile time. + * + * @return array + */ + public function getRemovedIds() + { + return []; + } + + /** + * Camelizes a string. + * + * @param string $id A string to camelize + * + * @return string The camelized string + */ + public static function camelize($id) + { + return strtr(ucwords(strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']); + } + + /** + * A string to underscore. + * + * @param string $id The string to underscore + * + * @return string The underscored string + */ + public static function underscore($id) + { + return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], str_replace('_', '.', $id))); + } + + /** + * Creates a service by requiring its factory file. + */ + protected function load($file) + { + return require $file; + } + + /** + * Fetches a variable from the environment. + * + * @param string $name The name of the environment variable + * + * @return mixed The value to use for the provided environment variable name + * + * @throws EnvNotFoundException When the environment variable is not found and has no default value + */ + protected function getEnv($name) + { + if (isset($this->resolving[$envName = "env($name)"])) { + throw new ParameterCircularReferenceException(array_keys($this->resolving)); + } + if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) { + return $this->envCache[$name]; + } + if (!$this->has($id = 'container.env_var_processors_locator')) { + $this->set($id, new ServiceLocator([])); + } + if (!$this->getEnv) { + $this->getEnv = new \ReflectionMethod($this, __FUNCTION__); + $this->getEnv->setAccessible(true); + $this->getEnv = $this->getEnv->getClosure($this); + } + $processors = $this->get($id); + + if (false !== $i = strpos($name, ':')) { + $prefix = substr($name, 0, $i); + $localName = substr($name, 1 + $i); + } else { + $prefix = 'string'; + $localName = $name; + } + $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this); + + $this->resolving[$envName] = true; + try { + return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv); + } finally { + unset($this->resolving[$envName]); + } + } + + /** + * Returns the case sensitive id used at registration time. + * + * @param string $id + * + * @return string + * + * @internal + */ + public function normalizeId($id) + { + if (!\is_string($id)) { + $id = (string) $id; + } + if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) { + $normalizedId = $this->normalizedIds[$normalizedId]; + if ($id !== $normalizedId) { + @trigger_error(sprintf('Service identifiers will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.3.', $id, $normalizedId), \E_USER_DEPRECATED); + } + } else { + $normalizedId = $this->normalizedIds[$normalizedId] = $id; + } + + return $normalizedId; + } + + private function __clone() + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerAwareInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerAwareInterface.php new file mode 100644 index 00000000..e7b9d575 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerAwareInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * ContainerAwareInterface should be implemented by classes that depends on a Container. + * + * @author Fabien Potencier + */ +interface ContainerAwareInterface +{ + /** + * Sets the container. + */ + public function setContainer(ContainerInterface $container = null); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerAwareTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerAwareTrait.php new file mode 100644 index 00000000..ee1ea2cb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerAwareTrait.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * ContainerAware trait. + * + * @author Fabien Potencier + */ +trait ContainerAwareTrait +{ + /** + * @var ContainerInterface + */ + protected $container; + + public function setContainer(ContainerInterface $container = null) + { + $this->container = $container; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerBuilder.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerBuilder.php new file mode 100644 index 00000000..97617cb0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerBuilder.php @@ -0,0 +1,1694 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\Config\Resource\ClassExistenceResource; +use Symfony\Component\Config\Resource\ComposerResource; +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Config\Resource\FileExistenceResource; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\Config\Resource\ReflectionClassResource; +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\Compiler\ResolveEnvPlaceholdersPass; +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface; +use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +/** + * ContainerBuilder is a DI container that provides an API to easily describe services. + * + * @author Fabien Potencier + */ +class ContainerBuilder extends Container implements TaggedContainerInterface +{ + /** + * @var ExtensionInterface[] + */ + private $extensions = []; + + /** + * @var ExtensionInterface[] + */ + private $extensionsByNs = []; + + /** + * @var Definition[] + */ + private $definitions = []; + + /** + * @var Alias[] + */ + private $aliasDefinitions = []; + + /** + * @var ResourceInterface[] + */ + private $resources = []; + + private $extensionConfigs = []; + + /** + * @var Compiler + */ + private $compiler; + + private $trackResources; + + /** + * @var InstantiatorInterface|null + */ + private $proxyInstantiator; + + /** + * @var ExpressionLanguage|null + */ + private $expressionLanguage; + + /** + * @var ExpressionFunctionProviderInterface[] + */ + private $expressionLanguageProviders = []; + + /** + * @var string[] with tag names used by findTaggedServiceIds + */ + private $usedTags = []; + + /** + * @var string[][] a map of env var names to their placeholders + */ + private $envPlaceholders = []; + + /** + * @var int[] a map of env vars to their resolution counter + */ + private $envCounters = []; + + /** + * @var string[] the list of vendor directories + */ + private $vendors; + + private $autoconfiguredInstanceof = []; + + private $removedIds = []; + + private $removedBindingIds = []; + + private static $internalTypes = [ + 'int' => true, + 'float' => true, + 'string' => true, + 'bool' => true, + 'resource' => true, + 'object' => true, + 'array' => true, + 'null' => true, + 'callable' => true, + 'iterable' => true, + 'mixed' => true, + ]; + + public function __construct(ParameterBagInterface $parameterBag = null) + { + parent::__construct($parameterBag); + + $this->trackResources = interface_exists('Symfony\Component\Config\Resource\ResourceInterface'); + $this->setDefinition('service_container', (new Definition(ContainerInterface::class))->setSynthetic(true)->setPublic(true)); + $this->setAlias(PsrContainerInterface::class, new Alias('service_container', false)); + $this->setAlias(ContainerInterface::class, new Alias('service_container', false)); + } + + /** + * @var \ReflectionClass[] a list of class reflectors + */ + private $classReflectors; + + /** + * Sets the track resources flag. + * + * If you are not using the loaders and therefore don't want + * to depend on the Config component, set this flag to false. + * + * @param bool $track True if you want to track resources, false otherwise + */ + public function setResourceTracking($track) + { + $this->trackResources = (bool) $track; + } + + /** + * Checks if resources are tracked. + * + * @return bool true If resources are tracked, false otherwise + */ + public function isTrackingResources() + { + return $this->trackResources; + } + + /** + * Sets the instantiator to be used when fetching proxies. + */ + public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator) + { + $this->proxyInstantiator = $proxyInstantiator; + } + + public function registerExtension(ExtensionInterface $extension) + { + $this->extensions[$extension->getAlias()] = $extension; + + if (false !== $extension->getNamespace()) { + $this->extensionsByNs[$extension->getNamespace()] = $extension; + } + } + + /** + * Returns an extension by alias or namespace. + * + * @param string $name An alias or a namespace + * + * @return ExtensionInterface An extension instance + * + * @throws LogicException if the extension is not registered + */ + public function getExtension($name) + { + if (isset($this->extensions[$name])) { + return $this->extensions[$name]; + } + + if (isset($this->extensionsByNs[$name])) { + return $this->extensionsByNs[$name]; + } + + throw new LogicException(sprintf('Container extension "%s" is not registered.', $name)); + } + + /** + * Returns all registered extensions. + * + * @return ExtensionInterface[] An array of ExtensionInterface + */ + public function getExtensions() + { + return $this->extensions; + } + + /** + * Checks if we have an extension. + * + * @param string $name The name of the extension + * + * @return bool If the extension exists + */ + public function hasExtension($name) + { + return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]); + } + + /** + * Returns an array of resources loaded to build this configuration. + * + * @return ResourceInterface[] An array of resources + */ + public function getResources() + { + return array_values($this->resources); + } + + /** + * @return $this + */ + public function addResource(ResourceInterface $resource) + { + if (!$this->trackResources) { + return $this; + } + + if ($resource instanceof GlobResource && $this->inVendors($resource->getPrefix())) { + return $this; + } + + $this->resources[(string) $resource] = $resource; + + return $this; + } + + /** + * Sets the resources for this configuration. + * + * @param ResourceInterface[] $resources An array of resources + * + * @return $this + */ + public function setResources(array $resources) + { + if (!$this->trackResources) { + return $this; + } + + $this->resources = $resources; + + return $this; + } + + /** + * Adds the object class hierarchy as resources. + * + * @param object|string $object An object instance or class name + * + * @return $this + */ + public function addObjectResource($object) + { + if ($this->trackResources) { + if (\is_object($object)) { + $object = \get_class($object); + } + if (!isset($this->classReflectors[$object])) { + $this->classReflectors[$object] = new \ReflectionClass($object); + } + $class = $this->classReflectors[$object]; + + foreach ($class->getInterfaceNames() as $name) { + if (null === $interface = &$this->classReflectors[$name]) { + $interface = new \ReflectionClass($name); + } + $file = $interface->getFileName(); + if (false !== $file && file_exists($file)) { + $this->fileExists($file); + } + } + do { + $file = $class->getFileName(); + if (false !== $file && file_exists($file)) { + $this->fileExists($file); + } + foreach ($class->getTraitNames() as $name) { + $this->addObjectResource($name); + } + } while ($class = $class->getParentClass()); + } + + return $this; + } + + /** + * Adds the given class hierarchy as resources. + * + * @return $this + * + * @deprecated since version 3.3, to be removed in 4.0. Use addObjectResource() or getReflectionClass() instead. + */ + public function addClassResource(\ReflectionClass $class) + { + @trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the addObjectResource() or the getReflectionClass() method instead.', \E_USER_DEPRECATED); + + return $this->addObjectResource($class->name); + } + + /** + * Retrieves the requested reflection class and registers it for resource tracking. + * + * @param string $class + * @param bool $throw + * + * @return \ReflectionClass|null + * + * @throws \ReflectionException when a parent class/interface/trait is not found and $throw is true + * + * @final + */ + public function getReflectionClass($class, $throw = true) + { + if (!$class = $this->getParameterBag()->resolveValue($class)) { + return null; + } + + if (isset(self::$internalTypes[$class])) { + return null; + } + + $resource = $classReflector = null; + + try { + if (isset($this->classReflectors[$class])) { + $classReflector = $this->classReflectors[$class]; + } elseif (class_exists(ClassExistenceResource::class)) { + $resource = new ClassExistenceResource($class, false); + $classReflector = $resource->isFresh(0) ? false : new \ReflectionClass($class); + } else { + $classReflector = class_exists($class) ? new \ReflectionClass($class) : false; + } + } catch (\ReflectionException $e) { + if ($throw) { + throw $e; + } + } + + if ($this->trackResources) { + if (!$classReflector) { + $this->addResource($resource ?: new ClassExistenceResource($class, false)); + } elseif (!$classReflector->isInternal()) { + $path = $classReflector->getFileName(); + + if (!$this->inVendors($path)) { + $this->addResource(new ReflectionClassResource($classReflector, $this->vendors)); + } + } + $this->classReflectors[$class] = $classReflector; + } + + return $classReflector ?: null; + } + + /** + * Checks whether the requested file or directory exists and registers the result for resource tracking. + * + * @param string $path The file or directory path for which to check the existence + * @param bool|string $trackContents Whether to track contents of the given resource. If a string is passed, + * it will be used as pattern for tracking contents of the requested directory + * + * @return bool + * + * @final + */ + public function fileExists($path, $trackContents = true) + { + $exists = file_exists($path); + + if (!$this->trackResources || $this->inVendors($path)) { + return $exists; + } + + if (!$exists) { + $this->addResource(new FileExistenceResource($path)); + + return $exists; + } + + if (is_dir($path)) { + if ($trackContents) { + $this->addResource(new DirectoryResource($path, \is_string($trackContents) ? $trackContents : null)); + } else { + $this->addResource(new GlobResource($path, '/*', false)); + } + } elseif ($trackContents) { + $this->addResource(new FileResource($path)); + } + + return $exists; + } + + /** + * Loads the configuration for an extension. + * + * @param string $extension The extension alias or namespace + * @param array $values An array of values that customizes the extension + * + * @return $this + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + * @throws \LogicException if the extension is not registered + */ + public function loadFromExtension($extension, array $values = null) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Cannot load from an extension on a compiled container.'); + } + + if (\func_num_args() < 2) { + $values = []; + } + + $namespace = $this->getExtension($extension)->getAlias(); + + $this->extensionConfigs[$namespace][] = $values; + + return $this; + } + + /** + * Adds a compiler pass. + * + * @param CompilerPassInterface $pass A compiler pass + * @param string $type The type of compiler pass + * @param int $priority Used to sort the passes + * + * @return $this + */ + public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/) + { + if (\func_num_args() >= 3) { + $priority = func_get_arg(2); + } else { + if (__CLASS__ !== static::class) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName()) { + @trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), \E_USER_DEPRECATED); + } + } + + $priority = 0; + } + + $this->getCompiler()->addPass($pass, $type, $priority); + + $this->addObjectResource($pass); + + return $this; + } + + /** + * Returns the compiler pass config which can then be modified. + * + * @return PassConfig The compiler pass config + */ + public function getCompilerPassConfig() + { + return $this->getCompiler()->getPassConfig(); + } + + /** + * Returns the compiler. + * + * @return Compiler The compiler + */ + public function getCompiler() + { + if (null === $this->compiler) { + $this->compiler = new Compiler(); + } + + return $this->compiler; + } + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object|null $service The service instance + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function set($id, $service) + { + $id = $this->normalizeId($id); + + if ($this->isCompiled() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) { + // setting a synthetic service on a compiled container is alright + throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id)); + } + + unset($this->definitions[$id], $this->aliasDefinitions[$id], $this->removedIds[$id]); + + parent::set($id, $service); + } + + /** + * Removes a service definition. + * + * @param string $id The service identifier + */ + public function removeDefinition($id) + { + if (isset($this->definitions[$id = $this->normalizeId($id)])) { + unset($this->definitions[$id]); + $this->removedIds[$id] = true; + } + } + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return bool true if the service is defined, false otherwise + */ + public function has($id) + { + $id = $this->normalizeId($id); + + return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id); + } + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object|null The associated service + * + * @throws InvalidArgumentException when no definitions are available + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * @throws \Exception + * + * @see Reference + */ + public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + if ($this->isCompiled() && isset($this->removedIds[$id = $this->normalizeId($id)])) { + @trigger_error(sprintf('Fetching the "%s" private service or alias is deprecated since Symfony 3.4 and will fail in 4.0. Make it public instead.', $id), \E_USER_DEPRECATED); + } + + return $this->doGet($id, $invalidBehavior); + } + + private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, array &$inlineServices = null, $isConstructorArgument = false) + { + $id = $this->normalizeId($id); + + if (isset($inlineServices[$id])) { + return $inlineServices[$id]; + } + if (null === $inlineServices) { + $isConstructorArgument = true; + $inlineServices = []; + } + try { + if (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $invalidBehavior) { + return parent::get($id, $invalidBehavior); + } + if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) { + return $service; + } + } catch (ServiceCircularReferenceException $e) { + if ($isConstructorArgument) { + throw $e; + } + } + + if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) { + return $this->doGet((string) $this->aliasDefinitions[$id], $invalidBehavior, $inlineServices, $isConstructorArgument); + } + + try { + $definition = $this->getDefinition($id); + } catch (ServiceNotFoundException $e) { + if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) { + return null; + } + + throw $e; + } + + if ($isConstructorArgument) { + $this->loading[$id] = true; + } + + try { + return $this->createService($definition, $inlineServices, $isConstructorArgument, $id); + } finally { + if ($isConstructorArgument) { + unset($this->loading[$id]); + } + } + } + + /** + * Merges a ContainerBuilder with the current ContainerBuilder configuration. + * + * Service definitions overrides the current defined ones. + * + * But for parameters, they are overridden by the current ones. It allows + * the parameters passed to the container constructor to have precedence + * over the loaded ones. + * + * $container = new ContainerBuilder(new ParameterBag(['foo' => 'bar'])); + * $loader = new LoaderXXX($container); + * $loader->load('resource_name'); + * $container->register('foo', 'stdClass'); + * + * In the above example, even if the loaded resource defines a foo + * parameter, the value will still be 'bar' as defined in the ContainerBuilder + * constructor. + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function merge(self $container) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Cannot merge on a compiled container.'); + } + + $this->addDefinitions($container->getDefinitions()); + $this->addAliases($container->getAliases()); + $this->getParameterBag()->add($container->getParameterBag()->all()); + + if ($this->trackResources) { + foreach ($container->getResources() as $resource) { + $this->addResource($resource); + } + } + + foreach ($this->extensions as $name => $extension) { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + + $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name)); + } + + if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) { + $envPlaceholders = $container->getParameterBag()->getEnvPlaceholders(); + $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag()); + } else { + $envPlaceholders = []; + } + + foreach ($container->envCounters as $env => $count) { + if (!$count && !isset($envPlaceholders[$env])) { + continue; + } + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = $count; + } else { + $this->envCounters[$env] += $count; + } + } + + foreach ($container->getAutoconfiguredInstanceof() as $interface => $childDefinition) { + if (isset($this->autoconfiguredInstanceof[$interface])) { + throw new InvalidArgumentException(sprintf('"%s" has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.', $interface)); + } + + $this->autoconfiguredInstanceof[$interface] = $childDefinition; + } + } + + /** + * Returns the configuration array for the given extension. + * + * @param string $name The name of the extension + * + * @return array An array of configuration + */ + public function getExtensionConfig($name) + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + + return $this->extensionConfigs[$name]; + } + + /** + * Prepends a config array to the configs of the given extension. + * + * @param string $name The name of the extension + * @param array $config The config to set + */ + public function prependExtensionConfig($name, array $config) + { + if (!isset($this->extensionConfigs[$name])) { + $this->extensionConfigs[$name] = []; + } + + array_unshift($this->extensionConfigs[$name], $config); + } + + /** + * Compiles the container. + * + * This method passes the container to compiler + * passes whose job is to manipulate and optimize + * the container. + * + * The main compiler passes roughly do four things: + * + * * The extension configurations are merged; + * * Parameter values are resolved; + * * The parameter bag is frozen; + * * Extension loading is disabled. + * + * @param bool $resolveEnvPlaceholders Whether %env()% parameters should be resolved using the current + * env vars or be replaced by uniquely identifiable placeholders. + * Set to "true" when you want to use the current ContainerBuilder + * directly, keep to "false" when the container is dumped instead. + */ + public function compile(/*$resolveEnvPlaceholders = false*/) + { + if (1 <= \func_num_args()) { + $resolveEnvPlaceholders = func_get_arg(0); + } else { + if (__CLASS__ !== static::class) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName() && (1 > $r->getNumberOfParameters() || 'resolveEnvPlaceholders' !== $r->getParameters()[0]->name)) { + @trigger_error(sprintf('The %s::compile() method expects a first "$resolveEnvPlaceholders" argument since Symfony 3.3. It will be made mandatory in 4.0.', static::class), \E_USER_DEPRECATED); + } + } + $resolveEnvPlaceholders = false; + } + $compiler = $this->getCompiler(); + + if ($this->trackResources) { + foreach ($compiler->getPassConfig()->getPasses() as $pass) { + $this->addObjectResource($pass); + } + } + $bag = $this->getParameterBag(); + + if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { + $compiler->addPass(new ResolveEnvPlaceholdersPass(), PassConfig::TYPE_AFTER_REMOVING, -1000); + } + + $compiler->compile($this); + + foreach ($this->definitions as $id => $definition) { + if ($this->trackResources && $definition->isLazy()) { + $this->getReflectionClass($definition->getClass()); + } + } + + $this->extensionConfigs = []; + + if ($bag instanceof EnvPlaceholderParameterBag) { + if ($resolveEnvPlaceholders) { + $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); + } + + $this->envPlaceholders = $bag->getEnvPlaceholders(); + } + + parent::compile(); + + foreach ($this->definitions + $this->aliasDefinitions as $id => $definition) { + if (!$definition->isPublic() || $definition->isPrivate()) { + $this->removedIds[$id] = true; + } + } + } + + /** + * {@inheritdoc} + */ + public function getServiceIds() + { + return array_map('strval', array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliasDefinitions), parent::getServiceIds()))); + } + + /** + * Gets removed service or alias ids. + * + * @return array + */ + public function getRemovedIds() + { + return $this->removedIds; + } + + /** + * Adds the service aliases. + */ + public function addAliases(array $aliases) + { + foreach ($aliases as $alias => $id) { + $this->setAlias($alias, $id); + } + } + + /** + * Sets the service aliases. + */ + public function setAliases(array $aliases) + { + $this->aliasDefinitions = []; + $this->addAliases($aliases); + } + + /** + * Sets an alias for an existing service. + * + * @param string $alias The alias to create + * @param string|Alias $id The service to alias + * + * @return Alias + * + * @throws InvalidArgumentException if the id is not a string or an Alias + * @throws InvalidArgumentException if the alias is for itself + */ + public function setAlias($alias, $id) + { + $alias = $this->normalizeId($alias); + + if ('' === $alias || '\\' === substr($alias, -1) || \strlen($alias) !== strcspn($alias, "\0\r\n'")) { + throw new InvalidArgumentException(sprintf('Invalid alias id: "%s".', $alias)); + } + + if (\is_string($id)) { + $id = new Alias($this->normalizeId($id)); + } elseif (!$id instanceof Alias) { + throw new InvalidArgumentException('$id must be a string, or an Alias object.'); + } + + if ($alias === (string) $id) { + throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias)); + } + + unset($this->definitions[$alias], $this->removedIds[$alias]); + + return $this->aliasDefinitions[$alias] = $id; + } + + /** + * Removes an alias. + * + * @param string $alias The alias to remove + */ + public function removeAlias($alias) + { + if (isset($this->aliasDefinitions[$alias = $this->normalizeId($alias)])) { + unset($this->aliasDefinitions[$alias]); + $this->removedIds[$alias] = true; + } + } + + /** + * Returns true if an alias exists under the given identifier. + * + * @param string $id The service identifier + * + * @return bool true if the alias exists, false otherwise + */ + public function hasAlias($id) + { + return isset($this->aliasDefinitions[$this->normalizeId($id)]); + } + + /** + * Gets all defined aliases. + * + * @return Alias[] An array of aliases + */ + public function getAliases() + { + return $this->aliasDefinitions; + } + + /** + * Gets an alias. + * + * @param string $id The service identifier + * + * @return Alias An Alias instance + * + * @throws InvalidArgumentException if the alias does not exist + */ + public function getAlias($id) + { + $id = $this->normalizeId($id); + + if (!isset($this->aliasDefinitions[$id])) { + throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id)); + } + + return $this->aliasDefinitions[$id]; + } + + /** + * Registers a service definition. + * + * This methods allows for simple registration of service definition + * with a fluid interface. + * + * @param string $id The service identifier + * @param string|null $class The service class + * + * @return Definition A Definition instance + */ + public function register($id, $class = null) + { + return $this->setDefinition($id, new Definition($class)); + } + + /** + * Registers an autowired service definition. + * + * This method implements a shortcut for using setDefinition() with + * an autowired definition. + * + * @param string $id The service identifier + * @param string|null $class The service class + * + * @return Definition The created definition + */ + public function autowire($id, $class = null) + { + return $this->setDefinition($id, (new Definition($class))->setAutowired(true)); + } + + /** + * Adds the service definitions. + * + * @param Definition[] $definitions An array of service definitions + */ + public function addDefinitions(array $definitions) + { + foreach ($definitions as $id => $definition) { + $this->setDefinition($id, $definition); + } + } + + /** + * Sets the service definitions. + * + * @param Definition[] $definitions An array of service definitions + */ + public function setDefinitions(array $definitions) + { + $this->definitions = []; + $this->addDefinitions($definitions); + } + + /** + * Gets all service definitions. + * + * @return Definition[] An array of Definition instances + */ + public function getDefinitions() + { + return $this->definitions; + } + + /** + * Sets a service definition. + * + * @param string $id The service identifier + * @param Definition $definition A Definition instance + * + * @return Definition the service definition + * + * @throws BadMethodCallException When this ContainerBuilder is compiled + */ + public function setDefinition($id, Definition $definition) + { + if ($this->isCompiled()) { + throw new BadMethodCallException('Adding definition to a compiled container is not allowed.'); + } + + $id = $this->normalizeId($id); + + if ('' === $id || '\\' === substr($id, -1) || \strlen($id) !== strcspn($id, "\0\r\n'")) { + throw new InvalidArgumentException(sprintf('Invalid service id: "%s".', $id)); + } + + unset($this->aliasDefinitions[$id], $this->removedIds[$id]); + + return $this->definitions[$id] = $definition; + } + + /** + * Returns true if a service definition exists under the given identifier. + * + * @param string $id The service identifier + * + * @return bool true if the service definition exists, false otherwise + */ + public function hasDefinition($id) + { + return isset($this->definitions[$this->normalizeId($id)]); + } + + /** + * Gets a service definition. + * + * @param string $id The service identifier + * + * @return Definition A Definition instance + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public function getDefinition($id) + { + $id = $this->normalizeId($id); + + if (!isset($this->definitions[$id])) { + throw new ServiceNotFoundException($id); + } + + return $this->definitions[$id]; + } + + /** + * Gets a service definition by id or alias. + * + * The method "unaliases" recursively to return a Definition instance. + * + * @param string $id The service identifier or alias + * + * @return Definition A Definition instance + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + public function findDefinition($id) + { + $id = $this->normalizeId($id); + + $seen = []; + while (isset($this->aliasDefinitions[$id])) { + $id = (string) $this->aliasDefinitions[$id]; + + if (isset($seen[$id])) { + $seen = array_values($seen); + $seen = \array_slice($seen, array_search($id, $seen)); + $seen[] = $id; + + throw new ServiceCircularReferenceException($id, $seen); + } + + $seen[$id] = $id; + } + + return $this->getDefinition($id); + } + + /** + * Creates a service for a service definition. + * + * @param Definition $definition A service definition instance + * @param string $id The service identifier + * @param bool $tryProxy Whether to try proxying the service with a lazy proxy + * + * @return mixed The service described by the service definition + * + * @throws RuntimeException When the factory definition is incomplete + * @throws RuntimeException When the service is a synthetic service + * @throws InvalidArgumentException When configure callable is not callable + */ + private function createService(Definition $definition, array &$inlineServices, $isConstructorArgument = false, $id = null, $tryProxy = true) + { + if (null === $id && isset($inlineServices[$h = spl_object_hash($definition)])) { + return $inlineServices[$h]; + } + + if ($definition instanceof ChildDefinition) { + throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id)); + } + + if ($definition->isSynthetic()) { + throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id)); + } + + if ($definition->isDeprecated()) { + @trigger_error($definition->getDeprecationMessage($id), \E_USER_DEPRECATED); + } + + if ($tryProxy && $definition->isLazy() && !$tryProxy = !($proxy = $this->proxyInstantiator) || $proxy instanceof RealServiceInstantiator) { + $proxy = $proxy->instantiateProxy( + $this, + $definition, + $id, function () use ($definition, &$inlineServices, $id) { + return $this->createService($definition, $inlineServices, true, $id, false); + } + ); + $this->shareService($definition, $proxy, $id, $inlineServices); + + return $proxy; + } + + $parameterBag = $this->getParameterBag(); + + if (null !== $definition->getFile()) { + require_once $parameterBag->resolveValue($definition->getFile()); + } + + $arguments = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())), $inlineServices, $isConstructorArgument); + + if (null !== $factory = $definition->getFactory()) { + if (\is_array($factory)) { + $factory = [$this->doResolveServices($parameterBag->resolveValue($factory[0]), $inlineServices, $isConstructorArgument), $factory[1]]; + } elseif (!\is_string($factory)) { + throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory.', $id)); + } + } + + if (null !== $id && $definition->isShared() && isset($this->services[$id]) && ($tryProxy || !$definition->isLazy())) { + return $this->services[$id]; + } + + if (null !== $factory) { + $service = \call_user_func_array($factory, $arguments); + + if (!$definition->isDeprecated() && \is_array($factory) && \is_string($factory[0])) { + $r = new \ReflectionClass($factory[0]); + + if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) { + @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name), \E_USER_DEPRECATED); + } + } + } else { + $r = new \ReflectionClass($class = $parameterBag->resolveValue($definition->getClass())); + + $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs(array_values($arguments)); + // don't trigger deprecations for internal uses + // @deprecated since version 3.3, to be removed in 4.0 along with the deprecated class + $deprecationAllowlist = ['event_dispatcher' => ContainerAwareEventDispatcher::class]; + + if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ") && (!isset($deprecationAllowlist[$id]) || $deprecationAllowlist[$id] !== $class)) { + @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name), \E_USER_DEPRECATED); + } + } + + if ($tryProxy || !$definition->isLazy()) { + // share only if proxying failed, or if not a proxy + $this->shareService($definition, $service, $id, $inlineServices); + } + + $properties = $this->doResolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())), $inlineServices); + foreach ($properties as $name => $value) { + $service->$name = $value; + } + + foreach ($definition->getMethodCalls() as $call) { + $this->callMethod($service, $call, $inlineServices); + } + + if ($callable = $definition->getConfigurator()) { + if (\is_array($callable)) { + $callable[0] = $parameterBag->resolveValue($callable[0]); + + if ($callable[0] instanceof Reference) { + $callable[0] = $this->doGet((string) $callable[0], $callable[0]->getInvalidBehavior(), $inlineServices); + } elseif ($callable[0] instanceof Definition) { + $callable[0] = $this->createService($callable[0], $inlineServices); + } + } + + if (!\is_callable($callable)) { + throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', \get_class($service))); + } + + \call_user_func($callable, $service); + } + + return $service; + } + + /** + * Replaces service references by the real service instance and evaluates expressions. + * + * @param mixed $value A value + * + * @return mixed The same value with all service references replaced by + * the real service instances and all expressions evaluated + */ + public function resolveServices($value) + { + return $this->doResolveServices($value); + } + + private function doResolveServices($value, array &$inlineServices = [], $isConstructorArgument = false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = $this->doResolveServices($v, $inlineServices, $isConstructorArgument); + } + } elseif ($value instanceof ServiceClosureArgument) { + $reference = $value->getValues()[0]; + $value = function () use ($reference) { + return $this->resolveServices($reference); + }; + } elseif ($value instanceof IteratorArgument) { + $value = new RewindableGenerator(function () use ($value) { + foreach ($value->getValues() as $k => $v) { + foreach (self::getServiceConditionals($v) as $s) { + if (!$this->has($s)) { + continue 2; + } + } + foreach (self::getInitializedConditionals($v) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + continue 2; + } + } + + yield $k => $this->resolveServices($v); + } + }, function () use ($value) { + $count = 0; + foreach ($value->getValues() as $v) { + foreach (self::getServiceConditionals($v) as $s) { + if (!$this->has($s)) { + continue 2; + } + } + foreach (self::getInitializedConditionals($v) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)) { + continue 2; + } + } + + ++$count; + } + + return $count; + }); + } elseif ($value instanceof Reference) { + $value = $this->doGet((string) $value, $value->getInvalidBehavior(), $inlineServices, $isConstructorArgument); + } elseif ($value instanceof Definition) { + $value = $this->createService($value, $inlineServices, $isConstructorArgument); + } elseif ($value instanceof Parameter) { + $value = $this->getParameter((string) $value); + } elseif ($value instanceof Expression) { + $value = $this->getExpressionLanguage()->evaluate($value, ['container' => $this]); + } + + return $value; + } + + /** + * Returns service ids for a given tag. + * + * Example: + * + * $container->register('foo')->addTag('my.tag', ['hello' => 'world']); + * + * $serviceIds = $container->findTaggedServiceIds('my.tag'); + * foreach ($serviceIds as $serviceId => $tags) { + * foreach ($tags as $tag) { + * echo $tag['hello']; + * } + * } + * + * @param string $name + * @param bool $throwOnAbstract + * + * @return array An array of tags with the tagged service as key, holding a list of attribute arrays + */ + public function findTaggedServiceIds($name, $throwOnAbstract = false) + { + $this->usedTags[] = $name; + $tags = []; + foreach ($this->getDefinitions() as $id => $definition) { + if ($definition->hasTag($name)) { + if ($throwOnAbstract && $definition->isAbstract()) { + throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must not be abstract.', $id, $name)); + } + $tags[$id] = $definition->getTag($name); + } + } + + return $tags; + } + + /** + * Returns all tags the defined services use. + * + * @return array An array of tags + */ + public function findTags() + { + $tags = []; + foreach ($this->getDefinitions() as $id => $definition) { + $tags = array_merge(array_keys($definition->getTags()), $tags); + } + + return array_unique($tags); + } + + /** + * Returns all tags not queried by findTaggedServiceIds. + * + * @return string[] An array of tags + */ + public function findUnusedTags() + { + return array_values(array_diff($this->findTags(), $this->usedTags)); + } + + public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) + { + $this->expressionLanguageProviders[] = $provider; + } + + /** + * @return ExpressionFunctionProviderInterface[] + */ + public function getExpressionLanguageProviders() + { + return $this->expressionLanguageProviders; + } + + /** + * Returns a ChildDefinition that will be used for autoconfiguring the interface/class. + * + * @param string $interface The class or interface to match + * + * @return ChildDefinition + */ + public function registerForAutoconfiguration($interface) + { + if (!isset($this->autoconfiguredInstanceof[$interface])) { + $this->autoconfiguredInstanceof[$interface] = new ChildDefinition(''); + } + + return $this->autoconfiguredInstanceof[$interface]; + } + + /** + * Returns an array of ChildDefinition[] keyed by interface. + * + * @return ChildDefinition[] + */ + public function getAutoconfiguredInstanceof() + { + return $this->autoconfiguredInstanceof; + } + + /** + * Resolves env parameter placeholders in a string or an array. + * + * @param mixed $value The value to resolve + * @param string|true|null $format A sprintf() format returning the replacement for each env var name or + * null to resolve back to the original "%env(VAR)%" format or + * true to resolve to the actual values of the referenced env vars + * @param array &$usedEnvs Env vars found while resolving are added to this array + * + * @return mixed The value with env parameters resolved if a string or an array is passed + */ + public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null) + { + if (null === $format) { + $format = '%%env(%s)%%'; + } + + $bag = $this->getParameterBag(); + if (true === $format) { + $value = $bag->resolveValue($value); + } + + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[\is_string($k) ? $this->resolveEnvPlaceholders($k, $format, $usedEnvs) : $k] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs); + } + + return $result; + } + + if (!\is_string($value) || 38 > \strlen($value)) { + return $value; + } + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + + $completed = false; + foreach ($envPlaceholders as $env => $placeholders) { + foreach ($placeholders as $placeholder) { + if (false !== stripos($value, $placeholder)) { + if (true === $format) { + $resolved = $bag->escapeValue($this->getEnv($env)); + } else { + $resolved = sprintf($format, $env); + } + if ($placeholder === $value) { + $value = $resolved; + $completed = true; + } else { + if (!\is_string($resolved) && !is_numeric($resolved)) { + throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "env(%s)" of type "%s" inside string value "%s".', $env, \gettype($resolved), $this->resolveEnvPlaceholders($value))); + } + $value = str_ireplace($placeholder, $resolved, $value); + } + $usedEnvs[$env] = $env; + $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1; + + if ($completed) { + break 2; + } + } + } + } + + return $value; + } + + /** + * Get statistics about env usage. + * + * @return int[] The number of time each env vars has been resolved + */ + public function getEnvCounters() + { + $bag = $this->getParameterBag(); + $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders; + + foreach ($envPlaceholders as $env => $placeholders) { + if (!isset($this->envCounters[$env])) { + $this->envCounters[$env] = 0; + } + } + + return $this->envCounters; + } + + /** + * @internal + */ + public function getNormalizedIds() + { + $normalizedIds = []; + + foreach ($this->normalizedIds as $k => $v) { + if ($v !== (string) $k) { + $normalizedIds[$k] = $v; + } + } + + return $normalizedIds; + } + + /** + * @final + */ + public function log(CompilerPassInterface $pass, $message) + { + $this->getCompiler()->log($pass, $this->resolveEnvPlaceholders($message)); + } + + /** + * {@inheritdoc} + */ + public function normalizeId($id) + { + if (!\is_string($id)) { + $id = (string) $id; + } + + return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || isset($this->removedIds[$id]) ? $id : parent::normalizeId($id); + } + + /** + * Gets removed binding ids. + * + * @return array + * + * @internal + */ + public function getRemovedBindingIds() + { + return $this->removedBindingIds; + } + + /** + * Removes bindings for a service. + * + * @param string $id The service identifier + * + * @internal + */ + public function removeBindings($id) + { + if ($this->hasDefinition($id)) { + foreach ($this->getDefinition($id)->getBindings() as $key => $binding) { + list(, $bindingId) = $binding->getValues(); + $this->removedBindingIds[(int) $bindingId] = true; + } + } + } + + /** + * Returns the Service Conditionals. + * + * @param mixed $value An array of conditionals to return + * + * @return array An array of Service conditionals + * + * @internal since version 3.4 + */ + public static function getServiceConditionals($value) + { + $services = []; + + if (\is_array($value)) { + foreach ($value as $v) { + $services = array_unique(array_merge($services, self::getServiceConditionals($v))); + } + } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) { + $services[] = (string) $value; + } + + return $services; + } + + /** + * Returns the initialized conditionals. + * + * @param mixed $value An array of conditionals to return + * + * @return array An array of uninitialized conditionals + * + * @internal + */ + public static function getInitializedConditionals($value) + { + $services = []; + + if (\is_array($value)) { + foreach ($value as $v) { + $services = array_unique(array_merge($services, self::getInitializedConditionals($v))); + } + } elseif ($value instanceof Reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()) { + $services[] = (string) $value; + } + + return $services; + } + + /** + * Computes a reasonably unique hash of a value. + * + * @param mixed $value A serializable value + * + * @return string + */ + public static function hash($value) + { + $hash = substr(base64_encode(hash('sha256', serialize($value), true)), 0, 7); + + return str_replace(['/', '+'], ['.', '_'], strtolower($hash)); + } + + /** + * {@inheritdoc} + */ + protected function getEnv($name) + { + $value = parent::getEnv($name); + $bag = $this->getParameterBag(); + + if (!\is_string($value) || !$bag instanceof EnvPlaceholderParameterBag) { + return $value; + } + + foreach ($bag->getEnvPlaceholders() as $env => $placeholders) { + if (isset($placeholders[$value])) { + $bag = new ParameterBag($bag->all()); + + return $bag->unescapeValue($bag->get("env($name)")); + } + } + + $this->resolving["env($name)"] = true; + try { + return $bag->unescapeValue($this->resolveEnvPlaceholders($bag->escapeValue($value), true)); + } finally { + unset($this->resolving["env($name)"]); + } + } + + private function callMethod($service, $call, array &$inlineServices) + { + foreach (self::getServiceConditionals($call[1]) as $s) { + if (!$this->has($s)) { + return; + } + } + foreach (self::getInitializedConditionals($call[1]) as $s) { + if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) { + return; + } + } + + \call_user_func_array([$service, $call[0]], $this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices)); + } + + /** + * Shares a given service in the container. + * + * @param mixed $service + * @param string|null $id + */ + private function shareService(Definition $definition, $service, $id, array &$inlineServices) + { + $inlineServices[null !== $id ? $id : spl_object_hash($definition)] = $service; + + if (null !== $id && $definition->isShared()) { + $this->services[$id] = $service; + unset($this->loading[$id]); + } + } + + private function getExpressionLanguage() + { + if (null === $this->expressionLanguage) { + if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { + throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders); + } + + return $this->expressionLanguage; + } + + private function inVendors($path) + { + if (null === $this->vendors) { + $resource = new ComposerResource(); + $this->vendors = $resource->getVendors(); + $this->addResource($resource); + } + $path = realpath($path) ?: $path; + + foreach ($this->vendors as $vendor) { + if (0 === strpos($path, $vendor) && false !== strpbrk(substr($path, \strlen($vendor), 1), '/'.\DIRECTORY_SEPARATOR)) { + return true; + } + } + + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerInterface.php new file mode 100644 index 00000000..c5ab4c2e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ContainerInterface.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +/** + * ContainerInterface is the interface implemented by service container classes. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +interface ContainerInterface extends PsrContainerInterface +{ + const EXCEPTION_ON_INVALID_REFERENCE = 1; + const NULL_ON_INVALID_REFERENCE = 2; + const IGNORE_ON_INVALID_REFERENCE = 3; + const IGNORE_ON_UNINITIALIZED_REFERENCE = 4; + + /** + * Sets a service. + * + * @param string $id The service identifier + * @param object|null $service The service instance + */ + public function set($id, $service); + + /** + * Gets a service. + * + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @return object|null The associated service + * + * @throws ServiceCircularReferenceException When a circular reference is detected + * @throws ServiceNotFoundException When the service is not defined + * + * @see Reference + */ + public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE); + + /** + * Returns true if the given service is defined. + * + * @param string $id The service identifier + * + * @return bool true if the service is defined, false otherwise + */ + public function has($id); + + /** + * Check for whether or not a service has been initialized. + * + * @param string $id + * + * @return bool true if the service has been initialized, false otherwise + */ + public function initialized($id); + + /** + * Gets a parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws InvalidArgumentException if the parameter is not defined + */ + public function getParameter($name); + + /** + * Checks if a parameter exists. + * + * @param string $name The parameter name + * + * @return bool The presence of parameter in container + */ + public function hasParameter($name); + + /** + * Sets a parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + */ + public function setParameter($name, $value); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Definition.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Definition.php new file mode 100644 index 00000000..c3a94f5c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Definition.php @@ -0,0 +1,973 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; + +/** + * Definition represents a service definition. + * + * @author Fabien Potencier + */ +class Definition +{ + private $class; + private $file; + private $factory; + private $shared = true; + private $deprecated = false; + private $deprecationTemplate; + private $properties = []; + private $calls = []; + private $instanceof = []; + private $autoconfigured = false; + private $configurator; + private $tags = []; + private $public = true; + private $private = true; + private $synthetic = false; + private $abstract = false; + private $lazy = false; + private $decoratedService; + private $autowired = false; + private $autowiringTypes = []; + private $changes = []; + private $bindings = []; + private $errors = []; + + protected $arguments = []; + + private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.'; + + /** + * @param string|null $class The service class + * @param array $arguments An array of arguments to pass to the service constructor + */ + public function __construct($class = null, array $arguments = []) + { + if (null !== $class) { + $this->setClass($class); + } + $this->arguments = $arguments; + } + + /** + * Returns all changes tracked for the Definition object. + * + * @return array An array of changes for this Definition + */ + public function getChanges() + { + return $this->changes; + } + + /** + * Sets the tracked changes for the Definition object. + * + * @param array $changes An array of changes for this Definition + * + * @return $this + */ + public function setChanges(array $changes) + { + $this->changes = $changes; + + return $this; + } + + /** + * Sets a factory. + * + * @param string|array $factory A PHP function or an array containing a class/Reference and a method to call + * + * @return $this + */ + public function setFactory($factory) + { + $this->changes['factory'] = true; + + if (\is_string($factory) && false !== strpos($factory, '::')) { + $factory = explode('::', $factory, 2); + } + + $this->factory = $factory; + + return $this; + } + + /** + * Gets the factory. + * + * @return string|array|null The PHP function or an array containing a class/Reference and a method to call + */ + public function getFactory() + { + return $this->factory; + } + + /** + * Sets the service that this service is decorating. + * + * @param string|null $id The decorated service id, use null to remove decoration + * @param string|null $renamedId The new decorated service id + * @param int $priority The priority of decoration + * + * @return $this + * + * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals + */ + public function setDecoratedService($id, $renamedId = null, $priority = 0) + { + if ($renamedId && $id === $renamedId) { + throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); + } + + $this->changes['decorated_service'] = true; + + if (null === $id) { + $this->decoratedService = null; + } else { + $this->decoratedService = [$id, $renamedId, (int) $priority]; + } + + return $this; + } + + /** + * Gets the service that this service is decorating. + * + * @return array|null An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated + */ + public function getDecoratedService() + { + return $this->decoratedService; + } + + /** + * Sets the service class. + * + * @param string $class The service class + * + * @return $this + */ + public function setClass($class) + { + $this->changes['class'] = true; + + $this->class = $class; + + return $this; + } + + /** + * Gets the service class. + * + * @return string|null The service class + */ + public function getClass() + { + return $this->class; + } + + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @return $this + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + + return $this; + } + + /** + * Sets the properties to define when creating the service. + * + * @return $this + */ + public function setProperties(array $properties) + { + $this->properties = $properties; + + return $this; + } + + /** + * Gets the properties to define when creating the service. + * + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * Sets a specific property. + * + * @param string $name + * @param mixed $value + * + * @return $this + */ + public function setProperty($name, $value) + { + $this->properties[$name] = $value; + + return $this; + } + + /** + * Adds an argument to pass to the service constructor/factory method. + * + * @param mixed $argument An argument + * + * @return $this + */ + public function addArgument($argument) + { + $this->arguments[] = $argument; + + return $this; + } + + /** + * Replaces a specific argument. + * + * @param int|string $index + * @param mixed $argument + * + * @return $this + * + * @throws OutOfBoundsException When the replaced argument does not exist + */ + public function replaceArgument($index, $argument) + { + if (0 === \count($this->arguments)) { + throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.'); + } + + if (\is_int($index) && ($index < 0 || $index > \count($this->arguments) - 1)) { + throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, \count($this->arguments) - 1)); + } + + if (!\array_key_exists($index, $this->arguments)) { + throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index)); + } + + $this->arguments[$index] = $argument; + + return $this; + } + + /** + * Sets a specific argument. + * + * @param int|string $key + * @param mixed $value + * + * @return $this + */ + public function setArgument($key, $value) + { + $this->arguments[$key] = $value; + + return $this; + } + + /** + * Gets the arguments to pass to the service constructor/factory method. + * + * @return array The array of arguments + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Gets an argument to pass to the service constructor/factory method. + * + * @param int|string $index + * + * @return mixed The argument value + * + * @throws OutOfBoundsException When the argument does not exist + */ + public function getArgument($index) + { + if (!\array_key_exists($index, $this->arguments)) { + throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index)); + } + + return $this->arguments[$index]; + } + + /** + * Sets the methods to call after service initialization. + * + * @return $this + */ + public function setMethodCalls(array $calls = []) + { + $this->calls = []; + foreach ($calls as $call) { + $this->addMethodCall($call[0], $call[1]); + } + + return $this; + } + + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * + * @return $this + * + * @throws InvalidArgumentException on empty $method param + */ + public function addMethodCall($method, array $arguments = []) + { + if (empty($method)) { + throw new InvalidArgumentException('Method name cannot be empty.'); + } + $this->calls[] = [$method, $arguments]; + + return $this; + } + + /** + * Removes a method to call after service initialization. + * + * @param string $method The method name to remove + * + * @return $this + */ + public function removeMethodCall($method) + { + foreach ($this->calls as $i => $call) { + if ($call[0] === $method) { + unset($this->calls[$i]); + break; + } + } + + return $this; + } + + /** + * Check if the current definition has a given method to call after service initialization. + * + * @param string $method The method name to search for + * + * @return bool + */ + public function hasMethodCall($method) + { + foreach ($this->calls as $call) { + if ($call[0] === $method) { + return true; + } + } + + return false; + } + + /** + * Gets the methods to call after service initialization. + * + * @return array An array of method calls + */ + public function getMethodCalls() + { + return $this->calls; + } + + /** + * Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. + * + * @param ChildDefinition[] $instanceof + * + * @return $this + */ + public function setInstanceofConditionals(array $instanceof) + { + $this->instanceof = $instanceof; + + return $this; + } + + /** + * Gets the definition templates to conditionally apply on the current definition, keyed by parent interface/class. + * + * @return ChildDefinition[] + */ + public function getInstanceofConditionals() + { + return $this->instanceof; + } + + /** + * Sets whether or not instanceof conditionals should be prepended with a global set. + * + * @param bool $autoconfigured + * + * @return $this + */ + public function setAutoconfigured($autoconfigured) + { + $this->changes['autoconfigured'] = true; + + $this->autoconfigured = $autoconfigured; + + return $this; + } + + /** + * @return bool + */ + public function isAutoconfigured() + { + return $this->autoconfigured; + } + + /** + * Sets tags for this definition. + * + * @return $this + */ + public function setTags(array $tags) + { + $this->tags = $tags; + + return $this; + } + + /** + * Returns all tags. + * + * @return array An array of tags + */ + public function getTags() + { + return $this->tags; + } + + /** + * Gets a tag by name. + * + * @param string $name The tag name + * + * @return array An array of attributes + */ + public function getTag($name) + { + return isset($this->tags[$name]) ? $this->tags[$name] : []; + } + + /** + * Adds a tag for this definition. + * + * @param string $name The tag name + * @param array $attributes An array of attributes + * + * @return $this + */ + public function addTag($name, array $attributes = []) + { + $this->tags[$name][] = $attributes; + + return $this; + } + + /** + * Whether this definition has a tag with the given name. + * + * @param string $name + * + * @return bool + */ + public function hasTag($name) + { + return isset($this->tags[$name]); + } + + /** + * Clears all tags for a given name. + * + * @param string $name The tag name + * + * @return $this + */ + public function clearTag($name) + { + unset($this->tags[$name]); + + return $this; + } + + /** + * Clears the tags for this definition. + * + * @return $this + */ + public function clearTags() + { + $this->tags = []; + + return $this; + } + + /** + * Sets a file to require before creating the service. + * + * @param string $file A full pathname to include + * + * @return $this + */ + public function setFile($file) + { + $this->changes['file'] = true; + + $this->file = $file; + + return $this; + } + + /** + * Gets the file to require before creating the service. + * + * @return string|null The full pathname to include + */ + public function getFile() + { + return $this->file; + } + + /** + * Sets if the service must be shared or not. + * + * @param bool $shared Whether the service must be shared or not + * + * @return $this + */ + public function setShared($shared) + { + $this->changes['shared'] = true; + + $this->shared = (bool) $shared; + + return $this; + } + + /** + * Whether this service is shared. + * + * @return bool + */ + public function isShared() + { + return $this->shared; + } + + /** + * Sets the visibility of this service. + * + * @param bool $boolean + * + * @return $this + */ + public function setPublic($boolean) + { + $this->changes['public'] = true; + + $this->public = (bool) $boolean; + $this->private = false; + + return $this; + } + + /** + * Whether this service is public facing. + * + * @return bool + */ + public function isPublic() + { + return $this->public; + } + + /** + * Sets if this service is private. + * + * When set, the "private" state has a higher precedence than "public". + * In version 3.4, a "private" service always remains publicly accessible, + * but triggers a deprecation notice when accessed from the container, + * so that the service can be made really private in 4.0. + * + * @param bool $boolean + * + * @return $this + */ + public function setPrivate($boolean) + { + $this->private = (bool) $boolean; + + return $this; + } + + /** + * Whether this service is private. + * + * @return bool + */ + public function isPrivate() + { + return $this->private; + } + + /** + * Sets the lazy flag of this service. + * + * @param bool $lazy + * + * @return $this + */ + public function setLazy($lazy) + { + $this->changes['lazy'] = true; + + $this->lazy = (bool) $lazy; + + return $this; + } + + /** + * Whether this service is lazy. + * + * @return bool + */ + public function isLazy() + { + return $this->lazy; + } + + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @param bool $boolean + * + * @return $this + */ + public function setSynthetic($boolean) + { + $this->synthetic = (bool) $boolean; + + return $this; + } + + /** + * Whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @return bool + */ + public function isSynthetic() + { + return $this->synthetic; + } + + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @param bool $boolean + * + * @return $this + */ + public function setAbstract($boolean) + { + $this->abstract = (bool) $boolean; + + return $this; + } + + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @return bool + */ + public function isAbstract() + { + return $this->abstract; + } + + /** + * Whether this definition is deprecated, that means it should not be called + * anymore. + * + * @param bool $status + * @param string $template Template message to use if the definition is deprecated + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + public function setDeprecated($status = true, $template = null) + { + if (null !== $template) { + if (preg_match('#[\r\n]|\*/#', $template)) { + throw new InvalidArgumentException('Invalid characters found in deprecation template.'); + } + + if (false === strpos($template, '%service_id%')) { + throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.'); + } + + $this->deprecationTemplate = $template; + } + + $this->changes['deprecated'] = true; + + $this->deprecated = (bool) $status; + + return $this; + } + + /** + * Whether this definition is deprecated, that means it should not be called + * anymore. + * + * @return bool + */ + public function isDeprecated() + { + return $this->deprecated; + } + + /** + * Message to use if this definition is deprecated. + * + * @param string $id Service id relying on this definition + * + * @return string + */ + public function getDeprecationMessage($id) + { + return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate); + } + + /** + * Sets a configurator to call after the service is fully initialized. + * + * @param string|array $configurator A PHP callable + * + * @return $this + */ + public function setConfigurator($configurator) + { + $this->changes['configurator'] = true; + + if (\is_string($configurator) && false !== strpos($configurator, '::')) { + $configurator = explode('::', $configurator, 2); + } + + $this->configurator = $configurator; + + return $this; + } + + /** + * Gets the configurator to call after the service is fully initialized. + * + * @return callable|array|null + */ + public function getConfigurator() + { + return $this->configurator; + } + + /** + * Sets types that will default to this definition. + * + * @param string[] $types + * + * @return $this + * + * @deprecated since version 3.3, to be removed in 4.0. + */ + public function setAutowiringTypes(array $types) + { + @trigger_error('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead.', \E_USER_DEPRECATED); + + $this->autowiringTypes = []; + + foreach ($types as $type) { + $this->autowiringTypes[$type] = true; + } + + return $this; + } + + /** + * Is the definition autowired? + * + * @return bool + */ + public function isAutowired() + { + return $this->autowired; + } + + /** + * Enables/disables autowiring. + * + * @param bool $autowired + * + * @return $this + */ + public function setAutowired($autowired) + { + $this->changes['autowired'] = true; + + $this->autowired = (bool) $autowired; + + return $this; + } + + /** + * Gets autowiring types that will default to this definition. + * + * @return string[] + * + * @deprecated since version 3.3, to be removed in 4.0. + */ + public function getAutowiringTypes(/*$triggerDeprecation = true*/) + { + if (1 > \func_num_args() || func_get_arg(0)) { + @trigger_error('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead.', \E_USER_DEPRECATED); + } + + return array_keys($this->autowiringTypes); + } + + /** + * Adds a type that will default to this definition. + * + * @param string $type + * + * @return $this + * + * @deprecated since version 3.3, to be removed in 4.0. + */ + public function addAutowiringType($type) + { + @trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), \E_USER_DEPRECATED); + + $this->autowiringTypes[$type] = true; + + return $this; + } + + /** + * Removes a type. + * + * @param string $type + * + * @return $this + * + * @deprecated since version 3.3, to be removed in 4.0. + */ + public function removeAutowiringType($type) + { + @trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), \E_USER_DEPRECATED); + + unset($this->autowiringTypes[$type]); + + return $this; + } + + /** + * Will this definition default for the given type? + * + * @param string $type + * + * @return bool + * + * @deprecated since version 3.3, to be removed in 4.0. + */ + public function hasAutowiringType($type) + { + @trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), \E_USER_DEPRECATED); + + return isset($this->autowiringTypes[$type]); + } + + /** + * Gets bindings. + * + * @return array + */ + public function getBindings() + { + return $this->bindings; + } + + /** + * Sets bindings. + * + * Bindings map $named or FQCN arguments to values that should be + * injected in the matching parameters (of the constructor, of methods + * called and of controller actions). + * + * @return $this + */ + public function setBindings(array $bindings) + { + foreach ($bindings as $key => $binding) { + if (!$binding instanceof BoundArgument) { + $bindings[$key] = new BoundArgument($binding); + } + } + + $this->bindings = $bindings; + + return $this; + } + + /** + * Add an error that occurred when building this Definition. + * + * @param string $error + */ + public function addError($error) + { + $this->errors[] = $error; + } + + /** + * Returns any errors that occurred while building this Definition. + * + * @return array + */ + public function getErrors() + { + return $this->errors; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/DefinitionDecorator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/DefinitionDecorator.php new file mode 100644 index 00000000..4753c2aa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/DefinitionDecorator.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +@trigger_error('The '.__NAMESPACE__.'\DefinitionDecorator class is deprecated since Symfony 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.', \E_USER_DEPRECATED); + +class_exists(ChildDefinition::class); + +if (false) { + /** + * This definition decorates another definition. + * + * @author Johannes M. Schmitt + * + * @deprecated The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead. + */ + class DefinitionDecorator extends Definition + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/Dumper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/Dumper.php new file mode 100644 index 00000000..e7407b0e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/Dumper.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Dumper is the abstract class for all built-in dumpers. + * + * @author Fabien Potencier + */ +abstract class Dumper implements DumperInterface +{ + protected $container; + + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/DumperInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/DumperInterface.php new file mode 100644 index 00000000..8abc1925 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/DumperInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +/** + * DumperInterface is the interface implemented by service container dumper classes. + * + * @author Fabien Potencier + */ +interface DumperInterface +{ + /** + * Dumps the service container. + * + * @return string|array The representation of the service container + */ + public function dump(array $options = []); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php new file mode 100644 index 00000000..0591e024 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/GraphvizDumper.php @@ -0,0 +1,312 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Reference; + +/** + * GraphvizDumper dumps a service container as a graphviz file. + * + * You can convert the generated dot file with the dot utility (http://www.graphviz.org/): + * + * dot -Tpng container.dot > foo.png + * + * @author Fabien Potencier + */ +class GraphvizDumper extends Dumper +{ + private $nodes; + private $edges; + // All values should be strings + private $options = [ + 'graph' => ['ratio' => 'compress'], + 'node' => ['fontsize' => '11', 'fontname' => 'Arial', 'shape' => 'record'], + 'edge' => ['fontsize' => '9', 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => '0.5'], + 'node.instance' => ['fillcolor' => '#9999ff', 'style' => 'filled'], + 'node.definition' => ['fillcolor' => '#eeeeee'], + 'node.missing' => ['fillcolor' => '#ff9999', 'style' => 'filled'], + ]; + + /** + * Dumps the service container as a graphviz graph. + * + * Available options: + * + * * graph: The default options for the whole graph + * * node: The default options for nodes + * * edge: The default options for edges + * * node.instance: The default options for services that are defined directly by object instances + * * node.definition: The default options for services that are defined via service definition instances + * * node.missing: The default options for missing services + * + * @return string The dot representation of the service container + */ + public function dump(array $options = []) + { + foreach (['graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing'] as $key) { + if (isset($options[$key])) { + $this->options[$key] = array_merge($this->options[$key], $options[$key]); + } + } + + $this->nodes = $this->findNodes(); + + $this->edges = []; + foreach ($this->container->getDefinitions() as $id => $definition) { + $this->edges[$id] = array_merge( + $this->findEdges($id, $definition->getArguments(), true, ''), + $this->findEdges($id, $definition->getProperties(), false, '') + ); + + foreach ($definition->getMethodCalls() as $call) { + $this->edges[$id] = array_merge( + $this->edges[$id], + $this->findEdges($id, $call[1], false, $call[0].'()') + ); + } + } + + return $this->container->resolveEnvPlaceholders($this->startDot().$this->addNodes().$this->addEdges().$this->endDot(), '__ENV_%s__'); + } + + /** + * Returns all nodes. + * + * @return string A string representation of all nodes + */ + private function addNodes() + { + $code = ''; + foreach ($this->nodes as $id => $node) { + $aliases = $this->getAliases($id); + + $code .= sprintf(" node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes'])); + } + + return $code; + } + + /** + * Returns all edges. + * + * @return string A string representation of all edges + */ + private function addEdges() + { + $code = ''; + foreach ($this->edges as $id => $edges) { + foreach ($edges as $edge) { + $code .= sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"%s];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed', $edge['lazy'] ? ' color="#9999ff"' : ''); + } + } + + return $code; + } + + /** + * Finds all edges belonging to a specific service id. + * + * @param string $id The service id used to find edges + * @param array $arguments An array of arguments + * @param bool $required + * @param string $name + * + * @return array An array of edges + */ + private function findEdges($id, array $arguments, $required, $name, $lazy = false) + { + $edges = []; + foreach ($arguments as $argument) { + if ($argument instanceof Parameter) { + $argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null; + } elseif (\is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) { + $argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null; + } + + if ($argument instanceof Reference) { + $lazyEdge = $lazy; + + if (!$this->container->has((string) $argument)) { + $this->nodes[(string) $argument] = ['name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']]; + } elseif ('service_container' !== (string) $argument) { + $lazyEdge = $lazy || $this->container->getDefinition((string) $argument)->isLazy(); + } + + $edges[] = ['name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge]; + } elseif ($argument instanceof ArgumentInterface) { + $edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true)); + } elseif ($argument instanceof Definition) { + $edges = array_merge($edges, + $this->findEdges($id, $argument->getArguments(), $required, ''), + $this->findEdges($id, $argument->getProperties(), false, '') + ); + foreach ($argument->getMethodCalls() as $call) { + $edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()')); + } + } elseif (\is_array($argument)) { + $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy)); + } + } + + return $edges; + } + + /** + * Finds all nodes. + * + * @return array An array of all nodes + */ + private function findNodes() + { + $nodes = []; + + $container = $this->cloneContainer(); + + foreach ($container->getDefinitions() as $id => $definition) { + $class = $definition->getClass(); + + if ('\\' === substr($class, 0, 1)) { + $class = substr($class, 1); + } + + try { + $class = $this->container->getParameterBag()->resolveValue($class); + } catch (ParameterNotFoundException $e) { + } + + $nodes[$id] = ['class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], ['style' => $definition->isShared() ? 'filled' : 'dotted'])]; + $container->setDefinition($id, new Definition('stdClass')); + } + + foreach ($container->getServiceIds() as $id) { + if (\array_key_exists($id, $container->getAliases())) { + continue; + } + + if (!$container->hasDefinition($id)) { + $nodes[$id] = ['class' => str_replace('\\', '\\\\', \get_class($container->get($id))), 'attributes' => $this->options['node.instance']]; + } + } + + return $nodes; + } + + private function cloneContainer() + { + $parameterBag = new ParameterBag($this->container->getParameterBag()->all()); + + $container = new ContainerBuilder($parameterBag); + $container->setDefinitions($this->container->getDefinitions()); + $container->setAliases($this->container->getAliases()); + $container->setResources($this->container->getResources()); + foreach ($this->container->getExtensions() as $extension) { + $container->registerExtension($extension); + } + + return $container; + } + + /** + * Returns the start dot. + * + * @return string The string representation of a start dot + */ + private function startDot() + { + return sprintf("digraph sc {\n %s\n node [%s];\n edge [%s];\n\n", + $this->addOptions($this->options['graph']), + $this->addOptions($this->options['node']), + $this->addOptions($this->options['edge']) + ); + } + + /** + * Returns the end dot. + * + * @return string + */ + private function endDot() + { + return "}\n"; + } + + /** + * Adds attributes. + * + * @param array $attributes An array of attributes + * + * @return string A comma separated list of attributes + */ + private function addAttributes(array $attributes) + { + $code = []; + foreach ($attributes as $k => $v) { + $code[] = sprintf('%s="%s"', $k, $v); + } + + return $code ? ', '.implode(', ', $code) : ''; + } + + /** + * Adds options. + * + * @param array $options An array of options + * + * @return string A space separated list of options + */ + private function addOptions(array $options) + { + $code = []; + foreach ($options as $k => $v) { + $code[] = sprintf('%s="%s"', $k, $v); + } + + return implode(' ', $code); + } + + /** + * Dotizes an identifier. + * + * @param string $id The identifier to dotize + * + * @return string A dotized string + */ + private function dotize($id) + { + return strtolower(preg_replace('/\W/i', '_', $id)); + } + + /** + * Compiles an array of aliases for a specified service id. + * + * @param string $id A service id + * + * @return array An array of aliases + */ + private function getAliases($id) + { + $aliases = []; + foreach ($this->container->getAliases() as $alias => $origin) { + if ($id == $origin) { + $aliases[] = $alias; + } + } + + return $aliases; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/PhpDumper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/PhpDumper.php new file mode 100644 index 00000000..8605d755 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/PhpDumper.php @@ -0,0 +1,2045 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\EnvParameterException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\ExpressionLanguage; +use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper; +use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Component\DependencyInjection\Variable; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\HttpKernel\Kernel; + +/** + * PhpDumper dumps a service container as a PHP class. + * + * @author Fabien Potencier + * @author Johannes M. Schmitt + */ +class PhpDumper extends Dumper +{ + /** + * Characters that might appear in the generated variable name as first character. + */ + const FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz'; + + /** + * Characters that might appear in the generated variable name as any but the first character. + */ + const NON_FIRST_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789_'; + + private $definitionVariables; + private $referenceVariables; + private $variableCount; + private $inlinedDefinitions; + private $serviceCalls; + private $reservedVariables = ['instance', 'class', 'this']; + private $expressionLanguage; + private $targetDirRegex; + private $targetDirMaxMatches; + private $docStar; + private $serviceIdToMethodNameMap; + private $usedMethodNames; + private $namespace; + private $asFiles; + private $hotPathTag; + private $inlineRequires; + private $inlinedRequires = []; + private $circularReferences = []; + + /** + * @var ProxyDumper + */ + private $proxyDumper; + + /** + * {@inheritdoc} + */ + public function __construct(ContainerBuilder $container) + { + if (!$container->isCompiled()) { + @trigger_error('Dumping an uncompiled ContainerBuilder is deprecated since Symfony 3.3 and will not be supported anymore in 4.0. Compile the container beforehand.', \E_USER_DEPRECATED); + } + + parent::__construct($container); + } + + /** + * Sets the dumper to be used when dumping proxies in the generated container. + */ + public function setProxyDumper(ProxyDumper $proxyDumper) + { + $this->proxyDumper = $proxyDumper; + } + + /** + * Dumps the service container as a PHP class. + * + * Available options: + * + * * class: The class name + * * base_class: The base class name + * * namespace: The class namespace + * * as_files: To split the container in several files + * + * @return string|array A PHP class representing the service container or an array of PHP files if the "as_files" option is set + * + * @throws EnvParameterException When an env var exists but has not been dumped + */ + public function dump(array $options = []) + { + $this->targetDirRegex = null; + $this->inlinedRequires = []; + $options = array_merge([ + 'class' => 'ProjectServiceContainer', + 'base_class' => 'Container', + 'namespace' => '', + 'as_files' => false, + 'debug' => true, + 'hot_path_tag' => 'container.hot_path', + 'inline_class_loader_parameter' => 'container.dumper.inline_class_loader', + 'build_time' => time(), + ], $options); + + $this->namespace = $options['namespace']; + $this->asFiles = $options['as_files']; + $this->hotPathTag = $options['hot_path_tag']; + $this->inlineRequires = $options['inline_class_loader_parameter'] && $this->container->hasParameter($options['inline_class_loader_parameter']) && $this->container->getParameter($options['inline_class_loader_parameter']); + + if (0 !== strpos($baseClass = $options['base_class'], '\\') && 'Container' !== $baseClass) { + $baseClass = sprintf('%s\%s', $options['namespace'] ? '\\'.$options['namespace'] : '', $baseClass); + $baseClassWithNamespace = $baseClass; + } elseif ('Container' === $baseClass) { + $baseClassWithNamespace = Container::class; + } else { + $baseClassWithNamespace = $baseClass; + } + + $this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass); + + if ($this->getProxyDumper() instanceof NullDumper) { + (new AnalyzeServiceReferencesPass(true, false))->process($this->container); + try { + (new CheckCircularReferencesPass())->process($this->container); + } catch (ServiceCircularReferenceException $e) { + $path = $e->getPath(); + end($path); + $path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge'; + + throw new ServiceCircularReferenceException($e->getServiceId(), $path); + } + } + + (new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container); + $checkedNodes = []; + $this->circularReferences = []; + foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) { + if (!$node->getValue() instanceof Definition) { + continue; + } + if (!isset($checkedNodes[$id])) { + $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes); + } + } + $this->container->getCompiler()->getServiceReferenceGraph()->clear(); + $checkedNodes = []; + + $this->docStar = $options['debug'] ? '*' : ''; + + if (!empty($options['file']) && is_dir($dir = \dirname($options['file']))) { + // Build a regexp where the first root dirs are mandatory, + // but every other sub-dir is optional up to the full path in $dir + // Mandate at least 1 root dir and not more than 5 optional dirs. + + $dir = explode(\DIRECTORY_SEPARATOR, realpath($dir)); + $i = \count($dir); + + if (2 + (int) ('\\' === \DIRECTORY_SEPARATOR) <= $i) { + $regex = ''; + $lastOptionalDir = $i > 8 ? $i - 5 : (2 + (int) ('\\' === \DIRECTORY_SEPARATOR)); + $this->targetDirMaxMatches = $i - $lastOptionalDir; + + while (--$i >= $lastOptionalDir) { + $regex = sprintf('(%s%s)?', preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#'), $regex); + } + + do { + $regex = preg_quote(\DIRECTORY_SEPARATOR.$dir[$i], '#').$regex; + } while (0 < --$i); + + $this->targetDirRegex = '#(^|file://|[:;, \|\r\n])'.preg_quote($dir[0], '#').$regex.'#'; + } + } + + $code = + $this->startClass($options['class'], $baseClass, $baseClassWithNamespace). + $this->addServices(). + $this->addDefaultParametersMethod(). + $this->endClass() + ; + + if ($this->asFiles) { + $fileStart = <<container->getRemovedIds())) { + sort($ids); + $c = "doExport($id)." => true,\n"; + } + $files['removed-ids.php'] = $c."];\n"; + } + + foreach ($this->generateServiceFiles() as $file => $c) { + $files[$file] = $fileStart.$c; + } + foreach ($this->generateProxyClasses() as $file => $c) { + $files[$file] = " $c) { + $code["Container{$hash}/{$file}"] = $c; + } + array_pop($code); + $code["Container{$hash}/{$options['class']}.php"] = substr_replace($files[$options['class'].'.php'], "namespace ? "\nnamespace {$this->namespace};\n" : ''; + $time = $options['build_time']; + $id = hash('crc32', $hash.$time); + + $code[$options['class'].'.php'] = << '$hash', + 'container.build_id' => '$id', + 'container.build_time' => $time, +], __DIR__.\\DIRECTORY_SEPARATOR.'Container{$hash}'); + +EOF; + } else { + foreach ($this->generateProxyClasses() as $c) { + $code .= $c; + } + } + + $this->targetDirRegex = null; + $this->inlinedRequires = []; + $this->circularReferences = []; + + $unusedEnvs = []; + foreach ($this->container->getEnvCounters() as $env => $use) { + if (!$use) { + $unusedEnvs[] = $env; + } + } + if ($unusedEnvs) { + throw new EnvParameterException($unusedEnvs, null, 'Environment variables "%s" are never used. Please, check your container\'s configuration.'); + } + + return $code; + } + + /** + * Retrieves the currently set proxy dumper or instantiates one. + * + * @return ProxyDumper + */ + private function getProxyDumper() + { + if (!$this->proxyDumper) { + $this->proxyDumper = new NullDumper(); + } + + return $this->proxyDumper; + } + + private function analyzeCircularReferences($sourceId, array $edges, &$checkedNodes, &$currentPath = [], $byConstructor = true) + { + $checkedNodes[$sourceId] = true; + $currentPath[$sourceId] = $byConstructor; + + foreach ($edges as $edge) { + $node = $edge->getDestNode(); + $id = $node->getId(); + + if (!$node->getValue() instanceof Definition || $sourceId === $id || $edge->isLazy() || $edge->isWeak()) { + // no-op + } elseif (isset($currentPath[$id])) { + $this->addCircularReferences($id, $currentPath, $edge->isReferencedByConstructor()); + } elseif (!isset($checkedNodes[$id])) { + $this->analyzeCircularReferences($id, $node->getOutEdges(), $checkedNodes, $currentPath, $edge->isReferencedByConstructor()); + } elseif (isset($this->circularReferences[$id])) { + $this->connectCircularReferences($id, $currentPath, $edge->isReferencedByConstructor()); + } + } + unset($currentPath[$sourceId]); + } + + private function connectCircularReferences($sourceId, &$currentPath, $byConstructor, &$subPath = []) + { + $currentPath[$sourceId] = $subPath[$sourceId] = $byConstructor; + + foreach ($this->circularReferences[$sourceId] as $id => $byConstructor) { + if (isset($currentPath[$id])) { + $this->addCircularReferences($id, $currentPath, $byConstructor); + } elseif (!isset($subPath[$id]) && isset($this->circularReferences[$id])) { + $this->connectCircularReferences($id, $currentPath, $byConstructor, $subPath); + } + } + unset($currentPath[$sourceId], $subPath[$sourceId]); + } + + private function addCircularReferences($id, $currentPath, $byConstructor) + { + $currentPath[$id] = $byConstructor; + $circularRefs = []; + + foreach (array_reverse($currentPath) as $parentId => $v) { + $byConstructor = $byConstructor && $v; + $circularRefs[] = $parentId; + + if ($parentId === $id) { + break; + } + } + + $currentId = $id; + foreach ($circularRefs as $parentId) { + if (empty($this->circularReferences[$parentId][$currentId])) { + $this->circularReferences[$parentId][$currentId] = $byConstructor; + } + + $currentId = $parentId; + } + } + + private function collectLineage($class, array &$lineage) + { + if (isset($lineage[$class])) { + return; + } + if (!$r = $this->container->getReflectionClass($class, false)) { + return; + } + if ($this->container instanceof $class) { + return; + } + $file = $r->getFileName(); + if (') : eval()\'d code' === substr($file, -17)) { + $file = substr($file, 0, strrpos($file, '(', -17)); + } + if (!$file || $this->doExport($file) === $exportedFile = $this->export($file)) { + return; + } + + if ($parent = $r->getParentClass()) { + $this->collectLineage($parent->name, $lineage); + } + + foreach ($r->getInterfaces() as $parent) { + $this->collectLineage($parent->name, $lineage); + } + + foreach ($r->getTraits() as $parent) { + $this->collectLineage($parent->name, $lineage); + } + + $lineage[$class] = substr($exportedFile, 1, -1); + } + + private function generateProxyClasses() + { + $alreadyGenerated = []; + $definitions = $this->container->getDefinitions(); + $strip = '' === $this->docStar && method_exists('Symfony\Component\HttpKernel\Kernel', 'stripComments'); + $proxyDumper = $this->getProxyDumper(); + ksort($definitions); + foreach ($definitions as $definition) { + if (!$proxyDumper->isProxyCandidate($definition)) { + continue; + } + if (isset($alreadyGenerated[$class = $definition->getClass()])) { + continue; + } + $alreadyGenerated[$class] = true; + // register class' reflector for resource tracking + $this->container->getReflectionClass($class); + if ("\n" === $proxyCode = "\n".$proxyDumper->getProxyCode($definition)) { + continue; + } + if ($strip) { + $proxyCode = " $proxyCode; + } + } + + /** + * Generates the require_once statement for service includes. + * + * @return string + */ + private function addServiceInclude($cId, Definition $definition) + { + $code = ''; + + if ($this->inlineRequires && !$this->isHotPath($definition)) { + $lineage = []; + foreach ($this->inlinedDefinitions as $def) { + if (!$def->isDeprecated() && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { + $this->collectLineage($class, $lineage); + } + } + + foreach ($this->serviceCalls as $id => list($callCount, $behavior)) { + if ('service_container' !== $id && $id !== $cId + && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE !== $behavior + && $this->container->has($id) + && $this->isTrivialInstance($def = $this->container->findDefinition($id)) + && \is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass()) + ) { + $this->collectLineage($class, $lineage); + } + } + + foreach (array_diff_key(array_flip($lineage), $this->inlinedRequires) as $file => $class) { + $code .= sprintf(" include_once %s;\n", $file); + } + } + + foreach ($this->inlinedDefinitions as $def) { + if ($file = $def->getFile()) { + $code .= sprintf(" include_once %s;\n", $this->dumpValue($file)); + } + } + + if ('' !== $code) { + $code .= "\n"; + } + + return $code; + } + + /** + * Generates the service instance. + * + * @param string $id + * @param bool $isSimpleInstance + * + * @return string + * + * @throws InvalidArgumentException + * @throws RuntimeException + */ + private function addServiceInstance($id, Definition $definition, $isSimpleInstance) + { + $class = $this->dumpValue($definition->getClass()); + + if (0 === strpos($class, "'") && false === strpos($class, '$') && !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + throw new InvalidArgumentException(sprintf('"%s" is not a valid class name for the "%s" service.', $class, $id)); + } + + $isProxyCandidate = $this->getProxyDumper()->isProxyCandidate($definition); + $instantiation = ''; + + if (!$isProxyCandidate && $definition->isShared()) { + $instantiation = sprintf('$this->services[%s] = %s', $this->doExport($id), $isSimpleInstance ? '' : '$instance'); + } elseif (!$isSimpleInstance) { + $instantiation = '$instance'; + } + + $return = ''; + if ($isSimpleInstance) { + $return = 'return '; + } else { + $instantiation .= ' = '; + } + + return $this->addNewInstance($definition, $return, $instantiation, $id); + } + + /** + * Checks if the definition is a trivial instance. + * + * @return bool + */ + private function isTrivialInstance(Definition $definition) + { + if ($definition->isSynthetic() || $definition->getFile() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) { + return false; + } + if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < \count($definition->getArguments())) { + return false; + } + + foreach ($definition->getArguments() as $arg) { + if (!$arg || $arg instanceof Parameter) { + continue; + } + if (\is_array($arg) && 3 >= \count($arg)) { + foreach ($arg as $k => $v) { + if ($this->dumpValue($k) !== $this->dumpValue($k, false)) { + return false; + } + if (!$v || $v instanceof Parameter) { + continue; + } + if ($v instanceof Reference && $this->container->has($id = (string) $v) && $this->container->findDefinition($id)->isSynthetic()) { + continue; + } + if (!is_scalar($v) || $this->dumpValue($v) !== $this->dumpValue($v, false)) { + return false; + } + } + } elseif ($arg instanceof Reference && $this->container->has($id = (string) $arg) && $this->container->findDefinition($id)->isSynthetic()) { + continue; + } elseif (!is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, false)) { + return false; + } + } + + return true; + } + + /** + * Adds method calls to a service definition. + * + * @param string $variableName + * + * @return string + */ + private function addServiceMethodCalls(Definition $definition, $variableName = 'instance') + { + $calls = ''; + foreach ($definition->getMethodCalls() as $call) { + $arguments = []; + foreach ($call[1] as $value) { + $arguments[] = $this->dumpValue($value); + } + + $calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments))); + } + + return $calls; + } + + private function addServiceProperties(Definition $definition, $variableName = 'instance') + { + $code = ''; + foreach ($definition->getProperties() as $name => $value) { + $code .= sprintf(" \$%s->%s = %s;\n", $variableName, $name, $this->dumpValue($value)); + } + + return $code; + } + + /** + * Adds configurator definition. + * + * @param string $variableName + * + * @return string + */ + private function addServiceConfigurator(Definition $definition, $variableName = 'instance') + { + if (!$callable = $definition->getConfigurator()) { + return ''; + } + + if (\is_array($callable)) { + if ($callable[0] instanceof Reference + || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0])) + ) { + return sprintf(" %s->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + $class = $this->dumpValue($callable[0]); + // If the class is a string we can optimize call_user_func away + if (0 === strpos($class, "'") && false === strpos($class, '$')) { + return sprintf(" %s::%s(\$%s);\n", $this->dumpLiteralClass($class), $callable[1], $variableName); + } + + if (0 === strpos($class, 'new ')) { + return sprintf(" (%s)->%s(\$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + return sprintf(" \\call_user_func([%s, '%s'], \$%s);\n", $this->dumpValue($callable[0]), $callable[1], $variableName); + } + + return sprintf(" %s(\$%s);\n", $callable, $variableName); + } + + /** + * Adds a service. + * + * @param string $id + * @param string &$file + * + * @return string + */ + private function addService($id, Definition $definition, &$file = null) + { + $this->definitionVariables = new \SplObjectStorage(); + $this->referenceVariables = []; + $this->variableCount = 0; + $this->referenceVariables[$id] = new Variable('instance'); + + $return = []; + + if ($class = $definition->getClass()) { + $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); + $return[] = sprintf(0 === strpos($class, '%') ? '@return object A %1$s instance' : '@return \%s', ltrim($class, '\\')); + } elseif ($definition->getFactory()) { + $factory = $definition->getFactory(); + if (\is_string($factory)) { + $return[] = sprintf('@return object An instance returned by %s()', $factory); + } elseif (\is_array($factory) && (\is_string($factory[0]) || $factory[0] instanceof Definition || $factory[0] instanceof Reference)) { + $class = $factory[0] instanceof Definition ? $factory[0]->getClass() : (string) $factory[0]; + $class = $class instanceof Parameter ? '%'.$class.'%' : $this->container->resolveEnvPlaceholders($class); + $return[] = sprintf('@return object An instance returned by %s::%s()', $class, $factory[1]); + } + } + + if ($definition->isDeprecated()) { + if ($return && 0 === strpos($return[\count($return) - 1], '@return')) { + $return[] = ''; + } + + $return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id)); + } + + $return = str_replace("\n * \n", "\n *\n", implode("\n * ", $return)); + $return = $this->container->resolveEnvPlaceholders($return); + + $shared = $definition->isShared() ? ' shared' : ''; + $public = $definition->isPublic() ? 'public' : 'private'; + $autowired = $definition->isAutowired() ? ' autowired' : ''; + + if ($definition->isLazy()) { + $lazyInitialization = '$lazyLoad = true'; + } else { + $lazyInitialization = ''; + } + + $asFile = $this->asFiles && $definition->isShared() && !$this->isHotPath($definition); + $methodName = $this->generateMethodName($id); + if ($asFile) { + $file = $methodName.'.php'; + $code = " // Returns the $public '$id'$shared$autowired service.\n\n"; + } else { + $code = <<docStar} + * Gets the $public '$id'$shared$autowired service. + * + * $return +EOF; + $code = str_replace('*/', ' ', $code).<<serviceCalls = []; + $this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls); + + $code .= $this->addServiceInclude($id, $definition); + + if ($this->getProxyDumper()->isProxyCandidate($definition)) { + $factoryCode = $asFile ? "\$this->load('%s.php', false)" : '$this->%s(false)'; + $code .= $this->getProxyDumper()->getProxyFactoryCode($definition, $id, sprintf($factoryCode, $methodName, $this->doExport($id))); + } + + if ($definition->isDeprecated()) { + $code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id))); + } + + $code .= $this->addInlineService($id, $definition); + + if ($asFile) { + $code = implode("\n", array_map(function ($line) { return $line ? substr($line, 8) : $line; }, explode("\n", $code))); + } else { + $code .= " }\n"; + } + + $this->definitionVariables = $this->inlinedDefinitions = null; + $this->referenceVariables = $this->serviceCalls = null; + + return $code; + } + + private function addInlineVariables($id, Definition $definition, array $arguments, $forConstructor) + { + $code = ''; + + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $code .= $this->addInlineVariables($id, $definition, $argument, $forConstructor); + } elseif ($argument instanceof Reference) { + $code .= $this->addInlineReference($id, $definition, $this->container->normalizeId($argument), $forConstructor); + } elseif ($argument instanceof Definition) { + $code .= $this->addInlineService($id, $definition, $argument, $forConstructor); + } + } + + return $code; + } + + private function addInlineReference($id, Definition $definition, $targetId, $forConstructor) + { + while ($this->container->hasAlias($targetId)) { + $targetId = (string) $this->container->getAlias($targetId); + } + + list($callCount, $behavior) = $this->serviceCalls[$targetId]; + + if ($id === $targetId) { + return $this->addInlineService($id, $definition, $definition); + } + + if ('service_container' === $targetId || isset($this->referenceVariables[$targetId])) { + return ''; + } + + $hasSelfRef = isset($this->circularReferences[$id][$targetId]) && !isset($this->definitionVariables[$definition]); + + if ($hasSelfRef && !$forConstructor && !$forConstructor = !$this->circularReferences[$id][$targetId]) { + $code = $this->addInlineService($id, $definition, $definition); + } else { + $code = ''; + } + + if (isset($this->referenceVariables[$targetId]) || (2 > $callCount && (!$hasSelfRef || !$forConstructor))) { + return $code; + } + + $name = $this->getNextVariableName(); + $this->referenceVariables[$targetId] = new Variable($name); + + $reference = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE >= $behavior ? new Reference($targetId, $behavior) : null; + $code .= sprintf(" \$%s = %s;\n", $name, $this->getServiceCall($targetId, $reference)); + + if (!$hasSelfRef || !$forConstructor) { + return $code; + } + + $code .= sprintf(<<<'EOTXT' + + if (isset($this->%s[%s])) { + return $this->%1$s[%2$s]; + } + +EOTXT + , + 'services', + $this->doExport($id) + ); + + return $code; + } + + private function addInlineService($id, Definition $definition, Definition $inlineDef = null, $forConstructor = true) + { + $code = ''; + + if ($isSimpleInstance = $isRootInstance = null === $inlineDef) { + foreach ($this->serviceCalls as $targetId => list($callCount, $behavior, $byConstructor)) { + if ($byConstructor && isset($this->circularReferences[$id][$targetId]) && !$this->circularReferences[$id][$targetId]) { + $code .= $this->addInlineReference($id, $definition, $targetId, $forConstructor); + } + } + } + + if (isset($this->definitionVariables[$inlineDef = $inlineDef ?: $definition])) { + return $code; + } + + $arguments = [$inlineDef->getArguments(), $inlineDef->getFactory()]; + + $code .= $this->addInlineVariables($id, $definition, $arguments, $forConstructor); + + if ($arguments = array_filter([$inlineDef->getProperties(), $inlineDef->getMethodCalls(), $inlineDef->getConfigurator()])) { + $isSimpleInstance = false; + } elseif ($definition !== $inlineDef && 2 > $this->inlinedDefinitions[$inlineDef]) { + return $code; + } + + if (isset($this->definitionVariables[$inlineDef])) { + $isSimpleInstance = false; + } else { + $name = $definition === $inlineDef ? 'instance' : $this->getNextVariableName(); + $this->definitionVariables[$inlineDef] = new Variable($name); + $code .= '' !== $code ? "\n" : ''; + + if ('instance' === $name) { + $code .= $this->addServiceInstance($id, $definition, $isSimpleInstance); + } else { + $code .= $this->addNewInstance($inlineDef, '$'.$name, ' = ', $id); + } + + if ('' !== $inline = $this->addInlineVariables($id, $definition, $arguments, false)) { + $code .= "\n".$inline."\n"; + } elseif ($arguments && 'instance' === $name) { + $code .= "\n"; + } + + $code .= $this->addServiceProperties($inlineDef, $name); + $code .= $this->addServiceMethodCalls($inlineDef, $name); + $code .= $this->addServiceConfigurator($inlineDef, $name); + } + + if ($isRootInstance && !$isSimpleInstance) { + $code .= "\n return \$instance;\n"; + } + + return $code; + } + + /** + * Adds multiple services. + * + * @return string + */ + private function addServices() + { + $publicServices = $privateServices = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if ($definition->isSynthetic() || ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition))) { + continue; + } + if ($definition->isPublic()) { + $publicServices .= $this->addService($id, $definition); + } else { + $privateServices .= $this->addService($id, $definition); + } + } + + return $publicServices.$privateServices; + } + + private function generateServiceFiles() + { + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) { + $code = $this->addService($id, $definition, $file); + yield $file => $code; + } + } + } + + private function addNewInstance(Definition $definition, $return, $instantiation, $id) + { + $class = $this->dumpValue($definition->getClass()); + $return = ' '.$return.$instantiation; + + $arguments = []; + foreach ($definition->getArguments() as $value) { + $arguments[] = $this->dumpValue($value); + } + + if (null !== $definition->getFactory()) { + $callable = $definition->getFactory(); + if (\is_array($callable)) { + if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $callable[1])) { + throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s).', $callable[1] ?: 'n/a')); + } + + if ($callable[0] instanceof Reference + || ($callable[0] instanceof Definition && $this->definitionVariables->contains($callable[0]))) { + return $return.sprintf("%s->%s(%s);\n", $this->dumpValue($callable[0]), $callable[1], $arguments ? implode(', ', $arguments) : ''); + } + + $class = $this->dumpValue($callable[0]); + // If the class is a string we can optimize call_user_func away + if (0 === strpos($class, "'") && false === strpos($class, '$')) { + if ("''" === $class) { + throw new RuntimeException(sprintf('Cannot dump definition: The "%s" service is defined to be created by a factory but is missing the service reference, did you forget to define the factory service id or class?', $id)); + } + + return $return.sprintf("%s::%s(%s);\n", $this->dumpLiteralClass($class), $callable[1], $arguments ? implode(', ', $arguments) : ''); + } + + if (0 === strpos($class, 'new ')) { + return $return.sprintf("(%s)->%s(%s);\n", $class, $callable[1], $arguments ? implode(', ', $arguments) : ''); + } + + return $return.sprintf("\\call_user_func([%s, '%s']%s);\n", $class, $callable[1], $arguments ? ', '.implode(', ', $arguments) : ''); + } + + return $return.sprintf("%s(%s);\n", $this->dumpLiteralClass($this->dumpValue($callable)), $arguments ? implode(', ', $arguments) : ''); + } + + if (false !== strpos($class, '$')) { + return sprintf(" \$class = %s;\n\n%snew \$class(%s);\n", $class, $return, implode(', ', $arguments)); + } + + return $return.sprintf("new %s(%s);\n", $this->dumpLiteralClass($class), implode(', ', $arguments)); + } + + /** + * Adds the class headers. + * + * @param string $class Class name + * @param string $baseClass The name of the base class + * @param string $baseClassWithNamespace Fully qualified base class name + * + * @return string + */ + private function startClass($class, $baseClass, $baseClassWithNamespace) + { + $bagClass = $this->container->isCompiled() ? 'use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;' : 'use Symfony\Component\DependencyInjection\ParameterBag\\ParameterBag;'; + $namespaceLine = !$this->asFiles && $this->namespace ? "\nnamespace {$this->namespace};\n" : ''; + + $code = <<docStar} + * This class has been auto-generated + * by the Symfony Dependency Injection Component. + * + * @final since Symfony 3.3 + */ +class $class extends $baseClass +{ + private \$parameters = []; + private \$targetDirs = []; + + public function __construct() + { + +EOF; + if (null !== $this->targetDirRegex) { + $dir = $this->asFiles ? '$this->targetDirs[0] = \\dirname($containerDir)' : '__DIR__'; + $code .= <<targetDirMaxMatches}; ++\$i) { + \$this->targetDirs[\$i] = \$dir = \\dirname(\$dir); + } + +EOF; + } + if ($this->asFiles) { + $code = str_replace('$parameters', "\$buildParameters;\n private \$containerDir;\n private \$parameters", $code); + $code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code); + $code .= " \$this->buildParameters = \$buildParameters;\n"; + $code .= " \$this->containerDir = \$containerDir;\n"; + } + + if ($this->container->isCompiled()) { + if (Container::class !== $baseClassWithNamespace) { + $r = $this->container->getReflectionClass($baseClassWithNamespace, false); + if (null !== $r + && (null !== $constructor = $r->getConstructor()) + && 0 === $constructor->getNumberOfRequiredParameters() + && Container::class !== $constructor->getDeclaringClass()->name + ) { + $code .= " parent::__construct();\n"; + $code .= " \$this->parameterBag = null;\n\n"; + } + } + + if ($this->container->getParameterBag()->all()) { + $code .= " \$this->parameters = \$this->getDefaultParameters();\n\n"; + } + + $code .= " \$this->services = [];\n"; + } else { + $arguments = $this->container->getParameterBag()->all() ? 'new ParameterBag($this->getDefaultParameters())' : null; + $code .= " parent::__construct($arguments);\n"; + } + + $code .= $this->addNormalizedIds(); + $code .= $this->addSyntheticIds(); + $code .= $this->addMethodMap(); + $code .= $this->asFiles ? $this->addFileMap() : ''; + $code .= $this->addPrivateServices(); + $code .= $this->addAliases(); + $code .= $this->addInlineRequires(); + $code .= <<<'EOF' + } + +EOF; + $code .= $this->addRemovedIds(); + + if ($this->container->isCompiled()) { + $code .= <<asFiles) { + $code .= <<containerDir.\\DIRECTORY_SEPARATOR.\$file; + } + +EOF; + } + + $proxyDumper = $this->getProxyDumper(); + foreach ($this->container->getDefinitions() as $definition) { + if (!$proxyDumper->isProxyCandidate($definition)) { + continue; + } + if ($this->asFiles) { + $proxyLoader = '$this->load("{$class}.php")'; + } elseif ($this->namespace) { + $proxyLoader = 'class_alias("'.$this->namespace.'\\\\{$class}", $class, false)'; + } else { + $proxyLoader = ''; + } + if ($proxyLoader) { + $proxyLoader = "class_exists(\$class, false) || {$proxyLoader};\n\n "; + } + $code .= <<container->getNormalizedIds(); + ksort($normalizedIds); + foreach ($normalizedIds as $id => $normalizedId) { + if ($this->container->has($normalizedId)) { + $code .= ' '.$this->doExport($id).' => '.$this->doExport($normalizedId).",\n"; + } + } + + return $code ? " \$this->normalizedIds = [\n".$code." ];\n" : ''; + } + + /** + * Adds the syntheticIds definition. + * + * @return string + */ + private function addSyntheticIds() + { + $code = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if ($definition->isSynthetic() && 'service_container' !== $id) { + $code .= ' '.$this->doExport($id)." => true,\n"; + } + } + + return $code ? " \$this->syntheticIds = [\n{$code} ];\n" : ''; + } + + /** + * Adds the removedIds definition. + * + * @return string + */ + private function addRemovedIds() + { + if (!$ids = $this->container->getRemovedIds()) { + return ''; + } + if ($this->asFiles) { + $code = "require \$this->containerDir.\\DIRECTORY_SEPARATOR.'removed-ids.php'"; + } else { + $code = ''; + $ids = array_keys($ids); + sort($ids); + foreach ($ids as $id) { + if (preg_match('/^\d+_[^~]++~[._a-zA-Z\d]{7}$/', $id)) { + continue; + } + $code .= ' '.$this->doExport($id)." => true,\n"; + } + + $code = "[\n{$code} ]"; + } + + return <<container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && (!$this->asFiles || !$definition->isShared() || $this->isHotPath($definition))) { + $code .= ' '.$this->doExport($id).' => '.$this->doExport($this->generateMethodName($id)).",\n"; + } + } + + return $code ? " \$this->methodMap = [\n{$code} ];\n" : ''; + } + + /** + * Adds the fileMap property definition. + * + * @return string + */ + private function addFileMap() + { + $code = ''; + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isSynthetic() && $definition->isShared() && !$this->isHotPath($definition)) { + $code .= sprintf(" %s => '%s.php',\n", $this->doExport($id), $this->generateMethodName($id)); + } + } + + return $code ? " \$this->fileMap = [\n{$code} ];\n" : ''; + } + + /** + * Adds the privates property definition. + * + * @return string + */ + private function addPrivateServices() + { + $code = ''; + + $aliases = $this->container->getAliases(); + ksort($aliases); + foreach ($aliases as $id => $alias) { + if ($alias->isPrivate()) { + $code .= ' '.$this->doExport($id)." => true,\n"; + } + } + + $definitions = $this->container->getDefinitions(); + ksort($definitions); + foreach ($definitions as $id => $definition) { + if (!$definition->isPublic()) { + $code .= ' '.$this->doExport($id)." => true,\n"; + } + } + + if (empty($code)) { + return ''; + } + + $out = " \$this->privates = [\n"; + $out .= $code; + $out .= " ];\n"; + + return $out; + } + + /** + * Adds the aliases property definition. + * + * @return string + */ + private function addAliases() + { + if (!$aliases = $this->container->getAliases()) { + return $this->container->isCompiled() ? "\n \$this->aliases = [];\n" : ''; + } + + $code = " \$this->aliases = [\n"; + ksort($aliases); + foreach ($aliases as $alias => $id) { + $id = $this->container->normalizeId($id); + while (isset($aliases[$id])) { + $id = $this->container->normalizeId($aliases[$id]); + } + $code .= ' '.$this->doExport($alias).' => '.$this->doExport($id).",\n"; + } + + return $code." ];\n"; + } + + private function addInlineRequires() + { + if (!$this->hotPathTag || !$this->inlineRequires) { + return ''; + } + + $lineage = []; + + foreach ($this->container->findTaggedServiceIds($this->hotPathTag) as $id => $tags) { + $definition = $this->container->getDefinition($id); + $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]); + + foreach ($inlinedDefinitions as $def) { + if (\is_string($class = \is_array($factory = $def->getFactory()) && \is_string($factory[0]) ? $factory[0] : $def->getClass())) { + $this->collectLineage($class, $lineage); + } + } + } + + $code = ''; + + foreach ($lineage as $file) { + if (!isset($this->inlinedRequires[$file])) { + $this->inlinedRequires[$file] = true; + $code .= sprintf("\n include_once %s;", $file); + } + } + + return $code ? sprintf("\n \$this->privates['service_container'] = function () {%s\n };\n", $code) : ''; + } + + /** + * Adds default parameters method. + * + * @return string + */ + private function addDefaultParametersMethod() + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + + $php = []; + $dynamicPhp = []; + $normalizedParams = []; + + foreach ($this->container->getParameterBag()->all() as $key => $value) { + if ($key !== $resolvedKey = $this->container->resolveEnvPlaceholders($key)) { + throw new InvalidArgumentException(sprintf('Parameter name cannot use env parameters: "%s".', $resolvedKey)); + } + if ($key !== $lcKey = strtolower($key)) { + $normalizedParams[] = sprintf(' %s => %s,', $this->export($lcKey), $this->export($key)); + } + $export = $this->exportParameters([$value]); + $export = explode('0 => ', substr(rtrim($export, " ]\n"), 2, -1), 2); + + if (preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $export[1])) { + $dynamicPhp[$key] = sprintf('%scase %s: $value = %s; break;', $export[0], $this->export($key), $export[1]); + } else { + $php[] = sprintf('%s%s => %s,', $export[0], $this->export($key), $export[1]); + } + } + + $parameters = sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', 8)); + + $code = ''; + if ($this->container->isCompiled()) { + $code .= <<<'EOF' + + public function getParameter($name) + { + $name = (string) $name; + if (isset($this->buildParameters[$name])) { + return $this->buildParameters[$name]; + } + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + if (isset($this->buildParameters[$name])) { + return true; + } + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + foreach ($this->buildParameters as $name => $value) { + $parameters[$name] = $value; + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + +EOF; + if (!$this->asFiles) { + $code = preg_replace('/^.*buildParameters.*\n.*\n.*\n/m', '', $code); + } + + if ($dynamicPhp) { + $loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, \count($dynamicPhp), false)), '', 8); + $getDynamicParameter = <<<'EOF' + switch ($name) { +%s + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; +EOF; + $getDynamicParameter = sprintf($getDynamicParameter, implode("\n", $dynamicPhp)); + } else { + $loadedDynamicParameters = '[]'; + $getDynamicParameter = str_repeat(' ', 8).'throw new InvalidArgumentException(sprintf(\'The dynamic parameter "%s" must be defined.\', $name));'; + } + + $code .= <<docStar} + * Computes a dynamic parameter. + * + * @param string \$name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter(\$name) + { +{$getDynamicParameter} + } + + +EOF; + + $code .= ' private $normalizedParameterNames = '.($normalizedParams ? sprintf("[\n%s\n ];", implode("\n", $normalizedParams)) : '[];')."\n"; + $code .= <<<'EOF' + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + +EOF; + } elseif ($dynamicPhp) { + throw new RuntimeException('You cannot dump a not-frozen container with dynamic parameters.'); + } + + $code .= <<docStar} + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return $parameters; + } + +EOF; + + return $code; + } + + /** + * Exports parameters. + * + * @param string $path + * @param int $indent + * + * @return string + * + * @throws InvalidArgumentException + */ + private function exportParameters(array $parameters, $path = '', $indent = 12) + { + $php = []; + foreach ($parameters as $key => $value) { + if (\is_array($value)) { + $value = $this->exportParameters($value, $path.'/'.$key, $indent + 4); + } elseif ($value instanceof ArgumentInterface) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain special arguments. "%s" found in "%s".', \get_class($value), $path.'/'.$key)); + } elseif ($value instanceof Variable) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain variable references. Variable "%s" found in "%s".', $value, $path.'/'.$key)); + } elseif ($value instanceof Definition) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain service definitions. Definition for "%s" found in "%s".', $value->getClass(), $path.'/'.$key)); + } elseif ($value instanceof Reference) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain references to other services (reference to service "%s" found in "%s").', $value, $path.'/'.$key)); + } elseif ($value instanceof Expression) { + throw new InvalidArgumentException(sprintf('You cannot dump a container with parameters that contain expressions. Expression "%s" found in "%s".', $value, $path.'/'.$key)); + } else { + $value = $this->export($value); + } + + $php[] = sprintf('%s%s => %s,', str_repeat(' ', $indent), $this->export($key), $value); + } + + return sprintf("[\n%s\n%s]", implode("\n", $php), str_repeat(' ', $indent - 4)); + } + + /** + * Ends the class definition. + * + * @return string + */ + private function endClass() + { + return <<<'EOF' +} + +EOF; + } + + /** + * Wraps the service conditionals. + * + * @param string $value + * @param string $code + * + * @return string + */ + private function wrapServiceConditionals($value, $code) + { + if (!$condition = $this->getServiceConditionals($value)) { + return $code; + } + + // re-indent the wrapped code + $code = implode("\n", array_map(function ($line) { return $line ? ' '.$line : $line; }, explode("\n", $code))); + + return sprintf(" if (%s) {\n%s }\n", $condition, $code); + } + + /** + * Get the conditions to execute for conditional services. + * + * @param string $value + * + * @return string|null + */ + private function getServiceConditionals($value) + { + $conditions = []; + foreach (ContainerBuilder::getInitializedConditionals($value) as $service) { + if (!$this->container->hasDefinition($service)) { + return 'false'; + } + $conditions[] = sprintf('isset($this->services[%s])', $this->doExport($service)); + } + foreach (ContainerBuilder::getServiceConditionals($value) as $service) { + if ($this->container->hasDefinition($service) && !$this->container->getDefinition($service)->isPublic()) { + continue; + } + + $conditions[] = sprintf('$this->has(%s)', $this->doExport($service)); + } + + if (!$conditions) { + return ''; + } + + return implode(' && ', $conditions); + } + + private function getDefinitionsFromArguments(array $arguments, \SplObjectStorage $definitions = null, array &$calls = [], $byConstructor = null) + { + if (null === $definitions) { + $definitions = new \SplObjectStorage(); + } + + foreach ($arguments as $argument) { + if (\is_array($argument)) { + $this->getDefinitionsFromArguments($argument, $definitions, $calls, $byConstructor); + } elseif ($argument instanceof Reference) { + $id = $this->container->normalizeId($argument); + + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if (!isset($calls[$id])) { + $calls[$id] = [0, $argument->getInvalidBehavior(), $byConstructor]; + } else { + $calls[$id][1] = min($calls[$id][1], $argument->getInvalidBehavior()); + } + + ++$calls[$id][0]; + } elseif (!$argument instanceof Definition) { + // no-op + } elseif (isset($definitions[$argument])) { + $definitions[$argument] = 1 + $definitions[$argument]; + } else { + $definitions[$argument] = 1; + $arguments = [$argument->getArguments(), $argument->getFactory()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null === $byConstructor || $byConstructor); + $arguments = [$argument->getProperties(), $argument->getMethodCalls(), $argument->getConfigurator()]; + $this->getDefinitionsFromArguments($arguments, $definitions, $calls, null !== $byConstructor && $byConstructor); + } + } + + return $definitions; + } + + /** + * Dumps values. + * + * @param mixed $value + * @param bool $interpolate + * + * @return string + * + * @throws RuntimeException + */ + private function dumpValue($value, $interpolate = true) + { + if (\is_array($value)) { + if ($value && $interpolate && false !== $param = array_search($value, $this->container->getParameterBag()->all(), true)) { + return $this->dumpValue("%$param%"); + } + $code = []; + foreach ($value as $k => $v) { + $code[] = sprintf('%s => %s', $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate)); + } + + return sprintf('[%s]', implode(', ', $code)); + } elseif ($value instanceof ArgumentInterface) { + $scope = [$this->definitionVariables, $this->referenceVariables]; + $this->definitionVariables = $this->referenceVariables = null; + + try { + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + $code = $this->dumpValue($value, $interpolate); + + if ($value instanceof TypedReference) { + $code = sprintf('$f = function (\\%s $v%s) { return $v; }; return $f(%s);', $value->getType(), ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $value->getInvalidBehavior() ? ' = null' : '', $code); + } else { + $code = sprintf('return %s;', $code); + } + + return sprintf("function () {\n %s\n }", $code); + } + + if ($value instanceof IteratorArgument) { + $operands = [0]; + $code = []; + $code[] = 'new RewindableGenerator(function () {'; + + if (!$values = $value->getValues()) { + $code[] = ' return new \EmptyIterator();'; + } else { + $countCode = []; + $countCode[] = 'function () {'; + + foreach ($values as $k => $v) { + ($c = $this->getServiceConditionals($v)) ? $operands[] = "(int) ($c)" : ++$operands[0]; + $v = $this->wrapServiceConditionals($v, sprintf(" yield %s => %s;\n", $this->dumpValue($k, $interpolate), $this->dumpValue($v, $interpolate))); + foreach (explode("\n", $v) as $v) { + if ($v) { + $code[] = ' '.$v; + } + } + } + + $countCode[] = sprintf(' return %s;', implode(' + ', $operands)); + $countCode[] = ' }'; + } + + $code[] = sprintf(' }, %s)', \count($operands) > 1 ? implode("\n", $countCode) : $operands[0]); + + return implode("\n", $code); + } + } finally { + list($this->definitionVariables, $this->referenceVariables) = $scope; + } + } elseif ($value instanceof Definition) { + if (null !== $this->definitionVariables && $this->definitionVariables->contains($value)) { + return $this->dumpValue($this->definitionVariables[$value], $interpolate); + } + if ($value->getMethodCalls()) { + throw new RuntimeException('Cannot dump definitions which have method calls.'); + } + if ($value->getProperties()) { + throw new RuntimeException('Cannot dump definitions which have properties.'); + } + if (null !== $value->getConfigurator()) { + throw new RuntimeException('Cannot dump definitions which have a configurator.'); + } + + $arguments = []; + foreach ($value->getArguments() as $argument) { + $arguments[] = $this->dumpValue($argument); + } + + if (null !== $value->getFactory()) { + $factory = $value->getFactory(); + + if (\is_string($factory)) { + return sprintf('%s(%s)', $this->dumpLiteralClass($this->dumpValue($factory)), implode(', ', $arguments)); + } + + if (\is_array($factory)) { + if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $factory[1])) { + throw new RuntimeException(sprintf('Cannot dump definition because of invalid factory method (%s).', $factory[1] ?: 'n/a')); + } + + $class = $this->dumpValue($factory[0]); + if (\is_string($factory[0])) { + return sprintf('%s::%s(%s)', $this->dumpLiteralClass($class), $factory[1], implode(', ', $arguments)); + } + + if ($factory[0] instanceof Definition) { + if (0 === strpos($class, 'new ')) { + return sprintf('(%s)->%s(%s)', $class, $factory[1], implode(', ', $arguments)); + } + + return sprintf("\\call_user_func([%s, '%s']%s)", $class, $factory[1], \count($arguments) > 0 ? ', '.implode(', ', $arguments) : ''); + } + + if ($factory[0] instanceof Reference) { + return sprintf('%s->%s(%s)', $class, $factory[1], implode(', ', $arguments)); + } + } + + throw new RuntimeException('Cannot dump definition because of invalid factory.'); + } + + $class = $value->getClass(); + if (null === $class) { + throw new RuntimeException('Cannot dump definitions which have no class nor factory.'); + } + + return sprintf('new %s(%s)', $this->dumpLiteralClass($this->dumpValue($class)), implode(', ', $arguments)); + } elseif ($value instanceof Variable) { + return '$'.$value; + } elseif ($value instanceof Reference) { + $id = $this->container->normalizeId($value); + + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + + if (null !== $this->referenceVariables && isset($this->referenceVariables[$id])) { + return $this->dumpValue($this->referenceVariables[$id], $interpolate); + } + + return $this->getServiceCall($id, $value); + } elseif ($value instanceof Expression) { + return $this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']); + } elseif ($value instanceof Parameter) { + return $this->dumpParameter($value); + } elseif (true === $interpolate && \is_string($value)) { + if (preg_match('/^%([^%]+)%$/', $value, $match)) { + // we do this to deal with non string values (Boolean, integer, ...) + // the preg_replace_callback converts them to strings + return $this->dumpParameter($match[1]); + } else { + $replaceParameters = function ($match) { + return "'.".$this->dumpParameter($match[2]).".'"; + }; + + $code = str_replace('%%', '%', preg_replace_callback('/(?export($value))); + + return $code; + } + } elseif (\is_object($value) || \is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + + return $this->export($value); + } + + /** + * Dumps a string to a literal (aka PHP Code) class value. + * + * @param string $class + * + * @return string + * + * @throws RuntimeException + */ + private function dumpLiteralClass($class) + { + if (false !== strpos($class, '$')) { + return sprintf('${($_ = %s) && false ?: "_"}', $class); + } + if (0 !== strpos($class, "'") || !preg_match('/^\'(?:\\\{2})?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(?:\\\{2}[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*\'$/', $class)) { + throw new RuntimeException(sprintf('Cannot dump definition because of invalid class name (%s).', $class ?: 'n/a')); + } + + $class = substr(str_replace('\\\\', '\\', $class), 1, -1); + + return 0 === strpos($class, '\\') ? $class : '\\'.$class; + } + + /** + * Dumps a parameter. + * + * @param string $name + * + * @return string + */ + private function dumpParameter($name) + { + $name = (string) $name; + + if ($this->container->isCompiled() && $this->container->hasParameter($name)) { + $value = $this->container->getParameter($name); + $dumpedValue = $this->dumpValue($value, false); + + if (!$value || !\is_array($value)) { + return $dumpedValue; + } + + if (!preg_match("/\\\$this->(?:getEnv\('(?:\w++:)*+\w++'\)|targetDirs\[\d++\])/", $dumpedValue)) { + return sprintf('$this->parameters[%s]', $this->doExport($name)); + } + } + + return sprintf('$this->getParameter(%s)', $this->doExport($name)); + } + + /** + * Gets a service call. + * + * @param string $id + * @param Reference $reference + * + * @return string + */ + private function getServiceCall($id, Reference $reference = null) + { + while ($this->container->hasAlias($id)) { + $id = (string) $this->container->getAlias($id); + } + $id = $this->container->normalizeId($id); + + if ('service_container' === $id) { + return '$this'; + } + + if ($this->container->hasDefinition($id) && $definition = $this->container->getDefinition($id)) { + if ($definition->isSynthetic()) { + $code = sprintf('$this->get(%s%s)', $this->doExport($id), null !== $reference ? ', '.$reference->getInvalidBehavior() : ''); + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + $code = 'null'; + if (!$definition->isShared()) { + return $code; + } + } elseif ($this->isTrivialInstance($definition)) { + $code = substr($this->addNewInstance($definition, '', '', $id), 8, -2); + if ($definition->isShared()) { + $code = sprintf('$this->services[%s] = %s', $this->doExport($id), $code); + } + $code = "($code)"; + } elseif ($this->asFiles && $definition->isShared() && !$this->isHotPath($definition)) { + $code = sprintf("\$this->load('%s.php')", $this->generateMethodName($id)); + } else { + $code = sprintf('$this->%s()', $this->generateMethodName($id)); + } + } elseif (null !== $reference && ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $reference->getInvalidBehavior()) { + return 'null'; + } elseif (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) { + $code = sprintf('$this->get(%s, /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ %d)', $this->doExport($id), ContainerInterface::NULL_ON_INVALID_REFERENCE); + } else { + $code = sprintf('$this->get(%s)', $this->doExport($id)); + } + + // The following is PHP 5.5 syntax for what could be written as "(\$this->services['$id'] ?? $code)" on PHP>=7.0 + + return sprintf("\${(\$_ = isset(\$this->services[%s]) ? \$this->services[%1\$s] : %s) && false ?: '_'}", $this->doExport($id), $code); + } + + /** + * Initializes the method names map to avoid conflicts with the Container methods. + * + * @param string $class the container base class + */ + private function initializeMethodNamesMap($class) + { + $this->serviceIdToMethodNameMap = []; + $this->usedMethodNames = []; + + if ($reflectionClass = $this->container->getReflectionClass($class)) { + foreach ($reflectionClass->getMethods() as $method) { + $this->usedMethodNames[strtolower($method->getName())] = true; + } + } + } + + /** + * Convert a service id to a valid PHP method name. + * + * @param string $id + * + * @return string + * + * @throws InvalidArgumentException + */ + private function generateMethodName($id) + { + if (isset($this->serviceIdToMethodNameMap[$id])) { + return $this->serviceIdToMethodNameMap[$id]; + } + + $i = strrpos($id, '\\'); + $name = Container::camelize(false !== $i && isset($id[1 + $i]) ? substr($id, 1 + $i) : $id); + $name = preg_replace('/[^a-zA-Z0-9_\x7f-\xff]/', '', $name); + $methodName = 'get'.$name.'Service'; + $suffix = 1; + + while (isset($this->usedMethodNames[strtolower($methodName)])) { + ++$suffix; + $methodName = 'get'.$name.$suffix.'Service'; + } + + $this->serviceIdToMethodNameMap[$id] = $methodName; + $this->usedMethodNames[strtolower($methodName)] = true; + + return $methodName; + } + + /** + * Returns the next name to use. + * + * @return string + */ + private function getNextVariableName() + { + $firstChars = self::FIRST_CHARS; + $firstCharsLength = \strlen($firstChars); + $nonFirstChars = self::NON_FIRST_CHARS; + $nonFirstCharsLength = \strlen($nonFirstChars); + + while (true) { + $name = ''; + $i = $this->variableCount; + + if ('' === $name) { + $name .= $firstChars[$i % $firstCharsLength]; + $i = (int) ($i / $firstCharsLength); + } + + while ($i > 0) { + --$i; + $name .= $nonFirstChars[$i % $nonFirstCharsLength]; + $i = (int) ($i / $nonFirstCharsLength); + } + + ++$this->variableCount; + + // check that the name is not reserved + if (\in_array($name, $this->reservedVariables, true)) { + continue; + } + + return $name; + } + } + + private function getExpressionLanguage() + { + if (null === $this->expressionLanguage) { + if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { + throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); + } + $providers = $this->container->getExpressionLanguageProviders(); + $this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) { + $id = '""' === substr_replace($arg, '', 1, -1) ? stripcslashes(substr($arg, 1, -1)) : null; + + if (null !== $id && ($this->container->hasAlias($id) || $this->container->hasDefinition($id))) { + return $this->getServiceCall($id); + } + + return sprintf('$this->get(%s)', $arg); + }); + + if ($this->container->isTrackingResources()) { + foreach ($providers as $provider) { + $this->container->addObjectResource($provider); + } + } + } + + return $this->expressionLanguage; + } + + private function isHotPath(Definition $definition) + { + return $this->hotPathTag && $definition->hasTag($this->hotPathTag) && !$definition->isDeprecated(); + } + + private function export($value) + { + if (null !== $this->targetDirRegex && \is_string($value) && preg_match($this->targetDirRegex, $value, $matches, \PREG_OFFSET_CAPTURE)) { + $suffix = $matches[0][1] + \strlen($matches[0][0]); + $matches[0][1] += \strlen($matches[1][0]); + $prefix = $matches[0][1] ? $this->doExport(substr($value, 0, $matches[0][1]), true).'.' : ''; + $suffix = isset($value[$suffix]) ? '.'.$this->doExport(substr($value, $suffix), true) : ''; + $dirname = $this->asFiles ? '$this->containerDir' : '__DIR__'; + $offset = 2 + $this->targetDirMaxMatches - \count($matches); + + if ($this->asFiles || 0 < $offset) { + $dirname = sprintf('$this->targetDirs[%d]', $offset); + } + + if ($prefix || $suffix) { + return sprintf('(%s%s%s)', $prefix, $dirname, $suffix); + } + + return $dirname; + } + + return $this->doExport($value, true); + } + + private function doExport($value, $resolveEnv = false) + { + if (\is_string($value) && false !== strpos($value, "\n")) { + $cleanParts = explode("\n", $value); + $cleanParts = array_map(function ($part) { return var_export($part, true); }, $cleanParts); + $export = implode('."\n".', $cleanParts); + } else { + $export = var_export($value, true); + } + + if ($resolveEnv && "'" === $export[0] && $export !== $resolvedExport = $this->container->resolveEnvPlaceholders($export, "'.\$this->getEnv('string:%s').'")) { + $export = $resolvedExport; + if (".''" === substr($export, -3)) { + $export = substr($export, 0, -3); + if ("'" === $export[1]) { + $export = substr_replace($export, '', 18, 7); + } + } + if ("'" === $export[1]) { + $export = substr($export, 3); + } + } + + return $export; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/XmlDumper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/XmlDumper.php new file mode 100644 index 00000000..eff421ec --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/XmlDumper.php @@ -0,0 +1,366 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * XmlDumper dumps a service container as an XML string. + * + * @author Fabien Potencier + * @author Martin Hasoň + */ +class XmlDumper extends Dumper +{ + /** + * @var \DOMDocument + */ + private $document; + + /** + * Dumps the service container as an XML string. + * + * @return string An xml string representing of the service container + */ + public function dump(array $options = []) + { + $this->document = new \DOMDocument('1.0', 'utf-8'); + $this->document->formatOutput = true; + + $container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container'); + $container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); + $container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd'); + + $this->addParameters($container); + $this->addServices($container); + + $this->document->appendChild($container); + $xml = $this->document->saveXML(); + $this->document = null; + + return $this->container->resolveEnvPlaceholders($xml); + } + + private function addParameters(\DOMElement $parent) + { + $data = $this->container->getParameterBag()->all(); + if (!$data) { + return; + } + + if ($this->container->isCompiled()) { + $data = $this->escape($data); + } + + $parameters = $this->document->createElement('parameters'); + $parent->appendChild($parameters); + $this->convertParameters($data, 'parameter', $parameters); + } + + private function addMethodCalls(array $methodcalls, \DOMElement $parent) + { + foreach ($methodcalls as $methodcall) { + $call = $this->document->createElement('call'); + $call->setAttribute('method', $methodcall[0]); + if (\count($methodcall[1])) { + $this->convertParameters($methodcall[1], 'argument', $call); + } + $parent->appendChild($call); + } + } + + /** + * Adds a service. + * + * @param Definition $definition + * @param string $id + */ + private function addService($definition, $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + if (null !== $id) { + $service->setAttribute('id', $id); + } + if ($class = $definition->getClass()) { + if ('\\' === substr($class, 0, 1)) { + $class = substr($class, 1); + } + + $service->setAttribute('class', $class); + } + if (!$definition->isShared()) { + $service->setAttribute('shared', 'false'); + } + if (!$definition->isPrivate()) { + $service->setAttribute('public', $definition->isPublic() ? 'true' : 'false'); + } + if ($definition->isSynthetic()) { + $service->setAttribute('synthetic', 'true'); + } + if ($definition->isLazy()) { + $service->setAttribute('lazy', 'true'); + } + if (null !== $decorated = $definition->getDecoratedService()) { + list($decorated, $renamedId, $priority) = $decorated; + $service->setAttribute('decorates', $decorated); + if (null !== $renamedId) { + $service->setAttribute('decoration-inner-name', $renamedId); + } + if (0 !== $priority) { + $service->setAttribute('decoration-priority', $priority); + } + } + + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $tag = $this->document->createElement('tag'); + $tag->setAttribute('name', $name); + foreach ($attributes as $key => $value) { + $tag->setAttribute($key, $value); + } + $service->appendChild($tag); + } + } + + if ($definition->getFile()) { + $file = $this->document->createElement('file'); + $file->appendChild($this->document->createTextNode($definition->getFile())); + $service->appendChild($file); + } + + if ($parameters = $definition->getArguments()) { + $this->convertParameters($parameters, 'argument', $service); + } + + if ($parameters = $definition->getProperties()) { + $this->convertParameters($parameters, 'property', $service, 'name'); + } + + $this->addMethodCalls($definition->getMethodCalls(), $service); + + if ($callable = $definition->getFactory()) { + $factory = $this->document->createElement('factory'); + + if (\is_array($callable) && $callable[0] instanceof Definition) { + $this->addService($callable[0], null, $factory); + $factory->setAttribute('method', $callable[1]); + } elseif (\is_array($callable)) { + if (null !== $callable[0]) { + $factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]); + } + $factory->setAttribute('method', $callable[1]); + } else { + $factory->setAttribute('function', $callable); + } + $service->appendChild($factory); + } + + if ($definition->isDeprecated()) { + $deprecated = $this->document->createElement('deprecated'); + $deprecated->appendChild($this->document->createTextNode($definition->getDeprecationMessage('%service_id%'))); + + $service->appendChild($deprecated); + } + + if ($definition->isAutowired()) { + $service->setAttribute('autowire', 'true'); + } + + foreach ($definition->getAutowiringTypes(false) as $autowiringTypeValue) { + $autowiringType = $this->document->createElement('autowiring-type'); + $autowiringType->appendChild($this->document->createTextNode($autowiringTypeValue)); + + $service->appendChild($autowiringType); + } + + if ($definition->isAutoconfigured()) { + $service->setAttribute('autoconfigure', 'true'); + } + + if ($definition->isAbstract()) { + $service->setAttribute('abstract', 'true'); + } + + if ($callable = $definition->getConfigurator()) { + $configurator = $this->document->createElement('configurator'); + + if (\is_array($callable) && $callable[0] instanceof Definition) { + $this->addService($callable[0], null, $configurator); + $configurator->setAttribute('method', $callable[1]); + } elseif (\is_array($callable)) { + $configurator->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]); + $configurator->setAttribute('method', $callable[1]); + } else { + $configurator->setAttribute('function', $callable); + } + $service->appendChild($configurator); + } + + $parent->appendChild($service); + } + + /** + * Adds a service alias. + * + * @param string $alias + */ + private function addServiceAlias($alias, Alias $id, \DOMElement $parent) + { + $service = $this->document->createElement('service'); + $service->setAttribute('id', $alias); + $service->setAttribute('alias', $id); + if (!$id->isPrivate()) { + $service->setAttribute('public', $id->isPublic() ? 'true' : 'false'); + } + $parent->appendChild($service); + } + + private function addServices(\DOMElement $parent) + { + $definitions = $this->container->getDefinitions(); + if (!$definitions) { + return; + } + + $services = $this->document->createElement('services'); + foreach ($definitions as $id => $definition) { + $this->addService($definition, $id, $services); + } + + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + while (isset($aliases[(string) $id])) { + $id = $aliases[(string) $id]; + } + $this->addServiceAlias($alias, $id, $services); + } + $parent->appendChild($services); + } + + /** + * Converts parameters. + * + * @param string $type + * @param string $keyAttribute + */ + private function convertParameters(array $parameters, $type, \DOMElement $parent, $keyAttribute = 'key') + { + $withKeys = array_keys($parameters) !== range(0, \count($parameters) - 1); + foreach ($parameters as $key => $value) { + $element = $this->document->createElement($type); + if ($withKeys) { + $element->setAttribute($keyAttribute, $key); + } + + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + } + if (\is_array($value)) { + $element->setAttribute('type', 'collection'); + $this->convertParameters($value, $type, $element, 'key'); + } elseif ($value instanceof TaggedIteratorArgument) { + $element->setAttribute('type', 'tagged'); + $element->setAttribute('tag', $value->getTag()); + } elseif ($value instanceof IteratorArgument) { + $element->setAttribute('type', 'iterator'); + $this->convertParameters($value->getValues(), $type, $element, 'key'); + } elseif ($value instanceof Reference) { + $element->setAttribute('type', 'service'); + $element->setAttribute('id', (string) $value); + $behavior = $value->getInvalidBehavior(); + if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'null'); + } elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'ignore'); + } elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behavior) { + $element->setAttribute('on-invalid', 'ignore_uninitialized'); + } + } elseif ($value instanceof Definition) { + $element->setAttribute('type', 'service'); + $this->addService($value, null, $element); + } elseif ($value instanceof Expression) { + $element->setAttribute('type', 'expression'); + $text = $this->document->createTextNode(self::phpToXml((string) $value)); + $element->appendChild($text); + } else { + if (\in_array($value, ['null', 'true', 'false'], true)) { + $element->setAttribute('type', 'string'); + } + + if (\is_string($value) && (is_numeric($value) || preg_match('/^0b[01]*$/', $value) || preg_match('/^0x[0-9a-f]++$/i', $value))) { + $element->setAttribute('type', 'string'); + } + + $text = $this->document->createTextNode(self::phpToXml($value)); + $element->appendChild($text); + } + $parent->appendChild($element); + } + } + + /** + * Escapes arguments. + * + * @return array + */ + private function escape(array $arguments) + { + $args = []; + foreach ($arguments as $k => $v) { + if (\is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (\is_string($v)) { + $args[$k] = str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + + return $args; + } + + /** + * Converts php types to xml types. + * + * @param mixed $value Value to convert + * + * @return string + * + * @throws RuntimeException When trying to dump object or resource + */ + public static function phpToXml($value) + { + switch (true) { + case null === $value: + return 'null'; + case true === $value: + return 'true'; + case false === $value: + return 'false'; + case $value instanceof Parameter: + return '%'.$value.'%'; + case \is_object($value) || \is_resource($value): + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + default: + return (string) $value; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/YamlDumper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/YamlDumper.php new file mode 100644 index 00000000..1e795c7d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Dumper/YamlDumper.php @@ -0,0 +1,376 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Dumper; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\Yaml\Dumper as YmlDumper; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; + +/** + * YamlDumper dumps a service container as a YAML string. + * + * @author Fabien Potencier + */ +class YamlDumper extends Dumper +{ + private $dumper; + + /** + * Dumps the service container as an YAML string. + * + * @return string A YAML string representing of the service container + */ + public function dump(array $options = []) + { + if (!class_exists('Symfony\Component\Yaml\Dumper')) { + throw new RuntimeException('Unable to dump the container as the Symfony Yaml Component is not installed.'); + } + + if (null === $this->dumper) { + $this->dumper = new YmlDumper(); + } + + return $this->container->resolveEnvPlaceholders($this->addParameters()."\n".$this->addServices()); + } + + /** + * Adds a service. + * + * @param string $id + * + * @return string + */ + private function addService($id, Definition $definition) + { + $code = " $id:\n"; + if ($class = $definition->getClass()) { + if ('\\' === substr($class, 0, 1)) { + $class = substr($class, 1); + } + + $code .= sprintf(" class: %s\n", $this->dumper->dump($class)); + } + + if (!$definition->isPrivate()) { + $code .= sprintf(" public: %s\n", $definition->isPublic() ? 'true' : 'false'); + } + + $tagsCode = ''; + foreach ($definition->getTags() as $name => $tags) { + foreach ($tags as $attributes) { + $att = []; + foreach ($attributes as $key => $value) { + $att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value)); + } + $att = $att ? ', '.implode(', ', $att) : ''; + + $tagsCode .= sprintf(" - { name: %s%s }\n", $this->dumper->dump($name), $att); + } + } + if ($tagsCode) { + $code .= " tags:\n".$tagsCode; + } + + if ($definition->getFile()) { + $code .= sprintf(" file: %s\n", $this->dumper->dump($definition->getFile())); + } + + if ($definition->isSynthetic()) { + $code .= " synthetic: true\n"; + } + + if ($definition->isDeprecated()) { + $code .= sprintf(" deprecated: %s\n", $this->dumper->dump($definition->getDeprecationMessage('%service_id%'))); + } + + if ($definition->isAutowired()) { + $code .= " autowire: true\n"; + } + + $autowiringTypesCode = ''; + foreach ($definition->getAutowiringTypes(false) as $autowiringType) { + $autowiringTypesCode .= sprintf(" - %s\n", $this->dumper->dump($autowiringType)); + } + if ($autowiringTypesCode) { + $code .= sprintf(" autowiring_types:\n%s", $autowiringTypesCode); + } + + if ($definition->isAutoconfigured()) { + $code .= " autoconfigure: true\n"; + } + + if ($definition->isAbstract()) { + $code .= " abstract: true\n"; + } + + if ($definition->isLazy()) { + $code .= " lazy: true\n"; + } + + if ($definition->getArguments()) { + $code .= sprintf(" arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0)); + } + + if ($definition->getProperties()) { + $code .= sprintf(" properties: %s\n", $this->dumper->dump($this->dumpValue($definition->getProperties()), 0)); + } + + if ($definition->getMethodCalls()) { + $code .= sprintf(" calls:\n%s\n", $this->dumper->dump($this->dumpValue($definition->getMethodCalls()), 1, 12)); + } + + if (!$definition->isShared()) { + $code .= " shared: false\n"; + } + + if (null !== $decorated = $definition->getDecoratedService()) { + list($decorated, $renamedId, $priority) = $decorated; + $code .= sprintf(" decorates: %s\n", $decorated); + if (null !== $renamedId) { + $code .= sprintf(" decoration_inner_name: %s\n", $renamedId); + } + if (0 !== $priority) { + $code .= sprintf(" decoration_priority: %s\n", $priority); + } + } + + if ($callable = $definition->getFactory()) { + $code .= sprintf(" factory: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0)); + } + + if ($callable = $definition->getConfigurator()) { + $code .= sprintf(" configurator: %s\n", $this->dumper->dump($this->dumpCallable($callable), 0)); + } + + return $code; + } + + /** + * Adds a service alias. + * + * @param string $alias + * + * @return string + */ + private function addServiceAlias($alias, Alias $id) + { + if ($id->isPrivate()) { + return sprintf(" %s: '@%s'\n", $alias, $id); + } + + return sprintf(" %s:\n alias: %s\n public: %s\n", $alias, $id, $id->isPublic() ? 'true' : 'false'); + } + + /** + * Adds services. + * + * @return string + */ + private function addServices() + { + if (!$this->container->getDefinitions()) { + return ''; + } + + $code = "services:\n"; + foreach ($this->container->getDefinitions() as $id => $definition) { + $code .= $this->addService($id, $definition); + } + + $aliases = $this->container->getAliases(); + foreach ($aliases as $alias => $id) { + while (isset($aliases[(string) $id])) { + $id = $aliases[(string) $id]; + } + $code .= $this->addServiceAlias($alias, $id); + } + + return $code; + } + + /** + * Adds parameters. + * + * @return string + */ + private function addParameters() + { + if (!$this->container->getParameterBag()->all()) { + return ''; + } + + $parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isCompiled()); + + return $this->dumper->dump(['parameters' => $parameters], 2); + } + + /** + * Dumps callable to YAML format. + * + * @param mixed $callable + */ + private function dumpCallable($callable) + { + if (\is_array($callable)) { + if ($callable[0] instanceof Reference) { + $callable = [$this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]]; + } else { + $callable = [$callable[0], $callable[1]]; + } + } + + return $callable; + } + + /** + * Dumps the value to YAML format. + * + * @param mixed $value + * + * @return mixed + * + * @throws RuntimeException When trying to dump object or resource + */ + private function dumpValue($value) + { + if ($value instanceof ServiceClosureArgument) { + $value = $value->getValues()[0]; + } + if ($value instanceof ArgumentInterface) { + if ($value instanceof TaggedIteratorArgument) { + return new TaggedValue('tagged', $value->getTag()); + } + if ($value instanceof IteratorArgument) { + $tag = 'iterator'; + } else { + throw new RuntimeException(sprintf('Unspecified Yaml tag for type "%s".', \get_class($value))); + } + + return new TaggedValue($tag, $this->dumpValue($value->getValues())); + } + + if (\is_array($value)) { + $code = []; + foreach ($value as $k => $v) { + $code[$k] = $this->dumpValue($v); + } + + return $code; + } elseif ($value instanceof Reference) { + return $this->getServiceCall((string) $value, $value); + } elseif ($value instanceof Parameter) { + return $this->getParameterCall((string) $value); + } elseif ($value instanceof Expression) { + return $this->getExpressionCall((string) $value); + } elseif ($value instanceof Definition) { + return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']); + } elseif (\is_object($value) || \is_resource($value)) { + throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.'); + } + + return $value; + } + + /** + * Gets the service call. + * + * @param string $id + * @param Reference $reference + * + * @return string + */ + private function getServiceCall($id, Reference $reference = null) + { + if (null !== $reference) { + switch ($reference->getInvalidBehavior()) { + case ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE: break; + case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE: return sprintf('@!%s', $id); + default: return sprintf('@?%s', $id); + } + } + + return sprintf('@%s', $id); + } + + /** + * Gets parameter call. + * + * @param string $id + * + * @return string + */ + private function getParameterCall($id) + { + return sprintf('%%%s%%', $id); + } + + private function getExpressionCall($expression) + { + return sprintf('@=%s', $expression); + } + + /** + * Prepares parameters. + * + * @param bool $escape + * + * @return array + */ + private function prepareParameters(array $parameters, $escape = true) + { + $filtered = []; + foreach ($parameters as $key => $value) { + if (\is_array($value)) { + $value = $this->prepareParameters($value, $escape); + } elseif ($value instanceof Reference || \is_string($value) && 0 === strpos($value, '@')) { + $value = '@'.$value; + } + + $filtered[$key] = $value; + } + + return $escape ? $this->escape($filtered) : $filtered; + } + + /** + * Escapes arguments. + * + * @return array + */ + private function escape(array $arguments) + { + $args = []; + foreach ($arguments as $k => $v) { + if (\is_array($v)) { + $args[$k] = $this->escape($v); + } elseif (\is_string($v)) { + $args[$k] = str_replace('%', '%%', $v); + } else { + $args[$k] = $v; + } + } + + return $args; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/EnvVarProcessor.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/EnvVarProcessor.php new file mode 100644 index 00000000..065673dc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/EnvVarProcessor.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\Config\Util\XmlUtils; +use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * @author Nicolas Grekas + */ +class EnvVarProcessor implements EnvVarProcessorInterface +{ + private $container; + + public function __construct(ContainerInterface $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public static function getProvidedTypes() + { + return [ + 'base64' => 'string', + 'bool' => 'bool', + 'const' => 'bool|int|float|string|array', + 'file' => 'string', + 'float' => 'float', + 'int' => 'int', + 'json' => 'array', + 'resolve' => 'string', + 'string' => 'string', + ]; + } + + /** + * {@inheritdoc} + */ + public function getEnv($prefix, $name, \Closure $getEnv) + { + $i = strpos($name, ':'); + + if ('file' === $prefix) { + if (!is_scalar($file = $getEnv($name))) { + throw new RuntimeException(sprintf('Invalid file name: env var "%s" is non-scalar.', $name)); + } + if (!file_exists($file)) { + throw new RuntimeException(sprintf('Env "file:%s" not found: "%s" does not exist.', $name, $file)); + } + + return file_get_contents($file); + } + + if (false !== $i || 'string' !== $prefix) { + if (null === $env = $getEnv($name)) { + return null; + } + } elseif (isset($_ENV[$name])) { + $env = $_ENV[$name]; + } elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) { + $env = $_SERVER[$name]; + } elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues + if (!$this->container->hasParameter("env($name)")) { + throw new EnvNotFoundException($name); + } + + if (null === $env = $this->container->getParameter("env($name)")) { + return null; + } + } + + if (!is_scalar($env)) { + throw new RuntimeException(sprintf('Non-scalar env var "%s" cannot be cast to "%s".', $name, $prefix)); + } + + if ('string' === $prefix) { + return (string) $env; + } + + if ('bool' === $prefix) { + return (bool) self::phpize($env); + } + + if ('int' === $prefix) { + if (!is_numeric($env = self::phpize($env))) { + throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to int.', $name)); + } + + return (int) $env; + } + + if ('float' === $prefix) { + if (!is_numeric($env = self::phpize($env))) { + throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to float.', $name)); + } + + return (float) $env; + } + + if ('const' === $prefix) { + if (!\defined($env)) { + throw new RuntimeException(sprintf('Env var "%s" maps to undefined constant "%s".', $name, $env)); + } + + return \constant($env); + } + + if ('base64' === $prefix) { + return base64_decode($env); + } + + if ('json' === $prefix) { + $env = json_decode($env, true); + + if (\JSON_ERROR_NONE !== json_last_error()) { + throw new RuntimeException(sprintf('Invalid JSON in env var "%s": ', $name).json_last_error_msg()); + } + + if (!\is_array($env)) { + throw new RuntimeException(sprintf('Invalid JSON env var "%s": array expected, "%s" given.', $name, \gettype($env))); + } + + return $env; + } + + if ('resolve' === $prefix) { + return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name) { + if (!isset($match[1])) { + return '%'; + } + $value = $this->container->getParameter($match[1]); + if (!is_scalar($value)) { + throw new RuntimeException(sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, \gettype($value))); + } + + return $value; + }, $env); + } + + throw new RuntimeException(sprintf('Unsupported env var prefix "%s".', $prefix)); + } + + private static function phpize($value) + { + if (!class_exists(XmlUtils::class)) { + throw new RuntimeException('The Symfony Config component is required to cast env vars to "bool", "int" or "float".'); + } + + return XmlUtils::phpize($value); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php new file mode 100644 index 00000000..654fe55e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/EnvVarProcessorInterface.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * The EnvVarProcessorInterface is implemented by objects that manage environment-like variables. + * + * @author Nicolas Grekas + */ +interface EnvVarProcessorInterface +{ + /** + * Returns the value of the given variable as managed by the current instance. + * + * @param string $prefix The namespace of the variable + * @param string $name The name of the variable within the namespace + * @param \Closure $getEnv A closure that allows fetching more env vars + * + * @return mixed + * + * @throws RuntimeException on error + */ + public function getEnv($prefix, $name, \Closure $getEnv); + + /** + * @return string[] The PHP-types managed by getEnv(), keyed by prefixes + */ + public static function getProvidedTypes(); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php new file mode 100644 index 00000000..145cd8cb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Thrown when a definition cannot be autowired. + */ +class AutowiringFailedException extends RuntimeException +{ + private $serviceId; + + public function __construct($serviceId, $message = '', $code = 0, \Exception $previous = null) + { + $this->serviceId = $serviceId; + + parent::__construct($message, $code, $previous); + } + + public function getServiceId() + { + return $this->serviceId; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php new file mode 100644 index 00000000..959238e9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/BadMethodCallException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base BadMethodCallException for Dependency Injection component. + */ +class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php new file mode 100644 index 00000000..577095e8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when an environment variable is not found. + * + * @author Nicolas Grekas + */ +class EnvNotFoundException extends InvalidArgumentException +{ + public function __construct($name) + { + parent::__construct(sprintf('Environment variable not found: "%s".', $name)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/EnvParameterException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/EnvParameterException.php new file mode 100644 index 00000000..3839a463 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/EnvParameterException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception wraps exceptions whose messages contain a reference to an env parameter. + * + * @author Nicolas Grekas + */ +class EnvParameterException extends InvalidArgumentException +{ + public function __construct(array $envs, \Exception $previous = null, $message = 'Incompatible use of dynamic environment variables "%s" found in parameters.') + { + parent::__construct(sprintf($message, implode('", "', $envs)), 0, $previous); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php new file mode 100644 index 00000000..5bec4786 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ExceptionInterface.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +use Psr\Container\ContainerExceptionInterface; + +/** + * Base ExceptionInterface for Dependency Injection component. + * + * @author Fabien Potencier + * @author Bulat Shakirzyanov + */ +interface ExceptionInterface extends ContainerExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..119bb7d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/InvalidArgumentException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base InvalidArgumentException for Dependency Injection component. + * + * @author Bulat Shakirzyanov + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/LogicException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/LogicException.php new file mode 100644 index 00000000..17a070ca --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/LogicException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base LogicException for Dependency Injection component. + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php new file mode 100644 index 00000000..a61f143b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/OutOfBoundsException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base OutOfBoundsException for Dependency Injection component. + */ +class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php new file mode 100644 index 00000000..29151765 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ParameterCircularReferenceException.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference in a parameter is detected. + * + * @author Fabien Potencier + */ +class ParameterCircularReferenceException extends RuntimeException +{ + private $parameters; + + public function __construct($parameters, \Exception $previous = null) + { + parent::__construct(sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], implode('" > "', $parameters), $parameters[0]), 0, $previous); + + $this->parameters = $parameters; + } + + public function getParameters() + { + return $this->parameters; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php new file mode 100644 index 00000000..b08f2e85 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ParameterNotFoundException.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a non-existent parameter is used. + * + * @author Fabien Potencier + */ +class ParameterNotFoundException extends InvalidArgumentException +{ + private $key; + private $sourceId; + private $sourceKey; + private $alternatives; + private $nonNestedAlternative; + + /** + * @param string $key The requested parameter key + * @param string $sourceId The service id that references the non-existent parameter + * @param string $sourceKey The parameter key that references the non-existent parameter + * @param \Exception $previous The previous exception + * @param string[] $alternatives Some parameter name alternatives + * @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters + */ + public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = [], $nonNestedAlternative = null) + { + $this->key = $key; + $this->sourceId = $sourceId; + $this->sourceKey = $sourceKey; + $this->alternatives = $alternatives; + $this->nonNestedAlternative = $nonNestedAlternative; + + parent::__construct('', 0, $previous); + + $this->updateRepr(); + } + + public function updateRepr() + { + if (null !== $this->sourceId) { + $this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key); + } elseif (null !== $this->sourceKey) { + $this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key); + } else { + $this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key); + } + + if ($this->alternatives) { + if (1 == \count($this->alternatives)) { + $this->message .= ' Did you mean this: "'; + } else { + $this->message .= ' Did you mean one of these: "'; + } + $this->message .= implode('", "', $this->alternatives).'"?'; + } elseif (null !== $this->nonNestedAlternative) { + $this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?'; + } + } + + public function getKey() + { + return $this->key; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function getSourceKey() + { + return $this->sourceKey; + } + + public function setSourceId($sourceId) + { + $this->sourceId = $sourceId; + + $this->updateRepr(); + } + + public function setSourceKey($sourceKey) + { + $this->sourceKey = $sourceKey; + + $this->updateRepr(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/RuntimeException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/RuntimeException.php new file mode 100644 index 00000000..5c245412 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/RuntimeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * Base RuntimeException for Dependency Injection component. + * + * @author Johannes M. Schmitt + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php new file mode 100644 index 00000000..26e3fb34 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ServiceCircularReferenceException.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +/** + * This exception is thrown when a circular reference is detected. + * + * @author Johannes M. Schmitt + */ +class ServiceCircularReferenceException extends RuntimeException +{ + private $serviceId; + private $path; + + public function __construct($serviceId, array $path, \Exception $previous = null) + { + parent::__construct(sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, implode(' -> ', $path)), 0, $previous); + + $this->serviceId = $serviceId; + $this->path = $path; + } + + public function getServiceId() + { + return $this->serviceId; + } + + public function getPath() + { + return $this->path; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php new file mode 100644 index 00000000..280dabf3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Exception/ServiceNotFoundException.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Exception; + +use Psr\Container\NotFoundExceptionInterface; + +/** + * This exception is thrown when a non-existent service is requested. + * + * @author Johannes M. Schmitt + */ +class ServiceNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface +{ + private $id; + private $sourceId; + private $alternatives; + + public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = [], $msg = null) + { + if (null !== $msg) { + // no-op + } elseif (null === $sourceId) { + $msg = sprintf('You have requested a non-existent service "%s".', $id); + } else { + $msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id); + } + + if ($alternatives) { + if (1 == \count($alternatives)) { + $msg .= ' Did you mean this: "'; + } else { + $msg .= ' Did you mean one of these: "'; + } + $msg .= implode('", "', $alternatives).'"?'; + } + + parent::__construct($msg, 0, $previous); + + $this->id = $id; + $this->sourceId = $sourceId; + $this->alternatives = $alternatives; + } + + public function getId() + { + return $this->id; + } + + public function getSourceId() + { + return $this->sourceId; + } + + public function getAlternatives() + { + return $this->alternatives; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ExpressionLanguage.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ExpressionLanguage.php new file mode 100644 index 00000000..0c1780b8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ExpressionLanguage.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage; + +/** + * Adds some function to the default ExpressionLanguage. + * + * @author Fabien Potencier + * + * @see ExpressionLanguageProvider + */ +class ExpressionLanguage extends BaseExpressionLanguage +{ + /** + * {@inheritdoc} + */ + public function __construct($cache = null, array $providers = [], callable $serviceCompiler = null) + { + // prepend the default provider to let users override it easily + array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler)); + + parent::__construct($cache, $providers); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php new file mode 100644 index 00000000..9198ca0a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ExpressionLanguageProvider.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; + +/** + * Define some ExpressionLanguage functions. + * + * To get a service, use service('request'). + * To get a parameter, use parameter('kernel.debug'). + * + * @author Fabien Potencier + */ +class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface +{ + private $serviceCompiler; + + public function __construct(callable $serviceCompiler = null) + { + $this->serviceCompiler = $serviceCompiler; + } + + public function getFunctions() + { + return [ + new ExpressionFunction('service', $this->serviceCompiler ?: function ($arg) { + return sprintf('$this->get(%s)', $arg); + }, function (array $variables, $value) { + return $variables['container']->get($value); + }), + + new ExpressionFunction('parameter', function ($arg) { + return sprintf('$this->getParameter(%s)', $arg); + }, function (array $variables, $value) { + return $variables['container']->getParameter($value); + }), + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php new file mode 100644 index 00000000..c3bd8423 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/ConfigurationExtensionInterface.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ConfigurationExtensionInterface is the interface implemented by container extension classes. + * + * @author Kevin Bond + */ +interface ConfigurationExtensionInterface +{ + /** + * Returns extension configuration. + * + * @return ConfigurationInterface|null The configuration or null + */ + public function getConfiguration(array $config, ContainerBuilder $container); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/Extension.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/Extension.php new file mode 100644 index 00000000..00fa9dc8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/Extension.php @@ -0,0 +1,130 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\BadMethodCallException; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * Provides useful features shared by many extensions. + * + * @author Fabien Potencier + */ +abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface +{ + private $processedConfigs = []; + + /** + * {@inheritdoc} + */ + public function getXsdValidationBasePath() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getNamespace() + { + return 'http://example.org/schema/dic/'.$this->getAlias(); + } + + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * This convention is to remove the "Extension" postfix from the class + * name and then lowercase and underscore the result. So: + * + * AcmeHelloExtension + * + * becomes + * + * acme_hello + * + * This can be overridden in a sub-class to specify the alias manually. + * + * @return string The alias + * + * @throws BadMethodCallException When the extension name does not follow conventions + */ + public function getAlias() + { + $className = static::class; + if ('Extension' != substr($className, -9)) { + throw new BadMethodCallException('This extension does not follow the naming convention; you must overwrite the getAlias() method.'); + } + $classBaseName = substr(strrchr($className, '\\'), 1, -9); + + return Container::underscore($classBaseName); + } + + /** + * {@inheritdoc} + */ + public function getConfiguration(array $config, ContainerBuilder $container) + { + $class = static::class; + + if (false !== strpos($class, "\0")) { + return null; // ignore anonymous classes + } + + $class = substr_replace($class, '\Configuration', strrpos($class, '\\')); + $class = $container->getReflectionClass($class); + $constructor = $class ? $class->getConstructor() : null; + + return $class && (!$constructor || !$constructor->getNumberOfRequiredParameters()) ? $class->newInstance() : null; + } + + /** + * @return array + */ + final protected function processConfiguration(ConfigurationInterface $configuration, array $configs) + { + $processor = new Processor(); + + return $this->processedConfigs[] = $processor->processConfiguration($configuration, $configs); + } + + /** + * @internal + */ + final public function getProcessedConfigs() + { + try { + return $this->processedConfigs; + } finally { + $this->processedConfigs = []; + } + } + + /** + * @return bool Whether the configuration is enabled + * + * @throws InvalidArgumentException When the config is not enableable + */ + protected function isConfigEnabled(ContainerBuilder $container, array $config) + { + if (!\array_key_exists('enabled', $config)) { + throw new InvalidArgumentException("The config array has no 'enabled' key."); + } + + return (bool) $container->getParameterBag()->resolveValue($config['enabled']); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php new file mode 100644 index 00000000..6a7a2cf0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/ExtensionInterface.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ExtensionInterface is the interface implemented by container extension classes. + * + * @author Fabien Potencier + */ +interface ExtensionInterface +{ + /** + * Loads a specific configuration. + * + * @throws \InvalidArgumentException When provided tag is not defined in this extension + */ + public function load(array $configs, ContainerBuilder $container); + + /** + * Returns the namespace to be used for this extension (XML namespace). + * + * @return string The XML namespace + */ + public function getNamespace(); + + /** + * Returns the base path for the XSD files. + * + * @return string|false + */ + public function getXsdValidationBasePath(); + + /** + * Returns the recommended alias to use in XML. + * + * This alias is also the mandatory prefix to use when using YAML. + * + * @return string The alias + */ + public function getAlias(); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php new file mode 100644 index 00000000..5bd18d79 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Extension/PrependExtensionInterface.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Extension; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +interface PrependExtensionInterface +{ + /** + * Allow an extension to prepend the extension configurations. + */ + public function prepend(ContainerBuilder $container); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/LICENSE b/modules/empikmarketplace/vendor/symfony/dependency-injection/LICENSE new file mode 100644 index 00000000..9e936ec0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2020 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php new file mode 100644 index 00000000..417ab908 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/Instantiator/InstantiatorInterface.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; + +/** + * Lazy proxy instantiator, capable of instantiating a proxy given a container, the + * service definitions and a callback that produces the real service instance. + * + * @author Marco Pivetta + */ +interface InstantiatorInterface +{ + /** + * Instantiates a proxy object. + * + * @param ContainerInterface $container The container from which the service is being requested + * @param Definition $definition The definition of the requested service + * @param string $id Identifier of the requested service + * @param callable $realInstantiator Zero-argument callback that is capable of producing the real service instance + * + * @return object + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php new file mode 100644 index 00000000..532e7686 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/Instantiator/RealServiceInstantiator.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\Instantiator; + +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; + +/** + * {@inheritdoc} + * + * Noop proxy instantiator - produces the real service instead of a proxy instance. + * + * @author Marco Pivetta + */ +class RealServiceInstantiator implements InstantiatorInterface +{ + /** + * {@inheritdoc} + */ + public function instantiateProxy(ContainerInterface $container, Definition $definition, $id, $realInstantiator) + { + return \call_user_func($realInstantiator); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php new file mode 100644 index 00000000..3946eafa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/DumperInterface.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Lazy proxy dumper capable of generating the instantiation logic PHP code for proxied services. + * + * @author Marco Pivetta + */ +interface DumperInterface +{ + /** + * Inspects whether the given definitions should produce proxy instantiation logic in the dumped container. + * + * @return bool + */ + public function isProxyCandidate(Definition $definition); + + /** + * Generates the code to be used to instantiate a proxy in the dumped factory code. + * + * @param string $id Service identifier + * + * @return string + */ + public function getProxyFactoryCode(Definition $definition, $id/**, $factoryCode = null */); + + /** + * Generates the code for the lazy proxy. + * + * @return string + */ + public function getProxyCode(Definition $definition); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php new file mode 100644 index 00000000..67f9fae9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/PhpDumper/NullDumper.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy\PhpDumper; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * Null dumper, negates any proxy code generation for any given service definition. + * + * @author Marco Pivetta + * + * @final since version 3.3 + */ +class NullDumper implements DumperInterface +{ + /** + * {@inheritdoc} + */ + public function isProxyCandidate(Definition $definition) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = null) + { + return ''; + } + + /** + * {@inheritdoc} + */ + public function getProxyCode(Definition $definition) + { + return ''; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php new file mode 100644 index 00000000..bfa65f56 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\LazyProxy; + +/** + * @author Nicolas Grekas + * + * @internal + */ +class ProxyHelper +{ + /** + * @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context + */ + public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionParameter $p = null, $noBuiltin = false) + { + if ($p instanceof \ReflectionParameter) { + if (method_exists($p, 'getType')) { + $type = $p->getType(); + } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $p, $type)) { + $name = $type = $type[1]; + + if ('callable' === $name || 'array' === $name) { + return $noBuiltin ? null : $name; + } + } + } else { + $type = method_exists($r, 'getReturnType') ? $r->getReturnType() : null; + } + if (!$type) { + return null; + } + + $types = []; + + foreach ($type instanceof \ReflectionUnionType ? $type->getTypes() : [$type] as $type) { + $name = $type instanceof \ReflectionNamedType ? $type->getName() : (string) $type; + + if (!\is_string($type) && $type->isBuiltin()) { + if (!$noBuiltin) { + $types[] = $name; + } + continue; + } + + $lcName = strtolower($name); + $prefix = $noBuiltin ? '' : '\\'; + + if ('self' !== $lcName && 'parent' !== $lcName) { + $types[] = '' !== $prefix ? $prefix.$name : $name; + continue; + } + if (!$r instanceof \ReflectionMethod) { + continue; + } + if ('self' === $lcName) { + $types[] = $prefix.$r->getDeclaringClass()->name; + } else { + $types[] = ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null; + } + } + + return $types ? implode('|', $types) : null; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/ClosureLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/ClosureLoader.php new file mode 100644 index 00000000..183cacc4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/ClosureLoader.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * ClosureLoader loads service definitions from a PHP closure. + * + * The Closure has access to the container as its first argument. + * + * @author Fabien Potencier + */ +class ClosureLoader extends Loader +{ + private $container; + + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + \call_user_func($resource, $this->container); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return $resource instanceof \Closure; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php new file mode 100644 index 00000000..428683ef --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +abstract class AbstractConfigurator +{ + const FACTORY = 'unknown'; + + /** @internal */ + protected $definition; + + public function __call($method, $args) + { + if (method_exists($this, 'set'.$method)) { + return \call_user_func_array([$this, 'set'.$method], $args); + } + + throw new \BadMethodCallException(sprintf('Call to undefined method "%s::%s()".', static::class, $method)); + } + + /** + * Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value. + * + * @param mixed $value + * @param bool $allowServices whether Definition and Reference are allowed; by default, only scalars and arrays are + * + * @return mixed the value, optionally cast to a Definition/Reference + */ + public static function processValue($value, $allowServices = false) + { + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = static::processValue($v, $allowServices); + } + + return $value; + } + + if ($value instanceof ReferenceConfigurator) { + return new Reference($value->id, $value->invalidBehavior); + } + + if ($value instanceof InlineServiceConfigurator) { + $def = $value->definition; + $value->definition = null; + + return $def; + } + + if ($value instanceof self) { + throw new InvalidArgumentException(sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY)); + } + + switch (true) { + case null === $value: + case is_scalar($value): + return $value; + + case $value instanceof ArgumentInterface: + case $value instanceof Definition: + case $value instanceof Expression: + case $value instanceof Parameter: + case $value instanceof Reference: + if ($allowServices) { + return $value; + } + } + + throw new InvalidArgumentException(sprintf('Cannot use values of type "%s" in service configuration files.', \is_object($value) ? \get_class($value) : \gettype($value))); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php new file mode 100644 index 00000000..0a565787 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +abstract class AbstractServiceConfigurator extends AbstractConfigurator +{ + protected $parent; + protected $id; + private $defaultTags = []; + + public function __construct(ServicesConfigurator $parent, Definition $definition, $id = null, array $defaultTags = []) + { + $this->parent = $parent; + $this->definition = $definition; + $this->id = $id; + $this->defaultTags = $defaultTags; + } + + public function __destruct() + { + // default tags should be added last + foreach ($this->defaultTags as $name => $attributes) { + foreach ($attributes as $attributes) { + $this->definition->addTag($name, $attributes); + } + } + $this->defaultTags = []; + } + + /** + * Registers a service. + * + * @param string $id + * @param string|null $class + * + * @return ServiceConfigurator + */ + final public function set($id, $class = null) + { + $this->__destruct(); + + return $this->parent->set($id, $class); + } + + /** + * Creates an alias. + * + * @param string $id + * @param string $referencedId + * + * @return AliasConfigurator + */ + final public function alias($id, $referencedId) + { + $this->__destruct(); + + return $this->parent->alias($id, $referencedId); + } + + /** + * Registers a PSR-4 namespace using a glob pattern. + * + * @param string $namespace + * @param string $resource + * + * @return PrototypeConfigurator + */ + final public function load($namespace, $resource) + { + $this->__destruct(); + + return $this->parent->load($namespace, $resource); + } + + /** + * Gets an already defined service definition. + * + * @param string $id + * + * @return ServiceConfigurator + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + final public function get($id) + { + $this->__destruct(); + + return $this->parent->get($id); + } + + /** + * Registers a service. + * + * @param string $id + * @param string|null $class + * + * @return ServiceConfigurator + */ + final public function __invoke($id, $class = null) + { + $this->__destruct(); + + return $this->parent->set($id, $class); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php new file mode 100644 index 00000000..cb00f58c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Alias; + +/** + * @author Nicolas Grekas + */ +class AliasConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'alias'; + + use Traits\PublicTrait; + + public function __construct(ServicesConfigurator $parent, Alias $alias) + { + $this->parent = $parent; + $this->definition = $alias; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php new file mode 100644 index 00000000..f2e5ccf8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * @author Nicolas Grekas + */ +class ContainerConfigurator extends AbstractConfigurator +{ + const FACTORY = 'container'; + + private $container; + private $loader; + private $instanceof; + private $path; + private $file; + + public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, $path, $file) + { + $this->container = $container; + $this->loader = $loader; + $this->instanceof = &$instanceof; + $this->path = $path; + $this->file = $file; + } + + final public function extension($namespace, array $config) + { + if (!$this->container->hasExtension($namespace)) { + $extensions = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $namespace, $this->file, $namespace, $extensions ? implode('", "', $extensions) : 'none')); + } + + $this->container->loadFromExtension($namespace, static::processValue($config)); + } + + final public function import($resource, $type = null, $ignoreErrors = false) + { + $this->loader->setCurrentDir(\dirname($this->path)); + $this->loader->import($resource, $type, $ignoreErrors, $this->file); + } + + /** + * @return ParametersConfigurator + */ + final public function parameters() + { + return new ParametersConfigurator($this->container); + } + + /** + * @return ServicesConfigurator + */ + final public function services() + { + return new ServicesConfigurator($this->container, $this->loader, $this->instanceof); + } +} + +/** + * Creates a service reference. + * + * @param string $id + * + * @return ReferenceConfigurator + */ +function ref($id) +{ + return new ReferenceConfigurator($id); +} + +/** + * Creates an inline service. + * + * @param string|null $class + * + * @return InlineServiceConfigurator + */ +function inline($class = null) +{ + return new InlineServiceConfigurator(new Definition($class)); +} + +/** + * Creates a lazy iterator. + * + * @param ReferenceConfigurator[] $values + * + * @return IteratorArgument + */ +function iterator(array $values) +{ + return new IteratorArgument(AbstractConfigurator::processValue($values, true)); +} + +/** + * Creates a lazy iterator by tag name. + * + * @param string $tag + * + * @return TaggedIteratorArgument + */ +function tagged($tag) +{ + return new TaggedIteratorArgument($tag); +} + +/** + * Creates an expression. + * + * @param string $expression an expression + * + * @return Expression + */ +function expr($expression) +{ + return new Expression($expression); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php new file mode 100644 index 00000000..662ba95d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * @author Nicolas Grekas + * + * @method InstanceofConfigurator instanceof(string $fqcn) + */ +class DefaultsConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'defaults'; + + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\PublicTrait; + + /** + * Adds a tag for this definition. + * + * @param string $name The tag name + * @param array $attributes An array of attributes + * + * @return $this + * + * @throws InvalidArgumentException when an invalid tag name or attribute is provided + */ + final public function tag($name, array $attributes = []) + { + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException('The tag name in "_defaults" must be a non-empty string.'); + } + + foreach ($attributes as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type.', $name, $attribute)); + } + } + + $this->definition->addTag($name, $attributes); + + return $this; + } + + /** + * Defines an instanceof-conditional to be applied to following service definitions. + * + * @param string $fqcn + * + * @return InstanceofConfigurator + */ + final protected function setInstanceof($fqcn) + { + return $this->parent->instanceof($fqcn); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php new file mode 100644 index 00000000..362b374e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Nicolas Grekas + */ +class InlineServiceConfigurator extends AbstractConfigurator +{ + const FACTORY = 'inline'; + + use Traits\ArgumentTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\FactoryTrait; + use Traits\FileTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\TagTrait; + + public function __construct(Definition $definition) + { + $this->definition = $definition; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php new file mode 100644 index 00000000..629874d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +/** + * @author Nicolas Grekas + * + * @method InstanceofConfigurator instanceof(string $fqcn) + */ +class InstanceofConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'instanceof'; + + use Traits\AutowireTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\LazyTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\TagTrait; + + /** + * Defines an instanceof-conditional to be applied to following service definitions. + * + * @param string $fqcn + * + * @return self + */ + final protected function setInstanceof($fqcn) + { + return $this->parent->instanceof($fqcn); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php new file mode 100644 index 00000000..9585b1a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Nicolas Grekas + */ +class ParametersConfigurator extends AbstractConfigurator +{ + const FACTORY = 'parameters'; + + private $container; + + public function __construct(ContainerBuilder $container) + { + $this->container = $container; + } + + /** + * Creates a parameter. + * + * @param string $name + * @param mixed $value + * + * @return $this + */ + final public function set($name, $value) + { + $this->container->setParameter($name, static::processValue($value, true)); + + return $this; + } + + /** + * Creates a parameter. + * + * @param string $name + * @param mixed $value + * + * @return $this + */ + final public function __invoke($name, $value) + { + return $this->set($name, $value); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php new file mode 100644 index 00000000..3d844798 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; + +/** + * @author Nicolas Grekas + */ +class PrototypeConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'load'; + + use Traits\AbstractTrait; + use Traits\ArgumentTrait; + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ConfiguratorTrait; + use Traits\DeprecateTrait; + use Traits\FactoryTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\TagTrait; + + private $loader; + private $resource; + private $exclude; + private $allowParent; + + public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, $namespace, $resource, $allowParent) + { + $definition = new Definition(); + if (!$defaults->isPublic() || !$defaults->isPrivate()) { + $definition->setPublic($defaults->isPublic()); + } + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + // deep clone, to avoid multiple process of the same instance in the passes + $definition->setBindings(unserialize(serialize($defaults->getBindings()))); + $definition->setChanges([]); + + $this->loader = $loader; + $this->resource = $resource; + $this->allowParent = $allowParent; + + parent::__construct($parent, $definition, $namespace, $defaults->getTags()); + } + + public function __destruct() + { + parent::__destruct(); + + if ($this->loader) { + $this->loader->registerClasses($this->definition, $this->id, $this->resource, $this->exclude); + } + $this->loader = null; + } + + /** + * Excludes files from registration using a glob pattern. + * + * @param string $exclude + * + * @return $this + */ + final public function exclude($exclude) + { + $this->exclude = $exclude; + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php new file mode 100644 index 00000000..1585c087 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * @author Nicolas Grekas + */ +class ReferenceConfigurator extends AbstractConfigurator +{ + /** @internal */ + protected $id; + + /** @internal */ + protected $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + + public function __construct($id) + { + $this->id = $id; + } + + /** + * @return $this + */ + final public function ignoreOnInvalid() + { + $this->invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + + return $this; + } + + /** + * @return $this + */ + final public function nullOnInvalid() + { + $this->invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + + return $this; + } + + /** + * @return $this + */ + final public function ignoreOnUninitialized() + { + $this->invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + + return $this; + } + + public function __toString() + { + return $this->id; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php new file mode 100644 index 00000000..897dedaa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; + +/** + * @author Nicolas Grekas + */ +class ServiceConfigurator extends AbstractServiceConfigurator +{ + const FACTORY = 'services'; + + use Traits\AbstractTrait; + use Traits\ArgumentTrait; + use Traits\AutoconfigureTrait; + use Traits\AutowireTrait; + use Traits\BindTrait; + use Traits\CallTrait; + use Traits\ClassTrait; + use Traits\ConfiguratorTrait; + use Traits\DecorateTrait; + use Traits\DeprecateTrait; + use Traits\FactoryTrait; + use Traits\FileTrait; + use Traits\LazyTrait; + use Traits\ParentTrait; + use Traits\PropertyTrait; + use Traits\PublicTrait; + use Traits\ShareTrait; + use Traits\SyntheticTrait; + use Traits\TagTrait; + + private $container; + private $instanceof; + private $allowParent; + + public function __construct(ContainerBuilder $container, array $instanceof, $allowParent, ServicesConfigurator $parent, Definition $definition, $id, array $defaultTags) + { + $this->container = $container; + $this->instanceof = $instanceof; + $this->allowParent = $allowParent; + + parent::__construct($parent, $definition, $id, $defaultTags); + } + + public function __destruct() + { + parent::__destruct(); + + $this->container->removeBindings($this->id); + + if (!$this->definition instanceof ChildDefinition) { + $this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof)); + } else { + $this->container->setDefinition($this->id, $this->definition); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php new file mode 100644 index 00000000..b6ccbc63 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; + +/** + * @author Nicolas Grekas + * + * @method InstanceofConfigurator instanceof($fqcn) + */ +class ServicesConfigurator extends AbstractConfigurator +{ + const FACTORY = 'services'; + + private $defaults; + private $container; + private $loader; + private $instanceof; + + public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof) + { + $this->defaults = new Definition(); + $this->container = $container; + $this->loader = $loader; + $this->instanceof = &$instanceof; + $instanceof = []; + } + + /** + * Defines a set of defaults for following service definitions. + * + * @return DefaultsConfigurator + */ + final public function defaults() + { + return new DefaultsConfigurator($this, $this->defaults = new Definition()); + } + + /** + * Defines an instanceof-conditional to be applied to following service definitions. + * + * @param string $fqcn + * + * @return InstanceofConfigurator + */ + final protected function setInstanceof($fqcn) + { + $this->instanceof[$fqcn] = $definition = new ChildDefinition(''); + + return new InstanceofConfigurator($this, $definition, $fqcn); + } + + /** + * Registers a service. + * + * @param string $id + * @param string|null $class + * + * @return ServiceConfigurator + */ + final public function set($id, $class = null) + { + $defaults = $this->defaults; + $allowParent = !$defaults->getChanges() && empty($this->instanceof); + + $definition = new Definition(); + if (!$defaults->isPublic() || !$defaults->isPrivate()) { + $definition->setPublic($defaults->isPublic() && !$defaults->isPrivate()); + } + $definition->setAutowired($defaults->isAutowired()); + $definition->setAutoconfigured($defaults->isAutoconfigured()); + // deep clone, to avoid multiple process of the same instance in the passes + $definition->setBindings(unserialize(serialize($defaults->getBindings()))); + $definition->setChanges([]); + + $configurator = new ServiceConfigurator($this->container, $this->instanceof, $allowParent, $this, $definition, $id, $defaults->getTags()); + + return null !== $class ? $configurator->class($class) : $configurator; + } + + /** + * Creates an alias. + * + * @param string $id + * @param string $referencedId + * + * @return AliasConfigurator + */ + final public function alias($id, $referencedId) + { + $ref = static::processValue($referencedId, true); + $alias = new Alias((string) $ref); + if (!$this->defaults->isPublic() || !$this->defaults->isPrivate()) { + $alias->setPublic($this->defaults->isPublic()); + } + $this->container->setAlias($id, $alias); + + return new AliasConfigurator($this, $alias); + } + + /** + * Registers a PSR-4 namespace using a glob pattern. + * + * @param string $namespace + * @param string $resource + * + * @return PrototypeConfigurator + */ + final public function load($namespace, $resource) + { + $allowParent = !$this->defaults->getChanges() && empty($this->instanceof); + + return new PrototypeConfigurator($this, $this->loader, $this->defaults, $namespace, $resource, $allowParent); + } + + /** + * Gets an already defined service definition. + * + * @param string $id + * + * @return ServiceConfigurator + * + * @throws ServiceNotFoundException if the service definition does not exist + */ + final public function get($id) + { + $allowParent = !$this->defaults->getChanges() && empty($this->instanceof); + $definition = $this->container->getDefinition($id); + + return new ServiceConfigurator($this->container, $definition->getInstanceofConditionals(), $allowParent, $this, $definition, $id, []); + } + + /** + * Registers a service. + * + * @param string $id + * @param string|null $class + * + * @return ServiceConfigurator + */ + final public function __invoke($id, $class = null) + { + return $this->set($id, $class); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php new file mode 100644 index 00000000..f69a7a5b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +/** + * @method $this abstract(bool $abstract = true) + */ +trait AbstractTrait +{ + /** + * Whether this definition is abstract, that means it merely serves as a + * template for other definitions. + * + * @param bool $abstract + * + * @return $this + */ + final protected function setAbstract($abstract = true) + { + $this->definition->setAbstract($abstract); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php new file mode 100644 index 00000000..7ec8c51d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ArgumentTrait +{ + /** + * Sets the arguments to pass to the service constructor/factory method. + * + * @param array $arguments An array of arguments + * + * @return $this + */ + final public function args(array $arguments) + { + $this->definition->setArguments(static::processValue($arguments, true)); + + return $this; + } + + /** + * Sets one argument to pass to the service constructor/factory method. + * + * @param string|int $key + * @param mixed $value + * + * @return $this + */ + final public function arg($key, $value) + { + $this->definition->setArgument($key, static::processValue($value, true)); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php new file mode 100644 index 00000000..42a69235 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait AutoconfigureTrait +{ + /** + * Sets whether or not instanceof conditionals should be prepended with a global set. + * + * @param bool $autoconfigured + * + * @return $this + * + * @throws InvalidArgumentException when a parent is already set + */ + final public function autoconfigure($autoconfigured = true) + { + if ($autoconfigured && $this->definition instanceof ChildDefinition) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id)); + } + $this->definition->setAutoconfigured($autoconfigured); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php new file mode 100644 index 00000000..3d4b2e85 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait AutowireTrait +{ + /** + * Enables/disables autowiring. + * + * @param bool $autowired + * + * @return $this + */ + final public function autowire($autowired = true) + { + $this->definition->setAutowired($autowired); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php new file mode 100644 index 00000000..4511ed65 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Reference; + +trait BindTrait +{ + /** + * Sets bindings. + * + * Bindings map $named or FQCN arguments to values that should be + * injected in the matching parameters (of the constructor, of methods + * called and of controller actions). + * + * @param string $nameOrFqcn A parameter name with its "$" prefix, or a FQCN + * @param mixed $valueOrRef The value or reference to bind + * + * @return $this + */ + final public function bind($nameOrFqcn, $valueOrRef) + { + $valueOrRef = static::processValue($valueOrRef, true); + if (isset($nameOrFqcn[0]) && '$' !== $nameOrFqcn[0] && !$valueOrRef instanceof Reference) { + throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn)); + } + $bindings = $this->definition->getBindings(); + $bindings[$nameOrFqcn] = $valueOrRef; + $this->definition->setBindings($bindings); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php new file mode 100644 index 00000000..8e6b17a1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/CallTrait.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait CallTrait +{ + /** + * Adds a method to call after service initialization. + * + * @param string $method The method name to call + * @param array $arguments An array of arguments to pass to the method call + * + * @return $this + * + * @throws InvalidArgumentException on empty $method param + */ + final public function call($method, array $arguments = []) + { + $this->definition->addMethodCall($method, static::processValue($arguments, true)); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php new file mode 100644 index 00000000..ae5b1c0a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ClassTrait.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +/** + * @method $this class(string $class) + */ +trait ClassTrait +{ + /** + * Sets the service class. + * + * @param string $class The service class + * + * @return $this + */ + final protected function setClass($class) + { + $this->definition->setClass($class); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php new file mode 100644 index 00000000..a38283b0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ConfiguratorTrait.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ConfiguratorTrait +{ + /** + * Sets a configurator to call after the service is fully initialized. + * + * @param string|array $configurator A PHP callable reference + * + * @return $this + */ + final public function configurator($configurator) + { + $this->definition->setConfigurator(static::processValue($configurator, true)); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php new file mode 100644 index 00000000..173ad15f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DecorateTrait.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait DecorateTrait +{ + /** + * Sets the service that this service is decorating. + * + * @param string|null $id The decorated service id, use null to remove decoration + * @param string|null $renamedId The new decorated service id + * @param int $priority The priority of decoration + * + * @return $this + * + * @throws InvalidArgumentException in case the decorated service id and the new decorated service id are equals + */ + final public function decorate($id, $renamedId = null, $priority = 0) + { + $this->definition->setDecoratedService($id, $renamedId, $priority); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php new file mode 100644 index 00000000..b14a6557 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/DeprecateTrait.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait DeprecateTrait +{ + /** + * Whether this definition is deprecated, that means it should not be called anymore. + * + * @param string $template Template message to use if the definition is deprecated + * + * @return $this + * + * @throws InvalidArgumentException when the message template is invalid + */ + final public function deprecate($template = null) + { + $this->definition->setDeprecated(true, $template); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php new file mode 100644 index 00000000..0d50fb74 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FactoryTrait.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait FactoryTrait +{ + /** + * Sets a factory. + * + * @param string|array $factory A PHP callable reference + * + * @return $this + */ + final public function factory($factory) + { + if (\is_string($factory) && 1 === substr_count($factory, ':')) { + $factoryParts = explode(':', $factory); + + throw new InvalidArgumentException(sprintf('Invalid factory "%s": the `service:method` notation is not available when using PHP-based DI configuration. Use "[ref(\'%s\'), \'%s\']" instead.', $factory, $factoryParts[0], $factoryParts[1])); + } + + $this->definition->setFactory(static::processValue($factory, true)); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php new file mode 100644 index 00000000..895f5304 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/FileTrait.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait FileTrait +{ + /** + * Sets a file to require before creating the service. + * + * @param string $file A full pathname to include + * + * @return $this + */ + final public function file($file) + { + $this->definition->setFile($file); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php new file mode 100644 index 00000000..d7ea8b27 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/LazyTrait.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait LazyTrait +{ + /** + * Sets the lazy flag of this service. + * + * @param bool $lazy + * + * @return $this + */ + final public function lazy($lazy = true) + { + $this->definition->setLazy($lazy); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php new file mode 100644 index 00000000..43f1223e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ParentTrait.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * @method $this parent(string $parent) + */ +trait ParentTrait +{ + /** + * Sets the Definition to inherit from. + * + * @param string $parent + * + * @return $this + * + * @throws InvalidArgumentException when parent cannot be set + */ + final protected function setParent($parent) + { + if (!$this->allowParent) { + throw new InvalidArgumentException(sprintf('A parent cannot be defined when either "_instanceof" or "_defaults" are also defined for service prototype "%s".', $this->id)); + } + + if ($this->definition instanceof ChildDefinition) { + $this->definition->setParent($parent); + } elseif ($this->definition->isAutoconfigured()) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id)); + } elseif ($this->definition->getBindings()) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also "bind" arguments.', $this->id)); + } else { + // cast Definition to ChildDefinition + $definition = serialize($this->definition); + $definition = substr_replace($definition, '53', 2, 2); + $definition = substr_replace($definition, 'Child', 44, 0); + $definition = unserialize($definition); + + $this->definition = $definition->setParent($parent); + } + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php new file mode 100644 index 00000000..d5d93870 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PropertyTrait.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait PropertyTrait +{ + /** + * Sets a specific property. + * + * @param string $name + * @param mixed $value + * + * @return $this + */ + final public function property($name, $value) + { + $this->definition->setProperty($name, static::processValue($value, true)); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php new file mode 100644 index 00000000..8f7f79f1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/PublicTrait.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +/** + * @method $this public() + * @method $this private() + */ +trait PublicTrait +{ + /** + * @return $this + */ + final protected function setPublic() + { + $this->definition->setPublic(true); + + return $this; + } + + /** + * @return $this + */ + final protected function setPrivate() + { + $this->definition->setPublic(false); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php new file mode 100644 index 00000000..1c2f97b5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/ShareTrait.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait ShareTrait +{ + /** + * Sets if the service must be shared or not. + * + * @param bool $shared Whether the service must be shared or not + * + * @return $this + */ + final public function share($shared = true) + { + $this->definition->setShared($shared); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php new file mode 100644 index 00000000..81eceff4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/SyntheticTrait.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +trait SyntheticTrait +{ + /** + * Sets whether this definition is synthetic, that is not constructed by the + * container, but dynamically injected. + * + * @param bool $synthetic + * + * @return $this + */ + final public function synthetic($synthetic = true) + { + $this->definition->setSynthetic($synthetic); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php new file mode 100644 index 00000000..d17339f8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/Configurator/Traits/TagTrait.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +trait TagTrait +{ + /** + * Adds a tag for this definition. + * + * @param string $name The tag name + * @param array $attributes An array of attributes + * + * @return $this + */ + final public function tag($name, array $attributes = []) + { + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(sprintf('The tag name for service "%s" must be a non-empty string.', $this->id)); + } + + foreach ($attributes as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('A tag attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s".', $this->id, $name, $attribute)); + } + } + + $this->definition->addTag($name, $attributes); + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php new file mode 100644 index 00000000..a57cac3b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/DirectoryLoader.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +/** + * DirectoryLoader is a recursive loader to go through directories. + * + * @author Sebastien Lavoie + */ +class DirectoryLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($file, $type = null) + { + $file = rtrim($file, '/'); + $path = $this->locator->locate($file); + $this->container->fileExists($path, false); + + foreach (scandir($path) as $dir) { + if ('.' !== $dir[0]) { + if (is_dir($path.'/'.$dir)) { + $dir .= '/'; // append / to allow recursion + } + + $this->setCurrentDir($path); + + $this->import($dir, null, false, $path); + } + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if ('directory' === $type) { + return true; + } + + return null === $type && \is_string($resource) && '/' === substr($resource, -1); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/FileLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/FileLoader.php new file mode 100644 index 00000000..749dd4d0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/FileLoader.php @@ -0,0 +1,176 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\FileLocatorInterface; +use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * FileLoader is the abstract class used by all built-in loaders that are file based. + * + * @author Fabien Potencier + */ +abstract class FileLoader extends BaseFileLoader +{ + protected $container; + protected $isLoadingInstanceof = false; + protected $instanceof = []; + + public function __construct(ContainerBuilder $container, FileLocatorInterface $locator) + { + $this->container = $container; + + parent::__construct($locator); + } + + /** + * Registers a set of classes as services using PSR-4 for discovery. + * + * @param Definition $prototype A definition to use as template + * @param string $namespace The namespace prefix of classes in the scanned directory + * @param string $resource The directory to look for classes, glob-patterns allowed + * @param string $exclude A globed path of files to exclude + */ + public function registerClasses(Definition $prototype, $namespace, $resource, $exclude = null) + { + if ('\\' !== substr($namespace, -1)) { + throw new InvalidArgumentException(sprintf('Namespace prefix must end with a "\\": "%s".', $namespace)); + } + if (!preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++$/', $namespace)) { + throw new InvalidArgumentException(sprintf('Namespace is not a valid PSR-4 prefix: "%s".', $namespace)); + } + + $classes = $this->findClasses($namespace, $resource, $exclude); + // prepare for deep cloning + $serializedPrototype = serialize($prototype); + $interfaces = []; + $singlyImplemented = []; + + foreach ($classes as $class => $errorMessage) { + if (interface_exists($class, false)) { + $interfaces[] = $class; + } else { + $this->setDefinition($class, $definition = unserialize($serializedPrototype)); + if (null !== $errorMessage) { + $definition->addError($errorMessage); + + continue; + } + foreach (class_implements($class, false) as $interface) { + $singlyImplemented[$interface] = isset($singlyImplemented[$interface]) ? false : $class; + } + } + } + foreach ($interfaces as $interface) { + if (!empty($singlyImplemented[$interface])) { + $this->container->setAlias($interface, $singlyImplemented[$interface]) + ->setPublic(false); + } + } + } + + /** + * Registers a definition in the container with its instanceof-conditionals. + * + * @param string $id + */ + protected function setDefinition($id, Definition $definition) + { + $this->container->removeBindings($id); + + if ($this->isLoadingInstanceof) { + if (!$definition instanceof ChildDefinition) { + throw new InvalidArgumentException(sprintf('Invalid type definition "%s": ChildDefinition expected, "%s" given.', $id, \get_class($definition))); + } + $this->instanceof[$id] = $definition; + } else { + $this->container->setDefinition($id, $definition instanceof ChildDefinition ? $definition : $definition->setInstanceofConditionals($this->instanceof)); + } + } + + private function findClasses($namespace, $pattern, $excludePattern) + { + $parameterBag = $this->container->getParameterBag(); + + $excludePaths = []; + $excludePrefix = null; + if ($excludePattern) { + $excludePattern = $parameterBag->unescapeValue($parameterBag->resolveValue($excludePattern)); + foreach ($this->glob($excludePattern, true, $resource, true) as $path => $info) { + if (null === $excludePrefix) { + $excludePrefix = $resource->getPrefix(); + } + + // normalize Windows slashes + $excludePaths[str_replace('\\', '/', $path)] = true; + } + } + + $pattern = $parameterBag->unescapeValue($parameterBag->resolveValue($pattern)); + $classes = []; + $extRegexp = \defined('HHVM_VERSION') ? '/\\.(?:php|hh)$/' : '/\\.php$/'; + $prefixLen = null; + foreach ($this->glob($pattern, true, $resource) as $path => $info) { + if (null === $prefixLen) { + $prefixLen = \strlen($resource->getPrefix()); + + if ($excludePrefix && 0 !== strpos($excludePrefix, $resource->getPrefix())) { + throw new InvalidArgumentException(sprintf('Invalid "exclude" pattern when importing classes for "%s": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s).', $namespace, $excludePattern, $pattern)); + } + } + + if (isset($excludePaths[str_replace('\\', '/', $path)])) { + continue; + } + + if (!preg_match($extRegexp, $path, $m) || !$info->isReadable()) { + continue; + } + $class = $namespace.ltrim(str_replace('/', '\\', substr($path, $prefixLen, -\strlen($m[0]))), '\\'); + + if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $class)) { + continue; + } + + try { + $r = $this->container->getReflectionClass($class); + } catch (\ReflectionException $e) { + $classes[$class] = $e->getMessage(); + continue; + } + // check to make sure the expected class exists + if (!$r) { + throw new InvalidArgumentException(sprintf('Expected to find class "%s" in file "%s" while importing services from resource "%s", but it was not found! Check the namespace prefix used with the resource.', $class, $path, $pattern)); + } + + if ($r->isInstantiable() || $r->isInterface()) { + $classes[$class] = null; + } + } + + // track only for new & removed files + if ($resource instanceof GlobResource) { + $this->container->addResource($resource); + } else { + foreach ($resource as $path) { + $this->container->fileExists($path, false); + } + } + + return $classes; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php new file mode 100644 index 00000000..4b25610e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/GlobFileLoader.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +/** + * GlobFileLoader loads files from a glob pattern. + * + * @author Nicolas Grekas + */ +class GlobFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + foreach ($this->glob($resource, false, $globResource) as $path => $info) { + $this->import($path); + } + + $this->container->addResource($globResource); + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + return 'glob' === $type; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/IniFileLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/IniFileLoader.php new file mode 100644 index 00000000..6c07c673 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/IniFileLoader.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Util\XmlUtils; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; + +/** + * IniFileLoader loads parameters from INI files. + * + * @author Fabien Potencier + */ +class IniFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $path = $this->locator->locate($resource); + + $this->container->fileExists($path); + + // first pass to catch parsing errors + $result = parse_ini_file($path, true); + if (false === $result || [] === $result) { + throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource)); + } + + // real raw parsing + $result = parse_ini_file($path, true, \INI_SCANNER_RAW); + + if (isset($result['parameters']) && \is_array($result['parameters'])) { + foreach ($result['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->phpize($value)); + } + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && 'ini' === pathinfo($resource, \PATHINFO_EXTENSION)) { + return true; + } + + return 'ini' === $type; + } + + /** + * Note that the following features are not supported: + * * strings with escaped quotes are not supported "foo\"bar"; + * * string concatenation ("foo" "bar"). + */ + private function phpize($value) + { + // trim on the right as comments removal keep whitespaces + if ($value !== $v = rtrim($value)) { + $value = '""' === substr_replace($v, '', 1, -1) ? substr($v, 1, -1) : $v; + } + $lowercaseValue = strtolower($value); + + switch (true) { + case \defined($value): + return \constant($value); + case 'yes' === $lowercaseValue || 'on' === $lowercaseValue: + return true; + case 'no' === $lowercaseValue || 'off' === $lowercaseValue || 'none' === $lowercaseValue: + return false; + case isset($value[1]) && ( + ("'" === $value[0] && "'" === $value[\strlen($value) - 1]) || + ('"' === $value[0] && '"' === $value[\strlen($value) - 1]) + ): + // quoted string + return substr($value, 1, -1); + default: + return XmlUtils::phpize($value); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php new file mode 100644 index 00000000..ddb671ff --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/PhpFileLoader.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + +/** + * PhpFileLoader loads service definitions from a PHP file. + * + * The PHP file is required and the $container variable can be + * used within the file to change the container. + * + * @author Fabien Potencier + */ +class PhpFileLoader extends FileLoader +{ + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + // the container and loader variables are exposed to the included file below + $container = $this->container; + $loader = $this; + + $path = $this->locator->locate($resource); + $this->setCurrentDir(\dirname($path)); + $this->container->fileExists($path); + + // the closure forbids access to the private scope in the included file + $load = \Closure::bind(function ($path) use ($container, $loader, $resource, $type) { + return include $path; + }, $this, ProtectedPhpFileLoader::class); + + $callback = $load($path); + + if ($callback instanceof \Closure) { + $callback(new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource), $this->container, $this); + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && 'php' === pathinfo($resource, \PATHINFO_EXTENSION)) { + return true; + } + + return 'php' === $type; + } +} + +/** + * @internal + */ +final class ProtectedPhpFileLoader extends PhpFileLoader +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php new file mode 100644 index 00000000..0ff54ee6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/XmlFileLoader.php @@ -0,0 +1,722 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\Config\Util\XmlUtils; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; + +/** + * XmlFileLoader loads XML files service definitions. + * + * @author Fabien Potencier + */ +class XmlFileLoader extends FileLoader +{ + const NS = 'http://symfony.com/schema/dic/services'; + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $path = $this->locator->locate($resource); + + $xml = $this->parseFileToDOM($path); + + $this->container->fileExists($path); + + $defaults = $this->getServiceDefaults($xml, $path); + + // anonymous services + $this->processAnonymousServices($xml, $path, $defaults); + + // imports + $this->parseImports($xml, $path); + + // parameters + $this->parseParameters($xml, $path); + + // extensions + $this->loadFromExtensions($xml); + + // services + try { + $this->parseDefinitions($xml, $path, $defaults); + } finally { + $this->instanceof = []; + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && 'xml' === pathinfo($resource, \PATHINFO_EXTENSION)) { + return true; + } + + return 'xml' === $type; + } + + /** + * Parses parameters. + * + * @param string $file + */ + private function parseParameters(\DOMDocument $xml, $file) + { + if ($parameters = $this->getChildren($xml->documentElement, 'parameters')) { + $this->container->getParameterBag()->add($this->getArgumentsAsPhp($parameters[0], 'parameter', $file)); + } + } + + /** + * Parses imports. + * + * @param string $file + */ + private function parseImports(\DOMDocument $xml, $file) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + if (false === $imports = $xpath->query('//container:imports/container:import')) { + return; + } + + $defaultDirectory = \dirname($file); + foreach ($imports as $import) { + $this->setCurrentDir($defaultDirectory); + $this->import($import->getAttribute('resource'), XmlUtils::phpize($import->getAttribute('type')) ?: null, (bool) XmlUtils::phpize($import->getAttribute('ignore-errors')), $file); + } + } + + /** + * Parses multiple definitions. + * + * @param string $file + */ + private function parseDefinitions(\DOMDocument $xml, $file, $defaults) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + if (false === $services = $xpath->query('//container:services/container:service|//container:services/container:prototype')) { + return; + } + $this->setCurrentDir(\dirname($file)); + + $this->instanceof = []; + $this->isLoadingInstanceof = true; + $instanceof = $xpath->query('//container:services/container:instanceof'); + foreach ($instanceof as $service) { + $this->setDefinition((string) $service->getAttribute('id'), $this->parseDefinition($service, $file, [])); + } + + $this->isLoadingInstanceof = false; + foreach ($services as $service) { + if (null !== $definition = $this->parseDefinition($service, $file, $defaults)) { + if ('prototype' === $service->tagName) { + $this->registerClasses($definition, (string) $service->getAttribute('namespace'), (string) $service->getAttribute('resource'), (string) $service->getAttribute('exclude')); + } else { + $this->setDefinition((string) $service->getAttribute('id'), $definition); + } + } + } + } + + /** + * Get service defaults. + * + * @return array + */ + private function getServiceDefaults(\DOMDocument $xml, $file) + { + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + if (null === $defaultsNode = $xpath->query('//container:services/container:defaults')->item(0)) { + return []; + } + $defaults = [ + 'tags' => $this->getChildren($defaultsNode, 'tag'), + 'bind' => array_map(function ($v) { return new BoundArgument($v); }, $this->getArgumentsAsPhp($defaultsNode, 'bind', $file)), + ]; + + foreach ($defaults['tags'] as $tag) { + if ('' === $tag->getAttribute('name')) { + throw new InvalidArgumentException(sprintf('The tag name for tag "" in "%s" must be a non-empty string.', $file)); + } + } + + if ($defaultsNode->hasAttribute('autowire')) { + $defaults['autowire'] = XmlUtils::phpize($defaultsNode->getAttribute('autowire')); + } + if ($defaultsNode->hasAttribute('public')) { + $defaults['public'] = XmlUtils::phpize($defaultsNode->getAttribute('public')); + } + if ($defaultsNode->hasAttribute('autoconfigure')) { + $defaults['autoconfigure'] = XmlUtils::phpize($defaultsNode->getAttribute('autoconfigure')); + } + + return $defaults; + } + + /** + * Parses an individual Definition. + * + * @param string $file + * + * @return Definition|null + */ + private function parseDefinition(\DOMElement $service, $file, array $defaults) + { + if ($alias = $service->getAttribute('alias')) { + $this->validateAlias($service, $file); + + $this->container->setAlias((string) $service->getAttribute('id'), $alias = new Alias($alias)); + if ($publicAttr = $service->getAttribute('public')) { + $alias->setPublic(XmlUtils::phpize($publicAttr)); + } elseif (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + + return null; + } + + if ($this->isLoadingInstanceof) { + $definition = new ChildDefinition(''); + } elseif ($parent = $service->getAttribute('parent')) { + if (!empty($this->instanceof)) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.', $service->getAttribute('id'))); + } + + foreach ($defaults as $k => $v) { + if ('tags' === $k) { + // since tags are never inherited from parents, there is no confusion + // thus we can safely add them as defaults to ChildDefinition + continue; + } + if ('bind' === $k) { + if ($defaults['bind']) { + throw new InvalidArgumentException(sprintf('Bound values on service "%s" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file.', $service->getAttribute('id'))); + } + + continue; + } + if (!$service->hasAttribute($k)) { + throw new InvalidArgumentException(sprintf('Attribute "%s" on service "%s" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.', $k, $service->getAttribute('id'))); + } + } + + $definition = new ChildDefinition($parent); + } else { + $definition = new Definition(); + + if (isset($defaults['public'])) { + $definition->setPublic($defaults['public']); + } + if (isset($defaults['autowire'])) { + $definition->setAutowired($defaults['autowire']); + } + if (isset($defaults['autoconfigure'])) { + $definition->setAutoconfigured($defaults['autoconfigure']); + } + + $definition->setChanges([]); + } + + foreach (['class', 'public', 'shared', 'synthetic', 'lazy', 'abstract'] as $key) { + if ($value = $service->getAttribute($key)) { + $method = 'set'.$key; + $definition->$method(XmlUtils::phpize($value)); + } + } + + if ($value = $service->getAttribute('autowire')) { + $definition->setAutowired(XmlUtils::phpize($value)); + } + + if ($value = $service->getAttribute('autoconfigure')) { + if (!$definition instanceof ChildDefinition) { + $definition->setAutoconfigured(XmlUtils::phpize($value)); + } elseif ($value = XmlUtils::phpize($value)) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting autoconfigure="false" for the service.', $service->getAttribute('id'))); + } + } + + if ($files = $this->getChildren($service, 'file')) { + $definition->setFile($files[0]->nodeValue); + } + + if ($deprecated = $this->getChildren($service, 'deprecated')) { + $definition->setDeprecated(true, $deprecated[0]->nodeValue ?: null); + } + + $definition->setArguments($this->getArgumentsAsPhp($service, 'argument', $file, $definition instanceof ChildDefinition)); + $definition->setProperties($this->getArgumentsAsPhp($service, 'property', $file)); + + if ($factories = $this->getChildren($service, 'factory')) { + $factory = $factories[0]; + if ($function = $factory->getAttribute('function')) { + $definition->setFactory($function); + } else { + if ($childService = $factory->getAttribute('service')) { + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } else { + $class = $factory->hasAttribute('class') ? $factory->getAttribute('class') : null; + } + + $definition->setFactory([$class, $factory->getAttribute('method')]); + } + } + + if ($configurators = $this->getChildren($service, 'configurator')) { + $configurator = $configurators[0]; + if ($function = $configurator->getAttribute('function')) { + $definition->setConfigurator($function); + } else { + if ($childService = $configurator->getAttribute('service')) { + $class = new Reference($childService, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE); + } else { + $class = $configurator->getAttribute('class'); + } + + $definition->setConfigurator([$class, $configurator->getAttribute('method')]); + } + } + + foreach ($this->getChildren($service, 'call') as $call) { + $definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file)); + } + + $tags = $this->getChildren($service, 'tag'); + + if (!empty($defaults['tags'])) { + $tags = array_merge($tags, $defaults['tags']); + } + + foreach ($tags as $tag) { + $parameters = []; + foreach ($tag->attributes as $name => $node) { + if ('name' === $name) { + continue; + } + + if (false !== strpos($name, '-') && false === strpos($name, '_') && !\array_key_exists($normalizedName = str_replace('-', '_', $name), $parameters)) { + $parameters[$normalizedName] = XmlUtils::phpize($node->nodeValue); + } + // keep not normalized key + $parameters[$name] = XmlUtils::phpize($node->nodeValue); + } + + if ('' === $tag->getAttribute('name')) { + throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', (string) $service->getAttribute('id'), $file)); + } + + $definition->addTag($tag->getAttribute('name'), $parameters); + } + + foreach ($this->getChildren($service, 'autowiring-type') as $type) { + $definition->addAutowiringType($type->textContent); + } + + $bindings = $this->getArgumentsAsPhp($service, 'bind', $file); + if (isset($defaults['bind'])) { + // deep clone, to avoid multiple process of the same instance in the passes + $bindings = array_merge(unserialize(serialize($defaults['bind'])), $bindings); + } + if ($bindings) { + $definition->setBindings($bindings); + } + + if ($value = $service->getAttribute('decorates')) { + $renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null; + $priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0; + $definition->setDecoratedService($value, $renameId, $priority); + } + + return $definition; + } + + /** + * Parses a XML file to a \DOMDocument. + * + * @param string $file Path to a file + * + * @return \DOMDocument + * + * @throws InvalidArgumentException When loading of XML file returns error + */ + private function parseFileToDOM($file) + { + try { + $dom = XmlUtils::loadFile($file, [$this, 'validateSchema']); + } catch (\InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Unable to parse file "%s": ', $file).$e->getMessage(), $e->getCode(), $e); + } + + $this->validateExtensions($dom, $file); + + return $dom; + } + + /** + * Processes anonymous services. + * + * @param string $file + * @param array $defaults + */ + private function processAnonymousServices(\DOMDocument $xml, $file, $defaults) + { + $definitions = []; + $count = 0; + $suffix = '~'.ContainerBuilder::hash($file); + + $xpath = new \DOMXPath($xml); + $xpath->registerNamespace('container', self::NS); + + // anonymous services as arguments/properties + if (false !== $nodes = $xpath->query('//container:argument[@type="service"][not(@id)]|//container:property[@type="service"][not(@id)]|//container:bind[not(@id)]|//container:factory[not(@service)]|//container:configurator[not(@service)]')) { + foreach ($nodes as $node) { + if ($services = $this->getChildren($node, 'service')) { + // give it a unique name + $id = sprintf('%d_%s', ++$count, preg_replace('/^.*\\\\/', '', $services[0]->getAttribute('class')).$suffix); + $node->setAttribute('id', $id); + $node->setAttribute('service', $id); + + $definitions[$id] = [$services[0], $file, false]; + $services[0]->setAttribute('id', $id); + + // anonymous services are always private + // we could not use the constant false here, because of XML parsing + $services[0]->setAttribute('public', 'false'); + } + } + } + + // anonymous services "in the wild" + if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) { + foreach ($nodes as $node) { + @trigger_error(sprintf('Top-level anonymous services are deprecated since Symfony 3.4, the "id" attribute will be required in version 4.0 in %s at line %d.', $file, $node->getLineNo()), \E_USER_DEPRECATED); + + // give it a unique name + $id = sprintf('%d_%s', ++$count, preg_replace('/^.*\\\\/', '', $node->getAttribute('class')).$suffix); + $node->setAttribute('id', $id); + $definitions[$id] = [$node, $file, true]; + } + } + + // resolve definitions + uksort($definitions, 'strnatcmp'); + foreach (array_reverse($definitions) as $id => list($domElement, $file, $wild)) { + if (null !== $definition = $this->parseDefinition($domElement, $file, $wild ? $defaults : [])) { + $this->setDefinition($id, $definition); + } + + if (true === $wild) { + $tmpDomElement = new \DOMElement('_services', null, self::NS); + $domElement->parentNode->replaceChild($tmpDomElement, $domElement); + $tmpDomElement->setAttribute('id', $id); + } + } + } + + /** + * Returns arguments as valid php types. + * + * @param string $name + * @param string $file + * + * @return mixed + */ + private function getArgumentsAsPhp(\DOMElement $node, $name, $file, $isChildDefinition = false) + { + $arguments = []; + foreach ($this->getChildren($node, $name) as $arg) { + if ($arg->hasAttribute('name')) { + $arg->setAttribute('key', $arg->getAttribute('name')); + } + + // this is used by ChildDefinition to overwrite a specific + // argument of the parent definition + if ($arg->hasAttribute('index')) { + $key = ($isChildDefinition ? 'index_' : '').$arg->getAttribute('index'); + } elseif (!$arg->hasAttribute('key')) { + // Append an empty argument, then fetch its key to overwrite it later + $arguments[] = null; + $keys = array_keys($arguments); + $key = array_pop($keys); + } else { + $key = $arg->getAttribute('key'); + } + + $onInvalid = $arg->getAttribute('on-invalid'); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + if ('ignore' == $onInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } elseif ('ignore_uninitialized' == $onInvalid) { + $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + } elseif ('null' == $onInvalid) { + $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; + } + + switch ($arg->getAttribute('type')) { + case 'service': + if ('' === $arg->getAttribute('id')) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="service" has no or empty "id" attribute in "%s".', $name, $file)); + } + if ($arg->hasAttribute('strict')) { + @trigger_error(sprintf('The "strict" attribute used when referencing the "%s" service is deprecated since Symfony 3.3 and will be removed in 4.0.', $arg->getAttribute('id')), \E_USER_DEPRECATED); + } + + $arguments[$key] = new Reference($arg->getAttribute('id'), $invalidBehavior); + break; + case 'expression': + if (!class_exists(Expression::class)) { + throw new \LogicException(sprintf('The type="expression" attribute cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".')); + } + + $arguments[$key] = new Expression($arg->nodeValue); + break; + case 'collection': + $arguments[$key] = $this->getArgumentsAsPhp($arg, $name, $file); + break; + case 'iterator': + $arg = $this->getArgumentsAsPhp($arg, $name, $file); + try { + $arguments[$key] = new IteratorArgument($arg); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="iterator" only accepts collections of type="service" references in "%s".', $name, $file)); + } + break; + case 'tagged': + if (!$arg->getAttribute('tag')) { + throw new InvalidArgumentException(sprintf('Tag "<%s>" with type="tagged" has no or empty "tag" attribute in "%s".', $name, $file)); + } + $arguments[$key] = new TaggedIteratorArgument($arg->getAttribute('tag')); + break; + case 'string': + $arguments[$key] = $arg->nodeValue; + break; + case 'constant': + $arguments[$key] = \constant(trim($arg->nodeValue)); + break; + default: + $arguments[$key] = XmlUtils::phpize($arg->nodeValue); + } + } + + return $arguments; + } + + /** + * Get child elements by name. + * + * @param mixed $name + * + * @return \DOMElement[] + */ + private function getChildren(\DOMNode $node, $name) + { + $children = []; + foreach ($node->childNodes as $child) { + if ($child instanceof \DOMElement && $child->localName === $name && self::NS === $child->namespaceURI) { + $children[] = $child; + } + } + + return $children; + } + + /** + * Validates a documents XML schema. + * + * @return bool + * + * @throws RuntimeException When extension references a non-existent XSD file + */ + public function validateSchema(\DOMDocument $dom) + { + $schemaLocations = ['http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd')]; + + if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) { + $items = preg_split('/\s+/', $element); + for ($i = 0, $nb = \count($items); $i < $nb; $i += 2) { + if (!$this->container->hasExtension($items[$i])) { + continue; + } + + if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) { + $ns = $extension->getNamespace(); + $path = str_replace([$ns, str_replace('http://', 'https://', $ns)], str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]); + + if (!is_file($path)) { + throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s".', \get_class($extension), $path)); + } + + $schemaLocations[$items[$i]] = $path; + } + } + } + + $tmpfiles = []; + $imports = ''; + foreach ($schemaLocations as $namespace => $location) { + $parts = explode('/', $location); + $locationstart = 'file:///'; + if (0 === stripos($location, 'phar://')) { + $tmpfile = tempnam(sys_get_temp_dir(), 'symfony'); + if ($tmpfile) { + copy($location, $tmpfile); + $tmpfiles[] = $tmpfile; + $parts = explode('/', str_replace('\\', '/', $tmpfile)); + } else { + array_shift($parts); + $locationstart = 'phar:///'; + } + } + $drive = '\\' === \DIRECTORY_SEPARATOR ? array_shift($parts).'/' : ''; + $location = $locationstart.$drive.implode('/', array_map('rawurlencode', $parts)); + + $imports .= sprintf(' '."\n", $namespace, $location); + } + + $source = << + + + +$imports + +EOF + ; + + if (\LIBXML_VERSION < 20900) { + $disableEntities = libxml_disable_entity_loader(false); + $valid = @$dom->schemaValidateSource($source); + libxml_disable_entity_loader($disableEntities); + } else { + $valid = @$dom->schemaValidateSource($source); + } + + foreach ($tmpfiles as $tmpfile) { + @unlink($tmpfile); + } + + return $valid; + } + + /** + * Validates an alias. + * + * @param string $file + */ + private function validateAlias(\DOMElement $alias, $file) + { + foreach ($alias->attributes as $name => $node) { + if (!\in_array($name, ['alias', 'id', 'public'])) { + @trigger_error(sprintf('Using the attribute "%s" is deprecated for the service "%s" which is defined as an alias in "%s". Allowed attributes for service aliases are "alias", "id" and "public". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $name, $alias->getAttribute('id'), $file), \E_USER_DEPRECATED); + } + } + + foreach ($alias->childNodes as $child) { + if ($child instanceof \DOMElement && self::NS === $child->namespaceURI) { + @trigger_error(sprintf('Using the element "%s" is deprecated for the service "%s" which is defined as an alias in "%s". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported elements.', $child->localName, $alias->getAttribute('id'), $file), \E_USER_DEPRECATED); + } + } + } + + /** + * Validates an extension. + * + * @param string $file + * + * @throws InvalidArgumentException When no extension is found corresponding to a tag + */ + private function validateExtensions(\DOMDocument $dom, $file) + { + foreach ($dom->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) { + continue; + } + + // can it be handled by an extension? + if (!$this->container->hasExtension($node->namespaceURI)) { + $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getNamespace(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $node->tagName, $file, $node->namespaceURI, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none')); + } + } + } + + /** + * Loads from an extension. + */ + private function loadFromExtensions(\DOMDocument $xml) + { + foreach ($xml->documentElement->childNodes as $node) { + if (!$node instanceof \DOMElement || self::NS === $node->namespaceURI) { + continue; + } + + $values = static::convertDomElementToArray($node); + if (!\is_array($values)) { + $values = []; + } + + $this->container->loadFromExtension($node->namespaceURI, $values); + } + } + + /** + * Converts a \DOMElement object to a PHP array. + * + * The following rules applies during the conversion: + * + * * Each tag is converted to a key value or an array + * if there is more than one "value" + * + * * The content of a tag is set under a "value" key (bar) + * if the tag also has some nested tags + * + * * The attributes are converted to keys () + * + * * The nested-tags are converted to keys (bar) + * + * @param \DOMElement $element A \DOMElement instance + * + * @return mixed + */ + public static function convertDomElementToArray(\DOMElement $element) + { + return XmlUtils::convertDomElementToArray($element); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php new file mode 100644 index 00000000..e598bc4c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/YamlFileLoader.php @@ -0,0 +1,847 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader; + +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\ExpressionLanguage\Expression; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Parser as YamlParser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; + +/** + * YamlFileLoader loads YAML files service definitions. + * + * @author Fabien Potencier + */ +class YamlFileLoader extends FileLoader +{ + private static $serviceKeywords = [ + 'alias' => 'alias', + 'parent' => 'parent', + 'class' => 'class', + 'shared' => 'shared', + 'synthetic' => 'synthetic', + 'lazy' => 'lazy', + 'public' => 'public', + 'abstract' => 'abstract', + 'deprecated' => 'deprecated', + 'factory' => 'factory', + 'file' => 'file', + 'arguments' => 'arguments', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'decorates' => 'decorates', + 'decoration_inner_name' => 'decoration_inner_name', + 'decoration_priority' => 'decoration_priority', + 'autowire' => 'autowire', + 'autowiring_types' => 'autowiring_types', + 'autoconfigure' => 'autoconfigure', + 'bind' => 'bind', + ]; + + private static $prototypeKeywords = [ + 'resource' => 'resource', + 'namespace' => 'namespace', + 'exclude' => 'exclude', + 'parent' => 'parent', + 'shared' => 'shared', + 'lazy' => 'lazy', + 'public' => 'public', + 'abstract' => 'abstract', + 'deprecated' => 'deprecated', + 'factory' => 'factory', + 'arguments' => 'arguments', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'autowire' => 'autowire', + 'autoconfigure' => 'autoconfigure', + 'bind' => 'bind', + ]; + + private static $instanceofKeywords = [ + 'shared' => 'shared', + 'lazy' => 'lazy', + 'public' => 'public', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'autowire' => 'autowire', + ]; + + private static $defaultsKeywords = [ + 'public' => 'public', + 'tags' => 'tags', + 'autowire' => 'autowire', + 'autoconfigure' => 'autoconfigure', + 'bind' => 'bind', + ]; + + private $yamlParser; + + private $anonymousServicesCount; + private $anonymousServicesSuffix; + + /** + * {@inheritdoc} + */ + public function load($resource, $type = null) + { + $path = $this->locator->locate($resource); + + $content = $this->loadFile($path); + + $this->container->fileExists($path); + + // empty file + if (null === $content) { + return; + } + + // imports + $this->parseImports($content, $path); + + // parameters + if (isset($content['parameters'])) { + if (!\is_array($content['parameters'])) { + throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in "%s". Check your YAML syntax.', $path)); + } + + foreach ($content['parameters'] as $key => $value) { + $this->container->setParameter($key, $this->resolveServices($value, $path, true)); + } + } + + // extensions + $this->loadFromExtensions($content); + + // services + $this->anonymousServicesCount = 0; + $this->anonymousServicesSuffix = '~'.ContainerBuilder::hash($path); + $this->setCurrentDir(\dirname($path)); + try { + $this->parseDefinitions($content, $path); + } finally { + $this->instanceof = []; + } + } + + /** + * {@inheritdoc} + */ + public function supports($resource, $type = null) + { + if (!\is_string($resource)) { + return false; + } + + if (null === $type && \in_array(pathinfo($resource, \PATHINFO_EXTENSION), ['yaml', 'yml'], true)) { + return true; + } + + return \in_array($type, ['yaml', 'yml'], true); + } + + /** + * Parses all imports. + * + * @param string $file + */ + private function parseImports(array $content, $file) + { + if (!isset($content['imports'])) { + return; + } + + if (!\is_array($content['imports'])) { + throw new InvalidArgumentException(sprintf('The "imports" key should contain an array in "%s". Check your YAML syntax.', $file)); + } + + $defaultDirectory = \dirname($file); + foreach ($content['imports'] as $import) { + if (!\is_array($import)) { + $import = ['resource' => $import]; + } + if (!isset($import['resource'])) { + throw new InvalidArgumentException(sprintf('An import should provide a resource in "%s". Check your YAML syntax.', $file)); + } + + $this->setCurrentDir($defaultDirectory); + $this->import($import['resource'], isset($import['type']) ? $import['type'] : null, isset($import['ignore_errors']) ? (bool) $import['ignore_errors'] : false, $file); + } + } + + /** + * Parses definitions. + * + * @param string $file + */ + private function parseDefinitions(array $content, $file) + { + if (!isset($content['services'])) { + return; + } + + if (!\is_array($content['services'])) { + throw new InvalidArgumentException(sprintf('The "services" key should contain an array in "%s". Check your YAML syntax.', $file)); + } + + if (\array_key_exists('_instanceof', $content['services'])) { + $instanceof = $content['services']['_instanceof']; + unset($content['services']['_instanceof']); + + if (!\is_array($instanceof)) { + throw new InvalidArgumentException(sprintf('Service "_instanceof" key must be an array, "%s" given in "%s".', \gettype($instanceof), $file)); + } + $this->instanceof = []; + $this->isLoadingInstanceof = true; + foreach ($instanceof as $id => $service) { + if (!$service || !\is_array($service)) { + throw new InvalidArgumentException(sprintf('Type definition "%s" must be a non-empty array within "_instanceof" in "%s". Check your YAML syntax.', $id, $file)); + } + if (\is_string($service) && 0 === strpos($service, '@')) { + throw new InvalidArgumentException(sprintf('Type definition "%s" cannot be an alias within "_instanceof" in "%s". Check your YAML syntax.', $id, $file)); + } + $this->parseDefinition($id, $service, $file, []); + } + } + + $this->isLoadingInstanceof = false; + $defaults = $this->parseDefaults($content, $file); + foreach ($content['services'] as $id => $service) { + $this->parseDefinition($id, $service, $file, $defaults); + } + } + + /** + * @param string $file + * + * @return array + * + * @throws InvalidArgumentException + */ + private function parseDefaults(array &$content, $file) + { + if (!\array_key_exists('_defaults', $content['services'])) { + return []; + } + $defaults = $content['services']['_defaults']; + unset($content['services']['_defaults']); + + if (!\is_array($defaults)) { + throw new InvalidArgumentException(sprintf('Service "_defaults" key must be an array, "%s" given in "%s".', \gettype($defaults), $file)); + } + + foreach ($defaults as $key => $default) { + if (!isset(self::$defaultsKeywords[$key])) { + throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', self::$defaultsKeywords))); + } + } + + if (isset($defaults['tags'])) { + if (!\is_array($tags = $defaults['tags'])) { + throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in "%s". Check your YAML syntax.', $file)); + } + + foreach ($tags as $tag) { + if (!\is_array($tag)) { + $tag = ['name' => $tag]; + } + + if (!isset($tag['name'])) { + throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in "%s".', $file)); + } + $name = $tag['name']; + unset($tag['name']); + + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in "%s".', $file)); + } + + foreach ($tag as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type in "%s". Check your YAML syntax.', $name, $attribute, $file)); + } + } + } + } + + if (isset($defaults['bind'])) { + if (!\is_array($defaults['bind'])) { + throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in "%s". Check your YAML syntax.', $file)); + } + + $defaults['bind'] = array_map(function ($v) { return new BoundArgument($v); }, $this->resolveServices($defaults['bind'], $file)); + } + + return $defaults; + } + + /** + * @return bool + */ + private function isUsingShortSyntax(array $service) + { + foreach ($service as $key => $value) { + if (\is_string($key) && ('' === $key || '$' !== $key[0])) { + return false; + } + } + + return true; + } + + /** + * Parses a definition. + * + * @param string $id + * @param array|string $service + * @param string $file + * + * @throws InvalidArgumentException When tags are invalid + */ + private function parseDefinition($id, $service, $file, array $defaults) + { + if (preg_match('/^_[a-zA-Z0-9_]*$/', $id)) { + @trigger_error(sprintf('Service names that start with an underscore are deprecated since Symfony 3.3 and will be reserved in 4.0. Rename the "%s" service or define it in XML instead.', $id), \E_USER_DEPRECATED); + } + if (\is_string($service) && 0 === strpos($service, '@')) { + $this->container->setAlias($id, $alias = new Alias(substr($service, 1))); + if (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + + return; + } + + if (\is_array($service) && $this->isUsingShortSyntax($service)) { + $service = ['arguments' => $service]; + } + + if (null === $service) { + $service = []; + } + + if (!\is_array($service)) { + throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but "%s" found for service "%s" in "%s". Check your YAML syntax.', \gettype($service), $id, $file)); + } + + $this->checkDefinition($id, $service, $file); + + if (isset($service['alias'])) { + $this->container->setAlias($id, $alias = new Alias($service['alias'])); + if (isset($service['public'])) { + $alias->setPublic($service['public']); + } elseif (isset($defaults['public'])) { + $alias->setPublic($defaults['public']); + } + + foreach ($service as $key => $value) { + if (!\in_array($key, ['alias', 'public'])) { + @trigger_error(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), \E_USER_DEPRECATED); + } + } + + return; + } + + if ($this->isLoadingInstanceof) { + $definition = new ChildDefinition(''); + } elseif (isset($service['parent'])) { + if (!empty($this->instanceof)) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "_instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.', $id)); + } + + foreach ($defaults as $k => $v) { + if ('tags' === $k) { + // since tags are never inherited from parents, there is no confusion + // thus we can safely add them as defaults to ChildDefinition + continue; + } + if ('bind' === $k) { + throw new InvalidArgumentException(sprintf('Attribute "bind" on service "%s" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file.', $id)); + } + if (!isset($service[$k])) { + throw new InvalidArgumentException(sprintf('Attribute "%s" on service "%s" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.', $k, $id)); + } + } + + $definition = new ChildDefinition($service['parent']); + } else { + $definition = new Definition(); + + if (isset($defaults['public'])) { + $definition->setPublic($defaults['public']); + } + if (isset($defaults['autowire'])) { + $definition->setAutowired($defaults['autowire']); + } + if (isset($defaults['autoconfigure'])) { + $definition->setAutoconfigured($defaults['autoconfigure']); + } + + $definition->setChanges([]); + } + + if (isset($service['class'])) { + $definition->setClass($service['class']); + } + + if (isset($service['shared'])) { + $definition->setShared($service['shared']); + } + + if (isset($service['synthetic'])) { + $definition->setSynthetic($service['synthetic']); + } + + if (isset($service['lazy'])) { + $definition->setLazy($service['lazy']); + } + + if (isset($service['public'])) { + $definition->setPublic($service['public']); + } + + if (isset($service['abstract'])) { + $definition->setAbstract($service['abstract']); + } + + if (\array_key_exists('deprecated', $service)) { + $definition->setDeprecated(true, $service['deprecated']); + } + + if (isset($service['factory'])) { + $definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file)); + } + + if (isset($service['file'])) { + $definition->setFile($service['file']); + } + + if (isset($service['arguments'])) { + $definition->setArguments($this->resolveServices($service['arguments'], $file)); + } + + if (isset($service['properties'])) { + $definition->setProperties($this->resolveServices($service['properties'], $file)); + } + + if (isset($service['configurator'])) { + $definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file)); + } + + if (isset($service['calls'])) { + if (!\is_array($service['calls'])) { + throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + + foreach ($service['calls'] as $call) { + if (isset($call['method'])) { + $method = $call['method']; + $args = isset($call['arguments']) ? $this->resolveServices($call['arguments'], $file) : []; + } else { + $method = $call[0]; + $args = isset($call[1]) ? $this->resolveServices($call[1], $file) : []; + } + + if (!\is_array($args)) { + throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in "%s". Check your YAML syntax.', $method, $id, $file)); + } + $definition->addMethodCall($method, $args); + } + } + + $tags = isset($service['tags']) ? $service['tags'] : []; + if (!\is_array($tags)) { + throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + + if (isset($defaults['tags'])) { + $tags = array_merge($tags, $defaults['tags']); + } + + foreach ($tags as $tag) { + if (!\is_array($tag)) { + $tag = ['name' => $tag]; + } + + if (!isset($tag['name'])) { + throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in "%s".', $id, $file)); + } + $name = $tag['name']; + unset($tag['name']); + + if (!\is_string($name) || '' === $name) { + throw new InvalidArgumentException(sprintf('The tag name for service "%s" in "%s" must be a non-empty string.', $id, $file)); + } + + foreach ($tag as $attribute => $value) { + if (!is_scalar($value) && null !== $value) { + throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in "%s". Check your YAML syntax.', $id, $name, $attribute, $file)); + } + } + + $definition->addTag($name, $tag); + } + + if (isset($service['decorates'])) { + if ('' !== $service['decorates'] && '@' === $service['decorates'][0]) { + throw new InvalidArgumentException(sprintf('The value of the "decorates" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $id, $service['decorates'], substr($service['decorates'], 1))); + } + + $renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null; + $priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0; + $definition->setDecoratedService($service['decorates'], $renameId, $priority); + } + + if (isset($service['autowire'])) { + $definition->setAutowired($service['autowire']); + } + + if (isset($service['autowiring_types'])) { + if (\is_string($service['autowiring_types'])) { + $definition->addAutowiringType($service['autowiring_types']); + } else { + if (!\is_array($service['autowiring_types'])) { + throw new InvalidArgumentException(sprintf('Parameter "autowiring_types" must be a string or an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + + foreach ($service['autowiring_types'] as $autowiringType) { + if (!\is_string($autowiringType)) { + throw new InvalidArgumentException(sprintf('A "autowiring_types" attribute must be of type string for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + + $definition->addAutowiringType($autowiringType); + } + } + } + + if (isset($defaults['bind']) || isset($service['bind'])) { + // deep clone, to avoid multiple process of the same instance in the passes + $bindings = isset($defaults['bind']) ? unserialize(serialize($defaults['bind'])) : []; + + if (isset($service['bind'])) { + if (!\is_array($service['bind'])) { + throw new InvalidArgumentException(sprintf('Parameter "bind" must be an array for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + + $bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file)); + } + + $definition->setBindings($bindings); + } + + if (isset($service['autoconfigure'])) { + if (!$definition instanceof ChildDefinition) { + $definition->setAutoconfigured($service['autoconfigure']); + } elseif ($service['autoconfigure']) { + throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting "autoconfigure: false" for the service.', $id)); + } + } + + if (\array_key_exists('namespace', $service) && !\array_key_exists('resource', $service)) { + throw new InvalidArgumentException(sprintf('A "resource" attribute must be set when the "namespace" attribute is set for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + + if (\array_key_exists('resource', $service)) { + if (!\is_string($service['resource'])) { + throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in "%s". Check your YAML syntax.', $id, $file)); + } + $exclude = isset($service['exclude']) ? $service['exclude'] : null; + $namespace = isset($service['namespace']) ? $service['namespace'] : $id; + $this->registerClasses($definition, $namespace, $service['resource'], $exclude); + } else { + $this->setDefinition($id, $definition); + } + } + + /** + * Parses a callable. + * + * @param string|array $callable A callable + * @param string $parameter A parameter (e.g. 'factory' or 'configurator') + * @param string $id A service identifier + * @param string $file A parsed file + * + * @throws InvalidArgumentException When errors occur + * + * @return string|array A parsed callable + */ + private function parseCallable($callable, $parameter, $id, $file) + { + if (\is_string($callable)) { + if ('' !== $callable && '@' === $callable[0]) { + throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $parameter, $id, $callable, substr($callable, 1))); + } + + if (false !== strpos($callable, ':') && false === strpos($callable, '::')) { + $parts = explode(':', $callable); + + return [$this->resolveServices('@'.$parts[0], $file), $parts[1]]; + } + + return $callable; + } + + if (\is_array($callable)) { + if (isset($callable[0]) && isset($callable[1])) { + return [$this->resolveServices($callable[0], $file), $callable[1]]; + } + + if ('factory' === $parameter && isset($callable[1]) && null === $callable[0]) { + return $callable; + } + + throw new InvalidArgumentException(sprintf('Parameter "%s" must contain an array with two elements for service "%s" in "%s". Check your YAML syntax.', $parameter, $id, $file)); + } + + throw new InvalidArgumentException(sprintf('Parameter "%s" must be a string or an array for service "%s" in "%s". Check your YAML syntax.', $parameter, $id, $file)); + } + + /** + * Loads a YAML file. + * + * @param string $file + * + * @return array The file content + * + * @throws InvalidArgumentException when the given file is not a local file or when it does not exist + */ + protected function loadFile($file) + { + if (!class_exists('Symfony\Component\Yaml\Parser')) { + throw new RuntimeException('Unable to load YAML config files as the Symfony Yaml Component is not installed.'); + } + + if (!stream_is_local($file)) { + throw new InvalidArgumentException(sprintf('This is not a local file "%s".', $file)); + } + + if (!file_exists($file)) { + throw new InvalidArgumentException(sprintf('The file "%s" does not exist.', $file)); + } + + if (null === $this->yamlParser) { + $this->yamlParser = new YamlParser(); + } + + $prevErrorHandler = set_error_handler(function ($level, $message, $script, $line) use ($file, &$prevErrorHandler) { + $message = \E_USER_DEPRECATED === $level ? preg_replace('/ on line \d+/', ' in "'.$file.'"$0', $message) : $message; + + return $prevErrorHandler ? $prevErrorHandler($level, $message, $script, $line) : false; + }); + + try { + $configuration = $this->yamlParser->parseFile($file, Yaml::PARSE_CONSTANT | Yaml::PARSE_CUSTOM_TAGS); + } catch (ParseException $e) { + throw new InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML: ', $file).$e->getMessage(), 0, $e); + } finally { + restore_error_handler(); + } + + return $this->validate($configuration, $file); + } + + /** + * Validates a YAML file. + * + * @param mixed $content + * @param string $file + * + * @return array + * + * @throws InvalidArgumentException When service file is not valid + */ + private function validate($content, $file) + { + if (null === $content) { + return $content; + } + + if (!\is_array($content)) { + throw new InvalidArgumentException(sprintf('The service file "%s" is not valid. It should contain an array. Check your YAML syntax.', $file)); + } + + foreach ($content as $namespace => $data) { + if (\in_array($namespace, ['imports', 'parameters', 'services'])) { + continue; + } + + if (!$this->container->hasExtension($namespace)) { + $extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions())); + throw new InvalidArgumentException(sprintf('There is no extension able to load the configuration for "%s" (in "%s"). Looked for namespace "%s", found "%s".', $namespace, $file, $namespace, $extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none')); + } + } + + return $content; + } + + /** + * Resolves services. + * + * @param mixed $value + * @param string $file + * @param bool $isParameter + * + * @return array|string|Reference|ArgumentInterface + */ + private function resolveServices($value, $file, $isParameter = false) + { + if ($value instanceof TaggedValue) { + $argument = $value->getValue(); + if ('iterator' === $value->getTag()) { + if (!\is_array($argument)) { + throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts sequences in "%s".', $file)); + } + $argument = $this->resolveServices($argument, $file, $isParameter); + try { + return new IteratorArgument($argument); + } catch (InvalidArgumentException $e) { + throw new InvalidArgumentException(sprintf('"!iterator" tag only accepts arrays of "@service" references in "%s".', $file)); + } + } + if ('tagged' === $value->getTag()) { + if (!\is_string($argument) || !$argument) { + throw new InvalidArgumentException(sprintf('"!tagged" tag only accepts non empty string in "%s".', $file)); + } + + return new TaggedIteratorArgument($argument); + } + if ('service' === $value->getTag()) { + if ($isParameter) { + throw new InvalidArgumentException(sprintf('Using an anonymous service in a parameter is not allowed in "%s".', $file)); + } + + $isLoadingInstanceof = $this->isLoadingInstanceof; + $this->isLoadingInstanceof = false; + $instanceof = $this->instanceof; + $this->instanceof = []; + + $id = sprintf('%d_%s', ++$this->anonymousServicesCount, preg_replace('/^.*\\\\/', '', isset($argument['class']) ? $argument['class'] : '').$this->anonymousServicesSuffix); + $this->parseDefinition($id, $argument, $file, []); + + if (!$this->container->hasDefinition($id)) { + throw new InvalidArgumentException(sprintf('Creating an alias using the tag "!service" is not allowed in "%s".', $file)); + } + + $this->container->getDefinition($id)->setPublic(false); + + $this->isLoadingInstanceof = $isLoadingInstanceof; + $this->instanceof = $instanceof; + + return new Reference($id); + } + + throw new InvalidArgumentException(sprintf('Unsupported tag "!%s".', $value->getTag())); + } + + if (\is_array($value)) { + foreach ($value as $k => $v) { + $value[$k] = $this->resolveServices($v, $file, $isParameter); + } + } elseif (\is_string($value) && 0 === strpos($value, '@=')) { + if (!class_exists(Expression::class)) { + throw new \LogicException(sprintf('The "@=" expression syntax cannot be used without the ExpressionLanguage component. Try running "composer require symfony/expression-language".')); + } + + return new Expression(substr($value, 2)); + } elseif (\is_string($value) && 0 === strpos($value, '@')) { + if (0 === strpos($value, '@@')) { + $value = substr($value, 1); + $invalidBehavior = null; + } elseif (0 === strpos($value, '@!')) { + $value = substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE; + } elseif (0 === strpos($value, '@?')) { + $value = substr($value, 2); + $invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE; + } else { + $value = substr($value, 1); + $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE; + } + + if ('=' === substr($value, -1)) { + @trigger_error(sprintf('The "=" suffix that used to disable strict references in Symfony 2.x is deprecated since Symfony 3.3 and will be unsupported in 4.0. Remove it in "%s".', $value), \E_USER_DEPRECATED); + $value = substr($value, 0, -1); + } + + if (null !== $invalidBehavior) { + $value = new Reference($value, $invalidBehavior); + } + } + + return $value; + } + + /** + * Loads from Extensions. + */ + private function loadFromExtensions(array $content) + { + foreach ($content as $namespace => $values) { + if (\in_array($namespace, ['imports', 'parameters', 'services'])) { + continue; + } + + if (!\is_array($values) && null !== $values) { + $values = []; + } + + $this->container->loadFromExtension($namespace, $values); + } + } + + /** + * Checks the keywords used to define a service. + * + * @param string $id The service name + * @param array $definition The service definition to check + * @param string $file The loaded YAML file + */ + private function checkDefinition($id, array $definition, $file) + { + if ($throw = $this->isLoadingInstanceof) { + $keywords = self::$instanceofKeywords; + } elseif ($throw = (isset($definition['resource']) || isset($definition['namespace']))) { + $keywords = self::$prototypeKeywords; + } else { + $keywords = self::$serviceKeywords; + } + + foreach ($definition as $key => $value) { + if (!isset($keywords[$key])) { + if ($throw) { + throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', $keywords))); + } + + @trigger_error(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s". The YamlFileLoader object will raise an exception instead in Symfony 4.0 when detecting an unsupported service configuration key.', $key, $id, $file, implode('", "', $keywords)), \E_USER_DEPRECATED); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd new file mode 100644 index 00000000..3a55a7df --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Loader/schema/dic/services/services-1.0.xsd @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Parameter.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Parameter.php new file mode 100644 index 00000000..cac6f6c4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Parameter.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Parameter represents a parameter reference. + * + * @author Fabien Potencier + */ +class Parameter +{ + private $id; + + /** + * @param string $id The parameter key + */ + public function __construct($id) + { + $this->id = $id; + } + + /** + * @return string The parameter key + */ + public function __toString() + { + return (string) $this->id; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php new file mode 100644 index 00000000..c4e369b0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/EnvPlaceholderParameterBag.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * @author Nicolas Grekas + */ +class EnvPlaceholderParameterBag extends ParameterBag +{ + private $envPlaceholders = []; + private $providedTypes = []; + + /** + * {@inheritdoc} + */ + public function get($name) + { + if (0 === strpos($name, 'env(') && ')' === substr($name, -1) && 'env()' !== $name) { + $env = substr($name, 4, -1); + + if (isset($this->envPlaceholders[$env])) { + foreach ($this->envPlaceholders[$env] as $placeholder) { + return $placeholder; // return first result + } + } + if (!preg_match('/^(?:\w++:)*+\w++$/', $env)) { + throw new InvalidArgumentException(sprintf('Invalid "%s" name: only "word" characters are allowed.', $name)); + } + + if ($this->has($name)) { + $defaultValue = parent::get($name); + + if (null !== $defaultValue && !is_scalar($defaultValue)) { + throw new RuntimeException(sprintf('The default value of an env() parameter must be scalar or null, but "%s" given to "%s".', \gettype($defaultValue), $name)); + } + } + + $uniqueName = md5($name.uniqid(mt_rand(), true)); + $placeholder = sprintf('env_%s_%s', str_replace(':', '_', $env), $uniqueName); + $this->envPlaceholders[$env][$placeholder] = $placeholder; + + return $placeholder; + } + + return parent::get($name); + } + + /** + * Returns the map of env vars used in the resolved parameter values to their placeholders. + * + * @return string[][] A map of env var names to their placeholders + */ + public function getEnvPlaceholders() + { + return $this->envPlaceholders; + } + + /** + * Merges the env placeholders of another EnvPlaceholderParameterBag. + */ + public function mergeEnvPlaceholders(self $bag) + { + if ($newPlaceholders = $bag->getEnvPlaceholders()) { + $this->envPlaceholders += $newPlaceholders; + + foreach ($newPlaceholders as $env => $placeholders) { + $this->envPlaceholders[$env] += $placeholders; + } + } + } + + /** + * Maps env prefixes to their corresponding PHP types. + */ + public function setProvidedTypes(array $providedTypes) + { + $this->providedTypes = $providedTypes; + } + + /** + * Gets the PHP types corresponding to env() parameter prefixes. + * + * @return string[][] + */ + public function getProvidedTypes() + { + return $this->providedTypes; + } + + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + parent::resolve(); + + foreach ($this->envPlaceholders as $env => $placeholders) { + if (!$this->has($name = "env($env)")) { + continue; + } + if (is_numeric($default = $this->parameters[$name])) { + $this->parameters[$name] = (string) $default; + } elseif (null !== $default && !is_scalar($default)) { + throw new RuntimeException(sprintf('The default value of env parameter "%s" must be scalar or null, "%s" given.', $env, \gettype($default))); + } + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php new file mode 100644 index 00000000..a5199937 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/FrozenParameterBag.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\LogicException; + +/** + * Holds read-only parameters. + * + * @author Fabien Potencier + */ +class FrozenParameterBag extends ParameterBag +{ + /** + * For performance reasons, the constructor assumes that + * all keys are already lowercased. + * + * This is always the case when used internally. + * + * @param array $parameters An array of parameters + */ + public function __construct(array $parameters = []) + { + $this->parameters = $parameters; + $this->resolved = true; + } + + /** + * {@inheritdoc} + */ + public function clear() + { + throw new LogicException('Impossible to call clear() on a frozen ParameterBag.'); + } + + /** + * {@inheritdoc} + */ + public function add(array $parameters) + { + throw new LogicException('Impossible to call add() on a frozen ParameterBag.'); + } + + /** + * {@inheritdoc} + */ + public function set($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + /** + * {@inheritdoc} + */ + public function remove($name) + { + throw new LogicException('Impossible to call remove() on a frozen ParameterBag.'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php new file mode 100644 index 00000000..24dc8035 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/ParameterBag.php @@ -0,0 +1,307 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; + +/** + * Holds parameters. + * + * @author Fabien Potencier + */ +class ParameterBag implements ParameterBagInterface +{ + protected $parameters = []; + protected $resolved = false; + + private $normalizedNames = []; + + /** + * @param array $parameters An array of parameters + */ + public function __construct(array $parameters = []) + { + $this->add($parameters); + } + + /** + * Clears all parameters. + */ + public function clear() + { + $this->parameters = []; + } + + /** + * Adds parameters to the service container parameters. + * + * @param array $parameters An array of parameters + */ + public function add(array $parameters) + { + foreach ($parameters as $key => $value) { + $this->set($key, $value); + } + } + + /** + * {@inheritdoc} + */ + public function all() + { + return $this->parameters; + } + + /** + * {@inheritdoc} + */ + public function get($name) + { + $name = $this->normalizeName($name); + + if (!\array_key_exists($name, $this->parameters)) { + if (!$name) { + throw new ParameterNotFoundException($name); + } + + $alternatives = []; + foreach ($this->parameters as $key => $parameterValue) { + $lev = levenshtein($name, $key); + if ($lev <= \strlen($name) / 3 || false !== strpos($key, $name)) { + $alternatives[] = $key; + } + } + + $nonNestedAlternative = null; + if (!\count($alternatives) && false !== strpos($name, '.')) { + $namePartsLength = array_map('strlen', explode('.', $name)); + $key = substr($name, 0, -1 * (1 + array_pop($namePartsLength))); + while (\count($namePartsLength)) { + if ($this->has($key)) { + if (\is_array($this->get($key))) { + $nonNestedAlternative = $key; + } + break; + } + + $key = substr($key, 0, -1 * (1 + array_pop($namePartsLength))); + } + } + + throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative); + } + + return $this->parameters[$name]; + } + + /** + * Sets a service container parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + */ + public function set($name, $value) + { + $this->parameters[$this->normalizeName($name)] = $value; + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return \array_key_exists($this->normalizeName($name), $this->parameters); + } + + /** + * Removes a parameter. + * + * @param string $name The parameter name + */ + public function remove($name) + { + unset($this->parameters[$this->normalizeName($name)]); + } + + /** + * {@inheritdoc} + */ + public function resolve() + { + if ($this->resolved) { + return; + } + + $parameters = []; + foreach ($this->parameters as $key => $value) { + try { + $value = $this->resolveValue($value); + $parameters[$key] = $this->unescapeValue($value); + } catch (ParameterNotFoundException $e) { + $e->setSourceKey($key); + + throw $e; + } + } + + $this->parameters = $parameters; + $this->resolved = true; + } + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @return mixed The resolved value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem + */ + public function resolveValue($value, array $resolving = []) + { + if (\is_array($value)) { + $args = []; + foreach ($value as $k => $v) { + $args[\is_string($k) ? $this->resolveValue($k, $resolving) : $k] = $this->resolveValue($v, $resolving); + } + + return $args; + } + + if (!\is_string($value) || 2 > \strlen($value)) { + return $value; + } + + return $this->resolveString($value, $resolving); + } + + /** + * Resolves parameters inside a string. + * + * @param string $value The string to resolve + * @param array $resolving An array of keys that are being resolved (used internally to detect circular references) + * + * @return mixed The resolved string + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + * @throws ParameterCircularReferenceException if a circular reference if detected + * @throws RuntimeException when a given parameter has a type problem + */ + public function resolveString($value, array $resolving = []) + { + // we do this to deal with non string values (Boolean, integer, ...) + // as the preg_replace_callback throw an exception when trying + // a non-string in a parameter value + if (preg_match('/^%([^%\s]+)%$/', $value, $match)) { + $key = $match[1]; + $lcKey = strtolower($key); // strtolower() to be removed in 4.0 + + if (isset($resolving[$lcKey])) { + throw new ParameterCircularReferenceException(array_keys($resolving)); + } + + $resolving[$lcKey] = true; + + return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving); + } + + return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($resolving, $value) { + // skip %% + if (!isset($match[1])) { + return '%%'; + } + + $key = $match[1]; + $lcKey = strtolower($key); // strtolower() to be removed in 4.0 + if (isset($resolving[$lcKey])) { + throw new ParameterCircularReferenceException(array_keys($resolving)); + } + + $resolved = $this->get($key); + + if (!\is_string($resolved) && !is_numeric($resolved)) { + throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type "%s" inside string value "%s".', $key, \gettype($resolved), $value)); + } + + $resolved = (string) $resolved; + $resolving[$lcKey] = true; + + return $this->isResolved() ? $resolved : $this->resolveString($resolved, $resolving); + }, $value); + } + + public function isResolved() + { + return $this->resolved; + } + + /** + * {@inheritdoc} + */ + public function escapeValue($value) + { + if (\is_string($value)) { + return str_replace('%', '%%', $value); + } + + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[$k] = $this->escapeValue($v); + } + + return $result; + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function unescapeValue($value) + { + if (\is_string($value)) { + return str_replace('%%', '%', $value); + } + + if (\is_array($value)) { + $result = []; + foreach ($value as $k => $v) { + $result[$k] = $this->unescapeValue($v); + } + + return $result; + } + + return $value; + } + + private function normalizeName($name) + { + if (isset($this->normalizedNames[$normalizedName = strtolower($name)])) { + $normalizedName = $this->normalizedNames[$normalizedName]; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), \E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php new file mode 100644 index 00000000..7386df06 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ParameterBag/ParameterBagInterface.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\ParameterBag; + +use Symfony\Component\DependencyInjection\Exception\LogicException; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +/** + * ParameterBagInterface. + * + * @author Fabien Potencier + */ +interface ParameterBagInterface +{ + /** + * Clears all parameters. + * + * @throws LogicException if the ParameterBagInterface can not be cleared + */ + public function clear(); + + /** + * Adds parameters to the service container parameters. + * + * @param array $parameters An array of parameters + * + * @throws LogicException if the parameter can not be added + */ + public function add(array $parameters); + + /** + * Gets the service container parameters. + * + * @return array An array of parameters + */ + public function all(); + + /** + * Gets a service container parameter. + * + * @param string $name The parameter name + * + * @return mixed The parameter value + * + * @throws ParameterNotFoundException if the parameter is not defined + */ + public function get($name); + + /** + * Removes a parameter. + * + * @param string $name The parameter name + */ + public function remove($name); + + /** + * Sets a service container parameter. + * + * @param string $name The parameter name + * @param mixed $value The parameter value + * + * @throws LogicException if the parameter can not be set + */ + public function set($name, $value); + + /** + * Returns true if a parameter name is defined. + * + * @param string $name The parameter name + * + * @return bool true if the parameter name is defined, false otherwise + */ + public function has($name); + + /** + * Replaces parameter placeholders (%name%) by their values for all parameters. + */ + public function resolve(); + + /** + * Replaces parameter placeholders (%name%) by their values. + * + * @param mixed $value A value + * + * @throws ParameterNotFoundException if a placeholder references a parameter that does not exist + */ + public function resolveValue($value); + + /** + * Escape parameter placeholders %. + * + * @param mixed $value + * + * @return mixed + */ + public function escapeValue($value); + + /** + * Unescape parameter placeholders %. + * + * @param mixed $value + * + * @return mixed + */ + public function unescapeValue($value); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/README.md b/modules/empikmarketplace/vendor/symfony/dependency-injection/README.md new file mode 100644 index 00000000..cb2d4a11 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/README.md @@ -0,0 +1,14 @@ +DependencyInjection Component +============================= + +The DependencyInjection component allows you to standardize and centralize the +way objects are constructed in your application. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/dependency_injection.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Reference.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Reference.php new file mode 100644 index 00000000..82906d2b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Reference.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Reference represents a service reference. + * + * @author Fabien Potencier + */ +class Reference +{ + private $id; + private $invalidBehavior; + + /** + * @param string $id The service identifier + * @param int $invalidBehavior The behavior when the service does not exist + * + * @see Container + */ + public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + $this->id = (string) $id; + $this->invalidBehavior = $invalidBehavior; + } + + /** + * @return string The service identifier + */ + public function __toString() + { + return $this->id; + } + + /** + * Returns the behavior to be used when the service does not exist. + * + * @return int + */ + public function getInvalidBehavior() + { + return $this->invalidBehavior; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ResettableContainerInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ResettableContainerInterface.php new file mode 100644 index 00000000..b74e6762 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ResettableContainerInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * ResettableContainerInterface defines additional resetting functionality + * for containers, allowing to release shared services when the container is + * not needed anymore. + * + * @author Christophe Coevoet + */ +interface ResettableContainerInterface extends ContainerInterface +{ + /** + * Resets shared services from the container. + * + * The container is not intended to be used again after being reset in a normal workflow. This method is + * meant as a way to release references for ref-counting. + * A subsequent call to ContainerInterface::get will recreate a new instance of the shared service. + */ + public function reset(); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ServiceLocator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ServiceLocator.php new file mode 100644 index 00000000..80be44eb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ServiceLocator.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; + +/** + * @author Robin Chalas + * @author Nicolas Grekas + */ +class ServiceLocator implements PsrContainerInterface +{ + private $factories; + private $loading = []; + private $externalId; + private $container; + + /** + * @param callable[] $factories + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + + /** + * {@inheritdoc} + */ + public function has($id) + { + return isset($this->factories[$id]); + } + + /** + * {@inheritdoc} + */ + public function get($id) + { + if (!isset($this->factories[$id])) { + throw new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], $this->createServiceNotFoundMessage($id)); + } + + if (isset($this->loading[$id])) { + $ids = array_values($this->loading); + $ids = \array_slice($this->loading, array_search($id, $ids)); + $ids[] = $id; + + throw new ServiceCircularReferenceException($id, $ids); + } + + $this->loading[$id] = $id; + try { + return $this->factories[$id](); + } finally { + unset($this->loading[$id]); + } + } + + public function __invoke($id) + { + return isset($this->factories[$id]) ? $this->get($id) : null; + } + + /** + * @internal + */ + public function withContext($externalId, Container $container) + { + $locator = clone $this; + $locator->externalId = $externalId; + $locator->container = $container; + + return $locator; + } + + private function createServiceNotFoundMessage($id) + { + if ($this->loading) { + return sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $this->formatAlternatives()); + } + + $class = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 3); + $class = isset($class[2]['object']) ? \get_class($class[2]['object']) : null; + $externalId = $this->externalId ?: $class; + + $msg = []; + $msg[] = sprintf('Service "%s" not found:', $id); + + if (!$this->container) { + $class = null; + } elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) { + $msg[] = 'even though it exists in the app\'s container,'; + } else { + try { + $this->container->get($id); + $class = null; + } catch (ServiceNotFoundException $e) { + if ($e->getAlternatives()) { + $msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or')); + } else { + $class = null; + } + } + } + if ($externalId) { + $msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives()); + } else { + $msg[] = sprintf('the current service locator %s', $this->formatAlternatives()); + } + + if (!$class) { + // no-op + } elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) { + $msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class)); + } else { + $msg[] = 'Try using dependency injection instead.'; + } + + return implode(' ', $msg); + } + + private function formatAlternatives(array $alternatives = null, $separator = 'and') + { + $format = '"%s"%s'; + if (null === $alternatives) { + if (!$alternatives = array_keys($this->factories)) { + return 'is empty...'; + } + $format = sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : ''); + } + $last = array_pop($alternatives); + + return sprintf($format, $alternatives ? implode('", "', $alternatives) : $last, $alternatives ? sprintf(' %s "%s"', $separator, $last) : ''); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/ServiceSubscriberInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/ServiceSubscriberInterface.php new file mode 100644 index 00000000..10c23875 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/ServiceSubscriberInterface.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method. + * + * The getSubscribedServices method returns an array of service types required by such instances, + * optionally keyed by the service names used internally. Service types that start with an interrogation + * mark "?" are optional, while the other ones are mandatory service dependencies. + * + * The injected service locators SHOULD NOT allow access to any other services not specified by the method. + * + * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally. + * This interface does not dictate any injection method for these service locators, although constructor + * injection is recommended. + * + * @author Nicolas Grekas + */ +interface ServiceSubscriberInterface +{ + /** + * Returns an array of service types required by such instances, optionally keyed by the service names used internally. + * + * For mandatory dependencies: + * + * * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name + * internally to fetch a service which must implement Psr\Log\LoggerInterface. + * * ['Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface'] + * + * otherwise: + * + * * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency + * * ['?Psr\Log\LoggerInterface'] is a shortcut for + * * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface'] + * + * @return array The required service types, optionally keyed by service names + */ + public static function getSubscribedServices(); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/TaggedContainerInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/TaggedContainerInterface.php new file mode 100644 index 00000000..90b297ff --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/TaggedContainerInterface.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * TaggedContainerInterface is the interface implemented when a container knows how to deals with tags. + * + * @author Fabien Potencier + */ +interface TaggedContainerInterface extends ContainerInterface +{ + /** + * Returns service ids for a given tag. + * + * @param string $name The tag name + * + * @return array An array of tags + */ + public function findTaggedServiceIds($name); +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Argument/RewindableGeneratorTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Argument/RewindableGeneratorTest.php new file mode 100644 index 00000000..31e3f11f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Argument/RewindableGeneratorTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Argument; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; + +class RewindableGeneratorTest extends TestCase +{ + public function testImplementsCountable() + { + $this->assertInstanceOf(\Countable::class, new RewindableGenerator(function () { + yield 1; + }, 1)); + } + + public function testCountUsesProvidedValue() + { + $generator = new RewindableGenerator(function () { + yield 1; + }, 3); + + $this->assertCount(3, $generator); + } + + public function testCountUsesProvidedValueAsCallback() + { + $called = 0; + $generator = new RewindableGenerator(function () { + yield 1; + }, function () use (&$called) { + ++$called; + + return 3; + }); + + $this->assertSame(0, $called, 'Count callback is called lazily'); + $this->assertCount(3, $generator); + + \count($generator); + + $this->assertSame(1, $called, 'Count callback is called only once'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ChildDefinitionTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ChildDefinitionTest.php new file mode 100644 index 00000000..50917483 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ChildDefinitionTest.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\DefinitionDecorator; + +class ChildDefinitionTest extends TestCase +{ + public function testConstructor() + { + $def = new ChildDefinition('foo'); + + $this->assertSame('foo', $def->getParent()); + $this->assertSame([], $def->getChanges()); + } + + /** + * @dataProvider getPropertyTests + */ + public function testSetProperty($property, $changeKey) + { + $def = new ChildDefinition('foo'); + + $getter = 'get'.ucfirst($property); + $setter = 'set'.ucfirst($property); + + $this->assertNull($def->$getter()); + $this->assertSame($def, $def->$setter('foo')); + $this->assertSame('foo', $def->$getter()); + $this->assertSame([$changeKey => true], $def->getChanges()); + } + + public function getPropertyTests() + { + return [ + ['class', 'class'], + ['factory', 'factory'], + ['configurator', 'configurator'], + ['file', 'file'], + ]; + } + + public function testSetPublic() + { + $def = new ChildDefinition('foo'); + + $this->assertTrue($def->isPublic()); + $this->assertSame($def, $def->setPublic(false)); + $this->assertFalse($def->isPublic()); + $this->assertSame(['public' => true], $def->getChanges()); + } + + public function testSetLazy() + { + $def = new ChildDefinition('foo'); + + $this->assertFalse($def->isLazy()); + $this->assertSame($def, $def->setLazy(false)); + $this->assertFalse($def->isLazy()); + $this->assertSame(['lazy' => true], $def->getChanges()); + } + + public function testSetAutowired() + { + $def = new ChildDefinition('foo'); + + $this->assertFalse($def->isAutowired()); + $this->assertSame($def, $def->setAutowired(true)); + $this->assertTrue($def->isAutowired()); + $this->assertSame(['autowired' => true], $def->getChanges()); + } + + public function testSetArgument() + { + $def = new ChildDefinition('foo'); + + $this->assertSame([], $def->getArguments()); + $this->assertSame($def, $def->replaceArgument(0, 'foo')); + $this->assertSame(['index_0' => 'foo'], $def->getArguments()); + } + + public function testReplaceArgumentShouldRequireIntegerIndex() + { + $this->expectException('InvalidArgumentException'); + $def = new ChildDefinition('foo'); + + $def->replaceArgument('0', 'foo'); + } + + public function testReplaceArgument() + { + $def = new ChildDefinition('foo'); + + $def->setArguments([0 => 'foo', 1 => 'bar']); + $this->assertSame('foo', $def->getArgument(0)); + $this->assertSame('bar', $def->getArgument(1)); + + $this->assertSame($def, $def->replaceArgument(1, 'baz')); + $this->assertSame('foo', $def->getArgument(0)); + $this->assertSame('baz', $def->getArgument(1)); + + $this->assertSame([0 => 'foo', 1 => 'bar', 'index_1' => 'baz'], $def->getArguments()); + + $this->assertSame($def, $def->replaceArgument('$bar', 'val')); + $this->assertSame('val', $def->getArgument('$bar')); + $this->assertSame([0 => 'foo', 1 => 'bar', 'index_1' => 'baz', '$bar' => 'val'], $def->getArguments()); + } + + public function testGetArgumentShouldCheckBounds() + { + $this->expectException('OutOfBoundsException'); + $def = new ChildDefinition('foo'); + + $def->setArguments([0 => 'foo']); + $def->replaceArgument(0, 'foo'); + + $def->getArgument(1); + } + + public function testDefinitionDecoratorAliasExistsForBackwardsCompatibility() + { + $this->assertInstanceOf(ChildDefinition::class, new DefinitionDecorator('foo')); + } + + public function testCannotCallSetAutoconfigured() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\BadMethodCallException'); + $def = new ChildDefinition('foo'); + $def->setAutoconfigured(true); + } + + public function testCannotCallSetInstanceofConditionals() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\BadMethodCallException'); + $def = new ChildDefinition('foo'); + $def->setInstanceofConditionals(['Foo' => new ChildDefinition('')]); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php new file mode 100644 index 00000000..66b6e19c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php @@ -0,0 +1,215 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class AnalyzeServiceReferencesPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ->addArgument($ref1 = new Reference('b')) + ; + + $container + ->register('b') + ->addMethodCall('setA', [$ref2 = new Reference('a')]) + ; + + $container + ->register('c') + ->addArgument($ref3 = new Reference('a')) + ->addArgument($ref4 = new Reference('b')) + ; + + $container + ->register('d') + ->setProperty('foo', $ref5 = new Reference('b')) + ; + + $container + ->register('e') + ->setConfigurator([$ref6 = new Reference('b'), 'methodName']) + ; + + $graph = $this->process($container); + + $this->assertCount(4, $edges = $graph->getNode('b')->getInEdges()); + + $this->assertSame($ref1, $edges[0]->getValue()); + $this->assertSame($ref4, $edges[1]->getValue()); + $this->assertSame($ref5, $edges[2]->getValue()); + $this->assertSame($ref6, $edges[3]->getValue()); + } + + public function testProcessMarksEdgesLazyWhenReferencedServiceIsLazy() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ->setLazy(true) + ->addArgument($ref1 = new Reference('b')) + ; + + $container + ->register('b') + ->addArgument($ref2 = new Reference('a')) + ; + + $graph = $this->process($container); + + $this->assertCount(1, $graph->getNode('b')->getInEdges()); + $this->assertCount(1, $edges = $graph->getNode('a')->getInEdges()); + + $this->assertSame($ref2, $edges[0]->getValue()); + $this->assertTrue($edges[0]->isLazy()); + } + + public function testProcessMarksEdgesLazyWhenReferencedFromIteratorArgument() + { + $container = new ContainerBuilder(); + $container->register('a'); + $container->register('b'); + + $container + ->register('c') + ->addArgument($ref1 = new Reference('a')) + ->addArgument(new IteratorArgument([$ref2 = new Reference('b')])) + ; + + $graph = $this->process($container); + + $this->assertCount(1, $graph->getNode('a')->getInEdges()); + $this->assertCount(1, $graph->getNode('b')->getInEdges()); + $this->assertCount(2, $edges = $graph->getNode('c')->getOutEdges()); + + $this->assertSame($ref1, $edges[0]->getValue()); + $this->assertFalse($edges[0]->isLazy()); + $this->assertSame($ref2, $edges[1]->getValue()); + $this->assertTrue($edges[1]->isLazy()); + } + + public function testProcessDetectsReferencesFromInlinedDefinitions() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + + $container + ->register('b') + ->addArgument(new Definition(null, [$ref = new Reference('a')])) + ; + + $graph = $this->process($container); + + $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges()); + $this->assertSame($ref, $refs[0]->getValue()); + } + + public function testProcessDetectsReferencesFromIteratorArguments() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + + $container + ->register('b') + ->addArgument(new IteratorArgument([$ref = new Reference('a')])) + ; + + $graph = $this->process($container); + + $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges()); + $this->assertSame($ref, $refs[0]->getValue()); + } + + public function testProcessDetectsReferencesFromInlinedFactoryDefinitions() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + + $factory = new Definition(); + $factory->setFactory([new Reference('a'), 'a']); + + $container + ->register('b') + ->addArgument($factory) + ; + + $graph = $this->process($container); + + $this->assertTrue($graph->hasNode('a')); + $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges()); + } + + public function testProcessDoesNotSaveDuplicateReferences() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + $container + ->register('b') + ->addArgument(new Definition(null, [$ref1 = new Reference('a')])) + ->addArgument(new Definition(null, [$ref2 = new Reference('a')])) + ; + + $graph = $this->process($container); + + $this->assertCount(2, $graph->getNode('a')->getInEdges()); + } + + public function testProcessDetectsFactoryReferences() + { + $container = new ContainerBuilder(); + + $container + ->register('foo', 'stdClass') + ->setFactory(['stdClass', 'getInstance']); + + $container + ->register('bar', 'stdClass') + ->setFactory([new Reference('foo'), 'getInstance']); + + $graph = $this->process($container); + + $this->assertTrue($graph->hasNode('foo')); + $this->assertCount(1, $graph->getNode('foo')->getInEdges()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new RepeatedPass([new AnalyzeServiceReferencesPass()]); + $pass->process($container); + + return $container->getCompiler()->getServiceReferenceGraph(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php new file mode 100644 index 00000000..4e17778f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutoAliasServicePassTest.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\AutoAliasServicePass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class AutoAliasServicePassTest extends TestCase +{ + public function testProcessWithMissingParameter() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException'); + $container = new ContainerBuilder(); + + $container->register('example') + ->addTag('auto_alias', ['format' => '%non_existing%.example']); + + $pass = new AutoAliasServicePass(); + $pass->process($container); + } + + public function testProcessWithMissingFormat() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $container = new ContainerBuilder(); + + $container->register('example') + ->addTag('auto_alias', []); + $container->setParameter('existing', 'mysql'); + + $pass = new AutoAliasServicePass(); + $pass->process($container); + } + + public function testProcessWithNonExistingAlias() + { + $container = new ContainerBuilder(); + + $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault') + ->addTag('auto_alias', ['format' => '%existing%.example']); + $container->setParameter('existing', 'mysql'); + + $pass = new AutoAliasServicePass(); + $pass->process($container); + + $this->assertEquals('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault', $container->getDefinition('example')->getClass()); + } + + public function testProcessWithExistingAlias() + { + $container = new ContainerBuilder(); + + $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault') + ->addTag('auto_alias', ['format' => '%existing%.example']); + + $container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql'); + $container->setParameter('existing', 'mysql'); + + $pass = new AutoAliasServicePass(); + $pass->process($container); + + $this->assertTrue($container->hasAlias('example')); + $this->assertEquals('mysql.example', $container->getAlias('example')); + $this->assertSame('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql', $container->getDefinition('mysql.example')->getClass()); + } + + public function testProcessWithManualAlias() + { + $container = new ContainerBuilder(); + + $container->register('example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassDefault') + ->addTag('auto_alias', ['format' => '%existing%.example']); + + $container->register('mysql.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMysql'); + $container->register('mariadb.example', 'Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariaDb'); + $container->setAlias('example', 'mariadb.example'); + $container->setParameter('existing', 'mysql'); + + $pass = new AutoAliasServicePass(); + $pass->process($container); + + $this->assertTrue($container->hasAlias('example')); + $this->assertEquals('mariadb.example', $container->getAlias('example')); + $this->assertSame('Symfony\Component\DependencyInjection\Tests\Compiler\ServiceClassMariaDb', $container->getDefinition('mariadb.example')->getClass()); + } +} + +class ServiceClassDefault +{ +} + +class ServiceClassMysql extends ServiceClassDefault +{ +} + +class ServiceClassMariaDb extends ServiceClassMysql +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowireExceptionPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowireExceptionPassTest.php new file mode 100644 index 00000000..c5ba149a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowireExceptionPassTest.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\AutowireExceptionPass; +use Symfony\Component\DependencyInjection\Compiler\AutowirePass; +use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException; + +/** + * @group legacy + */ +class AutowireExceptionPassTest extends TestCase +{ + public function testThrowsException() + { + $autowirePass = $this->getMockBuilder(AutowirePass::class) + ->getMock(); + + $autowireException = new AutowiringFailedException('foo_service_id', 'An autowiring exception message'); + $autowirePass->expects($this->any()) + ->method('getAutowiringExceptions') + ->willReturn([$autowireException]); + + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->willReturn([]); + + $container = new ContainerBuilder(); + $container->register('foo_service_id'); + + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); + + try { + $pass->process($container); + $this->fail('->process() should throw the exception if the service id exists'); + } catch (\Exception $e) { + $this->assertSame($autowireException, $e); + } + } + + public function testThrowExceptionIfServiceInlined() + { + $autowirePass = $this->getMockBuilder(AutowirePass::class) + ->getMock(); + + $autowireException = new AutowiringFailedException('a_service', 'An autowiring exception message'); + $autowirePass->expects($this->any()) + ->method('getAutowiringExceptions') + ->willReturn([$autowireException]); + + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->willReturn([ + // a_service inlined into b_service + 'a_service' => ['b_service'], + // b_service inlined into c_service + 'b_service' => ['c_service'], + ]); + + $container = new ContainerBuilder(); + // ONLY register c_service in the final container + $container->register('c_service', 'stdClass'); + + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); + + try { + $pass->process($container); + $this->fail('->process() should throw the exception if the service id exists'); + } catch (\Exception $e) { + $this->assertSame($autowireException, $e); + } + } + + public function testDoNotThrowExceptionIfServiceInlinedButRemoved() + { + $autowirePass = $this->getMockBuilder(AutowirePass::class) + ->getMock(); + + $autowireException = new AutowiringFailedException('a_service', 'An autowiring exception message'); + $autowirePass->expects($this->any()) + ->method('getAutowiringExceptions') + ->willReturn([$autowireException]); + + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->willReturn([ + // a_service inlined into b_service + 'a_service' => ['b_service'], + // b_service inlined into c_service + 'b_service' => ['c_service'], + ]); + + // do NOT register c_service in the container + $container = new ContainerBuilder(); + + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); + + $pass->process($container); + // mark the test as passed + $this->assertTrue(true); + } + + public function testNoExceptionIfServiceRemoved() + { + $autowirePass = $this->getMockBuilder(AutowirePass::class) + ->getMock(); + + $autowireException = new AutowiringFailedException('non_existent_service'); + $autowirePass->expects($this->any()) + ->method('getAutowiringExceptions') + ->willReturn([$autowireException]); + + $inlinePass = $this->getMockBuilder(InlineServiceDefinitionsPass::class) + ->getMock(); + $inlinePass->expects($this->any()) + ->method('getInlinedServiceIds') + ->willReturn([]); + + $container = new ContainerBuilder(); + + $pass = new AutowireExceptionPass($autowirePass, $inlinePass); + + $pass->process($container); + // mark the test as passed + $this->assertTrue(true); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php new file mode 100644 index 00000000..6c11a94c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowirePassTest.php @@ -0,0 +1,988 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Compiler\AutowirePass; +use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\FooVariadic; +use Symfony\Component\DependencyInjection\Tests\Fixtures\includes\MultipleArgumentsOptionalScalarNotReallyOptional; +use Symfony\Component\DependencyInjection\TypedReference; + +require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php'; + +/** + * @author Kévin Dunglas + */ +class AutowirePassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $container->register(Foo::class); + $barDefinition = $container->register('bar', Bar::class); + $barDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(1, $container->getDefinition('bar')->getArguments()); + $this->assertEquals(Foo::class, (string) $container->getDefinition('bar')->getArgument(0)); + } + + /** + * @requires PHP 5.6 + */ + public function testProcessVariadic() + { + $container = new ContainerBuilder(); + $container->register(Foo::class); + $definition = $container->register('fooVariadic', FooVariadic::class); + $definition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(1, $container->getDefinition('fooVariadic')->getArguments()); + $this->assertEquals(Foo::class, (string) $container->getDefinition('fooVariadic')->getArgument(0)); + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should alias the "Symfony\Component\DependencyInjection\Tests\Compiler\B" service to "Symfony\Component\DependencyInjection\Tests\Compiler\A" instead. + * @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessageInSymfony4 Cannot autowire service "c": argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\B" service. + */ + public function testProcessAutowireParent() + { + $container = new ContainerBuilder(); + + $container->register(B::class); + $cDefinition = $container->register('c', C::class); + $cDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(1, $container->getDefinition('c')->getArguments()); + $this->assertEquals(B::class, (string) $container->getDefinition('c')->getArgument(0)); + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" to "Symfony\Component\DependencyInjection\Tests\Compiler\AInterface" instead. + * @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessageInSymfony4 Cannot autowire service "c": argument "$a" of method "Symfony\Component\DependencyInjection\Tests\Compiler\C::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\B" service. + */ + public function testProcessLegacyAutowireWithAvailableInterface() + { + $container = new ContainerBuilder(); + + $container->setAlias(AInterface::class, B::class); + $container->register(B::class); + $cDefinition = $container->register('c', C::class); + $cDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(1, $container->getDefinition('c')->getArguments()); + $this->assertEquals(B::class, (string) $container->getDefinition('c')->getArgument(0)); + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should alias the "Symfony\Component\DependencyInjection\Tests\Compiler\F" service to "Symfony\Component\DependencyInjection\Tests\Compiler\DInterface" instead. + * @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\RuntimeException + * @expectedExceptionMessageInSymfony4 Cannot autowire service "g": argument "$d" of method "Symfony\Component\DependencyInjection\Tests\Compiler\G::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\DInterface" but no such service exists. You should maybe alias this interface to the existing "Symfony\Component\DependencyInjection\Tests\Compiler\F" service. + */ + public function testProcessAutowireInterface() + { + $container = new ContainerBuilder(); + + $container->register(F::class); + $gDefinition = $container->register('g', G::class); + $gDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(3, $container->getDefinition('g')->getArguments()); + $this->assertEquals(F::class, (string) $container->getDefinition('g')->getArgument(0)); + $this->assertEquals(F::class, (string) $container->getDefinition('g')->getArgument(1)); + $this->assertEquals(F::class, (string) $container->getDefinition('g')->getArgument(2)); + } + + public function testCompleteExistingDefinition() + { + $container = new ContainerBuilder(); + + $container->register('b', B::class); + $container->register(DInterface::class, F::class); + $hDefinition = $container->register('h', H::class)->addArgument(new Reference('b')); + $hDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(2, $container->getDefinition('h')->getArguments()); + $this->assertEquals('b', (string) $container->getDefinition('h')->getArgument(0)); + $this->assertEquals(DInterface::class, (string) $container->getDefinition('h')->getArgument(1)); + } + + public function testCompleteExistingDefinitionWithNotDefinedArguments() + { + $container = new ContainerBuilder(); + + $container->register(B::class); + $container->register(DInterface::class, F::class); + $hDefinition = $container->register('h', H::class)->addArgument('')->addArgument(''); + $hDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(2, $container->getDefinition('h')->getArguments()); + $this->assertEquals(B::class, (string) $container->getDefinition('h')->getArgument(0)); + $this->assertEquals(DInterface::class, (string) $container->getDefinition('h')->getArgument(1)); + } + + /** + * @group legacy + */ + public function testExceptionsAreStored() + { + $container = new ContainerBuilder(); + + $container->register('c1', CollisionA::class); + $container->register('c2', CollisionB::class); + $container->register('c3', CollisionB::class); + $aDefinition = $container->register('a', CannotBeAutowired::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(false); + $pass->process($container); + $this->assertCount(1, $pass->getAutowiringExceptions()); + } + + public function testPrivateConstructorThrowsAutowireException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Invalid service "private_service": constructor of class "Symfony\Component\DependencyInjection\Tests\Compiler\PrivateConstructor" must be public.'); + $container = new ContainerBuilder(); + + $container->autowire('private_service', PrivateConstructor::class); + + $pass = new AutowirePass(true); + $pass->process($container); + } + + public function testTypeCollision() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\CannotBeAutowired::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2", "c3".'); + $container = new ContainerBuilder(); + + $container->register('c1', CollisionA::class); + $container->register('c2', CollisionB::class); + $container->register('c3', CollisionB::class); + $aDefinition = $container->register('a', CannotBeAutowired::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testTypeNotGuessable() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgument::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. You should maybe alias this class to one of these existing services: "a1", "a2".'); + $container = new ContainerBuilder(); + + $container->register('a1', Foo::class); + $container->register('a2', Foo::class); + $aDefinition = $container->register('a', NotGuessableArgument::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testTypeNotGuessableWithSubclass() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$k" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotGuessableArgumentForSubclass::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\A" but no such service exists. You should maybe alias this class to one of these existing services: "a1", "a2".'); + $container = new ContainerBuilder(); + + $container->register('a1', B::class); + $container->register('a2', B::class); + $aDefinition = $container->register('a', NotGuessableArgumentForSubclass::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testTypeNotGuessableNoServicesFound() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\CannotBeAutowired::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists.'); + $container = new ContainerBuilder(); + + $aDefinition = $container->register('a', CannotBeAutowired::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + /** + * @requires PHP 8 + */ + public function testTypeNotGuessableUnionType() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\UnionClasses::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionA|Symfony\Component\DependencyInjection\Tests\Compiler\CollisionB" but this class was not found.'); + $container = new ContainerBuilder(); + + $container->register(CollisionA::class); + $container->register(CollisionB::class); + + $aDefinition = $container->register('a', UnionClasses::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testTypeNotGuessableWithTypeSet() + { + $container = new ContainerBuilder(); + + $container->register('a1', Foo::class); + $container->register('a2', Foo::class); + $container->register(Foo::class, Foo::class); + $aDefinition = $container->register('a', NotGuessableArgument::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertCount(1, $container->getDefinition('a')->getArguments()); + $this->assertEquals(Foo::class, (string) $container->getDefinition('a')->getArgument(0)); + } + + public function testWithTypeSet() + { + $container = new ContainerBuilder(); + + $container->register('c1', CollisionA::class); + $container->register('c2', CollisionB::class); + $container->setAlias(CollisionInterface::class, 'c2'); + $aDefinition = $container->register('a', CannotBeAutowired::class); + $aDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertCount(1, $container->getDefinition('a')->getArguments()); + $this->assertEquals(CollisionInterface::class, (string) $container->getDefinition('a')->getArgument(0)); + } + + /** + * @group legacy + * @expectedDeprecation Relying on service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\Lille" is deprecated since Symfony 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\Lille" instead. + * @expectedDeprecation Relying on service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas" is deprecated since Symfony 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas" instead. + */ + public function testCreateDefinition() + { + $container = new ContainerBuilder(); + + $coopTilleulsDefinition = $container->register('coop_tilleuls', LesTilleuls::class); + $coopTilleulsDefinition->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertCount(2, $container->getDefinition('coop_tilleuls')->getArguments()); + $this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0)); + $this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas', $container->getDefinition('coop_tilleuls')->getArgument(1)); + + $dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas'); + $this->assertEquals(Dunglas::class, $dunglasDefinition->getClass()); + $this->assertFalse($dunglasDefinition->isPublic()); + $this->assertCount(1, $dunglasDefinition->getArguments()); + $this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille', $dunglasDefinition->getArgument(0)); + + $lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille'); + $this->assertEquals(Lille::class, $lilleDefinition->getClass()); + } + + public function testResolveParameter() + { + $container = new ContainerBuilder(); + + $container->setParameter('class_name', Bar::class); + $container->register(Foo::class); + $barDefinition = $container->register('bar', '%class_name%'); + $barDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertEquals(Foo::class, $container->getDefinition('bar')->getArgument(0)); + } + + public function testOptionalParameter() + { + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Foo::class); + $optDefinition = $container->register('opt', OptionalParameter::class); + $optDefinition->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('opt'); + $this->assertNull($definition->getArgument(0)); + $this->assertEquals(A::class, $definition->getArgument(1)); + $this->assertEquals(Foo::class, $definition->getArgument(2)); + } + + /** + * @requires PHP 8 + */ + public function testParameterWithNullUnionIsSkipped() + { + $container = new ContainerBuilder(); + + $optDefinition = $container->register('opt', UnionNull::class); + $optDefinition->setAutowired(true); + + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('opt'); + $this->assertNull($definition->getArgument(0)); + } + + /** + * @requires PHP 8 + */ + public function testParameterWithNullUnionIsAutowired() + { + $container = new ContainerBuilder(); + + $container->register(CollisionInterface::class, CollisionA::class); + + $optDefinition = $container->register('opt', UnionNull::class); + $optDefinition->setAutowired(true); + + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('opt'); + $this->assertEquals(CollisionInterface::class, $definition->getArgument(0)); + } + + public function testDontTriggerAutowiring() + { + $container = new ContainerBuilder(); + + $container->register(Foo::class); + $container->register('bar', Bar::class); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertCount(0, $container->getDefinition('bar')->getArguments()); + } + + public function testClassNotFoundThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "a": argument "$r" of method "Symfony\Component\DependencyInjection\Tests\Compiler\BadTypeHintedArgument::__construct()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass" but this class was not found.'); + $container = new ContainerBuilder(); + + $aDefinition = $container->register('a', BadTypeHintedArgument::class); + $aDefinition->setAutowired(true); + + $container->register(Dunglas::class, Dunglas::class); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testParentClassNotFoundThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessageMatches('{^Cannot autowire service "a": argument "\$r" of method "(Symfony\\\\Component\\\\DependencyInjection\\\\Tests\\\\Compiler\\\\)BadParentTypeHintedArgument::__construct\(\)" has type "\1OptionalServiceClass" but this class is missing a parent class \(Class "?Symfony\\\\Bug\\\\NotExistClass"? not found}'); + + $container = new ContainerBuilder(); + + $aDefinition = $container->register('a', BadParentTypeHintedArgument::class); + $aDefinition->setAutowired(true); + + $container->register(Dunglas::class, Dunglas::class); + + $pass = new AutowirePass(); + $pass->process($container); + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "foo" service to "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" instead. + * @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException + * @expectedExceptionMessageInSymfony4 Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but this service is abstract. You should maybe alias this class to the existing "foo" service. + */ + public function testDontUseAbstractServices() + { + $container = new ContainerBuilder(); + + $container->register(Foo::class)->setAbstract(true); + $container->register('foo', Foo::class); + $container->register('bar', Bar::class)->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + } + + public function testSomeSpecificArgumentsAreSet() + { + $container = new ContainerBuilder(); + + $container->register('foo', Foo::class); + $container->register(A::class); + $container->register(Dunglas::class); + $container->register('multiple', MultipleArguments::class) + ->setAutowired(true) + // set the 2nd (index 1) argument only: autowire the first and third + // args are: A, Foo, Dunglas + ->setArguments([ + 1 => new Reference('foo'), + 3 => ['bar'], + ]); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('multiple'); + $this->assertEquals( + [ + new TypedReference(A::class, A::class, MultipleArguments::class), + new Reference('foo'), + new TypedReference(Dunglas::class, Dunglas::class, MultipleArguments::class), + ['bar'], + ], + $definition->getArguments() + ); + } + + public function testScalarArgsCannotBeAutowired() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "arg_no_type_hint": argument "$bar" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" is type-hinted "array", you should configure its value explicitly.'); + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Dunglas::class); + $container->register('arg_no_type_hint', MultipleArguments::class) + ->setArguments([1 => 'foo']) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + } + + /** + * @requires PHP 8 + */ + public function testUnionScalarArgsCannotBeAutowired() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "union_scalars": argument "$timeout" of method "Symfony\Component\DependencyInjection\Tests\Compiler\UnionScalars::__construct()" is type-hinted "int|float", you should configure its value explicitly.'); + $container = new ContainerBuilder(); + + $container->register('union_scalars', UnionScalars::class) + ->setAutowired(true); + + (new AutowirePass())->process($container); + } + + public function testNoTypeArgsCannotBeAutowired() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "arg_no_type_hint": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\MultipleArguments::__construct()" has no type-hint, you should configure its value explicitly.'); + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Dunglas::class); + $container->register('arg_no_type_hint', MultipleArguments::class) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + } + + /** + * @requires PHP < 8 + */ + public function testOptionalScalarNotReallyOptionalUsesDefaultValue() + { + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Lille::class); + $definition = $container->register('not_really_optional_scalar', MultipleArgumentsOptionalScalarNotReallyOptional::class) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertSame('default_val', $definition->getArgument(1)); + } + + public function testOptionalScalarArgsDontMessUpOrder() + { + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Lille::class); + $container->register('with_optional_scalar', MultipleArgumentsOptionalScalar::class) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('with_optional_scalar'); + $this->assertEquals( + [ + new TypedReference(A::class, A::class, MultipleArgumentsOptionalScalar::class), + // use the default value + 'default_val', + new TypedReference(Lille::class, Lille::class), + ], + $definition->getArguments() + ); + } + + public function testOptionalScalarArgsNotPassedIfLast() + { + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Lille::class); + $container->register('with_optional_scalar_last', MultipleArgumentsOptionalScalarLast::class) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('with_optional_scalar_last'); + $this->assertEquals( + [ + new TypedReference(A::class, A::class, MultipleArgumentsOptionalScalarLast::class), + new TypedReference(Lille::class, Lille::class, MultipleArgumentsOptionalScalarLast::class), + ], + $definition->getArguments() + ); + } + + public function testOptionalArgsNoRequiredForCoreClasses() + { + $container = new ContainerBuilder(); + + $container->register('foo', \SplFileObject::class) + ->addArgument('foo.txt') + ->setAutowired(true); + + (new AutowirePass())->process($container); + + $definition = $container->getDefinition('foo'); + $this->assertEquals( + ['foo.txt'], + $definition->getArguments() + ); + } + + public function testSetterInjection() + { + $container = new ContainerBuilder(); + $container->register(Foo::class); + $container->register(A::class); + $container->register(CollisionA::class); + $container->register(CollisionB::class); + + // manually configure *one* call, to override autowiring + $container + ->register('setter_injection', SetterInjection::class) + ->setAutowired(true) + ->addMethodCall('setWithCallsConfigured', ['manual_arg1', 'manual_arg2']) + ; + + (new ResolveClassPass())->process($container); + (new AutowireRequiredMethodsPass())->process($container); + (new AutowirePass())->process($container); + + $methodCalls = $container->getDefinition('setter_injection')->getMethodCalls(); + + $this->assertEquals( + ['setWithCallsConfigured', 'setFoo', 'setDependencies', 'setChildMethodWithoutDocBlock'], + array_column($methodCalls, 0) + ); + + // test setWithCallsConfigured args + $this->assertEquals( + ['manual_arg1', 'manual_arg2'], + $methodCalls[0][1] + ); + // test setFoo args + $this->assertEquals( + [new TypedReference(Foo::class, Foo::class, SetterInjection::class)], + $methodCalls[1][1] + ); + } + + public function testWithNonExistingSetterAndAutowiring() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass": method "setLogger()" does not exist.'); + $container = new ContainerBuilder(); + + $definition = $container->register(CaseSensitiveClass::class, CaseSensitiveClass::class)->setAutowired(true); + $definition->addMethodCall('setLogger'); + + (new ResolveClassPass())->process($container); + (new AutowireRequiredMethodsPass())->process($container); + (new AutowirePass())->process($container); + } + + public function testExplicitMethodInjection() + { + $container = new ContainerBuilder(); + $container->register(Foo::class); + $container->register(A::class); + $container->register(CollisionA::class); + $container->register(CollisionB::class); + + $container + ->register('setter_injection', SetterInjection::class) + ->setAutowired(true) + ->addMethodCall('notASetter', []) + ; + + (new ResolveClassPass())->process($container); + (new AutowireRequiredMethodsPass())->process($container); + (new AutowirePass())->process($container); + + $methodCalls = $container->getDefinition('setter_injection')->getMethodCalls(); + + $this->assertEquals( + ['notASetter', 'setFoo', 'setDependencies', 'setWithCallsConfigured', 'setChildMethodWithoutDocBlock'], + array_column($methodCalls, 0) + ); + $this->assertEquals( + [new TypedReference(A::class, A::class, SetterInjection::class)], + $methodCalls[0][1] + ); + } + + /** + * @group legacy + * @expectedDeprecation Relying on service auto-registration for type "Symfony\Component\DependencyInjection\Tests\Compiler\A" is deprecated since Symfony 3.4 and won't be supported in 4.0. Create a service named "Symfony\Component\DependencyInjection\Tests\Compiler\A" instead. + */ + public function testTypedReference() + { + $container = new ContainerBuilder(); + + $container + ->register('bar', Bar::class) + ->setProperty('a', [new TypedReference(A::class, A::class, Bar::class)]) + ; + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertSame(A::class, $container->getDefinition('autowired.'.A::class)->getClass()); + } + + /** + * @dataProvider getCreateResourceTests + * @group legacy + */ + public function testCreateResourceForClass($className, $isEqual) + { + $startingResource = AutowirePass::createResourceForClass( + new \ReflectionClass(ClassForResource::class) + ); + $newResource = AutowirePass::createResourceForClass( + new \ReflectionClass(__NAMESPACE__.'\\'.$className) + ); + + // hack so the objects don't differ by the class name + $startingReflObject = new \ReflectionObject($startingResource); + $reflProp = $startingReflObject->getProperty('class'); + $reflProp->setAccessible(true); + $reflProp->setValue($startingResource, __NAMESPACE__.'\\'.$className); + + if ($isEqual) { + $this->assertEquals($startingResource, $newResource); + } else { + $this->assertNotEquals($startingResource, $newResource); + } + } + + public function getCreateResourceTests() + { + return [ + ['IdenticalClassResource', true], + ['ClassChangedConstructorArgs', false], + ]; + } + + public function testIgnoreServiceWithClassNotExisting() + { + $container = new ContainerBuilder(); + + $container->register('class_not_exist', OptionalServiceClass::class); + + $barDefinition = $container->register('bar', Bar::class); + $barDefinition->setAutowired(true); + + $container->register(Foo::class, Foo::class); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertTrue($container->hasDefinition('bar')); + } + + public function testSetterInjectionCollisionThrowsException() + { + $container = new ContainerBuilder(); + + $container->register('c1', CollisionA::class); + $container->register('c2', CollisionB::class); + $aDefinition = $container->register('setter_injection_collision', SetterInjectionCollision::class); + $aDefinition->setAutowired(true); + + (new AutowireRequiredMethodsPass())->process($container); + + $pass = new AutowirePass(); + + try { + $pass->process($container); + } catch (AutowiringFailedException $e) { + } + + $this->assertNotNull($e); + $this->assertSame('Cannot autowire service "setter_injection_collision": argument "$collision" of method "Symfony\Component\DependencyInjection\Tests\Compiler\SetterInjectionCollision::setMultipleInstancesForOneArg()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\CollisionInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "c1", "c2".', $e->getMessage()); + } + + public function testInterfaceWithNoImplementationSuggestToWriteOne() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "my_service": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\K::__construct()" references interface "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" but no such service exists. Did you create a class that implements this interface?'); + $container = new ContainerBuilder(); + + $aDefinition = $container->register('my_service', K::class); + $aDefinition->setAutowired(true); + + (new AutowireRequiredMethodsPass())->process($container); + + $pass = new AutowirePass(); + $pass->process($container); + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. You should rename (or alias) the "foo" service to "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" instead. + * @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException + * @expectedExceptionMessageInSymfony4 Cannot autowire service "bar": argument "$foo" of method "Symfony\Component\DependencyInjection\Tests\Compiler\Bar::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\Foo" but no such service exists. You should maybe alias this class to the existing "foo" service. + */ + public function testProcessDoesNotTriggerDeprecations() + { + $container = new ContainerBuilder(); + $container->register('deprecated', 'Symfony\Component\DependencyInjection\Tests\Fixtures\DeprecatedClass')->setDeprecated(true); + $container->register('foo', Foo::class); + $container->register('bar', Bar::class)->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertTrue($container->hasDefinition('deprecated')); + $this->assertTrue($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + } + + public function testEmptyStringIsKept() + { + $container = new ContainerBuilder(); + + $container->register(A::class); + $container->register(Lille::class); + $container->register('foo', MultipleArgumentsOptionalScalar::class) + ->setAutowired(true) + ->setArguments(['', '']); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertEquals([new TypedReference(A::class, A::class, MultipleArgumentsOptionalScalar::class), '', new TypedReference(Lille::class, Lille::class)], $container->getDefinition('foo')->getArguments()); + } + + public function testWithFactory() + { + $container = new ContainerBuilder(); + + $container->register(Foo::class); + $definition = $container->register('a', A::class) + ->setFactory([A::class, 'create']) + ->setAutowired(true); + + (new ResolveClassPass())->process($container); + (new AutowirePass())->process($container); + + $this->assertEquals([new TypedReference(Foo::class, Foo::class, A::class)], $definition->getArguments()); + } + + /** + * @dataProvider provideNotWireableCalls + */ + public function testNotWireableCalls($method, $expectedMsg) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $container = new ContainerBuilder(); + + $foo = $container->register('foo', NotWireable::class)->setAutowired(true) + ->addMethodCall('setBar', []) + ->addMethodCall('setOptionalNotAutowireable', []) + ->addMethodCall('setOptionalNoTypeHint', []) + ->addMethodCall('setOptionalArgNoAutowireable', []) + ; + + if ($method) { + $foo->addMethodCall($method, []); + } + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage($expectedMsg); + + (new ResolveClassPass())->process($container); + (new AutowireRequiredMethodsPass())->process($container); + (new AutowirePass())->process($container); + } + + public function provideNotWireableCalls() + { + return [ + ['setNotAutowireable', 'Cannot autowire service "foo": argument "$n" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setNotAutowireable()" has type "Symfony\Component\DependencyInjection\Tests\Compiler\NotARealClass" but this class was not found.'], + ['setDifferentNamespace', 'Cannot autowire service "foo": argument "$n" of method "Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setDifferentNamespace()" references class "stdClass" but no such service exists. It cannot be auto-registered because it is from a different root namespace.'], + [null, 'Invalid service "foo": method "Symfony\Component\DependencyInjection\Tests\Compiler\NotWireable::setProtectedMethod()" must be public.'], + ]; + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead. + * @expectedExceptionInSymfony4 \Symfony\Component\DependencyInjection\Exception\AutowiringFailedException + * @expectedExceptionMessageInSymfony4 Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. Try changing the type-hint to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead. + */ + public function testByIdAlternative() + { + $container = new ContainerBuilder(); + + $container->setAlias(IInterface::class, 'i'); + $container->register('i', I::class); + $container->register('j', J::class) + ->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + /** + * @group legacy + * @expectedDeprecation Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won't be supported in version 4.0. Try changing the type-hint for "Symfony\Component\DependencyInjection\Tests\Compiler\A" in "Symfony\Component\DependencyInjection\Tests\Compiler\Bar" to "Symfony\Component\DependencyInjection\Tests\Compiler\AInterface" instead. + */ + public function testTypedReferenceDeprecationNotice() + { + $container = new ContainerBuilder(); + + $container->register('aClass', A::class); + $container->setAlias(AInterface::class, 'aClass'); + $container + ->register('bar', Bar::class) + ->setProperty('a', [new TypedReference(A::class, A::class, Bar::class)]) + ; + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testExceptionWhenAliasExists() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. Try changing the type-hint to "Symfony\Component\DependencyInjection\Tests\Compiler\IInterface" instead.'); + $container = new ContainerBuilder(); + + // multiple I services... but there *is* IInterface available + $container->setAlias(IInterface::class, 'i'); + $container->register('i', I::class); + $container->register('i2', I::class); + // J type-hints against I concretely + $container->register('j', J::class) + ->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testExceptionWhenAliasDoesNotExist() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\AutowiringFailedException'); + $this->expectExceptionMessage('Cannot autowire service "j": argument "$i" of method "Symfony\Component\DependencyInjection\Tests\Compiler\J::__construct()" references class "Symfony\Component\DependencyInjection\Tests\Compiler\I" but no such service exists. You should maybe alias this class to one of these existing services: "i", "i2".'); + + $container = new ContainerBuilder(); + + // multiple I instances... but no IInterface alias + $container->register('i', I::class); + $container->register('i2', I::class); + // J type-hints against I concretely + $container->register('j', J::class) + ->setAutowired(true); + + $pass = new AutowirePass(); + $pass->process($container); + } + + public function testInlineServicesAreNotCandidates() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(realpath(__DIR__.'/../Fixtures/xml'))); + $loader->load('services_inline_not_candidate.xml'); + + $pass = new AutowirePass(); + $pass->process($container); + + $this->assertSame([], $container->getDefinition('autowired')->getArguments()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowireRequiredMethodsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowireRequiredMethodsPassTest.php new file mode 100644 index 00000000..644b32d2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/AutowireRequiredMethodsPassTest.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php'; + +class AutowireRequiredMethodsPassTest extends TestCase +{ + public function testSetterInjection() + { + $container = new ContainerBuilder(); + $container->register(Foo::class); + $container->register(A::class); + $container->register(CollisionA::class); + $container->register(CollisionB::class); + + // manually configure *one* call, to override autowiring + $container + ->register('setter_injection', SetterInjection::class) + ->setAutowired(true) + ->addMethodCall('setWithCallsConfigured', ['manual_arg1', 'manual_arg2']); + + (new ResolveClassPass())->process($container); + (new AutowireRequiredMethodsPass())->process($container); + + $methodCalls = $container->getDefinition('setter_injection')->getMethodCalls(); + + $this->assertEquals( + ['setWithCallsConfigured', 'setFoo', 'setDependencies', 'setChildMethodWithoutDocBlock'], + array_column($methodCalls, 0) + ); + + // test setWithCallsConfigured args + $this->assertEquals( + ['manual_arg1', 'manual_arg2'], + $methodCalls[0][1] + ); + // test setFoo args + $this->assertEquals([], $methodCalls[1][1]); + } + + public function testExplicitMethodInjection() + { + $container = new ContainerBuilder(); + $container->register(Foo::class); + $container->register(A::class); + $container->register(CollisionA::class); + $container->register(CollisionB::class); + + $container + ->register('setter_injection', SetterInjection::class) + ->setAutowired(true) + ->addMethodCall('notASetter', []); + + (new ResolveClassPass())->process($container); + (new AutowireRequiredMethodsPass())->process($container); + + $methodCalls = $container->getDefinition('setter_injection')->getMethodCalls(); + + $this->assertEquals( + ['notASetter', 'setFoo', 'setDependencies', 'setWithCallsConfigured', 'setChildMethodWithoutDocBlock'], + array_column($methodCalls, 0) + ); + $this->assertEquals([], $methodCalls[0][1]); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckArgumentsValidityPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckArgumentsValidityPassTest.php new file mode 100644 index 00000000..9554c23b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckArgumentsValidityPassTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CheckArgumentsValidityPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @author Kévin Dunglas + */ +class CheckArgumentsValidityPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $definition = $container->register('foo'); + $definition->setArguments([null, 1, 'a']); + $definition->setMethodCalls([ + ['bar', ['a', 'b']], + ['baz', ['c', 'd']], + ]); + + $pass = new CheckArgumentsValidityPass(); + $pass->process($container); + + $this->assertEquals([null, 1, 'a'], $container->getDefinition('foo')->getArguments()); + $this->assertEquals([ + ['bar', ['a', 'b']], + ['baz', ['c', 'd']], + ], $container->getDefinition('foo')->getMethodCalls()); + } + + /** + * @dataProvider definitionProvider + */ + public function testException(array $arguments, array $methodCalls) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + $definition = $container->register('foo'); + $definition->setArguments($arguments); + $definition->setMethodCalls($methodCalls); + + $pass = new CheckArgumentsValidityPass(); + $pass->process($container); + } + + public function definitionProvider() + { + return [ + [[null, 'a' => 'a'], []], + [[1 => 1], []], + [[], [['baz', [null, 'a' => 'a']]]], + [[], [['baz', [1 => 1]]]], + ]; + } + + public function testNoException() + { + $container = new ContainerBuilder(); + $definition = $container->register('foo'); + $definition->setArguments([null, 'a' => 'a']); + + $pass = new CheckArgumentsValidityPass(false); + $pass->process($container); + $this->assertCount(1, $definition->getErrors()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckCircularReferencesPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckCircularReferencesPassTest.php new file mode 100644 index 00000000..8d501368 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckCircularReferencesPassTest.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\Compiler; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class CheckCircularReferencesPassTest extends TestCase +{ + public function testProcess() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addArgument(new Reference('a')); + + $this->process($container); + } + + public function testProcessWithAliases() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->setAlias('b', 'c'); + $container->setAlias('c', 'a'); + + $this->process($container); + } + + public function testProcessWithFactory() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + + $container + ->register('a', 'stdClass') + ->setFactory([new Reference('b'), 'getInstance']); + + $container + ->register('b', 'stdClass') + ->setFactory([new Reference('a'), 'getInstance']); + + $this->process($container); + } + + public function testProcessDetectsIndirectCircularReference() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addArgument(new Reference('c')); + $container->register('c')->addArgument(new Reference('a')); + + $this->process($container); + } + + public function testProcessDetectsIndirectCircularReferenceWithFactory() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + + $container->register('a')->addArgument(new Reference('b')); + + $container + ->register('b', 'stdClass') + ->setFactory([new Reference('c'), 'getInstance']); + + $container->register('c')->addArgument(new Reference('a')); + + $this->process($container); + } + + public function testDeepCircularReference() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addArgument(new Reference('c')); + $container->register('c')->addArgument(new Reference('b')); + + $this->process($container); + } + + public function testProcessIgnoresMethodCalls() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addMethodCall('setA', [new Reference('a')]); + + $this->process($container); + + $this->addToAssertionCount(1); + } + + public function testProcessIgnoresLazyServices() + { + $container = new ContainerBuilder(); + $container->register('a')->setLazy(true)->addArgument(new Reference('b')); + $container->register('b')->addArgument(new Reference('a')); + + $this->process($container); + + // just make sure that a lazily loaded service does not trigger a CircularReferenceException + $this->addToAssertionCount(1); + } + + public function testProcessIgnoresIteratorArguments() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b')->addArgument(new IteratorArgument([new Reference('a')])); + + $this->process($container); + + // just make sure that an IteratorArgument does not trigger a CircularReferenceException + $this->addToAssertionCount(1); + } + + protected function process(ContainerBuilder $container) + { + $compiler = new Compiler(); + $passConfig = $compiler->getPassConfig(); + $passConfig->setOptimizationPasses([ + new AnalyzeServiceReferencesPass(true), + new CheckCircularReferencesPass(), + ]); + $passConfig->setRemovingPasses([]); + + $compiler->compile($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckDefinitionValidityPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckDefinitionValidityPassTest.php new file mode 100644 index 00000000..6caa38c7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckDefinitionValidityPassTest.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CheckDefinitionValidityPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class CheckDefinitionValidityPassTest extends TestCase +{ + public function testProcessDetectsSyntheticNonPublicDefinitions() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + $container->register('a')->setSynthetic(true)->setPublic(false); + + $this->process($container); + } + + public function testProcessDetectsNonSyntheticNonAbstractDefinitionWithoutClass() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + $container->register('a')->setSynthetic(false)->setAbstract(false); + + $this->process($container); + } + + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('a', 'class'); + $container->register('b', 'class')->setSynthetic(true)->setPublic(true); + $container->register('c', 'class')->setAbstract(true); + $container->register('d', 'class')->setSynthetic(true); + + $this->process($container); + + $this->addToAssertionCount(1); + } + + public function testValidTags() + { + $container = new ContainerBuilder(); + $container->register('a', 'class')->addTag('foo', ['bar' => 'baz']); + $container->register('b', 'class')->addTag('foo', ['bar' => null]); + $container->register('c', 'class')->addTag('foo', ['bar' => 1]); + $container->register('d', 'class')->addTag('foo', ['bar' => 1.1]); + + $this->process($container); + + $this->addToAssertionCount(1); + } + + public function testInvalidTags() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + $container->register('a', 'class')->addTag('foo', ['bar' => ['baz' => 'baz']]); + + $this->process($container); + } + + public function testDynamicPublicServiceName() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\EnvParameterException'); + $container = new ContainerBuilder(); + $env = $container->getParameterBag()->get('env(BAR)'); + $container->register("foo.$env", 'class')->setPublic(true); + + $this->process($container); + } + + public function testDynamicPublicAliasName() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\EnvParameterException'); + $container = new ContainerBuilder(); + $env = $container->getParameterBag()->get('env(BAR)'); + $container->setAlias("foo.$env", 'class')->setPublic(true); + + $this->process($container); + } + + public function testDynamicPrivateName() + { + $container = new ContainerBuilder(); + $env = $container->getParameterBag()->get('env(BAR)'); + $container->register("foo.$env", 'class'); + $container->setAlias("bar.$env", 'class'); + + $this->process($container); + + $this->addToAssertionCount(1); + } + + protected function process(ContainerBuilder $container) + { + $pass = new CheckDefinitionValidityPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php new file mode 100644 index 00000000..c4f331b1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Compiler\CheckExceptionOnInvalidReferenceBehaviorPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class CheckExceptionOnInvalidReferenceBehaviorPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + $container->register('b', '\stdClass'); + + $this->process($container); + + $this->addToAssertionCount(1); + } + + public function testProcessThrowsExceptionOnInvalidReference() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException'); + $container = new ContainerBuilder(); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + + $this->process($container); + } + + public function testProcessThrowsExceptionOnInvalidReferenceFromInlinedDefinition() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException'); + $container = new ContainerBuilder(); + + $def = new Definition(); + $def->addArgument(new Reference('b')); + + $container + ->register('a', '\stdClass') + ->addArgument($def) + ; + + $this->process($container); + } + + public function testProcessDefinitionWithBindings() + { + $container = new ContainerBuilder(); + + $container + ->register('b') + ->setBindings([new BoundArgument(new Reference('a'))]) + ; + + $this->process($container); + + $this->addToAssertionCount(1); + } + + private function process(ContainerBuilder $container) + { + $pass = new CheckExceptionOnInvalidReferenceBehaviorPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckReferenceValidityPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckReferenceValidityPassTest.php new file mode 100644 index 00000000..85a8a40f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/CheckReferenceValidityPassTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CheckReferenceValidityPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class CheckReferenceValidityPassTest extends TestCase +{ + public function testProcessDetectsReferenceToAbstractDefinition() + { + $this->expectException('RuntimeException'); + $container = new ContainerBuilder(); + + $container->register('a')->setAbstract(true); + $container->register('b')->addArgument(new Reference('a')); + + $this->process($container); + } + + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('a')->addArgument(new Reference('b')); + $container->register('b'); + + $this->process($container); + + $this->addToAssertionCount(1); + } + + protected function process(ContainerBuilder $container) + { + $pass = new CheckReferenceValidityPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/DecoratorServicePassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/DecoratorServicePassTest.php new file mode 100644 index 00000000..29fc5cc5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/DecoratorServicePassTest.php @@ -0,0 +1,199 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Compiler\DecoratorServicePass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class DecoratorServicePassTest extends TestCase +{ + public function testProcessWithoutAlias() + { + $container = new ContainerBuilder(); + $fooDefinition = $container + ->register('foo') + ->setPublic(false) + ; + $fooExtendedDefinition = $container + ->register('foo.extended') + ->setPublic(true) + ->setDecoratedService('foo') + ; + $barDefinition = $container + ->register('bar') + ->setPublic(true) + ; + $barExtendedDefinition = $container + ->register('bar.extended') + ->setPublic(true) + ->setDecoratedService('bar', 'bar.yoo') + ; + + $this->process($container); + + $this->assertEquals('foo.extended', $container->getAlias('foo')); + $this->assertFalse($container->getAlias('foo')->isPublic()); + + $this->assertEquals('bar.extended', $container->getAlias('bar')); + $this->assertTrue($container->getAlias('bar')->isPublic()); + + $this->assertSame($fooDefinition, $container->getDefinition('foo.extended.inner')); + $this->assertFalse($container->getDefinition('foo.extended.inner')->isPublic()); + + $this->assertSame($barDefinition, $container->getDefinition('bar.yoo')); + $this->assertFalse($container->getDefinition('bar.yoo')->isPublic()); + + $this->assertNull($fooExtendedDefinition->getDecoratedService()); + $this->assertNull($barExtendedDefinition->getDecoratedService()); + } + + public function testProcessWithAlias() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(true) + ; + $container->setAlias('foo.alias', new Alias('foo', false)); + $fooExtendedDefinition = $container + ->register('foo.extended') + ->setPublic(true) + ->setDecoratedService('foo.alias') + ; + + $this->process($container); + + $this->assertEquals('foo.extended', $container->getAlias('foo.alias')); + $this->assertFalse($container->getAlias('foo.alias')->isPublic()); + + $this->assertEquals('foo', $container->getAlias('foo.extended.inner')); + $this->assertFalse($container->getAlias('foo.extended.inner')->isPublic()); + + $this->assertNull($fooExtendedDefinition->getDecoratedService()); + } + + public function testProcessWithPriority() + { + $container = new ContainerBuilder(); + $fooDefinition = $container + ->register('foo') + ->setPublic(false) + ; + $barDefinition = $container + ->register('bar') + ->setPublic(true) + ->setDecoratedService('foo') + ; + $bazDefinition = $container + ->register('baz') + ->setPublic(true) + ->setDecoratedService('foo', null, 5) + ; + $quxDefinition = $container + ->register('qux') + ->setPublic(true) + ->setDecoratedService('foo', null, 3) + ; + + $this->process($container); + + $this->assertEquals('bar', $container->getAlias('foo')); + $this->assertFalse($container->getAlias('foo')->isPublic()); + + $this->assertSame($fooDefinition, $container->getDefinition('baz.inner')); + $this->assertFalse($container->getDefinition('baz.inner')->isPublic()); + + $this->assertEquals('qux', $container->getAlias('bar.inner')); + $this->assertFalse($container->getAlias('bar.inner')->isPublic()); + + $this->assertEquals('baz', $container->getAlias('qux.inner')); + $this->assertFalse($container->getAlias('qux.inner')->isPublic()); + + $this->assertNull($barDefinition->getDecoratedService()); + $this->assertNull($bazDefinition->getDecoratedService()); + $this->assertNull($quxDefinition->getDecoratedService()); + } + + public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinition() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setTags(['bar' => ['attr' => 'baz']]) + ; + $container + ->register('baz') + ->setTags(['foobar' => ['attr' => 'bar']]) + ->setDecoratedService('foo') + ; + + $this->process($container); + + $this->assertEmpty($container->getDefinition('baz.inner')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz'], 'foobar' => ['attr' => 'bar']], $container->getDefinition('baz')->getTags()); + } + + /** + * @group legacy + */ + public function testProcessMergesAutowiringTypesInDecoratingDefinitionAndRemoveThemFromDecoratedDefinition() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addAutowiringType('Bar') + ; + + $container + ->register('child') + ->setDecoratedService('parent') + ->addAutowiringType('Foo') + ; + + $this->process($container); + + $this->assertEquals(['Bar', 'Foo'], $container->getDefinition('child')->getAutowiringTypes()); + $this->assertEmpty($container->getDefinition('child.inner')->getAutowiringTypes()); + } + + public function testProcessMovesTagsFromDecoratedDefinitionToDecoratingDefinitionMultipleTimes() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(true) + ->setTags(['bar' => ['attr' => 'baz']]) + ; + $container + ->register('deco1') + ->setDecoratedService('foo', null, 50) + ; + $container + ->register('deco2') + ->setDecoratedService('foo', null, 2) + ; + + $this->process($container); + + $this->assertEmpty($container->getDefinition('deco1')->getTags()); + $this->assertEquals(['bar' => ['attr' => 'baz']], $container->getDefinition('deco2')->getTags()); + } + + protected function process(ContainerBuilder $container) + { + $repeatedPass = new DecoratorServicePass(); + $repeatedPass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/DefinitionErrorExceptionPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/DefinitionErrorExceptionPassTest.php new file mode 100644 index 00000000..27326197 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/DefinitionErrorExceptionPassTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\DefinitionErrorExceptionPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; + +class DefinitionErrorExceptionPassTest extends TestCase +{ + public function testThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Things went wrong!'); + $container = new ContainerBuilder(); + $def = new Definition(); + $def->addError('Things went wrong!'); + $def->addError('Now something else!'); + $container->register('foo_service_id') + ->setArguments([ + $def, + ]); + + $pass = new DefinitionErrorExceptionPass(); + $pass->process($container); + } + + public function testNoExceptionThrown() + { + $container = new ContainerBuilder(); + $def = new Definition(); + $container->register('foo_service_id') + ->setArguments([ + $def, + ]); + + $pass = new DefinitionErrorExceptionPass(); + $pass->process($container); + $this->assertSame($def, $container->getDefinition('foo_service_id')->getArgument(0)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ExtensionCompilerPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ExtensionCompilerPassTest.php new file mode 100644 index 00000000..810fbe48 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ExtensionCompilerPassTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\ExtensionCompilerPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; + +/** + * @author Wouter J + */ +class ExtensionCompilerPassTest extends TestCase +{ + private $container; + private $pass; + + protected function setUp() + { + $this->container = new ContainerBuilder(); + $this->pass = new ExtensionCompilerPass(); + } + + public function testProcess() + { + $extension1 = new CompilerPassExtension('extension1'); + $extension2 = new DummyExtension('extension2'); + $extension3 = new DummyExtension('extension3'); + $extension4 = new CompilerPassExtension('extension4'); + + $this->container->registerExtension($extension1); + $this->container->registerExtension($extension2); + $this->container->registerExtension($extension3); + $this->container->registerExtension($extension4); + + $this->pass->process($this->container); + + $this->assertTrue($this->container->hasDefinition('extension1')); + $this->assertFalse($this->container->hasDefinition('extension2')); + $this->assertFalse($this->container->hasDefinition('extension3')); + $this->assertTrue($this->container->hasDefinition('extension4')); + } +} + +class DummyExtension extends Extension +{ + private $alias; + + public function __construct($alias) + { + $this->alias = $alias; + } + + public function getAlias() + { + return $this->alias; + } + + public function load(array $configs, ContainerBuilder $container) + { + } + + public function process(ContainerBuilder $container) + { + $container->register($this->alias); + } +} + +class CompilerPassExtension extends DummyExtension implements CompilerPassInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/FactoryReturnTypePassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/FactoryReturnTypePassTest.php new file mode 100644 index 00000000..87f07c70 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/FactoryReturnTypePassTest.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\FactoryReturnTypePass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\factoryFunction; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryParent; + +/** + * @author Guilhem N. + * + * @group legacy + */ +class FactoryReturnTypePassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $factory = $container->register('factory'); + $factory->setFactory([FactoryDummy::class, 'createFactory']); + + $container->setAlias('alias_factory', 'factory'); + + $foo = $container->register('foo'); + $foo->setFactory([new Reference('alias_factory'), 'create']); + + $bar = $container->register('bar', __CLASS__); + $bar->setFactory([new Reference('factory'), 'create']); + + $pass = new FactoryReturnTypePass(); + $pass->process($container); + + if (method_exists(\ReflectionMethod::class, 'getReturnType')) { + $this->assertEquals(FactoryDummy::class, $factory->getClass()); + $this->assertEquals(\stdClass::class, $foo->getClass()); + } else { + $this->assertNull($factory->getClass()); + $this->assertNull($foo->getClass()); + } + $this->assertEquals(__CLASS__, $bar->getClass()); + } + + /** + * @dataProvider returnTypesProvider + */ + public function testReturnTypes($factory, $returnType, $hhvmSupport = true) + { + if (!$hhvmSupport && \defined('HHVM_VERSION')) { + $this->markTestSkipped('Scalar typehints not supported by hhvm.'); + } + + $container = new ContainerBuilder(); + + $service = $container->register('service'); + $service->setFactory($factory); + + $pass = new FactoryReturnTypePass(); + $pass->process($container); + + if (method_exists(\ReflectionMethod::class, 'getReturnType')) { + $this->assertEquals($returnType, $service->getClass()); + } else { + $this->assertNull($service->getClass()); + } + } + + public function returnTypesProvider() + { + return [ + // must be loaded before the function as they are in the same file + [[FactoryDummy::class, 'createBuiltin'], null, false], + [[FactoryDummy::class, 'createParent'], FactoryParent::class], + [[FactoryDummy::class, 'createSelf'], FactoryDummy::class], + [factoryFunction::class, FactoryDummy::class], + ]; + } + + public function testCircularReference() + { + $container = new ContainerBuilder(); + + $factory = $container->register('factory'); + $factory->setFactory([new Reference('factory2'), 'createSelf']); + + $factory2 = $container->register('factory2'); + $factory2->setFactory([new Reference('factory'), 'create']); + + $pass = new FactoryReturnTypePass(); + $pass->process($container); + + $this->assertNull($factory->getClass()); + $this->assertNull($factory2->getClass()); + } + + /** + * @requires function ReflectionMethod::getReturnType + * @expectedDeprecation Relying on its factory's return-type to define the class of service "factory" is deprecated since Symfony 3.3 and won't work in 4.0. Set the "class" attribute to "Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy" on the service definition instead. + */ + public function testCompile() + { + $container = new ContainerBuilder(); + + $factory = $container->register('factory'); + $factory->setFactory([FactoryDummy::class, 'createFactory']); + $container->compile(); + + $this->assertEquals(FactoryDummy::class, $container->getDefinition('factory')->getClass()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/InlineServiceDefinitionsPassTest.php new file mode 100644 index 00000000..d98db640 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/InlineServiceDefinitionsPassTest.php @@ -0,0 +1,358 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\InlineServiceDefinitionsPass; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class InlineServiceDefinitionsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container + ->register('inlinable.service') + ->setPublic(false) + ; + + $container + ->register('service') + ->setArguments([new Reference('inlinable.service')]) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $arguments[0]); + $this->assertSame($container->getDefinition('inlinable.service'), $arguments[0]); + } + + public function testProcessDoesNotInlinesWhenAliasedServiceIsShared() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container->setAlias('moo', 'foo'); + + $container + ->register('service') + ->setArguments([$ref = new Reference('foo')]) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertSame($ref, $arguments[0]); + } + + public function testProcessDoesInlineNonSharedService() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setShared(false) + ; + $container + ->register('bar') + ->setPublic(false) + ->setShared(false) + ; + $container->setAlias('moo', 'bar'); + + $container + ->register('service') + ->setArguments([new Reference('foo'), $ref = new Reference('moo'), new Reference('bar')]) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertEquals($container->getDefinition('foo'), $arguments[0]); + $this->assertNotSame($container->getDefinition('foo'), $arguments[0]); + $this->assertSame($ref, $arguments[1]); + $this->assertEquals($container->getDefinition('bar'), $arguments[2]); + $this->assertNotSame($container->getDefinition('bar'), $arguments[2]); + } + + public function testProcessDoesNotInlineMixedServicesLoop() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->addArgument(new Reference('bar')) + ->setShared(false) + ; + $container + ->register('bar') + ->setPublic(false) + ->addMethodCall('setFoo', [new Reference('foo')]) + ; + + $this->process($container); + + $this->assertEquals(new Reference('bar'), $container->getDefinition('foo')->getArgument(0)); + } + + public function testProcessThrowsOnNonSharedLoops() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> foo -> bar".'); + $container = new ContainerBuilder(); + $container + ->register('foo') + ->addArgument(new Reference('bar')) + ->setShared(false) + ; + $container + ->register('bar') + ->setShared(false) + ->addMethodCall('setFoo', [new Reference('foo')]) + ; + + $this->process($container); + } + + public function testProcessNestedNonSharedServices() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->addArgument(new Reference('bar1')) + ->addArgument(new Reference('bar2')) + ; + $container + ->register('bar1') + ->setShared(false) + ->addArgument(new Reference('baz')) + ; + $container + ->register('bar2') + ->setShared(false) + ->addArgument(new Reference('baz')) + ; + $container + ->register('baz') + ->setShared(false) + ; + + $this->process($container); + + $baz1 = $container->getDefinition('foo')->getArgument(0)->getArgument(0); + $baz2 = $container->getDefinition('foo')->getArgument(1)->getArgument(0); + + $this->assertEquals($container->getDefinition('baz'), $baz1); + $this->assertEquals($container->getDefinition('baz'), $baz2); + $this->assertNotSame($baz1, $baz2); + } + + public function testProcessInlinesIfMultipleReferencesButAllFromTheSameDefinition() + { + $container = new ContainerBuilder(); + + $a = $container->register('a')->setPublic(false); + $b = $container + ->register('b') + ->addArgument(new Reference('a')) + ->addArgument(new Definition(null, [new Reference('a')])) + ; + + $this->process($container); + + $arguments = $b->getArguments(); + $this->assertSame($a, $arguments[0]); + + $inlinedArguments = $arguments[1]->getArguments(); + $this->assertSame($a, $inlinedArguments[0]); + } + + public function testProcessInlinesPrivateFactoryReference() + { + $container = new ContainerBuilder(); + + $container->register('a')->setPublic(false); + $b = $container + ->register('b') + ->setPublic(false) + ->setFactory([new Reference('a'), 'a']) + ; + + $container + ->register('foo') + ->setArguments([ + $ref = new Reference('b'), + ]); + + $this->process($container); + + $inlinedArguments = $container->getDefinition('foo')->getArguments(); + $this->assertSame($b, $inlinedArguments[0]); + } + + public function testProcessDoesNotInlinePrivateFactoryIfReferencedMultipleTimesWithinTheSameDefinition() + { + $container = new ContainerBuilder(); + $container + ->register('a') + ; + $container + ->register('b') + ->setPublic(false) + ->setFactory([new Reference('a'), 'a']) + ; + + $container + ->register('foo') + ->setArguments([ + $ref1 = new Reference('b'), + $ref2 = new Reference('b'), + ]) + ; + $this->process($container); + + $args = $container->getDefinition('foo')->getArguments(); + $this->assertSame($ref1, $args[0]); + $this->assertSame($ref2, $args[1]); + } + + public function testProcessDoesNotInlineReferenceWhenUsedByInlineFactory() + { + $container = new ContainerBuilder(); + $container + ->register('a') + ; + $container + ->register('b') + ->setPublic(false) + ->setFactory([new Reference('a'), 'a']) + ; + + $inlineFactory = new Definition(); + $inlineFactory->setPublic(false); + $inlineFactory->setFactory([new Reference('b'), 'b']); + + $container + ->register('foo') + ->setArguments([ + $ref = new Reference('b'), + $inlineFactory, + ]) + ; + $this->process($container); + + $args = $container->getDefinition('foo')->getArguments(); + $this->assertSame($ref, $args[0]); + } + + public function testProcessDoesNotInlineWhenServiceIsPrivateButLazy() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ->setLazy(true) + ; + + $container + ->register('service') + ->setArguments([$ref = new Reference('foo')]) + ; + + $this->process($container); + + $arguments = $container->getDefinition('service')->getArguments(); + $this->assertSame($ref, $arguments[0]); + } + + public function testProcessDoesNotInlineWhenServiceReferencesItself() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ->addMethodCall('foo', [$ref = new Reference('foo')]) + ; + + $this->process($container); + + $calls = $container->getDefinition('foo')->getMethodCalls(); + $this->assertSame($ref, $calls[0][1][0]); + } + + public function testProcessDoesNotSetLazyArgumentValuesAfterInlining() + { + $container = new ContainerBuilder(); + $container + ->register('inline') + ->setShared(false) + ; + $container + ->register('service-closure') + ->setArguments([new ServiceClosureArgument(new Reference('inline'))]) + ; + $container + ->register('iterator') + ->setArguments([new IteratorArgument([new Reference('inline')])]) + ; + + $this->process($container); + + $values = $container->getDefinition('service-closure')->getArgument(0)->getValues(); + $this->assertInstanceOf(Reference::class, $values[0]); + $this->assertSame('inline', (string) $values[0]); + + $values = $container->getDefinition('iterator')->getArgument(0)->getValues(); + $this->assertInstanceOf(Reference::class, $values[0]); + $this->assertSame('inline', (string) $values[0]); + } + + /** + * @group legacy + */ + public function testGetInlinedServiceIdData() + { + $container = new ContainerBuilder(); + $container + ->register('inlinable.service') + ->setPublic(false) + ; + $container + ->register('non_inlinable.service') + ->setPublic(true) + ; + + $container + ->register('other_service') + ->setArguments([new Reference('inlinable.service')]) + ; + + $inlinePass = new InlineServiceDefinitionsPass(); + $repeatedPass = new RepeatedPass([new AnalyzeServiceReferencesPass(), $inlinePass]); + $repeatedPass->process($container); + + $this->assertEquals(['inlinable.service' => ['other_service']], $inlinePass->getInlinedServiceIds()); + } + + protected function process(ContainerBuilder $container) + { + $repeatedPass = new RepeatedPass([new AnalyzeServiceReferencesPass(), new InlineServiceDefinitionsPass()]); + $repeatedPass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/IntegrationTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/IntegrationTest.php new file mode 100644 index 00000000..348d1d7f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/IntegrationTest.php @@ -0,0 +1,252 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; + +/** + * This class tests the integration of the different compiler passes. + */ +class IntegrationTest extends TestCase +{ + /** + * This tests that dependencies are correctly processed. + * + * We're checking that: + * + * * A is public, B/C are private + * * A -> C + * * B -> C + */ + public function testProcessRemovesAndInlinesRecursively() + { + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + + $a = $container + ->register('a', '\stdClass') + ->addArgument(new Reference('c')) + ; + + $container + ->register('b', '\stdClass') + ->addArgument(new Reference('c')) + ->setPublic(false) + ; + + $c = $container + ->register('c', '\stdClass') + ->setPublic(false) + ; + + $container->compile(); + + $this->assertTrue($container->hasDefinition('a')); + $arguments = $a->getArguments(); + $this->assertSame($c, $arguments[0]); + $this->assertFalse($container->hasDefinition('b')); + $this->assertFalse($container->hasDefinition('c')); + } + + public function testProcessInlinesReferencesToAliases() + { + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + + $a = $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ; + + $container->setAlias('b', new Alias('c', false)); + + $c = $container + ->register('c', '\stdClass') + ->setPublic(false) + ; + + $container->compile(); + + $this->assertTrue($container->hasDefinition('a')); + $arguments = $a->getArguments(); + $this->assertSame($c, $arguments[0]); + $this->assertFalse($container->hasAlias('b')); + $this->assertFalse($container->hasDefinition('c')); + } + + public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDefinition() + { + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + + $container + ->register('a', '\stdClass') + ->addArgument(new Reference('b')) + ->addMethodCall('setC', [new Reference('c')]) + ; + + $container + ->register('b', '\stdClass') + ->addArgument(new Reference('c')) + ->setPublic(false) + ; + + $container + ->register('c', '\stdClass') + ->setPublic(false) + ; + + $container->compile(); + + $this->assertTrue($container->hasDefinition('a')); + $this->assertFalse($container->hasDefinition('b')); + $this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.'); + } + + public function testCanDecorateServiceSubscriber() + { + $container = new ContainerBuilder(); + $container->register(ServiceSubscriberStub::class) + ->addTag('container.service_subscriber') + ->setPublic(true); + + $container->register(DecoratedServiceSubscriber::class) + ->setDecoratedService(ServiceSubscriberStub::class); + + $container->compile(); + + $this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class)); + } + + /** + * @dataProvider getYamlCompileTests + */ + public function testYamlContainerCompiles($directory, $actualServiceId, $expectedServiceId, ContainerBuilder $mainContainer = null) + { + // allow a container to be passed in, which might have autoconfigure settings + $container = $mainContainer ?: new ContainerBuilder(); + $container->setResourceTracking(false); + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Fixtures/yaml/integration/'.$directory)); + $loader->load('main.yml'); + $container->compile(); + $actualService = $container->getDefinition($actualServiceId); + + // create a fresh ContainerBuilder, to avoid autoconfigure stuff + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Fixtures/yaml/integration/'.$directory)); + $loader->load('expected.yml'); + $container->compile(); + $expectedService = $container->getDefinition($expectedServiceId); + + // reset changes, we don't care if these differ + $actualService->setChanges([]); + $expectedService->setChanges([]); + + $this->assertEquals($expectedService, $actualService); + } + + public function getYamlCompileTests() + { + $container = new ContainerBuilder(); + $container->registerForAutoconfiguration(IntegrationTestStub::class); + yield [ + 'autoconfigure_child_not_applied', + 'child_service', + 'child_service_expected', + $container, + ]; + + $container = new ContainerBuilder(); + $container->registerForAutoconfiguration(IntegrationTestStub::class); + yield [ + 'autoconfigure_parent_child', + 'child_service', + 'child_service_expected', + $container, + ]; + + $container = new ContainerBuilder(); + $container->registerForAutoconfiguration(IntegrationTestStub::class) + ->addTag('from_autoconfigure'); + yield [ + 'autoconfigure_parent_child_tags', + 'child_service', + 'child_service_expected', + $container, + ]; + + yield [ + 'child_parent', + 'child_service', + 'child_service_expected', + ]; + + yield [ + 'defaults_child_tags', + 'child_service', + 'child_service_expected', + ]; + + yield [ + 'defaults_instanceof_importance', + 'main_service', + 'main_service_expected', + ]; + + yield [ + 'defaults_parent_child', + 'child_service', + 'child_service_expected', + ]; + + yield [ + 'instanceof_parent_child', + 'child_service', + 'child_service_expected', + ]; + } +} + +class ServiceSubscriberStub implements ServiceSubscriberInterface +{ + public static function getSubscribedServices() + { + return []; + } +} + +class DecoratedServiceSubscriber +{ +} + +class IntegrationTestStub extends IntegrationTestStubParent +{ +} + +class IntegrationTestStubParent +{ + public function enableSummer($enable) + { + // methods used in calls - added here to prevent errors for not existing + } + + public function setSunshine($type) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/MergeExtensionConfigurationPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/MergeExtensionConfigurationPassTest.php new file mode 100644 index 00000000..13692657 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/MergeExtensionConfigurationPassTest.php @@ -0,0 +1,197 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +class MergeExtensionConfigurationPassTest extends TestCase +{ + public function testExpressionLanguageProviderForwarding() + { + $tmpProviders = []; + + $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock(); + $extension->expects($this->any()) + ->method('getXsdValidationBasePath') + ->willReturn(false); + $extension->expects($this->any()) + ->method('getNamespace') + ->willReturn('http://example.org/schema/dic/foo'); + $extension->expects($this->any()) + ->method('getAlias') + ->willReturn('foo'); + $extension->expects($this->once()) + ->method('load') + ->willReturnCallback(function (array $config, ContainerBuilder $container) use (&$tmpProviders) { + $tmpProviders = $container->getExpressionLanguageProviders(); + }); + + $provider = $this->getMockBuilder('Symfony\\Component\\ExpressionLanguage\\ExpressionFunctionProviderInterface')->getMock(); + $container = new ContainerBuilder(new ParameterBag()); + $container->registerExtension($extension); + $container->prependExtensionConfig('foo', ['bar' => true]); + $container->addExpressionLanguageProvider($provider); + + $pass = new MergeExtensionConfigurationPass(); + $pass->process($container); + + $this->assertEquals([$provider], $tmpProviders); + } + + public function testExtensionLoadGetAMergeExtensionConfigurationContainerBuilderInstance() + { + $extension = $this->getMockBuilder(FooExtension::class)->setMethods(['load'])->getMock(); + $extension->expects($this->once()) + ->method('load') + ->with($this->isType('array'), $this->isInstanceOf(MergeExtensionConfigurationContainerBuilder::class)) + ; + + $container = new ContainerBuilder(new ParameterBag()); + $container->registerExtension($extension); + $container->prependExtensionConfig('foo', []); + + $pass = new MergeExtensionConfigurationPass(); + $pass->process($container); + } + + public function testExtensionConfigurationIsTrackedByDefault() + { + $extension = $this->getMockBuilder(FooExtension::class)->setMethods(['getConfiguration'])->getMock(); + $extension->expects($this->exactly(2)) + ->method('getConfiguration') + ->willReturn(new FooConfiguration()); + + $container = new ContainerBuilder(new ParameterBag()); + $container->registerExtension($extension); + $container->prependExtensionConfig('foo', ['bar' => true]); + + $pass = new MergeExtensionConfigurationPass(); + $pass->process($container); + + $this->assertContainsEquals(new FileResource(__FILE__), $container->getResources()); + } + + public function testOverriddenEnvsAreMerged() + { + $container = new ContainerBuilder(); + $container->registerExtension(new FooExtension()); + $container->prependExtensionConfig('foo', ['bar' => '%env(FOO)%']); + $container->prependExtensionConfig('foo', ['bar' => '%env(BAR)%', 'baz' => '%env(BAZ)%']); + + $pass = new MergeExtensionConfigurationPass(); + $pass->process($container); + + $this->assertSame(['BAZ', 'FOO'], array_keys($container->getParameterBag()->getEnvPlaceholders())); + $this->assertSame(['BAZ' => 1, 'FOO' => 0], $container->getEnvCounters()); + } + + public function testProcessedEnvsAreIncompatibleWithResolve() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Using a cast in "env(int:FOO)" is incompatible with resolution at compile time in "Symfony\Component\DependencyInjection\Tests\Compiler\BarExtension". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.'); + $container = new ContainerBuilder(); + $container->registerExtension(new BarExtension()); + $container->prependExtensionConfig('bar', []); + + (new MergeExtensionConfigurationPass())->process($container); + } + + public function testThrowingExtensionsGetMergedBag() + { + $container = new ContainerBuilder(); + $container->registerExtension(new ThrowingExtension()); + $container->prependExtensionConfig('throwing', ['bar' => '%env(FOO)%']); + + try { + $pass = new MergeExtensionConfigurationPass(); + $pass->process($container); + $this->fail('An exception should have been thrown.'); + } catch (\Exception $e) { + } + + $this->assertSame(['FOO'], array_keys($container->getParameterBag()->getEnvPlaceholders())); + } +} + +class FooConfiguration implements ConfigurationInterface +{ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('foo'); + $rootNode + ->children() + ->scalarNode('bar')->end() + ->scalarNode('baz')->end() + ->end(); + + return $treeBuilder; + } +} + +class FooExtension extends Extension +{ + public function getAlias() + { + return 'foo'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new FooConfiguration(); + } + + public function load(array $configs, ContainerBuilder $container) + { + $configuration = $this->getConfiguration($configs, $container); + $config = $this->processConfiguration($configuration, $configs); + + if (isset($config['baz'])) { + $container->getParameterBag()->get('env(BOZ)'); + $container->resolveEnvPlaceholders($config['baz']); + } + } +} + +class BarExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + $container->resolveEnvPlaceholders('%env(int:FOO)%', true); + } +} + +class ThrowingExtension extends Extension +{ + public function getAlias() + { + return 'throwing'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + return new FooConfiguration(); + } + + public function load(array $configs, ContainerBuilder $container) + { + throw new \Exception(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/OptionalServiceClass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/OptionalServiceClass.php new file mode 100644 index 00000000..7e9238f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/OptionalServiceClass.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use Symfony\Bug\NotExistClass; + +class OptionalServiceClass extends NotExistClass +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/PassConfigTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/PassConfigTest.php new file mode 100644 index 00000000..9470e526 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/PassConfigTest.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; + +/** + * @author Guilhem N + */ +class PassConfigTest extends TestCase +{ + public function testPassOrdering() + { + $config = new PassConfig(); + $config->setBeforeOptimizationPasses([]); + + $pass1 = $this->getMockBuilder(CompilerPassInterface::class)->getMock(); + $config->addPass($pass1, PassConfig::TYPE_BEFORE_OPTIMIZATION, 10); + + $pass2 = $this->getMockBuilder(CompilerPassInterface::class)->getMock(); + $config->addPass($pass2, PassConfig::TYPE_BEFORE_OPTIMIZATION, 30); + + $passes = $config->getBeforeOptimizationPasses(); + $this->assertSame($pass2, $passes[0]); + $this->assertSame($pass1, $passes[1]); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/PriorityTaggedServiceTraitTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/PriorityTaggedServiceTraitTest.php new file mode 100644 index 00000000..57682b5d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/PriorityTaggedServiceTraitTest.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +class PriorityTaggedServiceTraitTest extends TestCase +{ + public function testThatCacheWarmersAreProcessedInPriorityOrder() + { + $services = [ + 'my_service1' => ['my_custom_tag' => ['priority' => 100]], + 'my_service2' => ['my_custom_tag' => ['priority' => 200]], + 'my_service3' => ['my_custom_tag' => ['priority' => -501]], + 'my_service4' => ['my_custom_tag' => []], + 'my_service5' => ['my_custom_tag' => ['priority' => -1]], + 'my_service6' => ['my_custom_tag' => ['priority' => -500]], + 'my_service7' => ['my_custom_tag' => ['priority' => -499]], + 'my_service8' => ['my_custom_tag' => ['priority' => 1]], + 'my_service9' => ['my_custom_tag' => ['priority' => -2]], + 'my_service10' => ['my_custom_tag' => ['priority' => -1000]], + 'my_service11' => ['my_custom_tag' => ['priority' => -1001]], + 'my_service12' => ['my_custom_tag' => ['priority' => -1002]], + 'my_service13' => ['my_custom_tag' => ['priority' => -1003]], + 'my_service14' => ['my_custom_tag' => ['priority' => -1000]], + 'my_service15' => ['my_custom_tag' => ['priority' => 1]], + 'my_service16' => ['my_custom_tag' => ['priority' => -1]], + 'my_service17' => ['my_custom_tag' => ['priority' => 200]], + 'my_service18' => ['my_custom_tag' => ['priority' => 100]], + 'my_service19' => ['my_custom_tag' => []], + ]; + + $container = new ContainerBuilder(); + + foreach ($services as $id => $tags) { + $definition = $container->register($id); + + foreach ($tags as $name => $attributes) { + $definition->addTag($name, $attributes); + } + } + + $expected = [ + new Reference('my_service2'), + new Reference('my_service17'), + new Reference('my_service1'), + new Reference('my_service18'), + new Reference('my_service8'), + new Reference('my_service15'), + new Reference('my_service4'), + new Reference('my_service19'), + new Reference('my_service5'), + new Reference('my_service16'), + new Reference('my_service9'), + new Reference('my_service7'), + new Reference('my_service6'), + new Reference('my_service3'), + new Reference('my_service10'), + new Reference('my_service14'), + new Reference('my_service11'), + new Reference('my_service12'), + new Reference('my_service13'), + ]; + + $priorityTaggedServiceTraitImplementation = new PriorityTaggedServiceTraitImplementation(); + + $this->assertEquals($expected, $priorityTaggedServiceTraitImplementation->test('my_custom_tag', $container)); + } +} + +class PriorityTaggedServiceTraitImplementation +{ + use PriorityTaggedServiceTrait; + + public function test($tagName, ContainerBuilder $container) + { + return $this->findAndSortTaggedServices($tagName, $container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php new file mode 100644 index 00000000..2c42ba0c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\RegisterEnvVarProcessorsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\EnvVarProcessorInterface; + +class RegisterEnvVarProcessorsPassTest extends TestCase +{ + public function testSimpleProcessor() + { + $container = new ContainerBuilder(); + $container->register('foo', SimpleProcessor::class)->addTag('container.env_var_processor'); + + (new RegisterEnvVarProcessorsPass())->process($container); + + $this->assertTrue($container->has('container.env_var_processors_locator')); + $this->assertInstanceOf(SimpleProcessor::class, $container->get('container.env_var_processors_locator')->get('foo')); + + $expected = [ + 'foo' => ['string'], + 'base64' => ['string'], + 'bool' => ['bool'], + 'const' => ['bool', 'int', 'float', 'string', 'array'], + 'file' => ['string'], + 'float' => ['float'], + 'int' => ['int'], + 'json' => ['array'], + 'resolve' => ['string'], + 'string' => ['string'], + ]; + + $this->assertSame($expected, $container->getParameterBag()->getProvidedTypes()); + } + + public function testNoProcessor() + { + $container = new ContainerBuilder(); + + (new RegisterEnvVarProcessorsPass())->process($container); + + $this->assertFalse($container->has('container.env_var_processors_locator')); + } + + public function testBadProcessor() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid type "foo" returned by "Symfony\Component\DependencyInjection\Tests\Compiler\BadProcessor::getProvidedTypes()", expected one of "array", "bool", "float", "int", "string".'); + $container = new ContainerBuilder(); + $container->register('foo', BadProcessor::class)->addTag('container.env_var_processor'); + + (new RegisterEnvVarProcessorsPass())->process($container); + } +} + +class SimpleProcessor implements EnvVarProcessorInterface +{ + public function getEnv($prefix, $name, \Closure $getEnv) + { + return $getEnv($name); + } + + public static function getProvidedTypes() + { + return ['foo' => 'string']; + } +} + +class BadProcessor extends SimpleProcessor +{ + public static function getProvidedTypes() + { + return ['foo' => 'string|foo']; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RegisterServiceSubscribersPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RegisterServiceSubscribersPassTest.php new file mode 100644 index 00000000..a16bfc16 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RegisterServiceSubscribersPassTest.php @@ -0,0 +1,133 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\RegisterServiceSubscribersPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveServiceSubscribersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; +use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber; +use Symfony\Component\DependencyInjection\TypedReference; + +require_once __DIR__.'/../Fixtures/includes/classes.php'; + +class RegisterServiceSubscribersPassTest extends TestCase +{ + public function testInvalidClass() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Service "foo" must implement interface "Symfony\Component\DependencyInjection\ServiceSubscriberInterface".'); + $container = new ContainerBuilder(); + + $container->register('foo', CustomDefinition::class) + ->addTag('container.service_subscriber') + ; + + (new RegisterServiceSubscribersPass())->process($container); + (new ResolveServiceSubscribersPass())->process($container); + } + + public function testInvalidAttributes() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "bar" given for service "foo".'); + $container = new ContainerBuilder(); + + $container->register('foo', TestServiceSubscriber::class) + ->addTag('container.service_subscriber', ['bar' => '123']) + ; + + (new RegisterServiceSubscribersPass())->process($container); + (new ResolveServiceSubscribersPass())->process($container); + } + + public function testNoAttributes() + { + $container = new ContainerBuilder(); + + $container->register('foo', TestServiceSubscriber::class) + ->addArgument(new Reference(PsrContainerInterface::class)) + ->addTag('container.service_subscriber') + ; + + (new RegisterServiceSubscribersPass())->process($container); + (new ResolveServiceSubscribersPass())->process($container); + + $foo = $container->getDefinition('foo'); + $locator = $container->getDefinition((string) $foo->getArgument(0)); + + $this->assertFalse($locator->isPublic()); + $this->assertSame(ServiceLocator::class, $locator->getClass()); + + $expected = [ + TestServiceSubscriber::class => new ServiceClosureArgument(new TypedReference(TestServiceSubscriber::class, TestServiceSubscriber::class, TestServiceSubscriber::class)), + CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), + 'bar' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class)), + 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), + ]; + + $this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0)); + } + + public function testWithAttributes() + { + $container = new ContainerBuilder(); + + $container->register('foo', TestServiceSubscriber::class) + ->setAutowired(true) + ->addArgument(new Reference(PsrContainerInterface::class)) + ->addTag('container.service_subscriber', ['key' => 'bar', 'id' => 'bar']) + ->addTag('container.service_subscriber', ['key' => 'bar', 'id' => 'baz']) // should be ignored: the first wins + ; + + (new RegisterServiceSubscribersPass())->process($container); + (new ResolveServiceSubscribersPass())->process($container); + + $foo = $container->getDefinition('foo'); + $locator = $container->getDefinition((string) $foo->getArgument(0)); + + $this->assertFalse($locator->isPublic()); + $this->assertSame(ServiceLocator::class, $locator->getClass()); + + $expected = [ + TestServiceSubscriber::class => new ServiceClosureArgument(new TypedReference(TestServiceSubscriber::class, TestServiceSubscriber::class, TestServiceSubscriber::class)), + CustomDefinition::class => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), + 'bar' => new ServiceClosureArgument(new TypedReference('bar', CustomDefinition::class, TestServiceSubscriber::class)), + 'baz' => new ServiceClosureArgument(new TypedReference(CustomDefinition::class, CustomDefinition::class, TestServiceSubscriber::class, ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), + ]; + + $this->assertEquals($expected, $container->getDefinition((string) $locator->getFactory()[0])->getArgument(0)); + } + + public function testExtraServiceSubscriber() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Service key "test" does not exist in the map returned by "Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber::getSubscribedServices()" for service "foo_service".'); + $container = new ContainerBuilder(); + $container->register('foo_service', TestServiceSubscriber::class) + ->setAutowired(true) + ->addArgument(new Reference(PsrContainerInterface::class)) + ->addTag('container.service_subscriber', [ + 'key' => 'test', + 'id' => TestServiceSubscriber::class, + ]) + ; + $container->register(TestServiceSubscriber::class, TestServiceSubscriber::class); + $container->compile(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php new file mode 100644 index 00000000..1dfdd9dd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass; +use Symfony\Component\DependencyInjection\Compiler\RemoveUnusedDefinitionsPass; +use Symfony\Component\DependencyInjection\Compiler\RepeatedPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class RemoveUnusedDefinitionsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container + ->register('bar') + ->setPublic(false) + ; + $container + ->register('moo') + ->setArguments([new Reference('bar')]) + ; + + $this->process($container); + + $this->assertFalse($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + $this->assertTrue($container->hasDefinition('moo')); + } + + public function testProcessRemovesUnusedDefinitionsRecursively() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container + ->register('bar') + ->setArguments([new Reference('foo')]) + ->setPublic(false) + ; + + $this->process($container); + + $this->assertFalse($container->hasDefinition('foo')); + $this->assertFalse($container->hasDefinition('bar')); + } + + public function testProcessWorksWithInlinedDefinitions() + { + $container = new ContainerBuilder(); + $container + ->register('foo') + ->setPublic(false) + ; + $container + ->register('bar') + ->setArguments([new Definition(null, [new Reference('foo')])]) + ; + + $this->process($container); + + $this->assertTrue($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + } + + public function testProcessWontRemovePrivateFactory() + { + $container = new ContainerBuilder(); + + $container + ->register('foo', 'stdClass') + ->setFactory(['stdClass', 'getInstance']) + ->setPublic(false); + + $container + ->register('bar', 'stdClass') + ->setFactory([new Reference('foo'), 'getInstance']) + ->setPublic(false); + + $container + ->register('foobar') + ->addArgument(new Reference('bar')); + + $this->process($container); + + $this->assertTrue($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + $this->assertTrue($container->hasDefinition('foobar')); + } + + public function testProcessConsiderEnvVariablesAsUsedEvenInPrivateServices() + { + $container = new ContainerBuilder(); + $container->setParameter('env(FOOBAR)', 'test'); + $container + ->register('foo') + ->setArguments(['%env(FOOBAR)%']) + ->setPublic(false) + ; + + $resolvePass = new ResolveParameterPlaceHoldersPass(); + $resolvePass->process($container); + + $this->process($container); + + $this->assertFalse($container->hasDefinition('foo')); + + $envCounters = $container->getEnvCounters(); + $this->assertArrayHasKey('FOOBAR', $envCounters); + $this->assertSame(1, $envCounters['FOOBAR']); + } + + protected function process(ContainerBuilder $container) + { + $repeatedPass = new RepeatedPass([new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass()]); + $repeatedPass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php new file mode 100644 index 00000000..2f0a413c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ReplaceAliasByActualDefinitionPassTest.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ReplaceAliasByActualDefinitionPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +require_once __DIR__.'/../Fixtures/includes/foo.php'; + +class ReplaceAliasByActualDefinitionPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $aDefinition = $container->register('a', '\stdClass'); + $aDefinition->setFactory([new Reference('b'), 'createA']); + + $bDefinition = new Definition('\stdClass'); + $bDefinition->setPublic(false); + $container->setDefinition('b', $bDefinition); + + $container->setAlias('a_alias', 'a'); + $container->setAlias('b_alias', 'b'); + + $container->setAlias('container', 'service_container'); + + $this->process($container); + + $this->assertTrue($container->has('a'), '->process() does nothing to public definitions.'); + $this->assertTrue($container->hasAlias('a_alias')); + $this->assertFalse($container->has('b'), '->process() removes non-public definitions.'); + $this->assertTrue( + $container->has('b_alias') && !$container->hasAlias('b_alias'), + '->process() replaces alias to actual.' + ); + + $this->assertTrue($container->has('container')); + + $resolvedFactory = $aDefinition->getFactory(); + $this->assertSame('b_alias', (string) $resolvedFactory[0]); + } + + public function testProcessWithInvalidAlias() + { + $this->expectException('InvalidArgumentException'); + $container = new ContainerBuilder(); + $container->setAlias('a_alias', 'a'); + $this->process($container); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ReplaceAliasByActualDefinitionPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveBindingsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveBindingsPassTest.php new file mode 100644 index 00000000..7e5994af --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveBindingsPassTest.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass; +use Symfony\Component\DependencyInjection\Compiler\DefinitionErrorExceptionPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists; +use Symfony\Component\DependencyInjection\TypedReference; + +require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php'; + +class ResolveBindingsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $bindings = [CaseSensitiveClass::class => new BoundArgument(new Reference('foo'))]; + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setArguments([1 => '123']); + $definition->addMethodCall('setSensitiveClass'); + $definition->setBindings($bindings); + + $container->register('foo', CaseSensitiveClass::class) + ->setBindings($bindings); + + $pass = new ResolveBindingsPass(); + $pass->process($container); + + $this->assertEquals([new Reference('foo'), '123'], $definition->getArguments()); + $this->assertEquals([['setSensitiveClass', [new Reference('foo')]]], $definition->getMethodCalls()); + } + + public function testUnusedBinding() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Unused binding "$quz" in service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy".'); + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setBindings(['$quz' => '123']); + + $pass = new ResolveBindingsPass(); + $pass->process($container); + } + + public function testMissingParent() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Unused binding "\$quz" in service [\s\S]+/'); + + $container = new ContainerBuilder(); + + $definition = $container->register(ParentNotExists::class, ParentNotExists::class); + $definition->setBindings(['$quz' => '123']); + + $pass = new ResolveBindingsPass(); + $pass->process($container); + } + + public function testTypedReferenceSupport() + { + $container = new ContainerBuilder(); + + $bindings = [CaseSensitiveClass::class => new BoundArgument(new Reference('foo'))]; + + // Explicit service id + $definition1 = $container->register('def1', NamedArgumentsDummy::class); + $definition1->addArgument($typedRef = new TypedReference('bar', CaseSensitiveClass::class)); + $definition1->setBindings($bindings); + + $definition2 = $container->register('def2', NamedArgumentsDummy::class); + $definition2->addArgument(new TypedReference(CaseSensitiveClass::class, CaseSensitiveClass::class)); + $definition2->setBindings($bindings); + + $pass = new ResolveBindingsPass(); + $pass->process($container); + + $this->assertEquals([$typedRef], $container->getDefinition('def1')->getArguments()); + $this->assertEquals([new Reference('foo')], $container->getDefinition('def2')->getArguments()); + } + + public function testScalarSetter() + { + $container = new ContainerBuilder(); + + $definition = $container->autowire('foo', ScalarSetter::class); + $definition->setBindings(['$defaultLocale' => 'fr']); + + (new AutowireRequiredMethodsPass())->process($container); + (new ResolveBindingsPass())->process($container); + + $this->assertEquals([['setDefaultLocale', ['fr']]], $definition->getMethodCalls()); + } + + public function testWithNonExistingSetterAndBinding() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "setLogger()" does not exist.'); + $container = new ContainerBuilder(); + + $bindings = [ + '$c' => (new Definition('logger'))->setFactory('logger'), + ]; + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->addMethodCall('setLogger'); + $definition->setBindings($bindings); + + $pass = new ResolveBindingsPass(); + $pass->process($container); + } + + public function testSyntheticServiceWithBind() + { + $container = new ContainerBuilder(); + $argument = new BoundArgument('bar'); + + $container->register('foo', 'stdClass') + ->addArgument(new Reference('synthetic.service')); + + $container->register('synthetic.service') + ->setSynthetic(true) + ->setBindings(['$apiKey' => $argument]); + + $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class) + ->setBindings(['$apiKey' => $argument]); + + (new ResolveBindingsPass())->process($container); + (new DefinitionErrorExceptionPass())->process($container); + + $this->assertSame([1 => 'bar'], $container->getDefinition(NamedArgumentsDummy::class)->getArguments()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveChildDefinitionsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveChildDefinitionsPassTest.php new file mode 100644 index 00000000..f3cd9fa1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveChildDefinitionsPassTest.php @@ -0,0 +1,449 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class ResolveChildDefinitionsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('parent', 'foo')->setArguments(['moo', 'b'])->setProperty('foo', 'moo'); + $container->setDefinition('child', new ChildDefinition('parent')) + ->replaceArgument(0, 'a') + ->setProperty('foo', 'bar') + ->setClass('bar') + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertNotInstanceOf(ChildDefinition::class, $def); + $this->assertEquals('bar', $def->getClass()); + $this->assertEquals(['a', 'b'], $def->getArguments()); + $this->assertEquals(['foo' => 'bar'], $def->getProperties()); + } + + public function testProcessAppendsMethodCallsAlways() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addMethodCall('foo', ['bar']) + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ->addMethodCall('bar', ['foo']) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals([ + ['foo', ['bar']], + ['bar', ['foo']], + ], $def->getMethodCalls()); + } + + public function testProcessDoesNotCopyAbstract() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setAbstract(true) + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertFalse($def->isAbstract()); + } + + public function testProcessDoesNotCopyShared() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setShared(false) + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertTrue($def->isShared()); + } + + public function testProcessDoesNotCopyTags() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addTag('foo') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals([], $def->getTags()); + } + + public function testProcessDoesNotCopyDecoratedService() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setDecoratedService('foo') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertNull($def->getDecoratedService()); + } + + public function testProcessDoesNotDropShared() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ->setShared(false) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertFalse($def->isShared()); + } + + public function testProcessHandlesMultipleInheritance() + { + $container = new ContainerBuilder(); + + $container + ->register('parent', 'foo') + ->setArguments(['foo', 'bar', 'c']) + ; + + $container + ->setDefinition('child2', new ChildDefinition('child1')) + ->replaceArgument(1, 'b') + ; + + $container + ->setDefinition('child1', new ChildDefinition('parent')) + ->replaceArgument(0, 'a') + ; + + $this->process($container); + + $def = $container->getDefinition('child2'); + $this->assertEquals(['a', 'b', 'c'], $def->getArguments()); + $this->assertEquals('foo', $def->getClass()); + } + + public function testSetLazyOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass'); + + $container->setDefinition('child1', new ChildDefinition('parent')) + ->setLazy(true) + ; + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isLazy()); + } + + public function testSetLazyOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setLazy(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isLazy()); + } + + public function testSetAutowiredOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutowired(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')) + ->setAutowired(false) + ; + + $this->process($container); + + $this->assertFalse($container->getDefinition('child1')->isAutowired()); + } + + public function testSetAutowiredOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutowired(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isAutowired()); + } + + public function testDeepDefinitionsResolving() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'parentClass'); + $container->register('sibling', 'siblingClass') + ->setConfigurator(new ChildDefinition('parent'), 'foo') + ->setFactory([new ChildDefinition('parent'), 'foo']) + ->addArgument(new ChildDefinition('parent')) + ->setProperty('prop', new ChildDefinition('parent')) + ->addMethodCall('meth', [new ChildDefinition('parent')]) + ; + + $this->process($container); + + $configurator = $container->getDefinition('sibling')->getConfigurator(); + $this->assertSame('Symfony\Component\DependencyInjection\Definition', \get_class($configurator)); + $this->assertSame('parentClass', $configurator->getClass()); + + $factory = $container->getDefinition('sibling')->getFactory(); + $this->assertSame('Symfony\Component\DependencyInjection\Definition', \get_class($factory[0])); + $this->assertSame('parentClass', $factory[0]->getClass()); + + $argument = $container->getDefinition('sibling')->getArgument(0); + $this->assertSame('Symfony\Component\DependencyInjection\Definition', \get_class($argument)); + $this->assertSame('parentClass', $argument->getClass()); + + $properties = $container->getDefinition('sibling')->getProperties(); + $this->assertSame('Symfony\Component\DependencyInjection\Definition', \get_class($properties['prop'])); + $this->assertSame('parentClass', $properties['prop']->getClass()); + + $methodCalls = $container->getDefinition('sibling')->getMethodCalls(); + $this->assertSame('Symfony\Component\DependencyInjection\Definition', \get_class($methodCalls[0][1][0])); + $this->assertSame('parentClass', $methodCalls[0][1][0]->getClass()); + } + + public function testSetDecoratedServiceOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass'); + + $container->setDefinition('child1', new ChildDefinition('parent')) + ->setDecoratedService('foo', 'foo_inner', 5) + ; + + $this->process($container); + + $this->assertEquals(['foo', 'foo_inner', 5], $container->getDefinition('child1')->getDecoratedService()); + } + + public function testDecoratedServiceCopiesDeprecatedStatusFromParent() + { + $container = new ContainerBuilder(); + $container->register('deprecated_parent') + ->setDeprecated(true) + ; + + $container->setDefinition('decorated_deprecated_parent', new ChildDefinition('deprecated_parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('decorated_deprecated_parent')->isDeprecated()); + } + + public function testDecoratedServiceCanOverwriteDeprecatedParentStatus() + { + $container = new ContainerBuilder(); + $container->register('deprecated_parent') + ->setDeprecated(true) + ; + + $container->setDefinition('decorated_deprecated_parent', new ChildDefinition('deprecated_parent')) + ->setDeprecated(false) + ; + + $this->process($container); + + $this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated()); + } + + /** + * @group legacy + */ + public function testProcessMergeAutowiringTypes() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addAutowiringType('Foo') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ->addAutowiringType('Bar') + ; + + $this->process($container); + + $childDef = $container->getDefinition('child'); + $this->assertEquals(['Foo', 'Bar'], $childDef->getAutowiringTypes()); + + $parentDef = $container->getDefinition('parent'); + $this->assertSame(['Foo'], $parentDef->getAutowiringTypes()); + } + + public function testProcessResolvesAliases() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'ParentClass'); + $container->setAlias('parent_alias', 'parent'); + $container->setDefinition('child', new ChildDefinition('parent_alias')); + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertSame('ParentClass', $def->getClass()); + } + + public function testProcessSetsArguments() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'ParentClass')->setArguments([0]); + $container->setDefinition('child', (new ChildDefinition('parent'))->setArguments([ + 1, + 'index_0' => 2, + 'foo' => 3, + ])); + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertSame([2, 1, 'foo' => 3], $def->getArguments()); + } + + public function testBindings() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setBindings(['a' => '1', 'b' => '2']) + ; + + $container->setDefinition('child', new ChildDefinition('parent')) + ->setBindings(['b' => 'B', 'c' => 'C']) + ; + + $this->process($container); + + $bindings = []; + foreach ($container->getDefinition('child')->getBindings() as $k => $v) { + $bindings[$k] = $v->getValues()[0]; + } + $this->assertEquals(['b' => 'B', 'c' => 'C', 'a' => '1'], $bindings); + } + + public function testSetAutoconfiguredOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutoconfigured(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')); + + $this->process($container); + + $this->assertFalse($container->getDefinition('child1')->isAutoconfigured()); + } + + /** + * @group legacy + */ + public function testAliasExistsForBackwardsCompatibility() + { + $this->assertInstanceOf(ResolveChildDefinitionsPass::class, new ResolveDefinitionTemplatesPass()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveChildDefinitionsPass(); + $pass->process($container); + } + + public function testProcessDetectsChildDefinitionIndirectCircularReference() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $this->expectExceptionMessageMatches('/^Circular reference detected for service "c", path: "c -> b -> a -> c"./'); + $container = new ContainerBuilder(); + + $container->register('a'); + + $container->setDefinition('b', new ChildDefinition('a')); + $container->setDefinition('c', new ChildDefinition('b')); + $container->setDefinition('a', new ChildDefinition('c')); + + $this->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveClassPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveClassPassTest.php new file mode 100644 index 00000000..81e05fb2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveClassPassTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; + +class ResolveClassPassTest extends TestCase +{ + /** + * @dataProvider provideValidClassId + */ + public function testResolveClassFromId($serviceId) + { + $container = new ContainerBuilder(); + $def = $container->register($serviceId); + + (new ResolveClassPass())->process($container); + + $this->assertSame($serviceId, $def->getClass()); + } + + public function provideValidClassId() + { + yield ['Acme\UnknownClass']; + yield [CaseSensitiveClass::class]; + } + + /** + * @dataProvider provideInvalidClassId + */ + public function testWontResolveClassFromId($serviceId) + { + $container = new ContainerBuilder(); + $def = $container->register($serviceId); + + (new ResolveClassPass())->process($container); + + $this->assertNull($def->getClass()); + } + + public function provideInvalidClassId() + { + yield [\stdClass::class]; + yield ['bar']; + yield ['\DateTime']; + } + + public function testNonFqcnChildDefinition() + { + $container = new ContainerBuilder(); + $parent = $container->register('App\Foo', null); + $child = $container->setDefinition('App\Foo.child', new ChildDefinition('App\Foo')); + + (new ResolveClassPass())->process($container); + + $this->assertSame('App\Foo', $parent->getClass()); + $this->assertNull($child->getClass()); + } + + public function testClassFoundChildDefinition() + { + $container = new ContainerBuilder(); + $parent = $container->register('App\Foo', null); + $child = $container->setDefinition(self::class, new ChildDefinition('App\Foo')); + + (new ResolveClassPass())->process($container); + + $this->assertSame('App\Foo', $parent->getClass()); + $this->assertSame(self::class, $child->getClass()); + } + + public function testAmbiguousChildDefinition() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Service definition "App\Foo\Child" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.'); + $container = new ContainerBuilder(); + $container->register('App\Foo', null); + $container->setDefinition('App\Foo\Child', new ChildDefinition('App\Foo')); + + (new ResolveClassPass())->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php new file mode 100644 index 00000000..407c803c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php @@ -0,0 +1,407 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * @group legacy + */ +class ResolveDefinitionTemplatesPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('parent', 'foo')->setArguments(['moo', 'b'])->setProperty('foo', 'moo'); + $container->setDefinition('child', new ChildDefinition('parent')) + ->replaceArgument(0, 'a') + ->setProperty('foo', 'bar') + ->setClass('bar') + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertNotInstanceOf(ChildDefinition::class, $def); + $this->assertEquals('bar', $def->getClass()); + $this->assertEquals(['a', 'b'], $def->getArguments()); + $this->assertEquals(['foo' => 'bar'], $def->getProperties()); + } + + public function testProcessAppendsMethodCallsAlways() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addMethodCall('foo', ['bar']) + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ->addMethodCall('bar', ['foo']) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals([ + ['foo', ['bar']], + ['bar', ['foo']], + ], $def->getMethodCalls()); + } + + public function testProcessDoesNotCopyAbstract() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setAbstract(true) + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertFalse($def->isAbstract()); + } + + public function testProcessDoesNotCopyShared() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setShared(false) + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertTrue($def->isShared()); + } + + public function testProcessDoesNotCopyTags() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addTag('foo') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertEquals([], $def->getTags()); + } + + public function testProcessDoesNotCopyDecoratedService() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->setDecoratedService('foo') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertNull($def->getDecoratedService()); + } + + public function testProcessDoesNotDropShared() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ->setShared(false) + ; + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertFalse($def->isShared()); + } + + public function testProcessHandlesMultipleInheritance() + { + $container = new ContainerBuilder(); + + $container + ->register('parent', 'foo') + ->setArguments(['foo', 'bar', 'c']) + ; + + $container + ->setDefinition('child2', new ChildDefinition('child1')) + ->replaceArgument(1, 'b') + ; + + $container + ->setDefinition('child1', new ChildDefinition('parent')) + ->replaceArgument(0, 'a') + ; + + $this->process($container); + + $def = $container->getDefinition('child2'); + $this->assertEquals(['a', 'b', 'c'], $def->getArguments()); + $this->assertEquals('foo', $def->getClass()); + } + + public function testSetLazyOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass'); + + $container->setDefinition('child1', new ChildDefinition('parent')) + ->setLazy(true) + ; + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isLazy()); + } + + public function testSetLazyOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setLazy(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isLazy()); + } + + public function testSetAutowiredOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutowired(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')) + ->setAutowired(false) + ; + + $this->process($container); + + $this->assertFalse($container->getDefinition('child1')->isAutowired()); + } + + public function testSetAutowiredOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutowired(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('child1')->isAutowired()); + } + + public function testDeepDefinitionsResolving() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'parentClass'); + $container->register('sibling', 'siblingClass') + ->setConfigurator(new ChildDefinition('parent'), 'foo') + ->setFactory([new ChildDefinition('parent'), 'foo']) + ->addArgument(new ChildDefinition('parent')) + ->setProperty('prop', new ChildDefinition('parent')) + ->addMethodCall('meth', [new ChildDefinition('parent')]) + ; + + $this->process($container); + + $configurator = $container->getDefinition('sibling')->getConfigurator(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $configurator); + $this->assertSame('parentClass', $configurator->getClass()); + + $factory = $container->getDefinition('sibling')->getFactory(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $factory[0]); + $this->assertSame('parentClass', $factory[0]->getClass()); + + $argument = $container->getDefinition('sibling')->getArgument(0); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $argument); + $this->assertSame('parentClass', $argument->getClass()); + + $properties = $container->getDefinition('sibling')->getProperties(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $properties['prop']); + $this->assertSame('parentClass', $properties['prop']->getClass()); + + $methodCalls = $container->getDefinition('sibling')->getMethodCalls(); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $methodCalls[0][1][0]); + $this->assertSame('parentClass', $methodCalls[0][1][0]->getClass()); + } + + public function testSetDecoratedServiceOnServiceHasParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass'); + + $container->setDefinition('child1', new ChildDefinition('parent')) + ->setDecoratedService('foo', 'foo_inner', 5) + ; + + $this->process($container); + + $this->assertEquals(['foo', 'foo_inner', 5], $container->getDefinition('child1')->getDecoratedService()); + } + + public function testDecoratedServiceCopiesDeprecatedStatusFromParent() + { + $container = new ContainerBuilder(); + $container->register('deprecated_parent') + ->setDeprecated(true) + ; + + $container->setDefinition('decorated_deprecated_parent', new ChildDefinition('deprecated_parent')); + + $this->process($container); + + $this->assertTrue($container->getDefinition('decorated_deprecated_parent')->isDeprecated()); + } + + public function testDecoratedServiceCanOverwriteDeprecatedParentStatus() + { + $container = new ContainerBuilder(); + $container->register('deprecated_parent') + ->setDeprecated(true) + ; + + $container->setDefinition('decorated_deprecated_parent', new ChildDefinition('deprecated_parent')) + ->setDeprecated(false) + ; + + $this->process($container); + + $this->assertFalse($container->getDefinition('decorated_deprecated_parent')->isDeprecated()); + } + + /** + * @group legacy + */ + public function testProcessMergeAutowiringTypes() + { + $container = new ContainerBuilder(); + + $container + ->register('parent') + ->addAutowiringType('Foo') + ; + + $container + ->setDefinition('child', new ChildDefinition('parent')) + ->addAutowiringType('Bar') + ; + + $this->process($container); + + $childDef = $container->getDefinition('child'); + $this->assertEquals(['Foo', 'Bar'], $childDef->getAutowiringTypes()); + + $parentDef = $container->getDefinition('parent'); + $this->assertSame(['Foo'], $parentDef->getAutowiringTypes()); + } + + public function testProcessResolvesAliases() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'ParentClass'); + $container->setAlias('parent_alias', 'parent'); + $container->setDefinition('child', new ChildDefinition('parent_alias')); + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertSame('ParentClass', $def->getClass()); + } + + public function testProcessSetsArguments() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'ParentClass')->setArguments([0]); + $container->setDefinition('child', (new ChildDefinition('parent'))->setArguments([ + 1, + 'index_0' => 2, + 'foo' => 3, + ])); + + $this->process($container); + + $def = $container->getDefinition('child'); + $this->assertSame([2, 1, 'foo' => 3], $def->getArguments()); + } + + public function testSetAutoconfiguredOnServiceIsParent() + { + $container = new ContainerBuilder(); + + $container->register('parent', 'stdClass') + ->setAutoconfigured(true) + ; + + $container->setDefinition('child1', new ChildDefinition('parent')); + + $this->process($container); + + $this->assertFalse($container->getDefinition('child1')->isAutoconfigured()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveDefinitionTemplatesPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveFactoryClassPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveFactoryClassPassTest.php new file mode 100644 index 00000000..b87fb3db --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveFactoryClassPassTest.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ResolveFactoryClassPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class ResolveFactoryClassPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $factory = $container->register('factory', 'Foo\Bar'); + $factory->setFactory([null, 'create']); + + $pass = new ResolveFactoryClassPass(); + $pass->process($container); + + $this->assertSame(['Foo\Bar', 'create'], $factory->getFactory()); + } + + public function testInlinedDefinitionFactoryIsProcessed() + { + $container = new ContainerBuilder(); + + $factory = $container->register('factory'); + $factory->setFactory([(new Definition('Baz\Qux'))->setFactory([null, 'getInstance']), 'create']); + + $pass = new ResolveFactoryClassPass(); + $pass->process($container); + + $this->assertSame(['Baz\Qux', 'getInstance'], $factory->getFactory()[0]->getFactory()); + } + + public function provideFulfilledFactories() + { + return [ + [['Foo\Bar', 'create']], + [[new Reference('foo'), 'create']], + [[new Definition('Baz'), 'create']], + ]; + } + + /** + * @dataProvider provideFulfilledFactories + */ + public function testIgnoresFulfilledFactories($factory) + { + $container = new ContainerBuilder(); + $definition = new Definition(); + $definition->setFactory($factory); + + $container->setDefinition('factory', $definition); + + $pass = new ResolveFactoryClassPass(); + $pass->process($container); + + $this->assertSame($factory, $container->getDefinition('factory')->getFactory()); + } + + public function testNotAnyClassThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The "factory" service is defined to be created by a factory, but is missing the factory class. Did you forget to define the factory or service class?'); + $container = new ContainerBuilder(); + + $factory = $container->register('factory'); + $factory->setFactory([null, 'create']); + + $pass = new ResolveFactoryClassPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveHotPathPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveHotPathPassTest.php new file mode 100644 index 00000000..a2fece05 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveHotPathPassTest.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\ResolveHotPathPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class ResolveHotPathPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $container->register('foo') + ->addTag('container.hot_path') + ->addArgument(new IteratorArgument([new Reference('lazy')])) + ->addArgument(new Reference('service_container')) + ->addArgument(new Definition('', [new Reference('bar')])) + ->addArgument(new Reference('baz', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE)) + ->addArgument(new Reference('missing')) + ; + + $container->register('lazy'); + $container->register('bar') + ->addArgument(new Reference('buz')) + ->addArgument(new Reference('deprec_ref_notag')); + $container->register('baz') + ->addArgument(new Reference('lazy')) + ->addArgument(new Reference('lazy')); + $container->register('buz'); + $container->register('deprec_with_tag')->setDeprecated()->addTag('container.hot_path'); + $container->register('deprec_ref_notag')->setDeprecated(); + + (new ResolveHotPathPass())->process($container); + + $this->assertFalse($container->getDefinition('lazy')->hasTag('container.hot_path')); + $this->assertTrue($container->getDefinition('bar')->hasTag('container.hot_path')); + $this->assertTrue($container->getDefinition('buz')->hasTag('container.hot_path')); + $this->assertFalse($container->getDefinition('baz')->hasTag('container.hot_path')); + $this->assertFalse($container->getDefinition('service_container')->hasTag('container.hot_path')); + $this->assertFalse($container->getDefinition('deprec_with_tag')->hasTag('container.hot_path')); + $this->assertFalse($container->getDefinition('deprec_ref_notag')->hasTag('container.hot_path')); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php new file mode 100644 index 00000000..0d81cdf3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php @@ -0,0 +1,262 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass; +use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class ResolveInstanceofConditionalsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $def = $container->register('foo', self::class)->addTag('tag')->setAutowired(true)->setChanges([]); + $def->setInstanceofConditionals([ + parent::class => (new ChildDefinition(''))->setProperty('foo', 'bar')->addTag('baz', ['attr' => 123]), + ]); + + (new ResolveInstanceofConditionalsPass())->process($container); + + $parent = 'instanceof.'.parent::class.'.0.foo'; + $def = $container->getDefinition('foo'); + $this->assertEmpty($def->getInstanceofConditionals()); + $this->assertInstanceOf(ChildDefinition::class, $def); + $this->assertTrue($def->isAutowired()); + $this->assertSame($parent, $def->getParent()); + $this->assertSame(['tag' => [[]], 'baz' => [['attr' => 123]]], $def->getTags()); + + $parent = $container->getDefinition($parent); + $this->assertSame(['foo' => 'bar'], $parent->getProperties()); + $this->assertSame([], $parent->getTags()); + } + + public function testProcessInheritance() + { + $container = new ContainerBuilder(); + + $def = $container + ->register('parent', parent::class) + ->addMethodCall('foo', ['foo']); + $def->setInstanceofConditionals([ + parent::class => (new ChildDefinition(''))->addMethodCall('foo', ['bar']), + ]); + + $def = (new ChildDefinition('parent'))->setClass(self::class); + $container->setDefinition('child', $def); + + (new ResolveInstanceofConditionalsPass())->process($container); + (new ResolveChildDefinitionsPass())->process($container); + + $expected = [ + ['foo', ['bar']], + ['foo', ['foo']], + ]; + + $this->assertSame($expected, $container->getDefinition('parent')->getMethodCalls()); + $this->assertSame($expected, $container->getDefinition('child')->getMethodCalls()); + } + + public function testProcessDoesReplaceShared() + { + $container = new ContainerBuilder(); + + $def = $container->register('foo', 'stdClass'); + $def->setInstanceofConditionals([ + 'stdClass' => (new ChildDefinition(''))->setShared(false), + ]); + + (new ResolveInstanceofConditionalsPass())->process($container); + + $def = $container->getDefinition('foo'); + $this->assertFalse($def->isShared()); + } + + public function testProcessHandlesMultipleInheritance() + { + $container = new ContainerBuilder(); + + $def = $container->register('foo', self::class)->setShared(true); + + $def->setInstanceofConditionals([ + parent::class => (new ChildDefinition(''))->setLazy(true)->setShared(false), + self::class => (new ChildDefinition(''))->setAutowired(true), + ]); + + (new ResolveInstanceofConditionalsPass())->process($container); + (new ResolveChildDefinitionsPass())->process($container); + + $def = $container->getDefinition('foo'); + $this->assertTrue($def->isAutowired()); + $this->assertTrue($def->isLazy()); + $this->assertTrue($def->isShared()); + } + + public function testProcessUsesAutoconfiguredInstanceof() + { + $container = new ContainerBuilder(); + $def = $container->register('normal_service', self::class); + $def->setInstanceofConditionals([ + parent::class => (new ChildDefinition('')) + ->addTag('local_instanceof_tag') + ->setFactory('locally_set_factory'), + ]); + $def->setAutoconfigured(true); + $container->registerForAutoconfiguration(parent::class) + ->addTag('autoconfigured_tag') + ->setAutowired(true) + ->setFactory('autoconfigured_factory'); + + (new ResolveInstanceofConditionalsPass())->process($container); + (new ResolveChildDefinitionsPass())->process($container); + + $def = $container->getDefinition('normal_service'); + // autowired thanks to the autoconfigured instanceof + $this->assertTrue($def->isAutowired()); + // factory from the specific instanceof overrides global one + $this->assertEquals('locally_set_factory', $def->getFactory()); + // tags are merged, the locally set one is first + $this->assertSame(['local_instanceof_tag' => [[]], 'autoconfigured_tag' => [[]]], $def->getTags()); + } + + public function testAutoconfigureInstanceofDoesNotDuplicateTags() + { + $container = new ContainerBuilder(); + $def = $container->register('normal_service', self::class); + $def + ->addTag('duplicated_tag') + ->addTag('duplicated_tag', ['and_attributes' => 1]) + ; + $def->setInstanceofConditionals([ + parent::class => (new ChildDefinition(''))->addTag('duplicated_tag'), + ]); + $def->setAutoconfigured(true); + $container->registerForAutoconfiguration(parent::class) + ->addTag('duplicated_tag', ['and_attributes' => 1]) + ; + + (new ResolveInstanceofConditionalsPass())->process($container); + (new ResolveChildDefinitionsPass())->process($container); + + $def = $container->getDefinition('normal_service'); + $this->assertSame(['duplicated_tag' => [[], ['and_attributes' => 1]]], $def->getTags()); + } + + public function testProcessDoesNotUseAutoconfiguredInstanceofIfNotEnabled() + { + $container = new ContainerBuilder(); + $def = $container->register('normal_service', self::class); + $def->setInstanceofConditionals([ + parent::class => (new ChildDefinition('')) + ->addTag('foo_tag'), + ]); + $container->registerForAutoconfiguration(parent::class) + ->setAutowired(true); + + (new ResolveInstanceofConditionalsPass())->process($container); + (new ResolveChildDefinitionsPass())->process($container); + + $def = $container->getDefinition('normal_service'); + $this->assertFalse($def->isAutowired()); + } + + public function testBadInterfaceThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('"App\FakeInterface" is set as an "instanceof" conditional, but it does not exist.'); + $container = new ContainerBuilder(); + $def = $container->register('normal_service', self::class); + $def->setInstanceofConditionals([ + 'App\\FakeInterface' => (new ChildDefinition('')) + ->addTag('foo_tag'), + ]); + + (new ResolveInstanceofConditionalsPass())->process($container); + } + + public function testBadInterfaceForAutomaticInstanceofIsOk() + { + $container = new ContainerBuilder(); + $container->register('normal_service', self::class) + ->setAutoconfigured(true); + $container->registerForAutoconfiguration('App\\FakeInterface') + ->setAutowired(true); + + (new ResolveInstanceofConditionalsPass())->process($container); + $this->assertTrue($container->hasDefinition('normal_service')); + } + + public function testProcessThrowsExceptionForAutoconfiguredCalls() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Autoconfigured instanceof for type "PHPUnit[\\\\_]Framework[\\\\_]TestCase" defines method calls but these are not supported and should be removed\./'); + $container = new ContainerBuilder(); + $container->registerForAutoconfiguration(parent::class) + ->addMethodCall('setFoo'); + + (new ResolveInstanceofConditionalsPass())->process($container); + } + + public function testProcessThrowsExceptionForArguments() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Autoconfigured instanceof for type "PHPUnit[\\\\_]Framework[\\\\_]TestCase" defines arguments but these are not supported and should be removed\./'); + $container = new ContainerBuilder(); + $container->registerForAutoconfiguration(parent::class) + ->addArgument('bar'); + + (new ResolveInstanceofConditionalsPass())->process($container); + } + + public function testMergeReset() + { + $container = new ContainerBuilder(); + + $container + ->register('bar', self::class) + ->addArgument('a') + ->addMethodCall('setB') + ->setDecoratedService('foo') + ->addTag('t') + ->setInstanceofConditionals([ + parent::class => (new ChildDefinition(''))->addTag('bar'), + ]) + ; + + (new ResolveInstanceofConditionalsPass())->process($container); + + $abstract = $container->getDefinition('abstract.instanceof.bar'); + + $this->assertEmpty($abstract->getArguments()); + $this->assertEmpty($abstract->getMethodCalls()); + $this->assertNull($abstract->getDecoratedService()); + $this->assertEmpty($abstract->getTags()); + $this->assertTrue($abstract->isAbstract()); + } + + public function testBindings() + { + $container = new ContainerBuilder(); + $def = $container->register('foo', self::class)->setBindings(['$toto' => 123]); + $def->setInstanceofConditionals([parent::class => new ChildDefinition('')]); + + (new ResolveInstanceofConditionalsPass())->process($container); + + $bindings = $container->getDefinition('foo')->getBindings(); + $this->assertSame(['$toto'], array_keys($bindings)); + $this->assertInstanceOf(BoundArgument::class, $bindings['$toto']); + $this->assertSame(123, $bindings['$toto']->getValues()[0]); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveInvalidReferencesPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveInvalidReferencesPassTest.php new file mode 100644 index 00000000..817cc64c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveInvalidReferencesPassTest.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\Compiler\ResolveInvalidReferencesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Reference; + +class ResolveInvalidReferencesPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->setArguments([ + new Reference('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE), + new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + ]) + ->addMethodCall('foo', [new Reference('moo', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertSame([null, null], $arguments); + $this->assertCount(0, $def->getMethodCalls()); + } + + public function testProcessIgnoreInvalidArgumentInCollectionArgument() + { + $container = new ContainerBuilder(); + $container->register('baz'); + $def = $container + ->register('foo') + ->setArguments([ + [ + new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + $baz = new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + new Reference('moo', ContainerInterface::NULL_ON_INVALID_REFERENCE), + ], + ]) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertSame([$baz, null], $arguments[0]); + } + + public function testProcessKeepMethodCallOnInvalidArgumentInCollectionArgument() + { + $container = new ContainerBuilder(); + $container->register('baz'); + $def = $container + ->register('foo') + ->addMethodCall('foo', [ + [ + new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + $baz = new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + new Reference('moo', ContainerInterface::NULL_ON_INVALID_REFERENCE), + ], + ]) + ; + + $this->process($container); + + $calls = $def->getMethodCalls(); + $this->assertCount(1, $def->getMethodCalls()); + $this->assertSame([$baz, null], $calls[0][1][0]); + } + + public function testProcessIgnoreNonExistentServices() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->setArguments([new Reference('bar')]) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertEquals('bar', (string) $arguments[0]); + } + + public function testProcessRemovesPropertiesOnInvalid() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->setProperty('foo', new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) + ; + + $this->process($container); + + $this->assertEquals([], $def->getProperties()); + } + + public function testProcessRemovesArgumentsOnInvalid() + { + $container = new ContainerBuilder(); + $def = $container + ->register('foo') + ->addArgument([ + [ + new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE), + new ServiceClosureArgument(new Reference('baz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)), + ], + ]) + ; + + $this->process($container); + + $this->assertSame([[[]]], $def->getArguments()); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveInvalidReferencesPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveNamedArgumentsPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveNamedArgumentsPassTest.php new file mode 100644 index 00000000..a10d226f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveNamedArgumentsPassTest.php @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ResolveNamedArgumentsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummyWithoutReturnTypes; +use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1; + +/** + * @author Kévin Dunglas + */ +class ResolveNamedArgumentsPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setArguments([ + 2 => 'http://api.example.com', + '$apiKey' => '123', + 0 => new Reference('foo'), + ]); + $definition->addMethodCall('setApiKey', ['$apiKey' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + + $this->assertEquals([0 => new Reference('foo'), 1 => '123', 2 => 'http://api.example.com'], $definition->getArguments()); + $this->assertEquals([['setApiKey', ['123']]], $definition->getMethodCalls()); + } + + public function testWithFactory() + { + $container = new ContainerBuilder(); + + $container->register('factory', NoConstructor::class); + $definition = $container->register('foo', NoConstructor::class) + ->setFactory([new Reference('factory'), 'create']) + ->setArguments(['$apiKey' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + + $this->assertSame([0 => '123'], $definition->getArguments()); + } + + public function testClassNull() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class); + $definition->setArguments(['$apiKey' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + } + + public function testClassNotExist() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + + $definition = $container->register(NotExist::class, NotExist::class); + $definition->setArguments(['$apiKey' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + } + + public function testClassNoConstructor() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $container = new ContainerBuilder(); + + $definition = $container->register(NoConstructor::class, NoConstructor::class); + $definition->setArguments(['$apiKey' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + } + + public function testArgumentNotFound() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy": method "__construct()" has no argument named "$notFound". Check your service definition.'); + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setArguments(['$notFound' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + } + + public function testCorrectMethodReportedInException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid service "Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1": method "Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummyWithoutReturnTypes::createTestDefinition1()" has no argument named "$notFound". Check your service definition.'); + $container = new ContainerBuilder(); + + $container->register(FactoryDummyWithoutReturnTypes::class, FactoryDummyWithoutReturnTypes::class); + + $definition = $container->register(TestDefinition1::class, TestDefinition1::class); + $definition->setFactory([FactoryDummyWithoutReturnTypes::class, 'createTestDefinition1']); + $definition->setArguments(['$notFound' => '123']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + } + + public function testTypedArgument() + { + $container = new ContainerBuilder(); + + $definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class); + $definition->setArguments(['$apiKey' => '123', CaseSensitiveClass::class => new Reference('foo')]); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + + $this->assertEquals([new Reference('foo'), '123'], $definition->getArguments()); + } + + public function testResolvesMultipleArgumentsOfTheSameType() + { + $container = new ContainerBuilder(); + + $definition = $container->register(SimilarArgumentsDummy::class, SimilarArgumentsDummy::class); + $definition->setArguments([CaseSensitiveClass::class => new Reference('foo'), '$token' => 'qwerty']); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + + $this->assertEquals([new Reference('foo'), 'qwerty', new Reference('foo')], $definition->getArguments()); + } + + public function testResolvePrioritizeNamedOverType() + { + $container = new ContainerBuilder(); + + $definition = $container->register(SimilarArgumentsDummy::class, SimilarArgumentsDummy::class); + $definition->setArguments([CaseSensitiveClass::class => new Reference('foo'), '$token' => 'qwerty', '$class1' => new Reference('bar')]); + + $pass = new ResolveNamedArgumentsPass(); + $pass->process($container); + + $this->assertEquals([new Reference('bar'), 'qwerty', new Reference('foo')], $definition->getArguments()); + } +} + +class NoConstructor +{ + public static function create($apiKey) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php new file mode 100644 index 00000000..06399614 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveParameterPlaceHoldersPassTest.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; + +class ResolveParameterPlaceHoldersPassTest extends TestCase +{ + private $compilerPass; + private $container; + private $fooDefinition; + + protected function setUp() + { + $this->compilerPass = new ResolveParameterPlaceHoldersPass(); + $this->container = $this->createContainerBuilder(); + $this->compilerPass->process($this->container); + $this->fooDefinition = $this->container->getDefinition('foo'); + } + + public function testClassParametersShouldBeResolved() + { + $this->assertSame('Foo', $this->fooDefinition->getClass()); + } + + public function testFactoryParametersShouldBeResolved() + { + $this->assertSame(['FooFactory', 'getFoo'], $this->fooDefinition->getFactory()); + } + + public function testArgumentParametersShouldBeResolved() + { + $this->assertSame(['bar', ['bar' => 'baz']], $this->fooDefinition->getArguments()); + } + + public function testMethodCallParametersShouldBeResolved() + { + $this->assertSame([['foobar', ['bar', ['bar' => 'baz']]]], $this->fooDefinition->getMethodCalls()); + } + + public function testPropertyParametersShouldBeResolved() + { + $this->assertSame(['bar' => 'baz'], $this->fooDefinition->getProperties()); + } + + public function testFileParametersShouldBeResolved() + { + $this->assertSame('foo.php', $this->fooDefinition->getFile()); + } + + public function testAliasParametersShouldBeResolved() + { + $this->assertSame('foo', $this->container->getAlias('bar')->__toString()); + } + + public function testBindingsShouldBeResolved() + { + list($boundValue) = $this->container->getDefinition('foo')->getBindings()['$baz']->getValues(); + + $this->assertSame($this->container->getParameterBag()->resolveValue('%env(BAZ)%'), $boundValue); + } + + public function testParameterNotFoundExceptionsIsThrown() + { + $this->expectException(ParameterNotFoundException::class); + $this->expectExceptionMessage('The service "baz_service_id" has a dependency on a non-existent parameter "non_existent_param".'); + + $containerBuilder = new ContainerBuilder(); + $definition = $containerBuilder->register('baz_service_id'); + $definition->setArgument(0, '%non_existent_param%'); + + $pass = new ResolveParameterPlaceHoldersPass(); + $pass->process($containerBuilder); + } + + public function testParameterNotFoundExceptionsIsNotThrown() + { + $containerBuilder = new ContainerBuilder(); + $definition = $containerBuilder->register('baz_service_id'); + $definition->setArgument(0, '%non_existent_param%'); + + $pass = new ResolveParameterPlaceHoldersPass(true, false); + $pass->process($containerBuilder); + + $this->assertCount(1, $definition->getErrors()); + } + + private function createContainerBuilder() + { + $containerBuilder = new ContainerBuilder(); + + $containerBuilder->setParameter('foo.class', 'Foo'); + $containerBuilder->setParameter('foo.factory.class', 'FooFactory'); + $containerBuilder->setParameter('foo.arg1', 'bar'); + $containerBuilder->setParameter('foo.arg2', ['%foo.arg1%' => 'baz']); + $containerBuilder->setParameter('foo.method', 'foobar'); + $containerBuilder->setParameter('foo.property.name', 'bar'); + $containerBuilder->setParameter('foo.property.value', 'baz'); + $containerBuilder->setParameter('foo.file', 'foo.php'); + $containerBuilder->setParameter('alias.id', 'bar'); + + $fooDefinition = $containerBuilder->register('foo', '%foo.class%'); + $fooDefinition->setFactory(['%foo.factory.class%', 'getFoo']); + $fooDefinition->setArguments(['%foo.arg1%', ['%foo.arg1%' => 'baz']]); + $fooDefinition->addMethodCall('%foo.method%', ['%foo.arg1%', '%foo.arg2%']); + $fooDefinition->setProperty('%foo.property.name%', '%foo.property.value%'); + $fooDefinition->setFile('%foo.file%'); + $fooDefinition->setBindings(['$baz' => '%env(BAZ)%']); + + $containerBuilder->setAlias('%alias.id%', 'foo'); + + return $containerBuilder; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolvePrivatesPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolvePrivatesPassTest.php new file mode 100644 index 00000000..89af24f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolvePrivatesPassTest.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\ResolvePrivatesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class ResolvePrivatesPassTest extends TestCase +{ + public function testPrivateHasHigherPrecedenceThanPublic() + { + $container = new ContainerBuilder(); + + $container->register('foo', 'stdClass') + ->setPublic(true) + ->setPrivate(true) + ; + + $container->setAlias('bar', 'foo') + ->setPublic(false) + ->setPrivate(false) + ; + + (new ResolvePrivatesPass())->process($container); + + $this->assertFalse($container->getDefinition('foo')->isPublic()); + $this->assertFalse($container->getAlias('bar')->isPublic()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php new file mode 100644 index 00000000..2465bb7e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Compiler\ResolveReferencesToAliasesPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; + +class ResolveReferencesToAliasesPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->setAlias('bar', 'foo'); + $def = $container + ->register('moo') + ->setArguments([new Reference('bar')]) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertEquals('foo', (string) $arguments[0]); + } + + public function testProcessRecursively() + { + $container = new ContainerBuilder(); + $container->setAlias('bar', 'foo'); + $container->setAlias('moo', 'bar'); + $def = $container + ->register('foobar') + ->setArguments([new Reference('moo')]) + ; + + $this->process($container); + + $arguments = $def->getArguments(); + $this->assertEquals('foo', (string) $arguments[0]); + } + + public function testAliasCircularReference() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $container = new ContainerBuilder(); + $container->setAlias('bar', 'foo'); + $container->setAlias('foo', 'bar'); + $this->process($container); + } + + public function testResolveFactory() + { + $container = new ContainerBuilder(); + $container->register('factory', 'Factory'); + $container->setAlias('factory_alias', new Alias('factory')); + $foo = new Definition(); + $foo->setFactory([new Reference('factory_alias'), 'createFoo']); + $container->setDefinition('foo', $foo); + $bar = new Definition(); + $bar->setFactory(['Factory', 'createFoo']); + $container->setDefinition('bar', $bar); + + $this->process($container); + + $resolvedFooFactory = $container->getDefinition('foo')->getFactory(); + $resolvedBarFactory = $container->getDefinition('bar')->getFactory(); + + $this->assertSame('factory', (string) $resolvedFooFactory[0]); + $this->assertSame('Factory', (string) $resolvedBarFactory[0]); + } + + protected function process(ContainerBuilder $container) + { + $pass = new ResolveReferencesToAliasesPass(); + $pass->process($container); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveTaggedIteratorArgumentPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveTaggedIteratorArgumentPassTest.php new file mode 100644 index 00000000..2322817e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ResolveTaggedIteratorArgumentPassTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\ResolveTaggedIteratorArgumentPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * @author Roland Franssen + */ +class ResolveTaggedIteratorArgumentPassTest extends TestCase +{ + public function testProcess() + { + $container = new ContainerBuilder(); + $container->register('a', 'stdClass')->addTag('foo'); + $container->register('b', 'stdClass')->addTag('foo', ['priority' => 20]); + $container->register('c', 'stdClass')->addTag('foo', ['priority' => 10]); + $container->register('d', 'stdClass')->setProperty('foos', new TaggedIteratorArgument('foo')); + + (new ResolveTaggedIteratorArgumentPass())->process($container); + + $properties = $container->getDefinition('d')->getProperties(); + $expected = new TaggedIteratorArgument('foo'); + $expected->setValues([new Reference('b'), new Reference('c'), new Reference('a')]); + $this->assertEquals($expected, $properties['foos']); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ServiceLocatorTagPassTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ServiceLocatorTagPassTest.php new file mode 100644 index 00000000..66af69b5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Compiler/ServiceLocatorTagPassTest.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Compiler; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\BoundArgument; +use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; +use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1; +use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition2; + +require_once __DIR__.'/../Fixtures/includes/classes.php'; + +class ServiceLocatorTagPassTest extends TestCase +{ + public function testNoServices() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid definition for service "foo": an array of references is expected as first argument when the "container.service_locator" tag is set.'); + $container = new ContainerBuilder(); + + $container->register('foo', ServiceLocator::class) + ->addTag('container.service_locator') + ; + + (new ServiceLocatorTagPass())->process($container); + } + + public function testInvalidServices() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid definition for service "foo": an array of references is expected as first argument when the "container.service_locator" tag is set, "string" found for key "0".'); + $container = new ContainerBuilder(); + + $container->register('foo', ServiceLocator::class) + ->setArguments([[ + 'dummy', + ]]) + ->addTag('container.service_locator') + ; + + (new ServiceLocatorTagPass())->process($container); + } + + public function testProcessValue() + { + $container = new ContainerBuilder(); + + $container->register('bar', CustomDefinition::class); + $container->register('baz', CustomDefinition::class); + + $container->register('foo', ServiceLocator::class) + ->setArguments([[ + new Reference('bar'), + new Reference('baz'), + 'some.service' => new Reference('bar'), + ]]) + ->addTag('container.service_locator') + ; + + (new ServiceLocatorTagPass())->process($container); + + /** @var ServiceLocator $locator */ + $locator = $container->get('foo'); + + $this->assertSame(CustomDefinition::class, \get_class($locator('bar'))); + $this->assertSame(CustomDefinition::class, \get_class($locator('baz'))); + $this->assertSame(CustomDefinition::class, \get_class($locator('some.service'))); + } + + public function testServiceWithKeyOverwritesPreviousInheritedKey() + { + $container = new ContainerBuilder(); + + $container->register('bar', TestDefinition1::class); + $container->register('baz', TestDefinition2::class); + + $container->register('foo', ServiceLocator::class) + ->setArguments([[ + new Reference('bar'), + 'bar' => new Reference('baz'), + ]]) + ->addTag('container.service_locator') + ; + + (new ServiceLocatorTagPass())->process($container); + + /** @var ServiceLocator $locator */ + $locator = $container->get('foo'); + + $this->assertSame(TestDefinition2::class, \get_class($locator('bar'))); + } + + public function testInheritedKeyOverwritesPreviousServiceWithKey() + { + $container = new ContainerBuilder(); + + $container->register('bar', TestDefinition1::class); + $container->register('baz', TestDefinition2::class); + + $container->register('foo', ServiceLocator::class) + ->setArguments([[ + 'bar' => new Reference('baz'), + new Reference('bar'), + 16 => new Reference('baz'), + ]]) + ->addTag('container.service_locator') + ; + + (new ServiceLocatorTagPass())->process($container); + + /** @var ServiceLocator $locator */ + $locator = $container->get('foo'); + + $this->assertSame(TestDefinition1::class, \get_class($locator('bar'))); + $this->assertSame(TestDefinition2::class, \get_class($locator(16))); + } + + public function testBindingsAreCopied() + { + $container = new ContainerBuilder(); + + $container->register('foo') + ->setBindings(['foo' => 'foo']); + + $locator = ServiceLocatorTagPass::register($container, ['foo' => new Reference('foo')], 'foo'); + $locator = $container->getDefinition($locator); + $locator = $container->getDefinition($locator->getFactory()[0]); + + $this->assertSame(['foo'], array_keys($locator->getBindings())); + $this->assertInstanceOf(BoundArgument::class, $locator->getBindings()['foo']); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/AutowireServiceResourceTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/AutowireServiceResourceTest.php new file mode 100644 index 00000000..32515507 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/AutowireServiceResourceTest.php @@ -0,0 +1,122 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Config; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Compiler\AutowirePass; +use Symfony\Component\DependencyInjection\Config\AutowireServiceResource; + +/** + * @group legacy + */ +class AutowireServiceResourceTest extends TestCase +{ + /** + * @var AutowireServiceResource + */ + private $resource; + private $file; + private $class; + private $time; + + protected function setUp() + { + $this->file = realpath(sys_get_temp_dir()).'/tmp.php'; + $this->time = time(); + touch($this->file, $this->time); + + $this->class = Foo::class; + $this->resource = new AutowireServiceResource( + $this->class, + $this->file, + [] + ); + } + + public function testToString() + { + $this->assertSame('service.autowire.'.$this->class, (string) $this->resource); + } + + public function testSerializeUnserialize() + { + $unserialized = unserialize(serialize($this->resource)); + + $this->assertEquals($this->resource, $unserialized); + } + + public function testIsFresh() + { + $this->assertTrue($this->resource->isFresh($this->time), '->isFresh() returns true if the resource has not changed in same second'); + $this->assertTrue($this->resource->isFresh($this->time + 10), '->isFresh() returns true if the resource has not changed'); + $this->assertFalse($this->resource->isFresh($this->time - 86400), '->isFresh() returns false if the resource has been updated'); + } + + public function testIsFreshForDeletedResources() + { + unlink($this->file); + + $this->assertFalse($this->resource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the resource does not exist'); + } + + public function testIsNotFreshChangedResource() + { + $oldResource = new AutowireServiceResource( + $this->class, + $this->file, + ['will_be_different'] + ); + + // test with a stale file *and* a resource that *will* be different than the actual + $this->assertFalse($oldResource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the constructor arguments have changed'); + } + + public function testIsFreshSameConstructorArgs() + { + $oldResource = AutowirePass::createResourceForClass( + new \ReflectionClass(Foo::class) + ); + + // test with a stale file *but* the resource will not be changed + $this->assertTrue($oldResource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the constructor arguments have changed'); + } + + public function testNotFreshIfClassNotFound() + { + $resource = new AutowireServiceResource( + 'Some\Non\Existent\Class', + $this->file, + [] + ); + + $this->assertFalse($resource->isFresh($this->getStaleFileTime()), '->isFresh() returns false if the class no longer exists'); + } + + protected function tearDown() + { + if (file_exists($this->file)) { + @unlink($this->file); + } + } + + private function getStaleFileTime() + { + return $this->time - 10; + } +} + +class Foo +{ + public function __construct($foo) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/ContainerParametersResourceCheckerTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/ContainerParametersResourceCheckerTest.php new file mode 100644 index 00000000..51af451c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/ContainerParametersResourceCheckerTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Config; + +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\ResourceCheckerInterface; +use Symfony\Component\DependencyInjection\Config\ContainerParametersResource; +use Symfony\Component\DependencyInjection\Config\ContainerParametersResourceChecker; +use Symfony\Component\DependencyInjection\ContainerInterface; + +class ContainerParametersResourceCheckerTest extends TestCase +{ + /** @var ContainerParametersResource */ + private $resource; + + /** @var ResourceCheckerInterface */ + private $resourceChecker; + + /** @var ContainerInterface */ + private $container; + + protected function setUp() + { + $this->resource = new ContainerParametersResource(['locales' => ['fr', 'en'], 'default_locale' => 'fr']); + $this->container = $this->getMockBuilder(ContainerInterface::class)->getMock(); + $this->resourceChecker = new ContainerParametersResourceChecker($this->container); + } + + public function testSupports() + { + $this->assertTrue($this->resourceChecker->supports($this->resource)); + } + + /** + * @dataProvider isFreshProvider + */ + public function testIsFresh(callable $mockContainer, $expected) + { + $mockContainer($this->container); + + $this->assertSame($expected, $this->resourceChecker->isFresh($this->resource, time())); + } + + public function isFreshProvider() + { + yield 'not fresh on missing parameter' => [function (MockObject $container) { + $container->method('hasParameter')->with('locales')->willReturn(false); + }, false]; + + yield 'not fresh on different value' => [function (MockObject $container) { + $container->method('getParameter')->with('locales')->willReturn(['nl', 'es']); + }, false]; + + yield 'fresh on every identical parameters' => [function (MockObject $container) { + $container->expects($this->exactly(2))->method('hasParameter')->willReturn(true); + $container->expects($this->exactly(2))->method('getParameter') + ->withConsecutive( + [$this->equalTo('locales')], + [$this->equalTo('default_locale')] + ) + ->willReturnMap([ + ['locales', ['fr', 'en']], + ['default_locale', 'fr'], + ]) + ; + }, true]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/ContainerParametersResourceTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/ContainerParametersResourceTest.php new file mode 100644 index 00000000..e177ac16 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Config/ContainerParametersResourceTest.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Config; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Config\ContainerParametersResource; + +class ContainerParametersResourceTest extends TestCase +{ + /** @var ContainerParametersResource */ + private $resource; + + protected function setUp() + { + $this->resource = new ContainerParametersResource(['locales' => ['fr', 'en'], 'default_locale' => 'fr']); + } + + public function testToString() + { + $this->assertSame('container_parameters_9893d3133814ab03cac3490f36dece77', (string) $this->resource); + } + + public function testSerializeUnserialize() + { + $unserialized = unserialize(serialize($this->resource)); + + $this->assertEquals($this->resource, $unserialized); + } + + public function testGetParameters() + { + $this->assertSame(['locales' => ['fr', 'en'], 'default_locale' => 'fr'], $this->resource->getParameters()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ContainerBuilderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ContainerBuilderTest.php new file mode 100644 index 00000000..fd33ce12 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ContainerBuilderTest.php @@ -0,0 +1,1536 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +require_once __DIR__.'/Fixtures/includes/classes.php'; +require_once __DIR__.'/Fixtures/includes/ProjectExtension.php'; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\Config\Resource\ComposerResource; +use Symfony\Component\Config\Resource\DirectoryResource; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\DependencyInjection\Alias; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; +use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory; +use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy; +use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Component\ExpressionLanguage\Expression; + +class ContainerBuilderTest extends TestCase +{ + public function testDefaultRegisteredDefinitions() + { + $builder = new ContainerBuilder(); + + $this->assertCount(1, $builder->getDefinitions()); + $this->assertTrue($builder->hasDefinition('service_container')); + + $definition = $builder->getDefinition('service_container'); + $this->assertInstanceOf(Definition::class, $definition); + $this->assertTrue($definition->isSynthetic()); + $this->assertSame(ContainerInterface::class, $definition->getClass()); + $this->assertTrue($builder->hasAlias(PsrContainerInterface::class)); + $this->assertTrue($builder->hasAlias(ContainerInterface::class)); + } + + public function testDefinitions() + { + $builder = new ContainerBuilder(); + $definitions = [ + 'foo' => new Definition('Bar\FooClass'), + 'bar' => new Definition('BarClass'), + ]; + $builder->setDefinitions($definitions); + $this->assertEquals($definitions, $builder->getDefinitions(), '->setDefinitions() sets the service definitions'); + $this->assertTrue($builder->hasDefinition('foo'), '->hasDefinition() returns true if a service definition exists'); + $this->assertFalse($builder->hasDefinition('foobar'), '->hasDefinition() returns false if a service definition does not exist'); + + $builder->setDefinition('foobar', $foo = new Definition('FooBarClass')); + $this->assertEquals($foo, $builder->getDefinition('foobar'), '->getDefinition() returns a service definition if defined'); + $this->assertSame($builder->setDefinition('foobar', $foo = new Definition('FooBarClass')), $foo, '->setDefinition() implements a fluid interface by returning the service reference'); + + $builder->addDefinitions($defs = ['foobar' => new Definition('FooBarClass')]); + $this->assertEquals(array_merge($definitions, $defs), $builder->getDefinitions(), '->addDefinitions() adds the service definitions'); + + try { + $builder->getDefinition('baz'); + $this->fail('->getDefinition() throws a ServiceNotFoundException if the service definition does not exist'); + } catch (ServiceNotFoundException $e) { + $this->assertEquals('You have requested a non-existent service "baz".', $e->getMessage(), '->getDefinition() throws a ServiceNotFoundException if the service definition does not exist'); + } + } + + /** + * @group legacy + * @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testCreateDeprecatedService() + { + $definition = new Definition('stdClass'); + $definition->setDeprecated(true); + + $builder = new ContainerBuilder(); + $builder->setDefinition('deprecated_foo', $definition); + $builder->get('deprecated_foo'); + } + + public function testRegister() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'Bar\FooClass'); + $this->assertTrue($builder->hasDefinition('foo'), '->register() registers a new service definition'); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Definition', $builder->getDefinition('foo'), '->register() returns the newly created Definition instance'); + } + + public function testAutowire() + { + $builder = new ContainerBuilder(); + $builder->autowire('foo', 'Bar\FooClass'); + + $this->assertTrue($builder->hasDefinition('foo'), '->autowire() registers a new service definition'); + $this->assertTrue($builder->getDefinition('foo')->isAutowired(), '->autowire() creates autowired definitions'); + } + + public function testHas() + { + $builder = new ContainerBuilder(); + $this->assertFalse($builder->has('foo'), '->has() returns false if the service does not exist'); + $builder->register('foo', 'Bar\FooClass'); + $this->assertTrue($builder->has('foo'), '->has() returns true if a service definition exists'); + $builder->set('bar', new \stdClass()); + $this->assertTrue($builder->has('bar'), '->has() returns true if a service exists'); + } + + public function testGetThrowsExceptionIfServiceDoesNotExist() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException'); + $this->expectExceptionMessage('You have requested a non-existent service "foo".'); + $builder = new ContainerBuilder(); + $builder->get('foo'); + } + + public function testGetReturnsNullIfServiceDoesNotExistAndInvalidReferenceIsUsed() + { + $builder = new ContainerBuilder(); + + $this->assertNull($builder->get('foo', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service does not exist and NULL_ON_INVALID_REFERENCE is passed as a second argument'); + } + + public function testGetThrowsCircularReferenceExceptionIfServiceHasReferenceToItself() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $builder = new ContainerBuilder(); + $builder->register('baz', 'stdClass')->setArguments([new Reference('baz')]); + $builder->get('baz'); + } + + public function testGetReturnsSameInstanceWhenServiceIsShared() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + + $this->assertTrue($builder->get('bar') === $builder->get('bar'), '->get() always returns the same instance if the service is shared'); + } + + public function testGetCreatesServiceBasedOnDefinition() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'stdClass'); + + $this->assertIsObject($builder->get('foo'), '->get() returns the service definition associated with the id'); + } + + public function testGetReturnsRegisteredService() + { + $builder = new ContainerBuilder(); + $builder->set('bar', $bar = new \stdClass()); + + $this->assertSame($bar, $builder->get('bar'), '->get() returns the service associated with the id'); + } + + public function testRegisterDoesNotOverrideExistingService() + { + $builder = new ContainerBuilder(); + $builder->set('bar', $bar = new \stdClass()); + $builder->register('bar', 'stdClass'); + + $this->assertSame($bar, $builder->get('bar'), '->get() returns the service associated with the id even if a definition has been defined'); + } + + public function testNonSharedServicesReturnsDifferentInstances() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass')->setShared(false); + + $this->assertNotSame($builder->get('bar'), $builder->get('bar')); + } + + /** + * @dataProvider provideBadId + */ + public function testBadAliasId($id) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $builder = new ContainerBuilder(); + $builder->setAlias($id, 'foo'); + } + + /** + * @dataProvider provideBadId + */ + public function testBadDefinitionId($id) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $builder = new ContainerBuilder(); + $builder->setDefinition($id, new Definition('Foo')); + } + + public function provideBadId() + { + return [ + [''], + ["\0"], + ["\r"], + ["\n"], + ["'"], + ['ab\\'], + ]; + } + + public function testGetUnsetLoadingServiceWhenCreateServiceThrowsAnException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('You have requested a synthetic service ("foo"). The DIC does not know how to construct this service.'); + $builder = new ContainerBuilder(); + $builder->register('foo', 'stdClass')->setSynthetic(true); + + // we expect a RuntimeException here as foo is synthetic + try { + $builder->get('foo'); + } catch (RuntimeException $e) { + } + + // we must also have the same RuntimeException here + $builder->get('foo'); + } + + public function testGetServiceIds() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'stdClass'); + $builder->bar = $bar = new \stdClass(); + $builder->register('bar', 'stdClass'); + $this->assertEquals( + [ + 'service_container', + 'foo', + 'bar', + 'Psr\Container\ContainerInterface', + 'Symfony\Component\DependencyInjection\ContainerInterface', + ], + $builder->getServiceIds(), + '->getServiceIds() returns all defined service ids' + ); + } + + public function testAliases() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'stdClass'); + $builder->setAlias('bar', 'foo'); + $this->assertTrue($builder->hasAlias('bar'), '->hasAlias() returns true if the alias exists'); + $this->assertFalse($builder->hasAlias('foobar'), '->hasAlias() returns false if the alias does not exist'); + $this->assertEquals('foo', (string) $builder->getAlias('bar'), '->getAlias() returns the aliased service'); + $this->assertTrue($builder->has('bar'), '->setAlias() defines a new service'); + $this->assertSame($builder->get('bar'), $builder->get('foo'), '->setAlias() creates a service that is an alias to another one'); + + try { + $builder->setAlias('foobar', 'foobar'); + $this->fail('->setAlias() throws an InvalidArgumentException if the alias references itself'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('An alias can not reference itself, got a circular reference on "foobar".', $e->getMessage(), '->setAlias() throws an InvalidArgumentException if the alias references itself'); + } + + try { + $builder->getAlias('foobar'); + $this->fail('->getAlias() throws an InvalidArgumentException if the alias does not exist'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('The service alias "foobar" does not exist.', $e->getMessage(), '->getAlias() throws an InvalidArgumentException if the alias does not exist'); + } + } + + public function testGetAliases() + { + $builder = new ContainerBuilder(); + $builder->setAlias('bar', 'foo'); + $builder->setAlias('foobar', 'foo'); + $builder->setAlias('moo', new Alias('foo', false)); + + $aliases = $builder->getAliases(); + $this->assertEquals('foo', (string) $aliases['bar']); + $this->assertTrue($aliases['bar']->isPublic()); + $this->assertEquals('foo', (string) $aliases['foobar']); + $this->assertEquals('foo', (string) $aliases['moo']); + $this->assertFalse($aliases['moo']->isPublic()); + + $builder->register('bar', 'stdClass'); + $this->assertFalse($builder->hasAlias('bar')); + + $builder->set('foobar', 'stdClass'); + $builder->set('moo', 'stdClass'); + $this->assertCount(2, $builder->getAliases(), '->getAliases() does not return aliased services that have been overridden'); + } + + public function testSetAliases() + { + $builder = new ContainerBuilder(); + $builder->setAliases(['bar' => 'foo', 'foobar' => 'foo']); + + $aliases = $builder->getAliases(); + $this->assertArrayHasKey('bar', $aliases); + $this->assertArrayHasKey('foobar', $aliases); + } + + public function testAddAliases() + { + $builder = new ContainerBuilder(); + $builder->setAliases(['bar' => 'foo']); + $builder->addAliases(['foobar' => 'foo']); + + $aliases = $builder->getAliases(); + $this->assertArrayHasKey('bar', $aliases); + $this->assertArrayHasKey('foobar', $aliases); + } + + public function testSetReplacesAlias() + { + $builder = new ContainerBuilder(); + $builder->setAlias('alias', 'aliased'); + $builder->set('aliased', new \stdClass()); + + $builder->set('alias', $foo = new \stdClass()); + $this->assertSame($foo, $builder->get('alias'), '->set() replaces an existing alias'); + } + + public function testAliasesKeepInvalidBehavior() + { + $builder = new ContainerBuilder(); + + $aliased = new Definition('stdClass'); + $aliased->addMethodCall('setBar', [new Reference('bar', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]); + $builder->setDefinition('aliased', $aliased); + $builder->setAlias('alias', 'aliased'); + + $this->assertEquals(new \stdClass(), $builder->get('alias')); + } + + public function testAddGetCompilerPass() + { + $builder = new ContainerBuilder(); + $builder->setResourceTracking(false); + $defaultPasses = $builder->getCompiler()->getPassConfig()->getPasses(); + $builder->addCompilerPass($pass1 = $this->getMockBuilder('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface')->getMock(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -5); + $builder->addCompilerPass($pass2 = $this->getMockBuilder('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface')->getMock(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10); + + $passes = $builder->getCompiler()->getPassConfig()->getPasses(); + $this->assertCount(\count($passes) - 2, $defaultPasses); + // Pass 1 is executed later + $this->assertTrue(array_search($pass1, $passes, true) > array_search($pass2, $passes, true)); + } + + public function testCreateService() + { + $builder = new ContainerBuilder(); + $builder->register('foo1', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php'); + $builder->register('foo2', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/%file%.php'); + $builder->setParameter('file', 'foo'); + $this->assertInstanceOf('\Bar\FooClass', $builder->get('foo1'), '->createService() requires the file defined by the service definition'); + $this->assertInstanceOf('\Bar\FooClass', $builder->get('foo2'), '->createService() replaces parameters in the file provided by the service definition'); + } + + public function testCreateProxyWithRealServiceInstantiator() + { + $builder = new ContainerBuilder(); + + $builder->register('foo1', 'Bar\FooClass')->setFile(__DIR__.'/Fixtures/includes/foo.php'); + $builder->getDefinition('foo1')->setLazy(true); + + $foo1 = $builder->get('foo1'); + + $this->assertSame($foo1, $builder->get('foo1'), 'The same proxy is retrieved on multiple subsequent calls'); + $this->assertSame('Bar\FooClass', \get_class($foo1)); + } + + public function testCreateServiceClass() + { + $builder = new ContainerBuilder(); + $builder->register('foo1', '%class%'); + $builder->setParameter('class', 'stdClass'); + $this->assertInstanceOf('\stdClass', $builder->get('foo1'), '->createService() replaces parameters in the class provided by the service definition'); + } + + public function testCreateServiceArguments() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'Bar\FooClass')->addArgument(['foo' => '%value%', '%value%' => 'foo', new Reference('bar'), '%%unescape_it%%']); + $builder->setParameter('value', 'bar'); + $this->assertEquals(['foo' => 'bar', 'bar' => 'foo', $builder->get('bar'), '%unescape_it%'], $builder->get('foo1')->arguments, '->createService() replaces parameters and service references in the arguments provided by the service definition'); + } + + public function testCreateServiceFactory() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'Bar\FooClass')->setFactory('Bar\FooClass::getInstance'); + $builder->register('qux', 'Bar\FooClass')->setFactory(['Bar\FooClass', 'getInstance']); + $builder->register('bar', 'Bar\FooClass')->setFactory([new Definition('Bar\FooClass'), 'getInstance']); + $builder->register('baz', 'Bar\FooClass')->setFactory([new Reference('bar'), 'getInstance']); + + $this->assertTrue($builder->get('foo')->called, '->createService() calls the factory method to create the service instance'); + $this->assertTrue($builder->get('qux')->called, '->createService() calls the factory method to create the service instance'); + $this->assertTrue($builder->get('bar')->called, '->createService() uses anonymous service as factory'); + $this->assertTrue($builder->get('baz')->called, '->createService() uses another service as factory'); + } + + public function testCreateServiceMethodCalls() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', [['%value%', new Reference('bar')]]); + $builder->setParameter('value', 'bar'); + $this->assertEquals(['bar', $builder->get('bar')], $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments'); + } + + public function testCreateServiceMethodCallsWithEscapedParam() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'Bar\FooClass')->addMethodCall('setBar', [['%%unescape_it%%']]); + $builder->setParameter('value', 'bar'); + $this->assertEquals(['%unescape_it%'], $builder->get('foo1')->bar, '->createService() replaces the values in the method calls arguments'); + } + + public function testCreateServiceProperties() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder->register('foo1', 'Bar\FooClass')->setProperty('bar', ['%value%', new Reference('bar'), '%%unescape_it%%']); + $builder->setParameter('value', 'bar'); + $this->assertEquals(['bar', $builder->get('bar'), '%unescape_it%'], $builder->get('foo1')->bar, '->createService() replaces the values in the properties'); + } + + public function testCreateServiceConfigurator() + { + $builder = new ContainerBuilder(); + $builder->register('foo1', 'Bar\FooClass')->setConfigurator('sc_configure'); + $builder->register('foo2', 'Bar\FooClass')->setConfigurator(['%class%', 'configureStatic']); + $builder->setParameter('class', 'BazClass'); + $builder->register('baz', 'BazClass'); + $builder->register('foo3', 'Bar\FooClass')->setConfigurator([new Reference('baz'), 'configure']); + $builder->register('foo4', 'Bar\FooClass')->setConfigurator([$builder->getDefinition('baz'), 'configure']); + $builder->register('foo5', 'Bar\FooClass')->setConfigurator('foo'); + + $this->assertTrue($builder->get('foo1')->configured, '->createService() calls the configurator'); + $this->assertTrue($builder->get('foo2')->configured, '->createService() calls the configurator'); + $this->assertTrue($builder->get('foo3')->configured, '->createService() calls the configurator'); + $this->assertTrue($builder->get('foo4')->configured, '->createService() calls the configurator'); + + try { + $builder->get('foo5'); + $this->fail('->createService() throws an InvalidArgumentException if the configure callable is not a valid callable'); + } catch (\InvalidArgumentException $e) { + $this->assertEquals('The configure callable for class "Bar\FooClass" is not a callable.', $e->getMessage(), '->createService() throws an InvalidArgumentException if the configure callable is not a valid callable'); + } + } + + public function testCreateServiceWithIteratorArgument() + { + $builder = new ContainerBuilder(); + $builder->register('bar', 'stdClass'); + $builder + ->register('lazy_context', 'LazyContext') + ->setArguments([ + new IteratorArgument(['k1' => new Reference('bar'), new Reference('invalid', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]), + new IteratorArgument([]), + ]) + ; + + $lazyContext = $builder->get('lazy_context'); + $this->assertInstanceOf(RewindableGenerator::class, $lazyContext->lazyValues); + $this->assertInstanceOf(RewindableGenerator::class, $lazyContext->lazyEmptyValues); + $this->assertCount(1, $lazyContext->lazyValues); + $this->assertCount(0, $lazyContext->lazyEmptyValues); + + $i = 0; + foreach ($lazyContext->lazyValues as $k => $v) { + ++$i; + $this->assertEquals('k1', $k); + $this->assertInstanceOf('\stdClass', $v); + } + + // The second argument should have been ignored. + $this->assertEquals(1, $i); + + $i = 0; + foreach ($lazyContext->lazyEmptyValues as $k => $v) { + ++$i; + } + + $this->assertEquals(0, $i); + } + + public function testCreateSyntheticService() + { + $this->expectException('RuntimeException'); + $builder = new ContainerBuilder(); + $builder->register('foo', 'Bar\FooClass')->setSynthetic(true); + $builder->get('foo'); + } + + public function testCreateServiceWithExpression() + { + $builder = new ContainerBuilder(); + $builder->setParameter('bar', 'bar'); + $builder->register('bar', 'BarClass'); + $builder->register('foo', 'Bar\FooClass')->addArgument(['foo' => new Expression('service("bar").foo ~ parameter("bar")')]); + $this->assertEquals('foobar', $builder->get('foo')->arguments['foo']); + } + + public function testResolveServices() + { + $builder = new ContainerBuilder(); + $builder->register('foo', 'Bar\FooClass'); + $this->assertEquals($builder->get('foo'), $builder->resolveServices(new Reference('foo')), '->resolveServices() resolves service references to service instances'); + $this->assertEquals(['foo' => ['foo', $builder->get('foo')]], $builder->resolveServices(['foo' => ['foo', new Reference('foo')]]), '->resolveServices() resolves service references to service instances in nested arrays'); + $this->assertEquals($builder->get('foo'), $builder->resolveServices(new Expression('service("foo")')), '->resolveServices() resolves expressions'); + } + + public function testResolveServicesWithDecoratedDefinition() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Constructing service "foo" from a parent definition is not supported at build time.'); + $builder = new ContainerBuilder(); + $builder->setDefinition('grandpa', new Definition('stdClass')); + $builder->setDefinition('parent', new ChildDefinition('grandpa')); + $builder->setDefinition('foo', new ChildDefinition('parent')); + + $builder->get('foo'); + } + + public function testResolveServicesWithCustomDefinitionClass() + { + $builder = new ContainerBuilder(); + $builder->setDefinition('foo', new CustomDefinition('stdClass')); + + $this->assertInstanceOf('stdClass', $builder->get('foo')); + } + + public function testMerge() + { + $container = new ContainerBuilder(new ParameterBag(['bar' => 'foo'])); + $container->setResourceTracking(false); + $config = new ContainerBuilder(new ParameterBag(['foo' => 'bar'])); + $container->merge($config); + $this->assertEquals(['bar' => 'foo', 'foo' => 'bar'], $container->getParameterBag()->all(), '->merge() merges current parameters with the loaded ones'); + + $container = new ContainerBuilder(new ParameterBag(['bar' => 'foo'])); + $container->setResourceTracking(false); + $config = new ContainerBuilder(new ParameterBag(['foo' => '%bar%'])); + $container->merge($config); + $container->compile(); + $this->assertEquals(['bar' => 'foo', 'foo' => 'foo'], $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones'); + + $container = new ContainerBuilder(new ParameterBag(['bar' => 'foo'])); + $container->setResourceTracking(false); + $config = new ContainerBuilder(new ParameterBag(['foo' => '%bar%', 'baz' => '%foo%'])); + $container->merge($config); + $container->compile(); + $this->assertEquals(['bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'], $container->getParameterBag()->all(), '->merge() evaluates the values of the parameters towards already defined ones'); + + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->register('foo', 'Bar\FooClass'); + $container->register('bar', 'BarClass'); + $config = new ContainerBuilder(); + $config->setDefinition('baz', new Definition('BazClass')); + $config->setAlias('alias_for_foo', 'foo'); + $container->merge($config); + $this->assertEquals(['service_container', 'foo', 'bar', 'baz'], array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones'); + + $aliases = $container->getAliases(); + $this->assertArrayHasKey('alias_for_foo', $aliases); + $this->assertEquals('foo', (string) $aliases['alias_for_foo']); + + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->register('foo', 'Bar\FooClass'); + $config->setDefinition('foo', new Definition('BazClass')); + $container->merge($config); + $this->assertEquals('BazClass', $container->getDefinition('foo')->getClass(), '->merge() overrides already defined services'); + + $container = new ContainerBuilder(); + $bag = new EnvPlaceholderParameterBag(); + $bag->get('env(Foo)'); + $config = new ContainerBuilder($bag); + $this->assertSame(['%env(Bar)%'], $config->resolveEnvPlaceholders([$bag->get('env(Bar)')])); + $container->merge($config); + $this->assertEquals(['Foo' => 0, 'Bar' => 1], $container->getEnvCounters()); + + $container = new ContainerBuilder(); + $config = new ContainerBuilder(); + $childDefA = $container->registerForAutoconfiguration('AInterface'); + $childDefB = $config->registerForAutoconfiguration('BInterface'); + $container->merge($config); + $this->assertSame(['AInterface' => $childDefA, 'BInterface' => $childDefB], $container->getAutoconfiguredInstanceof()); + } + + public function testMergeThrowsExceptionForDuplicateAutomaticInstanceofDefinitions() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('"AInterface" has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.'); + $container = new ContainerBuilder(); + $config = new ContainerBuilder(); + $container->registerForAutoconfiguration('AInterface'); + $config->registerForAutoconfiguration('AInterface'); + $container->merge($config); + } + + public function testResolveEnvValues() + { + $_ENV['DUMMY_ENV_VAR'] = 'du%%y'; + $_SERVER['DUMMY_SERVER_VAR'] = 'ABC'; + $_SERVER['HTTP_DUMMY_VAR'] = 'DEF'; + + $container = new ContainerBuilder(); + $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%'); + $container->setParameter('env(HTTP_DUMMY_VAR)', '123'); + + $this->assertSame('%% du%%%%y ABC 123', $container->resolveEnvPlaceholders('%bar%', true)); + + unset($_ENV['DUMMY_ENV_VAR'], $_SERVER['DUMMY_SERVER_VAR'], $_SERVER['HTTP_DUMMY_VAR']); + } + + public function testResolveEnvValuesWithArray() + { + $_ENV['ANOTHER_DUMMY_ENV_VAR'] = 'dummy'; + + $dummyArray = ['1' => 'one', '2' => 'two']; + + $container = new ContainerBuilder(); + $container->setParameter('dummy', '%env(ANOTHER_DUMMY_ENV_VAR)%'); + $container->setParameter('dummy2', $dummyArray); + + $container->resolveEnvPlaceholders('%dummy%', true); + $container->resolveEnvPlaceholders('%dummy2%', true); + + $this->assertIsArray($container->resolveEnvPlaceholders('%dummy2%', true)); + + foreach ($dummyArray as $key => $value) { + $this->assertArrayHasKey($key, $container->resolveEnvPlaceholders('%dummy2%', true)); + } + + unset($_ENV['ANOTHER_DUMMY_ENV_VAR']); + } + + public function testCompileWithResolveEnv() + { + putenv('DUMMY_ENV_VAR=du%%y'); + $_SERVER['DUMMY_SERVER_VAR'] = 'ABC'; + $_SERVER['HTTP_DUMMY_VAR'] = 'DEF'; + + $container = new ContainerBuilder(); + $container->setParameter('env(FOO)', 'Foo'); + $container->setParameter('env(DUMMY_ENV_VAR)', 'GHI'); + $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)% %env(DUMMY_SERVER_VAR)% %env(HTTP_DUMMY_VAR)%'); + $container->setParameter('foo', '%env(FOO)%'); + $container->setParameter('baz', '%foo%'); + $container->setParameter('env(HTTP_DUMMY_VAR)', '123'); + $container->register('teatime', 'stdClass') + ->setProperty('foo', '%env(DUMMY_ENV_VAR)%') + ->setPublic(true) + ; + $container->compile(true); + + $this->assertSame('% du%%y ABC 123', $container->getParameter('bar')); + $this->assertSame('Foo', $container->getParameter('baz')); + $this->assertSame('du%%y', $container->get('teatime')->foo); + + unset($_SERVER['DUMMY_SERVER_VAR'], $_SERVER['HTTP_DUMMY_VAR']); + putenv('DUMMY_ENV_VAR'); + } + + public function testCompileWithArrayResolveEnv() + { + putenv('ARRAY={"foo":"bar"}'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', '%env(json:ARRAY)%'); + $container->compile(true); + + $this->assertSame(['foo' => 'bar'], $container->getParameter('foo')); + + putenv('ARRAY'); + } + + public function testCompileWithArrayAndAnotherResolveEnv() + { + putenv('DUMMY_ENV_VAR=abc'); + putenv('ARRAY={"foo":"bar"}'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', '%env(json:ARRAY)%'); + $container->setParameter('bar', '%env(DUMMY_ENV_VAR)%'); + $container->compile(true); + + $this->assertSame(['foo' => 'bar'], $container->getParameter('foo')); + $this->assertSame('abc', $container->getParameter('bar')); + + putenv('DUMMY_ENV_VAR'); + putenv('ARRAY'); + } + + public function testCompileWithArrayInStringResolveEnv() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('A string value must be composed of strings and/or numbers, but found parameter "env(json:ARRAY)" of type "array" inside string value "ABC %env(json:ARRAY)%".'); + putenv('ARRAY={"foo":"bar"}'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', 'ABC %env(json:ARRAY)%'); + $container->compile(true); + + putenv('ARRAY'); + } + + public function testCompileWithResolveMissingEnv() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\EnvNotFoundException'); + $this->expectExceptionMessage('Environment variable not found: "FOO".'); + $container = new ContainerBuilder(); + $container->setParameter('foo', '%env(FOO)%'); + $container->compile(true); + } + + public function testDynamicEnv() + { + putenv('DUMMY_FOO=some%foo%'); + putenv('DUMMY_BAR=%bar%'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', 'Foo%env(resolve:DUMMY_BAR)%'); + $container->setParameter('bar', 'Bar'); + $container->setParameter('baz', '%env(resolve:DUMMY_FOO)%'); + + $container->compile(true); + putenv('DUMMY_FOO'); + putenv('DUMMY_BAR'); + + $this->assertSame('someFooBar', $container->getParameter('baz')); + } + + public function testCastEnv() + { + $container = new ContainerBuilder(); + $container->setParameter('env(FAKE)', '123'); + + $container->register('foo', 'stdClass') + ->setPublic(true) + ->setProperties([ + 'fake' => '%env(int:FAKE)%', + ]); + + $container->compile(true); + + $this->assertSame(123, $container->get('foo')->fake); + } + + public function testEnvAreNullable() + { + $container = new ContainerBuilder(); + $container->setParameter('env(FAKE)', null); + + $container->register('foo', 'stdClass') + ->setPublic(true) + ->setProperties([ + 'fake' => '%env(int:FAKE)%', + ]); + + $container->compile(true); + + $this->assertNull($container->get('foo')->fake); + } + + public function testEnvInId() + { + $container = include __DIR__.'/Fixtures/containers/container_env_in_id.php'; + $container->compile(true); + + $expected = [ + 'service_container', + 'foo', + 'bar', + 'bar_%env(BAR)%', + ]; + $this->assertSame($expected, array_keys($container->getDefinitions())); + + $expected = [ + PsrContainerInterface::class => true, + ContainerInterface::class => true, + 'baz_%env(BAR)%' => true, + 'bar_%env(BAR)%' => true, + ]; + $this->assertSame($expected, $container->getRemovedIds()); + + $this->assertSame(['baz_bar'], array_keys($container->getDefinition('foo')->getArgument(1))); + } + + public function testCircularDynamicEnv() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException'); + $this->expectExceptionMessage('Circular reference detected for parameter "env(resolve:DUMMY_ENV_VAR)" ("env(resolve:DUMMY_ENV_VAR)" > "env(resolve:DUMMY_ENV_VAR)").'); + putenv('DUMMY_ENV_VAR=some%foo%'); + + $container = new ContainerBuilder(); + $container->setParameter('foo', '%bar%'); + $container->setParameter('bar', '%env(resolve:DUMMY_ENV_VAR)%'); + + try { + $container->compile(true); + } finally { + putenv('DUMMY_ENV_VAR'); + } + } + + public function testMergeLogicException() + { + $this->expectException('LogicException'); + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->compile(); + $container->merge(new ContainerBuilder()); + } + + public function testfindTaggedServiceIds() + { + $builder = new ContainerBuilder(); + $builder + ->register('foo', 'Bar\FooClass') + ->addTag('foo', ['foo' => 'foo']) + ->addTag('bar', ['bar' => 'bar']) + ->addTag('foo', ['foofoo' => 'foofoo']) + ; + $this->assertEquals([ + 'foo' => [ + ['foo' => 'foo'], + ['foofoo' => 'foofoo'], + ], + ], $builder->findTaggedServiceIds('foo'), '->findTaggedServiceIds() returns an array of service ids and its tag attributes'); + $this->assertEquals([], $builder->findTaggedServiceIds('foobar'), '->findTaggedServiceIds() returns an empty array if there is annotated services'); + } + + public function testFindUnusedTags() + { + $builder = new ContainerBuilder(); + $builder + ->register('foo', 'Bar\FooClass') + ->addTag('kernel.event_listener', ['foo' => 'foo']) + ->addTag('kenrel.event_listener', ['bar' => 'bar']) + ; + $builder->findTaggedServiceIds('kernel.event_listener'); + $this->assertEquals(['kenrel.event_listener'], $builder->findUnusedTags(), '->findUnusedTags() returns an array with unused tags'); + } + + public function testFindDefinition() + { + $container = new ContainerBuilder(); + $container->setDefinition('foo', $definition = new Definition('Bar\FooClass')); + $container->setAlias('bar', 'foo'); + $container->setAlias('foobar', 'bar'); + $this->assertEquals($definition, $container->findDefinition('foobar'), '->findDefinition() returns a Definition'); + } + + public function testAddObjectResource() + { + $container = new ContainerBuilder(); + + $container->setResourceTracking(false); + $container->addObjectResource(new \BarClass()); + + $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking'); + + $container->setResourceTracking(true); + $container->addObjectResource(new \BarClass()); + + $resources = $container->getResources(); + + $this->assertCount(2, $resources, '2 resources were registered'); + + /* @var $resource \Symfony\Component\Config\Resource\FileResource */ + $resource = end($resources); + + $this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource); + $this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource())); + } + + /** + * @group legacy + */ + public function testAddClassResource() + { + $container = new ContainerBuilder(); + + $container->setResourceTracking(false); + $container->addClassResource(new \ReflectionClass('BarClass')); + + $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking'); + + $container->setResourceTracking(true); + $container->addClassResource(new \ReflectionClass('BarClass')); + + $resources = $container->getResources(); + + $this->assertCount(2, $resources, '2 resources were registered'); + + /* @var $resource \Symfony\Component\Config\Resource\FileResource */ + $resource = end($resources); + + $this->assertInstanceOf('Symfony\Component\Config\Resource\FileResource', $resource); + $this->assertSame(realpath(__DIR__.'/Fixtures/includes/classes.php'), realpath($resource->getResource())); + } + + public function testGetReflectionClass() + { + $container = new ContainerBuilder(); + + $container->setResourceTracking(false); + $r1 = $container->getReflectionClass('BarClass'); + + $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking'); + + $container->setResourceTracking(true); + $r2 = $container->getReflectionClass('BarClass'); + $r3 = $container->getReflectionClass('BarClass'); + + $this->assertNull($container->getReflectionClass('BarMissingClass')); + + $this->assertEquals($r1, $r2); + $this->assertSame($r2, $r3); + + $resources = $container->getResources(); + + $this->assertCount(3, $resources, '3 resources were registered'); + + $this->assertSame('reflection.BarClass', (string) $resources[1]); + $this->assertSame('BarMissingClass', (string) end($resources)); + } + + public function testGetReflectionClassOnInternalTypes() + { + $container = new ContainerBuilder(); + + $this->assertNull($container->getReflectionClass('int')); + $this->assertNull($container->getReflectionClass('float')); + $this->assertNull($container->getReflectionClass('string')); + $this->assertNull($container->getReflectionClass('bool')); + $this->assertNull($container->getReflectionClass('resource')); + $this->assertNull($container->getReflectionClass('object')); + $this->assertNull($container->getReflectionClass('array')); + $this->assertNull($container->getReflectionClass('null')); + $this->assertNull($container->getReflectionClass('callable')); + $this->assertNull($container->getReflectionClass('iterable')); + $this->assertNull($container->getReflectionClass('mixed')); + } + + public function testCompilesClassDefinitionsOfLazyServices() + { + $container = new ContainerBuilder(); + + $this->assertEmpty($container->getResources(), 'No resources get registered without resource tracking'); + + $container->register('foo', 'BarClass')->setPublic(true); + $container->getDefinition('foo')->setLazy(true); + + $container->compile(); + + $matchingResources = array_filter( + $container->getResources(), + function (ResourceInterface $resource) { + return 'reflection.BarClass' === (string) $resource; + } + ); + + $this->assertNotEmpty($matchingResources); + } + + public function testResources() + { + $container = new ContainerBuilder(); + $container->addResource($a = new FileResource(__DIR__.'/Fixtures/xml/services1.xml')); + $container->addResource($b = new FileResource(__DIR__.'/Fixtures/xml/services2.xml')); + $resources = []; + foreach ($container->getResources() as $resource) { + if (false === strpos($resource, '.php')) { + $resources[] = $resource; + } + } + $this->assertEquals([$a, $b], $resources, '->getResources() returns an array of resources read for the current configuration'); + $this->assertSame($container, $container->setResources([])); + $this->assertEquals([], $container->getResources()); + } + + public function testFileExists() + { + $container = new ContainerBuilder(); + $A = new ComposerResource(); + $a = new FileResource(__DIR__.'/Fixtures/xml/services1.xml'); + $b = new FileResource(__DIR__.'/Fixtures/xml/services2.xml'); + $c = new DirectoryResource($dir = \dirname($b)); + + $this->assertTrue($container->fileExists((string) $a) && $container->fileExists((string) $b) && $container->fileExists($dir)); + + $resources = []; + foreach ($container->getResources() as $resource) { + if (false === strpos($resource, '.php')) { + $resources[] = $resource; + } + } + + $this->assertEquals([$A, $a, $b, $c], $resources, '->getResources() returns an array of resources read for the current configuration'); + } + + public function testExtension() + { + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + + $container->registerExtension($extension = new \ProjectExtension()); + $this->assertSame($container->getExtension('project'), $extension, '->registerExtension() registers an extension'); + + $this->expectException('LogicException'); + $container->getExtension('no_registered'); + } + + public function testRegisteredButNotLoadedExtension() + { + $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock(); + $extension->expects($this->once())->method('getAlias')->willReturn('project'); + $extension->expects($this->never())->method('load'); + + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->registerExtension($extension); + $container->compile(); + } + + public function testRegisteredAndLoadedExtension() + { + $extension = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\Extension\\ExtensionInterface')->getMock(); + $extension->expects($this->exactly(2))->method('getAlias')->willReturn('project'); + $extension->expects($this->once())->method('load')->with([['foo' => 'bar']]); + + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->registerExtension($extension); + $container->loadFromExtension('project', ['foo' => 'bar']); + $container->compile(); + } + + public function testPrivateServiceUser() + { + $fooDefinition = new Definition('BarClass'); + $fooUserDefinition = new Definition('BarUserClass', [new Reference('bar')]); + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + + $fooDefinition->setPublic(false); + + $container->addDefinitions([ + 'bar' => $fooDefinition, + 'bar_user' => $fooUserDefinition->setPublic(true), + ]); + + $container->compile(); + $this->assertInstanceOf('BarClass', $container->get('bar_user')->bar); + } + + public function testThrowsExceptionWhenSetServiceOnACompiledContainer() + { + $this->expectException('BadMethodCallException'); + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->register('a', 'stdClass')->setPublic(true); + $container->compile(); + $container->set('a', new \stdClass()); + } + + public function testNoExceptionWhenAddServiceOnACompiledContainer() + { + $container = new ContainerBuilder(); + $container->compile(); + $container->set('a', $foo = new \stdClass()); + $this->assertSame($foo, $container->get('a')); + } + + public function testNoExceptionWhenSetSyntheticServiceOnACompiledContainer() + { + $container = new ContainerBuilder(); + $def = new Definition('stdClass'); + $def->setSynthetic(true)->setPublic(true); + $container->setDefinition('a', $def); + $container->compile(); + $container->set('a', $a = new \stdClass()); + $this->assertEquals($a, $container->get('a')); + } + + public function testThrowsExceptionWhenSetDefinitionOnACompiledContainer() + { + $this->expectException('BadMethodCallException'); + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->compile(); + $container->setDefinition('a', new Definition()); + } + + public function testExtensionConfig() + { + $container = new ContainerBuilder(); + + $configs = $container->getExtensionConfig('foo'); + $this->assertEmpty($configs); + + $first = ['foo' => 'bar']; + $container->prependExtensionConfig('foo', $first); + $configs = $container->getExtensionConfig('foo'); + $this->assertEquals([$first], $configs); + + $second = ['ding' => 'dong']; + $container->prependExtensionConfig('foo', $second); + $configs = $container->getExtensionConfig('foo'); + $this->assertEquals([$second, $first], $configs); + } + + public function testAbstractAlias() + { + $container = new ContainerBuilder(); + + $abstract = new Definition('AbstractClass'); + $abstract->setAbstract(true)->setPublic(true); + + $container->setDefinition('abstract_service', $abstract); + $container->setAlias('abstract_alias', 'abstract_service')->setPublic(true); + + $container->compile(); + + $this->assertSame('abstract_service', (string) $container->getAlias('abstract_alias')); + } + + public function testLazyLoadedService() + { + $loader = new ClosureLoader($container = new ContainerBuilder()); + $loader->load(function (ContainerBuilder $container) { + $container->set('a', new \BazClass()); + $definition = new Definition('BazClass'); + $definition->setLazy(true); + $definition->setPublic(true); + $container->setDefinition('a', $definition); + }); + + $container->setResourceTracking(true); + + $container->compile(); + + $r = new \ReflectionProperty($container, 'resources'); + $r->setAccessible(true); + $resources = $r->getValue($container); + + $classInList = false; + foreach ($resources as $resource) { + if ('reflection.BazClass' === (string) $resource) { + $classInList = true; + break; + } + } + + $this->assertTrue($classInList); + } + + public function testInlinedDefinitions() + { + $container = new ContainerBuilder(); + + $definition = new Definition('BarClass'); + + $container->register('bar_user', 'BarUserClass') + ->addArgument($definition) + ->setProperty('foo', $definition); + + $container->register('bar', 'BarClass') + ->setProperty('foo', $definition) + ->addMethodCall('setBaz', [$definition]); + + $barUser = $container->get('bar_user'); + $bar = $container->get('bar'); + + $this->assertSame($barUser->foo, $barUser->bar); + $this->assertSame($bar->foo, $bar->getBaz()); + $this->assertNotSame($bar->foo, $barUser->foo); + } + + public function testThrowsCircularExceptionForCircularAliases() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $this->expectExceptionMessage('Circular reference detected for service "app.test_class", path: "app.test_class -> App\TestClass -> app.test_class".'); + $builder = new ContainerBuilder(); + + $builder->setAliases([ + 'foo' => new Alias('app.test_class'), + 'app.test_class' => new Alias('App\\TestClass'), + 'App\\TestClass' => new Alias('app.test_class'), + ]); + + $builder->findDefinition('foo'); + } + + public function testInitializePropertiesBeforeMethodCalls() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass'); + $container->register('bar', 'MethodCallClass') + ->setPublic(true) + ->setProperty('simple', 'bar') + ->setProperty('complex', new Reference('foo')) + ->addMethodCall('callMe'); + + $container->compile(); + + $this->assertTrue($container->get('bar')->callPassed(), '->compile() initializes properties before method calls'); + } + + public function testAutowiring() + { + $container = new ContainerBuilder(); + + $container->register(A::class)->setPublic(true); + $bDefinition = $container->register('b', B::class); + $bDefinition->setAutowired(true); + $bDefinition->setPublic(true); + + $container->compile(); + + $this->assertEquals(A::class, (string) $container->getDefinition('b')->getArgument(0)); + } + + public function testClassFromId() + { + $container = new ContainerBuilder(); + + $unknown = $container->register('Acme\UnknownClass'); + $autoloadClass = $container->register(CaseSensitiveClass::class); + $container->compile(); + + $this->assertSame('Acme\UnknownClass', $unknown->getClass()); + $this->assertEquals(CaseSensitiveClass::class, $autoloadClass->getClass()); + } + + public function testNoClassFromGlobalNamespaceClassId() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The definition for "DateTime" has no class attribute, and appears to reference a class or interface in the global namespace.'); + $container = new ContainerBuilder(); + + $container->register(\DateTime::class); + $container->compile(); + } + + public function testNoClassFromGlobalNamespaceClassIdWithLeadingSlash() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The definition for "\DateTime" has no class attribute, and appears to reference a class or interface in the global namespace.'); + $container = new ContainerBuilder(); + + $container->register('\\'.\DateTime::class); + $container->compile(); + } + + public function testNoClassFromNamespaceClassIdWithLeadingSlash() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The definition for "\Symfony\Component\DependencyInjection\Tests\FooClass" has no class attribute, and appears to reference a class or interface. Please specify the class attribute explicitly or remove the leading backslash by renaming the service to "Symfony\Component\DependencyInjection\Tests\FooClass" to get rid of this error.'); + $container = new ContainerBuilder(); + + $container->register('\\'.FooClass::class); + $container->compile(); + } + + public function testNoClassFromNonClassId() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The definition for "123_abc" has no class.'); + $container = new ContainerBuilder(); + + $container->register('123_abc'); + $container->compile(); + } + + public function testNoClassFromNsSeparatorId() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The definition for "\foo" has no class.'); + $container = new ContainerBuilder(); + + $container->register('\\foo'); + $container->compile(); + } + + public function testServiceLocator() + { + $container = new ContainerBuilder(); + $container->register('foo_service', ServiceLocator::class) + ->setPublic(true) + ->addArgument([ + 'bar' => new ServiceClosureArgument(new Reference('bar_service')), + 'baz' => new ServiceClosureArgument(new TypedReference('baz_service', 'stdClass')), + ]) + ; + $container->register('bar_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true); + $container->register('baz_service', 'stdClass')->setPublic(false); + $container->compile(); + + $this->assertInstanceOf(ServiceLocator::class, $foo = $container->get('foo_service')); + $this->assertSame($container->get('bar_service'), $foo->get('bar')); + } + + public function testUninitializedReference() + { + $container = include __DIR__.'/Fixtures/containers/container_uninitialized_ref.php'; + $container->compile(); + + $bar = $container->get('bar'); + + $this->assertNull($bar->foo1); + $this->assertNull($bar->foo2); + $this->assertNull($bar->foo3); + $this->assertNull($bar->closures[0]()); + $this->assertNull($bar->closures[1]()); + $this->assertNull($bar->closures[2]()); + $this->assertSame([], iterator_to_array($bar->iter)); + + $container = include __DIR__.'/Fixtures/containers/container_uninitialized_ref.php'; + $container->compile(); + + $container->get('foo1'); + $container->get('baz'); + + $bar = $container->get('bar'); + + $this->assertEquals(new \stdClass(), $bar->foo1); + $this->assertNull($bar->foo2); + $this->assertEquals(new \stdClass(), $bar->foo3); + $this->assertEquals(new \stdClass(), $bar->closures[0]()); + $this->assertNull($bar->closures[1]()); + $this->assertEquals(new \stdClass(), $bar->closures[2]()); + $this->assertEquals(['foo1' => new \stdClass(), 'foo3' => new \stdClass()], iterator_to_array($bar->iter)); + } + + /** + * @dataProvider provideAlmostCircular + */ + public function testAlmostCircular($visibility) + { + $container = include __DIR__.'/Fixtures/containers/container_almost_circular.php'; + + $foo = $container->get('foo'); + $this->assertSame($foo, $foo->bar->foobar->foo); + + $foo2 = $container->get('foo2'); + $this->assertSame($foo2, $foo2->bar->foobar->foo); + + $this->assertSame([], (array) $container->get('foobar4')); + + $foo5 = $container->get('foo5'); + $this->assertSame($foo5, $foo5->bar->foo); + + $manager = $container->get('manager'); + $this->assertEquals(new \stdClass(), $manager); + + $manager = $container->get('manager2'); + $this->assertEquals(new \stdClass(), $manager); + + $foo6 = $container->get('foo6'); + $this->assertEquals((object) ['bar6' => (object) []], $foo6); + + $this->assertInstanceOf(\stdClass::class, $container->get('root')); + + $manager3 = $container->get('manager3'); + $listener3 = $container->get('listener3'); + $this->assertSame($manager3, $listener3->manager, 'Both should identically be the manager3 service'); + + $listener4 = $container->get('listener4'); + $this->assertInstanceOf('stdClass', $listener4); + } + + public function provideAlmostCircular() + { + yield ['public']; + yield ['private']; + } + + public function testRegisterForAutoconfiguration() + { + $container = new ContainerBuilder(); + $childDefA = $container->registerForAutoconfiguration('AInterface'); + $childDefB = $container->registerForAutoconfiguration('BInterface'); + $this->assertSame(['AInterface' => $childDefA, 'BInterface' => $childDefB], $container->getAutoconfiguredInstanceof()); + + // when called multiple times, the same instance is returned + $this->assertSame($childDefA, $container->registerForAutoconfiguration('AInterface')); + } + + /** + * This test checks the trigger of a deprecation note and should not be removed in major releases. + * + * @group legacy + * @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testPrivateServiceTriggersDeprecation() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass') + ->setPublic(false) + ->setDeprecated(true); + $container->register('bar', 'stdClass') + ->setPublic(true) + ->setProperty('foo', new Reference('foo')); + + $container->compile(); + + $container->get('bar'); + } + + /** + * @group legacy + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "FOO" instead of "foo" is deprecated since Symfony 3.4. + */ + public function testParameterWithMixedCase() + { + $container = new ContainerBuilder(new ParameterBag(['foo' => 'bar'])); + $container->register('foo', 'stdClass') + ->setPublic(true) + ->setProperty('foo', '%FOO%'); + + $container->compile(); + + $this->assertSame('bar', $container->get('foo')->foo); + } + + public function testArgumentsHaveHigherPriorityThanBindings() + { + $container = new ContainerBuilder(); + $container->register('class.via.bindings', CaseSensitiveClass::class)->setArguments([ + 'via-bindings', + ]); + $container->register('class.via.argument', CaseSensitiveClass::class)->setArguments([ + 'via-argument', + ]); + $container->register('foo', SimilarArgumentsDummy::class)->setPublic(true)->setBindings([ + CaseSensitiveClass::class => new Reference('class.via.bindings'), + '$token' => '1234', + ])->setArguments([ + '$class1' => new Reference('class.via.argument'), + ]); + + $this->assertSame(['service_container', 'class.via.bindings', 'class.via.argument', 'foo', 'Psr\Container\ContainerInterface', 'Symfony\Component\DependencyInjection\ContainerInterface'], $container->getServiceIds()); + + $container->compile(); + + $this->assertSame('via-argument', $container->get('foo')->class1->identifier); + $this->assertSame('via-bindings', $container->get('foo')->class2->identifier); + } + + public function testUninitializedSyntheticReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true); + $container->register('bar', 'stdClass')->setPublic(true)->setShared(false) + ->setProperty('foo', new Reference('foo', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)); + + $container->compile(); + + $this->assertEquals((object) ['foo' => null], $container->get('bar')); + + $container->set('foo', (object) [123]); + $this->assertEquals((object) ['foo' => (object) [123]], $container->get('bar')); + } + + public function testDecoratedSelfReferenceInvolvingPrivateServices() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass') + ->setPublic(false) + ->setProperty('bar', new Reference('foo')); + $container->register('baz', 'stdClass') + ->setPublic(false) + ->setProperty('inner', new Reference('baz.inner')) + ->setDecoratedService('foo'); + + $container->compile(); + + $this->assertSame(['service_container'], array_keys($container->getDefinitions())); + } + + public function testScalarService() + { + $c = new ContainerBuilder(); + $c->register('foo', 'string') + ->setPublic(true) + ->setFactory([ScalarFactory::class, 'getSomeValue']) + ; + + $c->compile(); + + $this->assertTrue($c->has('foo')); + $this->assertSame('some value', $c->get('foo')); + } +} + +class FooClass +{ +} + +class A +{ +} + +class B +{ + public function __construct(A $a) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ContainerTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ContainerTest.php new file mode 100644 index 00000000..46527e09 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ContainerTest.php @@ -0,0 +1,692 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +class ContainerTest extends TestCase +{ + public function testConstructor() + { + $sc = new Container(); + $this->assertSame($sc, $sc->get('service_container'), '__construct() automatically registers itself as a service'); + + $sc = new Container(new ParameterBag(['foo' => 'bar'])); + $this->assertEquals(['foo' => 'bar'], $sc->getParameterBag()->all(), '__construct() takes an array of parameters as its first argument'); + } + + /** + * @dataProvider dataForTestCamelize + */ + public function testCamelize($id, $expected) + { + $this->assertEquals($expected, Container::camelize($id), sprintf('Container::camelize("%s")', $id)); + } + + public function dataForTestCamelize() + { + return [ + ['foo_bar', 'FooBar'], + ['foo.bar', 'Foo_Bar'], + ['foo.bar_baz', 'Foo_BarBaz'], + ['foo._bar', 'Foo_Bar'], + ['foo_.bar', 'Foo_Bar'], + ['_foo', 'Foo'], + ['.foo', '_Foo'], + ['foo_', 'Foo'], + ['foo.', 'Foo_'], + ['foo\bar', 'Foo_Bar'], + ]; + } + + /** + * @dataProvider dataForTestUnderscore + */ + public function testUnderscore($id, $expected) + { + $this->assertEquals($expected, Container::underscore($id), sprintf('Container::underscore("%s")', $id)); + } + + public function dataForTestUnderscore() + { + return [ + ['FooBar', 'foo_bar'], + ['Foo_Bar', 'foo.bar'], + ['Foo_BarBaz', 'foo.bar_baz'], + ['FooBar_BazQux', 'foo_bar.baz_qux'], + ['_Foo', '.foo'], + ['Foo_', 'foo.'], + ]; + } + + public function testCompile() + { + $sc = new Container(new ParameterBag(['foo' => 'bar'])); + $this->assertFalse($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag'); + $sc->compile(); + $this->assertTrue($sc->getParameterBag()->isResolved(), '->compile() resolves the parameter bag'); + $this->assertInstanceOf('Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag', $sc->getParameterBag(), '->compile() changes the parameter bag to a FrozenParameterBag instance'); + $this->assertEquals(['foo' => 'bar'], $sc->getParameterBag()->all(), '->compile() copies the current parameters to the new parameter bag'); + } + + /** + * @group legacy + * @expectedDeprecation The Symfony\Component\DependencyInjection\Container::isFrozen() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead. + * @expectedDeprecation The Symfony\Component\DependencyInjection\Container::isFrozen() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead. + */ + public function testIsFrozen() + { + $sc = new Container(new ParameterBag(['foo' => 'bar'])); + $this->assertFalse($sc->isFrozen(), '->isFrozen() returns false if the parameters are not frozen'); + $sc->compile(); + $this->assertTrue($sc->isFrozen(), '->isFrozen() returns true if the parameters are frozen'); + } + + public function testIsCompiled() + { + $sc = new Container(new ParameterBag(['foo' => 'bar'])); + $this->assertFalse($sc->isCompiled(), '->isCompiled() returns false if the container is not compiled'); + $sc->compile(); + $this->assertTrue($sc->isCompiled(), '->isCompiled() returns true if the container is compiled'); + } + + public function testIsCompiledWithFrozenParameters() + { + $sc = new Container(new FrozenParameterBag(['foo' => 'bar'])); + $this->assertFalse($sc->isCompiled(), '->isCompiled() returns false if the container is not compiled but the parameter bag is already frozen'); + } + + public function testGetParameterBag() + { + $sc = new Container(); + $this->assertEquals([], $sc->getParameterBag()->all(), '->getParameterBag() returns an empty array if no parameter has been defined'); + } + + public function testGetSetParameter() + { + $sc = new Container(new ParameterBag(['foo' => 'bar'])); + $sc->setParameter('bar', 'foo'); + $this->assertEquals('foo', $sc->getParameter('bar'), '->setParameter() sets the value of a new parameter'); + + $sc->setParameter('foo', 'baz'); + $this->assertEquals('baz', $sc->getParameter('foo'), '->setParameter() overrides previously set parameter'); + + try { + $sc->getParameter('baba'); + $this->fail('->getParameter() thrown an \InvalidArgumentException if the key does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->getParameter() thrown an \InvalidArgumentException if the key does not exist'); + $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->getParameter() thrown an \InvalidArgumentException if the key does not exist'); + } + } + + /** + * @group legacy + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.4. + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "FOO" instead of "foo" is deprecated since Symfony 3.4. + */ + public function testGetSetParameterWithMixedCase() + { + $sc = new Container(new ParameterBag(['foo' => 'bar'])); + + $sc->setParameter('Foo', 'baz1'); + $this->assertEquals('baz1', $sc->getParameter('foo'), '->setParameter() converts the key to lowercase'); + $this->assertEquals('baz1', $sc->getParameter('FOO'), '->getParameter() converts the key to lowercase'); + } + + public function testGetServiceIds() + { + $sc = new Container(); + $sc->set('foo', $obj = new \stdClass()); + $sc->set('bar', $obj = new \stdClass()); + $this->assertEquals(['service_container', 'foo', 'bar'], $sc->getServiceIds(), '->getServiceIds() returns all defined service ids'); + + $sc = new ProjectServiceContainer(); + $sc->set('foo', $obj = new \stdClass()); + $this->assertEquals(['service_container', 'internal', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'internal_dependency', 'alias', 'foo'], $sc->getServiceIds(), '->getServiceIds() returns defined service ids by factory methods in the method map, followed by service ids defined by set()'); + } + + /** + * @group legacy + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + */ + public function testGetLegacyServiceIds() + { + $sc = new LegacyProjectServiceContainer(); + $sc->set('foo', $obj = new \stdClass()); + + $this->assertEquals(['internal', 'bar', 'foo_bar', 'foo.baz', 'circular', 'throw_exception', 'throws_exception_on_service_configuration', 'service_container', 'alias', 'foo'], $sc->getServiceIds(), '->getServiceIds() returns defined service ids by getXXXService() methods, followed by service ids defined by set()'); + } + + public function testSet() + { + $sc = new Container(); + $sc->set('._. \\o/', $foo = new \stdClass()); + $this->assertSame($foo, $sc->get('._. \\o/'), '->set() sets a service'); + } + + public function testSetWithNullResetTheService() + { + $sc = new Container(); + $sc->set('foo', null); + $this->assertFalse($sc->has('foo'), '->set() with null service resets the service'); + } + + public function testSetReplacesAlias() + { + $c = new ProjectServiceContainer(); + + $c->set('alias', $foo = new \stdClass()); + $this->assertSame($foo, $c->get('alias'), '->set() replaces an existing alias'); + } + + /** + * @group legacy + * @expectedDeprecation The "bar" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0. + */ + public function testSetWithNullOnInitializedPredefinedService() + { + $sc = new Container(); + $sc->set('foo', new \stdClass()); + $sc->set('foo', null); + $this->assertFalse($sc->has('foo'), '->set() with null service resets the service'); + + $sc = new ProjectServiceContainer(); + $sc->get('bar'); + $sc->set('bar', null); + $this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service'); + } + + public function testSetWithNullOnUninitializedPredefinedService() + { + $sc = new Container(); + $sc->set('foo', new \stdClass()); + $sc->get('foo', null); + $sc->set('foo', null); + $this->assertFalse($sc->has('foo'), '->set() with null service resets the service'); + + $sc = new ProjectServiceContainer(); + $sc->set('bar', null); + $this->assertTrue($sc->has('bar'), '->set() with null service resets the pre-defined service'); + } + + public function testGet() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', $foo = new \stdClass()); + $this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id'); + $this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id'); + $this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined'); + $this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined'); + + try { + $sc->get(''); + $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty'); + } + $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty'); + } + + /** + * @group legacy + * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.3. + */ + public function testGetInsensitivity() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', $foo = new \stdClass()); + $this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase'); + } + + /** + * @group legacy + * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "foo" instead of "Foo" is deprecated since Symfony 3.3. + */ + public function testNormalizeIdKeepsCase() + { + $sc = new ProjectServiceContainer(); + $sc->normalizeId('Foo', true); + $this->assertSame('Foo', $sc->normalizeId('foo')); + } + + /** + * @group legacy + * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.3. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + */ + public function testLegacyGet() + { + $sc = new LegacyProjectServiceContainer(); + $sc->set('foo', $foo = new \stdClass()); + + $this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id'); + $this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase'); + $this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id'); + $this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined'); + $this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined'); + $this->assertSame($sc->__foo_baz, $sc->get('foo\\baz'), '->get() returns the service if a get*Method() is defined'); + + $sc->set('bar', $bar = new \stdClass()); + $this->assertSame($bar, $sc->get('bar'), '->get() prefers to return a service defined with set() than one defined with a getXXXMethod()'); + + try { + $sc->get(''); + $this->fail('->get() throws a \InvalidArgumentException exception if the service is empty'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws a ServiceNotFoundException exception if the service is empty'); + } + $this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty'); + } + + public function testGetThrowServiceNotFoundException() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', $foo = new \stdClass()); + $sc->set('baz', $foo = new \stdClass()); + + try { + $sc->get('foo1'); + $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist'); + $this->assertEquals('You have requested a non-existent service "foo1". Did you mean this: "foo"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices'); + } + + try { + $sc->get('bag'); + $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException if the key does not exist'); + $this->assertEquals('You have requested a non-existent service "bag". Did you mean one of these: "bar", "baz"?', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException with some advices'); + } + } + + public function testGetCircularReference() + { + $sc = new ProjectServiceContainer(); + try { + $sc->get('circular'); + $this->fail('->get() throws a ServiceCircularReferenceException if it contains circular reference'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException', $e, '->get() throws a ServiceCircularReferenceException if it contains circular reference'); + $this->assertStringStartsWith('Circular reference detected for service "circular"', $e->getMessage(), '->get() throws a \LogicException if it contains circular reference'); + } + } + + public function testGetSyntheticServiceThrows() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException'); + $this->expectExceptionMessage('The "request" service is synthetic, it needs to be set at boot time before it can be used.'); + require_once __DIR__.'/Fixtures/php/services9_compiled.php'; + + $container = new \ProjectServiceContainer(); + $container->get('request'); + } + + public function testGetRemovedServiceThrows() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException'); + $this->expectExceptionMessage('The "inlined" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.'); + require_once __DIR__.'/Fixtures/php/services9_compiled.php'; + + $container = new \ProjectServiceContainer(); + $container->get('inlined'); + } + + public function testHas() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', new \stdClass()); + $this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist'); + $this->assertTrue($sc->has('foo'), '->has() returns true if the service exists'); + $this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined'); + } + + /** + * @group legacy + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + * @expectedDeprecation Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map. + */ + public function testLegacyHas() + { + $sc = new LegacyProjectServiceContainer(); + $sc->set('foo', new \stdClass()); + + $this->assertFalse($sc->has('foo1'), '->has() returns false if the service does not exist'); + $this->assertTrue($sc->has('foo'), '->has() returns true if the service exists'); + $this->assertTrue($sc->has('bar'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo_bar'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo.baz'), '->has() returns true if a get*Method() is defined'); + $this->assertTrue($sc->has('foo\\baz'), '->has() returns true if a get*Method() is defined'); + } + + public function testScalarService() + { + $c = new Container(); + + $c->set('foo', 'some value'); + + $this->assertTrue($c->has('foo')); + $this->assertSame('some value', $c->get('foo')); + } + + public function testInitialized() + { + $sc = new ProjectServiceContainer(); + $sc->set('foo', new \stdClass()); + $this->assertTrue($sc->initialized('foo'), '->initialized() returns true if service is loaded'); + $this->assertFalse($sc->initialized('foo1'), '->initialized() returns false if service is not loaded'); + $this->assertFalse($sc->initialized('bar'), '->initialized() returns false if a service is defined, but not currently loaded'); + $this->assertFalse($sc->initialized('alias'), '->initialized() returns false if an aliased service is not initialized'); + + $sc->get('bar'); + $this->assertTrue($sc->initialized('alias'), '->initialized() returns true for alias if aliased service is initialized'); + } + + /** + * @group legacy + * @expectedDeprecation Checking for the initialization of the "internal" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. + */ + public function testInitializedWithPrivateService() + { + $sc = new ProjectServiceContainer(); + $sc->get('internal_dependency'); + $this->assertTrue($sc->initialized('internal')); + } + + public function testReset() + { + $c = new Container(); + $c->set('bar', new \stdClass()); + + $c->reset(); + + $this->assertNull($c->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE)); + } + + public function testGetThrowsException() + { + $this->expectException('Exception'); + $this->expectExceptionMessage('Something went terribly wrong!'); + $c = new ProjectServiceContainer(); + + try { + $c->get('throw_exception'); + } catch (\Exception $e) { + // Do nothing. + } + + // Retry, to make sure that get*Service() will be called. + $c->get('throw_exception'); + } + + public function testGetThrowsExceptionOnServiceConfiguration() + { + $c = new ProjectServiceContainer(); + + try { + $c->get('throws_exception_on_service_configuration'); + } catch (\Exception $e) { + // Do nothing. + } + + $this->assertFalse($c->initialized('throws_exception_on_service_configuration')); + + // Retry, to make sure that get*Service() will be called. + try { + $c->get('throws_exception_on_service_configuration'); + } catch (\Exception $e) { + // Do nothing. + } + $this->assertFalse($c->initialized('throws_exception_on_service_configuration')); + } + + protected function getField($obj, $field) + { + $reflection = new \ReflectionProperty($obj, $field); + $reflection->setAccessible(true); + + return $reflection->getValue($obj); + } + + public function testAlias() + { + $c = new ProjectServiceContainer(); + + $this->assertTrue($c->has('alias')); + $this->assertSame($c->get('alias'), $c->get('bar')); + } + + public function testThatCloningIsNotSupported() + { + $class = new \ReflectionClass('Symfony\Component\DependencyInjection\Container'); + $clone = $class->getMethod('__clone'); + $this->assertFalse($class->isCloneable()); + $this->assertTrue($clone->isPrivate()); + } + + /** + * @group legacy + * @expectedDeprecation The "internal" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0. + */ + public function testUnsetInternalPrivateServiceIsDeprecated() + { + $c = new ProjectServiceContainer(); + $c->set('internal', null); + } + + /** + * @group legacy + * @expectedDeprecation The "internal" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0. + */ + public function testChangeInternalPrivateServiceIsDeprecated() + { + $c = new ProjectServiceContainer(); + $c->set('internal', $internal = new \stdClass()); + $this->assertSame($c->get('internal'), $internal); + } + + /** + * @group legacy + * @expectedDeprecation The "internal" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0. + */ + public function testCheckExistenceOfAnInternalPrivateServiceIsDeprecated() + { + $c = new ProjectServiceContainer(); + $c->get('internal_dependency'); + $this->assertTrue($c->has('internal')); + } + + /** + * @group legacy + * @expectedDeprecation The "internal" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + */ + public function testRequestAnInternalSharedPrivateServiceIsDeprecated() + { + $c = new ProjectServiceContainer(); + $c->get('internal_dependency'); + $c->get('internal'); + } + + /** + * @group legacy + * @expectedDeprecation The "bar" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0. + */ + public function testReplacingAPreDefinedServiceIsDeprecated() + { + $c = new ProjectServiceContainer(); + $c->set('bar', new \stdClass()); + $c->set('bar', $bar = new \stdClass()); + + $this->assertSame($bar, $c->get('bar'), '->set() replaces a pre-defined service'); + } + + /** + * @group legacy + * @expectedDeprecation The "synthetic" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0. + */ + public function testSetWithPrivateSyntheticServiceThrowsDeprecation() + { + $c = new ProjectServiceContainer(); + $c->set('synthetic', new \stdClass()); + } +} + +class ProjectServiceContainer extends Container +{ + public $__bar; + public $__foo_bar; + public $__foo_baz; + public $__internal; + protected $privates; + protected $methodMap = [ + 'internal' => 'getInternalService', + 'bar' => 'getBarService', + 'foo_bar' => 'getFooBarService', + 'foo.baz' => 'getFoo_BazService', + 'circular' => 'getCircularService', + 'throw_exception' => 'getThrowExceptionService', + 'throws_exception_on_service_configuration' => 'getThrowsExceptionOnServiceConfigurationService', + 'internal_dependency' => 'getInternalDependencyService', + ]; + + public function __construct() + { + parent::__construct(); + + $this->__bar = new \stdClass(); + $this->__foo_bar = new \stdClass(); + $this->__foo_baz = new \stdClass(); + $this->__internal = new \stdClass(); + $this->privates = [ + 'internal' => true, + 'synthetic' => true, + ]; + $this->aliases = ['alias' => 'bar']; + $this->syntheticIds['synthetic'] = true; + } + + protected function getInternalService() + { + return $this->services['internal'] = $this->__internal; + } + + protected function getBarService() + { + return $this->services['bar'] = $this->__bar; + } + + protected function getFooBarService() + { + return $this->__foo_bar; + } + + protected function getFoo_BazService() + { + return $this->__foo_baz; + } + + protected function getCircularService() + { + return $this->get('circular'); + } + + protected function getThrowExceptionService() + { + throw new \Exception('Something went terribly wrong!'); + } + + protected function getThrowsExceptionOnServiceConfigurationService() + { + $this->services['throws_exception_on_service_configuration'] = $instance = new \stdClass(); + + throw new \Exception('Something was terribly wrong while trying to configure the service!'); + } + + protected function getInternalDependencyService() + { + $this->services['internal_dependency'] = $instance = new \stdClass(); + + $instance->internal = isset($this->services['internal']) ? $this->services['internal'] : $this->getInternalService(); + + return $instance; + } +} + +class LegacyProjectServiceContainer extends Container +{ + public $__bar; + public $__foo_bar; + public $__foo_baz; + public $__internal; + + public function __construct() + { + parent::__construct(); + + $this->__bar = new \stdClass(); + $this->__foo_bar = new \stdClass(); + $this->__foo_baz = new \stdClass(); + $this->__internal = new \stdClass(); + $this->privates = ['internal' => true]; + $this->aliases = ['alias' => 'bar']; + } + + protected function getInternalService() + { + return $this->__internal; + } + + protected function getBarService() + { + return $this->__bar; + } + + protected function getFooBarService() + { + return $this->__foo_bar; + } + + protected function getFoo_BazService() + { + return $this->__foo_baz; + } + + protected function getCircularService() + { + return $this->get('circular'); + } + + protected function getThrowExceptionService() + { + throw new \Exception('Something went terribly wrong!'); + } + + protected function getThrowsExceptionOnServiceConfigurationService() + { + $this->services['throws_exception_on_service_configuration'] = $instance = new \stdClass(); + + throw new \Exception('Something was terribly wrong while trying to configure the service!'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/CrossCheckTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/CrossCheckTest.php new file mode 100644 index 00000000..fe132af4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/CrossCheckTest.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +class CrossCheckTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/Fixtures/'; + + require_once self::$fixturesPath.'/includes/classes.php'; + require_once self::$fixturesPath.'/includes/foo.php'; + } + + /** + * @dataProvider crossCheckLoadersDumpers + */ + public function testCrossCheck($fixture, $type) + { + $loaderClass = 'Symfony\\Component\\DependencyInjection\\Loader\\'.ucfirst($type).'FileLoader'; + $dumperClass = 'Symfony\\Component\\DependencyInjection\\Dumper\\'.ucfirst($type).'Dumper'; + + $tmp = tempnam(sys_get_temp_dir(), 'sf'); + + copy(self::$fixturesPath.'/'.$type.'/'.$fixture, $tmp); + + $container1 = new ContainerBuilder(); + $loader1 = new $loaderClass($container1, new FileLocator()); + $loader1->load($tmp); + + $dumper = new $dumperClass($container1); + file_put_contents($tmp, $dumper->dump()); + + $container2 = new ContainerBuilder(); + $loader2 = new $loaderClass($container2, new FileLocator()); + $loader2->load($tmp); + + unlink($tmp); + + $this->assertEquals($container2->getAliases(), $container1->getAliases(), 'loading a dump from a previously loaded container returns the same container'); + $this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container'); + $this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers'); + + $r = new \ReflectionProperty(ContainerBuilder::class, 'normalizedIds'); + $r->setAccessible(true); + $r->setValue($container2, []); + $r->setValue($container1, []); + + $this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container'); + + $services1 = []; + foreach ($container1 as $id => $service) { + $services1[$id] = serialize($service); + } + $services2 = []; + foreach ($container2 as $id => $service) { + $services2[$id] = serialize($service); + } + + unset($services1['service_container'], $services2['service_container']); + + $this->assertEquals($services2, $services1, 'Iterator on the containers returns the same services'); + } + + public function crossCheckLoadersDumpers() + { + return [ + ['services1.xml', 'xml'], + ['services2.xml', 'xml'], + ['services6.xml', 'xml'], + ['services8.xml', 'xml'], + ['services9.xml', 'xml'], + ['services1.yml', 'yaml'], + ['services2.yml', 'yaml'], + ['services6.yml', 'yaml'], + ['services8.yml', 'yaml'], + ['services9.yml', 'yaml'], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/DefinitionDecoratorTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/DefinitionDecoratorTest.php new file mode 100644 index 00000000..8d382f81 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/DefinitionDecoratorTest.php @@ -0,0 +1,128 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\DefinitionDecorator; + +/** + * @group legacy + */ +class DefinitionDecoratorTest extends TestCase +{ + public function testConstructor() + { + $def = new DefinitionDecorator('foo'); + + $this->assertEquals('foo', $def->getParent()); + $this->assertEquals([], $def->getChanges()); + } + + /** + * @dataProvider getPropertyTests + */ + public function testSetProperty($property, $changeKey) + { + $def = new DefinitionDecorator('foo'); + + $getter = 'get'.ucfirst($property); + $setter = 'set'.ucfirst($property); + + $this->assertNull($def->$getter()); + $this->assertSame($def, $def->$setter('foo')); + $this->assertEquals('foo', $def->$getter()); + $this->assertEquals([$changeKey => true], $def->getChanges()); + } + + public function getPropertyTests() + { + return [ + ['class', 'class'], + ['factory', 'factory'], + ['configurator', 'configurator'], + ['file', 'file'], + ]; + } + + public function testSetPublic() + { + $def = new DefinitionDecorator('foo'); + + $this->assertTrue($def->isPublic()); + $this->assertSame($def, $def->setPublic(false)); + $this->assertFalse($def->isPublic()); + $this->assertEquals(['public' => true], $def->getChanges()); + } + + public function testSetLazy() + { + $def = new DefinitionDecorator('foo'); + + $this->assertFalse($def->isLazy()); + $this->assertSame($def, $def->setLazy(false)); + $this->assertFalse($def->isLazy()); + $this->assertEquals(['lazy' => true], $def->getChanges()); + } + + public function testSetAutowired() + { + $def = new DefinitionDecorator('foo'); + + $this->assertFalse($def->isAutowired()); + $this->assertSame($def, $def->setAutowired(true)); + $this->assertTrue($def->isAutowired()); + $this->assertSame(['autowired' => true], $def->getChanges()); + } + + public function testSetArgument() + { + $def = new DefinitionDecorator('foo'); + + $this->assertEquals([], $def->getArguments()); + $this->assertSame($def, $def->replaceArgument(0, 'foo')); + $this->assertEquals(['index_0' => 'foo'], $def->getArguments()); + } + + public function testReplaceArgumentShouldRequireIntegerIndex() + { + $this->expectException('InvalidArgumentException'); + $def = new DefinitionDecorator('foo'); + + $def->replaceArgument('0', 'foo'); + } + + public function testReplaceArgument() + { + $def = new DefinitionDecorator('foo'); + + $def->setArguments([0 => 'foo', 1 => 'bar']); + $this->assertEquals('foo', $def->getArgument(0)); + $this->assertEquals('bar', $def->getArgument(1)); + + $this->assertSame($def, $def->replaceArgument(1, 'baz')); + $this->assertEquals('foo', $def->getArgument(0)); + $this->assertEquals('baz', $def->getArgument(1)); + + $this->assertEquals([0 => 'foo', 1 => 'bar', 'index_1' => 'baz'], $def->getArguments()); + } + + public function testGetArgumentShouldCheckBounds() + { + $this->expectException('OutOfBoundsException'); + $def = new DefinitionDecorator('foo'); + + $def->setArguments([0 => 'foo']); + $def->replaceArgument(0, 'foo'); + + $def->getArgument(1); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/DefinitionTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/DefinitionTest.php new file mode 100644 index 00000000..63ca748e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/DefinitionTest.php @@ -0,0 +1,387 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Definition; + +class DefinitionTest extends TestCase +{ + public function testConstructor() + { + $def = new Definition('stdClass'); + $this->assertEquals('stdClass', $def->getClass(), '__construct() takes the class name as its first argument'); + $this->assertSame(['class' => true], $def->getChanges()); + + $def = new Definition('stdClass', ['foo']); + $this->assertEquals(['foo'], $def->getArguments(), '__construct() takes an optional array of arguments as its second argument'); + } + + public function testSetGetFactory() + { + $def = new Definition(); + + $this->assertSame($def, $def->setFactory('foo'), '->setFactory() implements a fluent interface'); + $this->assertEquals('foo', $def->getFactory(), '->getFactory() returns the factory'); + + $def->setFactory('Foo::bar'); + $this->assertEquals(['Foo', 'bar'], $def->getFactory(), '->setFactory() converts string static method call to the array'); + $this->assertSame(['factory' => true], $def->getChanges()); + } + + public function testSetGetClass() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setClass('foo'), '->setClass() implements a fluent interface'); + $this->assertEquals('foo', $def->getClass(), '->getClass() returns the class name'); + } + + public function testSetGetDecoratedService() + { + $def = new Definition('stdClass'); + $this->assertNull($def->getDecoratedService()); + $def->setDecoratedService('foo', 'foo.renamed', 5); + $this->assertEquals(['foo', 'foo.renamed', 5], $def->getDecoratedService()); + $def->setDecoratedService(null); + $this->assertNull($def->getDecoratedService()); + + $def = new Definition('stdClass'); + $this->assertNull($def->getDecoratedService()); + $def->setDecoratedService('foo', 'foo.renamed'); + $this->assertEquals(['foo', 'foo.renamed', 0], $def->getDecoratedService()); + $def->setDecoratedService(null); + $this->assertNull($def->getDecoratedService()); + + $def = new Definition('stdClass'); + $def->setDecoratedService('foo'); + $this->assertEquals(['foo', null, 0], $def->getDecoratedService()); + $def->setDecoratedService(null); + $this->assertNull($def->getDecoratedService()); + + $def = new Definition('stdClass'); + + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The decorated service inner name for "foo" must be different than the service name itself.'); + + $def->setDecoratedService('foo', 'foo'); + } + + public function testArguments() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setArguments(['foo']), '->setArguments() implements a fluent interface'); + $this->assertEquals(['foo'], $def->getArguments(), '->getArguments() returns the arguments'); + $this->assertSame($def, $def->addArgument('bar'), '->addArgument() implements a fluent interface'); + $this->assertEquals(['foo', 'bar'], $def->getArguments(), '->addArgument() adds an argument'); + } + + public function testMethodCalls() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setMethodCalls([['foo', ['foo']]]), '->setMethodCalls() implements a fluent interface'); + $this->assertEquals([['foo', ['foo']]], $def->getMethodCalls(), '->getMethodCalls() returns the methods to call'); + $this->assertSame($def, $def->addMethodCall('bar', ['bar']), '->addMethodCall() implements a fluent interface'); + $this->assertEquals([['foo', ['foo']], ['bar', ['bar']]], $def->getMethodCalls(), '->addMethodCall() adds a method to call'); + $this->assertTrue($def->hasMethodCall('bar'), '->hasMethodCall() returns true if first argument is a method to call registered'); + $this->assertFalse($def->hasMethodCall('no_registered'), '->hasMethodCall() returns false if first argument is not a method to call registered'); + $this->assertSame($def, $def->removeMethodCall('bar'), '->removeMethodCall() implements a fluent interface'); + $this->assertEquals([['foo', ['foo']]], $def->getMethodCalls(), '->removeMethodCall() removes a method to call'); + } + + public function testExceptionOnEmptyMethodCall() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Method name cannot be empty.'); + $def = new Definition('stdClass'); + $def->addMethodCall(''); + } + + public function testSetGetFile() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setFile('foo'), '->setFile() implements a fluent interface'); + $this->assertEquals('foo', $def->getFile(), '->getFile() returns the file to include'); + } + + public function testSetIsShared() + { + $def = new Definition('stdClass'); + $this->assertTrue($def->isShared(), '->isShared() returns true by default'); + $this->assertSame($def, $def->setShared(false), '->setShared() implements a fluent interface'); + $this->assertFalse($def->isShared(), '->isShared() returns false if the instance must not be shared'); + } + + public function testSetIsPublic() + { + $def = new Definition('stdClass'); + $this->assertTrue($def->isPublic(), '->isPublic() returns true by default'); + $this->assertSame($def, $def->setPublic(false), '->setPublic() implements a fluent interface'); + $this->assertFalse($def->isPublic(), '->isPublic() returns false if the instance must not be public.'); + } + + public function testSetIsSynthetic() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isSynthetic(), '->isSynthetic() returns false by default'); + $this->assertSame($def, $def->setSynthetic(true), '->setSynthetic() implements a fluent interface'); + $this->assertTrue($def->isSynthetic(), '->isSynthetic() returns true if the service is synthetic.'); + } + + public function testSetIsLazy() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isLazy(), '->isLazy() returns false by default'); + $this->assertSame($def, $def->setLazy(true), '->setLazy() implements a fluent interface'); + $this->assertTrue($def->isLazy(), '->isLazy() returns true if the service is lazy.'); + } + + public function testSetIsAbstract() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isAbstract(), '->isAbstract() returns false by default'); + $this->assertSame($def, $def->setAbstract(true), '->setAbstract() implements a fluent interface'); + $this->assertTrue($def->isAbstract(), '->isAbstract() returns true if the instance must not be public.'); + } + + public function testSetIsDeprecated() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isDeprecated(), '->isDeprecated() returns false by default'); + $this->assertSame($def, $def->setDeprecated(true), '->setDeprecated() implements a fluent interface'); + $this->assertTrue($def->isDeprecated(), '->isDeprecated() returns true if the instance should not be used anymore.'); + $this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template'); + } + + /** + * @dataProvider invalidDeprecationMessageProvider + */ + public function testSetDeprecatedWithInvalidDeprecationTemplate($message) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $def = new Definition('stdClass'); + $def->setDeprecated(false, $message); + } + + public function invalidDeprecationMessageProvider() + { + return [ + "With \rs" => ["invalid \r message %service_id%"], + "With \ns" => ["invalid \n message %service_id%"], + 'With */s' => ['invalid */ message %service_id%'], + 'message not containing require %service_id% variable' => ['this is deprecated'], + ]; + } + + public function testSetGetConfigurator() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->setConfigurator('foo'), '->setConfigurator() implements a fluent interface'); + $this->assertEquals('foo', $def->getConfigurator(), '->getConfigurator() returns the configurator'); + } + + public function testClearTags() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface'); + $def->addTag('foo', ['foo' => 'bar']); + $def->clearTags(); + $this->assertEquals([], $def->getTags(), '->clearTags() removes all current tags'); + } + + public function testClearTag() + { + $def = new Definition('stdClass'); + $this->assertSame($def, $def->clearTags(), '->clearTags() implements a fluent interface'); + $def->addTag('1foo1', ['foo1' => 'bar1']); + $def->addTag('2foo2', ['foo2' => 'bar2']); + $def->addTag('3foo3', ['foo3' => 'bar3']); + $def->clearTag('2foo2'); + $this->assertTrue($def->hasTag('1foo1')); + $this->assertFalse($def->hasTag('2foo2')); + $this->assertTrue($def->hasTag('3foo3')); + $def->clearTag('1foo1'); + $this->assertFalse($def->hasTag('1foo1')); + $this->assertTrue($def->hasTag('3foo3')); + } + + public function testTags() + { + $def = new Definition('stdClass'); + $this->assertEquals([], $def->getTag('foo'), '->getTag() returns an empty array if the tag is not defined'); + $this->assertFalse($def->hasTag('foo')); + $this->assertSame($def, $def->addTag('foo'), '->addTag() implements a fluent interface'); + $this->assertTrue($def->hasTag('foo')); + $this->assertEquals([[]], $def->getTag('foo'), '->getTag() returns attributes for a tag name'); + $def->addTag('foo', ['foo' => 'bar']); + $this->assertEquals([[], ['foo' => 'bar']], $def->getTag('foo'), '->addTag() can adds the same tag several times'); + $def->addTag('bar', ['bar' => 'bar']); + $this->assertEquals([ + 'foo' => [[], ['foo' => 'bar']], + 'bar' => [['bar' => 'bar']], + ], $def->getTags(), '->getTags() returns all tags'); + } + + public function testSetArgument() + { + $def = new Definition('stdClass'); + + $def->addArgument('foo'); + $this->assertSame(['foo'], $def->getArguments()); + + $this->assertSame($def, $def->replaceArgument(0, 'moo')); + $this->assertSame(['moo'], $def->getArguments()); + + $def->addArgument('moo'); + $def + ->replaceArgument(0, 'foo') + ->replaceArgument(1, 'bar') + ; + $this->assertSame(['foo', 'bar'], $def->getArguments()); + } + + public function testGetArgumentShouldCheckBounds() + { + $this->expectException('OutOfBoundsException'); + $def = new Definition('stdClass'); + + $def->addArgument('foo'); + $def->getArgument(1); + } + + public function testReplaceArgumentShouldCheckBounds() + { + $this->expectException('OutOfBoundsException'); + $this->expectExceptionMessage('The index "1" is not in the range [0, 0].'); + $def = new Definition('stdClass'); + + $def->addArgument('foo'); + $def->replaceArgument(1, 'bar'); + } + + public function testReplaceArgumentWithoutExistingArgumentsShouldCheckBounds() + { + $this->expectException('OutOfBoundsException'); + $this->expectExceptionMessage('Cannot replace arguments if none have been configured yet.'); + $def = new Definition('stdClass'); + $def->replaceArgument(0, 'bar'); + } + + public function testSetGetProperties() + { + $def = new Definition('stdClass'); + + $this->assertEquals([], $def->getProperties()); + $this->assertSame($def, $def->setProperties(['foo' => 'bar'])); + $this->assertEquals(['foo' => 'bar'], $def->getProperties()); + } + + public function testSetProperty() + { + $def = new Definition('stdClass'); + + $this->assertEquals([], $def->getProperties()); + $this->assertSame($def, $def->setProperty('foo', 'bar')); + $this->assertEquals(['foo' => 'bar'], $def->getProperties()); + } + + public function testAutowired() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isAutowired()); + + $def->setAutowired(true); + $this->assertTrue($def->isAutowired()); + + $def->setAutowired(false); + $this->assertFalse($def->isAutowired()); + } + + public function testChangesNoChanges() + { + $def = new Definition(); + + $this->assertSame([], $def->getChanges()); + } + + public function testGetChangesWithChanges() + { + $def = new Definition('stdClass', ['fooarg']); + + $def->setAbstract(true); + $def->setAutowired(true); + $def->setConfigurator('configuration_func'); + $def->setDecoratedService(null); + $def->setDeprecated(true); + $def->setFactory('factory_func'); + $def->setFile('foo.php'); + $def->setLazy(true); + $def->setPublic(true); + $def->setShared(true); + $def->setSynthetic(true); + // changes aren't tracked for these, class or arguments + $def->setInstanceofConditionals([]); + $def->addTag('foo_tag'); + $def->addMethodCall('methodCall'); + $def->setProperty('fooprop', true); + $def->setAutoconfigured(true); + + $this->assertSame([ + 'class' => true, + 'autowired' => true, + 'configurator' => true, + 'decorated_service' => true, + 'deprecated' => true, + 'factory' => true, + 'file' => true, + 'lazy' => true, + 'public' => true, + 'shared' => true, + 'autoconfigured' => true, + ], $def->getChanges()); + + $def->setChanges([]); + $this->assertSame([], $def->getChanges()); + } + + /** + * @group legacy + */ + public function testTypes() + { + $def = new Definition('stdClass'); + + $this->assertEquals([], $def->getAutowiringTypes()); + $this->assertSame($def, $def->setAutowiringTypes(['Foo'])); + $this->assertEquals(['Foo'], $def->getAutowiringTypes()); + $this->assertSame($def, $def->addAutowiringType('Bar')); + $this->assertTrue($def->hasAutowiringType('Bar')); + $this->assertSame($def, $def->removeAutowiringType('Foo')); + $this->assertEquals(['Bar'], $def->getAutowiringTypes()); + } + + public function testShouldAutoconfigure() + { + $def = new Definition('stdClass'); + $this->assertFalse($def->isAutoconfigured()); + $def->setAutoconfigured(true); + $this->assertTrue($def->isAutoconfigured()); + } + + public function testAddError() + { + $def = new Definition('stdClass'); + $this->assertEmpty($def->getErrors()); + $def->addError('First error'); + $def->addError('Second error'); + $this->assertSame(['First error', 'Second error'], $def->getErrors()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/GraphvizDumperTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/GraphvizDumperTest.php new file mode 100644 index 00000000..ea11c7c5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/GraphvizDumperTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Dumper\GraphvizDumper; +use Symfony\Component\DependencyInjection\Reference; + +class GraphvizDumperTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/../Fixtures/'; + } + + public function testDump() + { + $dumper = new GraphvizDumper($container = new ContainerBuilder()); + + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services1.dot', $dumper->dump(), '->dump() dumps an empty container as an empty dot file'); + + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new GraphvizDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services9.dot', $dumper->dump(), '->dump() dumps services'); + + $container = include self::$fixturesPath.'/containers/container10.php'; + $dumper = new GraphvizDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services10.dot', $dumper->dump(), '->dump() dumps services'); + + $container = include self::$fixturesPath.'/containers/container10.php'; + $dumper = new GraphvizDumper($container); + $this->assertEquals($dumper->dump([ + 'graph' => ['ratio' => 'normal'], + 'node' => ['fontsize' => 13, 'fontname' => 'Verdana', 'shape' => 'square'], + 'edge' => ['fontsize' => 12, 'fontname' => 'Verdana', 'color' => 'white', 'arrowhead' => 'closed', 'arrowsize' => 1], + 'node.instance' => ['fillcolor' => 'green', 'style' => 'empty'], + 'node.definition' => ['fillcolor' => 'grey'], + 'node.missing' => ['fillcolor' => 'red', 'style' => 'empty'], + ]), file_get_contents(self::$fixturesPath.'/graphviz/services10-1.dot'), '->dump() dumps services'); + } + + public function testDumpWithFrozenContainer() + { + $container = include self::$fixturesPath.'/containers/container13.php'; + $dumper = new GraphvizDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services13.dot', $dumper->dump(), '->dump() dumps services'); + } + + public function testDumpWithFrozenCustomClassContainer() + { + $container = include self::$fixturesPath.'/containers/container14.php'; + $dumper = new GraphvizDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services14.dot', $dumper->dump(), '->dump() dumps services'); + } + + public function testDumpWithUnresolvedParameter() + { + $container = include self::$fixturesPath.'/containers/container17.php'; + $dumper = new GraphvizDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services17.dot', $dumper->dump(), '->dump() dumps services'); + } + + public function testDumpWithInlineDefinition() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addArgument( + (new Definition('stdClass'))->addArgument(new Reference('bar')) + ); + $container->register('bar', 'stdClass'); + $dumper = new GraphvizDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/graphviz/services_inline.dot', $dumper->dump(), '->dump() dumps nested references'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/PhpDumperTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/PhpDumperTest.php new file mode 100644 index 00000000..946d09c7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/PhpDumperTest.php @@ -0,0 +1,1184 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; +use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument; +use Symfony\Component\DependencyInjection\ChildDefinition; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\EnvVarProcessorInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Parameter; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition; +use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory; +use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator; +use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber; +use Symfony\Component\DependencyInjection\TypedReference; +use Symfony\Component\DependencyInjection\Variable; +use Symfony\Component\ExpressionLanguage\Expression; + +require_once __DIR__.'/../Fixtures/includes/classes.php'; + +class PhpDumperTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + public function testDump() + { + $container = new ContainerBuilder(); + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class'); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services1-1.php', $dumper->dump(['class' => 'Container', 'base_class' => 'AbstractContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Dump']), '->dump() takes a class and a base_class options'); + } + + public function testDumpOptimizationString() + { + $definition = new Definition(); + $definition->setClass('stdClass'); + $definition->addArgument([ + 'only dot' => '.', + 'concatenation as value' => '.\'\'.', + 'concatenation from the start value' => '\'\'.', + '.' => 'dot as a key', + '.\'\'.' => 'concatenation as a key', + '\'\'.' => 'concatenation from the start key', + 'optimize concatenation' => 'string1%some_string%string2', + 'optimize concatenation with empty string' => 'string1%empty_value%string2', + 'optimize concatenation from the start' => '%empty_value%start', + 'optimize concatenation at the end' => 'end%empty_value%', + 'new line' => "string with \nnew line", + ]); + $definition->setPublic(true); + + $container = new ContainerBuilder(); + $container->setResourceTracking(false); + $container->setDefinition('test', $definition); + $container->setParameter('empty_value', ''); + $container->setParameter('some_string', '-'); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services10.php', $dumper->dump(), '->dump() dumps an empty container as an empty PHP class'); + } + + public function testDumpRelativeDir() + { + $definition = new Definition(); + $definition->setClass('stdClass'); + $definition->addArgument('%foo%'); + $definition->addArgument(['%foo%' => '%buz%/']); + $definition->setPublic(true); + + $container = new ContainerBuilder(); + $container->setDefinition('test', $definition); + $container->setParameter('foo', 'file://'.\dirname(__DIR__)); + $container->setParameter('bar', __DIR__); + $container->setParameter('baz', '%bar%/PhpDumperTest.php'); + $container->setParameter('buz', \dirname(\dirname(__DIR__))); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services12.php', $dumper->dump(['file' => __FILE__]), '->dump() dumps __DIR__ relative strings'); + } + + public function testDumpCustomContainerClassWithoutConstructor() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_without_constructor.php', $dumper->dump(['base_class' => 'NoConstructorContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'])); + } + + public function testDumpCustomContainerClassConstructorWithoutArguments() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_constructor_without_arguments.php', $dumper->dump(['base_class' => 'ConstructorWithoutArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'])); + } + + public function testDumpCustomContainerClassWithOptionalArgumentLessConstructor() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_optional_constructor_arguments.php', $dumper->dump(['base_class' => 'ConstructorWithOptionalArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'])); + } + + public function testDumpCustomContainerClassWithMandatoryArgumentLessConstructor() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/custom_container_class_with_mandatory_constructor_arguments.php', $dumper->dump(['base_class' => 'ConstructorWithMandatoryArgumentsContainer', 'namespace' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container'])); + } + + /** + * @dataProvider provideInvalidParameters + */ + public function testExportParameters($parameters) + { + $this->expectException('InvalidArgumentException'); + $container = new ContainerBuilder(new ParameterBag($parameters)); + $container->compile(); + $dumper = new PhpDumper($container); + $dumper->dump(); + } + + public function provideInvalidParameters() + { + return [ + [['foo' => new Definition('stdClass')]], + [['foo' => new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')]], + [['foo' => new Reference('foo')]], + [['foo' => new Variable('foo')]], + ]; + } + + public function testAddParameters() + { + $container = include self::$fixturesPath.'/containers/container8.php'; + $container->compile(); + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services8.php', $dumper->dump(), '->dump() dumps parameters'); + } + + /** + * @group legacy + * @expectedDeprecation Dumping an uncompiled ContainerBuilder is deprecated since Symfony 3.3 and will not be supported anymore in 4.0. Compile the container beforehand. + */ + public function testAddServiceWithoutCompilation() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services9.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.\DIRECTORY_SEPARATOR.'includes'.\DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services'); + } + + public function testAddService() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $container->compile(); + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services9_compiled.php', str_replace(str_replace('\\', '\\\\', self::$fixturesPath.\DIRECTORY_SEPARATOR.'includes'.\DIRECTORY_SEPARATOR), '%path%', $dumper->dump()), '->dump() dumps services'); + + $container = new ContainerBuilder(); + $container->register('foo', 'FooClass')->addArgument(new \stdClass())->setPublic(true); + $container->compile(); + $dumper = new PhpDumper($container); + try { + $dumper->dump(); + $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Symfony\Component\DependencyInjection\Exception\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } + } + + public function testDumpAsFiles() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $container->getDefinition('bar')->addTag('hot'); + $container->compile(); + $dumper = new PhpDumper($container); + $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot']), true); + if ('\\' === \DIRECTORY_SEPARATOR) { + $dump = str_replace('\\\\Fixtures\\\\includes\\\\foo.php', '/Fixtures/includes/foo.php', $dump); + } + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump); + } + + public function testServicesWithAnonymousFactories() + { + $container = include self::$fixturesPath.'/containers/container19.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services19.php', $dumper->dump(), '->dump() dumps services with anonymous factories'); + } + + public function testAddServiceIdWithUnsupportedCharacters() + { + $class = 'Symfony_DI_PhpDumper_Test_Unsupported_Characters'; + $container = new ContainerBuilder(); + $container->setParameter("'", 'oh-no'); + $container->register('foo*/oh-no', 'FooClass')->setPublic(true); + $container->register('bar$', 'FooClass')->setPublic(true); + $container->register('bar$!', 'FooClass')->setPublic(true); + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_unsupported_characters.php', $dumper->dump(['class' => $class])); + + require_once self::$fixturesPath.'/php/services_unsupported_characters.php'; + + $this->assertTrue(method_exists($class, 'getFooOhNoService')); + $this->assertTrue(method_exists($class, 'getBarService')); + $this->assertTrue(method_exists($class, 'getBar2Service')); + } + + public function testConflictingServiceIds() + { + $class = 'Symfony_DI_PhpDumper_Test_Conflicting_Service_Ids'; + $container = new ContainerBuilder(); + $container->register('foo_bar', 'FooClass')->setPublic(true); + $container->register('foobar', 'FooClass')->setPublic(true); + $container->compile(); + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => $class])); + + $this->assertTrue(method_exists($class, 'getFooBarService')); + $this->assertTrue(method_exists($class, 'getFoobar2Service')); + } + + public function testConflictingMethodsWithParent() + { + $class = 'Symfony_DI_PhpDumper_Test_Conflicting_Method_With_Parent'; + $container = new ContainerBuilder(); + $container->register('bar', 'FooClass')->setPublic(true); + $container->register('foo_bar', 'FooClass')->setPublic(true); + $container->compile(); + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump([ + 'class' => $class, + 'base_class' => 'Symfony\Component\DependencyInjection\Tests\Fixtures\containers\CustomContainer', + ])); + + $this->assertTrue(method_exists($class, 'getBar2Service')); + $this->assertTrue(method_exists($class, 'getFoobar2Service')); + } + + /** + * @dataProvider provideInvalidFactories + */ + public function testInvalidFactories($factory) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Cannot dump definition'); + $container = new ContainerBuilder(); + $def = new Definition('stdClass'); + $def->setPublic(true); + $def->setFactory($factory); + $container->setDefinition('bar', $def); + $container->compile(); + $dumper = new PhpDumper($container); + $dumper->dump(); + } + + public function provideInvalidFactories() + { + return [ + [['', 'method']], + [['class', '']], + [['...', 'method']], + [['class', '...']], + ]; + } + + public function testAliases() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $container->setParameter('foo_bar', 'foo_bar'); + $container->compile(); + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Aliases'])); + + $container = new \Symfony_DI_PhpDumper_Test_Aliases(); + $foo = $container->get('foo'); + $this->assertSame($foo, $container->get('alias_for_foo')); + $this->assertSame($foo, $container->get('alias_for_alias')); + } + + public function testFrozenContainerWithoutAliases() + { + $container = new ContainerBuilder(); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Frozen_No_Aliases'])); + + $container = new \Symfony_DI_PhpDumper_Test_Frozen_No_Aliases(); + $this->assertFalse($container->has('foo')); + } + + /** + * @group legacy + * @expectedDeprecation The "decorator_service" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0. + */ + public function testOverrideServiceWhenUsingADumpedContainer() + { + require_once self::$fixturesPath.'/php/services9_compiled.php'; + + $container = new \ProjectServiceContainer(); + $container->get('decorator_service'); + $container->set('decorator_service', $decorator = new \stdClass()); + + $this->assertSame($decorator, $container->get('decorator_service'), '->set() overrides an already defined service'); + } + + public function testDumpAutowireData() + { + $container = include self::$fixturesPath.'/containers/container24.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services24.php', $dumper->dump()); + } + + public function testEnvInId() + { + $container = include self::$fixturesPath.'/containers/container_env_in_id.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_env_in_id.php', $dumper->dump()); + } + + public function testEnvParameter() + { + $rand = mt_rand(); + putenv('Baz='.$rand); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services26.yml'); + $container->setParameter('env(json_file)', self::$fixturesPath.'/array.json'); + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services26.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_EnvParameters', 'file' => self::$fixturesPath.'/php/services26.php'])); + + require self::$fixturesPath.'/php/services26.php'; + $container = new \Symfony_DI_PhpDumper_Test_EnvParameters(); + $this->assertSame($rand, $container->getParameter('baz')); + $this->assertSame([123, 'abc'], $container->getParameter('json')); + $this->assertSame('sqlite:///foo/bar/var/data.db', $container->getParameter('db_dsn')); + putenv('Baz'); + } + + public function testResolvedBase64EnvParameters() + { + $container = new ContainerBuilder(); + $container->setParameter('env(foo)', base64_encode('world')); + $container->setParameter('hello', '%env(base64:foo)%'); + $container->compile(true); + + $expected = [ + 'env(foo)' => 'd29ybGQ=', + 'hello' => 'world', + ]; + $this->assertSame($expected, $container->getParameterBag()->all()); + } + + public function testDumpedBase64EnvParameters() + { + $container = new ContainerBuilder(); + $container->setParameter('env(foo)', base64_encode('world')); + $container->setParameter('hello', '%env(base64:foo)%'); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->dump(); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_base64_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Base64Parameters'])); + + require self::$fixturesPath.'/php/services_base64_env.php'; + $container = new \Symfony_DI_PhpDumper_Test_Base64Parameters(); + $this->assertSame('world', $container->getParameter('hello')); + } + + public function testCustomEnvParameters() + { + $container = new ContainerBuilder(); + $container->setParameter('env(foo)', str_rot13('world')); + $container->setParameter('hello', '%env(rot13:foo)%'); + $container->register(Rot13EnvVarProcessor::class)->addTag('container.env_var_processor')->setPublic(true); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->dump(); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_rot13_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Rot13Parameters'])); + + require self::$fixturesPath.'/php/services_rot13_env.php'; + $container = new \Symfony_DI_PhpDumper_Test_Rot13Parameters(); + $this->assertSame('world', $container->getParameter('hello')); + } + + public function testFileEnvProcessor() + { + $container = new ContainerBuilder(); + $container->setParameter('env(foo)', __FILE__); + $container->setParameter('random', '%env(file:foo)%'); + $container->compile(true); + + $this->assertStringEqualsFile(__FILE__, $container->getParameter('random')); + } + + public function testUnusedEnvParameter() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\EnvParameterException'); + $this->expectExceptionMessage('Environment variables "FOO" are never used. Please, check your container\'s configuration.'); + $container = new ContainerBuilder(); + $container->getParameter('env(FOO)'); + $container->compile(); + $dumper = new PhpDumper($container); + $dumper->dump(); + } + + public function testCircularDynamicEnv() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException'); + $this->expectExceptionMessage('Circular reference detected for parameter "env(resolve:DUMMY_ENV_VAR)" ("env(resolve:DUMMY_ENV_VAR)" > "env(resolve:DUMMY_ENV_VAR)").'); + $container = new ContainerBuilder(); + $container->setParameter('foo', '%bar%'); + $container->setParameter('bar', '%env(resolve:DUMMY_ENV_VAR)%'); + $container->compile(); + + $dumper = new PhpDumper($container); + $dump = $dumper->dump(['class' => $class = __FUNCTION__]); + + eval('?>'.$dump); + $container = new $class(); + + putenv('DUMMY_ENV_VAR=%foo%'); + try { + $container->getParameter('bar'); + } finally { + putenv('DUMMY_ENV_VAR'); + } + } + + public function testInlinedDefinitionReferencingServiceContainer() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addMethodCall('add', [new Reference('service_container')])->setPublic(false); + $container->register('bar', 'stdClass')->addArgument(new Reference('foo'))->setPublic(true); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container'); + } + + public function testNonSharedLazyDefinitionReferences() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setShared(false)->setLazy(true); + $container->register('bar', 'stdClass')->addArgument(new Reference('foo', ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, false)); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->setProxyDumper(new \DummyProxyDumper()); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_non_shared_lazy.php', $dumper->dump()); + } + + public function testInitializePropertiesBeforeMethodCalls() + { + require_once self::$fixturesPath.'/includes/classes.php'; + + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true); + $container->register('bar', 'MethodCallClass') + ->setPublic(true) + ->setProperty('simple', 'bar') + ->setProperty('complex', new Reference('foo')) + ->addMethodCall('callMe'); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls'])); + + $container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls(); + $this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls'); + } + + public function testCircularReferenceAllowanceForLazyServices() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->addArgument(new Reference('bar'))->setPublic(true); + $container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'))->setPublic(true); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->setProxyDumper(new \DummyProxyDumper()); + $dumper->dump(); + + $this->addToAssertionCount(1); + + $dumper = new PhpDumper($container); + + $message = 'Circular reference detected for service "foo", path: "foo -> bar -> foo". Try running "composer require symfony/proxy-manager-bridge".'; + $this->expectException(ServiceCircularReferenceException::class); + $this->expectExceptionMessage($message); + + $dumper->dump(); + } + + public function testDedupLazyProxy() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setLazy(true)->setPublic(true); + $container->register('bar', 'stdClass')->setLazy(true)->setPublic(true); + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->setProxyDumper(new \DummyProxyDumper()); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dedup_lazy_proxy.php', $dumper->dump()); + } + + public function testLazyArgumentProvideGenerator() + { + require_once self::$fixturesPath.'/includes/classes.php'; + + $container = new ContainerBuilder(); + $container->register('lazy_referenced', 'stdClass')->setPublic(true); + $container + ->register('lazy_context', 'LazyContext') + ->setPublic(true) + ->setArguments([ + new IteratorArgument(['k1' => new Reference('lazy_referenced'), 'k2' => new Reference('service_container')]), + new IteratorArgument([]), + ]) + ; + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator'])); + + $container = new \Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator(); + $lazyContext = $container->get('lazy_context'); + + $this->assertInstanceOf(RewindableGenerator::class, $lazyContext->lazyValues); + $this->assertInstanceOf(RewindableGenerator::class, $lazyContext->lazyEmptyValues); + $this->assertCount(2, $lazyContext->lazyValues); + $this->assertCount(0, $lazyContext->lazyEmptyValues); + + $i = -1; + foreach ($lazyContext->lazyValues as $k => $v) { + switch (++$i) { + case 0: + $this->assertEquals('k1', $k); + $this->assertInstanceOf('stdCLass', $v); + break; + case 1: + $this->assertEquals('k2', $k); + $this->assertInstanceOf('Symfony_DI_PhpDumper_Test_Lazy_Argument_Provide_Generator', $v); + break; + } + } + + $this->assertEmpty(iterator_to_array($lazyContext->lazyEmptyValues)); + } + + public function testNormalizedId() + { + $container = include self::$fixturesPath.'/containers/container33.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services33.php', $dumper->dump()); + } + + public function testDumpContainerBuilderWithFrozenConstructorIncludingPrivateServices() + { + $container = new ContainerBuilder(); + $container->register('foo_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true); + $container->register('bar_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true); + $container->register('baz_service', 'stdClass')->setPublic(false); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_private_frozen.php', $dumper->dump()); + } + + public function testServiceLocator() + { + $container = new ContainerBuilder(); + $container->register('foo_service', ServiceLocator::class) + ->setPublic(true) + ->addArgument([ + 'bar' => new ServiceClosureArgument(new Reference('bar_service')), + 'baz' => new ServiceClosureArgument(new TypedReference('baz_service', 'stdClass')), + 'nil' => $nil = new ServiceClosureArgument(new Reference('nil')), + ]) + ; + + // no method calls + $container->register('translator.loader_1', 'stdClass')->setPublic(true); + $container->register('translator.loader_1_locator', ServiceLocator::class) + ->setPublic(false) + ->addArgument([ + 'translator.loader_1' => new ServiceClosureArgument(new Reference('translator.loader_1')), + ]); + $container->register('translator_1', StubbedTranslator::class) + ->setPublic(true) + ->addArgument(new Reference('translator.loader_1_locator')); + + // one method calls + $container->register('translator.loader_2', 'stdClass')->setPublic(true); + $container->register('translator.loader_2_locator', ServiceLocator::class) + ->setPublic(false) + ->addArgument([ + 'translator.loader_2' => new ServiceClosureArgument(new Reference('translator.loader_2')), + ]); + $container->register('translator_2', StubbedTranslator::class) + ->setPublic(true) + ->addArgument(new Reference('translator.loader_2_locator')) + ->addMethodCall('addResource', ['db', new Reference('translator.loader_2'), 'nl']); + + // two method calls + $container->register('translator.loader_3', 'stdClass')->setPublic(true); + $container->register('translator.loader_3_locator', ServiceLocator::class) + ->setPublic(false) + ->addArgument([ + 'translator.loader_3' => new ServiceClosureArgument(new Reference('translator.loader_3')), + ]); + $container->register('translator_3', StubbedTranslator::class) + ->setPublic(true) + ->addArgument(new Reference('translator.loader_3_locator')) + ->addMethodCall('addResource', ['db', new Reference('translator.loader_3'), 'nl']) + ->addMethodCall('addResource', ['db', new Reference('translator.loader_3'), 'en']); + + $nil->setValues([null]); + $container->register('bar_service', 'stdClass')->setArguments([new Reference('baz_service')])->setPublic(true); + $container->register('baz_service', 'stdClass')->setPublic(false); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_locator.php', $dumper->dump()); + } + + public function testServiceSubscriber() + { + $container = new ContainerBuilder(); + $container->register('foo_service', TestServiceSubscriber::class) + ->setPublic(true) + ->setAutowired(true) + ->addArgument(new Reference(ContainerInterface::class)) + ->addTag('container.service_subscriber', [ + 'key' => 'bar', + 'id' => TestServiceSubscriber::class, + ]) + ; + $container->register(TestServiceSubscriber::class, TestServiceSubscriber::class)->setPublic(true); + + $container->register(CustomDefinition::class, CustomDefinition::class) + ->setPublic(false); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_subscriber.php', $dumper->dump()); + } + + public function testPrivateWithIgnoreOnInvalidReference() + { + require_once self::$fixturesPath.'/includes/classes.php'; + + $container = new ContainerBuilder(); + $container->register('not_invalid', 'BazClass') + ->setPublic(false); + $container->register('bar', 'BarClass') + ->setPublic(true) + ->addMethodCall('setBaz', [new Reference('not_invalid', SymfonyContainerInterface::IGNORE_ON_INVALID_REFERENCE)]); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference'])); + + $container = new \Symfony_DI_PhpDumper_Test_Private_With_Ignore_On_Invalid_Reference(); + $this->assertInstanceOf('BazClass', $container->get('bar')->getBaz()); + } + + public function testArrayParameters() + { + $container = new ContainerBuilder(); + $container->setParameter('array_1', [123]); + $container->setParameter('array_2', [__DIR__]); + $container->register('bar', 'BarClass') + ->setPublic(true) + ->addMethodCall('setBaz', ['%array_1%', '%array_2%', '%%array_1%%', [123]]); + $container->compile(); + + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_array_params.php', str_replace('\\\\Dumper', '/Dumper', $dumper->dump(['file' => self::$fixturesPath.'/php/services_array_params.php']))); + } + + public function testExpressionReferencingPrivateService() + { + $container = new ContainerBuilder(); + $container->register('private_bar', 'stdClass') + ->setPublic(false); + $container->register('private_foo', 'stdClass') + ->setPublic(false); + $container->register('public_foo', 'stdClass') + ->setPublic(true) + ->addArgument(new Expression('service("private_foo").bar')); + + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_private_in_expression.php', $dumper->dump()); + } + + public function testUninitializedReference() + { + $container = include self::$fixturesPath.'/containers/container_uninitialized_ref.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_uninitialized_ref.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Uninitialized_Reference'])); + + require self::$fixturesPath.'/php/services_uninitialized_ref.php'; + + $container = new \Symfony_DI_PhpDumper_Test_Uninitialized_Reference(); + + $bar = $container->get('bar'); + + $this->assertNull($bar->foo1); + $this->assertNull($bar->foo2); + $this->assertNull($bar->foo3); + $this->assertNull($bar->closures[0]()); + $this->assertNull($bar->closures[1]()); + $this->assertNull($bar->closures[2]()); + $this->assertSame([], iterator_to_array($bar->iter)); + + $container = new \Symfony_DI_PhpDumper_Test_Uninitialized_Reference(); + + $container->get('foo1'); + $container->get('baz'); + + $bar = $container->get('bar'); + + $this->assertEquals(new \stdClass(), $bar->foo1); + $this->assertNull($bar->foo2); + $this->assertEquals(new \stdClass(), $bar->foo3); + $this->assertEquals(new \stdClass(), $bar->closures[0]()); + $this->assertNull($bar->closures[1]()); + $this->assertEquals(new \stdClass(), $bar->closures[2]()); + $this->assertEquals(['foo1' => new \stdClass(), 'foo3' => new \stdClass()], iterator_to_array($bar->iter)); + } + + /** + * @dataProvider provideAlmostCircular + */ + public function testAlmostCircular($visibility) + { + $container = include self::$fixturesPath.'/containers/container_almost_circular.php'; + $container->compile(); + $dumper = new PhpDumper($container); + + $container = 'Symfony_DI_PhpDumper_Test_Almost_Circular_'.ucfirst($visibility); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_almost_circular_'.$visibility.'.php', $dumper->dump(['class' => $container])); + + require self::$fixturesPath.'/php/services_almost_circular_'.$visibility.'.php'; + + $container = new $container(); + + $foo = $container->get('foo'); + $this->assertSame($foo, $foo->bar->foobar->foo); + + $foo2 = $container->get('foo2'); + $this->assertSame($foo2, $foo2->bar->foobar->foo); + + $this->assertSame([], (array) $container->get('foobar4')); + + $foo5 = $container->get('foo5'); + $this->assertSame($foo5, $foo5->bar->foo); + + $manager = $container->get('manager'); + $this->assertEquals(new \stdClass(), $manager); + + $manager = $container->get('manager2'); + $this->assertEquals(new \stdClass(), $manager); + + $foo6 = $container->get('foo6'); + $this->assertEquals((object) ['bar6' => (object) []], $foo6); + + $this->assertInstanceOf(\stdClass::class, $container->get('root')); + + $manager3 = $container->get('manager3'); + $listener3 = $container->get('listener3'); + $this->assertSame($manager3, $listener3->manager); + + $listener4 = $container->get('listener4'); + $this->assertInstanceOf('stdClass', $listener4); + } + + public function provideAlmostCircular() + { + yield ['public']; + yield ['private']; + } + + public function testDeepServiceGraph() + { + $container = new ContainerBuilder(); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_deep_graph.yml'); + + $container->compile(); + + $dumper = new PhpDumper($container); + $dumper->dump(); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_deep_graph.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Deep_Graph'])); + + require self::$fixturesPath.'/php/services_deep_graph.php'; + + $container = new \Symfony_DI_PhpDumper_Test_Deep_Graph(); + + $this->assertInstanceOf(FooForDeepGraph::class, $container->get('foo')); + $this->assertEquals((object) ['p2' => (object) ['p3' => (object) []]], $container->get('foo')->bClone); + } + + public function testInlineSelfRef() + { + $container = new ContainerBuilder(); + + $bar = (new Definition('App\Bar')) + ->setProperty('foo', new Reference('App\Foo')); + + $baz = (new Definition('App\Baz')) + ->setProperty('bar', $bar) + ->addArgument($bar); + + $container->register('App\Foo') + ->setPublic(true) + ->addArgument($baz); + + $container->getCompiler()->getPassConfig(); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_self_ref.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Inline_Self_Ref'])); + } + + public function testHotPathOptimizations() + { + $container = include self::$fixturesPath.'/containers/container_inline_requires.php'; + $container->setParameter('inline_requires', true); + $container->compile(); + $dumper = new PhpDumper($container); + + $dump = $dumper->dump(['hot_path_tag' => 'container.hot_path', 'inline_class_loader_parameter' => 'inline_requires', 'file' => self::$fixturesPath.'/php/services_inline_requires.php']); + if ('\\' === \DIRECTORY_SEPARATOR) { + $dump = str_replace("'\\\\includes\\\\HotPath\\\\", "'/includes/HotPath/", $dump); + } + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_inline_requires.php', $dump); + } + + public function testDumpHandlesLiteralClassWithRootNamespace() + { + $container = new ContainerBuilder(); + $container->register('foo', '\\stdClass')->setPublic(true); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Literal_Class_With_Root_Namespace'])); + + $container = new \Symfony_DI_PhpDumper_Test_Literal_Class_With_Root_Namespace(); + + $this->assertInstanceOf('stdClass', $container->get('foo')); + } + + public function testDumpHandlesObjectClassNames() + { + $container = new ContainerBuilder(new ParameterBag([ + 'class' => 'stdClass', + ])); + + $container->setDefinition('foo', new Definition(new Parameter('class'))); + $container->setDefinition('bar', new Definition('stdClass', [ + new Reference('foo'), + ]))->setPublic(true); + + $container->setParameter('inline_requires', true); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump([ + 'class' => 'Symfony_DI_PhpDumper_Test_Object_Class_Name', + 'inline_class_loader_parameter' => 'inline_requires', + ])); + + $container = new \Symfony_DI_PhpDumper_Test_Object_Class_Name(); + + $this->assertInstanceOf('stdClass', $container->get('bar')); + } + + public function testUninitializedSyntheticReference() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass')->setPublic(true)->setSynthetic(true); + $container->register('bar', 'stdClass')->setPublic(true)->setShared(false) + ->setProperty('foo', new Reference('foo', ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE)); + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump([ + 'class' => 'Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference', + 'inline_class_loader_parameter' => 'inline_requires', + ])); + + $container = new \Symfony_DI_PhpDumper_Test_UninitializedSyntheticReference(); + + $this->assertEquals((object) ['foo' => null], $container->get('bar')); + + $container->set('foo', (object) [123]); + $this->assertEquals((object) ['foo' => (object) [123]], $container->get('bar')); + } + + public function testAdawsonContainer() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_adawson.yml'); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_adawson.php', $dumper->dump()); + } + + /** + * @group legacy + * @expectedDeprecation The "private" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "private_alias" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "decorated_private" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "decorated_private_alias" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "private_not_inlined" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "private_not_removed" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "private_child" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + * @expectedDeprecation The "private_parent" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. + */ + public function testLegacyPrivateServices() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_legacy_privates.yml'); + + $container->setDefinition('private_child', new ChildDefinition('foo')); + $container->setDefinition('private_parent', new ChildDefinition('private')); + + $container->getDefinition('private')->setPrivate(true); + $container->getDefinition('private_not_inlined')->setPrivate(true); + $container->getDefinition('private_not_removed')->setPrivate(true); + $container->getDefinition('decorated_private')->setPrivate(true); + $container->getDefinition('private_child')->setPrivate(true); + $container->getAlias('decorated_private_alias')->setPrivate(true); + $container->getAlias('private_alias')->setPrivate(true); + + $container->compile(); + $dumper = new PhpDumper($container); + + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_legacy_privates.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Legacy_Privates', 'file' => self::$fixturesPath.'/php/services_legacy_privates.php'])); + + require self::$fixturesPath.'/php/services_legacy_privates.php'; + + $container = new \Symfony_DI_PhpDumper_Test_Legacy_Privates(); + + $container->get('private'); + $container->get('private_alias'); + $container->get('alias_to_private'); + $container->get('decorated_private'); + $container->get('decorated_private_alias'); + $container->get('private_not_inlined'); + $container->get('private_not_removed'); + $container->get('private_child'); + $container->get('private_parent'); + $container->get('public_child'); + } + + /** + * This test checks the trigger of a deprecation note and should not be removed in major releases. + * + * @group legacy + * @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testPrivateServiceTriggersDeprecation() + { + $container = new ContainerBuilder(); + $container->register('foo', 'stdClass') + ->setPublic(false) + ->setDeprecated(true); + $container->register('bar', 'stdClass') + ->setPublic(true) + ->setProperty('foo', new Reference('foo')); + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Private_Service_Triggers_Deprecation'])); + + $container = new \Symfony_DI_PhpDumper_Test_Private_Service_Triggers_Deprecation(); + + $container->get('bar'); + } + + /** + * @group legacy + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "foo" instead of "Foo" is deprecated since Symfony 3.4. + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "FOO" instead of "Foo" is deprecated since Symfony 3.4. + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "bar" instead of "BAR" is deprecated since Symfony 3.4. + */ + public function testParameterWithMixedCase() + { + $container = new ContainerBuilder(new ParameterBag(['Foo' => 'bar', 'BAR' => 'foo'])); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Parameter_With_Mixed_Case'])); + + $container = new \Symfony_DI_PhpDumper_Test_Parameter_With_Mixed_Case(); + + $this->assertSame('bar', $container->getParameter('foo')); + $this->assertSame('bar', $container->getParameter('FOO')); + $this->assertSame('foo', $container->getParameter('bar')); + $this->assertSame('foo', $container->getParameter('BAR')); + } + + /** + * @group legacy + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "FOO" instead of "foo" is deprecated since Symfony 3.4. + */ + public function testParameterWithLowerCase() + { + $container = new ContainerBuilder(new ParameterBag(['foo' => 'bar'])); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Parameter_With_Lower_Case'])); + + $container = new \Symfony_DI_PhpDumper_Test_Parameter_With_Lower_Case(); + + $this->assertSame('bar', $container->getParameter('FOO')); + } + + /** + * @group legacy + * @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "foo" instead of "Foo" is deprecated since Symfony 3.3. + * @expectedDeprecation The "Foo" service is deprecated. You should stop using it, as it will soon be removed. + */ + public function testReferenceWithLowerCaseId() + { + $container = new ContainerBuilder(); + $container->register('Bar', 'stdClass')->setProperty('foo', new Reference('foo'))->setPublic(true); + $container->register('Foo', 'stdClass')->setDeprecated(); + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Reference_With_Lower_Case_Id'])); + + $container = new \Symfony_DI_PhpDumper_Test_Reference_With_Lower_Case_Id(); + + $this->assertEquals((object) ['foo' => (object) []], $container->get('Bar')); + } + + public function testScalarService() + { + $container = new ContainerBuilder(); + $container->register('foo', 'string') + ->setPublic(true) + ->setFactory([ScalarFactory::class, 'getSomeValue']) + ; + + $container->compile(); + + $dumper = new PhpDumper($container); + eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Scalar_Service'])); + + $container = new \Symfony_DI_PhpDumper_Test_Scalar_Service(); + + $this->assertTrue($container->has('foo')); + $this->assertSame('some value', $container->get('foo')); + } + + public function testAliasCanBeFoundInTheDumpedContainerWhenBothTheAliasAndTheServiceArePublic() + { + $container = new ContainerBuilder(); + + $container->register('foo', 'stdClass')->setPublic(true); + $container->setAlias('bar', 'foo')->setPublic(true); + + $container->compile(); + + // Bar is found in the compiled container + $service_ids = $container->getServiceIds(); + $this->assertContains('bar', $service_ids); + + $dumper = new PhpDumper($container); + $dump = $dumper->dump(['class' => 'Symfony_DI_PhpDumper_AliasesCanBeFoundInTheDumpedContainer']); + eval('?>'.$dump); + + $container = new \Symfony_DI_PhpDumper_AliasesCanBeFoundInTheDumpedContainer(); + + // Bar should still be found in the compiled container + $service_ids = $container->getServiceIds(); + $this->assertContains('bar', $service_ids); + } +} + +class Rot13EnvVarProcessor implements EnvVarProcessorInterface +{ + public function getEnv($prefix, $name, \Closure $getEnv) + { + return str_rot13($getEnv($name)); + } + + public static function getProvidedTypes() + { + return ['rot13' => 'string']; + } +} + +class FooForDeepGraph +{ + public $bClone; + + public function __construct(\stdClass $a, \stdClass $b) + { + // clone to verify that $b has been fully initialized before + $this->bClone = clone $b; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php new file mode 100644 index 00000000..e660c7e8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/XmlDumperTest.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Dumper\XmlDumper; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Reference; + +class XmlDumperTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + public function testDump() + { + $dumper = new XmlDumper(new ContainerBuilder()); + + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services1.xml', $dumper->dump(), '->dump() dumps an empty container as an empty XML file'); + } + + public function testExportParameters() + { + $container = include self::$fixturesPath.'//containers/container8.php'; + $dumper = new XmlDumper($container); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddParameters() + { + $container = include self::$fixturesPath.'//containers/container8.php'; + $dumper = new XmlDumper($container); + $this->assertXmlStringEqualsXmlFile(self::$fixturesPath.'/xml/services8.xml', $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddService() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new XmlDumper($container); + + $this->assertEquals(str_replace('%path%', self::$fixturesPath.\DIRECTORY_SEPARATOR.'includes'.\DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/xml/services9.xml')), $dumper->dump(), '->dump() dumps services'); + + $dumper = new XmlDumper($container = new ContainerBuilder()); + $container->register('foo', 'FooClass')->addArgument(new \stdClass())->setPublic(true); + try { + $dumper->dump(); + $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } + } + + public function testDumpAnonymousServices() + { + $container = include self::$fixturesPath.'/containers/container11.php'; + $dumper = new XmlDumper($container); + $this->assertEquals(' + + + + + + + + + + + + + + + + +', $dumper->dump()); + } + + public function testDumpEntities() + { + $container = include self::$fixturesPath.'/containers/container12.php'; + $dumper = new XmlDumper($container); + $this->assertEquals(" + + + + + + foo<>&bar + + + + + +", $dumper->dump()); + } + + /** + * @dataProvider provideDecoratedServicesData + */ + public function testDumpDecoratedServices($expectedXmlDump, $container) + { + $dumper = new XmlDumper($container); + $this->assertEquals($expectedXmlDump, $dumper->dump()); + } + + public function provideDecoratedServicesData() + { + $fixturesPath = realpath(__DIR__.'/../Fixtures/'); + + return [ + [" + + + + + + + + +", include $fixturesPath.'/containers/container15.php'], + [" + + + + + + + + +", include $fixturesPath.'/containers/container16.php'], + ]; + } + + /** + * @dataProvider provideCompiledContainerData + */ + public function testCompiledContainerCanBeDumped($containerFile) + { + $fixturesPath = __DIR__.'/../Fixtures'; + $container = require $fixturesPath.'/containers/'.$containerFile.'.php'; + $container->compile(); + $dumper = new XmlDumper($container); + $dumper->dump(); + + $this->addToAssertionCount(1); + } + + public function provideCompiledContainerData() + { + return [ + ['container8'], + ['container9'], + ['container11'], + ['container12'], + ['container14'], + ]; + } + + public function testDumpInlinedServices() + { + $container = include self::$fixturesPath.'/containers/container21.php'; + $dumper = new XmlDumper($container); + + $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services21.xml'), $dumper->dump()); + } + + public function testDumpAutowireData() + { + $container = include self::$fixturesPath.'/containers/container24.php'; + $dumper = new XmlDumper($container); + + $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services24.xml'), $dumper->dump()); + } + + public function testDumpLoad() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_dump_load.xml'); + + $this->assertEquals([new Reference('bar', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)], $container->getDefinition('foo')->getArguments()); + + $dumper = new XmlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/xml/services_dump_load.xml', $dumper->dump()); + } + + public function testDumpAbstractServices() + { + $container = include self::$fixturesPath.'/containers/container_abstract.php'; + $dumper = new XmlDumper($container); + + $this->assertEquals(file_get_contents(self::$fixturesPath.'/xml/services_abstract.xml'), $dumper->dump()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/YamlDumperTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/YamlDumperTest.php new file mode 100644 index 00000000..49ee8e6f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Dumper/YamlDumperTest.php @@ -0,0 +1,104 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Dumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Dumper\YamlDumper; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Yaml; + +class YamlDumperTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + public function testDump() + { + $dumper = new YamlDumper($container = new ContainerBuilder()); + + $this->assertEqualYamlStructure(file_get_contents(self::$fixturesPath.'/yaml/services1.yml'), $dumper->dump(), '->dump() dumps an empty container as an empty YAML file'); + } + + public function testAddParameters() + { + $container = include self::$fixturesPath.'/containers/container8.php'; + $dumper = new YamlDumper($container); + $this->assertEqualYamlStructure(file_get_contents(self::$fixturesPath.'/yaml/services8.yml'), $dumper->dump(), '->dump() dumps parameters'); + } + + public function testAddService() + { + $container = include self::$fixturesPath.'/containers/container9.php'; + $dumper = new YamlDumper($container); + $this->assertEqualYamlStructure(str_replace('%path%', self::$fixturesPath.\DIRECTORY_SEPARATOR.'includes'.\DIRECTORY_SEPARATOR, file_get_contents(self::$fixturesPath.'/yaml/services9.yml')), $dumper->dump(), '->dump() dumps services'); + + $dumper = new YamlDumper($container = new ContainerBuilder()); + $container->register('foo', 'FooClass')->addArgument(new \stdClass())->setPublic(true); + try { + $dumper->dump(); + $this->fail('->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } catch (\Exception $e) { + $this->assertInstanceOf('\RuntimeException', $e, '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + $this->assertEquals('Unable to dump a service container if a parameter is an object or a resource.', $e->getMessage(), '->dump() throws a RuntimeException if the container to be dumped has reference to objects or resources'); + } + } + + public function testDumpAutowireData() + { + $container = include self::$fixturesPath.'/containers/container24.php'; + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services24.yml', $dumper->dump()); + } + + public function testDumpLoad() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_dump_load.yml'); + + $this->assertEquals([new Reference('bar', ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE)], $container->getDefinition('foo')->getArguments()); + + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_dump_load.yml', $dumper->dump()); + } + + public function testInlineServices() + { + $container = new ContainerBuilder(); + $container->register('foo', 'Class1') + ->setPublic(true) + ->addArgument((new Definition('Class2')) + ->addArgument(new Definition('Class2')) + ) + ; + + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/yaml/services_inline.yml', $dumper->dump()); + } + + private function assertEqualYamlStructure($expected, $yaml, $message = '') + { + $parser = new Parser(); + + $this->assertEquals($parser->parse($expected, Yaml::PARSE_CUSTOM_TAGS), $parser->parse($yaml, Yaml::PARSE_CUSTOM_TAGS), $message); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/EnvVarProcessorTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/EnvVarProcessorTest.php new file mode 100644 index 00000000..6f0dfd3e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/EnvVarProcessorTest.php @@ -0,0 +1,300 @@ +setParameter('env(foo)', $value); + $container->compile(); + + $processor = new EnvVarProcessor($container); + + $result = $processor->getEnv('string', 'foo', function () { + $this->fail('Should not be called'); + }); + + $this->assertSame($processed, $result); + } + + public function validStrings() + { + return [ + ['hello', 'hello'], + ['true', 'true'], + ['false', 'false'], + ['null', 'null'], + ['1', '1'], + ['0', '0'], + ['1.1', '1.1'], + ['1e1', '1e1'], + ]; + } + + /** + * @dataProvider validBools + */ + public function testGetEnvBool($value, $processed) + { + $processor = new EnvVarProcessor(new Container()); + + $result = $processor->getEnv('bool', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + + $this->assertSame($processed, $result); + } + + public function validBools() + { + return [ + ['true', true], + ['false', false], + ['null', false], + ['1', true], + ['0', false], + ['1.1', true], + ['1e1', true], + ]; + } + + /** + * @dataProvider validInts + */ + public function testGetEnvInt($value, $processed) + { + $processor = new EnvVarProcessor(new Container()); + + $result = $processor->getEnv('int', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + + $this->assertSame($processed, $result); + } + + public function validInts() + { + return [ + ['1', 1], + ['1.1', 1], + ['1e1', 10], + ]; + } + + /** + * @dataProvider invalidInts + */ + public function testGetEnvIntInvalid($value) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Non-numeric env var'); + $processor = new EnvVarProcessor(new Container()); + + $processor->getEnv('int', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + } + + public function invalidInts() + { + return [ + ['foo'], + ['true'], + ['null'], + ]; + } + + /** + * @dataProvider validFloats + */ + public function testGetEnvFloat($value, $processed) + { + $processor = new EnvVarProcessor(new Container()); + + $result = $processor->getEnv('float', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + + $this->assertSame($processed, $result); + } + + public function validFloats() + { + return [ + ['1', 1.0], + ['1.1', 1.1], + ['1e1', 10.0], + ]; + } + + /** + * @dataProvider invalidFloats + */ + public function testGetEnvFloatInvalid($value) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Non-numeric env var'); + $processor = new EnvVarProcessor(new Container()); + + $processor->getEnv('float', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + } + + public function invalidFloats() + { + return [ + ['foo'], + ['true'], + ['null'], + ]; + } + + /** + * @dataProvider validConsts + */ + public function testGetEnvConst($value, $processed) + { + $processor = new EnvVarProcessor(new Container()); + + $result = $processor->getEnv('const', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + + $this->assertSame($processed, $result); + } + + public function validConsts() + { + return [ + ['Symfony\Component\DependencyInjection\Tests\EnvVarProcessorTest::TEST_CONST', self::TEST_CONST], + ['E_ERROR', \E_ERROR], + ]; + } + + /** + * @dataProvider invalidConsts + */ + public function testGetEnvConstInvalid($value) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('undefined constant'); + $processor = new EnvVarProcessor(new Container()); + + $processor->getEnv('const', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return $value; + }); + } + + public function invalidConsts() + { + return [ + ['Symfony\Component\DependencyInjection\Tests\EnvVarProcessorTest::UNDEFINED_CONST'], + ['UNDEFINED_CONST'], + ]; + } + + public function testGetEnvBase64() + { + $processor = new EnvVarProcessor(new Container()); + + $result = $processor->getEnv('base64', 'foo', function ($name) { + $this->assertSame('foo', $name); + + return base64_encode('hello'); + }); + + $this->assertSame('hello', $result); + } + + public function testGetEnvJson() + { + $processor = new EnvVarProcessor(new Container()); + + $result = $processor->getEnv('json', 'foo', function ($name) { + $this->assertSame('foo', $name); + + return json_encode([1]); + }); + + $this->assertSame([1], $result); + } + + public function testGetEnvInvalidJson() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Syntax error'); + $processor = new EnvVarProcessor(new Container()); + + $processor->getEnv('json', 'foo', function ($name) { + $this->assertSame('foo', $name); + + return 'invalid_json'; + }); + } + + /** + * @dataProvider otherJsonValues + */ + public function testGetEnvJsonOther($value) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Invalid JSON env var'); + $processor = new EnvVarProcessor(new Container()); + + $processor->getEnv('json', 'foo', function ($name) use ($value) { + $this->assertSame('foo', $name); + + return json_encode($value); + }); + } + + public function otherJsonValues() + { + return [ + [1], + [1.1], + [true], + [false], + ]; + } + + public function testGetEnvUnknown() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('Unsupported env var prefix'); + $processor = new EnvVarProcessor(new Container()); + + $processor->getEnv('unknown', 'foo', function ($name) { + $this->assertSame('foo', $name); + + return 'foo'; + }); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Extension/ExtensionTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Extension/ExtensionTest.php new file mode 100644 index 00000000..9f35b4a4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Extension/ExtensionTest.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Extension; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; + +class ExtensionTest extends TestCase +{ + /** + * @dataProvider getResolvedEnabledFixtures + */ + public function testIsConfigEnabledReturnsTheResolvedValue($enabled) + { + $extension = new EnableableExtension(); + $this->assertSame($enabled, $extension->isConfigEnabled(new ContainerBuilder(), ['enabled' => $enabled])); + } + + public function getResolvedEnabledFixtures() + { + return [ + [true], + [false], + ]; + } + + public function testIsConfigEnabledOnNonEnableableConfig() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The config array has no \'enabled\' key.'); + $extension = new EnableableExtension(); + + $extension->isConfigEnabled(new ContainerBuilder(), []); + } +} + +class EnableableExtension extends Extension +{ + public function load(array $configs, ContainerBuilder $container) + { + } + + public function isConfigEnabled(ContainerBuilder $container, array $config) + { + return parent::isConfigEnabled($container, $config); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/Bar.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/Bar.php new file mode 100644 index 00000000..1aaca2f1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/Bar.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class Bar implements BarInterface +{ + public $quz; + + public function __construct($quz = null, \NonExistent $nonExistent = null, BarInterface $decorated = null, array $foo = []) + { + $this->quz = $quz; + } + + public static function create(\NonExistent $nonExistent = null, $factory = null) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/BarInterface.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/BarInterface.php new file mode 100644 index 00000000..dc81f33f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/BarInterface.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +interface BarInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/CaseSensitiveClass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/CaseSensitiveClass.php new file mode 100644 index 00000000..7c6f0ff4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/CaseSensitiveClass.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class CaseSensitiveClass +{ + public $identifier; + + public function __construct($identifier = null) + { + $this->identifier = $identifier; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php new file mode 100644 index 00000000..ba55fb75 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/Container/ConstructorWithMandatoryArgumentsContainer.php @@ -0,0 +1,10 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +use Symfony\Component\DependencyInjection\Definition; + +class CustomDefinition extends Definition +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/DeprecatedClass.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/DeprecatedClass.php new file mode 100644 index 00000000..33f37a03 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/DeprecatedClass.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +@trigger_error('deprecated', E_USER_DEPRECATED); + +class DeprecatedClass +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FactoryDummy.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FactoryDummy.php new file mode 100644 index 00000000..da984b56 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FactoryDummy.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class FactoryDummy extends FactoryParent +{ + public static function createFactory(): FactoryDummy + { + } + + public function create(): \stdClass + { + } + + // Not supported by hhvm + public function createBuiltin(): int + { + } + + public static function createSelf(): self + { + } + + public static function createParent(): parent + { + } +} + +class FactoryParent +{ +} + +function factoryFunction(): FactoryDummy +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FactoryDummyWithoutReturnTypes.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FactoryDummyWithoutReturnTypes.php new file mode 100644 index 00000000..f480a668 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FactoryDummyWithoutReturnTypes.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class FactoryDummyWithoutReturnTypes +{ + public function createTestDefinition1() + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FooForCircularWithAddCalls.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FooForCircularWithAddCalls.php new file mode 100644 index 00000000..a8331dc3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/FooForCircularWithAddCalls.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class FooForCircularWithAddCalls +{ + public function call(\stdClass $argument) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/NamedArgumentsDummy.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/NamedArgumentsDummy.php new file mode 100644 index 00000000..09d907df --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/NamedArgumentsDummy.php @@ -0,0 +1,21 @@ + + */ +class NamedArgumentsDummy +{ + public function __construct(CaseSensitiveClass $c, $apiKey, $hostName) + { + } + + public function setApiKey($apiKey) + { + } + + public function setSensitiveClass(CaseSensitiveClass $c) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/ParentNotExists.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/ParentNotExists.php new file mode 100644 index 00000000..ae637f91 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/ParentNotExists.php @@ -0,0 +1,7 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +class SimilarArgumentsDummy +{ + public $class1; + public $class2; + + public function __construct(CaseSensitiveClass $class1, $token, CaseSensitiveClass $class2) + { + $this->class1 = $class1; + $this->class2 = $class2; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/StubbedTranslator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/StubbedTranslator.php new file mode 100644 index 00000000..eed18426 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/StubbedTranslator.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +use Psr\Container\ContainerInterface; + +/** + * @author Iltar van der Berg + */ +class StubbedTranslator +{ + public function __construct(ContainerInterface $container) + { + } + + public function addResource($format, $resource, $locale, $domain = null) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/TestDefinition1.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/TestDefinition1.php new file mode 100644 index 00000000..8ec76a9d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/TestDefinition1.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Fixtures; + +use Symfony\Component\DependencyInjection\Definition; + +class TestDefinition1 extends Definition +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/TestDefinition2.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/TestDefinition2.php new file mode 100644 index 00000000..2ec8f9cf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/TestDefinition2.php @@ -0,0 +1,9 @@ + CustomDefinition::class, + 'baz' => '?'.CustomDefinition::class, + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/array.json b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/array.json new file mode 100644 index 00000000..dc27f0fa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/array.json @@ -0,0 +1 @@ +[123, "abc"] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/basic.expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/basic.expected.yml new file mode 100644 index 00000000..39a3b631 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/basic.expected.yml @@ -0,0 +1,9 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + App\BarService: + class: App\BarService + arguments: [!service { class: FooClass }] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/basic.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/basic.php new file mode 100644 index 00000000..a9e250b9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/basic.php @@ -0,0 +1,11 @@ +services(); + $s->set(BarService::class) + ->args([inline('FooClass')]); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/child.expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/child.expected.yml new file mode 100644 index 00000000..f60d6bb5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/child.expected.yml @@ -0,0 +1,12 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + foo: + class: Class2 + file: file.php + lazy: true + arguments: [!service { class: Class1, public: false }] + bar: '@foo' diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/child.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/child.php new file mode 100644 index 00000000..8a5f2431 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/child.php @@ -0,0 +1,22 @@ +services() + ->set('bar', 'Class1') + ->set(BarService::class) + ->abstract(true) + ->lazy() + ->set('foo') + ->parent(BarService::class) + ->decorate('bar', 'b', 1) + ->args([ref('b')]) + ->class('Class2') + ->file('file.php') + ->parent('bar') + ->parent(BarService::class) + ; +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/defaults.expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/defaults.expected.yml new file mode 100644 index 00000000..3f01b109 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/defaults.expected.yml @@ -0,0 +1,26 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + App\BarService: + class: App\BarService + arguments: [!service { class: FooClass }] + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + public: true + tags: + - { name: t, a: b } + autowire: true + autoconfigure: true + arguments: ['@bar'] + bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + public: false + tags: + - { name: t, a: b } + autowire: true + calls: + - [setFoo, ['@bar']] + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/defaults.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/defaults.php new file mode 100644 index 00000000..2889d3fb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/defaults.php @@ -0,0 +1,21 @@ +import('basic.php'); + + $s = $c->services()->defaults() + ->public() + ->private() + ->autoconfigure() + ->autowire() + ->tag('t', ['a' => 'b']) + ->bind(Foo::class, ref('bar')) + ->private(); + + $s->set(Foo::class)->args([ref('bar')])->public(); + $s->set('bar', Foo::class)->call('setFoo')->autoconfigure(false); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/factory_short_notation.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/factory_short_notation.php new file mode 100644 index 00000000..5b37793e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/factory_short_notation.php @@ -0,0 +1,9 @@ +services() + ->set('service', \stdClass::class) + ->factory('factory:method'); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/instanceof.expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/instanceof.expected.yml new file mode 100644 index 00000000..1238a7bd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/instanceof.expected.yml @@ -0,0 +1,19 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + tags: + - { name: tag, k: v } + lazy: true + properties: { p: 1 } + calls: + - [setFoo, ['@foo']] + + shared: false + configurator: c + foo: + class: App\FooService diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/instanceof.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/instanceof.php new file mode 100644 index 00000000..0d6aac7a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/instanceof.php @@ -0,0 +1,22 @@ +services(); + $s->instanceof(Prototype\Foo::class) + ->property('p', 0) + ->call('setFoo', [ref('foo')]) + ->tag('tag', ['k' => 'v']) + ->share(false) + ->lazy() + ->configurator('c') + ->property('p', 1); + + $s->load(Prototype::class.'\\', '../Prototype')->exclude('../Prototype/*/*'); + + $s->set('foo', FooService::class); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/php7.expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/php7.expected.yml new file mode 100644 index 00000000..7cec320b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/php7.expected.yml @@ -0,0 +1,18 @@ +parameters: + foo: Foo + bar: Bar + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + public: true + arguments: ['@bar'] + bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + calls: + - [setFoo, { }] + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/php7.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/php7.php new file mode 100644 index 00000000..7711624e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/php7.php @@ -0,0 +1,19 @@ +parameters() + ('foo', 'Foo') + ('bar', 'Bar') + ; + $c->services() + (Foo::class) + ->arg('$bar', ref('bar')) + ->public() + ('bar', Foo::class) + ->call('setFoo') + ; +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/prototype.expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/prototype.expected.yml new file mode 100644 index 00000000..24a79401 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/prototype.expected.yml @@ -0,0 +1,23 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + tags: + - { name: foo } + - { name: baz } + deprecated: '%service_id%' + arguments: [1] + factory: f + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar + tags: + - { name: foo } + - { name: baz } + deprecated: '%service_id%' + lazy: true + arguments: [1] + factory: f diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/prototype.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/prototype.php new file mode 100644 index 00000000..e2884aa2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/prototype.php @@ -0,0 +1,22 @@ +services()->defaults() + ->tag('baz'); + $di->load(Prototype::class.'\\', '../Prototype') + ->autoconfigure() + ->exclude('../Prototype/{OtherDir,BadClasses}') + ->factory('f') + ->deprecate('%service_id%') + ->args([0]) + ->args([1]) + ->autoconfigure(false) + ->tag('foo') + ->parent('foo'); + $di->set('foo')->lazy()->abstract(); + $di->get(Prototype\Foo::class)->lazy(false); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/services9.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/services9.php new file mode 100644 index 00000000..ef390937 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/services9.php @@ -0,0 +1,127 @@ +parameters(); + $p->set('baz_class', 'BazClass'); + $p->set('foo_class', FooClass::class) + ->set('foo', 'bar'); + + $s = $c->services()->defaults()->public(); + $s->set('foo') + ->args(['foo', ref('foo.baz'), ['%foo%' => 'foo is %foo%', 'foobar' => '%foo%'], true, ref('service_container')]) + ->class(FooClass::class) + ->tag('foo', ['foo' => 'foo']) + ->tag('foo', ['bar' => 'bar', 'baz' => 'baz']) + ->factory([FooClass::class, 'getInstance']) + ->property('foo', 'bar') + ->property('moo', ref('foo.baz')) + ->property('qux', ['%foo%' => 'foo is %foo%', 'foobar' => '%foo%']) + ->call('setBar', [ref('bar')]) + ->call('initialize') + ->configurator('sc_configure'); + + $s->set('foo.baz', '%baz_class%') + ->factory(['%baz_class%', 'getInstance']) + ->configurator(['%baz_class%', 'configureStatic1']); + + $s->set('bar', FooClass::class) + ->args(['foo', ref('foo.baz'), new Parameter('foo_bar')]) + ->configurator([ref('foo.baz'), 'configure']); + + $s->set('foo_bar', '%foo_class%') + ->args([ref('deprecated_service')]) + ->share(false); + + $s->set('method_call1', 'Bar\FooClass') + ->file(realpath(__DIR__.'/../includes/foo.php')) + ->call('setBar', [ref('foo')]) + ->call('setBar', [ref('foo2')->nullOnInvalid()]) + ->call('setBar', [ref('foo3')->ignoreOnInvalid()]) + ->call('setBar', [ref('foobaz')->ignoreOnInvalid()]) + ->call('setBar', [expr('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')]); + + $s->set('foo_with_inline', 'Foo') + ->call('setBar', [ref('inlined')]); + + $s->set('inlined', 'Bar') + ->property('pub', 'pub') + ->call('setBaz', [ref('baz')]) + ->private(); + + $s->set('baz', 'Baz') + ->call('setFoo', [ref('foo_with_inline')]); + + $s->set('request', 'Request') + ->synthetic(); + + $s->set('configurator_service', 'ConfClass') + ->private() + ->call('setFoo', [ref('baz')]); + + $s->set('configured_service', 'stdClass') + ->configurator([ref('configurator_service'), 'configureStdClass']); + + $s->set('configurator_service_simple', 'ConfClass') + ->args(['bar']) + ->private(); + + $s->set('configured_service_simple', 'stdClass') + ->configurator([ref('configurator_service_simple'), 'configureStdClass']); + + $s->set('decorated', 'stdClass'); + + $s->set('decorator_service', 'stdClass') + ->decorate('decorated'); + + $s->set('decorator_service_with_name', 'stdClass') + ->decorate('decorated', 'decorated.pif-pouf'); + + $s->set('deprecated_service', 'stdClass') + ->deprecate(); + + $s->set('new_factory', 'FactoryClass') + ->property('foo', 'bar') + ->private(); + + $s->set('factory_service', 'Bar') + ->factory([ref('foo.baz'), 'getInstance']); + + $s->set('new_factory_service', 'FooBarBaz') + ->property('foo', 'bar') + ->factory([ref('new_factory'), 'getInstance']); + + $s->set('service_from_static_method', 'Bar\FooClass') + ->factory(['Bar\FooClass', 'getInstance']); + + $s->set('factory_simple', 'SimpleFactoryClass') + ->deprecate() + ->args(['foo']) + ->private(); + + $s->set('factory_service_simple', 'Bar') + ->factory([ref('factory_simple'), 'getInstance']); + + $s->set('lazy_context', 'LazyContext') + ->args([iterator(['k1' => ref('foo.baz'), 'k2' => ref('service_container')]), iterator([])]); + + $s->set('lazy_context_ignore_invalid_ref', 'LazyContext') + ->args([iterator([ref('foo.baz'), ref('invalid')->ignoreOnInvalid()]), iterator([])]); + + $s->set('tagged_iterator_foo', 'Bar') + ->private() + ->tag('foo'); + + $s->set('tagged_iterator', 'Bar') + ->args([tagged('foo')]); + + $s->alias('alias_for_foo', 'foo')->private()->public(); + $s->alias('alias_for_alias', ref('alias_for_foo')); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/services_autoconfigure_with_parent.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/services_autoconfigure_with_parent.php new file mode 100644 index 00000000..f8ffb1de --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/config/services_autoconfigure_with_parent.php @@ -0,0 +1,9 @@ +services() + ->set('parent_service', \stdClass::class) + ->set('child_service')->parent('parent_service')->autoconfigure(true); +}; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/CustomContainer.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/CustomContainer.php new file mode 100644 index 00000000..22514353 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/CustomContainer.php @@ -0,0 +1,17 @@ + + register('foo', 'FooClass')-> + addArgument(new Reference('bar')) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container11.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container11.php new file mode 100644 index 00000000..91e5c263 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container11.php @@ -0,0 +1,13 @@ + + register('foo', 'FooClass')-> + addArgument(new Definition('BarClass', [new Definition('BazClass')])) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container12.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container12.php new file mode 100644 index 00000000..ef077030 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container12.php @@ -0,0 +1,13 @@ + + register('foo', 'FooClass\\Foo')-> + addArgument('foo<>&bar')-> + addTag('foo"bar\\bar', ['foo' => 'foo"barřž€']) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container13.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container13.php new file mode 100644 index 00000000..df598d4e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container13.php @@ -0,0 +1,18 @@ + + register('foo', 'FooClass')-> + addArgument(new Reference('bar')) + ->setPublic(true) +; +$container-> + register('bar', 'BarClass') + ->setPublic(true) +; +$container->compile(); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php new file mode 100644 index 00000000..191afb8c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container14.php @@ -0,0 +1,17 @@ +register('foo', 'FooClass\\Foo') + ->setDecoratedService('bar', 'bar.woozy') + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container16.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container16.php new file mode 100644 index 00000000..88619ec5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container16.php @@ -0,0 +1,12 @@ +register('foo', 'FooClass\\Foo') + ->setDecoratedService('bar') + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container17.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container17.php new file mode 100644 index 00000000..7f1db676 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container17.php @@ -0,0 +1,11 @@ +register('foo', '%foo.class%') + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container19.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container19.php new file mode 100644 index 00000000..c3af5c96 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container19.php @@ -0,0 +1,27 @@ +setParameter('env(FOO)', 'Bar\FaooClass'); +$container->setParameter('foo', '%env(FOO)%'); + +$container + ->register('service_from_anonymous_factory', '%foo%') + ->setFactory([new Definition('%foo%'), 'getInstance']) + ->setPublic(true) +; + +$anonymousServiceWithFactory = new Definition('Bar\FooClass'); +$anonymousServiceWithFactory->setFactory('Bar\FooClass::getInstance'); +$container + ->register('service_with_method_call_and_factory', 'Bar\FooClass') + ->addMethodCall('setBar', [$anonymousServiceWithFactory]) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container21.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container21.php new file mode 100644 index 00000000..d82cf385 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container21.php @@ -0,0 +1,21 @@ +setConfigurator([new Definition('Baz'), 'configureBar']); + +$fooFactory = new Definition('FooFactory'); +$fooFactory->setFactory([new Definition('Foobar'), 'createFooFactory']); + +$container + ->register('foo', 'Foo') + ->setFactory([$fooFactory, 'createFoo']) + ->setConfigurator([$bar, 'configureFoo']) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container24.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container24.php new file mode 100644 index 00000000..b9d0b91f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container24.php @@ -0,0 +1,13 @@ +register('foo', 'Foo') + ->setAutowired(true) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container33.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container33.php new file mode 100644 index 00000000..673abe20 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container33.php @@ -0,0 +1,12 @@ +register(\Foo\Foo::class)->setPublic(true); +$container->register(\Bar\Foo::class)->setPublic(true); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container8.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container8.php new file mode 100644 index 00000000..edcd045e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container8.php @@ -0,0 +1,25 @@ + '%baz%', + 'baz' => 'bar', + 'bar' => 'foo is %%foo bar', + 'escape' => '@escapeme', + 'values' => [true, false, null, 0, 1000.3, 'true', 'false', 'null'], + 'null string' => 'null', + 'string of digits' => '123', + 'string of digits prefixed with minus character' => '-123', + 'true string' => 'true', + 'false string' => 'false', + 'binary number string' => '0b0110', + 'numeric string' => '-1.2E2', + 'hexadecimal number string' => '0xFF', + 'float string' => '10100.1', + 'positive float string' => '+10100.1', + 'negative float string' => '-10100.1', +])); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container9.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container9.php new file mode 100644 index 00000000..691a7fa6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container9.php @@ -0,0 +1,176 @@ +register('foo', '\Bar\FooClass') + ->addTag('foo', ['foo' => 'foo']) + ->addTag('foo', ['bar' => 'bar', 'baz' => 'baz']) + ->setFactory(['Bar\\FooClass', 'getInstance']) + ->setArguments(['foo', new Reference('foo.baz'), ['%foo%' => 'foo is %foo%', 'foobar' => '%foo%'], true, new Reference('service_container')]) + ->setProperties(['foo' => 'bar', 'moo' => new Reference('foo.baz'), 'qux' => ['%foo%' => 'foo is %foo%', 'foobar' => '%foo%']]) + ->addMethodCall('setBar', [new Reference('bar')]) + ->addMethodCall('initialize') + ->setConfigurator('sc_configure') + ->setPublic(true) +; +$container + ->register('foo.baz', '%baz_class%') + ->setFactory(['%baz_class%', 'getInstance']) + ->setConfigurator(['%baz_class%', 'configureStatic1']) + ->setPublic(true) +; +$container + ->register('bar', 'Bar\FooClass') + ->setArguments(['foo', new Reference('foo.baz'), new Parameter('foo_bar')]) + ->setConfigurator([new Reference('foo.baz'), 'configure']) + ->setPublic(true) +; +$container + ->register('foo_bar', '%foo_class%') + ->addArgument(new Reference('deprecated_service')) + ->setShared(false) + ->setPublic(true) +; +$container->getParameterBag()->clear(); +$container->getParameterBag()->add([ + 'baz_class' => 'BazClass', + 'foo_class' => 'Bar\FooClass', + 'foo' => 'bar', +]); +$container + ->register('method_call1', 'Bar\FooClass') + ->setFile(realpath(__DIR__.'/../includes/foo.php')) + ->addMethodCall('setBar', [new Reference('foo')]) + ->addMethodCall('setBar', [new Reference('foo2', ContainerInterface::NULL_ON_INVALID_REFERENCE)]) + ->addMethodCall('setBar', [new Reference('foo3', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]) + ->addMethodCall('setBar', [new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]) + ->addMethodCall('setBar', [new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')]) + ->setPublic(true) +; +$container + ->register('foo_with_inline', 'Foo') + ->addMethodCall('setBar', [new Reference('inlined')]) + ->setPublic(true) +; +$container + ->register('inlined', 'Bar') + ->setProperty('pub', 'pub') + ->addMethodCall('setBaz', [new Reference('baz')]) + ->setPublic(false) +; +$container + ->register('baz', 'Baz') + ->addMethodCall('setFoo', [new Reference('foo_with_inline')]) + ->setPublic(true) +; +$container + ->register('request', 'Request') + ->setSynthetic(true) + ->setPublic(true) +; +$container + ->register('configurator_service', 'ConfClass') + ->setPublic(false) + ->addMethodCall('setFoo', [new Reference('baz')]) +; +$container + ->register('configured_service', 'stdClass') + ->setConfigurator([new Reference('configurator_service'), 'configureStdClass']) + ->setPublic(true) +; +$container + ->register('configurator_service_simple', 'ConfClass') + ->addArgument('bar') + ->setPublic(false) +; +$container + ->register('configured_service_simple', 'stdClass') + ->setConfigurator([new Reference('configurator_service_simple'), 'configureStdClass']) + ->setPublic(true) +; +$container + ->register('decorated', 'stdClass') + ->setPublic(true) +; +$container + ->register('decorator_service', 'stdClass') + ->setDecoratedService('decorated') + ->setPublic(true) +; +$container + ->register('decorator_service_with_name', 'stdClass') + ->setDecoratedService('decorated', 'decorated.pif-pouf') + ->setPublic(true) +; +$container + ->register('deprecated_service', 'stdClass') + ->setDeprecated(true) + ->setPublic(true) +; +$container + ->register('new_factory', 'FactoryClass') + ->setProperty('foo', 'bar') + ->setPublic(false) +; +$container + ->register('factory_service', 'Bar') + ->setFactory([new Reference('foo.baz'), 'getInstance']) + ->setPublic(true) +; +$container + ->register('new_factory_service', 'FooBarBaz') + ->setProperty('foo', 'bar') + ->setFactory([new Reference('new_factory'), 'getInstance']) + ->setPublic(true) +; +$container + ->register('service_from_static_method', 'Bar\FooClass') + ->setFactory(['Bar\FooClass', 'getInstance']) + ->setPublic(true) +; +$container + ->register('factory_simple', 'SimpleFactoryClass') + ->addArgument('foo') + ->setDeprecated(true) + ->setPublic(false) +; +$container + ->register('factory_service_simple', 'Bar') + ->setFactory([new Reference('factory_simple'), 'getInstance']) + ->setPublic(true) +; +$container + ->register('lazy_context', 'LazyContext') + ->setArguments([new IteratorArgument(['k1' => new Reference('foo.baz'), 'k2' => new Reference('service_container')]), new IteratorArgument([])]) + ->setPublic(true) +; +$container + ->register('lazy_context_ignore_invalid_ref', 'LazyContext') + ->setArguments([new IteratorArgument([new Reference('foo.baz'), new Reference('invalid', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)]), new IteratorArgument([])]) + ->setPublic(true) +; +$container + ->register('tagged_iterator_foo', 'Bar') + ->addTag('foo') + ->setPublic(false) +; +$container + ->register('tagged_iterator', 'Bar') + ->addArgument(new TaggedIteratorArgument('foo')) + ->setPublic(true) +; +$container->setAlias('alias_for_foo', 'foo')->setPublic(true); +$container->setAlias('alias_for_alias', 'alias_for_foo')->setPublic(true); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_abstract.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_abstract.php new file mode 100644 index 00000000..308e2252 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_abstract.php @@ -0,0 +1,13 @@ +register('foo', 'Foo') + ->setAbstract(true) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_almost_circular.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_almost_circular.php new file mode 100644 index 00000000..a1f88539 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_almost_circular.php @@ -0,0 +1,176 @@ +register('foo', FooCircular::class)->setPublic(true) + ->addArgument(new Reference('bar')); + +$container->register('bar', BarCircular::class)->setPublic($public) + ->addMethodCall('addFoobar', [new Reference('foobar')]); + +$container->register('foobar', FoobarCircular::class)->setPublic($public) + ->addArgument(new Reference('foo')); + +// mixed visibility for deps + +$container->register('foo2', FooCircular::class)->setPublic(true) + ->addArgument(new Reference('bar2')); + +$container->register('bar2', BarCircular::class)->setPublic(!$public) + ->addMethodCall('addFoobar', [new Reference('foobar2')]); + +$container->register('foobar2', FoobarCircular::class)->setPublic($public) + ->addArgument(new Reference('foo2')); + +// simple inline setter with internal reference + +$container->register('bar3', BarCircular::class)->setPublic(true) + ->addMethodCall('addFoobar', [new Reference('foobar3'), new Reference('foobar3')]); + +$container->register('foobar3', FoobarCircular::class)->setPublic($public); + +// loop with non-shared dep + +$container->register('foo4', 'stdClass')->setPublic($public) + ->setShared(false) + ->setProperty('foobar', new Reference('foobar4')); + +$container->register('foobar4', 'stdClass')->setPublic(true) + ->addArgument(new Reference('foo4')); + +// loop on the constructor of a setter-injected dep with property + +$container->register('foo5', 'stdClass')->setPublic(true) + ->setProperty('bar', new Reference('bar5')); + +$container->register('bar5', 'stdClass')->setPublic($public) + ->addArgument(new Reference('foo5')) + ->setProperty('foo', new Reference('foo5')); + +// doctrine-like event system + some extra + +$container->register('manager', 'stdClass')->setPublic(true) + ->addArgument(new Reference('connection')); + +$container->register('logger', 'stdClass')->setPublic(true) + ->addArgument(new Reference('connection')) + ->setProperty('handler', (new Definition('stdClass'))->addArgument(new Reference('manager'))) +; +$container->register('connection', 'stdClass')->setPublic(true) + ->addArgument(new Reference('dispatcher')) + ->addArgument(new Reference('config')); + +$container->register('config', 'stdClass')->setPublic(false) + ->setProperty('logger', new Reference('logger')); + +$container->register('dispatcher', 'stdClass')->setPublic($public) + ->setLazy($public) + ->setProperty('subscriber', new Reference('subscriber')); + +$container->register('subscriber', 'stdClass')->setPublic(true) + ->addArgument(new Reference('manager')); + +// doctrine-like event system + some extra (bis) + +$container->register('manager2', 'stdClass')->setPublic(true) + ->addArgument(new Reference('connection2')); + +$container->register('logger2', 'stdClass')->setPublic(false) + ->addArgument(new Reference('connection2')) + ->setProperty('handler2', (new Definition('stdClass'))->addArgument(new Reference('manager2'))) +; +$container->register('connection2', 'stdClass')->setPublic(true) + ->addArgument(new Reference('dispatcher2')) + ->addArgument(new Reference('config2')); + +$container->register('config2', 'stdClass')->setPublic(false) + ->setProperty('logger2', new Reference('logger2')); + +$container->register('dispatcher2', 'stdClass')->setPublic($public) + ->setLazy($public) + ->setProperty('subscriber2', new Reference('subscriber2')); + +$container->register('subscriber2', 'stdClass')->setPublic(false) + ->addArgument(new Reference('manager2')); + +// doctrine-like event system with listener + +$container->register('manager3', 'stdClass') + ->setLazy(true) + ->setPublic(true) + ->addArgument(new Reference('connection3')); + +$container->register('connection3', 'stdClass') + ->setPublic($public) + ->setProperty('listener', [new Reference('listener3')]); + +$container->register('listener3', 'stdClass') + ->setPublic(true) + ->setProperty('manager', new Reference('manager3')); + +// doctrine-like event system with small differences + +$container->register('manager4', 'stdClass') + ->setLazy(true) + ->addArgument(new Reference('connection4')); + +$container->register('connection4', 'stdClass') + ->setPublic($public) + ->setProperty('listener', [new Reference('listener4')]); + +$container->register('listener4', 'stdClass') + ->setPublic(true) + ->addArgument(new Reference('manager4')); + +// private service involved in a loop + +$container->register('foo6', 'stdClass') + ->setPublic(true) + ->setProperty('bar6', new Reference('bar6')); + +$container->register('bar6', 'stdClass') + ->setPublic(false) + ->addArgument(new Reference('foo6')); + +$container->register('baz6', 'stdClass') + ->setPublic(true) + ->setProperty('bar6', new Reference('bar6')); + +// provided by Christian Schiffler + +$container + ->register('root', 'stdClass') + ->setArguments([new Reference('level2'), new Reference('multiuse1')]) + ->setPublic(true); + +$container + ->register('level2', FooForCircularWithAddCalls::class) + ->addMethodCall('call', [new Reference('level3')]); + +$container->register('multiuse1', 'stdClass'); + +$container + ->register('level3', 'stdClass') + ->addArgument(new Reference('level4')); + +$container + ->register('level4', 'stdClass') + ->setArguments([new Reference('multiuse1'), new Reference('level5')]); + +$container + ->register('level5', 'stdClass') + ->addArgument(new Reference('level6')); + +$container + ->register('level6', FooForCircularWithAddCalls::class) + ->addMethodCall('call', [new Reference('level5')]); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_env_in_id.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_env_in_id.php new file mode 100644 index 00000000..1e851cf0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_env_in_id.php @@ -0,0 +1,22 @@ +setParameter('env(BAR)', 'bar'); + +$container->register('foo', 'stdClass')->setPublic(true) + ->addArgument(new Reference('bar_%env(BAR)%')) + ->addArgument(['baz_%env(BAR)%' => new Reference('baz_%env(BAR)%')]); + +$container->register('bar', 'stdClass')->setPublic(true) + ->addArgument(new Reference('bar_%env(BAR)%')); + +$container->register('bar_%env(BAR)%', 'stdClass')->setPublic(false); +$container->register('baz_%env(BAR)%', 'stdClass')->setPublic(false); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_inline_requires.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_inline_requires.php new file mode 100644 index 00000000..3bbfa31f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_inline_requires.php @@ -0,0 +1,19 @@ +register(HotPath\C1::class)->addTag('container.hot_path')->setPublic(true); +$container->register(HotPath\C2::class)->addArgument(new Reference(HotPath\C3::class))->setPublic(true); +$container->register(HotPath\C3::class); +$container->register(ParentNotExists::class)->setPublic(true); + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_uninitialized_ref.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_uninitialized_ref.php new file mode 100644 index 00000000..36c05c3f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/containers/container_uninitialized_ref.php @@ -0,0 +1,49 @@ +register('foo1', 'stdClass') + ->setPublic(true) +; + +$container + ->register('foo2', 'stdClass') + ->setPublic(false) +; + +$container + ->register('foo3', 'stdClass') + ->setPublic(false) +; + +$container + ->register('baz', 'stdClass') + ->setProperty('foo3', new Reference('foo3')) + ->setPublic(true) +; + +$container + ->register('bar', 'stdClass') + ->setProperty('foo1', new Reference('foo1', $container::IGNORE_ON_UNINITIALIZED_REFERENCE)) + ->setProperty('foo2', new Reference('foo2', $container::IGNORE_ON_UNINITIALIZED_REFERENCE)) + ->setProperty('foo3', new Reference('foo3', $container::IGNORE_ON_UNINITIALIZED_REFERENCE)) + ->setProperty('closures', [ + new ServiceClosureArgument(new Reference('foo1', $container::IGNORE_ON_UNINITIALIZED_REFERENCE)), + new ServiceClosureArgument(new Reference('foo2', $container::IGNORE_ON_UNINITIALIZED_REFERENCE)), + new ServiceClosureArgument(new Reference('foo3', $container::IGNORE_ON_UNINITIALIZED_REFERENCE)), + ]) + ->setProperty('iter', new IteratorArgument([ + 'foo1' => new Reference('foo1', $container::IGNORE_ON_UNINITIALIZED_REFERENCE), + 'foo2' => new Reference('foo2', $container::IGNORE_ON_UNINITIALIZED_REFERENCE), + 'foo3' => new Reference('foo3', $container::IGNORE_ON_UNINITIALIZED_REFERENCE), + ])) + ->setPublic(true) +; + +return $container; diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/import/import.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/import/import.yml new file mode 100644 index 00000000..35ec4a04 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/import/import.yml @@ -0,0 +1,2 @@ +imports: + - { resource: ../recurse/ } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/recurse/simple.ini b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/recurse/simple.ini new file mode 100644 index 00000000..0984cdac --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/recurse/simple.ini @@ -0,0 +1,2 @@ +[parameters] + ini = ini diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/recurse/simple.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/recurse/simple.yml new file mode 100644 index 00000000..f98ef12e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/recurse/simple.yml @@ -0,0 +1,2 @@ +parameters: + yaml: yaml diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/simple.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/simple.php new file mode 100644 index 00000000..4750324a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/directory/simple.php @@ -0,0 +1,3 @@ +setParameter('php', 'php'); diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services1.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services1.dot new file mode 100644 index 00000000..e7401080 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services1.dot @@ -0,0 +1,7 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services10-1.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services10-1.dot new file mode 100644 index 00000000..9fdf3410 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services10-1.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="normal" + node [fontsize="13" fontname="Verdana" shape="square"]; + edge [fontsize="12" fontname="Verdana" color="white" arrowhead="closed" arrowsize="1"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=square, fillcolor="grey", style="filled"]; + node_foo [label="foo\nFooClass\n", shape=square, fillcolor="grey", style="filled"]; + node_bar [label="bar\n\n", shape=square, fillcolor="red", style="empty"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services10.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services10.dot new file mode 100644 index 00000000..309388ea --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services10.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_bar [label="bar\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services13.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services13.dot new file mode 100644 index 00000000..fffe8f1b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services13.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_bar [label="bar\nBarClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services14.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services14.dot new file mode 100644 index 00000000..e7401080 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services14.dot @@ -0,0 +1,7 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services17.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services17.dot new file mode 100644 index 00000000..e177fae2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services17.dot @@ -0,0 +1,8 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo\n%foo.class%\n", shape=record, fillcolor="#eeeeee", style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services18.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services18.dot new file mode 100644 index 00000000..4fbcceef --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services18.dot @@ -0,0 +1,8 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_foo [label="foo\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services9.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services9.dot new file mode 100644 index 00000000..6a34c573 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services9.dot @@ -0,0 +1,56 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo (alias_for_foo)\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_baz [label="foo.baz\nBazClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_bar [label="bar\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_bar [label="foo_bar\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"]; + node_method_call1 [label="method_call1\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_request [label="request\nRequest\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_configurator_service [label="configurator_service\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_configured_service [label="configured_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_configurator_service_simple [label="configurator_service_simple\nConfClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_configured_service_simple [label="configured_service_simple\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_decorated [label="decorated\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_decorator_service [label="decorator_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_decorator_service_with_name [label="decorator_service_with_name\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_deprecated_service [label="deprecated_service\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_new_factory [label="new_factory\nFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_new_factory_service [label="new_factory_service\nFooBarBaz\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_service_from_static_method [label="service_from_static_method\nBar\\FooClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_simple [label="factory_simple\nSimpleFactoryClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_factory_service_simple [label="factory_service_simple\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_lazy_context [label="lazy_context\nLazyContext\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_lazy_context_ignore_invalid_ref [label="lazy_context_ignore_invalid_ref\nLazyContext\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_tagged_iterator_foo [label="tagged_iterator_foo\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_tagged_iterator [label="tagged_iterator\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foobaz [label="foobaz\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_invalid [label="invalid\n\n", shape=record, fillcolor="#ff9999", style="filled"]; + node_foo -> node_foo_baz [label="" style="filled"]; + node_foo -> node_service_container [label="" style="filled"]; + node_foo -> node_foo_baz [label="" style="dashed"]; + node_foo -> node_bar [label="setBar()" style="dashed"]; + node_bar -> node_foo_baz [label="" style="filled"]; + node_foo_bar -> node_deprecated_service [label="" style="filled"]; + node_method_call1 -> node_foo [label="setBar()" style="dashed"]; + node_method_call1 -> node_foo2 [label="setBar()" style="dashed"]; + node_method_call1 -> node_foo3 [label="setBar()" style="dashed"]; + node_method_call1 -> node_foobaz [label="setBar()" style="dashed"]; + node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"]; + node_inlined -> node_baz [label="setBaz()" style="dashed"]; + node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"]; + node_configurator_service -> node_baz [label="setFoo()" style="dashed"]; + node_lazy_context -> node_foo_baz [label="" style="filled" color="#9999ff"]; + node_lazy_context -> node_service_container [label="" style="filled" color="#9999ff"]; + node_lazy_context_ignore_invalid_ref -> node_foo_baz [label="" style="filled" color="#9999ff"]; + node_lazy_context_ignore_invalid_ref -> node_invalid [label="" style="filled" color="#9999ff"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services_inline.dot b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services_inline.dot new file mode 100644 index 00000000..b430b186 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/graphviz/services_inline.dot @@ -0,0 +1,10 @@ +digraph sc { + ratio="compress" + node [fontsize="11" fontname="Arial" shape="record"]; + edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; + + node_service_container [label="service_container (Psr\Container\ContainerInterface, Symfony\Component\DependencyInjection\ContainerInterface)\nSymfony\\Component\\DependencyInjection\\ContainerInterface\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo [label="foo\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_bar [label="bar\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_foo -> node_bar [label="" style="filled"]; +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/FooVariadic.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/FooVariadic.php new file mode 100644 index 00000000..12861c56 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/FooVariadic.php @@ -0,0 +1,16 @@ +setParameter('project.configs', $configs); + $configs = array_filter($configs); + + if ($configs) { + $config = call_user_func_array('array_merge', $configs); + } else { + $config = []; + } + + $configuration->setDefinition('project.service.bar', new Definition('FooClass')); + $configuration->setParameter('project.parameter.bar', isset($config['foo']) ? $config['foo'] : 'foobar'); + + $configuration->setDefinition('project.service.foo', new Definition('FooClass')); + $configuration->setParameter('project.parameter.foo', isset($config['foo']) ? $config['foo'] : 'foobar'); + + return $configuration; + } + + public function getXsdValidationBasePath() + { + return false; + } + + public function getNamespace() + { + return 'http://www.example.com/schema/project'; + } + + public function getAlias() + { + return 'project'; + } + + public function getConfiguration(array $config, ContainerBuilder $container) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtension.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtension.php new file mode 100644 index 00000000..2ee2f12d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/ProjectWithXsdExtension.php @@ -0,0 +1,19 @@ += 80000) { + require __DIR__.'/uniontype_classes.php'; +} + +class Foo +{ +} + +class Bar +{ + public function __construct(Foo $foo) + { + } +} + +interface AInterface +{ +} + +class A implements AInterface +{ + public static function create(Foo $foo) + { + } +} + +class B extends A +{ +} + +class C +{ + public function __construct(A $a) + { + } +} + +interface DInterface +{ +} + +interface EInterface extends DInterface +{ +} + +interface IInterface +{ +} + +class I implements IInterface +{ +} + +class F extends I implements EInterface +{ +} + +class G +{ + public function __construct(DInterface $d, EInterface $e, IInterface $i) + { + } +} + +class H +{ + public function __construct(B $b, DInterface $d) + { + } +} + +class D +{ + public function __construct(A $a, DInterface $d) + { + } +} + +class E +{ + public function __construct(D $d = null) + { + } +} + +class J +{ + public function __construct(I $i) + { + } +} + +class K +{ + public function __construct(IInterface $i) + { + } +} + +interface CollisionInterface +{ +} + +class CollisionA implements CollisionInterface +{ +} + +class CollisionB implements CollisionInterface +{ +} + +class CannotBeAutowired +{ + public function __construct(CollisionInterface $collision) + { + } +} + +class Lille +{ +} + +class Dunglas +{ + public function __construct(Lille $l) + { + } +} + +class LesTilleuls +{ + public function __construct(Dunglas $j, Dunglas $k) + { + } +} + +class OptionalParameter +{ + public function __construct(CollisionInterface $c = null, A $a, Foo $f = null) + { + } +} + +class BadTypeHintedArgument +{ + public function __construct(Dunglas $k, NotARealClass $r) + { + } +} +class BadParentTypeHintedArgument +{ + public function __construct(Dunglas $k, OptionalServiceClass $r) + { + } +} +class NotGuessableArgument +{ + public function __construct(Foo $k) + { + } +} +class NotGuessableArgumentForSubclass +{ + public function __construct(A $k) + { + } +} +class MultipleArguments +{ + public function __construct(A $k, $foo, Dunglas $dunglas, array $bar) + { + } +} + +class MultipleArgumentsOptionalScalar +{ + public function __construct(A $a, $foo = 'default_val', Lille $lille = null) + { + } +} +class MultipleArgumentsOptionalScalarLast +{ + public function __construct(A $a, Lille $lille, $foo = 'some_val') + { + } +} + +/* + * Classes used for testing createResourceForClass + */ +class ClassForResource +{ + public function __construct($foo, Bar $bar = null) + { + } + + public function setBar(Bar $bar) + { + } +} +class IdenticalClassResource extends ClassForResource +{ +} + +class ClassChangedConstructorArgs extends ClassForResource +{ + public function __construct($foo, Bar $bar, $baz) + { + } +} + +class SetterInjectionCollision +{ + /** + * @required + */ + public function setMultipleInstancesForOneArg(CollisionInterface $collision) + { + // The CollisionInterface cannot be autowired - there are multiple + + // should throw an exception + } +} + +class SetterInjection extends SetterInjectionParent +{ + /** + * @required + */ + public function setFoo(Foo $foo) + { + // should be called + } + + /** @inheritdoc*/ // <- brackets are missing on purpose + public function setDependencies(Foo $foo, A $a) + { + // should be called + } + + /** {@inheritdoc} */ + public function setWithCallsConfigured(A $a) + { + // this method has a calls configured on it + } + + public function notASetter(A $a) + { + // should be called only when explicitly specified + } + + /** + * @required*/ + public function setChildMethodWithoutDocBlock(A $a) + { + } +} + +class SetterInjectionParent +{ + /** @required*/ + public function setDependencies(Foo $foo, A $a) + { + // should be called + } + + public function notASetter(A $a) + { + // @required should be ignored when the child does not add @inheritdoc + } + + /** @required prefix is on purpose */ + public function setWithCallsConfigured(A $a) + { + } + + /** @required */ + public function setChildMethodWithoutDocBlock(A $a) + { + } +} + +class NotWireable +{ + public function setNotAutowireable(NotARealClass $n) + { + } + + public function setBar() + { + } + + public function setOptionalNotAutowireable(NotARealClass $n = null) + { + } + + public function setDifferentNamespace(\stdClass $n) + { + } + + public function setOptionalNoTypeHint($foo = null) + { + } + + public function setOptionalArgNoAutowireable($other = 'default_val') + { + } + + /** @required */ + protected function setProtectedMethod(A $a) + { + } +} + +class PrivateConstructor +{ + private function __construct() + { + } +} + +class ScalarSetter +{ + /** + * @required + */ + public function setDefaultLocale($defaultLocale) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/classes.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/classes.php new file mode 100644 index 00000000..33b043fa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/classes.php @@ -0,0 +1,136 @@ +configure(); +} + +class BarClass extends BazClass +{ + protected $baz; + public $foo = 'foo'; + + public function setBaz(BazClass $baz) + { + $this->baz = $baz; + } + + public function getBaz() + { + return $this->baz; + } +} + +class BazClass +{ + protected $foo; + + public function setFoo(Foo $foo) + { + $this->foo = $foo; + } + + public function configure($instance) + { + $instance->configure(); + } + + public static function getInstance() + { + return new self(); + } + + public static function configureStatic($instance) + { + $instance->configure(); + } + + public static function configureStatic1() + { + } +} + +class BarUserClass +{ + public $bar; + + public function __construct(BarClass $bar) + { + $this->bar = $bar; + } +} + +class MethodCallClass +{ + public $simple; + public $complex; + private $callPassed = false; + + public function callMe() + { + $this->callPassed = is_scalar($this->simple) && is_object($this->complex); + } + + public function callPassed() + { + return $this->callPassed; + } +} + +class DummyProxyDumper implements ProxyDumper +{ + public function isProxyCandidate(Definition $definition) + { + return $definition->isLazy(); + } + + public function getProxyFactoryCode(Definition $definition, $id, $factoryCall = null) + { + return " // lazy factory for {$definition->getClass()}\n\n"; + } + + public function getProxyCode(Definition $definition) + { + return "// proxy code for {$definition->getClass()}\n"; + } +} + +class LazyContext +{ + public $lazyValues; + public $lazyEmptyValues; + + public function __construct($lazyValues, $lazyEmptyValues) + { + $this->lazyValues = $lazyValues; + $this->lazyEmptyValues = $lazyEmptyValues; + } +} + +class FoobarCircular +{ + public function __construct(FooCircular $foo) + { + $this->foo = $foo; + } +} + +class FooCircular +{ + public function __construct(BarCircular $bar) + { + $this->bar = $bar; + } +} + +class BarCircular +{ + public function addFoobar(FoobarCircular $foobar) + { + $this->foobar = $foobar; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/createphar.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/createphar.php new file mode 100644 index 00000000..c675478f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/createphar.php @@ -0,0 +1,47 @@ +addFromString('ProjectWithXsdExtensionInPhar.php', <<<'EOT' +addFromString('schema/project-1.0.xsd', <<<'EOT' + + + + + + + + + + +EOT +); +$phar->setStub(''); diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/foo.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/foo.php new file mode 100644 index 00000000..20bc928b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/foo.php @@ -0,0 +1,43 @@ +arguments = $arguments; + } + + public static function getInstance($arguments = []) + { + $obj = new self($arguments); + $obj->called = true; + + return $obj; + } + + public function initialize() + { + $this->initialized = true; + } + + public function configure() + { + $this->configured = true; + } + + public function setBar($value = null) + { + $this->bar = $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/schema/project-1.0.xsd b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/schema/project-1.0.xsd new file mode 100644 index 00000000..282884e4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/schema/project-1.0.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/uniontype_classes.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/uniontype_classes.php new file mode 100644 index 00000000..3a0c77c5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/includes/uniontype_classes.php @@ -0,0 +1,24 @@ +parameterBag = null; + + $this->services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php new file mode 100644 index 00000000..9e1abeb4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_with_mandatory_constructor_arguments.php @@ -0,0 +1,55 @@ +services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php new file mode 100644 index 00000000..2fe30f22 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_with_optional_constructor_arguments.php @@ -0,0 +1,58 @@ +parameterBag = null; + + $this->services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_without_constructor.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_without_constructor.php new file mode 100644 index 00000000..c630ad09 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/custom_container_class_without_constructor.php @@ -0,0 +1,55 @@ +services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/php_with_wrong_ext.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/php_with_wrong_ext.yml new file mode 100644 index 00000000..fdd31250 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/php_with_wrong_ext.yml @@ -0,0 +1,3 @@ +setParameter('with_wrong_ext', 'from php'); diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php new file mode 100644 index 00000000..3c0ced8e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1-1.php @@ -0,0 +1,55 @@ +services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1.php new file mode 100644 index 00000000..f7d49dd4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services1.php @@ -0,0 +1,53 @@ +services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services10.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services10.php new file mode 100644 index 00000000..96128299 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services10.php @@ -0,0 +1,157 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->methodMap = [ + 'test' => 'getTestService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'test' shared service. + * + * @return \stdClass + */ + protected function getTestService() + { + return $this->services['test'] = new \stdClass(['only dot' => '.', 'concatenation as value' => '.\'\'.', 'concatenation from the start value' => '\'\'.', '.' => 'dot as a key', '.\'\'.' => 'concatenation as a key', '\'\'.' => 'concatenation from the start key', 'optimize concatenation' => 'string1-string2', 'optimize concatenation with empty string' => 'string1string2', 'optimize concatenation from the start' => 'start', 'optimize concatenation at the end' => 'end', 'new line' => 'string with '."\n".'new line']); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'empty_value' => '', + 'some_string' => '-', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services12.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services12.php new file mode 100644 index 00000000..eb215596 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services12.php @@ -0,0 +1,171 @@ +targetDirs[$i] = $dir = \dirname($dir); + } + $this->parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->methodMap = [ + 'test' => 'getTestService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'test' shared service. + * + * @return \stdClass + */ + protected function getTestService() + { + return $this->services['test'] = new \stdClass(('file://'.$this->targetDirs[1]), [('file://'.$this->targetDirs[1]) => ($this->targetDirs[2].'/')]); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = [ + 'foo' => false, + 'buz' => false, + ]; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + switch ($name) { + case 'foo': $value = ('file://'.$this->targetDirs[1]); break; + case 'buz': $value = $this->targetDirs[2]; break; + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'bar' => __DIR__, + 'baz' => (__DIR__.'/PhpDumperTest.php'), + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services13.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services13.php new file mode 100644 index 00000000..52f5cf25 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services13.php @@ -0,0 +1,70 @@ +services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'foo' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService() + { + $a = new \stdClass(); + $a->add($this); + + return $this->services['bar'] = new \stdClass($a); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services19.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services19.php new file mode 100644 index 00000000..6f6f6045 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services19.php @@ -0,0 +1,181 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->methodMap = [ + 'service_from_anonymous_factory' => 'getServiceFromAnonymousFactoryService', + 'service_with_method_call_and_factory' => 'getServiceWithMethodCallAndFactoryService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'service_from_anonymous_factory' shared service. + * + * @return object A %env(FOO)% instance + */ + protected function getServiceFromAnonymousFactoryService() + { + return $this->services['service_from_anonymous_factory'] = (new ${($_ = $this->getEnv('FOO')) && false ?: "_"}())->getInstance(); + } + + /** + * Gets the public 'service_with_method_call_and_factory' shared service. + * + * @return \Bar\FooClass + */ + protected function getServiceWithMethodCallAndFactoryService() + { + $this->services['service_with_method_call_and_factory'] = $instance = new \Bar\FooClass(); + + $instance->setBar(\Bar\FooClass::getInstance()); + + return $instance; + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = [ + 'foo' => false, + ]; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + switch ($name) { + case 'foo': $value = $this->getEnv('FOO'); break; + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; + } + + private $normalizedParameterNames = [ + 'env(foo)' => 'env(FOO)', + ]; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'env(FOO)' => 'Bar\\FaooClass', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services24.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services24.php new file mode 100644 index 00000000..963118e2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services24.php @@ -0,0 +1,66 @@ +services = []; + $this->methodMap = [ + 'foo' => 'getFooService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'foo' shared autowired service. + * + * @return \Foo + */ + protected function getFooService() + { + return $this->services['foo'] = new \Foo(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services26.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services26.php new file mode 100644 index 00000000..95055207 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services26.php @@ -0,0 +1,194 @@ +targetDirs[$i] = $dir = \dirname($dir); + } + $this->parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'test' => 'getTestService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\Bar + */ + protected function getBarService() + { + return $this->services['bar'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\Bar($this->getEnv('QUZ')); + } + + /** + * Gets the public 'test' shared service. + * + * @return object A %env(FOO)% instance + */ + protected function getTestService() + { + $class = $this->getEnv('FOO'); + + return $this->services['test'] = new $class($this->getEnv('Bar'), 'foo'.$this->getEnv('string:FOO').'baz', $this->getEnv('int:Baz')); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = [ + 'bar' => false, + 'baz' => false, + 'json' => false, + 'db_dsn' => false, + 'env(json_file)' => false, + ]; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + switch ($name) { + case 'bar': $value = $this->getEnv('FOO'); break; + case 'baz': $value = $this->getEnv('int:Baz'); break; + case 'json': $value = $this->getEnv('json:file:json_file'); break; + case 'db_dsn': $value = $this->getEnv('resolve:DB'); break; + case 'env(json_file)': $value = ($this->targetDirs[1].'/array.json'); break; + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; + } + + private $normalizedParameterNames = [ + 'env(foo)' => 'env(FOO)', + 'env(db)' => 'env(DB)', + ]; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'project_dir' => '/foo/bar', + 'env(FOO)' => 'foo', + 'env(DB)' => 'sqlite://%project_dir%/var/data.db', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services33.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services33.php new file mode 100644 index 00000000..915d0537 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services33.php @@ -0,0 +1,81 @@ +services = []; + $this->normalizedIds = [ + 'bar\\foo' => 'Bar\\Foo', + 'foo\\foo' => 'Foo\\Foo', + ]; + $this->methodMap = [ + 'Bar\\Foo' => 'getFooService', + 'Foo\\Foo' => 'getFoo2Service', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'Bar\Foo' shared service. + * + * @return \Bar\Foo + */ + protected function getFooService() + { + return $this->services['Bar\\Foo'] = new \Bar\Foo(); + } + + /** + * Gets the public 'Foo\Foo' shared service. + * + * @return \Foo\Foo + */ + protected function getFoo2Service() + { + return $this->services['Foo\\Foo'] = new \Foo\Foo(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services8.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services8.php new file mode 100644 index 00000000..e7a0214a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services8.php @@ -0,0 +1,167 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'foo' => 'bar', + 'baz' => 'bar', + 'bar' => 'foo is %foo bar', + 'escape' => '@escapeme', + 'values' => [ + 0 => true, + 1 => false, + 2 => NULL, + 3 => 0, + 4 => 1000.3, + 5 => 'true', + 6 => 'false', + 7 => 'null', + ], + 'null string' => 'null', + 'string of digits' => '123', + 'string of digits prefixed with minus character' => '-123', + 'true string' => 'true', + 'false string' => 'false', + 'binary number string' => '0b0110', + 'numeric string' => '-1.2E2', + 'hexadecimal number string' => '0xFF', + 'float string' => '10100.1', + 'positive float string' => '+10100.1', + 'negative float string' => '-10100.1', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9.php new file mode 100644 index 00000000..6dd0baab --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9.php @@ -0,0 +1,443 @@ +getDefaultParameters())); + $this->normalizedIds = [ + 'psr\\container\\containerinterface' => 'Psr\\Container\\ContainerInterface', + 'symfony\\component\\dependencyinjection\\containerinterface' => 'Symfony\\Component\\DependencyInjection\\ContainerInterface', + ]; + $this->syntheticIds = [ + 'request' => true, + ]; + $this->methodMap = [ + 'bar' => 'getBarService', + 'baz' => 'getBazService', + 'configurator_service' => 'getConfiguratorServiceService', + 'configurator_service_simple' => 'getConfiguratorServiceSimpleService', + 'configured_service' => 'getConfiguredServiceService', + 'configured_service_simple' => 'getConfiguredServiceSimpleService', + 'decorated' => 'getDecoratedService', + 'decorator_service' => 'getDecoratorServiceService', + 'decorator_service_with_name' => 'getDecoratorServiceWithNameService', + 'deprecated_service' => 'getDeprecatedServiceService', + 'factory_service' => 'getFactoryServiceService', + 'factory_service_simple' => 'getFactoryServiceSimpleService', + 'factory_simple' => 'getFactorySimpleService', + 'foo' => 'getFooService', + 'foo.baz' => 'getFoo_BazService', + 'foo_bar' => 'getFooBarService', + 'foo_with_inline' => 'getFooWithInlineService', + 'inlined' => 'getInlinedService', + 'lazy_context' => 'getLazyContextService', + 'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService', + 'method_call1' => 'getMethodCall1Service', + 'new_factory' => 'getNewFactoryService', + 'new_factory_service' => 'getNewFactoryServiceService', + 'service_from_static_method' => 'getServiceFromStaticMethodService', + 'tagged_iterator' => 'getTaggedIteratorService', + 'tagged_iterator_foo' => 'getTaggedIteratorFooService', + ]; + $this->privates = [ + 'configurator_service' => true, + 'configurator_service_simple' => true, + 'factory_simple' => true, + 'inlined' => true, + 'new_factory' => true, + 'tagged_iterator_foo' => true, + ]; + $this->aliases = [ + 'Psr\\Container\\ContainerInterface' => 'service_container', + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => 'service_container', + 'alias_for_alias' => 'foo', + 'alias_for_foo' => 'foo', + ]; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \Bar\FooClass + */ + protected function getBarService() + { + $a = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + + $this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar')); + + $a->configure($instance); + + return $instance; + } + + /** + * Gets the public 'baz' shared service. + * + * @return \Baz + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \Baz(); + + $instance->setFoo(${($_ = isset($this->services['foo_with_inline']) ? $this->services['foo_with_inline'] : $this->getFooWithInlineService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'configured_service' shared service. + * + * @return \stdClass + */ + protected function getConfiguredServiceService() + { + $this->services['configured_service'] = $instance = new \stdClass(); + + ${($_ = isset($this->services['configurator_service']) ? $this->services['configurator_service'] : $this->getConfiguratorServiceService()) && false ?: '_'}->configureStdClass($instance); + + return $instance; + } + + /** + * Gets the public 'configured_service_simple' shared service. + * + * @return \stdClass + */ + protected function getConfiguredServiceSimpleService() + { + $this->services['configured_service_simple'] = $instance = new \stdClass(); + + ${($_ = isset($this->services['configurator_service_simple']) ? $this->services['configurator_service_simple'] : ($this->services['configurator_service_simple'] = new \ConfClass('bar'))) && false ?: '_'}->configureStdClass($instance); + + return $instance; + } + + /** + * Gets the public 'decorated' shared service. + * + * @return \stdClass + */ + protected function getDecoratedService() + { + return $this->services['decorated'] = new \stdClass(); + } + + /** + * Gets the public 'decorator_service' shared service. + * + * @return \stdClass + */ + protected function getDecoratorServiceService() + { + return $this->services['decorator_service'] = new \stdClass(); + } + + /** + * Gets the public 'decorator_service_with_name' shared service. + * + * @return \stdClass + */ + protected function getDecoratorServiceWithNameService() + { + return $this->services['decorator_service_with_name'] = new \stdClass(); + } + + /** + * Gets the public 'deprecated_service' shared service. + * + * @return \stdClass + * + * @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed. + */ + protected function getDeprecatedServiceService() + { + @trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED); + + return $this->services['deprecated_service'] = new \stdClass(); + } + + /** + * Gets the public 'factory_service' shared service. + * + * @return \Bar + */ + protected function getFactoryServiceService() + { + return $this->services['factory_service'] = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}->getInstance(); + } + + /** + * Gets the public 'factory_service_simple' shared service. + * + * @return \Bar + */ + protected function getFactoryServiceSimpleService() + { + return $this->services['factory_service_simple'] = ${($_ = isset($this->services['factory_simple']) ? $this->services['factory_simple'] : $this->getFactorySimpleService()) && false ?: '_'}->getInstance(); + } + + /** + * Gets the public 'foo' shared service. + * + * @return \Bar\FooClass + */ + protected function getFooService() + { + $a = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + + $this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, [$this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')], true, $this); + + $instance->foo = 'bar'; + $instance->moo = $a; + $instance->qux = [$this->getParameter('foo') => 'foo is '.$this->getParameter('foo').'', 'foobar' => $this->getParameter('foo')]; + $instance->setBar(${($_ = isset($this->services['bar']) ? $this->services['bar'] : $this->getBarService()) && false ?: '_'}); + $instance->initialize(); + sc_configure($instance); + + return $instance; + } + + /** + * Gets the public 'foo.baz' shared service. + * + * @return object A %baz_class% instance + */ + protected function getFoo_BazService() + { + $this->services['foo.baz'] = $instance = \call_user_func([$this->getParameter('baz_class'), 'getInstance']); + + \call_user_func([$this->getParameter('baz_class'), 'configureStatic1'], $instance); + + return $instance; + } + + /** + * Gets the public 'foo_bar' service. + * + * @return object A %foo_class% instance + */ + protected function getFooBarService() + { + $class = $this->getParameter('foo_class'); + + return new $class(${($_ = isset($this->services['deprecated_service']) ? $this->services['deprecated_service'] : $this->getDeprecatedServiceService()) && false ?: '_'}); + } + + /** + * Gets the public 'foo_with_inline' shared service. + * + * @return \Foo + */ + protected function getFooWithInlineService() + { + $this->services['foo_with_inline'] = $instance = new \Foo(); + + $instance->setBar(${($_ = isset($this->services['inlined']) ? $this->services['inlined'] : $this->getInlinedService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'lazy_context' shared service. + * + * @return \LazyContext + */ + protected function getLazyContextService() + { + return $this->services['lazy_context'] = new \LazyContext(new RewindableGenerator(function () { + yield 'k1' => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + yield 'k2' => $this; + }, 2), new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)); + } + + /** + * Gets the public 'lazy_context_ignore_invalid_ref' shared service. + * + * @return \LazyContext + */ + protected function getLazyContextIgnoreInvalidRefService() + { + return $this->services['lazy_context_ignore_invalid_ref'] = new \LazyContext(new RewindableGenerator(function () { + yield 0 => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + if ($this->has('invalid')) { + yield 1 => ${($_ = isset($this->services['invalid']) ? $this->services['invalid'] : $this->get('invalid', /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ 2)) && false ?: '_'}; + } + }, function () { + return 1 + (int) ($this->has('invalid')); + }), new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)); + } + + /** + * Gets the public 'method_call1' shared service. + * + * @return \Bar\FooClass + */ + protected function getMethodCall1Service() + { + include_once '%path%foo.php'; + + $this->services['method_call1'] = $instance = new \Bar\FooClass(); + + $instance->setBar(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}); + $instance->setBar(${($_ = isset($this->services['foo2']) ? $this->services['foo2'] : $this->get('foo2', /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ 2)) && false ?: '_'}); + if ($this->has('foo3')) { + $instance->setBar(${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : $this->get('foo3', /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ 2)) && false ?: '_'}); + } + if ($this->has('foobaz')) { + $instance->setBar(${($_ = isset($this->services['foobaz']) ? $this->services['foobaz'] : $this->get('foobaz', /* ContainerInterface::NULL_ON_INVALID_REFERENCE */ 2)) && false ?: '_'}); + } + $instance->setBar((${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); + + return $instance; + } + + /** + * Gets the public 'new_factory_service' shared service. + * + * @return \FooBarBaz + */ + protected function getNewFactoryServiceService() + { + $this->services['new_factory_service'] = $instance = ${($_ = isset($this->services['new_factory']) ? $this->services['new_factory'] : $this->getNewFactoryService()) && false ?: '_'}->getInstance(); + + $instance->foo = 'bar'; + + return $instance; + } + + /** + * Gets the public 'service_from_static_method' shared service. + * + * @return \Bar\FooClass + */ + protected function getServiceFromStaticMethodService() + { + return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance(); + } + + /** + * Gets the public 'tagged_iterator' shared service. + * + * @return \Bar + */ + protected function getTaggedIteratorService() + { + return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)); + } + + /** + * Gets the private 'configurator_service' shared service. + * + * @return \ConfClass + */ + protected function getConfiguratorServiceService() + { + $this->services['configurator_service'] = $instance = new \ConfClass(); + + $instance->setFoo(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the private 'configurator_service_simple' shared service. + * + * @return \ConfClass + */ + protected function getConfiguratorServiceSimpleService() + { + return $this->services['configurator_service_simple'] = new \ConfClass('bar'); + } + + /** + * Gets the private 'factory_simple' shared service. + * + * @return \SimpleFactoryClass + * + * @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed. + */ + protected function getFactorySimpleService() + { + @trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED); + + return $this->services['factory_simple'] = new \SimpleFactoryClass('foo'); + } + + /** + * Gets the private 'inlined' shared service. + * + * @return \Bar + */ + protected function getInlinedService() + { + $this->services['inlined'] = $instance = new \Bar(); + + $instance->pub = 'pub'; + $instance->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the private 'new_factory' shared service. + * + * @return \FactoryClass + */ + protected function getNewFactoryService() + { + $this->services['new_factory'] = $instance = new \FactoryClass(); + + $instance->foo = 'bar'; + + return $instance; + } + + /** + * Gets the private 'tagged_iterator_foo' shared service. + * + * @return \Bar + */ + protected function getTaggedIteratorFooService() + { + return $this->services['tagged_iterator_foo'] = new \Bar(); + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'baz_class' => 'BazClass', + 'foo_class' => 'Bar\\FooClass', + 'foo' => 'bar', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9_as_files.txt b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9_as_files.txt new file mode 100644 index 00000000..ab7024fa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9_as_files.txt @@ -0,0 +1,508 @@ +Array +( + [Container%s/removed-ids.php] => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'configurator_service' => true, + 'configurator_service_simple' => true, + 'decorated.pif-pouf' => true, + 'decorator_service.inner' => true, + 'factory_simple' => true, + 'inlined' => true, + 'new_factory' => true, + 'tagged_iterator_foo' => true, +]; + + [Container%s/getBazService.php] => services['baz'] = $instance = new \Baz(); + +$instance->setFoo(${($_ = isset($this->services['foo_with_inline']) ? $this->services['foo_with_inline'] : $this->load('getFooWithInlineService.php')) && false ?: '_'}); + +return $instance; + + [Container%s/getConfiguredServiceService.php] => services['configured_service'] = $instance = new \stdClass(); + +$a = new \ConfClass(); +$a->setFoo(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->load('getBazService.php')) && false ?: '_'}); + +$a->configureStdClass($instance); + +return $instance; + + [Container%s/getConfiguredServiceSimpleService.php] => services['configured_service_simple'] = $instance = new \stdClass(); + +(new \ConfClass('bar'))->configureStdClass($instance); + +return $instance; + + [Container%s/getDecoratorServiceService.php] => services['decorator_service'] = new \stdClass(); + + [Container%s/getDecoratorServiceWithNameService.php] => services['decorator_service_with_name'] = new \stdClass(); + + [Container%s/getDeprecatedServiceService.php] => services['deprecated_service'] = new \stdClass(); + + [Container%s/getFactoryServiceService.php] => services['factory_service'] = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->load('getFoo_BazService.php')) && false ?: '_'}->getInstance(); + + [Container%s/getFactoryServiceSimpleService.php] => services['factory_service_simple'] = ${($_ = isset($this->services['factory_simple']) ? $this->services['factory_simple'] : $this->load('getFactorySimpleService.php')) && false ?: '_'}->getInstance(); + + [Container%s/getFactorySimpleService.php] => services['factory_simple'] = new \SimpleFactoryClass('foo'); + + [Container%s/getFooService.php] => services['foo.baz']) ? $this->services['foo.baz'] : $this->load('getFoo_BazService.php')) && false ?: '_'}; + +$this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, ['bar' => 'foo is bar', 'foobar' => 'bar'], true, $this); + +$instance->foo = 'bar'; +$instance->moo = $a; +$instance->qux = ['bar' => 'foo is bar', 'foobar' => 'bar']; +$instance->setBar(${($_ = isset($this->services['bar']) ? $this->services['bar'] : $this->getBarService()) && false ?: '_'}); +$instance->initialize(); +sc_configure($instance); + +return $instance; + + [Container%s/getFoo_BazService.php] => services['foo.baz'] = $instance = \BazClass::getInstance(); + +\BazClass::configureStatic1($instance); + +return $instance; + + [Container%s/getFooWithInlineService.php] => services['foo_with_inline'] = $instance = new \Foo(); + +$a = new \Bar(); +$a->pub = 'pub'; +$a->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->load('getBazService.php')) && false ?: '_'}); + +$instance->setBar($a); + +return $instance; + + [Container%s/getLazyContextService.php] => services['lazy_context'] = new \LazyContext(new RewindableGenerator(function () { + yield 'k1' => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->load('getFoo_BazService.php')) && false ?: '_'}; + yield 'k2' => $this; +}, 2), new RewindableGenerator(function () { + return new \EmptyIterator(); +}, 0)); + + [Container%s/getLazyContextIgnoreInvalidRefService.php] => services['lazy_context_ignore_invalid_ref'] = new \LazyContext(new RewindableGenerator(function () { + yield 0 => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->load('getFoo_BazService.php')) && false ?: '_'}; +}, 1), new RewindableGenerator(function () { + return new \EmptyIterator(); +}, 0)); + + [Container%s/getMethodCall1Service.php] => targetDirs[0].'/Fixtures/includes/foo.php'); + +$this->services['method_call1'] = $instance = new \Bar\FooClass(); + +$instance->setBar(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->load('getFooService.php')) && false ?: '_'}); +$instance->setBar(NULL); +$instance->setBar((${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->load('getFooService.php')) && false ?: '_'}->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); + +return $instance; + + [Container%s/getNewFactoryServiceService.php] => foo = 'bar'; + +$this->services['new_factory_service'] = $instance = $a->getInstance(); + +$instance->foo = 'bar'; + +return $instance; + + [Container%s/getServiceFromStaticMethodService.php] => services['service_from_static_method'] = \Bar\FooClass::getInstance(); + + [Container%s/getTaggedIteratorService.php] => services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () { + yield 0 => ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->load('getFooService.php')) && false ?: '_'}; + yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : ($this->services['tagged_iterator_foo'] = new \Bar())) && false ?: '_'}; +}, 2)); + + [Container%s/getTaggedIteratorFooService.php] => services['tagged_iterator_foo'] = new \Bar(); + + [Container%s/ProjectServiceContainer.php] => targetDirs[0] = \dirname($containerDir); + for ($i = 1; $i <= 5; ++$i) { + $this->targetDirs[$i] = $dir = \dirname($dir); + } + $this->buildParameters = $buildParameters; + $this->containerDir = $containerDir; + $this->parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->syntheticIds = [ + 'request' => true, + ]; + $this->methodMap = [ + 'bar' => 'getBarService', + 'foo_bar' => 'getFooBarService', + ]; + $this->fileMap = [ + 'baz' => 'getBazService.php', + 'configured_service' => 'getConfiguredServiceService.php', + 'configured_service_simple' => 'getConfiguredServiceSimpleService.php', + 'decorator_service' => 'getDecoratorServiceService.php', + 'decorator_service_with_name' => 'getDecoratorServiceWithNameService.php', + 'deprecated_service' => 'getDeprecatedServiceService.php', + 'factory_service' => 'getFactoryServiceService.php', + 'factory_service_simple' => 'getFactoryServiceSimpleService.php', + 'factory_simple' => 'getFactorySimpleService.php', + 'foo' => 'getFooService.php', + 'foo.baz' => 'getFoo_BazService.php', + 'foo_with_inline' => 'getFooWithInlineService.php', + 'lazy_context' => 'getLazyContextService.php', + 'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService.php', + 'method_call1' => 'getMethodCall1Service.php', + 'new_factory_service' => 'getNewFactoryServiceService.php', + 'service_from_static_method' => 'getServiceFromStaticMethodService.php', + 'tagged_iterator' => 'getTaggedIteratorService.php', + 'tagged_iterator_foo' => 'getTaggedIteratorFooService.php', + ]; + $this->privates = [ + 'factory_simple' => true, + 'tagged_iterator_foo' => true, + ]; + $this->aliases = [ + 'alias_for_alias' => 'foo', + 'alias_for_foo' => 'foo', + 'decorated' => 'decorator_service_with_name', + ]; + } + + public function getRemovedIds() + { + return require $this->containerDir.\DIRECTORY_SEPARATOR.'removed-ids.php'; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + protected function load($file, $lazyLoad = true) + { + return require $this->containerDir.\DIRECTORY_SEPARATOR.$file; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \Bar\FooClass + */ + protected function getBarService() + { + $a = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->load('getFoo_BazService.php')) && false ?: '_'}; + + $this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar')); + + $a->configure($instance); + + return $instance; + } + + /** + * Gets the public 'foo_bar' service. + * + * @return \Bar\FooClass + */ + protected function getFooBarService() + { + return new \Bar\FooClass(${($_ = isset($this->services['deprecated_service']) ? $this->services['deprecated_service'] : $this->load('getDeprecatedServiceService.php')) && false ?: '_'}); + } + + public function getParameter($name) + { + $name = (string) $name; + if (isset($this->buildParameters[$name])) { + return $this->buildParameters[$name]; + } + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + if (isset($this->buildParameters[$name])) { + return true; + } + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + foreach ($this->buildParameters as $name => $value) { + $parameters[$name] = $value; + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'baz_class' => 'BazClass', + 'foo_class' => 'Bar\\FooClass', + 'foo' => 'bar', + ]; + } +} + + [ProjectServiceContainer.php] => '%s', + 'container.build_id' => '%s', + 'container.build_time' => %d, +], __DIR__.\DIRECTORY_SEPARATOR.'Container%s'); + +) diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9_compiled.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9_compiled.php new file mode 100644 index 00000000..c9df13b2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services9_compiled.php @@ -0,0 +1,475 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->syntheticIds = [ + 'request' => true, + ]; + $this->methodMap = [ + 'bar' => 'getBarService', + 'baz' => 'getBazService', + 'configured_service' => 'getConfiguredServiceService', + 'configured_service_simple' => 'getConfiguredServiceSimpleService', + 'decorator_service' => 'getDecoratorServiceService', + 'decorator_service_with_name' => 'getDecoratorServiceWithNameService', + 'deprecated_service' => 'getDeprecatedServiceService', + 'factory_service' => 'getFactoryServiceService', + 'factory_service_simple' => 'getFactoryServiceSimpleService', + 'factory_simple' => 'getFactorySimpleService', + 'foo' => 'getFooService', + 'foo.baz' => 'getFoo_BazService', + 'foo_bar' => 'getFooBarService', + 'foo_with_inline' => 'getFooWithInlineService', + 'lazy_context' => 'getLazyContextService', + 'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService', + 'method_call1' => 'getMethodCall1Service', + 'new_factory_service' => 'getNewFactoryServiceService', + 'service_from_static_method' => 'getServiceFromStaticMethodService', + 'tagged_iterator' => 'getTaggedIteratorService', + 'tagged_iterator_foo' => 'getTaggedIteratorFooService', + ]; + $this->privates = [ + 'factory_simple' => true, + 'tagged_iterator_foo' => true, + ]; + $this->aliases = [ + 'alias_for_alias' => 'foo', + 'alias_for_foo' => 'foo', + 'decorated' => 'decorator_service_with_name', + ]; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'configurator_service' => true, + 'configurator_service_simple' => true, + 'decorated.pif-pouf' => true, + 'decorator_service.inner' => true, + 'factory_simple' => true, + 'inlined' => true, + 'new_factory' => true, + 'tagged_iterator_foo' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \Bar\FooClass + */ + protected function getBarService() + { + $a = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + + $this->services['bar'] = $instance = new \Bar\FooClass('foo', $a, $this->getParameter('foo_bar')); + + $a->configure($instance); + + return $instance; + } + + /** + * Gets the public 'baz' shared service. + * + * @return \Baz + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \Baz(); + + $instance->setFoo(${($_ = isset($this->services['foo_with_inline']) ? $this->services['foo_with_inline'] : $this->getFooWithInlineService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'configured_service' shared service. + * + * @return \stdClass + */ + protected function getConfiguredServiceService() + { + $this->services['configured_service'] = $instance = new \stdClass(); + + $a = new \ConfClass(); + $a->setFoo(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'}); + + $a->configureStdClass($instance); + + return $instance; + } + + /** + * Gets the public 'configured_service_simple' shared service. + * + * @return \stdClass + */ + protected function getConfiguredServiceSimpleService() + { + $this->services['configured_service_simple'] = $instance = new \stdClass(); + + (new \ConfClass('bar'))->configureStdClass($instance); + + return $instance; + } + + /** + * Gets the public 'decorator_service' shared service. + * + * @return \stdClass + */ + protected function getDecoratorServiceService() + { + return $this->services['decorator_service'] = new \stdClass(); + } + + /** + * Gets the public 'decorator_service_with_name' shared service. + * + * @return \stdClass + */ + protected function getDecoratorServiceWithNameService() + { + return $this->services['decorator_service_with_name'] = new \stdClass(); + } + + /** + * Gets the public 'deprecated_service' shared service. + * + * @return \stdClass + * + * @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed. + */ + protected function getDeprecatedServiceService() + { + @trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED); + + return $this->services['deprecated_service'] = new \stdClass(); + } + + /** + * Gets the public 'factory_service' shared service. + * + * @return \Bar + */ + protected function getFactoryServiceService() + { + return $this->services['factory_service'] = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}->getInstance(); + } + + /** + * Gets the public 'factory_service_simple' shared service. + * + * @return \Bar + */ + protected function getFactoryServiceSimpleService() + { + return $this->services['factory_service_simple'] = ${($_ = isset($this->services['factory_simple']) ? $this->services['factory_simple'] : $this->getFactorySimpleService()) && false ?: '_'}->getInstance(); + } + + /** + * Gets the public 'foo' shared service. + * + * @return \Bar\FooClass + */ + protected function getFooService() + { + $a = ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + + $this->services['foo'] = $instance = \Bar\FooClass::getInstance('foo', $a, ['bar' => 'foo is bar', 'foobar' => 'bar'], true, $this); + + $instance->foo = 'bar'; + $instance->moo = $a; + $instance->qux = ['bar' => 'foo is bar', 'foobar' => 'bar']; + $instance->setBar(${($_ = isset($this->services['bar']) ? $this->services['bar'] : $this->getBarService()) && false ?: '_'}); + $instance->initialize(); + sc_configure($instance); + + return $instance; + } + + /** + * Gets the public 'foo.baz' shared service. + * + * @return \BazClass + */ + protected function getFoo_BazService() + { + $this->services['foo.baz'] = $instance = \BazClass::getInstance(); + + \BazClass::configureStatic1($instance); + + return $instance; + } + + /** + * Gets the public 'foo_bar' service. + * + * @return \Bar\FooClass + */ + protected function getFooBarService() + { + return new \Bar\FooClass(${($_ = isset($this->services['deprecated_service']) ? $this->services['deprecated_service'] : $this->getDeprecatedServiceService()) && false ?: '_'}); + } + + /** + * Gets the public 'foo_with_inline' shared service. + * + * @return \Foo + */ + protected function getFooWithInlineService() + { + $this->services['foo_with_inline'] = $instance = new \Foo(); + + $a = new \Bar(); + $a->pub = 'pub'; + $a->setBaz(${($_ = isset($this->services['baz']) ? $this->services['baz'] : $this->getBazService()) && false ?: '_'}); + + $instance->setBar($a); + + return $instance; + } + + /** + * Gets the public 'lazy_context' shared service. + * + * @return \LazyContext + */ + protected function getLazyContextService() + { + return $this->services['lazy_context'] = new \LazyContext(new RewindableGenerator(function () { + yield 'k1' => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + yield 'k2' => $this; + }, 2), new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)); + } + + /** + * Gets the public 'lazy_context_ignore_invalid_ref' shared service. + * + * @return \LazyContext + */ + protected function getLazyContextIgnoreInvalidRefService() + { + return $this->services['lazy_context_ignore_invalid_ref'] = new \LazyContext(new RewindableGenerator(function () { + yield 0 => ${($_ = isset($this->services['foo.baz']) ? $this->services['foo.baz'] : $this->getFoo_BazService()) && false ?: '_'}; + }, 1), new RewindableGenerator(function () { + return new \EmptyIterator(); + }, 0)); + } + + /** + * Gets the public 'method_call1' shared service. + * + * @return \Bar\FooClass + */ + protected function getMethodCall1Service() + { + include_once '%path%foo.php'; + + $this->services['method_call1'] = $instance = new \Bar\FooClass(); + + $instance->setBar(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}); + $instance->setBar(NULL); + $instance->setBar((${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}->foo() . (($this->hasParameter("foo")) ? ($this->getParameter("foo")) : ("default")))); + + return $instance; + } + + /** + * Gets the public 'new_factory_service' shared service. + * + * @return \FooBarBaz + */ + protected function getNewFactoryServiceService() + { + $a = new \FactoryClass(); + $a->foo = 'bar'; + + $this->services['new_factory_service'] = $instance = $a->getInstance(); + + $instance->foo = 'bar'; + + return $instance; + } + + /** + * Gets the public 'service_from_static_method' shared service. + * + * @return \Bar\FooClass + */ + protected function getServiceFromStaticMethodService() + { + return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance(); + } + + /** + * Gets the public 'tagged_iterator' shared service. + * + * @return \Bar + */ + protected function getTaggedIteratorService() + { + return $this->services['tagged_iterator'] = new \Bar(new RewindableGenerator(function () { + yield 0 => ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}; + yield 1 => ${($_ = isset($this->services['tagged_iterator_foo']) ? $this->services['tagged_iterator_foo'] : ($this->services['tagged_iterator_foo'] = new \Bar())) && false ?: '_'}; + }, 2)); + } + + /** + * Gets the private 'factory_simple' shared service. + * + * @return \SimpleFactoryClass + * + * @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed. + */ + protected function getFactorySimpleService() + { + @trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED); + + return $this->services['factory_simple'] = new \SimpleFactoryClass('foo'); + } + + /** + * Gets the private 'tagged_iterator_foo' shared service. + * + * @return \Bar + */ + protected function getTaggedIteratorFooService() + { + return $this->services['tagged_iterator_foo'] = new \Bar(); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'baz_class' => 'BazClass', + 'foo_class' => 'Bar\\FooClass', + 'foo' => 'bar', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_adawson.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_adawson.php new file mode 100644 index 00000000..f4364df7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_adawson.php @@ -0,0 +1,190 @@ +services = []; + $this->normalizedIds = [ + 'app\\bus' => 'App\\Bus', + 'app\\db' => 'App\\Db', + 'app\\handler1' => 'App\\Handler1', + 'app\\handler2' => 'App\\Handler2', + 'app\\processor' => 'App\\Processor', + 'app\\registry' => 'App\\Registry', + 'app\\schema' => 'App\\Schema', + ]; + $this->methodMap = [ + 'App\\Bus' => 'getBusService', + 'App\\Db' => 'getDbService', + 'App\\Handler1' => 'getHandler1Service', + 'App\\Handler2' => 'getHandler2Service', + 'App\\Processor' => 'getProcessorService', + 'App\\Registry' => 'getRegistryService', + 'App\\Schema' => 'getSchemaService', + ]; + $this->privates = [ + 'App\\Handler1' => true, + 'App\\Handler2' => true, + 'App\\Processor' => true, + 'App\\Registry' => true, + 'App\\Schema' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'App\\Handler1' => true, + 'App\\Handler2' => true, + 'App\\Processor' => true, + 'App\\Registry' => true, + 'App\\Schema' => true, + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'App\Bus' shared service. + * + * @return \App\Bus + */ + protected function getBusService() + { + $this->services['App\\Bus'] = $instance = new \App\Bus(${($_ = isset($this->services['App\\Db']) ? $this->services['App\\Db'] : $this->getDbService()) && false ?: '_'}); + + $instance->handler1 = ${($_ = isset($this->services['App\\Handler1']) ? $this->services['App\\Handler1'] : $this->getHandler1Service()) && false ?: '_'}; + $instance->handler2 = ${($_ = isset($this->services['App\\Handler2']) ? $this->services['App\\Handler2'] : $this->getHandler2Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'App\Db' shared service. + * + * @return \App\Db + */ + protected function getDbService() + { + $this->services['App\\Db'] = $instance = new \App\Db(); + + $instance->schema = ${($_ = isset($this->services['App\\Schema']) ? $this->services['App\\Schema'] : $this->getSchemaService()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the private 'App\Handler1' shared service. + * + * @return \App\Handler1 + */ + protected function getHandler1Service() + { + $a = ${($_ = isset($this->services['App\\Processor']) ? $this->services['App\\Processor'] : $this->getProcessorService()) && false ?: '_'}; + + if (isset($this->services['App\\Handler1'])) { + return $this->services['App\\Handler1']; + } + + return $this->services['App\\Handler1'] = new \App\Handler1(${($_ = isset($this->services['App\\Db']) ? $this->services['App\\Db'] : $this->getDbService()) && false ?: '_'}, ${($_ = isset($this->services['App\\Schema']) ? $this->services['App\\Schema'] : $this->getSchemaService()) && false ?: '_'}, $a); + } + + /** + * Gets the private 'App\Handler2' shared service. + * + * @return \App\Handler2 + */ + protected function getHandler2Service() + { + $a = ${($_ = isset($this->services['App\\Processor']) ? $this->services['App\\Processor'] : $this->getProcessorService()) && false ?: '_'}; + + if (isset($this->services['App\\Handler2'])) { + return $this->services['App\\Handler2']; + } + + return $this->services['App\\Handler2'] = new \App\Handler2(${($_ = isset($this->services['App\\Db']) ? $this->services['App\\Db'] : $this->getDbService()) && false ?: '_'}, ${($_ = isset($this->services['App\\Schema']) ? $this->services['App\\Schema'] : $this->getSchemaService()) && false ?: '_'}, $a); + } + + /** + * Gets the private 'App\Processor' shared service. + * + * @return \App\Processor + */ + protected function getProcessorService() + { + $a = ${($_ = isset($this->services['App\\Registry']) ? $this->services['App\\Registry'] : $this->getRegistryService()) && false ?: '_'}; + + if (isset($this->services['App\\Processor'])) { + return $this->services['App\\Processor']; + } + + return $this->services['App\\Processor'] = new \App\Processor($a, ${($_ = isset($this->services['App\\Db']) ? $this->services['App\\Db'] : $this->getDbService()) && false ?: '_'}); + } + + /** + * Gets the private 'App\Registry' shared service. + * + * @return \App\Registry + */ + protected function getRegistryService() + { + $this->services['App\\Registry'] = $instance = new \App\Registry(); + + $instance->processor = [0 => ${($_ = isset($this->services['App\\Db']) ? $this->services['App\\Db'] : $this->getDbService()) && false ?: '_'}, 1 => ${($_ = isset($this->services['App\\Bus']) ? $this->services['App\\Bus'] : $this->getBusService()) && false ?: '_'}]; + + return $instance; + } + + /** + * Gets the private 'App\Schema' shared service. + * + * @return \App\Schema + */ + protected function getSchemaService() + { + $a = ${($_ = isset($this->services['App\\Db']) ? $this->services['App\\Db'] : $this->getDbService()) && false ?: '_'}; + + if (isset($this->services['App\\Schema'])) { + return $this->services['App\\Schema']; + } + + return $this->services['App\\Schema'] = new \App\Schema($a); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_almost_circular_private.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_almost_circular_private.php new file mode 100644 index 00000000..775235db --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_almost_circular_private.php @@ -0,0 +1,514 @@ +services = []; + $this->methodMap = [ + 'bar2' => 'getBar2Service', + 'bar3' => 'getBar3Service', + 'bar6' => 'getBar6Service', + 'baz6' => 'getBaz6Service', + 'connection' => 'getConnectionService', + 'connection2' => 'getConnection2Service', + 'foo' => 'getFooService', + 'foo2' => 'getFoo2Service', + 'foo5' => 'getFoo5Service', + 'foo6' => 'getFoo6Service', + 'foobar4' => 'getFoobar4Service', + 'level2' => 'getLevel2Service', + 'level3' => 'getLevel3Service', + 'level4' => 'getLevel4Service', + 'level5' => 'getLevel5Service', + 'level6' => 'getLevel6Service', + 'listener3' => 'getListener3Service', + 'listener4' => 'getListener4Service', + 'logger' => 'getLoggerService', + 'manager' => 'getManagerService', + 'manager2' => 'getManager2Service', + 'manager3' => 'getManager3Service', + 'manager4' => 'getManager4Service', + 'multiuse1' => 'getMultiuse1Service', + 'root' => 'getRootService', + 'subscriber' => 'getSubscriberService', + ]; + $this->privates = [ + 'bar6' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, + 'manager4' => true, + 'multiuse1' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'bar' => true, + 'bar5' => true, + 'bar6' => true, + 'config' => true, + 'config2' => true, + 'connection3' => true, + 'connection4' => true, + 'dispatcher' => true, + 'dispatcher2' => true, + 'foo4' => true, + 'foobar' => true, + 'foobar2' => true, + 'foobar3' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, + 'logger2' => true, + 'manager4' => true, + 'multiuse1' => true, + 'subscriber2' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar2' shared service. + * + * @return \BarCircular + */ + protected function getBar2Service() + { + $this->services['bar2'] = $instance = new \BarCircular(); + + $instance->addFoobar(new \FoobarCircular(${($_ = isset($this->services['foo2']) ? $this->services['foo2'] : $this->getFoo2Service()) && false ?: '_'})); + + return $instance; + } + + /** + * Gets the public 'bar3' shared service. + * + * @return \BarCircular + */ + protected function getBar3Service() + { + $this->services['bar3'] = $instance = new \BarCircular(); + + $a = new \FoobarCircular(); + + $instance->addFoobar($a, $a); + + return $instance; + } + + /** + * Gets the public 'baz6' shared service. + * + * @return \stdClass + */ + protected function getBaz6Service() + { + $this->services['baz6'] = $instance = new \stdClass(); + + $instance->bar6 = ${($_ = isset($this->services['bar6']) ? $this->services['bar6'] : $this->getBar6Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'connection' shared service. + * + * @return \stdClass + */ + protected function getConnectionService() + { + $a = new \stdClass(); + + $b = new \stdClass(); + + $this->services['connection'] = $instance = new \stdClass($a, $b); + + $b->logger = ${($_ = isset($this->services['logger']) ? $this->services['logger'] : $this->getLoggerService()) && false ?: '_'}; + + $a->subscriber = ${($_ = isset($this->services['subscriber']) ? $this->services['subscriber'] : $this->getSubscriberService()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'connection2' shared service. + * + * @return \stdClass + */ + protected function getConnection2Service() + { + $a = new \stdClass(); + + $b = new \stdClass(); + + $this->services['connection2'] = $instance = new \stdClass($a, $b); + + $c = new \stdClass($instance); + + $d = ${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'}; + + $c->handler2 = new \stdClass($d); + + $b->logger2 = $c; + + $a->subscriber2 = new \stdClass($d); + + return $instance; + } + + /** + * Gets the public 'foo' shared service. + * + * @return \FooCircular + */ + protected function getFooService() + { + $a = new \BarCircular(); + + $this->services['foo'] = $instance = new \FooCircular($a); + + $a->addFoobar(new \FoobarCircular($instance)); + + return $instance; + } + + /** + * Gets the public 'foo2' shared service. + * + * @return \FooCircular + */ + protected function getFoo2Service() + { + $a = ${($_ = isset($this->services['bar2']) ? $this->services['bar2'] : $this->getBar2Service()) && false ?: '_'}; + + if (isset($this->services['foo2'])) { + return $this->services['foo2']; + } + + return $this->services['foo2'] = new \FooCircular($a); + } + + /** + * Gets the public 'foo5' shared service. + * + * @return \stdClass + */ + protected function getFoo5Service() + { + $this->services['foo5'] = $instance = new \stdClass(); + + $a = new \stdClass($instance); + $a->foo = $instance; + + $instance->bar = $a; + + return $instance; + } + + /** + * Gets the public 'foo6' shared service. + * + * @return \stdClass + */ + protected function getFoo6Service() + { + $this->services['foo6'] = $instance = new \stdClass(); + + $instance->bar6 = ${($_ = isset($this->services['bar6']) ? $this->services['bar6'] : $this->getBar6Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'foobar4' shared service. + * + * @return \stdClass + */ + protected function getFoobar4Service() + { + $a = new \stdClass(); + + $this->services['foobar4'] = $instance = new \stdClass($a); + + $a->foobar = $instance; + + return $instance; + } + + /** + * Gets the public 'listener3' shared service. + * + * @return \stdClass + */ + protected function getListener3Service() + { + $this->services['listener3'] = $instance = new \stdClass(); + + $instance->manager = ${($_ = isset($this->services['manager3']) ? $this->services['manager3'] : $this->getManager3Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'listener4' shared service. + * + * @return \stdClass + */ + protected function getListener4Service() + { + $a = ${($_ = isset($this->services['manager4']) ? $this->services['manager4'] : $this->getManager4Service()) && false ?: '_'}; + + if (isset($this->services['listener4'])) { + return $this->services['listener4']; + } + + return $this->services['listener4'] = new \stdClass($a); + } + + /** + * Gets the public 'logger' shared service. + * + * @return \stdClass + */ + protected function getLoggerService() + { + $a = ${($_ = isset($this->services['connection']) ? $this->services['connection'] : $this->getConnectionService()) && false ?: '_'}; + + if (isset($this->services['logger'])) { + return $this->services['logger']; + } + + $this->services['logger'] = $instance = new \stdClass($a); + + $instance->handler = new \stdClass(${($_ = isset($this->services['manager']) ? $this->services['manager'] : $this->getManagerService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'manager' shared service. + * + * @return \stdClass + */ + protected function getManagerService() + { + $a = ${($_ = isset($this->services['connection']) ? $this->services['connection'] : $this->getConnectionService()) && false ?: '_'}; + + if (isset($this->services['manager'])) { + return $this->services['manager']; + } + + return $this->services['manager'] = new \stdClass($a); + } + + /** + * Gets the public 'manager2' shared service. + * + * @return \stdClass + */ + protected function getManager2Service() + { + $a = ${($_ = isset($this->services['connection2']) ? $this->services['connection2'] : $this->getConnection2Service()) && false ?: '_'}; + + if (isset($this->services['manager2'])) { + return $this->services['manager2']; + } + + return $this->services['manager2'] = new \stdClass($a); + } + + /** + * Gets the public 'manager3' shared service. + * + * @return \stdClass + */ + protected function getManager3Service($lazyLoad = true) + { + $a = ${($_ = isset($this->services['listener3']) ? $this->services['listener3'] : $this->getListener3Service()) && false ?: '_'}; + + if (isset($this->services['manager3'])) { + return $this->services['manager3']; + } + $b = new \stdClass(); + $b->listener = [0 => $a]; + + return $this->services['manager3'] = new \stdClass($b); + } + + /** + * Gets the public 'root' shared service. + * + * @return \stdClass + */ + protected function getRootService() + { + return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the public 'subscriber' shared service. + * + * @return \stdClass + */ + protected function getSubscriberService() + { + $a = ${($_ = isset($this->services['manager']) ? $this->services['manager'] : $this->getManagerService()) && false ?: '_'}; + + if (isset($this->services['subscriber'])) { + return $this->services['subscriber']; + } + + return $this->services['subscriber'] = new \stdClass($a); + } + + /** + * Gets the private 'bar6' shared service. + * + * @return \stdClass + */ + protected function getBar6Service() + { + $a = ${($_ = isset($this->services['foo6']) ? $this->services['foo6'] : $this->getFoo6Service()) && false ?: '_'}; + + if (isset($this->services['bar6'])) { + return $this->services['bar6']; + } + + return $this->services['bar6'] = new \stdClass($a); + } + + /** + * Gets the private 'level2' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls + */ + protected function getLevel2Service() + { + $this->services['level2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $instance->call(${($_ = isset($this->services['level3']) ? $this->services['level3'] : $this->getLevel3Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the private 'level3' shared service. + * + * @return \stdClass + */ + protected function getLevel3Service() + { + return $this->services['level3'] = new \stdClass(${($_ = isset($this->services['level4']) ? $this->services['level4'] : $this->getLevel4Service()) && false ?: '_'}); + } + + /** + * Gets the private 'level4' shared service. + * + * @return \stdClass + */ + protected function getLevel4Service() + { + return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); + } + + /** + * Gets the private 'level5' shared service. + * + * @return \stdClass + */ + protected function getLevel5Service() + { + $a = ${($_ = isset($this->services['level6']) ? $this->services['level6'] : $this->getLevel6Service()) && false ?: '_'}; + + if (isset($this->services['level5'])) { + return $this->services['level5']; + } + + return $this->services['level5'] = new \stdClass($a); + } + + /** + * Gets the private 'level6' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls + */ + protected function getLevel6Service() + { + $this->services['level6'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $instance->call(${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the private 'manager4' shared service. + * + * @return \stdClass + */ + protected function getManager4Service($lazyLoad = true) + { + $a = new \stdClass(); + + $this->services['manager4'] = $instance = new \stdClass($a); + + $a->listener = [0 => ${($_ = isset($this->services['listener4']) ? $this->services['listener4'] : $this->getListener4Service()) && false ?: '_'}]; + + return $instance; + } + + /** + * Gets the private 'multiuse1' shared service. + * + * @return \stdClass + */ + protected function getMultiuse1Service() + { + return $this->services['multiuse1'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_almost_circular_public.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_almost_circular_public.php new file mode 100644 index 00000000..d3bab912 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_almost_circular_public.php @@ -0,0 +1,640 @@ +services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'bar3' => 'getBar3Service', + 'bar5' => 'getBar5Service', + 'bar6' => 'getBar6Service', + 'baz6' => 'getBaz6Service', + 'connection' => 'getConnectionService', + 'connection2' => 'getConnection2Service', + 'connection3' => 'getConnection3Service', + 'connection4' => 'getConnection4Service', + 'dispatcher' => 'getDispatcherService', + 'dispatcher2' => 'getDispatcher2Service', + 'foo' => 'getFooService', + 'foo2' => 'getFoo2Service', + 'foo4' => 'getFoo4Service', + 'foo5' => 'getFoo5Service', + 'foo6' => 'getFoo6Service', + 'foobar' => 'getFoobarService', + 'foobar2' => 'getFoobar2Service', + 'foobar3' => 'getFoobar3Service', + 'foobar4' => 'getFoobar4Service', + 'level2' => 'getLevel2Service', + 'level3' => 'getLevel3Service', + 'level4' => 'getLevel4Service', + 'level5' => 'getLevel5Service', + 'level6' => 'getLevel6Service', + 'listener3' => 'getListener3Service', + 'listener4' => 'getListener4Service', + 'logger' => 'getLoggerService', + 'manager' => 'getManagerService', + 'manager2' => 'getManager2Service', + 'manager3' => 'getManager3Service', + 'manager4' => 'getManager4Service', + 'multiuse1' => 'getMultiuse1Service', + 'root' => 'getRootService', + 'subscriber' => 'getSubscriberService', + ]; + $this->privates = [ + 'bar6' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, + 'manager4' => true, + 'multiuse1' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'bar2' => true, + 'bar6' => true, + 'config' => true, + 'config2' => true, + 'level2' => true, + 'level3' => true, + 'level4' => true, + 'level5' => true, + 'level6' => true, + 'logger2' => true, + 'manager4' => true, + 'multiuse1' => true, + 'subscriber2' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \BarCircular + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \BarCircular(); + + $instance->addFoobar(${($_ = isset($this->services['foobar']) ? $this->services['foobar'] : $this->getFoobarService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'bar3' shared service. + * + * @return \BarCircular + */ + protected function getBar3Service() + { + $this->services['bar3'] = $instance = new \BarCircular(); + + $a = ${($_ = isset($this->services['foobar3']) ? $this->services['foobar3'] : ($this->services['foobar3'] = new \FoobarCircular())) && false ?: '_'}; + + $instance->addFoobar($a, $a); + + return $instance; + } + + /** + * Gets the public 'bar5' shared service. + * + * @return \stdClass + */ + protected function getBar5Service() + { + $a = ${($_ = isset($this->services['foo5']) ? $this->services['foo5'] : $this->getFoo5Service()) && false ?: '_'}; + + if (isset($this->services['bar5'])) { + return $this->services['bar5']; + } + + $this->services['bar5'] = $instance = new \stdClass($a); + + $instance->foo = $a; + + return $instance; + } + + /** + * Gets the public 'baz6' shared service. + * + * @return \stdClass + */ + protected function getBaz6Service() + { + $this->services['baz6'] = $instance = new \stdClass(); + + $instance->bar6 = ${($_ = isset($this->services['bar6']) ? $this->services['bar6'] : $this->getBar6Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'connection' shared service. + * + * @return \stdClass + */ + protected function getConnectionService() + { + $a = ${($_ = isset($this->services['dispatcher']) ? $this->services['dispatcher'] : $this->getDispatcherService()) && false ?: '_'}; + + if (isset($this->services['connection'])) { + return $this->services['connection']; + } + $b = new \stdClass(); + + $this->services['connection'] = $instance = new \stdClass($a, $b); + + $b->logger = ${($_ = isset($this->services['logger']) ? $this->services['logger'] : $this->getLoggerService()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'connection2' shared service. + * + * @return \stdClass + */ + protected function getConnection2Service() + { + $a = ${($_ = isset($this->services['dispatcher2']) ? $this->services['dispatcher2'] : $this->getDispatcher2Service()) && false ?: '_'}; + + if (isset($this->services['connection2'])) { + return $this->services['connection2']; + } + $b = new \stdClass(); + + $this->services['connection2'] = $instance = new \stdClass($a, $b); + + $c = new \stdClass($instance); + $c->handler2 = new \stdClass(${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'}); + + $b->logger2 = $c; + + return $instance; + } + + /** + * Gets the public 'connection3' shared service. + * + * @return \stdClass + */ + protected function getConnection3Service() + { + $this->services['connection3'] = $instance = new \stdClass(); + + $instance->listener = [0 => ${($_ = isset($this->services['listener3']) ? $this->services['listener3'] : $this->getListener3Service()) && false ?: '_'}]; + + return $instance; + } + + /** + * Gets the public 'connection4' shared service. + * + * @return \stdClass + */ + protected function getConnection4Service() + { + $this->services['connection4'] = $instance = new \stdClass(); + + $instance->listener = [0 => ${($_ = isset($this->services['listener4']) ? $this->services['listener4'] : $this->getListener4Service()) && false ?: '_'}]; + + return $instance; + } + + /** + * Gets the public 'dispatcher' shared service. + * + * @return \stdClass + */ + protected function getDispatcherService($lazyLoad = true) + { + $this->services['dispatcher'] = $instance = new \stdClass(); + + $instance->subscriber = ${($_ = isset($this->services['subscriber']) ? $this->services['subscriber'] : $this->getSubscriberService()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'dispatcher2' shared service. + * + * @return \stdClass + */ + protected function getDispatcher2Service($lazyLoad = true) + { + $this->services['dispatcher2'] = $instance = new \stdClass(); + + $instance->subscriber2 = new \stdClass(${($_ = isset($this->services['manager2']) ? $this->services['manager2'] : $this->getManager2Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'foo' shared service. + * + * @return \FooCircular + */ + protected function getFooService() + { + $a = ${($_ = isset($this->services['bar']) ? $this->services['bar'] : $this->getBarService()) && false ?: '_'}; + + if (isset($this->services['foo'])) { + return $this->services['foo']; + } + + return $this->services['foo'] = new \FooCircular($a); + } + + /** + * Gets the public 'foo2' shared service. + * + * @return \FooCircular + */ + protected function getFoo2Service() + { + $a = new \BarCircular(); + + $this->services['foo2'] = $instance = new \FooCircular($a); + + $a->addFoobar(${($_ = isset($this->services['foobar2']) ? $this->services['foobar2'] : $this->getFoobar2Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'foo4' service. + * + * @return \stdClass + */ + protected function getFoo4Service() + { + $instance = new \stdClass(); + + $instance->foobar = ${($_ = isset($this->services['foobar4']) ? $this->services['foobar4'] : $this->getFoobar4Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'foo5' shared service. + * + * @return \stdClass + */ + protected function getFoo5Service() + { + $this->services['foo5'] = $instance = new \stdClass(); + + $instance->bar = ${($_ = isset($this->services['bar5']) ? $this->services['bar5'] : $this->getBar5Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'foo6' shared service. + * + * @return \stdClass + */ + protected function getFoo6Service() + { + $this->services['foo6'] = $instance = new \stdClass(); + + $instance->bar6 = ${($_ = isset($this->services['bar6']) ? $this->services['bar6'] : $this->getBar6Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'foobar' shared service. + * + * @return \FoobarCircular + */ + protected function getFoobarService() + { + $a = ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}; + + if (isset($this->services['foobar'])) { + return $this->services['foobar']; + } + + return $this->services['foobar'] = new \FoobarCircular($a); + } + + /** + * Gets the public 'foobar2' shared service. + * + * @return \FoobarCircular + */ + protected function getFoobar2Service() + { + $a = ${($_ = isset($this->services['foo2']) ? $this->services['foo2'] : $this->getFoo2Service()) && false ?: '_'}; + + if (isset($this->services['foobar2'])) { + return $this->services['foobar2']; + } + + return $this->services['foobar2'] = new \FoobarCircular($a); + } + + /** + * Gets the public 'foobar3' shared service. + * + * @return \FoobarCircular + */ + protected function getFoobar3Service() + { + return $this->services['foobar3'] = new \FoobarCircular(); + } + + /** + * Gets the public 'foobar4' shared service. + * + * @return \stdClass + */ + protected function getFoobar4Service() + { + $a = new \stdClass(); + + $this->services['foobar4'] = $instance = new \stdClass($a); + + $a->foobar = $instance; + + return $instance; + } + + /** + * Gets the public 'listener3' shared service. + * + * @return \stdClass + */ + protected function getListener3Service() + { + $this->services['listener3'] = $instance = new \stdClass(); + + $instance->manager = ${($_ = isset($this->services['manager3']) ? $this->services['manager3'] : $this->getManager3Service()) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'listener4' shared service. + * + * @return \stdClass + */ + protected function getListener4Service() + { + $a = ${($_ = isset($this->services['manager4']) ? $this->services['manager4'] : $this->getManager4Service()) && false ?: '_'}; + + if (isset($this->services['listener4'])) { + return $this->services['listener4']; + } + + return $this->services['listener4'] = new \stdClass($a); + } + + /** + * Gets the public 'logger' shared service. + * + * @return \stdClass + */ + protected function getLoggerService() + { + $a = ${($_ = isset($this->services['connection']) ? $this->services['connection'] : $this->getConnectionService()) && false ?: '_'}; + + if (isset($this->services['logger'])) { + return $this->services['logger']; + } + + $this->services['logger'] = $instance = new \stdClass($a); + + $instance->handler = new \stdClass(${($_ = isset($this->services['manager']) ? $this->services['manager'] : $this->getManagerService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'manager' shared service. + * + * @return \stdClass + */ + protected function getManagerService() + { + $a = ${($_ = isset($this->services['connection']) ? $this->services['connection'] : $this->getConnectionService()) && false ?: '_'}; + + if (isset($this->services['manager'])) { + return $this->services['manager']; + } + + return $this->services['manager'] = new \stdClass($a); + } + + /** + * Gets the public 'manager2' shared service. + * + * @return \stdClass + */ + protected function getManager2Service() + { + $a = ${($_ = isset($this->services['connection2']) ? $this->services['connection2'] : $this->getConnection2Service()) && false ?: '_'}; + + if (isset($this->services['manager2'])) { + return $this->services['manager2']; + } + + return $this->services['manager2'] = new \stdClass($a); + } + + /** + * Gets the public 'manager3' shared service. + * + * @return \stdClass + */ + protected function getManager3Service($lazyLoad = true) + { + $a = ${($_ = isset($this->services['connection3']) ? $this->services['connection3'] : $this->getConnection3Service()) && false ?: '_'}; + + if (isset($this->services['manager3'])) { + return $this->services['manager3']; + } + + return $this->services['manager3'] = new \stdClass($a); + } + + /** + * Gets the public 'root' shared service. + * + * @return \stdClass + */ + protected function getRootService() + { + return $this->services['root'] = new \stdClass(${($_ = isset($this->services['level2']) ? $this->services['level2'] : $this->getLevel2Service()) && false ?: '_'}, ${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the public 'subscriber' shared service. + * + * @return \stdClass + */ + protected function getSubscriberService() + { + $a = ${($_ = isset($this->services['manager']) ? $this->services['manager'] : $this->getManagerService()) && false ?: '_'}; + + if (isset($this->services['subscriber'])) { + return $this->services['subscriber']; + } + + return $this->services['subscriber'] = new \stdClass($a); + } + + /** + * Gets the private 'bar6' shared service. + * + * @return \stdClass + */ + protected function getBar6Service() + { + $a = ${($_ = isset($this->services['foo6']) ? $this->services['foo6'] : $this->getFoo6Service()) && false ?: '_'}; + + if (isset($this->services['bar6'])) { + return $this->services['bar6']; + } + + return $this->services['bar6'] = new \stdClass($a); + } + + /** + * Gets the private 'level2' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls + */ + protected function getLevel2Service() + { + $this->services['level2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $instance->call(${($_ = isset($this->services['level3']) ? $this->services['level3'] : $this->getLevel3Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the private 'level3' shared service. + * + * @return \stdClass + */ + protected function getLevel3Service() + { + return $this->services['level3'] = new \stdClass(${($_ = isset($this->services['level4']) ? $this->services['level4'] : $this->getLevel4Service()) && false ?: '_'}); + } + + /** + * Gets the private 'level4' shared service. + * + * @return \stdClass + */ + protected function getLevel4Service() + { + return $this->services['level4'] = new \stdClass(${($_ = isset($this->services['multiuse1']) ? $this->services['multiuse1'] : ($this->services['multiuse1'] = new \stdClass())) && false ?: '_'}, ${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); + } + + /** + * Gets the private 'level5' shared service. + * + * @return \stdClass + */ + protected function getLevel5Service() + { + $a = ${($_ = isset($this->services['level6']) ? $this->services['level6'] : $this->getLevel6Service()) && false ?: '_'}; + + if (isset($this->services['level5'])) { + return $this->services['level5']; + } + + return $this->services['level5'] = new \stdClass($a); + } + + /** + * Gets the private 'level6' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls + */ + protected function getLevel6Service() + { + $this->services['level6'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\FooForCircularWithAddCalls(); + + $instance->call(${($_ = isset($this->services['level5']) ? $this->services['level5'] : $this->getLevel5Service()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the private 'manager4' shared service. + * + * @return \stdClass + */ + protected function getManager4Service($lazyLoad = true) + { + $a = ${($_ = isset($this->services['connection4']) ? $this->services['connection4'] : $this->getConnection4Service()) && false ?: '_'}; + + if (isset($this->services['manager4'])) { + return $this->services['manager4']; + } + + return $this->services['manager4'] = new \stdClass($a); + } + + /** + * Gets the private 'multiuse1' shared service. + * + * @return \stdClass + */ + protected function getMultiuse1Service() + { + return $this->services['multiuse1'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_array_params.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_array_params.php new file mode 100644 index 00000000..dd1ca0a6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_array_params.php @@ -0,0 +1,176 @@ +targetDirs[$i] = $dir = \dirname($dir); + } + $this->parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \BarClass + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \BarClass(); + + $instance->setBaz($this->parameters['array_1'], $this->getParameter('array_2'), '%array_1%', $this->parameters['array_1']); + + return $instance; + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = [ + 'array_2' => false, + ]; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + switch ($name) { + case 'array_2': $value = [ + 0 => ($this->targetDirs[2].'/Dumper'), + ]; break; + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'array_1' => [ + 0 => 123, + ], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_base64_env.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_base64_env.php new file mode 100644 index 00000000..709a3c4f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_base64_env.php @@ -0,0 +1,151 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = [ + 'hello' => false, + ]; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + switch ($name) { + case 'hello': $value = $this->getEnv('base64:foo'); break; + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'env(foo)' => 'd29ybGQ=', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_dedup_lazy_proxy.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_dedup_lazy_proxy.php new file mode 100644 index 00000000..096b3b39 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_dedup_lazy_proxy.php @@ -0,0 +1,88 @@ +services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'foo' => 'getFooService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + protected function createProxy($class, \Closure $factory) + { + return $factory(); + } + + /** + * Gets the public 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService($lazyLoad = true) + { + // lazy factory for stdClass + + return new \stdClass(); + } + + /** + * Gets the public 'foo' shared service. + * + * @return \stdClass + */ + protected function getFooService($lazyLoad = true) + { + // lazy factory for stdClass + + return new \stdClass(); + } +} + +// proxy code for stdClass diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_deep_graph.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_deep_graph.php new file mode 100644 index 00000000..0e3eed27 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_deep_graph.php @@ -0,0 +1,93 @@ +services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'foo' => 'getFooService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \stdClass(); + + $instance->p5 = new \stdClass(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}); + + return $instance; + } + + /** + * Gets the public 'foo' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Dumper\FooForDeepGraph + */ + protected function getFooService() + { + $a = ${($_ = isset($this->services['bar']) ? $this->services['bar'] : $this->getBarService()) && false ?: '_'}; + + if (isset($this->services['foo'])) { + return $this->services['foo']; + } + $b = new \stdClass(); + + $c = new \stdClass(); + $c->p3 = new \stdClass(); + + $b->p2 = $c; + + return $this->services['foo'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\FooForDeepGraph($a, $b); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_env_in_id.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_env_in_id.php new file mode 100644 index 00000000..e0e4827d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_env_in_id.php @@ -0,0 +1,188 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->normalizedIds = [ + 'bar_%env(bar)%' => 'bar_%env(BAR)%', + ]; + $this->methodMap = [ + 'bar' => 'getBarService', + 'bar_%env(BAR)%' => 'getBarenvBARService', + 'foo' => 'getFooService', + ]; + $this->privates = [ + 'bar_%env(BAR)%' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'bar_%env(BAR)%' => true, + 'baz_%env(BAR)%' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService() + { + return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : ($this->services['bar_%env(BAR)%'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the public 'foo' shared service. + * + * @return \stdClass + */ + protected function getFooService() + { + return $this->services['foo'] = new \stdClass(${($_ = isset($this->services['bar_%env(BAR)%']) ? $this->services['bar_%env(BAR)%'] : ($this->services['bar_%env(BAR)%'] = new \stdClass())) && false ?: '_'}, ['baz_'.$this->getEnv('string:BAR') => new \stdClass()]); + } + + /** + * Gets the private 'bar_%env(BAR)%' shared service. + * + * @return \stdClass + */ + protected function getBarenvBARService() + { + return $this->services['bar_%env(BAR)%'] = new \stdClass(); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = [ + 'env(bar)' => 'env(BAR)', + ]; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'env(BAR)' => 'bar', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_inline_requires.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_inline_requires.php new file mode 100644 index 00000000..84187883 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_inline_requires.php @@ -0,0 +1,215 @@ +targetDirs[$i] = $dir = \dirname($dir); + } + $this->parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->normalizedIds = [ + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\includes\\hotpath\\c1' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C1', + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\includes\\hotpath\\c2' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2', + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\includes\\hotpath\\c3' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3', + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\parentnotexists' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\ParentNotExists', + ]; + $this->methodMap = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\ParentNotExists' => 'getParentNotExistsService', + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C1' => 'getC1Service', + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2' => 'getC2Service', + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3' => 'getC3Service', + ]; + $this->privates = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3' => true, + ]; + + $this->aliases = []; + + $this->privates['service_container'] = function () { + include_once $this->targetDirs[1].'/includes/HotPath/I1.php'; + include_once $this->targetDirs[1].'/includes/HotPath/P1.php'; + include_once $this->targetDirs[1].'/includes/HotPath/T1.php'; + include_once $this->targetDirs[1].'/includes/HotPath/C1.php'; + }; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists + */ + protected function getParentNotExistsService() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\ParentNotExists'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists(); + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1 + */ + protected function getC1Service() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C1'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C1(); + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2 + */ + protected function getC2Service() + { + include_once $this->targetDirs[1].'/includes/HotPath/C2.php'; + include_once $this->targetDirs[1].'/includes/HotPath/C3.php'; + + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C2'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C2(${($_ = isset($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3']) ? $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3'] : ($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3())) && false ?: '_'}); + } + + /** + * Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3 + */ + protected function getC3Service() + { + include_once $this->targetDirs[1].'/includes/HotPath/C3.php'; + + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\includes\\HotPath\\C3'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\includes\HotPath\C3(); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'inline_requires' => true, + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_inline_self_ref.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_inline_self_ref.php new file mode 100644 index 00000000..906b0cdc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_inline_self_ref.php @@ -0,0 +1,78 @@ +services = []; + $this->normalizedIds = [ + 'app\\foo' => 'App\\Foo', + ]; + $this->methodMap = [ + 'App\\Foo' => 'getFooService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'App\Foo' shared service. + * + * @return \App\Foo + */ + protected function getFooService() + { + $a = new \App\Bar(); + + $b = new \App\Baz($a); + $b->bar = $a; + + $this->services['App\\Foo'] = $instance = new \App\Foo($b); + + $a->foo = $instance; + + return $instance; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_legacy_privates.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_legacy_privates.php new file mode 100644 index 00000000..9a060617 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_legacy_privates.php @@ -0,0 +1,193 @@ +targetDirs[$i] = $dir = \dirname($dir); + } + $this->services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'private' => 'getPrivateService', + 'private_alias' => 'getPrivateAliasService', + 'private_alias_decorator' => 'getPrivateAliasDecoratorService', + 'private_child' => 'getPrivateChildService', + 'private_decorator' => 'getPrivateDecoratorService', + 'private_not_inlined' => 'getPrivateNotInlinedService', + 'private_not_removed' => 'getPrivateNotRemovedService', + 'private_parent' => 'getPrivateParentService', + 'public_child' => 'getPublicChildService', + ]; + $this->privates = [ + 'decorated_private' => true, + 'decorated_private_alias' => true, + 'private' => true, + 'private_alias' => true, + 'private_child' => true, + 'private_not_inlined' => true, + 'private_not_removed' => true, + 'private_parent' => true, + ]; + $this->aliases = [ + 'alias_to_private' => 'private', + 'decorated_private' => 'private_decorator', + 'decorated_private_alias' => 'private_alias_decorator', + ]; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'decorated_private' => true, + 'decorated_private_alias' => true, + 'foo' => true, + 'private' => true, + 'private_alias' => true, + 'private_alias_decorator.inner' => true, + 'private_child' => true, + 'private_decorator.inner' => true, + 'private_not_inlined' => true, + 'private_not_removed' => true, + 'private_parent' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService() + { + return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['private_not_inlined']) ? $this->services['private_not_inlined'] : ($this->services['private_not_inlined'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the public 'private_alias_decorator' shared service. + * + * @return \stdClass + */ + protected function getPrivateAliasDecoratorService() + { + return $this->services['private_alias_decorator'] = new \stdClass(); + } + + /** + * Gets the public 'private_decorator' shared service. + * + * @return \stdClass + */ + protected function getPrivateDecoratorService() + { + return $this->services['private_decorator'] = new \stdClass(); + } + + /** + * Gets the public 'public_child' shared service. + * + * @return \stdClass + */ + protected function getPublicChildService() + { + return $this->services['public_child'] = new \stdClass(); + } + + /** + * Gets the private 'private' shared service. + * + * @return \stdClass + */ + protected function getPrivateService() + { + return $this->services['private'] = new \stdClass(); + } + + /** + * Gets the private 'private_alias' shared service. + * + * @return \stdClass + */ + protected function getPrivateAliasService() + { + return $this->services['private_alias'] = new \stdClass(); + } + + /** + * Gets the private 'private_child' shared service. + * + * @return \stdClass + */ + protected function getPrivateChildService() + { + return $this->services['private_child'] = new \stdClass(); + } + + /** + * Gets the private 'private_not_inlined' shared service. + * + * @return \stdClass + */ + protected function getPrivateNotInlinedService() + { + return $this->services['private_not_inlined'] = new \stdClass(); + } + + /** + * Gets the private 'private_not_removed' shared service. + * + * @return \stdClass + */ + protected function getPrivateNotRemovedService() + { + return $this->services['private_not_removed'] = new \stdClass(); + } + + /** + * Gets the private 'private_parent' shared service. + * + * @return \stdClass + */ + protected function getPrivateParentService() + { + return $this->services['private_parent'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_locator.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_locator.php new file mode 100644 index 00000000..3826d5a6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_locator.php @@ -0,0 +1,184 @@ +services = []; + $this->methodMap = [ + 'bar_service' => 'getBarServiceService', + 'baz_service' => 'getBazServiceService', + 'foo_service' => 'getFooServiceService', + 'translator.loader_1' => 'getTranslator_Loader1Service', + 'translator.loader_2' => 'getTranslator_Loader2Service', + 'translator.loader_3' => 'getTranslator_Loader3Service', + 'translator_1' => 'getTranslator1Service', + 'translator_2' => 'getTranslator2Service', + 'translator_3' => 'getTranslator3Service', + ]; + $this->privates = [ + 'baz_service' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'baz_service' => true, + 'translator.loader_1_locator' => true, + 'translator.loader_2_locator' => true, + 'translator.loader_3_locator' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar_service' shared service. + * + * @return \stdClass + */ + protected function getBarServiceService() + { + return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the public 'foo_service' shared service. + * + * @return \Symfony\Component\DependencyInjection\ServiceLocator + */ + protected function getFooServiceService() + { + return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\ServiceLocator(['bar' => function () { + return ${($_ = isset($this->services['bar_service']) ? $this->services['bar_service'] : $this->getBarServiceService()) && false ?: '_'}; + }, 'baz' => function () { + $f = function (\stdClass $v) { return $v; }; return $f(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); + }, 'nil' => function () { + return NULL; + }]); + } + + /** + * Gets the public 'translator.loader_1' shared service. + * + * @return \stdClass + */ + protected function getTranslator_Loader1Service() + { + return $this->services['translator.loader_1'] = new \stdClass(); + } + + /** + * Gets the public 'translator.loader_2' shared service. + * + * @return \stdClass + */ + protected function getTranslator_Loader2Service() + { + return $this->services['translator.loader_2'] = new \stdClass(); + } + + /** + * Gets the public 'translator.loader_3' shared service. + * + * @return \stdClass + */ + protected function getTranslator_Loader3Service() + { + return $this->services['translator.loader_3'] = new \stdClass(); + } + + /** + * Gets the public 'translator_1' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator + */ + protected function getTranslator1Service() + { + return $this->services['translator_1'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(['translator.loader_1' => function () { + return ${($_ = isset($this->services['translator.loader_1']) ? $this->services['translator.loader_1'] : ($this->services['translator.loader_1'] = new \stdClass())) && false ?: '_'}; + }])); + } + + /** + * Gets the public 'translator_2' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator + */ + protected function getTranslator2Service() + { + $this->services['translator_2'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(['translator.loader_2' => function () { + return ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : ($this->services['translator.loader_2'] = new \stdClass())) && false ?: '_'}; + }])); + + $instance->addResource('db', ${($_ = isset($this->services['translator.loader_2']) ? $this->services['translator.loader_2'] : ($this->services['translator.loader_2'] = new \stdClass())) && false ?: '_'}, 'nl'); + + return $instance; + } + + /** + * Gets the public 'translator_3' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator + */ + protected function getTranslator3Service() + { + $this->services['translator_3'] = $instance = new \Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator(new \Symfony\Component\DependencyInjection\ServiceLocator(['translator.loader_3' => function () { + return ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : ($this->services['translator.loader_3'] = new \stdClass())) && false ?: '_'}; + }])); + + $a = ${($_ = isset($this->services['translator.loader_3']) ? $this->services['translator.loader_3'] : ($this->services['translator.loader_3'] = new \stdClass())) && false ?: '_'}; + + $instance->addResource('db', $a, 'nl'); + $instance->addResource('db', $a, 'en'); + + return $instance; + } + + /** + * Gets the private 'baz_service' shared service. + * + * @return \stdClass + */ + protected function getBazServiceService() + { + return $this->services['baz_service'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_non_shared_lazy.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_non_shared_lazy.php new file mode 100644 index 00000000..4cea5d2d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_non_shared_lazy.php @@ -0,0 +1,92 @@ +services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'foo' => 'getFooService', + ]; + $this->privates = [ + 'bar' => true, + 'foo' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'bar' => true, + 'foo' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + protected function createProxy($class, \Closure $factory) + { + return $factory(); + } + + /** + * Gets the private 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService() + { + return $this->services['bar'] = new \stdClass(${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->getFooService()) && false ?: '_'}); + } + + /** + * Gets the private 'foo' service. + * + * @return \stdClass + */ + protected function getFooService($lazyLoad = true) + { + // lazy factory for stdClass + + return new \stdClass(); + } +} + +// proxy code for stdClass diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_private_frozen.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_private_frozen.php new file mode 100644 index 00000000..95995dec --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_private_frozen.php @@ -0,0 +1,92 @@ +services = []; + $this->methodMap = [ + 'bar_service' => 'getBarServiceService', + 'baz_service' => 'getBazServiceService', + 'foo_service' => 'getFooServiceService', + ]; + $this->privates = [ + 'baz_service' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'baz_service' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar_service' shared service. + * + * @return \stdClass + */ + protected function getBarServiceService() + { + return $this->services['bar_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the public 'foo_service' shared service. + * + * @return \stdClass + */ + protected function getFooServiceService() + { + return $this->services['foo_service'] = new \stdClass(${($_ = isset($this->services['baz_service']) ? $this->services['baz_service'] : ($this->services['baz_service'] = new \stdClass())) && false ?: '_'}); + } + + /** + * Gets the private 'baz_service' shared service. + * + * @return \stdClass + */ + protected function getBazServiceService() + { + return $this->services['baz_service'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_private_in_expression.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_private_in_expression.php new file mode 100644 index 00000000..56d73c25 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_private_in_expression.php @@ -0,0 +1,82 @@ +services = []; + $this->methodMap = [ + 'private_foo' => 'getPrivateFooService', + 'public_foo' => 'getPublicFooService', + ]; + $this->privates = [ + 'private_foo' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'private_bar' => true, + 'private_foo' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'public_foo' shared service. + * + * @return \stdClass + */ + protected function getPublicFooService() + { + return $this->services['public_foo'] = new \stdClass(${($_ = isset($this->services['private_foo']) ? $this->services['private_foo'] : ($this->services['private_foo'] = new \stdClass())) && false ?: '_'}->bar); + } + + /** + * Gets the private 'private_foo' shared service. + * + * @return \stdClass + */ + protected function getPrivateFooService() + { + return $this->services['private_foo'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_rot13_env.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_rot13_env.php new file mode 100644 index 00000000..a7ad1f1c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_rot13_env.php @@ -0,0 +1,180 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->normalizedIds = [ + 'symfony\\component\\dependencyinjection\\tests\\dumper\\rot13envvarprocessor' => 'Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor', + ]; + $this->methodMap = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor' => 'getRot13EnvVarProcessorService', + 'container.env_var_processors_locator' => 'getContainer_EnvVarProcessorsLocatorService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor + */ + protected function getRot13EnvVarProcessorService() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor(); + } + + /** + * Gets the public 'container.env_var_processors_locator' shared service. + * + * @return \Symfony\Component\DependencyInjection\ServiceLocator + */ + protected function getContainer_EnvVarProcessorsLocatorService() + { + return $this->services['container.env_var_processors_locator'] = new \Symfony\Component\DependencyInjection\ServiceLocator(['rot13' => function () { + return ${($_ = isset($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor']) ? $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor'] : ($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Dumper\\Rot13EnvVarProcessor'] = new \Symfony\Component\DependencyInjection\Tests\Dumper\Rot13EnvVarProcessor())) && false ?: '_'}; + }]); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = [ + 'hello' => false, + ]; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + switch ($name) { + case 'hello': $value = $this->getEnv('rot13:foo'); break; + default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + $this->loadedDynamicParameters[$name] = true; + + return $this->dynamicParameters[$name] = $value; + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + 'env(foo)' => 'jbeyq', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_subscriber.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_subscriber.php new file mode 100644 index 00000000..ca89e01c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_subscriber.php @@ -0,0 +1,106 @@ +services = []; + $this->normalizedIds = [ + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\customdefinition' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition', + 'symfony\\component\\dependencyinjection\\tests\\fixtures\\testservicesubscriber' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber', + ]; + $this->methodMap = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => 'getCustomDefinitionService', + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => 'getTestServiceSubscriberService', + 'foo_service' => 'getFooServiceService', + ]; + $this->privates = [ + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true, + 'service_locator.jmktfsv' => true, + 'service_locator.jmktfsv.foo_service' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber + */ + protected function getTestServiceSubscriberService() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(); + } + + /** + * Gets the public 'foo_service' shared autowired service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber + */ + protected function getFooServiceService() + { + return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber((new \Symfony\Component\DependencyInjection\ServiceLocator(['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function () { + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition']) ? $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] : ($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition())) && false ?: '_'}); + }, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function () { + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber']) ? $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] : ($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber())) && false ?: '_'}); + }, 'bar' => function () { + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v) { return $v; }; return $f(${($_ = isset($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber']) ? $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] : ($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber())) && false ?: '_'}); + }, 'baz' => function () { + $f = function (\Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition $v = null) { return $v; }; return $f(${($_ = isset($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition']) ? $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] : ($this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition())) && false ?: '_'}); + }]))->withContext('foo_service', $this)); + } + + /** + * Gets the private 'Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared service. + * + * @return \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition + */ + protected function getCustomDefinitionService() + { + return $this->services['Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_tsantos.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_tsantos.php new file mode 100644 index 00000000..b314feff --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_tsantos.php @@ -0,0 +1,87 @@ +services = []; + $this->normalizedIds = [ + 'tsantos\\serializer\\serializerinterface' => 'TSantos\\Serializer\\SerializerInterface', + ]; + $this->methodMap = [ + 'tsantos_serializer' => 'getTsantosSerializerService', + ]; + $this->aliases = [ + 'TSantos\\Serializer\\SerializerInterface' => 'tsantos_serializer', + ]; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'tsantos_serializer' shared service. + * + * @return \TSantos\Serializer\EventEmitterSerializer + */ + protected function getTsantosSerializerService() + { + $a = new \TSantos\Serializer\NormalizerRegistry(); + + $b = new \TSantos\Serializer\Normalizer\CollectionNormalizer(); + + $c = new \TSantos\Serializer\EventDispatcher\EventDispatcher(); + $c->addSubscriber(new \TSantos\SerializerBundle\EventListener\StopwatchListener(new \Symfony\Component\Stopwatch\Stopwatch(true))); + + $this->services['tsantos_serializer'] = $instance = new \TSantos\Serializer\EventEmitterSerializer(new \TSantos\Serializer\Encoder\JsonEncoder(), $a, $c); + + $b->setSerializer($instance); + $d = new \TSantos\Serializer\Normalizer\JsonNormalizer(); + $d->setSerializer($instance); + + $a->add(new \TSantos\Serializer\Normalizer\ObjectNormalizer(new \TSantos\SerializerBundle\Serializer\CircularReferenceHandler())); + $a->add($b); + $a->add($d); + + return $instance; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_uninitialized_ref.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_uninitialized_ref.php new file mode 100644 index 00000000..a338c9d5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_uninitialized_ref.php @@ -0,0 +1,134 @@ +services = []; + $this->methodMap = [ + 'bar' => 'getBarService', + 'baz' => 'getBazService', + 'foo1' => 'getFoo1Service', + 'foo3' => 'getFoo3Service', + ]; + $this->privates = [ + 'foo3' => true, + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + 'foo2' => true, + 'foo3' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar' shared service. + * + * @return \stdClass + */ + protected function getBarService() + { + $this->services['bar'] = $instance = new \stdClass(); + + $instance->foo1 = ${($_ = isset($this->services['foo1']) ? $this->services['foo1'] : null) && false ?: '_'}; + $instance->foo2 = null; + $instance->foo3 = ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : null) && false ?: '_'}; + $instance->closures = [0 => function () { + return ${($_ = isset($this->services['foo1']) ? $this->services['foo1'] : null) && false ?: '_'}; + }, 1 => function () { + return null; + }, 2 => function () { + return ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : null) && false ?: '_'}; + }]; + $instance->iter = new RewindableGenerator(function () { + if (isset($this->services['foo1'])) { + yield 'foo1' => ${($_ = isset($this->services['foo1']) ? $this->services['foo1'] : null) && false ?: '_'}; + } + if (false) { + yield 'foo2' => null; + } + if (isset($this->services['foo3'])) { + yield 'foo3' => ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : null) && false ?: '_'}; + } + }, function () { + return 0 + (int) (isset($this->services['foo1'])) + (int) (false) + (int) (isset($this->services['foo3'])); + }); + + return $instance; + } + + /** + * Gets the public 'baz' shared service. + * + * @return \stdClass + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \stdClass(); + + $instance->foo3 = ${($_ = isset($this->services['foo3']) ? $this->services['foo3'] : ($this->services['foo3'] = new \stdClass())) && false ?: '_'}; + + return $instance; + } + + /** + * Gets the public 'foo1' shared service. + * + * @return \stdClass + */ + protected function getFoo1Service() + { + return $this->services['foo1'] = new \stdClass(); + } + + /** + * Gets the private 'foo3' shared service. + * + * @return \stdClass + */ + protected function getFoo3Service() + { + return $this->services['foo3'] = new \stdClass(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_unsupported_characters.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_unsupported_characters.php new file mode 100644 index 00000000..9e7e817d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/services_unsupported_characters.php @@ -0,0 +1,178 @@ +parameters = $this->getDefaultParameters(); + + $this->services = []; + $this->methodMap = [ + 'bar$' => 'getBarService', + 'bar$!' => 'getBar2Service', + 'foo*/oh-no' => 'getFooohnoService', + ]; + + $this->aliases = []; + } + + public function getRemovedIds() + { + return [ + 'Psr\\Container\\ContainerInterface' => true, + 'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true, + ]; + } + + public function compile() + { + throw new LogicException('You cannot compile a dumped container that was already compiled.'); + } + + public function isCompiled() + { + return true; + } + + public function isFrozen() + { + @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED); + + return true; + } + + /** + * Gets the public 'bar$' shared service. + * + * @return \FooClass + */ + protected function getBarService() + { + return $this->services['bar$'] = new \FooClass(); + } + + /** + * Gets the public 'bar$!' shared service. + * + * @return \FooClass + */ + protected function getBar2Service() + { + return $this->services['bar$!'] = new \FooClass(); + } + + /** + * Gets the public 'foo oh-no' shared service. + * + * @return \FooClass + */ + protected function getFooohnoService() + { + return $this->services['foo*/oh-no'] = new \FooClass(); + } + + public function getParameter($name) + { + $name = (string) $name; + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + $name = $this->normalizeParameterName($name); + + if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) { + throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name)); + } + } + if (isset($this->loadedDynamicParameters[$name])) { + return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + + return $this->parameters[$name]; + } + + public function hasParameter($name) + { + $name = (string) $name; + $name = $this->normalizeParameterName($name); + + return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters); + } + + public function setParameter($name, $value) + { + throw new LogicException('Impossible to call set() on a frozen ParameterBag.'); + } + + public function getParameterBag() + { + if (null === $this->parameterBag) { + $parameters = $this->parameters; + foreach ($this->loadedDynamicParameters as $name => $loaded) { + $parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name); + } + $this->parameterBag = new FrozenParameterBag($parameters); + } + + return $this->parameterBag; + } + + private $loadedDynamicParameters = []; + private $dynamicParameters = []; + + /** + * Computes a dynamic parameter. + * + * @param string $name The name of the dynamic parameter to load + * + * @return mixed The value of the dynamic parameter + * + * @throws InvalidArgumentException When the dynamic parameter does not exist + */ + private function getDynamicParameter($name) + { + throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name)); + } + + private $normalizedParameterNames = []; + + private function normalizeParameterName($name) + { + if (isset($this->normalizedParameterNames[$normalizedName = strtolower($name)]) || isset($this->parameters[$normalizedName]) || array_key_exists($normalizedName, $this->parameters)) { + $normalizedName = isset($this->normalizedParameterNames[$normalizedName]) ? $this->normalizedParameterNames[$normalizedName] : $normalizedName; + if ((string) $name !== $normalizedName) { + @trigger_error(sprintf('Parameter names will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.4.', $name, $normalizedName), E_USER_DEPRECATED); + } + } else { + $normalizedName = $this->normalizedParameterNames[$normalizedName] = (string) $name; + } + + return $normalizedName; + } + + /** + * Gets the default parameters. + * + * @return array An array of the default parameters + */ + protected function getDefaultParameters() + { + return [ + '\'' => 'oh-no', + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/simple.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/simple.php new file mode 100644 index 00000000..aa4df998 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/php/simple.php @@ -0,0 +1,3 @@ +setParameter('foo', 'foo'); diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/class_from_id.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/class_from_id.xml new file mode 100644 index 00000000..5b741009 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/class_from_id.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/defaults_bindings.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/defaults_bindings.xml new file mode 100644 index 00000000..d943dfad --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/defaults_bindings.xml @@ -0,0 +1,15 @@ + + + + + value + + value + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/defaults_bindings2.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/defaults_bindings2.xml new file mode 100644 index 00000000..db41330f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/defaults_bindings2.xml @@ -0,0 +1,10 @@ + + + + + overridden + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extension1/services.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extension1/services.xml new file mode 100644 index 00000000..1323dd5f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extension1/services.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extension2/services.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extension2/services.xml new file mode 100644 index 00000000..f9c01225 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extension2/services.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services1.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services1.xml new file mode 100644 index 00000000..792fa070 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services1.xml @@ -0,0 +1,19 @@ + + + + + + BAR + + + + + + + + + %project.parameter.foo% + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services2.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services2.xml new file mode 100644 index 00000000..65c90696 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services2.xml @@ -0,0 +1,19 @@ + + + + + + BAR + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services3.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services3.xml new file mode 100644 index 00000000..4c818448 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services3.xml @@ -0,0 +1,19 @@ + + + + + + BAR + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services4.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services4.xml new file mode 100644 index 00000000..2c33c3a7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services4.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services5.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services5.xml new file mode 100644 index 00000000..c0343373 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services5.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services6.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services6.xml new file mode 100644 index 00000000..da2b4bf2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services6.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services7.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services7.xml new file mode 100644 index 00000000..fa5c364b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/extensions/services7.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml new file mode 100644 index 00000000..a5387b25 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/namespaces.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/namespaces.xml new file mode 100644 index 00000000..9dc27fad --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/namespaces.xml @@ -0,0 +1,17 @@ + + + + + + + + + foo + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/nested_service_without_id.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/nested_service_without_id.xml new file mode 100644 index 00000000..cfeed0ff --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/nested_service_without_id.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/nonvalid.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/nonvalid.xml new file mode 100644 index 00000000..e7b5bc97 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/nonvalid.xml @@ -0,0 +1,3 @@ + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services1.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services1.xml new file mode 100644 index 00000000..7d8674a3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services1.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services10.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services10.xml new file mode 100644 index 00000000..921070e1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services10.xml @@ -0,0 +1,16 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services13.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services13.xml new file mode 100644 index 00000000..9d86b8e5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services13.xml @@ -0,0 +1,9 @@ + + + + + true + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services14.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services14.xml new file mode 100644 index 00000000..639075f5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services14.xml @@ -0,0 +1,19 @@ + + + + + app + + + + + + app + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services2.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services2.xml new file mode 100644 index 00000000..243a289f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services2.xml @@ -0,0 +1,31 @@ + + + + + a string + bar + + 0 + 4 + null + true + true + false + on + off + 1.3 + 1000.3 + a string + + foo + bar + + + + value + + PHP_EOL + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services21.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services21.xml new file mode 100644 index 00000000..20dd4cf4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services21.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services22.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services22.xml new file mode 100644 index 00000000..6de7945b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services22.xml @@ -0,0 +1,9 @@ + + + + + Bar + Baz + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services23.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services23.xml new file mode 100644 index 00000000..eb56fd11 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services23.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services24.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services24.xml new file mode 100644 index 00000000..23c91cdc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services24.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services28.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services28.xml new file mode 100644 index 00000000..6b53c098 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services28.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services3.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services3.xml new file mode 100644 index 00000000..5f0afeb4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services3.xml @@ -0,0 +1,13 @@ + + + + + foo + + true + false + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services4.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services4.xml new file mode 100644 index 00000000..399da815 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services4.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services4_bad_import.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services4_bad_import.xml new file mode 100644 index 00000000..b30178f9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services4_bad_import.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services5.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services5.xml new file mode 100644 index 00000000..6c6a1424 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services5.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services6.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services6.xml new file mode 100644 index 00000000..84eb57bb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services6.xml @@ -0,0 +1,69 @@ + + + + + + + + + %path%/foo.php + + + foo + + + true + false + + + + + + + + + + + + + + + service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default") + + + + + foo + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services7.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services7.xml new file mode 100644 index 00000000..5b322105 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services7.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services8.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services8.xml new file mode 100644 index 00000000..4b07bbb7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services8.xml @@ -0,0 +1,38 @@ + + + + + %baz% + bar + foo is %%foo bar + @escapeme + + true + false + null + 0 + 1000.3 + true + false + null + + null + 123 + -123 + true + false + 0b0110 + -1.2E2 + 0xFF + 10100.1 + +10100.1 + -10100.1 + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services9.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services9.xml new file mode 100644 index 00000000..128c1bac --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services9.xml @@ -0,0 +1,147 @@ + + + + BazClass + Bar\FooClass + bar + + + + + + + foo + + + foo is %foo% + %foo% + + true + + bar + + + foo is %foo% + %foo% + + + + + + + + + + + + + + foo + + %foo_bar% + + + + + + + %path%foo.php + + + + + + + + + + + + + + service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default") + + + + + + + + + pub + + + + + + + + + + + + + + + + + + + + bar + + + + + + + + + The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed. + + + bar + + + + + + bar + + + + + + + foo + The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_abstract.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_abstract.xml new file mode 100644 index 00000000..47fd3a53 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_abstract.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_autoconfigure.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_autoconfigure.xml new file mode 100644 index 00000000..91cfa5f4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_autoconfigure.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_autoconfigure_with_parent.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_autoconfigure_with_parent.xml new file mode 100644 index 00000000..97a8facf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_autoconfigure_with_parent.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_bindings.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_bindings.xml new file mode 100644 index 00000000..0fb57daa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_bindings.xml @@ -0,0 +1,21 @@ + + + + + null + quz + factory + + + + + + null + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_defaults_with_parent.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_defaults_with_parent.xml new file mode 100644 index 00000000..bb151189 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_defaults_with_parent.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_deprecated.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_deprecated.xml new file mode 100644 index 00000000..ae3a0b08 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_deprecated.xml @@ -0,0 +1,11 @@ + + + + + + + + The "%service_id%" service is deprecated. + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_dump_load.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_dump_load.xml new file mode 100644 index 00000000..7a91166c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_dump_load.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_inline_not_candidate.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_inline_not_candidate.xml new file mode 100644 index 00000000..e6857813 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_inline_not_candidate.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_instanceof.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_instanceof.xml new file mode 100644 index 00000000..097687e1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_instanceof.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_instanceof_with_parent.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_instanceof_with_parent.xml new file mode 100644 index 00000000..c2fce5eb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_instanceof_with_parent.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_named_args.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_named_args.xml new file mode 100644 index 00000000..68ade19d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_named_args.xml @@ -0,0 +1,12 @@ + + + + + ABCD + null + + 123 + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_prototype.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_prototype.xml new file mode 100644 index 00000000..9d1d622d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_prototype.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_tsantos.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_tsantos.xml new file mode 100644 index 00000000..2a35f468 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_tsantos.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_without_id.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_without_id.xml new file mode 100644 index 00000000..fe65f08f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/services_without_id.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/tag_with_empty_name.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/tag_with_empty_name.xml new file mode 100644 index 00000000..08e3e78f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/tag_with_empty_name.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/tag_without_name.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/tag_without_name.xml new file mode 100644 index 00000000..1ff39290 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/tag_without_name.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/with_key_outside_collection.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/with_key_outside_collection.xml new file mode 100644 index 00000000..1f6d3207 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/with_key_outside_collection.xml @@ -0,0 +1,9 @@ + + + + + foo + bar + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/withdoctype.xml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/withdoctype.xml new file mode 100644 index 00000000..f217d5bc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/withdoctype.xml @@ -0,0 +1,3 @@ + + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/xml_with_wrong_ext.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/xml_with_wrong_ext.php new file mode 100644 index 00000000..dcf167db --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/xml/xml_with_wrong_ext.php @@ -0,0 +1,9 @@ + + + + + from xml + + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services.yml new file mode 100644 index 00000000..fe54b898 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services.yml @@ -0,0 +1,14 @@ +imports: + # Ensure the anonymous services count is reset after importing a file + - { resource: anonymous_services_in_instanceof.yml } + +services: + _defaults: + autowire: true + + Foo: + arguments: + - !service + class: Bar + autowire: true + factory: [ !service { class: Quz }, 'constructFoo' ] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_alias.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_alias.yml new file mode 100644 index 00000000..96546b83 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_alias.yml @@ -0,0 +1,7 @@ +services: + Bar: ~ + + Foo: + arguments: + - !service + alias: Bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_in_instanceof.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_in_instanceof.yml new file mode 100644 index 00000000..ea0bebaf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_in_instanceof.yml @@ -0,0 +1,15 @@ +services: + _instanceof: + # Ensure previous conditionals aren't applied on anonymous services + Quz: + autowire: true + + DummyInterface: + properties: + foo: !service { class: Anonymous } + + # Ensure next conditionals are not considered as services + Bar: + autowire: true + + Dummy: ~ diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_in_parameters.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_in_parameters.yml new file mode 100644 index 00000000..9d9bea34 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/anonymous_services_in_parameters.yml @@ -0,0 +1,2 @@ +parameters: + foo: [ !service { } ] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_calls.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_calls.yml new file mode 100644 index 00000000..3f34b07e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_calls.yml @@ -0,0 +1,4 @@ +services: + method_call1: + class: FooClass + calls: foo diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_decorates.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_decorates.yml new file mode 100644 index 00000000..79c048a8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_decorates.yml @@ -0,0 +1,7 @@ +services: + foo: + class: stdClass + bar: + class: stdClass + decorates: "@foo" + arguments: ["@bar.inner"] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_empty_defaults.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_empty_defaults.yml new file mode 100644 index 00000000..85d910e3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_empty_defaults.yml @@ -0,0 +1,2 @@ +services: + _defaults: diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_empty_instanceof.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_empty_instanceof.yml new file mode 100644 index 00000000..2c8ce09f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_empty_instanceof.yml @@ -0,0 +1,2 @@ +services: + _instanceof: diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_format.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_format.yml new file mode 100644 index 00000000..1f58cac6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_format.yml @@ -0,0 +1,2 @@ +parameters: + FOO: bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_import.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_import.yml new file mode 100644 index 00000000..2dbbcbf2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_import.yml @@ -0,0 +1,2 @@ +imports: + - { resource: ~ } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_imports.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_imports.yml new file mode 100644 index 00000000..1ce9d57c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_imports.yml @@ -0,0 +1,2 @@ +imports: + foo:bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_parameters.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_parameters.yml new file mode 100644 index 00000000..bbd13ac0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_parameters.yml @@ -0,0 +1,2 @@ +parameters: + foo:bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_service.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_service.yml new file mode 100644 index 00000000..811af3c0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_service.yml @@ -0,0 +1,2 @@ +services: + foo: bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_services.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_services.yml new file mode 100644 index 00000000..cfbf17ce --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_services.yml @@ -0,0 +1 @@ +services: foo diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_types1.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_types1.yml new file mode 100644 index 00000000..891e0149 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_types1.yml @@ -0,0 +1,5 @@ +services: + foo_service: + class: FooClass + # types is not an array + autowiring_types: 1 diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_types2.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_types2.yml new file mode 100644 index 00000000..fb1d53e1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bad_types2.yml @@ -0,0 +1,5 @@ +services: + foo_service: + class: FooClass + # autowiring_types is not a string + autowiring_types: [ 1 ] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag1.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag1.yml new file mode 100644 index 00000000..14536fdb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag1.yml @@ -0,0 +1,5 @@ +services: + foo_service: + class: FooClass + # tags is not an array + tags: string diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag2.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag2.yml new file mode 100644 index 00000000..90288144 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag2.yml @@ -0,0 +1,6 @@ +services: + foo_service: + class: FooClass + tags: + # tag is missing the name key + foo_tag: { foo: bar } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag3.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag3.yml new file mode 100644 index 00000000..72ec4e8f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/badtag3.yml @@ -0,0 +1,6 @@ +services: + foo_service: + class: FooClass + tags: + # tag-attribute is not a scalar + - { name: foo, bar: { foo: foo, bar: bar } } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bar/services.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bar/services.yml new file mode 100644 index 00000000..0f846f5f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/bar/services.yml @@ -0,0 +1,4 @@ +services: + AppBundle\Foo: + arguments: + - !service {class: AppBundle\Bar } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/class_from_id.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/class_from_id.yml new file mode 100644 index 00000000..33f0b2ea --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/class_from_id.yml @@ -0,0 +1,3 @@ +services: + Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass: + autowire: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/defaults_bindings.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/defaults_bindings.yml new file mode 100644 index 00000000..ca5e5048 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/defaults_bindings.yml @@ -0,0 +1,11 @@ +services: + _defaults: + bind: + $quz: value + $foo: [value] + + bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar + + foo: + class: stdClass diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/defaults_bindings2.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/defaults_bindings2.yml new file mode 100644 index 00000000..01fc5af6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/defaults_bindings2.yml @@ -0,0 +1,7 @@ +services: + _defaults: + bind: + $quz: overridden + + bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/foo/services.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/foo/services.yml new file mode 100644 index 00000000..76eee552 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/foo/services.yml @@ -0,0 +1,4 @@ +services: + AppBundle\Hello: + arguments: + - !service {class: AppBundle\World} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/_child.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/_child.yml new file mode 100644 index 00000000..89d8b914 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/_child.yml @@ -0,0 +1,4 @@ +services: + child_service: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/expected.yml new file mode 100644 index 00000000..ca08caad --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/expected.yml @@ -0,0 +1,10 @@ +services: + child_service_expected: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + # the parent has autoconfigure true, but that does not cascade to the child + autoconfigure: false + # an autoconfigured "instanceof" is setup for IntegrationTestStub + # but its calls are NOT added, because the class was only + # set on the parent, not the child + #calls: + # - [enableSummer, [true]] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/main.yml new file mode 100644 index 00000000..02533bf0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/main.yml @@ -0,0 +1,7 @@ +imports: + - { resource: _child.yml } + +services: + parent_service: + autoconfigure: true + abstract: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/_child.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/_child.yml new file mode 100644 index 00000000..5319c204 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/_child.yml @@ -0,0 +1,3 @@ +services: + child_service: + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/expected.yml new file mode 100644 index 00000000..c1dca076 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/expected.yml @@ -0,0 +1,5 @@ +services: + child_service_expected: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + # autoconfigure is set on the parent, but not on the child + autoconfigure: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/main.yml new file mode 100644 index 00000000..ab9877d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/main.yml @@ -0,0 +1,7 @@ +imports: + - { resource: _child.yml } + +services: + parent_service: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + autoconfigure: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/_child.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/_child.yml new file mode 100644 index 00000000..5319c204 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/_child.yml @@ -0,0 +1,3 @@ +services: + child_service: + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/expected.yml new file mode 100644 index 00000000..02cf0037 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/expected.yml @@ -0,0 +1,6 @@ +services: + child_service_expected: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + # from an autoconfigured "instanceof" applied to parent class + # but NOT inherited down to child + # tags: [from_autoconfigure] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/main.yml new file mode 100644 index 00000000..ab9877d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/main.yml @@ -0,0 +1,7 @@ +imports: + - { resource: _child.yml } + +services: + parent_service: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + autoconfigure: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/child_parent/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/child_parent/expected.yml new file mode 100644 index 00000000..54cd91c2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/child_parent/expected.yml @@ -0,0 +1,9 @@ +services: + # child_service in the end should be identical to this + child_service_expected: + class: stdClass + autowire: false + public: true + lazy: true + # ONLY the child tag, the parent tag does not inherit + tags: [from_child] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/child_parent/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/child_parent/main.yml new file mode 100644 index 00000000..edaa3a3b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/child_parent/main.yml @@ -0,0 +1,13 @@ +services: + parent_service: + abstract: true + lazy: true + autowire: false + public: false + tags: [from_parent] + + child_service: + class: stdClass + parent: parent_service + public: true + tags: [from_child] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_child_tags/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_child_tags/expected.yml new file mode 100644 index 00000000..cb36636e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_child_tags/expected.yml @@ -0,0 +1,8 @@ +services: + child_service_expected: + class: stdClass + # set explicitly on child (not overridden by parent) + autoconfigure: false + # set explicitly on child + autowire: true + tags: [from_defaults] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_child_tags/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_child_tags/main.yml new file mode 100644 index 00000000..b5dc66ff --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_child_tags/main.yml @@ -0,0 +1,18 @@ +services: + _defaults: + autoconfigure: true + autowire: true + tags: [from_defaults] + + parent_service: + class: stdClass + # will not override child + autoconfigure: true + # parent definitions are not applied to children + tags: [from_parent] + + child_service: + parent: parent_service + # _defaults is ok because these are explicitly set + autoconfigure: false + autowire: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/expected.yml new file mode 100644 index 00000000..e9161dcc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/expected.yml @@ -0,0 +1,26 @@ +services: + # main_service should look like this in the end + main_service_expected: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + # _instanceof overrides _defaults + autowire: false + # inherited from _defaults + autoconfigure: true + # from _instanceof + shared: false + # service definition overrides _instanceof + public: true + + tags: + - { name: foo_tag, tag_option: from_service } + # these 2 are from instanceof + - { name: foo_tag, tag_option: from_instanceof } + - { name: bar_tag } + - { name: from_defaults } + # calls from instanceof are kept, but this comes later + calls: + # first call is from instanceof + - [setSunshine, [bright]] + # + - [enableSummer, [true]] + - [setSunshine, [warm]] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/main.yml new file mode 100644 index 00000000..406a351d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/main.yml @@ -0,0 +1,30 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: true + tags: [from_defaults] + + _instanceof: + Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStubParent: + autowire: false + shared: false + public: false + tags: + - { name: foo_tag, tag_option: from_instanceof } + calls: + - [setSunshine, [bright]] + + Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub: + tags: + - { name: bar_tag } + + main_service: + class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub + public: true + tags: + - { name: foo_tag, tag_option: from_service } + # calls from instanceof are kept, but this comes later + calls: + - [enableSummer, [true]] + - [setSunshine, [warm]] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/_child.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/_child.yml new file mode 100644 index 00000000..86ef83c2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/_child.yml @@ -0,0 +1,4 @@ +services: + # loaded here to avoid defaults in other file + child_service: + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/expected.yml new file mode 100644 index 00000000..012672ff --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/expected.yml @@ -0,0 +1,6 @@ +services: + child_service_expected: + class: stdClass + # _defaults is applied to the parent, but autoconfigure: true + # does not cascade to the child + autoconfigure: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/main.yml new file mode 100644 index 00000000..8b90b4e9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/defaults_parent_child/main.yml @@ -0,0 +1,9 @@ +imports: + - { resource: _child.yml } + +services: + _defaults: + autoconfigure: true + + parent_service: + class: stdClass diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/_child.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/_child.yml new file mode 100644 index 00000000..86ef83c2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/_child.yml @@ -0,0 +1,4 @@ +services: + # loaded here to avoid defaults in other file + child_service: + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/expected.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/expected.yml new file mode 100644 index 00000000..074ed01d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/expected.yml @@ -0,0 +1,7 @@ +services: + child_service_expected: + class: stdClass + # applied to _instanceof of parent + autowire: true + # from _instanceof, applies to parent, but does NOT inherit to here + # tags: [from_instanceof] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/main.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/main.yml new file mode 100644 index 00000000..44cf9b00 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/integration/instanceof_parent_child/main.yml @@ -0,0 +1,11 @@ +imports: + - { resource: _child.yml } + +services: + _instanceof: + stdClass: + autowire: true + tags: [from_instanceof] + + parent_service: + class: stdClass diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml new file mode 100644 index 00000000..00c011c1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml @@ -0,0 +1,5 @@ +services: + foo: + alias: bar + factory: foo + parent: quz diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/legacy_invalid_definition.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/legacy_invalid_definition.yml new file mode 100644 index 00000000..8487e854 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/legacy_invalid_definition.yml @@ -0,0 +1,10 @@ +services: + # This definition is valid and should not raise any deprecation notice + foo: + class: stdClass + arguments: [ 'foo', 'bar' ] + + # This definition is invalid and must raise a deprecation notice + bar: + class: stdClass + private: true # the "private" keyword is invalid diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/nonvalid1.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/nonvalid1.yml new file mode 100644 index 00000000..4eddb872 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/nonvalid1.yml @@ -0,0 +1,2 @@ +foo: + bar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/nonvalid2.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/nonvalid2.yml new file mode 100644 index 00000000..c508d536 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/nonvalid2.yml @@ -0,0 +1 @@ +false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/null_config.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/null_config.yml new file mode 100644 index 00000000..e88e12e2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/null_config.yml @@ -0,0 +1 @@ +project: ~ diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services1.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services1.yml new file mode 100644 index 00000000..071742f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services1.yml @@ -0,0 +1,11 @@ +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services10.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services10.yml new file mode 100644 index 00000000..c66084cd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services10.yml @@ -0,0 +1,9 @@ +parameters: + project.parameter.foo: BAR + +services: + project.service.foo: + class: BAR + +project: + test: '%project.parameter.foo%' diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services11.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services11.yml new file mode 100644 index 00000000..40126f00 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services11.yml @@ -0,0 +1 @@ +foobarfoobar: {} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services13.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services13.yml new file mode 100644 index 00000000..d52d355c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services13.yml @@ -0,0 +1,3 @@ +# used to test imports in XML +parameters: + imported_from_yaml: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services14.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services14.yml new file mode 100644 index 00000000..4c188c5f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services14.yml @@ -0,0 +1,3 @@ +services: + factory: { class: FooBarClass, factory: baz:getClass} + factory_with_static_call: { class: FooBarClass, factory: FooBacFactory::createFooBar} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services2.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services2.yml new file mode 100644 index 00000000..e05d69d7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services2.yml @@ -0,0 +1,13 @@ +parameters: + foo: bar + values: + - true + - false + - 0 + - 1000.3 + - !php/const PHP_INT_MAX + bar: foo + escape: '@@escapeme' + foo_bar: '@foo_bar' + mixedcase: + MixedCaseKey: value diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services21.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services21.yml new file mode 100644 index 00000000..a2617c16 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services21.yml @@ -0,0 +1,15 @@ +services: + manager: + class: UserManager + arguments: + - true + calls: + - method: setLogger + arguments: + - '@logger' + - method: setClass + arguments: + - User + tags: + - name: manager + alias: user diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services22.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services22.yml new file mode 100644 index 00000000..55d015ba --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services22.yml @@ -0,0 +1,8 @@ +services: + foo_service: + class: FooClass + autowiring_types: [ Foo, Bar ] + + baz_service: + class: Baz + autowiring_types: Foo diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services23.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services23.yml new file mode 100644 index 00000000..1984c177 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services23.yml @@ -0,0 +1,4 @@ +services: + bar_service: + class: BarClass + autowire: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services24.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services24.yml new file mode 100644 index 00000000..f59354e3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services24.yml @@ -0,0 +1,16 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + foo: + class: Foo + public: true + autowire: true + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services26.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services26.yml new file mode 100644 index 00000000..a1f235a7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services26.yml @@ -0,0 +1,22 @@ +parameters: + project_dir: '/foo/bar' + env(FOO): foo + env(DB): 'sqlite://%%project_dir%%/var/data.db' + bar: '%env(FOO)%' + baz: '%env(int:Baz)%' + json: '%env(json:file:json_file)%' + db_dsn: '%env(resolve:DB)%' + +services: + test: + public: true + class: '%env(FOO)%' + arguments: + - '%env(Bar)%' + - 'foo%bar%baz' + - '%baz%' + bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar + public: true + bind: + $quz: '%env(QUZ)%' diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services28.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services28.yml new file mode 100644 index 00000000..fd0ce4cf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services28.yml @@ -0,0 +1,34 @@ +services: + _defaults: + public: false + autowire: true + tags: + - name: foo + + Acme\Foo: ~ + + with_defaults: + class: Foo + + with_null: + class: Foo + public: true + autowire: ~ + + no_defaults: + class: Foo + public: true + autowire: false + tags: [] + + with_defaults_aliased: + alias: with_defaults + + with_defaults_aliased_short: '@with_defaults' + + Acme\WithShortCutArgs: [foo] + + child_def: + parent: with_defaults + public: true + autowire: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services3.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services3.yml new file mode 100644 index 00000000..0e92cdf5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services3.yml @@ -0,0 +1,5 @@ +parameters: + foo: foo + values: + - true + - false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services31_invalid_tags.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services31_invalid_tags.yml new file mode 100644 index 00000000..a6061a90 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services31_invalid_tags.yml @@ -0,0 +1,6 @@ +services: + _defaults: + tags: ['foo'] + + Foo\Bar: + tags: invalid diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services4.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services4.yml new file mode 100644 index 00000000..073f5554 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services4.yml @@ -0,0 +1,8 @@ +imports: + - services2.yml + - { resource: services3.yml } + - { resource: "../php/simple.php" } + - { resource: "../ini/parameters.ini", class: Symfony\Component\DependencyInjection\Loader\IniFileLoader } + - { resource: "../ini/parameters2.ini" } + - { resource: "../xml/services13.xml" } + - { resource: "../xml/xml_with_wrong_ext.php", type: xml } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services4_bad_import.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services4_bad_import.yml new file mode 100644 index 00000000..f7089fc4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services4_bad_import.yml @@ -0,0 +1,2 @@ +imports: + - { resource: foo_fake.yml, ignore_errors: true } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services6.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services6.yml new file mode 100644 index 00000000..1ee6c6ec --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services6.yml @@ -0,0 +1,43 @@ +services: + foo: { class: FooClass } + baz: { class: BazClass } + not_shared: { class: FooClass, shared: false } + file: { class: FooClass, file: '%path%/foo.php' } + arguments: { class: FooClass, arguments: [foo, '@foo', [true, false]] } + configurator1: { class: FooClass, configurator: sc_configure } + configurator2: { class: FooClass, configurator: ['@baz', configure] } + configurator3: { class: FooClass, configurator: [BazClass, configureStatic] } + method_call1: + class: FooClass + calls: + - [ setBar, [] ] + - [ setBar ] + - [ setBar, ['@=service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")'] ] + method_call2: + class: FooClass + calls: + - [ setBar, [ foo, '@foo', [true, false] ] ] + request: + class: Request + synthetic: true + lazy: true + decorator_service: + decorates: decorated + decorator_service_with_name: + decorates: decorated + decoration_inner_name: decorated.pif-pouf + decorator_service_with_name_and_priority: + decorates: decorated + decoration_inner_name: decorated.pif-pouf + decoration_priority: 5 + new_factory1: { class: FooBarClass, factory: factory} + new_factory2: { class: FooBarClass, factory: ['@baz', getClass]} + new_factory3: { class: FooBarClass, factory: [BazClass, getInstance]} + new_factory4: { class: BazClass, factory: [~, getInstance]} + Acme\WithShortCutArgs: [foo, '@baz'] + alias_for_foo: '@foo' + another_alias_for_foo: + alias: foo + public: false + another_third_alias_for_foo: + alias: foo diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services7.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services7.yml new file mode 100644 index 00000000..09064f20 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services7.yml @@ -0,0 +1,2 @@ +services: + foo: { class: BarClass } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services8.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services8.yml new file mode 100644 index 00000000..002b1d4b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services8.yml @@ -0,0 +1,29 @@ +parameters: + foo: '%baz%' + baz: bar + bar: 'foo is %%foo bar' + escape: '@@escapeme' + values: [true, false, null, 0, 1000.3, 'true', 'false', 'null'] + null string: 'null' + string of digits: '123' + string of digits prefixed with minus character: '-123' + true string: 'true' + false string: 'false' + binary number string: '0b0110' + numeric string: '-1.2E2' + hexadecimal number string: '0xFF' + float string: '10100.1' + positive float string: '+10100.1' + negative float string: '-10100.1' + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services9.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services9.yml new file mode 100644 index 00000000..2501ddcc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services9.yml @@ -0,0 +1,163 @@ +parameters: + baz_class: BazClass + foo_class: Bar\FooClass + foo: bar + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + foo: + class: Bar\FooClass + tags: + - { name: foo, foo: foo } + - { name: foo, bar: bar, baz: baz } + arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', foobar: '%foo%' }, true, '@service_container'] + properties: { foo: bar, moo: '@foo.baz', qux: { '%foo%': 'foo is %foo%', foobar: '%foo%' } } + calls: + - [setBar, ['@bar']] + - [initialize, { }] + + factory: [Bar\FooClass, getInstance] + configurator: sc_configure + public: true + foo.baz: + class: '%baz_class%' + factory: ['%baz_class%', getInstance] + configurator: ['%baz_class%', configureStatic1] + public: true + bar: + class: Bar\FooClass + arguments: [foo, '@foo.baz', '%foo_bar%'] + configurator: ['@foo.baz', configure] + public: true + foo_bar: + class: '%foo_class%' + shared: false + arguments: ['@deprecated_service'] + public: true + method_call1: + class: Bar\FooClass + file: '%path%foo.php' + calls: + - [setBar, ['@foo']] + - [setBar, ['@?foo2']] + - [setBar, ['@?foo3']] + - [setBar, ['@?foobaz']] + - [setBar, ['@=service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")']] + public: true + + foo_with_inline: + class: Foo + calls: + - [setBar, ['@inlined']] + public: true + + inlined: + class: Bar + public: false + properties: { pub: pub } + calls: + - [setBaz, ['@baz']] + + baz: + class: Baz + calls: + - [setFoo, ['@foo_with_inline']] + public: true + + request: + class: Request + synthetic: true + public: true + configurator_service: + class: ConfClass + public: false + calls: + - [setFoo, ['@baz']] + + configured_service: + class: stdClass + configurator: ['@configurator_service', configureStdClass] + public: true + configurator_service_simple: + class: ConfClass + public: false + arguments: ['bar'] + configured_service_simple: + class: stdClass + configurator: ['@configurator_service_simple', configureStdClass] + public: true + decorated: + class: stdClass + public: true + decorator_service: + class: stdClass + decorates: decorated + public: true + decorator_service_with_name: + class: stdClass + decorates: decorated + decoration_inner_name: decorated.pif-pouf + public: true + deprecated_service: + class: stdClass + deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed. + public: true + new_factory: + class: FactoryClass + public: false + properties: { foo: bar } + factory_service: + class: Bar + factory: ['@foo.baz', getInstance] + public: true + new_factory_service: + class: FooBarBaz + properties: { foo: bar } + factory: ['@new_factory', getInstance] + public: true + service_from_static_method: + class: Bar\FooClass + factory: [Bar\FooClass, getInstance] + public: true + factory_simple: + class: SimpleFactoryClass + deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed. + public: false + arguments: ['foo'] + factory_service_simple: + class: Bar + factory: ['@factory_simple', getInstance] + public: true + lazy_context: + class: LazyContext + arguments: [!iterator {'k1': '@foo.baz', 'k2': '@service_container'}, !iterator []] + public: true + lazy_context_ignore_invalid_ref: + class: LazyContext + arguments: [!iterator ['@foo.baz', '@?invalid'], !iterator []] + public: true + tagged_iterator_foo: + class: Bar + tags: + - { name: foo } + public: false + tagged_iterator: + class: Bar + arguments: + - !tagged foo + public: true + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false + alias_for_foo: + alias: 'foo' + public: true + alias_for_alias: + alias: 'foo' + public: true diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_adawson.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_adawson.yml new file mode 100644 index 00000000..2a26f38a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_adawson.yml @@ -0,0 +1,28 @@ +services: + App\Db: + public: true + properties: + schema: '@App\Schema' + + App\Bus: + public: true + arguments: ['@App\Db'] + properties: + handler1: '@App\Handler1' + handler2: '@App\Handler2' + + App\Handler1: + ['@App\Db', '@App\Schema', '@App\Processor'] + + App\Handler2: + ['@App\Db', '@App\Schema', '@App\Processor'] + + App\Processor: + ['@App\Registry', '@App\Db'] + + App\Registry: + properties: + processor: ['@App\Db', '@App\Bus'] + + App\Schema: + arguments: ['@App\Db'] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_autoconfigure.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_autoconfigure.yml new file mode 100644 index 00000000..809c9f47 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_autoconfigure.yml @@ -0,0 +1,9 @@ + +services: + _defaults: + autoconfigure: true + + use_defaults_settings: ~ + + override_defaults_settings_to_false: + autoconfigure: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_autoconfigure_with_parent.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_autoconfigure_with_parent.yml new file mode 100644 index 00000000..c6e30801 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_autoconfigure_with_parent.yml @@ -0,0 +1,8 @@ +services: + parent_service: + class: stdClass + + child_service: + class: stdClass + autoconfigure: true + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_bindings.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_bindings.yml new file mode 100644 index 00000000..48ad0404 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_bindings.yml @@ -0,0 +1,16 @@ +services: + _defaults: + bind: + NonExistent: ~ + $quz: quz + $factory: factory + + bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar + autowire: true + bind: + Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface: '@Symfony\Component\DependencyInjection\Tests\Fixtures\Bar' + $foo: [ ~ ] + + Symfony\Component\DependencyInjection\Tests\Fixtures\Bar: + factory: [ ~, 'create' ] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_configurator_short_syntax.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_configurator_short_syntax.yml new file mode 100644 index 00000000..cc5c2be5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_configurator_short_syntax.yml @@ -0,0 +1,8 @@ +services: + foo_bar: + class: FooBarClass + configurator: foo_bar_configurator:configure + + foo_bar_with_static_call: + class: FooBarClass + configurator: FooBarConfigurator::configureFooBar diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_deep_graph.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_deep_graph.yml new file mode 100644 index 00000000..f16329ae --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_deep_graph.yml @@ -0,0 +1,24 @@ + +services: + foo: + class: Symfony\Component\DependencyInjection\Tests\Dumper\FooForDeepGraph + public: true + arguments: + - '@bar' + - !service + class: stdClass + properties: + p2: !service + class: stdClass + properties: + p3: !service + class: stdClass + + bar: + class: stdClass + public: true + properties: + p5: !service + class: stdClass + arguments: ['@foo'] + diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_defaults_with_parent.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_defaults_with_parent.yml new file mode 100644 index 00000000..28dec4ce --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_defaults_with_parent.yml @@ -0,0 +1,10 @@ +services: + _defaults: + autowire: true + + parent_service: + class: stdClass + + child_service: + class: stdClass + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_dump_load.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_dump_load.yml new file mode 100644 index 00000000..8f3e153a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_dump_load.yml @@ -0,0 +1,15 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + synthetic: true + foo: + autoconfigure: true + abstract: true + arguments: ['@!bar'] + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_inline.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_inline.yml new file mode 100644 index 00000000..b985cabd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_inline.yml @@ -0,0 +1,16 @@ + +services: + service_container: + class: Symfony\Component\DependencyInjection\ContainerInterface + public: true + synthetic: true + foo: + class: Class1 + public: true + arguments: [!service { class: Class2, arguments: [!service { class: Class2 }] }] + Psr\Container\ContainerInterface: + alias: service_container + public: false + Symfony\Component\DependencyInjection\ContainerInterface: + alias: service_container + public: false diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_instanceof.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_instanceof.yml new file mode 100644 index 00000000..a58cc079 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_instanceof.yml @@ -0,0 +1,11 @@ +services: + _instanceof: + Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface: + autowire: true + lazy: true + tags: + - { name: foo } + - { name: bar } + + Symfony\Component\DependencyInjection\Tests\Fixtures\Bar: ~ + Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface: '@Symfony\Component\DependencyInjection\Tests\Fixtures\Bar' diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_instanceof_with_parent.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_instanceof_with_parent.yml new file mode 100644 index 00000000..fb21cdf2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_instanceof_with_parent.yml @@ -0,0 +1,11 @@ +services: + _instanceof: + FooInterface: + autowire: true + + parent_service: + class: stdClass + + child_service: + class: stdClass + parent: parent_service diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_legacy_privates.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_legacy_privates.yml new file mode 100644 index 00000000..0fd20446 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_legacy_privates.yml @@ -0,0 +1,27 @@ +services: + _defaults: {public: true} + + foo: {class: stdClass, public: false} + + bar: + class: stdClass + arguments: [ '@private_not_inlined' ] + + private: {class: stdClass, public: false} + decorated_private: {class: stdClass} + decorated_private_alias: '@foo' + alias_to_private: '@private' + private_alias: {alias: foo, public: false} + + private_decorator: + class: stdClass + decorates: 'decorated_private' + + private_alias_decorator: + class: stdClass + decorates: 'decorated_private_alias' + + private_not_inlined: {class: stdClass, public: false} + private_not_removed: {class: stdClass, public: false} + + public_child: {parent: private, public: true} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_named_args.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_named_args.yml new file mode 100644 index 00000000..97e31014 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_named_args.yml @@ -0,0 +1,10 @@ +services: + Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy: { 0: ~, $apiKey: ABCD } + + another_one: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy + arguments: + $apiKey: ABCD + Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass: ~ + calls: + - ['setApiKey', { $apiKey: '123' }] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype.yml new file mode 100644 index 00000000..8c0b202a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype.yml @@ -0,0 +1,4 @@ +services: + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\: + resource: ../Prototype + exclude: '../Prototype/{OtherDir,BadClasses}' diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype_namespace.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype_namespace.yml new file mode 100644 index 00000000..5c30d011 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype_namespace.yml @@ -0,0 +1,10 @@ +services: + dir1: + namespace: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\ + resource: ../Prototype/OtherDir/*/Dir1 + tags: [foo] + + dir2: + namespace: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\ + resource: ../Prototype/OtherDir/*/Dir2 + tags: [bar] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype_namespace_without_resource.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype_namespace_without_resource.yml new file mode 100644 index 00000000..abd370ef --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_prototype_namespace_without_resource.yml @@ -0,0 +1,4 @@ +services: + dir1: + namespace: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\ + tags: [foo] diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_underscore.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_underscore.yml new file mode 100644 index 00000000..0cdbf903 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/services_underscore.yml @@ -0,0 +1,3 @@ +services: + _foo: + class: Foo diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_empty_string.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_empty_string.yml new file mode 100644 index 00000000..0ea5f53d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_empty_string.yml @@ -0,0 +1,6 @@ +services: + foo_service: + class: FooClass + tags: + # tag name is an empty string + - { name: '', foo: bar } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_no_string.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_no_string.yml new file mode 100644 index 00000000..f24cafd2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_no_string.yml @@ -0,0 +1,6 @@ +services: + foo_service: + class: FooClass + tags: + # tag name is not a string + - { name: [], foo: bar } diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_only.yml b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_only.yml new file mode 100644 index 00000000..90180b0b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/tag_name_only.yml @@ -0,0 +1,5 @@ +services: + foo_service: + class: FooClass + tags: + - foo diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/yaml_with_wrong_ext.ini b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/yaml_with_wrong_ext.ini new file mode 100644 index 00000000..1395458b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Fixtures/yaml/yaml_with_wrong_ext.ini @@ -0,0 +1,2 @@ +parameters: + with_wrong_ext: from yaml diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/LazyProxy/Instantiator/RealServiceInstantiatorTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/LazyProxy/Instantiator/RealServiceInstantiatorTest.php new file mode 100644 index 00000000..7f757297 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/LazyProxy/Instantiator/RealServiceInstantiatorTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\LazyProxy\Instantiator; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator; + +/** + * Tests for {@see \Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator}. + * + * @author Marco Pivetta + */ +class RealServiceInstantiatorTest extends TestCase +{ + public function testInstantiateProxy() + { + $instantiator = new RealServiceInstantiator(); + $instance = new \stdClass(); + $container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock(); + $callback = function () use ($instance) { + return $instance; + }; + + $this->assertSame($instance, $instantiator->instantiateProxy($container, new Definition(), 'foo', $callback)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/LazyProxy/PhpDumper/NullDumperTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/LazyProxy/PhpDumper/NullDumperTest.php new file mode 100644 index 00000000..5ae14932 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/LazyProxy/PhpDumper/NullDumperTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\LazyProxy\PhpDumper; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper; + +/** + * Tests for {@see \Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper}. + * + * @author Marco Pivetta + */ +class NullDumperTest extends TestCase +{ + public function testNullDumper() + { + $dumper = new NullDumper(); + $definition = new Definition('stdClass'); + + $this->assertFalse($dumper->isProxyCandidate($definition)); + $this->assertSame('', $dumper->getProxyFactoryCode($definition, 'foo', '(false)')); + $this->assertSame('', $dumper->getProxyCode($definition)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/ClosureLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/ClosureLoaderTest.php new file mode 100644 index 00000000..125e09b6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/ClosureLoaderTest.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; + +class ClosureLoaderTest extends TestCase +{ + public function testSupports() + { + $loader = new ClosureLoader(new ContainerBuilder()); + + $this->assertTrue($loader->supports(function ($container) {}), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns true if the resource is loadable'); + } + + public function testLoad() + { + $loader = new ClosureLoader($container = new ContainerBuilder()); + + $loader->load(function ($container) { + $container->setParameter('foo', 'foo'); + }); + + $this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a \Closure resource'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/DirectoryLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/DirectoryLoaderTest.php new file mode 100644 index 00000000..b4f969a0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/DirectoryLoaderTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\DirectoryLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class DirectoryLoaderTest extends TestCase +{ + private static $fixturesPath; + + private $container; + private $loader; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + } + + protected function setUp() + { + $locator = new FileLocator(self::$fixturesPath); + $this->container = new ContainerBuilder(); + $this->loader = new DirectoryLoader($this->container, $locator); + $resolver = new LoaderResolver([ + new PhpFileLoader($this->container, $locator), + new IniFileLoader($this->container, $locator), + new YamlFileLoader($this->container, $locator), + $this->loader, + ]); + $this->loader->setResolver($resolver); + } + + public function testDirectoryCanBeLoadedRecursively() + { + $this->loader->load('directory/'); + $this->assertEquals(['ini' => 'ini', 'yaml' => 'yaml', 'php' => 'php'], $this->container->getParameterBag()->all(), '->load() takes a single directory'); + } + + public function testImports() + { + $this->loader->resolve('directory/import/import.yml')->load('directory/import/import.yml'); + $this->assertEquals(['ini' => 'ini', 'yaml' => 'yaml'], $this->container->getParameterBag()->all(), '->load() takes a single file that imports a directory'); + } + + public function testExceptionIsRaisedWhenDirectoryDoesNotExist() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The file "foo" does not exist (in:'); + $this->loader->load('foo/'); + } + + public function testSupports() + { + $loader = new DirectoryLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('directory/'), '->supports("directory/") returns true'); + $this->assertTrue($loader->supports('directory/', 'directory'), '->supports("directory/", "directory") returns true'); + $this->assertFalse($loader->supports('directory'), '->supports("directory") returns false'); + $this->assertTrue($loader->supports('directory', 'directory'), '->supports("directory", "directory") returns true'); + $this->assertFalse($loader->supports('directory', 'foo'), '->supports("directory", "foo") returns false'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/FileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/FileLoaderTest.php new file mode 100644 index 00000000..ad0a30ba --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/FileLoaderTest.php @@ -0,0 +1,246 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Psr\Container\ContainerInterface as PsrContainerInterface; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\Loader\FileLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\MissingParent; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\FooInterface; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\AnotherSub\DeeperBaz; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\OtherDir\Baz; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\BarInterface; + +class FileLoaderTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../'); + } + + public function testImportWithGlobPattern() + { + $container = new ContainerBuilder(); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath)); + + $resolver = new LoaderResolver([ + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')), + new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')), + new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + ]); + + $loader->setResolver($resolver); + $loader->import('{F}ixtures/{xml,yaml}/services2.{yml,xml}'); + + $actual = $container->getParameterBag()->all(); + $expected = [ + 'a string', + 'foo' => 'bar', + 'values' => [ + 0, + 'integer' => 4, + 100 => null, + 'true', + true, + false, + 'on', + 'off', + 'float' => 1.3, + 1000.3, + 'a string', + ['foo', 'bar'], + ], + 'mixedcase' => ['MixedCaseKey' => 'value'], + 'constant' => \PHP_EOL, + 'bar' => '%foo%', + 'escape' => '@escapeme', + 'foo_bar' => new Reference('foo_bar'), + ]; + + $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files'); + } + + public function testRegisterClasses() + { + $container = new ContainerBuilder(); + $container->setParameter('sub_dir', 'Sub'); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + $loader->registerClasses(new Definition(), 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\\', 'Prototype/%sub_dir%/*'); + + $this->assertEquals( + ['service_container', Bar::class], + array_keys($container->getDefinitions()) + ); + $this->assertEquals( + [ + PsrContainerInterface::class, + ContainerInterface::class, + BarInterface::class, + ], + array_keys($container->getAliases()) + ); + } + + public function testRegisterClassesWithExclude() + { + $container = new ContainerBuilder(); + $container->setParameter('other_dir', 'OtherDir'); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + $loader->registerClasses( + new Definition(), + 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', + 'Prototype/*', + // load everything, except OtherDir/AnotherSub & Foo.php + 'Prototype/{%other_dir%/AnotherSub,Foo.php}' + ); + + $this->assertTrue($container->has(Bar::class)); + $this->assertTrue($container->has(Baz::class)); + $this->assertFalse($container->has(Foo::class)); + $this->assertFalse($container->has(DeeperBaz::class)); + + $this->assertEquals( + [ + PsrContainerInterface::class, + ContainerInterface::class, + BarInterface::class, + ], + array_keys($container->getAliases()) + ); + + $loader->registerClasses( + new Definition(), + 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', + 'Prototype/*', + 'Prototype/NotExistingDir' + ); + } + + public function testNestedRegisterClasses() + { + $container = new ContainerBuilder(); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + $prototype = new Definition(); + $prototype->setPublic(true)->setPrivate(true); + $loader->registerClasses($prototype, 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', 'Prototype/*'); + + $this->assertTrue($container->has(Bar::class)); + $this->assertTrue($container->has(Baz::class)); + $this->assertTrue($container->has(Foo::class)); + + $this->assertEquals( + [ + PsrContainerInterface::class, + ContainerInterface::class, + FooInterface::class, + ], + array_keys($container->getAliases()) + ); + + $alias = $container->getAlias(FooInterface::class); + $this->assertSame(Foo::class, (string) $alias); + $this->assertFalse($alias->isPublic()); + $this->assertFalse($alias->isPrivate()); + } + + public function testMissingParentClass() + { + $container = new ContainerBuilder(); + $container->setParameter('bad_classes_dir', 'BadClasses'); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + $loader->registerClasses( + (new Definition())->setPublic(false), + 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\BadClasses\\', + 'Prototype/%bad_classes_dir%/*' + ); + + $this->assertTrue($container->has(MissingParent::class)); + + $this->assertMatchesRegularExpression( + '{Class "?Symfony\\\\Component\\\\DependencyInjection\\\\Tests\\\\Fixtures\\\\Prototype\\\\BadClasses\\\\MissingClass"? not found}', + $container->getDefinition(MissingParent::class)->getErrors()[0] + ); + } + + public function testRegisterClassesWithBadPrefix() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Expected to find class "Symfony\\\Component\\\DependencyInjection\\\Tests\\\Fixtures\\\Prototype\\\Bar" in file ".+" while importing services from resource "Prototype\/Sub\/\*", but it was not found\! Check the namespace prefix used with the resource/'); + $container = new ContainerBuilder(); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + // the Sub is missing from namespace prefix + $loader->registerClasses(new Definition(), 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', 'Prototype/Sub/*'); + } + + /** + * @dataProvider getIncompatibleExcludeTests + */ + public function testRegisterClassesWithIncompatibleExclude($resourcePattern, $excludePattern) + { + $container = new ContainerBuilder(); + $loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures')); + + try { + $loader->registerClasses( + new Definition(), + 'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\', + $resourcePattern, + $excludePattern + ); + } catch (InvalidArgumentException $e) { + $this->assertEquals( + sprintf('Invalid "exclude" pattern when importing classes for "Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\": make sure your "exclude" pattern (%s) is a subset of the "resource" pattern (%s).', $excludePattern, $resourcePattern), + $e->getMessage() + ); + } + } + + public function getIncompatibleExcludeTests() + { + yield ['Prototype/*', 'yaml/*', false]; + yield ['Prototype/OtherDir/*', 'Prototype/*', false]; + } +} + +class TestFileLoader extends FileLoader +{ + public function load($resource, $type = null) + { + return $resource; + } + + public function supports($resource, $type = null) + { + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/GlobFileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/GlobFileLoaderTest.php new file mode 100644 index 00000000..74822f55 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/GlobFileLoaderTest.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\GlobFileLoader; + +class GlobFileLoaderTest extends TestCase +{ + public function testSupports() + { + $loader = new GlobFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('any-path', 'glob'), '->supports() returns true if the resource has the glob type'); + $this->assertFalse($loader->supports('any-path'), '->supports() returns false if the resource is not of glob type'); + } + + public function testLoadAddsTheGlobResourceToTheContainer() + { + $loader = new GlobFileLoaderWithoutImport($container = new ContainerBuilder(), new FileLocator()); + $loader->load(__DIR__.'/../Fixtures/config/*'); + + $this->assertEquals(new GlobResource(__DIR__.'/../Fixtures/config', '/*', false), $container->getResources()[1]); + } +} + +class GlobFileLoaderWithoutImport extends GlobFileLoader +{ + public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null) + { + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/IniFileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/IniFileLoaderTest.php new file mode 100644 index 00000000..8f261bfc --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/IniFileLoaderTest.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; + +class IniFileLoaderTest extends TestCase +{ + protected $container; + protected $loader; + + protected function setUp() + { + $this->container = new ContainerBuilder(); + $this->loader = new IniFileLoader($this->container, new FileLocator(realpath(__DIR__.'/../Fixtures/').'/ini')); + } + + public function testIniFileCanBeLoaded() + { + $this->loader->load('parameters.ini'); + $this->assertEquals(['foo' => 'bar', 'bar' => '%foo%'], $this->container->getParameterBag()->all(), '->load() takes a single file name as its first argument'); + } + + /** + * @dataProvider getTypeConversions + */ + public function testTypeConversions($key, $value, $supported) + { + $this->loader->load('types.ini'); + $parameters = $this->container->getParameterBag()->all(); + $this->assertSame($value, $parameters[$key], '->load() converts values to PHP types'); + } + + /** + * @dataProvider getTypeConversions + * @requires PHP 5.6.1 + * This test illustrates where our conversions differs from INI_SCANNER_TYPED introduced in PHP 5.6.1 + */ + public function testTypeConversionsWithNativePhp($key, $value, $supported) + { + if (\defined('HHVM_VERSION_ID')) { + $this->markTestSkipped(); + } + + if (!$supported) { + $this->markTestSkipped(sprintf('Converting the value "%s" to "%s" is not supported by the IniFileLoader.', $key, $value)); + } + + $expected = parse_ini_file(__DIR__.'/../Fixtures/ini/types.ini', true, \INI_SCANNER_TYPED); + $this->assertSame($value, $expected['parameters'][$key], '->load() converts values to PHP types'); + } + + public function getTypeConversions() + { + return [ + ['true_comment', true, true], + ['true', true, true], + ['false', false, true], + ['on', true, true], + ['off', false, true], + ['yes', true, true], + ['no', false, true], + ['none', false, true], + ['null', null, true], + ['constant', \PHP_VERSION, true], + ['12', 12, true], + ['12_string', '12', true], + ['12_quoted_number', 12, false], // INI_SCANNER_RAW removes the double quotes + ['12_comment', 12, true], + ['12_string_comment', '12', true], + ['12_quoted_number_comment', 12, false], // INI_SCANNER_RAW removes the double quotes + ['-12', -12, true], + ['1', 1, true], + ['0', 0, true], + ['0b0110', bindec('0b0110'), false], // not supported by INI_SCANNER_TYPED + ['11112222333344445555', '1111,2222,3333,4444,5555', true], + ['0777', 0777, false], // not supported by INI_SCANNER_TYPED + ['255', 0xFF, false], // not supported by INI_SCANNER_TYPED + ['100.0', 1e2, false], // not supported by INI_SCANNER_TYPED + ['-120.0', -1.2E2, false], // not supported by INI_SCANNER_TYPED + ['-10100.1', -10100.1, false], // not supported by INI_SCANNER_TYPED + ['-10,100.1', '-10,100.1', true], + ]; + } + + public function testExceptionIsRaisedWhenIniFileDoesNotExist() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The file "foo.ini" does not exist (in:'); + $this->loader->load('foo.ini'); + } + + public function testExceptionIsRaisedWhenIniFileCannotBeParsed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The "nonvalid.ini" file is not valid.'); + @$this->loader->load('nonvalid.ini'); + } + + public function testExceptionIsRaisedWhenIniFileIsAlmostValid() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The "almostvalid.ini" file is not valid.'); + @$this->loader->load('almostvalid.ini'); + } + + public function testSupports() + { + $loader = new IniFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.ini'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable'); + $this->assertTrue($loader->supports('with_wrong_ext.yml', 'ini'), '->supports() returns true if the resource with forced type is loadable'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/LoaderResolverTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/LoaderResolverTest.php new file mode 100644 index 00000000..9167e18c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/LoaderResolverTest.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\ClosureLoader; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + +class LoaderResolverTest extends TestCase +{ + private static $fixturesPath; + + /** @var LoaderResolver */ + private $resolver; + + protected function setUp() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + + $container = new ContainerBuilder(); + $this->resolver = new LoaderResolver([ + new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')), + new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')), + new ClosureLoader($container), + ]); + } + + public function provideResourcesToLoad() + { + return [ + ['ini_with_wrong_ext.xml', 'ini', IniFileLoader::class], + ['xml_with_wrong_ext.php', 'xml', XmlFileLoader::class], + ['php_with_wrong_ext.yml', 'php', PhpFileLoader::class], + ['yaml_with_wrong_ext.ini', 'yaml', YamlFileLoader::class], + ]; + } + + /** + * @dataProvider provideResourcesToLoad + */ + public function testResolvesForcedType($resource, $type, $expectedClass) + { + $this->assertInstanceOf($expectedClass, $this->resolver->resolve($resource, $type)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/PhpFileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/PhpFileLoaderTest.php new file mode 100644 index 00000000..e1812305 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/PhpFileLoaderTest.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Dumper\YamlDumper; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; + +class PhpFileLoaderTest extends TestCase +{ + public function testSupports() + { + $loader = new PhpFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.php'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable'); + $this->assertTrue($loader->supports('with_wrong_ext.yml', 'php'), '->supports() returns true if the resource with forced type is loadable'); + } + + public function testLoad() + { + $loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator()); + + $loader->load(__DIR__.'/../Fixtures/php/simple.php'); + + $this->assertEquals('foo', $container->getParameter('foo'), '->load() loads a PHP file resource'); + } + + public function testConfigServices() + { + $fixtures = realpath(__DIR__.'/../Fixtures'); + $loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator()); + $loader->load($fixtures.'/config/services9.php'); + + $container->compile(); + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile($fixtures.'/php/services9_compiled.php', str_replace(str_replace('\\', '\\\\', $fixtures.\DIRECTORY_SEPARATOR.'includes'.\DIRECTORY_SEPARATOR), '%path%', $dumper->dump())); + } + + /** + * @dataProvider provideConfig + */ + public function testConfig($file) + { + $fixtures = realpath(__DIR__.'/../Fixtures'); + $loader = new PhpFileLoader($container = new ContainerBuilder(), new FileLocator()); + $loader->load($fixtures.'/config/'.$file.'.php'); + + $container->compile(); + + $dumper = new YamlDumper($container); + $this->assertStringEqualsFile($fixtures.'/config/'.$file.'.expected.yml', $dumper->dump()); + } + + public function provideConfig() + { + yield ['basic']; + yield ['defaults']; + yield ['instanceof']; + yield ['prototype']; + yield ['child']; + + if (\PHP_VERSION_ID >= 70000) { + yield ['php7']; + } + } + + public function testAutoConfigureAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The service "child_service" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.'); + $fixtures = realpath(__DIR__.'/../Fixtures'); + $container = new ContainerBuilder(); + $loader = new PhpFileLoader($container, new FileLocator()); + $loader->load($fixtures.'/config/services_autoconfigure_with_parent.php'); + $container->compile(); + } + + public function testFactoryShortNotationNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid factory "factory:method": the `service:method` notation is not available when using PHP-based DI configuration. Use "[ref(\'factory\'), \'method\']" instead.'); + $fixtures = realpath(__DIR__.'/../Fixtures'); + $container = new ContainerBuilder(); + $loader = new PhpFileLoader($container, new FileLocator()); + $loader->load($fixtures.'/config/factory_short_notation.php'); + $container->compile(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/XmlFileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/XmlFileLoaderTest.php new file mode 100644 index 00000000..c65ebdcf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/XmlFileLoaderTest.php @@ -0,0 +1,833 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar; +use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype; +use Symfony\Component\ExpressionLanguage\Expression; + +class XmlFileLoaderTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + require_once self::$fixturesPath.'/includes/foo.php'; + require_once self::$fixturesPath.'/includes/ProjectExtension.php'; + require_once self::$fixturesPath.'/includes/ProjectWithXsdExtension.php'; + } + + public function testLoad() + { + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); + + try { + $loader->load('foo.xml'); + $this->fail('->load() throws an InvalidArgumentException if the loaded file does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the loaded file does not exist'); + $this->assertStringStartsWith('The file "foo.xml" does not exist (in:', $e->getMessage(), '->load() throws an InvalidArgumentException if the loaded file does not exist'); + } + } + + public function testParseFile() + { + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('parseFileToDOM'); + $m->setAccessible(true); + + try { + $m->invoke($loader, self::$fixturesPath.'/ini/parameters.ini'); + $this->fail('->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + $this->assertMatchesRegularExpression(sprintf('#^Unable to parse file ".+%s": .+.$#', 'parameters.ini'), $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + + $e = $e->getPrevious(); + $this->assertInstanceOf('InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + $this->assertStringStartsWith('[ERROR 4] Start tag expected, \'<\' not found (in', $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + } + + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/xml')); + + try { + $m->invoke($loader, self::$fixturesPath.'/xml/nonvalid.xml'); + $this->fail('->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + $this->assertMatchesRegularExpression(sprintf('#^Unable to parse file ".+%s": .+.$#', 'nonvalid.xml'), $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file is not a valid XML file'); + + $e = $e->getPrevious(); + $this->assertInstanceOf('InvalidArgumentException', $e, '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + $this->assertStringStartsWith('[ERROR 1845] Element \'nonvalid\': No matching global declaration available for the validation root. (in', $e->getMessage(), '->parseFileToDOM() throws an InvalidArgumentException if the loaded file does not validate the XSD'); + } + + $xml = $m->invoke($loader, self::$fixturesPath.'/xml/services1.xml'); + $this->assertInstanceOf('DOMDocument', $xml, '->parseFileToDOM() returns an SimpleXMLElement object'); + } + + public function testLoadWithExternalEntitiesDisabled() + { + if (\LIBXML_VERSION < 20900) { + $disableEntities = libxml_disable_entity_loader(true); + } + + $containerBuilder = new ContainerBuilder(); + $loader = new XmlFileLoader($containerBuilder, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services2.xml'); + + if (\LIBXML_VERSION < 20900) { + libxml_disable_entity_loader($disableEntities); + } + + $this->assertGreaterThan(0, $containerBuilder->getParameterBag()->all(), 'Parameters can be read from the config file.'); + } + + public function testLoadParameters() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services2.xml'); + + $actual = $container->getParameterBag()->all(); + $expected = [ + 'a string', + 'foo' => 'bar', + 'values' => [ + 0, + 'integer' => 4, + 100 => null, + 'true', + true, + false, + 'on', + 'off', + 'float' => 1.3, + 1000.3, + 'a string', + ['foo', 'bar'], + ], + 'mixedcase' => ['MixedCaseKey' => 'value'], + 'constant' => \PHP_EOL, + ]; + + $this->assertEquals($expected, $actual, '->load() converts XML values to PHP ones'); + } + + public function testLoadImports() + { + $container = new ContainerBuilder(); + $resolver = new LoaderResolver([ + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')), + new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yml')), + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + ]); + $loader->setResolver($resolver); + $loader->load('services4.xml'); + + $actual = $container->getParameterBag()->all(); + $expected = [ + 'a string', + 'foo' => 'bar', + 'values' => [ + 0, + 'integer' => 4, + 100 => null, + 'true', + true, + false, + 'on', + 'off', + 'float' => 1.3, + 1000.3, + 'a string', + ['foo', 'bar'], + ], + 'mixedcase' => ['MixedCaseKey' => 'value'], + 'constant' => \PHP_EOL, + 'bar' => '%foo%', + 'imported_from_ini' => true, + 'imported_from_yaml' => true, + 'with_wrong_ext' => 'from yaml', + ]; + + $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files'); + $this->assertTrue($actual['imported_from_ini']); + + // Bad import throws no exception due to ignore_errors value. + $loader->load('services4_bad_import.xml'); + } + + public function testLoadAnonymousServices() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services5.xml'); + $services = $container->getDefinitions(); + $this->assertCount(7, $services, '->load() attributes unique ids to anonymous services'); + + // anonymous service as an argument + $args = $services['foo']->getArguments(); + $this->assertCount(1, $args, '->load() references anonymous services as "normal" ones'); + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $args[0], '->load() converts anonymous services to references to "normal" services'); + $this->assertArrayHasKey((string) $args[0], $services, '->load() makes a reference to the created ones'); + $inner = $services[(string) $args[0]]; + $this->assertEquals('BarClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones'); + $this->assertFalse($inner->isPublic()); + + // inner anonymous services + $args = $inner->getArguments(); + $this->assertCount(1, $args, '->load() references anonymous services as "normal" ones'); + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $args[0], '->load() converts anonymous services to references to "normal" services'); + $this->assertArrayHasKey((string) $args[0], $services, '->load() makes a reference to the created ones'); + $inner = $services[(string) $args[0]]; + $this->assertEquals('BazClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones'); + $this->assertFalse($inner->isPublic()); + + // anonymous service as a property + $properties = $services['foo']->getProperties(); + $property = $properties['p']; + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Reference', $property, '->load() converts anonymous services to references to "normal" services'); + $this->assertArrayHasKey((string) $property, $services, '->load() makes a reference to the created ones'); + $inner = $services[(string) $property]; + $this->assertEquals('BuzClass', $inner->getClass(), '->load() uses the same configuration as for the anonymous ones'); + $this->assertFalse($inner->isPublic()); + + // "wild" service + $service = $container->findTaggedServiceIds('biz_tag'); + $this->assertCount(1, $service); + + foreach ($service as $id => $tag) { + $service = $container->getDefinition($id); + } + $this->assertEquals('BizClass', $service->getClass(), '->load() uses the same configuration as for the anonymous ones'); + $this->assertTrue($service->isPublic()); + + // anonymous services are shared when using decoration definitions + $container->compile(); + $services = $container->getDefinitions(); + $fooArgs = $services['foo']->getArguments(); + $barArgs = $services['bar']->getArguments(); + $this->assertSame($fooArgs[0], $barArgs[0]); + } + + /** + * @group legacy + * @expectedDeprecation Top-level anonymous services are deprecated since Symfony 3.4, the "id" attribute will be required in version 4.0 in %sservices_without_id.xml at line 5. + */ + public function testLoadAnonymousServicesWithoutId() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_without_id.xml'); + } + + public function testLoadAnonymousNestedServices() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('nested_service_without_id.xml'); + + $this->assertTrue($container->hasDefinition('FooClass')); + $arguments = $container->getDefinition('FooClass')->getArguments(); + $this->assertInstanceOf(Reference::class, array_shift($arguments)); + } + + public function testLoadServices() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services6.xml'); + $services = $container->getDefinitions(); + $this->assertArrayHasKey('foo', $services, '->load() parses elements'); + $this->assertFalse($services['not_shared']->isShared(), '->load() parses shared flag'); + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts element to Definition instances'); + $this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute'); + $this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag'); + $this->assertEquals(['foo', new Reference('foo'), [true, false]], $services['arguments']->getArguments(), '->load() parses the argument tags'); + $this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals([new Reference('baz'), 'configure'], $services['configurator2']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(['BazClass', 'configureStatic'], $services['configurator3']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals([['setBar', []], ['setBar', [new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')]]], $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals([['setBar', ['foo', new Reference('foo'), [true, false]]]], $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals('factory', $services['new_factory1']->getFactory(), '->load() parses the factory tag'); + $this->assertEquals([new Reference('baz'), 'getClass'], $services['new_factory2']->getFactory(), '->load() parses the factory tag'); + $this->assertEquals(['BazClass', 'getInstance'], $services['new_factory3']->getFactory(), '->load() parses the factory tag'); + $this->assertSame([null, 'getInstance'], $services['new_factory4']->getFactory(), '->load() accepts factory tag without class'); + + $aliases = $container->getAliases(); + $this->assertArrayHasKey('alias_for_foo', $aliases, '->load() parses elements'); + $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); + $this->assertTrue($aliases['alias_for_foo']->isPublic()); + $this->assertArrayHasKey('another_alias_for_foo', $aliases); + $this->assertEquals('foo', (string) $aliases['another_alias_for_foo']); + $this->assertFalse($aliases['another_alias_for_foo']->isPublic()); + + $this->assertEquals(['decorated', null, 0], $services['decorator_service']->getDecoratedService()); + $this->assertEquals(['decorated', 'decorated.pif-pouf', 0], $services['decorator_service_with_name']->getDecoratedService()); + $this->assertEquals(['decorated', 'decorated.pif-pouf', 5], $services['decorator_service_with_name_and_priority']->getDecoratedService()); + } + + public function testParsesIteratorArgument() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services9.xml'); + + $lazyDefinition = $container->getDefinition('lazy_context'); + + $this->assertEquals([new IteratorArgument(['k1' => new Reference('foo.baz'), 'k2' => new Reference('service_container')]), new IteratorArgument([])], $lazyDefinition->getArguments(), '->load() parses lazy arguments'); + } + + public function testParsesTags() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services10.xml'); + + $services = $container->findTaggedServiceIds('foo_tag'); + $this->assertCount(1, $services); + + foreach ($services as $id => $tagAttributes) { + foreach ($tagAttributes as $attributes) { + $this->assertArrayHasKey('other_option', $attributes); + $this->assertEquals('lorem', $attributes['other_option']); + $this->assertArrayHasKey('other-option', $attributes, 'unnormalized tag attributes should not be removed'); + + $this->assertEquals('ciz', $attributes['some_option'], 'no overriding should be done when normalizing'); + $this->assertEquals('cat', $attributes['some-option']); + + $this->assertArrayNotHasKey('an_other_option', $attributes, 'normalization should not be done when an underscore is already found'); + } + } + } + + public function testParseTagsWithoutNameThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('tag_without_name.xml'); + } + + public function testParseTagWithEmptyNameThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The tag name for service ".+" in .* must be a non-empty string/'); + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('tag_with_empty_name.xml'); + } + + public function testDeprecated() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_deprecated.xml'); + + $this->assertTrue($container->getDefinition('foo')->isDeprecated()); + $message = 'The "foo" service is deprecated. You should stop using it, as it will soon be removed.'; + $this->assertSame($message, $container->getDefinition('foo')->getDeprecationMessage('foo')); + + $this->assertTrue($container->getDefinition('bar')->isDeprecated()); + $message = 'The "bar" service is deprecated.'; + $this->assertSame($message, $container->getDefinition('bar')->getDeprecationMessage('bar')); + } + + public function testConvertDomElementToArray() + { + $doc = new \DOMDocument('1.0'); + $doc->loadXML('bar'); + $this->assertEquals('bar', XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument('1.0'); + $doc->loadXML(''); + $this->assertEquals(['foo' => 'bar'], XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument('1.0'); + $doc->loadXML('bar'); + $this->assertEquals(['foo' => 'bar'], XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument('1.0'); + $doc->loadXML('barbar'); + $this->assertEquals(['foo' => ['value' => 'bar', 'foo' => 'bar']], XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument('1.0'); + $doc->loadXML(''); + $this->assertEquals(['foo' => null], XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument('1.0'); + $doc->loadXML(''); + $this->assertEquals(['foo' => null], XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + + $doc = new \DOMDocument('1.0'); + $doc->loadXML(''); + $this->assertEquals(['foo' => [['foo' => 'bar'], ['foo' => 'bar']]], XmlFileLoader::convertDomElementToArray($doc->documentElement), '::convertDomElementToArray() converts a \DomElement to an array'); + } + + public function testExtensions() + { + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $container->registerExtension(new \ProjectWithXsdExtension()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + // extension without an XSD + $loader->load('extensions/services1.xml'); + $container->compile(); + $services = $container->getDefinitions(); + $parameters = $container->getParameterBag()->all(); + + $this->assertArrayHasKey('project.service.bar', $services, '->load() parses extension elements'); + $this->assertArrayHasKey('project.parameter.bar', $parameters, '->load() parses extension elements'); + + $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements'); + $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements'); + + // extension with an XSD + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $container->registerExtension(new \ProjectWithXsdExtension()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('extensions/services2.xml'); + $container->compile(); + $services = $container->getDefinitions(); + $parameters = $container->getParameterBag()->all(); + + $this->assertArrayHasKey('project.service.bar', $services, '->load() parses extension elements'); + $this->assertArrayHasKey('project.parameter.bar', $parameters, '->load() parses extension elements'); + + $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements'); + $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements'); + + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $container->registerExtension(new \ProjectWithXsdExtension()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + // extension with an XSD (does not validate) + try { + $loader->load('extensions/services3.xml'); + $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + $this->assertMatchesRegularExpression(sprintf('#^Unable to parse file ".+%s": .+.$#', 'services3.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + + $e = $e->getPrevious(); + $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + $this->assertStringContainsString('The attribute \'bar\' is not allowed', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } + + // non-registered extension + try { + $loader->load('extensions/services4.xml'); + $this->fail('->load() throws an InvalidArgumentException if the tag is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid'); + $this->assertStringStartsWith('There is no extension able to load the configuration for "project:bar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid'); + } + } + + public function testExtensionInPhar() + { + if (\extension_loaded('suhosin') && false === strpos(ini_get('suhosin.executor.include.whitelist'), 'phar')) { + $this->markTestSkipped('To run this test, add "phar" to the "suhosin.executor.include.whitelist" settings in your php.ini file.'); + } + if (\defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM makes this test conflict with those run in separate processes.'); + } + + require_once self::$fixturesPath.'/includes/ProjectWithXsdExtensionInPhar.phar'; + + // extension with an XSD in PHAR archive + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectWithXsdExtensionInPhar()); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('extensions/services6.xml'); + + // extension with an XSD in PHAR archive (does not validate) + try { + $loader->load('extensions/services7.xml'); + $this->fail('->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + $this->assertMatchesRegularExpression(sprintf('#^Unable to parse file ".+%s": .+.$#', 'services7.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + + $e = $e->getPrevious(); + $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + $this->assertStringContainsString('The attribute \'bar\' is not allowed', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration does not validate the XSD'); + } + } + + public function testSupports() + { + $loader = new XmlFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable'); + $this->assertTrue($loader->supports('with_wrong_ext.yml', 'xml'), '->supports() returns true if the resource with forced type is loadable'); + } + + public function testNoNamingConflictsForAnonymousServices() + { + $container = new ContainerBuilder(); + + $loader1 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension1')); + $loader1->load('services.xml'); + $services = $container->getDefinitions(); + $this->assertCount(3, $services, '->load() attributes unique ids to anonymous services'); + $loader2 = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml/extension2')); + $loader2->load('services.xml'); + $services = $container->getDefinitions(); + $this->assertCount(5, $services, '->load() attributes unique ids to anonymous services'); + + $services = $container->getDefinitions(); + $args1 = $services['extension1.foo']->getArguments(); + $inner1 = $services[(string) $args1[0]]; + $this->assertEquals('BarClass1', $inner1->getClass(), '->load() uses the same configuration as for the anonymous ones'); + $args2 = $services['extension2.foo']->getArguments(); + $inner2 = $services[(string) $args2[0]]; + $this->assertEquals('BarClass2', $inner2->getClass(), '->load() uses the same configuration as for the anonymous ones'); + } + + public function testDocTypeIsNotAllowed() + { + $container = new ContainerBuilder(); + + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + // document types are not allowed. + try { + $loader->load('withdoctype.xml'); + $this->fail('->load() throws an InvalidArgumentException if the configuration contains a document type'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Exception\\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration contains a document type'); + $this->assertMatchesRegularExpression(sprintf('#^Unable to parse file ".+%s": .+.$#', 'withdoctype.xml'), $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration contains a document type'); + + $e = $e->getPrevious(); + $this->assertInstanceOf('InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the configuration contains a document type'); + $this->assertSame('Document types are not allowed.', $e->getMessage(), '->load() throws an InvalidArgumentException if the configuration contains a document type'); + } + } + + public function testXmlNamespaces() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('namespaces.xml'); + $services = $container->getDefinitions(); + + $this->assertArrayHasKey('foo', $services, '->load() parses elements'); + $this->assertCount(1, $services['foo']->getTag('foo.tag'), '->load parses elements'); + $this->assertEquals([['setBar', ['foo']]], $services['foo']->getMethodCalls(), '->load() parses the tag'); + } + + public function testLoadIndexedArguments() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services14.xml'); + + $this->assertEquals(['index_0' => 'app'], $container->findDefinition('logger')->getArguments()); + } + + public function testLoadInlinedServices() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services21.xml'); + + $foo = $container->getDefinition('foo'); + + $fooFactory = $foo->getFactory(); + $this->assertInstanceOf(Reference::class, $fooFactory[0]); + $this->assertTrue($container->has((string) $fooFactory[0])); + $fooFactoryDefinition = $container->getDefinition((string) $fooFactory[0]); + $this->assertSame('FooFactory', $fooFactoryDefinition->getClass()); + $this->assertSame('createFoo', $fooFactory[1]); + + $fooFactoryFactory = $fooFactoryDefinition->getFactory(); + $this->assertInstanceOf(Reference::class, $fooFactoryFactory[0]); + $this->assertTrue($container->has((string) $fooFactoryFactory[0])); + $this->assertSame('Foobar', $container->getDefinition((string) $fooFactoryFactory[0])->getClass()); + $this->assertSame('createFooFactory', $fooFactoryFactory[1]); + + $fooConfigurator = $foo->getConfigurator(); + $this->assertInstanceOf(Reference::class, $fooConfigurator[0]); + $this->assertTrue($container->has((string) $fooConfigurator[0])); + $fooConfiguratorDefinition = $container->getDefinition((string) $fooConfigurator[0]); + $this->assertSame('Bar', $fooConfiguratorDefinition->getClass()); + $this->assertSame('configureFoo', $fooConfigurator[1]); + + $barConfigurator = $fooConfiguratorDefinition->getConfigurator(); + $this->assertInstanceOf(Reference::class, $barConfigurator[0]); + $this->assertSame('Baz', $container->getDefinition((string) $barConfigurator[0])->getClass()); + $this->assertSame('configureBar', $barConfigurator[1]); + } + + /** + * @group legacy + */ + public function testType() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services22.xml'); + + $this->assertEquals(['Bar', 'Baz'], $container->getDefinition('foo')->getAutowiringTypes()); + } + + public function testAutowire() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services23.xml'); + + $this->assertTrue($container->getDefinition('bar')->isAutowired()); + } + + public function testClassFromId() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('class_from_id.xml'); + $container->compile(); + + $this->assertEquals(CaseSensitiveClass::class, $container->getDefinition(CaseSensitiveClass::class)->getClass()); + } + + public function testPrototype() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_prototype.xml'); + + $ids = array_keys($container->getDefinitions()); + sort($ids); + $this->assertSame([Prototype\Foo::class, Prototype\Sub\Bar::class, 'service_container'], $ids); + + $resources = $container->getResources(); + + $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; + $resources = array_map('strval', $resources); + $this->assertContains((string) (new FileResource($fixturesDir.'xml'.\DIRECTORY_SEPARATOR.'services_prototype.xml')), $resources); + $this->assertContains((string) (new GlobResource($fixturesDir.'Prototype', '/*', true)), $resources); + $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo', $resources); + $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar', $resources); + } + + /** + * @group legacy + * @expectedDeprecation Using the attribute "class" is deprecated for the service "bar" which is defined as an alias %s. + * @expectedDeprecation Using the element "tag" is deprecated for the service "bar" which is defined as an alias %s. + * @expectedDeprecation Using the element "factory" is deprecated for the service "bar" which is defined as an alias %s. + */ + public function testAliasDefinitionContainsUnsupportedElements() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + + $loader->load('legacy_invalid_alias_definition.xml'); + + $this->assertTrue($container->has('bar')); + } + + public function testArgumentWithKeyOutsideCollection() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('with_key_outside_collection.xml'); + + $this->assertSame(['type' => 'foo', 'bar'], $container->getDefinition('foo')->getArguments()); + } + + public function testDefaults() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services28.xml'); + + $this->assertFalse($container->getDefinition('with_defaults')->isPublic()); + $this->assertSame(['foo' => [[]]], $container->getDefinition('with_defaults')->getTags()); + $this->assertTrue($container->getDefinition('with_defaults')->isAutowired()); + $this->assertArrayNotHasKey('public', $container->getDefinition('with_defaults')->getChanges()); + $this->assertArrayNotHasKey('autowire', $container->getDefinition('with_defaults')->getChanges()); + + $container->compile(); + + $this->assertTrue($container->getDefinition('no_defaults')->isPublic()); + + $this->assertSame(['foo' => [[]]], $container->getDefinition('no_defaults')->getTags()); + + $this->assertFalse($container->getDefinition('no_defaults')->isAutowired()); + + $this->assertTrue($container->getDefinition('child_def')->isPublic()); + $this->assertSame(['foo' => [[]]], $container->getDefinition('child_def')->getTags()); + $this->assertFalse($container->getDefinition('child_def')->isAutowired()); + + $definitions = $container->getDefinitions(); + $this->assertSame('service_container', key($definitions)); + + array_shift($definitions); + $anonymous = current($definitions); + $this->assertSame('bar', key($definitions)); + $this->assertTrue($anonymous->isPublic()); + $this->assertTrue($anonymous->isAutowired()); + $this->assertSame(['foo' => [[]]], $anonymous->getTags()); + } + + public function testNamedArguments() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_named_args.xml'); + + $this->assertEquals(['$apiKey' => 'ABCD', CaseSensitiveClass::class => null], $container->getDefinition(NamedArgumentsDummy::class)->getArguments()); + + $container->compile(); + + $this->assertEquals([null, 'ABCD'], $container->getDefinition(NamedArgumentsDummy::class)->getArguments()); + $this->assertEquals([['setApiKey', ['123']]], $container->getDefinition(NamedArgumentsDummy::class)->getMethodCalls()); + } + + public function testInstanceof() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_instanceof.xml'); + $container->compile(); + + $definition = $container->getDefinition(Bar::class); + $this->assertTrue($definition->isAutowired()); + $this->assertTrue($definition->isLazy()); + $this->assertSame(['foo' => [[]], 'bar' => [[]]], $definition->getTags()); + } + + public function testInstanceOfAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The service "child_service" cannot use the "parent" option in the same file where "instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.'); + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_instanceof_with_parent.xml'); + $container->compile(); + } + + public function testAutoConfigureAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The service "child_service" cannot have a "parent" and also have "autoconfigure". Try setting autoconfigure="false" for the service.'); + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_autoconfigure_with_parent.xml'); + $container->compile(); + } + + public function testDefaultsAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Attribute "autowire" on service "child_service" cannot be inherited from "defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.'); + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_defaults_with_parent.xml'); + $container->compile(); + } + + public function testAutoConfigureInstanceof() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_autoconfigure.xml'); + + $this->assertTrue($container->getDefinition('use_defaults_settings')->isAutoconfigured()); + $this->assertFalse($container->getDefinition('override_defaults_settings_to_false')->isAutoconfigured()); + } + + public function testBindings() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_bindings.xml'); + $container->compile(); + + $definition = $container->getDefinition('bar'); + $this->assertEquals([ + 'NonExistent' => null, + BarInterface::class => new Reference(Bar::class), + '$foo' => [null], + '$quz' => 'quz', + '$factory' => 'factory', + ], array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings())); + $this->assertEquals([ + 'quz', + null, + new Reference(Bar::class), + [null], + ], $definition->getArguments()); + + $definition = $container->getDefinition(Bar::class); + $this->assertEquals([ + null, + 'factory', + ], $definition->getArguments()); + $this->assertEquals([ + 'NonExistent' => null, + '$quz' => 'quz', + '$factory' => 'factory', + ], array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings())); + } + + public function testTsantosContainer() + { + $container = new ContainerBuilder(); + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('services_tsantos.xml'); + $container->compile(); + + $dumper = new PhpDumper($container); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services_tsantos.php', $dumper->dump()); + } + + /** + * The pass may throw an exception, which will cause the test to fail. + */ + public function testOverriddenDefaultsBindings() + { + $container = new ContainerBuilder(); + + $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')); + $loader->load('defaults_bindings.xml'); + $loader->load('defaults_bindings2.xml'); + + (new ResolveBindingsPass())->process($container); + + $this->assertSame('overridden', $container->get('bar')->quz); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/YamlFileLoaderTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/YamlFileLoaderTest.php new file mode 100644 index 00000000..3a5cc380 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/Loader/YamlFileLoaderTest.php @@ -0,0 +1,736 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\Config\Loader\LoaderResolver; +use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Resource\GlobResource; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\IniFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Bar; +use Symfony\Component\DependencyInjection\Tests\Fixtures\BarInterface; +use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass; +use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy; +use Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype; +use Symfony\Component\ExpressionLanguage\Expression; + +class YamlFileLoaderTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/../Fixtures/'); + require_once self::$fixturesPath.'/includes/foo.php'; + require_once self::$fixturesPath.'/includes/ProjectExtension.php'; + } + + public function testLoadUnExistFile() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The file ".+" does not exist./'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/ini')); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('loadFile'); + $m->setAccessible(true); + + $m->invoke($loader, 'foo.yml'); + } + + public function testLoadInvalidYamlFile() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The file ".+" does not contain valid YAML./'); + $path = self::$fixturesPath.'/ini'; + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator($path)); + $r = new \ReflectionObject($loader); + $m = $r->getMethod('loadFile'); + $m->setAccessible(true); + + $m->invoke($loader, $path.'/parameters.ini'); + } + + /** + * @dataProvider provideInvalidFiles + */ + public function testLoadInvalidFile($file) + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + + $loader->load($file.'.yml'); + } + + public function provideInvalidFiles() + { + return [ + ['bad_parameters'], + ['bad_imports'], + ['bad_import'], + ['bad_services'], + ['bad_service'], + ['bad_calls'], + ['bad_format'], + ['nonvalid1'], + ['nonvalid2'], + ]; + } + + public function testLoadParameters() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services2.yml'); + $this->assertEquals(['foo' => 'bar', 'mixedcase' => ['MixedCaseKey' => 'value'], 'values' => [true, false, 0, 1000.3, \PHP_INT_MAX], 'bar' => 'foo', 'escape' => '@escapeme', 'foo_bar' => new Reference('foo_bar')], $container->getParameterBag()->all(), '->load() converts YAML keys to lowercase'); + } + + public function testLoadImports() + { + $container = new ContainerBuilder(); + $resolver = new LoaderResolver([ + new IniFileLoader($container, new FileLocator(self::$fixturesPath.'/ini')), + new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml')), + new PhpFileLoader($container, new FileLocator(self::$fixturesPath.'/php')), + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')), + ]); + $loader->setResolver($resolver); + $loader->load('services4.yml'); + + $actual = $container->getParameterBag()->all(); + $expected = [ + 'foo' => 'bar', + 'values' => [true, false, \PHP_INT_MAX], + 'bar' => '%foo%', + 'escape' => '@escapeme', + 'foo_bar' => new Reference('foo_bar'), + 'mixedcase' => ['MixedCaseKey' => 'value'], + 'imported_from_ini' => true, + 'imported_from_xml' => true, + 'with_wrong_ext' => 'from yaml', + ]; + $this->assertEquals(array_keys($expected), array_keys($actual), '->load() imports and merges imported files'); + $this->assertTrue($actual['imported_from_ini']); + + // Bad import throws no exception due to ignore_errors value. + $loader->load('services4_bad_import.yml'); + } + + public function testLoadServices() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services6.yml'); + $services = $container->getDefinitions(); + $this->assertArrayHasKey('foo', $services, '->load() parses service elements'); + $this->assertFalse($services['not_shared']->isShared(), '->load() parses the shared flag'); + $this->assertInstanceOf('Symfony\\Component\\DependencyInjection\\Definition', $services['foo'], '->load() converts service element to Definition instances'); + $this->assertEquals('FooClass', $services['foo']->getClass(), '->load() parses the class attribute'); + $this->assertEquals('%path%/foo.php', $services['file']->getFile(), '->load() parses the file tag'); + $this->assertEquals(['foo', new Reference('foo'), [true, false]], $services['arguments']->getArguments(), '->load() parses the argument tags'); + $this->assertEquals('sc_configure', $services['configurator1']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals([new Reference('baz'), 'configure'], $services['configurator2']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals(['BazClass', 'configureStatic'], $services['configurator3']->getConfigurator(), '->load() parses the configurator tag'); + $this->assertEquals([['setBar', []], ['setBar', []], ['setBar', [new Expression('service("foo").foo() ~ (container.hasParameter("foo") ? parameter("foo") : "default")')]]], $services['method_call1']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals([['setBar', ['foo', new Reference('foo'), [true, false]]]], $services['method_call2']->getMethodCalls(), '->load() parses the method_call tag'); + $this->assertEquals('factory', $services['new_factory1']->getFactory(), '->load() parses the factory tag'); + $this->assertEquals([new Reference('baz'), 'getClass'], $services['new_factory2']->getFactory(), '->load() parses the factory tag'); + $this->assertEquals(['BazClass', 'getInstance'], $services['new_factory3']->getFactory(), '->load() parses the factory tag'); + $this->assertSame([null, 'getInstance'], $services['new_factory4']->getFactory(), '->load() accepts factory tag without class'); + $this->assertEquals(['foo', new Reference('baz')], $services['Acme\WithShortCutArgs']->getArguments(), '->load() parses short service definition'); + + $aliases = $container->getAliases(); + $this->assertArrayHasKey('alias_for_foo', $aliases, '->load() parses aliases'); + $this->assertEquals('foo', (string) $aliases['alias_for_foo'], '->load() parses aliases'); + $this->assertTrue($aliases['alias_for_foo']->isPublic()); + $this->assertArrayHasKey('another_alias_for_foo', $aliases); + $this->assertEquals('foo', (string) $aliases['another_alias_for_foo']); + $this->assertFalse($aliases['another_alias_for_foo']->isPublic()); + $this->assertTrue(isset($aliases['another_third_alias_for_foo'])); + $this->assertEquals('foo', (string) $aliases['another_third_alias_for_foo']); + $this->assertTrue($aliases['another_third_alias_for_foo']->isPublic()); + + $this->assertEquals(['decorated', null, 0], $services['decorator_service']->getDecoratedService()); + $this->assertEquals(['decorated', 'decorated.pif-pouf', 0], $services['decorator_service_with_name']->getDecoratedService()); + $this->assertEquals(['decorated', 'decorated.pif-pouf', 5], $services['decorator_service_with_name_and_priority']->getDecoratedService()); + } + + public function testLoadFactoryShortSyntax() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services14.yml'); + $services = $container->getDefinitions(); + + $this->assertEquals([new Reference('baz'), 'getClass'], $services['factory']->getFactory(), '->load() parses the factory tag with service:method'); + $this->assertEquals(['FooBacFactory', 'createFooBar'], $services['factory_with_static_call']->getFactory(), '->load() parses the factory tag with Class::method'); + } + + public function testLoadConfiguratorShortSyntax() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_configurator_short_syntax.yml'); + $services = $container->getDefinitions(); + + $this->assertEquals([new Reference('foo_bar_configurator'), 'configure'], $services['foo_bar']->getConfigurator(), '->load() parses the configurator tag with service:method'); + $this->assertEquals(['FooBarConfigurator', 'configureFooBar'], $services['foo_bar_with_static_call']->getConfigurator(), '->load() parses the configurator tag with Class::method'); + } + + public function testExtensions() + { + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services10.yml'); + $container->compile(); + $services = $container->getDefinitions(); + $parameters = $container->getParameterBag()->all(); + + $this->assertArrayHasKey('project.service.bar', $services, '->load() parses extension elements'); + $this->assertArrayHasKey('project.parameter.bar', $parameters, '->load() parses extension elements'); + + $this->assertEquals('BAR', $services['project.service.foo']->getClass(), '->load() parses extension elements'); + $this->assertEquals('BAR', $parameters['project.parameter.foo'], '->load() parses extension elements'); + + try { + $loader->load('services11.yml'); + $this->fail('->load() throws an InvalidArgumentException if the tag is not valid'); + } catch (\Exception $e) { + $this->assertInstanceOf('\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tag is not valid'); + $this->assertStringStartsWith('There is no extension able to load the configuration for "foobarfoobar" (in', $e->getMessage(), '->load() throws an InvalidArgumentException if the tag is not valid'); + } + } + + public function testExtensionWithNullConfig() + { + $container = new ContainerBuilder(); + $container->registerExtension(new \ProjectExtension()); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('null_config.yml'); + $container->compile(); + + $this->assertSame([null], $container->getParameter('project.configs')); + } + + public function testSupports() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator()); + + $this->assertTrue($loader->supports('foo.yml'), '->supports() returns true if the resource is loadable'); + $this->assertTrue($loader->supports('foo.yaml'), '->supports() returns true if the resource is loadable'); + $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable'); + $this->assertTrue($loader->supports('with_wrong_ext.xml', 'yml'), '->supports() returns true if the resource with forced type is loadable'); + $this->assertTrue($loader->supports('with_wrong_ext.xml', 'yaml'), '->supports() returns true if the resource with forced type is loadable'); + } + + public function testNonArrayTagsThrowsException() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + try { + $loader->load('badtag1.yml'); + $this->fail('->load() should throw an exception when the tags key of a service is not an array'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if the tags key is not an array'); + $this->assertStringStartsWith('Parameter "tags" must be an array for service', $e->getMessage(), '->load() throws an InvalidArgumentException if the tags key is not an array'); + } + } + + public function testTagWithoutNameThrowsException() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + try { + $loader->load('badtag2.yml'); + $this->fail('->load() should throw an exception when a tag is missing the name key'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag is missing the name key'); + $this->assertStringStartsWith('A "tags" entry is missing a "name" key for service ', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag is missing the name key'); + } + } + + public function testNameOnlyTagsAreAllowedAsString() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('tag_name_only.yml'); + + $this->assertCount(1, $container->getDefinition('foo_service')->getTag('foo')); + } + + public function testTagWithAttributeArrayThrowsException() + { + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + try { + $loader->load('badtag3.yml'); + $this->fail('->load() should throw an exception when a tag-attribute is not a scalar'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException', $e, '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar'); + $this->assertStringStartsWith('A "tags" attribute must be of a scalar-type for service "foo_service", tag "foo", attribute "bar"', $e->getMessage(), '->load() throws an InvalidArgumentException if a tag-attribute is not a scalar'); + } + } + + public function testLoadYamlOnlyWithKeys() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services21.yml'); + + $definition = $container->getDefinition('manager'); + $this->assertEquals([['setLogger', [new Reference('logger')]], ['setClass', ['User']]], $definition->getMethodCalls()); + $this->assertEquals([true], $definition->getArguments()); + $this->assertEquals(['manager' => [['alias' => 'user']]], $definition->getTags()); + } + + public function testTagWithEmptyNameThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The tag name for service ".+" in .+ must be a non-empty string/'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('tag_name_empty_string.yml'); + } + + public function testTagWithNonStringNameThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/The tag name for service ".+" in .+ must be a non-empty string/'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('tag_name_no_string.yml'); + } + + public function testTypesNotArray() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('bad_types1.yml'); + } + + public function testTypeNotString() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('bad_types2.yml'); + } + + /** + * @group legacy + */ + public function testTypes() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services22.yml'); + + $this->assertEquals(['Foo', 'Bar'], $container->getDefinition('foo_service')->getAutowiringTypes()); + $this->assertEquals(['Foo'], $container->getDefinition('baz_service')->getAutowiringTypes()); + } + + public function testParsesIteratorArgument() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services9.yml'); + + $lazyDefinition = $container->getDefinition('lazy_context'); + + $this->assertEquals([new IteratorArgument(['k1' => new Reference('foo.baz'), 'k2' => new Reference('service_container')]), new IteratorArgument([])], $lazyDefinition->getArguments(), '->load() parses lazy arguments'); + + $message = 'The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.'; + $this->assertSame($message, $container->getDefinition('deprecated_service')->getDeprecationMessage('deprecated_service')); + } + + public function testAutowire() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services23.yml'); + + $this->assertTrue($container->getDefinition('bar_service')->isAutowired()); + } + + public function testClassFromId() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('class_from_id.yml'); + $container->compile(); + + $this->assertEquals(CaseSensitiveClass::class, $container->getDefinition(CaseSensitiveClass::class)->getClass()); + } + + public function testPrototype() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_prototype.yml'); + + $ids = array_keys($container->getDefinitions()); + sort($ids); + $this->assertSame([Prototype\Foo::class, Prototype\Sub\Bar::class, 'service_container'], $ids); + + $resources = $container->getResources(); + + $fixturesDir = \dirname(__DIR__).\DIRECTORY_SEPARATOR.'Fixtures'.\DIRECTORY_SEPARATOR; + $resources = array_map('strval', $resources); + $this->assertContains((string) (new FileResource($fixturesDir.'yaml'.\DIRECTORY_SEPARATOR.'services_prototype.yml')), $resources); + $this->assertContains((string) (new GlobResource($fixturesDir.'Prototype', '', true)), $resources); + $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo', $resources); + $this->assertContains('reflection.Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar', $resources); + } + + public function testPrototypeWithNamespace() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_prototype_namespace.yml'); + + $ids = array_keys($container->getDefinitions()); + sort($ids); + + $this->assertSame([ + Prototype\OtherDir\Component1\Dir1\Service1::class, + Prototype\OtherDir\Component1\Dir2\Service2::class, + Prototype\OtherDir\Component2\Dir1\Service4::class, + Prototype\OtherDir\Component2\Dir2\Service5::class, + 'service_container', + ], $ids); + + $this->assertTrue($container->getDefinition(Prototype\OtherDir\Component1\Dir1\Service1::class)->hasTag('foo')); + $this->assertTrue($container->getDefinition(Prototype\OtherDir\Component2\Dir1\Service4::class)->hasTag('foo')); + $this->assertFalse($container->getDefinition(Prototype\OtherDir\Component1\Dir1\Service1::class)->hasTag('bar')); + $this->assertFalse($container->getDefinition(Prototype\OtherDir\Component2\Dir1\Service4::class)->hasTag('bar')); + + $this->assertTrue($container->getDefinition(Prototype\OtherDir\Component1\Dir2\Service2::class)->hasTag('bar')); + $this->assertTrue($container->getDefinition(Prototype\OtherDir\Component2\Dir2\Service5::class)->hasTag('bar')); + $this->assertFalse($container->getDefinition(Prototype\OtherDir\Component1\Dir2\Service2::class)->hasTag('foo')); + $this->assertFalse($container->getDefinition(Prototype\OtherDir\Component2\Dir2\Service5::class)->hasTag('foo')); + } + + public function testPrototypeWithNamespaceAndNoResource() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/A "resource" attribute must be set when the "namespace" attribute is set for service ".+" in .+/'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_prototype_namespace_without_resource.yml'); + } + + public function testDefaults() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services28.yml'); + + $this->assertFalse($container->getDefinition('with_defaults')->isPublic()); + $this->assertSame(['foo' => [[]]], $container->getDefinition('with_defaults')->getTags()); + $this->assertTrue($container->getDefinition('with_defaults')->isAutowired()); + $this->assertArrayNotHasKey('public', $container->getDefinition('with_defaults')->getChanges()); + $this->assertArrayNotHasKey('autowire', $container->getDefinition('with_defaults')->getChanges()); + + $this->assertFalse($container->getAlias('with_defaults_aliased')->isPublic()); + $this->assertFalse($container->getAlias('with_defaults_aliased_short')->isPublic()); + + $this->assertFalse($container->getDefinition('Acme\WithShortCutArgs')->isPublic()); + $this->assertSame(['foo' => [[]]], $container->getDefinition('Acme\WithShortCutArgs')->getTags()); + $this->assertTrue($container->getDefinition('Acme\WithShortCutArgs')->isAutowired()); + + $container->compile(); + + $this->assertTrue($container->getDefinition('with_null')->isPublic()); + $this->assertTrue($container->getDefinition('no_defaults')->isPublic()); + + // foo tag is inherited from defaults + $this->assertSame(['foo' => [[]]], $container->getDefinition('with_null')->getTags()); + $this->assertSame(['foo' => [[]]], $container->getDefinition('no_defaults')->getTags()); + + $this->assertTrue($container->getDefinition('with_null')->isAutowired()); + $this->assertFalse($container->getDefinition('no_defaults')->isAutowired()); + + $this->assertTrue($container->getDefinition('child_def')->isPublic()); + $this->assertSame(['foo' => [[]]], $container->getDefinition('child_def')->getTags()); + $this->assertFalse($container->getDefinition('child_def')->isAutowired()); + } + + public function testNamedArguments() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_named_args.yml'); + + $this->assertEquals([null, '$apiKey' => 'ABCD'], $container->getDefinition(NamedArgumentsDummy::class)->getArguments()); + $this->assertEquals(['$apiKey' => 'ABCD', CaseSensitiveClass::class => null], $container->getDefinition('another_one')->getArguments()); + + $container->compile(); + + $this->assertEquals([null, 'ABCD'], $container->getDefinition(NamedArgumentsDummy::class)->getArguments()); + $this->assertEquals([null, 'ABCD'], $container->getDefinition('another_one')->getArguments()); + $this->assertEquals([['setApiKey', ['123']]], $container->getDefinition('another_one')->getMethodCalls()); + } + + public function testInstanceof() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_instanceof.yml'); + $container->compile(); + + $definition = $container->getDefinition(Bar::class); + $this->assertTrue($definition->isAutowired()); + $this->assertTrue($definition->isLazy()); + $this->assertSame(['foo' => [[]], 'bar' => [[]]], $definition->getTags()); + } + + public function testInstanceOfAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The service "child_service" cannot use the "parent" option in the same file where "_instanceof" configuration is defined as using both is not supported. Move your child definitions to a separate file.'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_instanceof_with_parent.yml'); + $container->compile(); + } + + public function testAutoConfigureAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The service "child_service" cannot have a "parent" and also have "autoconfigure". Try setting "autoconfigure: false" for the service.'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_autoconfigure_with_parent.yml'); + $container->compile(); + } + + public function testDefaultsAndChildDefinitionNotAllowed() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Attribute "autowire" on service "child_service" cannot be inherited from "_defaults" when a "parent" is set. Move your child definitions to a separate file or define this attribute explicitly.'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_defaults_with_parent.yml'); + $container->compile(); + } + + public function testDecoratedServicesWithWrongSyntaxThrowsException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The value of the "decorates" option for the "bar" service must be the id of the service without the "@" prefix (replace "@foo" with "foo").'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('bad_decorates.yml'); + } + + public function testInvalidTagsWithDefaults() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Parameter "tags" must be an array for service "Foo\\\Bar" in ".+services31_invalid_tags\.yml"\. Check your YAML syntax./'); + $loader = new YamlFileLoader(new ContainerBuilder(), new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services31_invalid_tags.yml'); + } + + /** + * @group legacy + * @expectedDeprecation Service names that start with an underscore are deprecated since Symfony 3.3 and will be reserved in 4.0. Rename the "_foo" service or define it in XML instead. + */ + public function testUnderscoreServiceId() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_underscore.yml'); + } + + public function testAnonymousServices() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('anonymous_services.yml'); + + $definition = $container->getDefinition('Foo'); + $this->assertTrue($definition->isAutowired()); + + // Anonymous service in an argument + $args = $definition->getArguments(); + $this->assertCount(1, $args); + $this->assertInstanceOf(Reference::class, $args[0]); + $this->assertTrue($container->has((string) $args[0])); + $this->assertMatchesRegularExpression('/^\d+_Bar~[._A-Za-z0-9]{7}$/', (string) $args[0]); + + $anonymous = $container->getDefinition((string) $args[0]); + $this->assertEquals('Bar', $anonymous->getClass()); + $this->assertFalse($anonymous->isPublic()); + $this->assertTrue($anonymous->isAutowired()); + + // Anonymous service in a callable + $factory = $definition->getFactory(); + $this->assertIsArray($factory); + $this->assertInstanceOf(Reference::class, $factory[0]); + $this->assertTrue($container->has((string) $factory[0])); + $this->assertMatchesRegularExpression('/^\d+_Quz~[._A-Za-z0-9]{7}$/', (string) $factory[0]); + $this->assertEquals('constructFoo', $factory[1]); + + $anonymous = $container->getDefinition((string) $factory[0]); + $this->assertEquals('Quz', $anonymous->getClass()); + $this->assertFalse($anonymous->isPublic()); + $this->assertFalse($anonymous->isAutowired()); + } + + public function testAnonymousServicesInDifferentFilesWithSameNameDoNotConflict() + { + $container = new ContainerBuilder(); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml/foo')); + $loader->load('services.yml'); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml/bar')); + $loader->load('services.yml'); + + $this->assertCount(5, $container->getDefinitions()); + } + + public function testAnonymousServicesInInstanceof() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('anonymous_services_in_instanceof.yml'); + + $definition = $container->getDefinition('Dummy'); + + $instanceof = $definition->getInstanceofConditionals(); + $this->assertCount(3, $instanceof); + $this->assertArrayHasKey('DummyInterface', $instanceof); + + $args = $instanceof['DummyInterface']->getProperties(); + $this->assertCount(1, $args); + $this->assertInstanceOf(Reference::class, $args['foo']); + $this->assertTrue($container->has((string) $args['foo'])); + + $anonymous = $container->getDefinition((string) $args['foo']); + $this->assertEquals('Anonymous', $anonymous->getClass()); + $this->assertFalse($anonymous->isPublic()); + $this->assertEmpty($anonymous->getInstanceofConditionals()); + + $this->assertFalse($container->has('Bar')); + } + + public function testAnonymousServicesWithAliases() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Creating an alias using the tag "!service" is not allowed in ".+anonymous_services_alias\.yml"\./'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('anonymous_services_alias.yml'); + } + + public function testAnonymousServicesInParameters() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Using an anonymous service in a parameter is not allowed in ".+anonymous_services_in_parameters\.yml"\./'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('anonymous_services_in_parameters.yml'); + } + + public function testAutoConfigureInstanceof() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_autoconfigure.yml'); + + $this->assertTrue($container->getDefinition('use_defaults_settings')->isAutoconfigured()); + $this->assertFalse($container->getDefinition('override_defaults_settings_to_false')->isAutoconfigured()); + } + + public function testEmptyDefaultsThrowsClearException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Service "_defaults" key must be an array, "NULL" given in ".+bad_empty_defaults\.yml"\./'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('bad_empty_defaults.yml'); + } + + public function testEmptyInstanceofThrowsClearException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $this->expectExceptionMessageMatches('/Service "_instanceof" key must be an array, "NULL" given in ".+bad_empty_instanceof\.yml"\./'); + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('bad_empty_instanceof.yml'); + } + + public function testBindings() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('services_bindings.yml'); + $container->compile(); + + $definition = $container->getDefinition('bar'); + $this->assertEquals([ + 'NonExistent' => null, + BarInterface::class => new Reference(Bar::class), + '$foo' => [null], + '$quz' => 'quz', + '$factory' => 'factory', + ], array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings())); + $this->assertEquals([ + 'quz', + null, + new Reference(Bar::class), + [null], + ], $definition->getArguments()); + + $definition = $container->getDefinition(Bar::class); + $this->assertEquals([ + null, + 'factory', + ], $definition->getArguments()); + $this->assertEquals([ + 'NonExistent' => null, + '$quz' => 'quz', + '$factory' => 'factory', + ], array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings())); + } + + /** + * The pass may throw an exception, which will cause the test to fail. + */ + public function testOverriddenDefaultsBindings() + { + $container = new ContainerBuilder(); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('defaults_bindings.yml'); + $loader->load('defaults_bindings2.yml'); + + (new ResolveBindingsPass())->process($container); + + $this->assertSame('overridden', $container->get('bar')->quz); + } + + /** + * @group legacy + * @expectedDeprecation The configuration key "factory" is unsupported for the service "foo" which is defined as an alias in %s. + * @expectedDeprecation The configuration key "parent" is unsupported for the service "foo" which is defined as an alias in %s. + */ + public function testAliasDefinitionContainsUnsupportedElements() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('legacy_invalid_alias_definition.yml'); + $this->assertTrue($container->has('foo')); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php new file mode 100644 index 00000000..273072f9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/EnvPlaceholderParameterBagTest.php @@ -0,0 +1,159 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\ParameterBag; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; + +class EnvPlaceholderParameterBagTest extends TestCase +{ + public function testGetThrowsInvalidArgumentExceptionIfEnvNameContainsNonWordCharacters() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException'); + $bag = new EnvPlaceholderParameterBag(); + $bag->get('env(%foo%)'); + } + + public function testMergeWillNotDuplicateIdenticalParameters() + { + $envVariableName = 'DB_HOST'; + $parameter = sprintf('env(%s)', $envVariableName); + $firstBag = new EnvPlaceholderParameterBag(); + + // initialize placeholders + $firstBag->get($parameter); + $secondBag = clone $firstBag; + + $firstBag->mergeEnvPlaceholders($secondBag); + $mergedPlaceholders = $firstBag->getEnvPlaceholders(); + + $placeholderForVariable = $mergedPlaceholders[$envVariableName]; + $placeholder = array_values($placeholderForVariable)[0]; + + $this->assertCount(1, $placeholderForVariable); + $this->assertIsString($placeholder); + $this->assertStringContainsString($envVariableName, $placeholder); + } + + public function testMergeWhereFirstBagIsEmptyWillWork() + { + $envVariableName = 'DB_HOST'; + $parameter = sprintf('env(%s)', $envVariableName); + $firstBag = new EnvPlaceholderParameterBag(); + $secondBag = new EnvPlaceholderParameterBag(); + + // initialize placeholder only in second bag + $secondBag->get($parameter); + + $this->assertEmpty($firstBag->getEnvPlaceholders()); + + $firstBag->mergeEnvPlaceholders($secondBag); + $mergedPlaceholders = $firstBag->getEnvPlaceholders(); + + $placeholderForVariable = $mergedPlaceholders[$envVariableName]; + $placeholder = array_values($placeholderForVariable)[0]; + + $this->assertCount(1, $placeholderForVariable); + $this->assertIsString($placeholder); + $this->assertStringContainsString($envVariableName, $placeholder); + } + + public function testMergeWherePlaceholderOnlyExistsInSecond() + { + $uniqueEnvName = 'DB_HOST'; + $commonEnvName = 'DB_USER'; + + $uniqueParamName = sprintf('env(%s)', $uniqueEnvName); + $commonParamName = sprintf('env(%s)', $commonEnvName); + + $firstBag = new EnvPlaceholderParameterBag(); + // initialize common placeholder + $firstBag->get($commonParamName); + $secondBag = clone $firstBag; + + // initialize unique placeholder + $secondBag->get($uniqueParamName); + + $firstBag->mergeEnvPlaceholders($secondBag); + $merged = $firstBag->getEnvPlaceholders(); + + $this->assertCount(1, $merged[$uniqueEnvName]); + // second bag has same placeholder for commonEnvName + $this->assertCount(1, $merged[$commonEnvName]); + } + + public function testMergeWithDifferentIdentifiersForPlaceholders() + { + $envName = 'DB_USER'; + $paramName = sprintf('env(%s)', $envName); + + $firstBag = new EnvPlaceholderParameterBag(); + $secondBag = new EnvPlaceholderParameterBag(); + // initialize placeholders + $firstPlaceholder = $firstBag->get($paramName); + $secondPlaceholder = $secondBag->get($paramName); + + $firstBag->mergeEnvPlaceholders($secondBag); + $merged = $firstBag->getEnvPlaceholders(); + + $this->assertNotEquals($firstPlaceholder, $secondPlaceholder); + $this->assertCount(2, $merged[$envName]); + } + + public function testResolveEnvCastsIntToString() + { + $bag = new EnvPlaceholderParameterBag(); + $bag->get('env(INT_VAR)'); + $bag->set('env(INT_VAR)', 2); + $bag->resolve(); + $this->assertSame('2', $bag->all()['env(INT_VAR)']); + } + + public function testResolveEnvAllowsNull() + { + $bag = new EnvPlaceholderParameterBag(); + $bag->get('env(NULL_VAR)'); + $bag->set('env(NULL_VAR)', null); + $bag->resolve(); + $this->assertNull($bag->all()['env(NULL_VAR)']); + } + + public function testResolveThrowsOnBadDefaultValue() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The default value of env parameter "ARRAY_VAR" must be scalar or null, "array" given.'); + $bag = new EnvPlaceholderParameterBag(); + $bag->get('env(ARRAY_VAR)'); + $bag->set('env(ARRAY_VAR)', []); + $bag->resolve(); + } + + public function testGetEnvAllowsNull() + { + $bag = new EnvPlaceholderParameterBag(); + $bag->set('env(NULL_VAR)', null); + $bag->get('env(NULL_VAR)'); + $bag->resolve(); + + $this->assertNull($bag->all()['env(NULL_VAR)']); + } + + public function testGetThrowsOnBadDefaultValue() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\RuntimeException'); + $this->expectExceptionMessage('The default value of an env() parameter must be scalar or null, but "array" given to "env(ARRAY_VAR)".'); + $bag = new EnvPlaceholderParameterBag(); + $bag->set('env(ARRAY_VAR)', []); + $bag->get('env(ARRAY_VAR)'); + $bag->resolve(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/FrozenParameterBagTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/FrozenParameterBagTest.php new file mode 100644 index 00000000..ed89c8e4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/FrozenParameterBagTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\ParameterBag; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; + +class FrozenParameterBagTest extends TestCase +{ + public function testConstructor() + { + $parameters = [ + 'foo' => 'foo', + 'bar' => 'bar', + ]; + $bag = new FrozenParameterBag($parameters); + $this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument'); + } + + public function testClear() + { + $this->expectException('LogicException'); + $bag = new FrozenParameterBag([]); + $bag->clear(); + } + + public function testSet() + { + $this->expectException('LogicException'); + $bag = new FrozenParameterBag([]); + $bag->set('foo', 'bar'); + } + + public function testAdd() + { + $this->expectException('LogicException'); + $bag = new FrozenParameterBag([]); + $bag->add([]); + } + + public function testRemove() + { + $this->expectException('LogicException'); + $bag = new FrozenParameterBag(['foo' => 'bar']); + $bag->remove('foo'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/ParameterBagTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/ParameterBagTest.php new file mode 100644 index 00000000..9b39458c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterBag/ParameterBagTest.php @@ -0,0 +1,264 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\ParameterBag; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException; +use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException; +use Symfony\Component\DependencyInjection\Exception\RuntimeException; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; + +class ParameterBagTest extends TestCase +{ + public function testConstructor() + { + $bag = new ParameterBag($parameters = [ + 'foo' => 'foo', + 'bar' => 'bar', + ]); + $this->assertEquals($parameters, $bag->all(), '__construct() takes an array of parameters as its first argument'); + } + + public function testClear() + { + $bag = new ParameterBag($parameters = [ + 'foo' => 'foo', + 'bar' => 'bar', + ]); + $bag->clear(); + $this->assertEquals([], $bag->all(), '->clear() removes all parameters'); + } + + public function testRemove() + { + $bag = new ParameterBag([ + 'foo' => 'foo', + 'bar' => 'bar', + ]); + $bag->remove('foo'); + $this->assertEquals(['bar' => 'bar'], $bag->all(), '->remove() removes a parameter'); + } + + public function testGetSet() + { + $bag = new ParameterBag(['foo' => 'bar']); + $bag->set('bar', 'foo'); + $this->assertEquals('foo', $bag->get('bar'), '->set() sets the value of a new parameter'); + + $bag->set('foo', 'baz'); + $this->assertEquals('baz', $bag->get('foo'), '->set() overrides previously set parameter'); + + try { + $bag->get('baba'); + $this->fail('->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException', $e, '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); + $this->assertEquals('You have requested a non-existent parameter "baba".', $e->getMessage(), '->get() throws an Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException if the key does not exist'); + } + } + + /** + * @dataProvider provideGetThrowParameterNotFoundExceptionData + */ + public function testGetThrowParameterNotFoundException($parameterKey, $exceptionMessage) + { + $bag = new ParameterBag([ + 'foo' => 'foo', + 'bar' => 'bar', + 'baz' => 'baz', + 'fiz' => ['bar' => ['boo' => 12]], + ]); + + $this->expectException(ParameterNotFoundException::class); + $this->expectExceptionMessage($exceptionMessage); + + $bag->get($parameterKey); + } + + public function provideGetThrowParameterNotFoundExceptionData() + { + return [ + ['foo1', 'You have requested a non-existent parameter "foo1". Did you mean this: "foo"?'], + ['bag', 'You have requested a non-existent parameter "bag". Did you mean one of these: "bar", "baz"?'], + ['', 'You have requested a non-existent parameter "".'], + + ['fiz.bar.boo', 'You have requested a non-existent parameter "fiz.bar.boo". You cannot access nested array items, do you want to inject "fiz" instead?'], + ]; + } + + public function testHas() + { + $bag = new ParameterBag(['foo' => 'bar']); + $this->assertTrue($bag->has('foo'), '->has() returns true if a parameter is defined'); + $this->assertFalse($bag->has('bar'), '->has() returns false if a parameter is not defined'); + } + + /** + * @group legacy + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "BAR" instead of "bar" is deprecated since Symfony 3.4. + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.4. + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "FOO" instead of "foo" is deprecated since Symfony 3.4. + * @expectedDeprecation Parameter names will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since Symfony 3.4. + */ + public function testMixedCase() + { + $bag = new ParameterBag([ + 'foo' => 'foo', + 'bar' => 'bar', + ]); + + $bag->remove('BAR'); + $this->assertEquals(['foo' => 'foo'], $bag->all(), '->remove() converts key to lowercase before removing'); + + $bag->set('Foo', 'baz1'); + $this->assertEquals('baz1', $bag->get('foo'), '->set() converts the key to lowercase'); + $this->assertEquals('baz1', $bag->get('FOO'), '->get() converts the key to lowercase'); + + $this->assertTrue($bag->has('Foo'), '->has() converts the key to lowercase'); + } + + public function testResolveValue() + { + $bag = new ParameterBag([]); + $this->assertEquals('foo', $bag->resolveValue('foo'), '->resolveValue() returns its argument unmodified if no placeholders are found'); + + $bag = new ParameterBag(['foo' => 'bar']); + $this->assertEquals('I\'m a bar', $bag->resolveValue('I\'m a %foo%'), '->resolveValue() replaces placeholders by their values'); + $this->assertEquals(['bar' => 'bar'], $bag->resolveValue(['%foo%' => '%foo%']), '->resolveValue() replaces placeholders in keys and values of arrays'); + $this->assertEquals(['bar' => ['bar' => ['bar' => 'bar']]], $bag->resolveValue(['%foo%' => ['%foo%' => ['%foo%' => '%foo%']]]), '->resolveValue() replaces placeholders in nested arrays'); + $this->assertEquals('I\'m a %%foo%%', $bag->resolveValue('I\'m a %%foo%%'), '->resolveValue() supports % escaping by doubling it'); + $this->assertEquals('I\'m a bar %%foo bar', $bag->resolveValue('I\'m a %foo% %%foo %foo%'), '->resolveValue() supports % escaping by doubling it'); + $this->assertEquals(['foo' => ['bar' => ['ding' => 'I\'m a bar %%foo %%bar']]], $bag->resolveValue(['foo' => ['bar' => ['ding' => 'I\'m a bar %%foo %%bar']]]), '->resolveValue() supports % escaping by doubling it'); + + $bag = new ParameterBag(['foo' => true]); + $this->assertTrue($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings'); + $bag = new ParameterBag(['foo' => null]); + $this->assertNull($bag->resolveValue('%foo%'), '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings'); + + $bag = new ParameterBag(['foo' => 'bar', 'baz' => '%%%foo% %foo%%% %%foo%% %%%foo%%%']); + $this->assertEquals('%%bar bar%% %%foo%% %%bar%%', $bag->resolveValue('%baz%'), '->resolveValue() replaces params placed besides escaped %'); + + $bag = new ParameterBag(['baz' => '%%s?%%s']); + $this->assertEquals('%%s?%%s', $bag->resolveValue('%baz%'), '->resolveValue() is not replacing greedily'); + + $bag = new ParameterBag([]); + try { + $bag->resolveValue('%foobar%'); + $this->fail('->resolveValue() throws an InvalidArgumentException if a placeholder references a non-existent parameter'); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter'); + } + + try { + $bag->resolveValue('foo %foobar% bar'); + $this->fail('->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter'); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('You have requested a non-existent parameter "foobar".', $e->getMessage(), '->resolveValue() throws a ParameterNotFoundException if a placeholder references a non-existent parameter'); + } + + $bag = new ParameterBag(['foo' => 'a %bar%', 'bar' => []]); + try { + $bag->resolveValue('%foo%'); + $this->fail('->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter'); + } catch (RuntimeException $e) { + $this->assertEquals('A string value must be composed of strings and/or numbers, but found parameter "bar" of type "array" inside string value "a %bar%".', $e->getMessage(), '->resolveValue() throws a RuntimeException when a parameter embeds another non-string parameter'); + } + + $bag = new ParameterBag(['foo' => '%bar%', 'bar' => '%foobar%', 'foobar' => '%foo%']); + try { + $bag->resolveValue('%foo%'); + $this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } catch (ParameterCircularReferenceException $e) { + $this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } + + $bag = new ParameterBag(['foo' => 'a %bar%', 'bar' => 'a %foobar%', 'foobar' => 'a %foo%']); + try { + $bag->resolveValue('%foo%'); + $this->fail('->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } catch (ParameterCircularReferenceException $e) { + $this->assertEquals('Circular reference detected for parameter "foo" ("foo" > "bar" > "foobar" > "foo").', $e->getMessage(), '->resolveValue() throws a ParameterCircularReferenceException when a parameter has a circular reference'); + } + + $bag = new ParameterBag(['host' => 'foo.bar', 'port' => 1337]); + $this->assertEquals('foo.bar:1337', $bag->resolveValue('%host%:%port%')); + } + + public function testResolveIndicatesWhyAParameterIsNeeded() + { + $bag = new ParameterBag(['foo' => '%bar%']); + + try { + $bag->resolve(); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage()); + } + + $bag = new ParameterBag(['foo' => '%bar%']); + + try { + $bag->resolve(); + } catch (ParameterNotFoundException $e) { + $this->assertEquals('The parameter "foo" has a dependency on a non-existent parameter "bar".', $e->getMessage()); + } + } + + public function testResolveUnescapesValue() + { + $bag = new ParameterBag([ + 'foo' => ['bar' => ['ding' => 'I\'m a bar %%foo %%bar']], + 'bar' => 'I\'m a %%foo%%', + ]); + + $bag->resolve(); + + $this->assertEquals('I\'m a %foo%', $bag->get('bar'), '->resolveValue() supports % escaping by doubling it'); + $this->assertEquals(['bar' => ['ding' => 'I\'m a bar %foo %bar']], $bag->get('foo'), '->resolveValue() supports % escaping by doubling it'); + } + + public function testEscapeValue() + { + $bag = new ParameterBag(); + + $bag->add([ + 'foo' => $bag->escapeValue(['bar' => ['ding' => 'I\'m a bar %foo %bar', 'zero' => null]]), + 'bar' => $bag->escapeValue('I\'m a %foo%'), + ]); + + $this->assertEquals('I\'m a %%foo%%', $bag->get('bar'), '->escapeValue() escapes % by doubling it'); + $this->assertEquals(['bar' => ['ding' => 'I\'m a bar %%foo %%bar', 'zero' => null]], $bag->get('foo'), '->escapeValue() escapes % by doubling it'); + } + + /** + * @dataProvider stringsWithSpacesProvider + */ + public function testResolveStringWithSpacesReturnsString($expected, $test, $description) + { + $bag = new ParameterBag(['foo' => 'bar']); + + try { + $this->assertEquals($expected, $bag->resolveString($test), $description); + } catch (ParameterNotFoundException $e) { + $this->fail(sprintf('%s - "%s"', $description, $expected)); + } + } + + public function stringsWithSpacesProvider() + { + return [ + ['bar', '%foo%', 'Parameters must be wrapped by %.'], + ['% foo %', '% foo %', 'Parameters should not have spaces.'], + ['{% set my_template = "foo" %}', '{% set my_template = "foo" %}', 'Twig-like strings are not parameters.'], + ['50% is less than 100%', '50% is less than 100%', 'Text between % signs is allowed, if there are spaces.'], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterTest.php new file mode 100644 index 00000000..975e5582 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ParameterTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Parameter; + +class ParameterTest extends TestCase +{ + public function testConstructor() + { + $ref = new Parameter('foo'); + $this->assertEquals('foo', (string) $ref, '__construct() sets the id of the parameter, which is used for the __toString() method'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ReferenceTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ReferenceTest.php new file mode 100644 index 00000000..1fc274a2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ReferenceTest.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Reference; + +class ReferenceTest extends TestCase +{ + public function testConstructor() + { + $ref = new Reference('foo'); + $this->assertEquals('foo', (string) $ref, '__construct() sets the id of the reference, which is used for the __toString() method'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ServiceLocatorTest.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ServiceLocatorTest.php new file mode 100644 index 00000000..52466af9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Tests/ServiceLocatorTest.php @@ -0,0 +1,148 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Container; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\DependencyInjection\ServiceSubscriberInterface; + +class ServiceLocatorTest extends TestCase +{ + public function testHas() + { + $locator = new ServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + function () { return 'dummy'; }, + ]); + + $this->assertTrue($locator->has('foo')); + $this->assertTrue($locator->has('bar')); + $this->assertFalse($locator->has('dummy')); + } + + public function testGet() + { + $locator = new ServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('baz', $locator->get('bar')); + } + + public function testGetDoesNotMemoize() + { + $i = 0; + $locator = new ServiceLocator([ + 'foo' => function () use (&$i) { + ++$i; + + return 'bar'; + }, + ]); + + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame('bar', $locator->get('foo')); + $this->assertSame(2, $i); + } + + public function testGetThrowsOnUndefinedService() + { + $this->expectException('Psr\Container\NotFoundExceptionInterface'); + $this->expectExceptionMessage('Service "dummy" not found: the container inside "Symfony\Component\DependencyInjection\Tests\ServiceLocatorTest" is a smaller service locator that only knows about the "foo" and "bar" services.'); + $locator = new ServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + ]); + + $locator->get('dummy'); + } + + public function testThrowsOnUndefinedInternalService() + { + $this->expectException('Psr\Container\NotFoundExceptionInterface'); + $this->expectExceptionMessage('The service "foo" has a dependency on a non-existent service "bar". This locator only knows about the "foo" service.'); + $locator = new ServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $locator->get('foo'); + } + + public function testThrowsOnCircularReference() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException'); + $this->expectExceptionMessage('Circular reference detected for service "bar", path: "bar -> baz -> bar".'); + $locator = new ServiceLocator([ + 'foo' => function () use (&$locator) { return $locator->get('bar'); }, + 'bar' => function () use (&$locator) { return $locator->get('baz'); }, + 'baz' => function () use (&$locator) { return $locator->get('bar'); }, + ]); + + $locator->get('foo'); + } + + public function testThrowsInServiceSubscriber() + { + $this->expectException('Psr\Container\NotFoundExceptionInterface'); + $this->expectExceptionMessage('Service "foo" not found: even though it exists in the app\'s container, the container inside "caller" is a smaller service locator that only knows about the "bar" service. Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "SomeServiceSubscriber::getSubscribedServices()".'); + $container = new Container(); + $container->set('foo', new \stdClass()); + $subscriber = new SomeServiceSubscriber(); + $subscriber->container = new ServiceLocator(['bar' => function () {}]); + $subscriber->container = $subscriber->container->withContext('caller', $container); + + $subscriber->getFoo(); + } + + public function testGetThrowsServiceNotFoundException() + { + $this->expectException('Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException'); + $this->expectExceptionMessage('Service "foo" not found: even though it exists in the app\'s container, the container inside "foo" is a smaller service locator that is empty... Try using dependency injection instead.'); + $container = new Container(); + $container->set('foo', new \stdClass()); + + $locator = new ServiceLocator([]); + $locator = $locator->withContext('foo', $container); + $locator->get('foo'); + } + + public function testInvoke() + { + $locator = new ServiceLocator([ + 'foo' => function () { return 'bar'; }, + 'bar' => function () { return 'baz'; }, + ]); + + $this->assertSame('bar', $locator('foo')); + $this->assertSame('baz', $locator('bar')); + $this->assertNull($locator('dummy'), '->__invoke() should return null on invalid service'); + } +} + +class SomeServiceSubscriber implements ServiceSubscriberinterface +{ + public $container; + + public function getFoo() + { + return $this->container->get('foo'); + } + + public static function getSubscribedServices() + { + return ['bar' => 'stdClass']; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/TypedReference.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/TypedReference.php new file mode 100644 index 00000000..aad78e80 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/TypedReference.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Represents a PHP type-hinted service reference. + * + * @author Nicolas Grekas + */ +class TypedReference extends Reference +{ + private $type; + private $requiringClass; + + /** + * @param string $id The service identifier + * @param string $type The PHP type of the identified service + * @param string $requiringClass The class of the service that requires the referenced type + * @param int $invalidBehavior The behavior when the service does not exist + */ + public function __construct($id, $type, $requiringClass = '', $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE) + { + parent::__construct($id, $invalidBehavior); + $this->type = $type; + $this->requiringClass = $requiringClass; + } + + public function getType() + { + return $this->type; + } + + public function getRequiringClass() + { + return $this->requiringClass; + } + + public function canBeAutoregistered() + { + return $this->requiringClass && (false !== $i = strpos($this->type, '\\')) && 0 === strncasecmp($this->type, $this->requiringClass, 1 + $i); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/Variable.php b/modules/empikmarketplace/vendor/symfony/dependency-injection/Variable.php new file mode 100644 index 00000000..9654ee4d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/Variable.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection; + +/** + * Represents a variable. + * + * $var = new Variable('a'); + * + * will be dumped as + * + * $a + * + * by the PHP dumper. + * + * @author Johannes M. Schmitt + */ +class Variable +{ + private $name; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + } + + public function __toString() + { + return $this->name; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/composer.json b/modules/empikmarketplace/vendor/symfony/dependency-injection/composer.json new file mode 100644 index 00000000..eee41ce0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/composer.json @@ -0,0 +1,50 @@ +{ + "name": "symfony/dependency-injection", + "type": "library", + "description": "Symfony DependencyInjection Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "require-dev": { + "symfony/yaml": "~3.4|~4.0", + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/yaml": "", + "symfony/config": "", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/modules/empikmarketplace/vendor/symfony/dependency-injection/phpunit.xml.dist b/modules/empikmarketplace/vendor/symfony/dependency-injection/phpunit.xml.dist new file mode 100644 index 00000000..21dee2a8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/dependency-injection/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Resources + ./Tests + ./vendor + + + + diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/.gitignore b/modules/empikmarketplace/vendor/symfony/expression-language/.gitignore new file mode 100644 index 00000000..c49a5d8d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/CHANGELOG.md b/modules/empikmarketplace/vendor/symfony/expression-language/CHANGELOG.md new file mode 100644 index 00000000..d00d17c7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/CHANGELOG.md @@ -0,0 +1,12 @@ +CHANGELOG +========= + +2.6.0 +----- + + * Added ExpressionFunction and ExpressionFunctionProviderInterface + +2.4.0 +----- + + * added the component diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Compiler.php b/modules/empikmarketplace/vendor/symfony/expression-language/Compiler.php new file mode 100644 index 00000000..1ae427b9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Compiler.php @@ -0,0 +1,146 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Compiles a node to PHP code. + * + * @author Fabien Potencier + */ +class Compiler +{ + private $source; + private $functions; + + public function __construct(array $functions) + { + $this->functions = $functions; + } + + public function getFunction($name) + { + return $this->functions[$name]; + } + + /** + * Gets the current PHP code after compilation. + * + * @return string The PHP code + */ + public function getSource() + { + return $this->source; + } + + public function reset() + { + $this->source = ''; + + return $this; + } + + /** + * Compiles a node. + * + * @return $this + */ + public function compile(Node\Node $node) + { + $node->compile($this); + + return $this; + } + + public function subcompile(Node\Node $node) + { + $current = $this->source; + $this->source = ''; + + $node->compile($this); + + $source = $this->source; + $this->source = $current; + + return $source; + } + + /** + * Adds a raw string to the compiled code. + * + * @param string $string The string + * + * @return $this + */ + public function raw($string) + { + $this->source .= $string; + + return $this; + } + + /** + * Adds a quoted string to the compiled code. + * + * @param string $value The string + * + * @return $this + */ + public function string($value) + { + $this->source .= sprintf('"%s"', addcslashes($value, "\0\t\"\$\\")); + + return $this; + } + + /** + * Returns a PHP representation of a given value. + * + * @param mixed $value The value to convert + * + * @return $this + */ + public function repr($value) + { + if (\is_int($value) || \is_float($value)) { + if (false !== $locale = setlocale(\LC_NUMERIC, 0)) { + setlocale(\LC_NUMERIC, 'C'); + } + + $this->raw($value); + + if (false !== $locale) { + setlocale(\LC_NUMERIC, $locale); + } + } elseif (null === $value) { + $this->raw('null'); + } elseif (\is_bool($value)) { + $this->raw($value ? 'true' : 'false'); + } elseif (\is_array($value)) { + $this->raw('['); + $first = true; + foreach ($value as $key => $value) { + if (!$first) { + $this->raw(', '); + } + $first = false; + $this->repr($key); + $this->raw(' => '); + $this->repr($value); + } + $this->raw(']'); + } else { + $this->string($value); + } + + return $this; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Expression.php b/modules/empikmarketplace/vendor/symfony/expression-language/Expression.php new file mode 100644 index 00000000..ac656cce --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Expression.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Represents an expression. + * + * @author Fabien Potencier + */ +class Expression +{ + protected $expression; + + /** + * @param string $expression An expression + */ + public function __construct($expression) + { + $this->expression = (string) $expression; + } + + /** + * Gets the expression. + * + * @return string The expression + */ + public function __toString() + { + return $this->expression; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionFunction.php b/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionFunction.php new file mode 100644 index 00000000..77c88f66 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionFunction.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Represents a function that can be used in an expression. + * + * A function is defined by two PHP callables. The callables are used + * by the language to compile and/or evaluate the function. + * + * The "compiler" function is used at compilation time and must return a + * PHP representation of the function call (it receives the function + * arguments as arguments). + * + * The "evaluator" function is used for expression evaluation and must return + * the value of the function call based on the values defined for the + * expression (it receives the values as a first argument and the function + * arguments as remaining arguments). + * + * @author Fabien Potencier + */ +class ExpressionFunction +{ + private $name; + private $compiler; + private $evaluator; + + /** + * @param string $name The function name + * @param callable $compiler A callable able to compile the function + * @param callable $evaluator A callable able to evaluate the function + */ + public function __construct($name, callable $compiler, callable $evaluator) + { + $this->name = $name; + $this->compiler = $compiler; + $this->evaluator = $evaluator; + } + + public function getName() + { + return $this->name; + } + + public function getCompiler() + { + return $this->compiler; + } + + public function getEvaluator() + { + return $this->evaluator; + } + + /** + * Creates an ExpressionFunction from a PHP function name. + * + * @param string $phpFunctionName The PHP function name + * @param string|null $expressionFunctionName The expression function name (default: same than the PHP function name) + * + * @return self + * + * @throws \InvalidArgumentException if given PHP function name does not exist + * @throws \InvalidArgumentException if given PHP function name is in namespace + * and expression function name is not defined + */ + public static function fromPhp($phpFunctionName, $expressionFunctionName = null) + { + $phpFunctionName = ltrim($phpFunctionName, '\\'); + if (!\function_exists($phpFunctionName)) { + throw new \InvalidArgumentException(sprintf('PHP function "%s" does not exist.', $phpFunctionName)); + } + + $parts = explode('\\', $phpFunctionName); + if (!$expressionFunctionName && \count($parts) > 1) { + throw new \InvalidArgumentException(sprintf('An expression function name must be defined when PHP function "%s" is namespaced.', $phpFunctionName)); + } + + $compiler = function () use ($phpFunctionName) { + return sprintf('\%s(%s)', $phpFunctionName, implode(', ', \func_get_args())); + }; + + $evaluator = function () use ($phpFunctionName) { + $args = \func_get_args(); + + return \call_user_func_array($phpFunctionName, array_splice($args, 1)); + }; + + return new self($expressionFunctionName ?: end($parts), $compiler, $evaluator); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionFunctionProviderInterface.php b/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionFunctionProviderInterface.php new file mode 100644 index 00000000..414b0138 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionFunctionProviderInterface.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * @author Fabien Potencier + */ +interface ExpressionFunctionProviderInterface +{ + /** + * @return ExpressionFunction[] An array of Function instances + */ + public function getFunctions(); +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionLanguage.php b/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionLanguage.php new file mode 100644 index 00000000..16476669 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ExpressionLanguage.php @@ -0,0 +1,178 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; +use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheAdapter; +use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface; + +/** + * Allows to compile and evaluate expressions written in your own DSL. + * + * @author Fabien Potencier + */ +class ExpressionLanguage +{ + private $cache; + private $lexer; + private $parser; + private $compiler; + + protected $functions = []; + + /** + * @param CacheItemPoolInterface $cache + * @param ExpressionFunctionProviderInterface[] $providers + */ + public function __construct($cache = null, array $providers = []) + { + if (null !== $cache) { + if ($cache instanceof ParserCacheInterface) { + @trigger_error(sprintf('Passing an instance of %s as constructor argument for %s is deprecated as of 3.2 and will be removed in 4.0. Pass an instance of %s instead.', ParserCacheInterface::class, self::class, CacheItemPoolInterface::class), \E_USER_DEPRECATED); + $cache = new ParserCacheAdapter($cache); + } elseif (!$cache instanceof CacheItemPoolInterface) { + throw new \InvalidArgumentException(sprintf('Cache argument has to implement "%s".', CacheItemPoolInterface::class)); + } + } + + $this->cache = $cache ?: new ArrayAdapter(); + $this->registerFunctions(); + foreach ($providers as $provider) { + $this->registerProvider($provider); + } + } + + /** + * Compiles an expression source code. + * + * @param Expression|string $expression The expression to compile + * @param array $names An array of valid names + * + * @return string The compiled PHP source code + */ + public function compile($expression, $names = []) + { + return $this->getCompiler()->compile($this->parse($expression, $names)->getNodes())->getSource(); + } + + /** + * Evaluate an expression. + * + * @param Expression|string $expression The expression to compile + * @param array $values An array of values + * + * @return mixed The result of the evaluation of the expression + */ + public function evaluate($expression, $values = []) + { + return $this->parse($expression, array_keys($values))->getNodes()->evaluate($this->functions, $values); + } + + /** + * Parses an expression. + * + * @param Expression|string $expression The expression to parse + * @param array $names An array of valid names + * + * @return ParsedExpression A ParsedExpression instance + */ + public function parse($expression, $names) + { + if ($expression instanceof ParsedExpression) { + return $expression; + } + + asort($names); + $cacheKeyItems = []; + + foreach ($names as $nameKey => $name) { + $cacheKeyItems[] = \is_int($nameKey) ? $name : $nameKey.':'.$name; + } + + $cacheItem = $this->cache->getItem(rawurlencode($expression.'//'.implode('|', $cacheKeyItems))); + + if (null === $parsedExpression = $cacheItem->get()) { + $nodes = $this->getParser()->parse($this->getLexer()->tokenize((string) $expression), $names); + $parsedExpression = new ParsedExpression((string) $expression, $nodes); + + $cacheItem->set($parsedExpression); + $this->cache->save($cacheItem); + } + + return $parsedExpression; + } + + /** + * Registers a function. + * + * @param string $name The function name + * @param callable $compiler A callable able to compile the function + * @param callable $evaluator A callable able to evaluate the function + * + * @throws \LogicException when registering a function after calling evaluate(), compile() or parse() + * + * @see ExpressionFunction + */ + public function register($name, callable $compiler, callable $evaluator) + { + if (null !== $this->parser) { + throw new \LogicException('Registering functions after calling evaluate(), compile() or parse() is not supported.'); + } + + $this->functions[$name] = ['compiler' => $compiler, 'evaluator' => $evaluator]; + } + + public function addFunction(ExpressionFunction $function) + { + $this->register($function->getName(), $function->getCompiler(), $function->getEvaluator()); + } + + public function registerProvider(ExpressionFunctionProviderInterface $provider) + { + foreach ($provider->getFunctions() as $function) { + $this->addFunction($function); + } + } + + protected function registerFunctions() + { + $this->addFunction(ExpressionFunction::fromPhp('constant')); + } + + private function getLexer() + { + if (null === $this->lexer) { + $this->lexer = new Lexer(); + } + + return $this->lexer; + } + + private function getParser() + { + if (null === $this->parser) { + $this->parser = new Parser($this->functions); + } + + return $this->parser; + } + + private function getCompiler() + { + if (null === $this->compiler) { + $this->compiler = new Compiler($this->functions); + } + + return $this->compiler->reset(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/LICENSE b/modules/empikmarketplace/vendor/symfony/expression-language/LICENSE new file mode 100644 index 00000000..9e936ec0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2020 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Lexer.php b/modules/empikmarketplace/vendor/symfony/expression-language/Lexer.php new file mode 100644 index 00000000..ace847b0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Lexer.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Lexes an expression. + * + * @author Fabien Potencier + */ +class Lexer +{ + /** + * Tokenizes an expression. + * + * @param string $expression The expression to tokenize + * + * @return TokenStream A token stream instance + * + * @throws SyntaxError + */ + public function tokenize($expression) + { + $expression = str_replace(["\r", "\n", "\t", "\v", "\f"], ' ', $expression); + $cursor = 0; + $tokens = []; + $brackets = []; + $end = \strlen($expression); + + while ($cursor < $end) { + if (' ' == $expression[$cursor]) { + ++$cursor; + + continue; + } + + if (preg_match('/[0-9]+(?:\.[0-9]+)?/A', $expression, $match, 0, $cursor)) { + // numbers + $number = (float) $match[0]; // floats + if (preg_match('/^[0-9]+$/', $match[0]) && $number <= \PHP_INT_MAX) { + $number = (int) $match[0]; // integers lower than the maximum + } + $tokens[] = new Token(Token::NUMBER_TYPE, $number, $cursor + 1); + $cursor += \strlen($match[0]); + } elseif (false !== strpos('([{', $expression[$cursor])) { + // opening bracket + $brackets[] = [$expression[$cursor], $cursor]; + + $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); + ++$cursor; + } elseif (false !== strpos(')]}', $expression[$cursor])) { + // closing bracket + if (empty($brackets)) { + throw new SyntaxError(sprintf('Unexpected "%s".', $expression[$cursor]), $cursor, $expression); + } + + list($expect, $cur) = array_pop($brackets); + if ($expression[$cursor] != strtr($expect, '([{', ')]}')) { + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression); + } + + $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); + ++$cursor; + } elseif (preg_match('/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As', $expression, $match, 0, $cursor)) { + // strings + $tokens[] = new Token(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)), $cursor + 1); + $cursor += \strlen($match[0]); + } elseif (preg_match('/(?<=^|[\s(])not in(?=[\s(])|\!\=\=|(?<=^|[\s(])not(?=[\s(])|(?<=^|[\s(])and(?=[\s(])|\=\=\=|\>\=|(?<=^|[\s(])or(?=[\s(])|\<\=|\*\*|\.\.|(?<=^|[\s(])in(?=[\s(])|&&|\|\||(?<=^|[\s(])matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, 0, $cursor)) { + // operators + $tokens[] = new Token(Token::OPERATOR_TYPE, $match[0], $cursor + 1); + $cursor += \strlen($match[0]); + } elseif (false !== strpos('.,?:', $expression[$cursor])) { + // punctuation + $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); + ++$cursor; + } elseif (preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $expression, $match, 0, $cursor)) { + // names + $tokens[] = new Token(Token::NAME_TYPE, $match[0], $cursor + 1); + $cursor += \strlen($match[0]); + } else { + // unlexable + throw new SyntaxError(sprintf('Unexpected character "%s".', $expression[$cursor]), $cursor, $expression); + } + } + + $tokens[] = new Token(Token::EOF_TYPE, null, $cursor + 1); + + if (!empty($brackets)) { + list($expect, $cur) = array_pop($brackets); + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression); + } + + return new TokenStream($tokens, $expression); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/ArgumentsNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ArgumentsNode.php new file mode 100644 index 00000000..e9849a44 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ArgumentsNode.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class ArgumentsNode extends ArrayNode +{ + public function compile(Compiler $compiler) + { + $this->compileArguments($compiler, false); + } + + public function toArray() + { + $array = []; + + foreach ($this->getKeyValuePairs() as $pair) { + $array[] = $pair['value']; + $array[] = ', '; + } + array_pop($array); + + return $array; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/ArrayNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ArrayNode.php new file mode 100644 index 00000000..921319a7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ArrayNode.php @@ -0,0 +1,118 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class ArrayNode extends Node +{ + protected $index; + + public function __construct() + { + $this->index = -1; + } + + public function addElement(Node $value, Node $key = null) + { + if (null === $key) { + $key = new ConstantNode(++$this->index); + } + + array_push($this->nodes, $key, $value); + } + + /** + * Compiles the node to PHP. + */ + public function compile(Compiler $compiler) + { + $compiler->raw('['); + $this->compileArguments($compiler); + $compiler->raw(']'); + } + + public function evaluate($functions, $values) + { + $result = []; + foreach ($this->getKeyValuePairs() as $pair) { + $result[$pair['key']->evaluate($functions, $values)] = $pair['value']->evaluate($functions, $values); + } + + return $result; + } + + public function toArray() + { + $value = []; + foreach ($this->getKeyValuePairs() as $pair) { + $value[$pair['key']->attributes['value']] = $pair['value']; + } + + $array = []; + + if ($this->isHash($value)) { + foreach ($value as $k => $v) { + $array[] = ', '; + $array[] = new ConstantNode($k); + $array[] = ': '; + $array[] = $v; + } + $array[0] = '{'; + $array[] = '}'; + } else { + foreach ($value as $v) { + $array[] = ', '; + $array[] = $v; + } + $array[0] = '['; + $array[] = ']'; + } + + return $array; + } + + protected function getKeyValuePairs() + { + $pairs = []; + foreach (array_chunk($this->nodes, 2) as $pair) { + $pairs[] = ['key' => $pair[0], 'value' => $pair[1]]; + } + + return $pairs; + } + + protected function compileArguments(Compiler $compiler, $withKeys = true) + { + $first = true; + foreach ($this->getKeyValuePairs() as $pair) { + if (!$first) { + $compiler->raw(', '); + } + $first = false; + + if ($withKeys) { + $compiler + ->compile($pair['key']) + ->raw(' => ') + ; + } + + $compiler->compile($pair['value']); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/BinaryNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/BinaryNode.php new file mode 100644 index 00000000..549161b3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/BinaryNode.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class BinaryNode extends Node +{ + private static $operators = [ + '~' => '.', + 'and' => '&&', + 'or' => '||', + ]; + + private static $functions = [ + '**' => 'pow', + '..' => 'range', + 'in' => 'in_array', + 'not in' => '!in_array', + ]; + + public function __construct($operator, Node $left, Node $right) + { + parent::__construct( + ['left' => $left, 'right' => $right], + ['operator' => $operator] + ); + } + + public function compile(Compiler $compiler) + { + $operator = $this->attributes['operator']; + + if ('matches' == $operator) { + $compiler + ->raw('preg_match(') + ->compile($this->nodes['right']) + ->raw(', ') + ->compile($this->nodes['left']) + ->raw(')') + ; + + return; + } + + if (isset(self::$functions[$operator])) { + $compiler + ->raw(sprintf('%s(', self::$functions[$operator])) + ->compile($this->nodes['left']) + ->raw(', ') + ->compile($this->nodes['right']) + ->raw(')') + ; + + return; + } + + if (isset(self::$operators[$operator])) { + $operator = self::$operators[$operator]; + } + + $compiler + ->raw('(') + ->compile($this->nodes['left']) + ->raw(' ') + ->raw($operator) + ->raw(' ') + ->compile($this->nodes['right']) + ->raw(')') + ; + } + + public function evaluate($functions, $values) + { + $operator = $this->attributes['operator']; + $left = $this->nodes['left']->evaluate($functions, $values); + + if (isset(self::$functions[$operator])) { + $right = $this->nodes['right']->evaluate($functions, $values); + + if ('not in' === $operator) { + return !\in_array($left, $right); + } + $f = self::$functions[$operator]; + + return $f($left, $right); + } + + switch ($operator) { + case 'or': + case '||': + return $left || $this->nodes['right']->evaluate($functions, $values); + case 'and': + case '&&': + return $left && $this->nodes['right']->evaluate($functions, $values); + } + + $right = $this->nodes['right']->evaluate($functions, $values); + + switch ($operator) { + case '|': + return $left | $right; + case '^': + return $left ^ $right; + case '&': + return $left & $right; + case '==': + return $left == $right; + case '===': + return $left === $right; + case '!=': + return $left != $right; + case '!==': + return $left !== $right; + case '<': + return $left < $right; + case '>': + return $left > $right; + case '>=': + return $left >= $right; + case '<=': + return $left <= $right; + case 'not in': + return !\in_array($left, $right); + case 'in': + return \in_array($left, $right); + case '+': + return $left + $right; + case '-': + return $left - $right; + case '~': + return $left.$right; + case '*': + return $left * $right; + case '/': + if (0 == $right) { + throw new \DivisionByZeroError('Division by zero.'); + } + + return $left / $right; + case '%': + if (0 == $right) { + throw new \DivisionByZeroError('Modulo by zero.'); + } + + return $left % $right; + case 'matches': + return preg_match($right, $left); + } + } + + public function toArray() + { + return ['(', $this->nodes['left'], ' '.$this->attributes['operator'].' ', $this->nodes['right'], ')']; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/ConditionalNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ConditionalNode.php new file mode 100644 index 00000000..ca1b484b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ConditionalNode.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class ConditionalNode extends Node +{ + public function __construct(Node $expr1, Node $expr2, Node $expr3) + { + parent::__construct( + ['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3] + ); + } + + public function compile(Compiler $compiler) + { + $compiler + ->raw('((') + ->compile($this->nodes['expr1']) + ->raw(') ? (') + ->compile($this->nodes['expr2']) + ->raw(') : (') + ->compile($this->nodes['expr3']) + ->raw('))') + ; + } + + public function evaluate($functions, $values) + { + if ($this->nodes['expr1']->evaluate($functions, $values)) { + return $this->nodes['expr2']->evaluate($functions, $values); + } + + return $this->nodes['expr3']->evaluate($functions, $values); + } + + public function toArray() + { + return ['(', $this->nodes['expr1'], ' ? ', $this->nodes['expr2'], ' : ', $this->nodes['expr3'], ')']; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/ConstantNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ConstantNode.php new file mode 100644 index 00000000..670e52ed --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/ConstantNode.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class ConstantNode extends Node +{ + private $isIdentifier; + + public function __construct($value, $isIdentifier = false) + { + $this->isIdentifier = $isIdentifier; + parent::__construct( + [], + ['value' => $value] + ); + } + + public function compile(Compiler $compiler) + { + $compiler->repr($this->attributes['value']); + } + + public function evaluate($functions, $values) + { + return $this->attributes['value']; + } + + public function toArray() + { + $array = []; + $value = $this->attributes['value']; + + if ($this->isIdentifier) { + $array[] = $value; + } elseif (true === $value) { + $array[] = 'true'; + } elseif (false === $value) { + $array[] = 'false'; + } elseif (null === $value) { + $array[] = 'null'; + } elseif (is_numeric($value)) { + $array[] = $value; + } elseif (!\is_array($value)) { + $array[] = $this->dumpString($value); + } elseif ($this->isHash($value)) { + foreach ($value as $k => $v) { + $array[] = ', '; + $array[] = new self($k); + $array[] = ': '; + $array[] = new self($v); + } + $array[0] = '{'; + $array[] = '}'; + } else { + foreach ($value as $v) { + $array[] = ', '; + $array[] = new self($v); + } + $array[0] = '['; + $array[] = ']'; + } + + return $array; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/FunctionNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/FunctionNode.php new file mode 100644 index 00000000..90008d5d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/FunctionNode.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class FunctionNode extends Node +{ + public function __construct($name, Node $arguments) + { + parent::__construct( + ['arguments' => $arguments], + ['name' => $name] + ); + } + + public function compile(Compiler $compiler) + { + $arguments = []; + foreach ($this->nodes['arguments']->nodes as $node) { + $arguments[] = $compiler->subcompile($node); + } + + $function = $compiler->getFunction($this->attributes['name']); + + $compiler->raw(\call_user_func_array($function['compiler'], $arguments)); + } + + public function evaluate($functions, $values) + { + $arguments = [$values]; + foreach ($this->nodes['arguments']->nodes as $node) { + $arguments[] = $node->evaluate($functions, $values); + } + + return \call_user_func_array($functions[$this->attributes['name']]['evaluator'], $arguments); + } + + public function toArray() + { + $array = []; + $array[] = $this->attributes['name']; + + foreach ($this->nodes['arguments']->nodes as $node) { + $array[] = ', '; + $array[] = $node; + } + $array[1] = '('; + $array[] = ')'; + + return $array; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/GetAttrNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/GetAttrNode.php new file mode 100644 index 00000000..dffe0e30 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/GetAttrNode.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class GetAttrNode extends Node +{ + const PROPERTY_CALL = 1; + const METHOD_CALL = 2; + const ARRAY_CALL = 3; + + public function __construct(Node $node, Node $attribute, ArrayNode $arguments, $type) + { + parent::__construct( + ['node' => $node, 'attribute' => $attribute, 'arguments' => $arguments], + ['type' => $type] + ); + } + + public function compile(Compiler $compiler) + { + switch ($this->attributes['type']) { + case self::PROPERTY_CALL: + $compiler + ->compile($this->nodes['node']) + ->raw('->') + ->raw($this->nodes['attribute']->attributes['value']) + ; + break; + + case self::METHOD_CALL: + $compiler + ->compile($this->nodes['node']) + ->raw('->') + ->raw($this->nodes['attribute']->attributes['value']) + ->raw('(') + ->compile($this->nodes['arguments']) + ->raw(')') + ; + break; + + case self::ARRAY_CALL: + $compiler + ->compile($this->nodes['node']) + ->raw('[') + ->compile($this->nodes['attribute'])->raw(']') + ; + break; + } + } + + public function evaluate($functions, $values) + { + switch ($this->attributes['type']) { + case self::PROPERTY_CALL: + $obj = $this->nodes['node']->evaluate($functions, $values); + if (!\is_object($obj)) { + throw new \RuntimeException('Unable to get a property on a non-object.'); + } + + $property = $this->nodes['attribute']->attributes['value']; + + return $obj->$property; + + case self::METHOD_CALL: + $obj = $this->nodes['node']->evaluate($functions, $values); + if (!\is_object($obj)) { + throw new \RuntimeException('Unable to get a property on a non-object.'); + } + if (!\is_callable($toCall = [$obj, $this->nodes['attribute']->attributes['value']])) { + throw new \RuntimeException(sprintf('Unable to call method "%s" of object "%s".', $this->nodes['attribute']->attributes['value'], \get_class($obj))); + } + + $arguments = $this->nodes['arguments']->evaluate($functions, $values); + + if (\PHP_VERSION_ID >= 80000) { + $arguments = array_values($arguments); + } + + return \call_user_func_array($toCall, $arguments); + + case self::ARRAY_CALL: + $array = $this->nodes['node']->evaluate($functions, $values); + if (!\is_array($array) && !$array instanceof \ArrayAccess) { + throw new \RuntimeException('Unable to get an item on a non-array.'); + } + + return $array[$this->nodes['attribute']->evaluate($functions, $values)]; + } + } + + public function toArray() + { + switch ($this->attributes['type']) { + case self::PROPERTY_CALL: + return [$this->nodes['node'], '.', $this->nodes['attribute']]; + + case self::METHOD_CALL: + return [$this->nodes['node'], '.', $this->nodes['attribute'], '(', $this->nodes['arguments'], ')']; + + case self::ARRAY_CALL: + return [$this->nodes['node'], '[', $this->nodes['attribute'], ']']; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/NameNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/NameNode.php new file mode 100644 index 00000000..1c9c277b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/NameNode.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class NameNode extends Node +{ + public function __construct($name) + { + parent::__construct( + [], + ['name' => $name] + ); + } + + public function compile(Compiler $compiler) + { + $compiler->raw('$'.$this->attributes['name']); + } + + public function evaluate($functions, $values) + { + return $values[$this->attributes['name']]; + } + + public function toArray() + { + return [$this->attributes['name']]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/Node.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/Node.php new file mode 100644 index 00000000..95045902 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/Node.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * Represents a node in the AST. + * + * @author Fabien Potencier + */ +class Node +{ + public $nodes = []; + public $attributes = []; + + /** + * @param array $nodes An array of nodes + * @param array $attributes An array of attributes + */ + public function __construct(array $nodes = [], array $attributes = []) + { + $this->nodes = $nodes; + $this->attributes = $attributes; + } + + public function __toString() + { + $attributes = []; + foreach ($this->attributes as $name => $value) { + $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true))); + } + + $repr = [str_replace('Symfony\Component\ExpressionLanguage\Node\\', '', static::class).'('.implode(', ', $attributes)]; + + if (\count($this->nodes)) { + foreach ($this->nodes as $node) { + foreach (explode("\n", (string) $node) as $line) { + $repr[] = ' '.$line; + } + } + + $repr[] = ')'; + } else { + $repr[0] .= ')'; + } + + return implode("\n", $repr); + } + + public function compile(Compiler $compiler) + { + foreach ($this->nodes as $node) { + $node->compile($compiler); + } + } + + public function evaluate($functions, $values) + { + $results = []; + foreach ($this->nodes as $node) { + $results[] = $node->evaluate($functions, $values); + } + + return $results; + } + + public function toArray() + { + throw new \BadMethodCallException(sprintf('Dumping a "%s" instance is not supported yet.', static::class)); + } + + public function dump() + { + $dump = ''; + + foreach ($this->toArray() as $v) { + $dump .= is_scalar($v) ? $v : $v->dump(); + } + + return $dump; + } + + protected function dumpString($value) + { + return sprintf('"%s"', addcslashes($value, "\0\t\"\\")); + } + + protected function isHash(array $value) + { + $expectedKey = 0; + + foreach ($value as $key => $val) { + if ($key !== $expectedKey++) { + return true; + } + } + + return false; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Node/UnaryNode.php b/modules/empikmarketplace/vendor/symfony/expression-language/Node/UnaryNode.php new file mode 100644 index 00000000..497b7fe5 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Node/UnaryNode.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Node; + +use Symfony\Component\ExpressionLanguage\Compiler; + +/** + * @author Fabien Potencier + * + * @internal + */ +class UnaryNode extends Node +{ + private static $operators = [ + '!' => '!', + 'not' => '!', + '+' => '+', + '-' => '-', + ]; + + public function __construct($operator, Node $node) + { + parent::__construct( + ['node' => $node], + ['operator' => $operator] + ); + } + + public function compile(Compiler $compiler) + { + $compiler + ->raw('(') + ->raw(self::$operators[$this->attributes['operator']]) + ->compile($this->nodes['node']) + ->raw(')') + ; + } + + public function evaluate($functions, $values) + { + $value = $this->nodes['node']->evaluate($functions, $values); + switch ($this->attributes['operator']) { + case 'not': + case '!': + return !$value; + case '-': + return -$value; + } + + return $value; + } + + public function toArray() + { + return ['(', $this->attributes['operator'].' ', $this->nodes['node'], ')']; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ParsedExpression.php b/modules/empikmarketplace/vendor/symfony/expression-language/ParsedExpression.php new file mode 100644 index 00000000..a5603fc3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ParsedExpression.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +use Symfony\Component\ExpressionLanguage\Node\Node; + +/** + * Represents an already parsed expression. + * + * @author Fabien Potencier + */ +class ParsedExpression extends Expression +{ + private $nodes; + + /** + * @param string $expression An expression + * @param Node $nodes A Node representing the expression + */ + public function __construct($expression, Node $nodes) + { + parent::__construct($expression); + + $this->nodes = $nodes; + } + + public function getNodes() + { + return $this->nodes; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Parser.php b/modules/empikmarketplace/vendor/symfony/expression-language/Parser.php new file mode 100644 index 00000000..bfc24395 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Parser.php @@ -0,0 +1,380 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Parsers a token stream. + * + * This parser implements a "Precedence climbing" algorithm. + * + * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm + * @see http://en.wikipedia.org/wiki/Operator-precedence_parser + * + * @author Fabien Potencier + */ +class Parser +{ + const OPERATOR_LEFT = 1; + const OPERATOR_RIGHT = 2; + + private $stream; + private $unaryOperators; + private $binaryOperators; + private $functions; + private $names; + + public function __construct(array $functions) + { + $this->functions = $functions; + + $this->unaryOperators = [ + 'not' => ['precedence' => 50], + '!' => ['precedence' => 50], + '-' => ['precedence' => 500], + '+' => ['precedence' => 500], + ]; + $this->binaryOperators = [ + 'or' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT], + '||' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT], + 'and' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT], + '&&' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT], + '|' => ['precedence' => 16, 'associativity' => self::OPERATOR_LEFT], + '^' => ['precedence' => 17, 'associativity' => self::OPERATOR_LEFT], + '&' => ['precedence' => 18, 'associativity' => self::OPERATOR_LEFT], + '==' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '===' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '!=' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '!==' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '<' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '>' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '>=' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '<=' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + 'not in' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + 'in' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + 'matches' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '..' => ['precedence' => 25, 'associativity' => self::OPERATOR_LEFT], + '+' => ['precedence' => 30, 'associativity' => self::OPERATOR_LEFT], + '-' => ['precedence' => 30, 'associativity' => self::OPERATOR_LEFT], + '~' => ['precedence' => 40, 'associativity' => self::OPERATOR_LEFT], + '*' => ['precedence' => 60, 'associativity' => self::OPERATOR_LEFT], + '/' => ['precedence' => 60, 'associativity' => self::OPERATOR_LEFT], + '%' => ['precedence' => 60, 'associativity' => self::OPERATOR_LEFT], + '**' => ['precedence' => 200, 'associativity' => self::OPERATOR_RIGHT], + ]; + } + + /** + * Converts a token stream to a node tree. + * + * The valid names is an array where the values + * are the names that the user can use in an expression. + * + * If the variable name in the compiled PHP code must be + * different, define it as the key. + * + * For instance, ['this' => 'container'] means that the + * variable 'container' can be used in the expression + * but the compiled code will use 'this'. + * + * @param TokenStream $stream A token stream instance + * @param array $names An array of valid names + * + * @return Node\Node A node tree + * + * @throws SyntaxError + */ + public function parse(TokenStream $stream, $names = []) + { + $this->stream = $stream; + $this->names = $names; + + $node = $this->parseExpression(); + if (!$stream->isEOF()) { + throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', $stream->current->type, $stream->current->value), $stream->current->cursor, $stream->getExpression()); + } + + return $node; + } + + public function parseExpression($precedence = 0) + { + $expr = $this->getPrimary(); + $token = $this->stream->current; + while ($token->test(Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->value]) && $this->binaryOperators[$token->value]['precedence'] >= $precedence) { + $op = $this->binaryOperators[$token->value]; + $this->stream->next(); + + $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']); + $expr = new Node\BinaryNode($token->value, $expr, $expr1); + + $token = $this->stream->current; + } + + if (0 === $precedence) { + return $this->parseConditionalExpression($expr); + } + + return $expr; + } + + protected function getPrimary() + { + $token = $this->stream->current; + + if ($token->test(Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->value])) { + $operator = $this->unaryOperators[$token->value]; + $this->stream->next(); + $expr = $this->parseExpression($operator['precedence']); + + return $this->parsePostfixExpression(new Node\UnaryNode($token->value, $expr)); + } + + if ($token->test(Token::PUNCTUATION_TYPE, '(')) { + $this->stream->next(); + $expr = $this->parseExpression(); + $this->stream->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed'); + + return $this->parsePostfixExpression($expr); + } + + return $this->parsePrimaryExpression(); + } + + protected function parseConditionalExpression($expr) + { + while ($this->stream->current->test(Token::PUNCTUATION_TYPE, '?')) { + $this->stream->next(); + if (!$this->stream->current->test(Token::PUNCTUATION_TYPE, ':')) { + $expr2 = $this->parseExpression(); + if ($this->stream->current->test(Token::PUNCTUATION_TYPE, ':')) { + $this->stream->next(); + $expr3 = $this->parseExpression(); + } else { + $expr3 = new Node\ConstantNode(null); + } + } else { + $this->stream->next(); + $expr2 = $expr; + $expr3 = $this->parseExpression(); + } + + $expr = new Node\ConditionalNode($expr, $expr2, $expr3); + } + + return $expr; + } + + public function parsePrimaryExpression() + { + $token = $this->stream->current; + switch ($token->type) { + case Token::NAME_TYPE: + $this->stream->next(); + switch ($token->value) { + case 'true': + case 'TRUE': + return new Node\ConstantNode(true); + + case 'false': + case 'FALSE': + return new Node\ConstantNode(false); + + case 'null': + case 'NULL': + return new Node\ConstantNode(null); + + default: + if ('(' === $this->stream->current->value) { + if (false === isset($this->functions[$token->value])) { + throw new SyntaxError(sprintf('The function "%s" does not exist.', $token->value), $token->cursor, $this->stream->getExpression(), $token->value, array_keys($this->functions)); + } + + $node = new Node\FunctionNode($token->value, $this->parseArguments()); + } else { + if (!\in_array($token->value, $this->names, true)) { + throw new SyntaxError(sprintf('Variable "%s" is not valid.', $token->value), $token->cursor, $this->stream->getExpression(), $token->value, $this->names); + } + + // is the name used in the compiled code different + // from the name used in the expression? + if (\is_int($name = array_search($token->value, $this->names))) { + $name = $token->value; + } + + $node = new Node\NameNode($name); + } + } + break; + + case Token::NUMBER_TYPE: + case Token::STRING_TYPE: + $this->stream->next(); + + return new Node\ConstantNode($token->value); + + default: + if ($token->test(Token::PUNCTUATION_TYPE, '[')) { + $node = $this->parseArrayExpression(); + } elseif ($token->test(Token::PUNCTUATION_TYPE, '{')) { + $node = $this->parseHashExpression(); + } else { + throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', $token->type, $token->value), $token->cursor, $this->stream->getExpression()); + } + } + + return $this->parsePostfixExpression($node); + } + + public function parseArrayExpression() + { + $this->stream->expect(Token::PUNCTUATION_TYPE, '[', 'An array element was expected'); + + $node = new Node\ArrayNode(); + $first = true; + while (!$this->stream->current->test(Token::PUNCTUATION_TYPE, ']')) { + if (!$first) { + $this->stream->expect(Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma'); + + // trailing ,? + if ($this->stream->current->test(Token::PUNCTUATION_TYPE, ']')) { + break; + } + } + $first = false; + + $node->addElement($this->parseExpression()); + } + $this->stream->expect(Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed'); + + return $node; + } + + public function parseHashExpression() + { + $this->stream->expect(Token::PUNCTUATION_TYPE, '{', 'A hash element was expected'); + + $node = new Node\ArrayNode(); + $first = true; + while (!$this->stream->current->test(Token::PUNCTUATION_TYPE, '}')) { + if (!$first) { + $this->stream->expect(Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma'); + + // trailing ,? + if ($this->stream->current->test(Token::PUNCTUATION_TYPE, '}')) { + break; + } + } + $first = false; + + // a hash key can be: + // + // * a number -- 12 + // * a string -- 'a' + // * a name, which is equivalent to a string -- a + // * an expression, which must be enclosed in parentheses -- (1 + 2) + if ($this->stream->current->test(Token::STRING_TYPE) || $this->stream->current->test(Token::NAME_TYPE) || $this->stream->current->test(Token::NUMBER_TYPE)) { + $key = new Node\ConstantNode($this->stream->current->value); + $this->stream->next(); + } elseif ($this->stream->current->test(Token::PUNCTUATION_TYPE, '(')) { + $key = $this->parseExpression(); + } else { + $current = $this->stream->current; + + throw new SyntaxError(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', $current->type, $current->value), $current->cursor, $this->stream->getExpression()); + } + + $this->stream->expect(Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); + $value = $this->parseExpression(); + + $node->addElement($value, $key); + } + $this->stream->expect(Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed'); + + return $node; + } + + public function parsePostfixExpression($node) + { + $token = $this->stream->current; + while (Token::PUNCTUATION_TYPE == $token->type) { + if ('.' === $token->value) { + $this->stream->next(); + $token = $this->stream->current; + $this->stream->next(); + + if ( + Token::NAME_TYPE !== $token->type + && + // Operators like "not" and "matches" are valid method or property names, + // + // In other words, besides NAME_TYPE, OPERATOR_TYPE could also be parsed as a property or method. + // This is because operators are processed by the lexer prior to names. So "not" in "foo.not()" or "matches" in "foo.matches" will be recognized as an operator first. + // But in fact, "not" and "matches" in such expressions shall be parsed as method or property names. + // + // And this ONLY works if the operator consists of valid characters for a property or method name. + // + // Other types, such as STRING_TYPE and NUMBER_TYPE, can't be parsed as property nor method names. + // + // As a result, if $token is NOT an operator OR $token->value is NOT a valid property or method name, an exception shall be thrown. + (Token::OPERATOR_TYPE !== $token->type || !preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $token->value)) + ) { + throw new SyntaxError('Expected name.', $token->cursor, $this->stream->getExpression()); + } + + $arg = new Node\ConstantNode($token->value, true); + + $arguments = new Node\ArgumentsNode(); + if ($this->stream->current->test(Token::PUNCTUATION_TYPE, '(')) { + $type = Node\GetAttrNode::METHOD_CALL; + foreach ($this->parseArguments()->nodes as $n) { + $arguments->addElement($n); + } + } else { + $type = Node\GetAttrNode::PROPERTY_CALL; + } + + $node = new Node\GetAttrNode($node, $arg, $arguments, $type); + } elseif ('[' === $token->value) { + $this->stream->next(); + $arg = $this->parseExpression(); + $this->stream->expect(Token::PUNCTUATION_TYPE, ']'); + + $node = new Node\GetAttrNode($node, $arg, new Node\ArgumentsNode(), Node\GetAttrNode::ARRAY_CALL); + } else { + break; + } + + $token = $this->stream->current; + } + + return $node; + } + + /** + * Parses arguments. + */ + public function parseArguments() + { + $args = []; + $this->stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); + while (!$this->stream->current->test(Token::PUNCTUATION_TYPE, ')')) { + if (!empty($args)) { + $this->stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); + } + + $args[] = $this->parseExpression(); + } + $this->stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); + + return new Node\Node($args); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php b/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php new file mode 100644 index 00000000..f009df73 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\ParserCache; + +@trigger_error('The '.__NAMESPACE__.'\ArrayParserCache class is deprecated since Symfony 3.2 and will be removed in 4.0. Use the Symfony\Component\Cache\Adapter\ArrayAdapter class instead.', \E_USER_DEPRECATED); + +use Symfony\Component\ExpressionLanguage\ParsedExpression; + +/** + * @author Adrien Brault + * + * @deprecated ArrayParserCache class is deprecated since version 3.2 and will be removed in 4.0. Use the Symfony\Component\Cache\Adapter\ArrayAdapter class instead. + */ +class ArrayParserCache implements ParserCacheInterface +{ + private $cache = []; + + /** + * {@inheritdoc} + */ + public function fetch($key) + { + return isset($this->cache[$key]) ? $this->cache[$key] : null; + } + + /** + * {@inheritdoc} + */ + public function save($key, ParsedExpression $expression) + { + $this->cache[$key] = $expression; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php b/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php new file mode 100644 index 00000000..b9b448dd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\ParserCache; + +use Psr\Cache\CacheItemInterface; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\CacheItem; + +/** + * @author Alexandre GESLIN + * + * @internal and will be removed in Symfony 4.0. + */ +class ParserCacheAdapter implements CacheItemPoolInterface +{ + private $pool; + private $createCacheItem; + + public function __construct(ParserCacheInterface $pool) + { + $this->pool = $pool; + + $this->createCacheItem = \Closure::bind( + static function ($key, $value, $isHit) { + $item = new CacheItem(); + $item->key = $key; + $item->value = $value; + $item->isHit = $isHit; + + return $item; + }, + null, + CacheItem::class + ); + } + + /** + * {@inheritdoc} + */ + public function getItem($key) + { + $value = $this->pool->fetch($key); + $f = $this->createCacheItem; + + return $f($key, $value, null !== $value); + } + + /** + * {@inheritdoc} + */ + public function save(CacheItemInterface $item) + { + $this->pool->save($item->getKey(), $item->get()); + } + + /** + * {@inheritdoc} + */ + public function getItems(array $keys = []) + { + throw new \BadMethodCallException('Not implemented.'); + } + + /** + * {@inheritdoc} + */ + public function hasItem($key) + { + throw new \BadMethodCallException('Not implemented.'); + } + + /** + * {@inheritdoc} + */ + public function clear() + { + throw new \BadMethodCallException('Not implemented.'); + } + + /** + * {@inheritdoc} + */ + public function deleteItem($key) + { + throw new \BadMethodCallException('Not implemented.'); + } + + /** + * {@inheritdoc} + */ + public function deleteItems(array $keys) + { + throw new \BadMethodCallException('Not implemented.'); + } + + /** + * {@inheritdoc} + */ + public function saveDeferred(CacheItemInterface $item) + { + throw new \BadMethodCallException('Not implemented.'); + } + + /** + * {@inheritdoc} + */ + public function commit() + { + throw new \BadMethodCallException('Not implemented.'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php b/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php new file mode 100644 index 00000000..98a80edd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\ParserCache; + +@trigger_error('The '.__NAMESPACE__.'\ParserCacheInterface interface is deprecated since Symfony 3.2 and will be removed in 4.0. Use Psr\Cache\CacheItemPoolInterface instead.', \E_USER_DEPRECATED); + +use Symfony\Component\ExpressionLanguage\ParsedExpression; + +/** + * @author Adrien Brault + * + * @deprecated since version 3.2, to be removed in 4.0. Use Psr\Cache\CacheItemPoolInterface instead. + */ +interface ParserCacheInterface +{ + /** + * Saves an expression in the cache. + * + * @param string $key The cache key + * @param ParsedExpression $expression A ParsedExpression instance to store in the cache + */ + public function save($key, ParsedExpression $expression); + + /** + * Fetches an expression from the cache. + * + * @param string $key The cache key + * + * @return ParsedExpression|null + */ + public function fetch($key); +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/README.md b/modules/empikmarketplace/vendor/symfony/expression-language/README.md new file mode 100644 index 00000000..08b310d1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/README.md @@ -0,0 +1,15 @@ +ExpressionLanguage Component +============================ + +The ExpressionLanguage component provides an engine that can compile and +evaluate expressions. An expression is a one-liner that returns a value +(mostly, but not limited to, Booleans). + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/expression_language/introduction.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php b/modules/empikmarketplace/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php new file mode 100644 index 00000000..c86e9625 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +$operators = ['not', '!', 'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', 'matches', '**']; +$operators = array_combine($operators, array_map('strlen', $operators)); +arsort($operators); + +$regex = []; +foreach ($operators as $operator => $length) { + // Collisions of character operators: + // - an operator that begins with a character must have a space or a parenthesis before or starting at the beginning of a string + // - an operator that ends with a character must be followed by a whitespace or a parenthesis + $regex[] = + (ctype_alpha($operator[0]) ? '(?<=^|[\s(])' : '') + .preg_quote($operator, '/') + .(ctype_alpha($operator[$length - 1]) ? '(?=[\s(])' : ''); +} + +echo '/'.implode('|', $regex).'/A'; diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/SerializedParsedExpression.php b/modules/empikmarketplace/vendor/symfony/expression-language/SerializedParsedExpression.php new file mode 100644 index 00000000..dd763f75 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/SerializedParsedExpression.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Represents an already parsed expression. + * + * @author Fabien Potencier + */ +class SerializedParsedExpression extends ParsedExpression +{ + private $nodes; + + /** + * @param string $expression An expression + * @param string $nodes The serialized nodes for the expression + */ + public function __construct($expression, $nodes) + { + $this->expression = (string) $expression; + $this->nodes = $nodes; + } + + public function getNodes() + { + return unserialize($this->nodes); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/SyntaxError.php b/modules/empikmarketplace/vendor/symfony/expression-language/SyntaxError.php new file mode 100644 index 00000000..a942b8cb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/SyntaxError.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +class SyntaxError extends \LogicException +{ + public function __construct($message, $cursor = 0, $expression = '', $subject = null, array $proposals = null) + { + $message = sprintf('%s around position %d', rtrim($message, '.'), $cursor); + if ($expression) { + $message = sprintf('%s for expression `%s`', $message, $expression); + } + $message .= '.'; + + if (null !== $subject && null !== $proposals) { + $minScore = \INF; + foreach ($proposals as $proposal) { + $distance = levenshtein($subject, $proposal); + if ($distance < $minScore) { + $guess = $proposal; + $minScore = $distance; + } + } + + if (isset($guess) && $minScore < 3) { + $message .= sprintf(' Did you mean "%s"?', $guess); + } + } + + parent::__construct($message); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php new file mode 100644 index 00000000..d7e23cb4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\ExpressionFunction; + +/** + * Tests ExpressionFunction. + * + * @author Dany Maillard + */ +class ExpressionFunctionTest extends TestCase +{ + public function testFunctionDoesNotExist() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('PHP function "fn_does_not_exist" does not exist.'); + ExpressionFunction::fromPhp('fn_does_not_exist'); + } + + public function testFunctionNamespaced() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('An expression function name must be defined when PHP function "Symfony\Component\ExpressionLanguage\Tests\fn_namespaced" is namespaced.'); + ExpressionFunction::fromPhp('Symfony\Component\ExpressionLanguage\Tests\fn_namespaced'); + } +} + +function fn_namespaced() +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php new file mode 100644 index 00000000..97e915ac --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php @@ -0,0 +1,308 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\ExpressionLanguage\ParsedExpression; +use Symfony\Component\ExpressionLanguage\Tests\Fixtures\TestProvider; + +class ExpressionLanguageTest extends TestCase +{ + public function testCachedParse() + { + $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemPoolInterface')->getMock(); + $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); + $savedParsedExpression = null; + $expressionLanguage = new ExpressionLanguage($cacheMock); + + $cacheMock + ->expects($this->exactly(2)) + ->method('getItem') + ->with('1%20%2B%201%2F%2F') + ->willReturn($cacheItemMock) + ; + + $cacheItemMock + ->expects($this->exactly(2)) + ->method('get') + ->willReturnCallback(function () use (&$savedParsedExpression) { + return $savedParsedExpression; + }) + ; + + $cacheItemMock + ->expects($this->exactly(1)) + ->method('set') + ->with($this->isInstanceOf(ParsedExpression::class)) + ->willReturnCallback(function ($parsedExpression) use (&$savedParsedExpression) { + $savedParsedExpression = $parsedExpression; + }) + ; + + $cacheMock + ->expects($this->exactly(1)) + ->method('save') + ->with($cacheItemMock) + ; + + $parsedExpression = $expressionLanguage->parse('1 + 1', []); + $this->assertSame($savedParsedExpression, $parsedExpression); + + $parsedExpression = $expressionLanguage->parse('1 + 1', []); + $this->assertSame($savedParsedExpression, $parsedExpression); + } + + /** + * @group legacy + */ + public function testCachedParseWithDeprecatedParserCacheInterface() + { + $cacheMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + + $savedParsedExpression = null; + $expressionLanguage = new ExpressionLanguage($cacheMock); + + $cacheMock + ->expects($this->exactly(1)) + ->method('fetch') + ->with('1%20%2B%201%2F%2F') + ->willReturn($savedParsedExpression) + ; + + $cacheMock + ->expects($this->exactly(1)) + ->method('save') + ->with('1%20%2B%201%2F%2F', $this->isInstanceOf(ParsedExpression::class)) + ->willReturnCallback(function ($key, $expression) use (&$savedParsedExpression) { + $savedParsedExpression = $expression; + }) + ; + + $parsedExpression = $expressionLanguage->parse('1 + 1', []); + $this->assertSame($savedParsedExpression, $parsedExpression); + } + + public function testWrongCacheImplementation() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Cache argument has to implement "Psr\Cache\CacheItemPoolInterface".'); + $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemSpoolInterface')->getMock(); + new ExpressionLanguage($cacheMock); + } + + public function testConstantFunction() + { + $expressionLanguage = new ExpressionLanguage(); + $this->assertEquals(\PHP_VERSION, $expressionLanguage->evaluate('constant("PHP_VERSION")')); + + $expressionLanguage = new ExpressionLanguage(); + $this->assertEquals('\constant("PHP_VERSION")', $expressionLanguage->compile('constant("PHP_VERSION")')); + } + + public function testProviders() + { + $expressionLanguage = new ExpressionLanguage(null, [new TestProvider()]); + $this->assertEquals('foo', $expressionLanguage->evaluate('identity("foo")')); + $this->assertEquals('"foo"', $expressionLanguage->compile('identity("foo")')); + $this->assertEquals('FOO', $expressionLanguage->evaluate('strtoupper("foo")')); + $this->assertEquals('\strtoupper("foo")', $expressionLanguage->compile('strtoupper("foo")')); + $this->assertEquals('foo', $expressionLanguage->evaluate('strtolower("FOO")')); + $this->assertEquals('\strtolower("FOO")', $expressionLanguage->compile('strtolower("FOO")')); + $this->assertTrue($expressionLanguage->evaluate('fn_namespaced()')); + $this->assertEquals('\Symfony\Component\ExpressionLanguage\Tests\Fixtures\fn_namespaced()', $expressionLanguage->compile('fn_namespaced()')); + } + + /** + * @dataProvider shortCircuitProviderEvaluate + */ + public function testShortCircuitOperatorsEvaluate($expression, array $values, $expected) + { + $expressionLanguage = new ExpressionLanguage(); + $this->assertEquals($expected, $expressionLanguage->evaluate($expression, $values)); + } + + /** + * @dataProvider shortCircuitProviderCompile + */ + public function testShortCircuitOperatorsCompile($expression, array $names, $expected) + { + $result = null; + $expressionLanguage = new ExpressionLanguage(); + eval(sprintf('$result = %s;', $expressionLanguage->compile($expression, $names))); + $this->assertSame($expected, $result); + } + + public function testParseThrowsInsteadOfNotice() + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Unexpected end of expression around position 6 for expression `node.`.'); + $expressionLanguage = new ExpressionLanguage(); + $expressionLanguage->parse('node.', ['node']); + } + + public function shortCircuitProviderEvaluate() + { + $object = $this->getMockBuilder('stdClass')->setMethods(['foo'])->getMock(); + $object->expects($this->never())->method('foo'); + + return [ + ['false and object.foo()', ['object' => $object], false], + ['false && object.foo()', ['object' => $object], false], + ['true || object.foo()', ['object' => $object], true], + ['true or object.foo()', ['object' => $object], true], + ]; + } + + public function shortCircuitProviderCompile() + { + return [ + ['false and foo', ['foo' => 'foo'], false], + ['false && foo', ['foo' => 'foo'], false], + ['true || foo', ['foo' => 'foo'], true], + ['true or foo', ['foo' => 'foo'], true], + ]; + } + + public function testCachingForOverriddenVariableNames() + { + $expressionLanguage = new ExpressionLanguage(); + $expression = 'a + b'; + $expressionLanguage->evaluate($expression, ['a' => 1, 'b' => 1]); + $result = $expressionLanguage->compile($expression, ['a', 'B' => 'b']); + $this->assertSame('($a + $B)', $result); + } + + public function testStrictEquality() + { + $expressionLanguage = new ExpressionLanguage(); + $expression = '123 === a'; + $result = $expressionLanguage->compile($expression, ['a']); + $this->assertSame('(123 === $a)', $result); + } + + public function testCachingWithDifferentNamesOrder() + { + $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemPoolInterface')->getMock(); + $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); + $expressionLanguage = new ExpressionLanguage($cacheMock); + $savedParsedExpression = null; + + $cacheMock + ->expects($this->exactly(2)) + ->method('getItem') + ->with('a%20%2B%20b%2F%2Fa%7CB%3Ab') + ->willReturn($cacheItemMock) + ; + + $cacheItemMock + ->expects($this->exactly(2)) + ->method('get') + ->willReturnCallback(function () use (&$savedParsedExpression) { + return $savedParsedExpression; + }) + ; + + $cacheItemMock + ->expects($this->exactly(1)) + ->method('set') + ->with($this->isInstanceOf(ParsedExpression::class)) + ->willReturnCallback(function ($parsedExpression) use (&$savedParsedExpression) { + $savedParsedExpression = $parsedExpression; + }) + ; + + $cacheMock + ->expects($this->exactly(1)) + ->method('save') + ->with($cacheItemMock) + ; + + $expression = 'a + b'; + $expressionLanguage->compile($expression, ['a', 'B' => 'b']); + $expressionLanguage->compile($expression, ['B' => 'b', 'a']); + } + + public function testOperatorCollisions() + { + $expressionLanguage = new ExpressionLanguage(); + $expression = 'foo.not in [bar]'; + $compiled = $expressionLanguage->compile($expression, ['foo', 'bar']); + $this->assertSame('in_array($foo->not, [0 => $bar])', $compiled); + + $result = $expressionLanguage->evaluate($expression, ['foo' => (object) ['not' => 'test'], 'bar' => 'test']); + $this->assertTrue($result); + } + + /** + * @dataProvider getRegisterCallbacks + */ + public function testRegisterAfterParse($registerCallback) + { + $this->expectException('LogicException'); + $el = new ExpressionLanguage(); + $el->parse('1 + 1', []); + $registerCallback($el); + } + + /** + * @dataProvider getRegisterCallbacks + */ + public function testRegisterAfterEval($registerCallback) + { + $this->expectException('LogicException'); + $el = new ExpressionLanguage(); + $el->evaluate('1 + 1'); + $registerCallback($el); + } + + public function testCallBadCallable() + { + $this->expectException('RuntimeException'); + $this->expectExceptionMessageMatches('/Unable to call method "\w+" of object "\w+"./'); + $el = new ExpressionLanguage(); + $el->evaluate('foo.myfunction()', ['foo' => new \stdClass()]); + } + + /** + * @dataProvider getRegisterCallbacks + */ + public function testRegisterAfterCompile($registerCallback) + { + $this->expectException('LogicException'); + $el = new ExpressionLanguage(); + $el->compile('1 + 1'); + $registerCallback($el); + } + + public function getRegisterCallbacks() + { + return [ + [ + function (ExpressionLanguage $el) { + $el->register('fn', function () {}, function () {}); + }, + ], + [ + function (ExpressionLanguage $el) { + $el->addFunction(new ExpressionFunction('fn', function () {}, function () {})); + }, + ], + [ + function (ExpressionLanguage $el) { + $el->registerProvider(new TestProvider()); + }, + ], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionTest.php new file mode 100644 index 00000000..052ef220 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ExpressionTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Expression; + +class ExpressionTest extends TestCase +{ + public function testSerialization() + { + $expression = new Expression('kernel.boot()'); + + $serializedExpression = serialize($expression); + $unserializedExpression = unserialize($serializedExpression); + + $this->assertEquals($expression, $unserializedExpression); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php new file mode 100644 index 00000000..8405d4f9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Fixtures; + +use Symfony\Component\ExpressionLanguage\ExpressionFunction; +use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; +use Symfony\Component\ExpressionLanguage\ExpressionPhpFunction; + +class TestProvider implements ExpressionFunctionProviderInterface +{ + public function getFunctions() + { + return [ + new ExpressionFunction('identity', function ($input) { + return $input; + }, function (array $values, $input) { + return $input; + }), + + ExpressionFunction::fromPhp('strtoupper'), + + ExpressionFunction::fromPhp('\strtolower'), + + ExpressionFunction::fromPhp('Symfony\Component\ExpressionLanguage\Tests\Fixtures\fn_namespaced', 'fn_namespaced'), + ]; + } +} + +function fn_namespaced() +{ + return true; +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/LexerTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/LexerTest.php new file mode 100644 index 00000000..6c3d1a7d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/LexerTest.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Lexer; +use Symfony\Component\ExpressionLanguage\Token; +use Symfony\Component\ExpressionLanguage\TokenStream; + +class LexerTest extends TestCase +{ + /** + * @var Lexer + */ + private $lexer; + + protected function setUp() + { + $this->lexer = new Lexer(); + } + + /** + * @dataProvider getTokenizeData + */ + public function testTokenize($tokens, $expression) + { + $tokens[] = new Token('end of expression', null, \strlen($expression) + 1); + $this->assertEquals(new TokenStream($tokens, $expression), $this->lexer->tokenize($expression)); + } + + public function testTokenizeThrowsErrorWithMessage() + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Unexpected character "\'" around position 33 for expression `service(faulty.expression.example\').dummyMethod()`.'); + $expression = "service(faulty.expression.example').dummyMethod()"; + $this->lexer->tokenize($expression); + } + + public function testTokenizeThrowsErrorOnUnclosedBrace() + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Unclosed "(" around position 7 for expression `service(unclosed.expression.dummyMethod()`.'); + $expression = 'service(unclosed.expression.dummyMethod()'; + $this->lexer->tokenize($expression); + } + + public function getTokenizeData() + { + return [ + [ + [new Token('name', 'a', 3)], + ' a ', + ], + [ + [new Token('name', 'a', 1)], + 'a', + ], + [ + [new Token('string', 'foo', 1)], + '"foo"', + ], + [ + [new Token('number', '3', 1)], + '3', + ], + [ + [new Token('operator', '+', 1)], + '+', + ], + [ + [new Token('punctuation', '.', 1)], + '.', + ], + [ + [ + new Token('punctuation', '(', 1), + new Token('number', '3', 2), + new Token('operator', '+', 4), + new Token('number', '5', 6), + new Token('punctuation', ')', 7), + new Token('operator', '~', 9), + new Token('name', 'foo', 11), + new Token('punctuation', '(', 14), + new Token('string', 'bar', 15), + new Token('punctuation', ')', 20), + new Token('punctuation', '.', 21), + new Token('name', 'baz', 22), + new Token('punctuation', '[', 25), + new Token('number', '4', 26), + new Token('punctuation', ']', 27), + ], + '(3 + 5) ~ foo("bar").baz[4]', + ], + [ + [new Token('operator', '..', 1)], + '..', + ], + [ + [new Token('string', '#foo', 1)], + "'#foo'", + ], + [ + [new Token('string', '#foo', 1)], + '"#foo"', + ], + [ + [ + new Token('name', 'foo', 1), + new Token('punctuation', '.', 4), + new Token('name', 'not', 5), + new Token('operator', 'in', 9), + new Token('punctuation', '[', 12), + new Token('name', 'bar', 13), + new Token('punctuation', ']', 16), + ], + 'foo.not in [bar]', + ], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php new file mode 100644 index 00000000..29750374 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Compiler; + +abstract class AbstractNodeTest extends TestCase +{ + /** + * @dataProvider getEvaluateData + */ + public function testEvaluate($expected, $node, $variables = [], $functions = []) + { + $this->assertSame($expected, $node->evaluate($functions, $variables)); + } + + abstract public function getEvaluateData(); + + /** + * @dataProvider getCompileData + */ + public function testCompile($expected, $node, $functions = []) + { + $compiler = new Compiler($functions); + $node->compile($compiler); + $this->assertSame($expected, $compiler->getSource()); + } + + abstract public function getCompileData(); + + /** + * @dataProvider getDumpData + */ + public function testDump($expected, $node) + { + $this->assertSame($expected, $node->dump()); + } + + abstract public function getDumpData(); +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php new file mode 100644 index 00000000..9d88b4ae --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ArgumentsNode; + +class ArgumentsNodeTest extends ArrayNodeTest +{ + public function getCompileData() + { + return [ + ['"a", "b"', $this->getArrayNode()], + ]; + } + + public function getDumpData() + { + return [ + ['"a", "b"', $this->getArrayNode()], + ]; + } + + protected function createArrayNode() + { + return new ArgumentsNode(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php new file mode 100644 index 00000000..3d03d837 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ArrayNode; +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; + +class ArrayNodeTest extends AbstractNodeTest +{ + public function testSerialization() + { + $node = $this->createArrayNode(); + $node->addElement(new ConstantNode('foo')); + + $serializedNode = serialize($node); + $unserializedNode = unserialize($serializedNode); + + $this->assertEquals($node, $unserializedNode); + $this->assertNotEquals($this->createArrayNode(), $unserializedNode); + } + + public function getEvaluateData() + { + return [ + [['b' => 'a', 'b'], $this->getArrayNode()], + ]; + } + + public function getCompileData() + { + return [ + ['["b" => "a", 0 => "b"]', $this->getArrayNode()], + ]; + } + + public function getDumpData() + { + yield ['{"b": "a", 0: "b"}', $this->getArrayNode()]; + + $array = $this->createArrayNode(); + $array->addElement(new ConstantNode('c'), new ConstantNode('a"b')); + $array->addElement(new ConstantNode('d'), new ConstantNode('a\b')); + yield ['{"a\\"b": "c", "a\\\\b": "d"}', $array]; + + $array = $this->createArrayNode(); + $array->addElement(new ConstantNode('c')); + $array->addElement(new ConstantNode('d')); + yield ['["c", "d"]', $array]; + } + + protected function getArrayNode() + { + $array = $this->createArrayNode(); + $array->addElement(new ConstantNode('a'), new ConstantNode('b')); + $array->addElement(new ConstantNode('b')); + + return $array; + } + + protected function createArrayNode() + { + return new ArrayNode(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php new file mode 100644 index 00000000..b45a1e57 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ArrayNode; +use Symfony\Component\ExpressionLanguage\Node\BinaryNode; +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; + +class BinaryNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + $array = new ArrayNode(); + $array->addElement(new ConstantNode('a')); + $array->addElement(new ConstantNode('b')); + + return [ + [true, new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))], + [true, new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))], + [false, new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))], + [false, new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))], + + [0, new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))], + [6, new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))], + [6, new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))], + + [true, new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))], + [true, new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))], + [true, new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))], + + [false, new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))], + [false, new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))], + [true, new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))], + + [true, new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))], + [false, new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))], + + [false, new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))], + [true, new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))], + + [-1, new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))], + [3, new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))], + [4, new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))], + [1, new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))], + [1, new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))], + [25, new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))], + ['ab', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))], + + [true, new BinaryNode('in', new ConstantNode('a'), $array)], + [false, new BinaryNode('in', new ConstantNode('c'), $array)], + [true, new BinaryNode('not in', new ConstantNode('c'), $array)], + [false, new BinaryNode('not in', new ConstantNode('a'), $array)], + + [[1, 2, 3], new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))], + + [1, new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))], + ]; + } + + public function getCompileData() + { + $array = new ArrayNode(); + $array->addElement(new ConstantNode('a')); + $array->addElement(new ConstantNode('b')); + + return [ + ['(true || false)', new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))], + ['(true || false)', new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))], + ['(true && false)', new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))], + ['(true && false)', new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))], + + ['(2 & 4)', new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))], + ['(2 | 4)', new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))], + ['(2 ^ 4)', new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))], + + ['(1 < 2)', new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 2)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 1)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))], + + ['(1 > 2)', new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 2)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 1)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))], + + ['(true === true)', new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))], + ['(true !== true)', new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))], + + ['(2 == 1)', new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))], + ['(2 != 1)', new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))], + + ['(1 - 2)', new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))], + ['(1 + 2)', new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))], + ['(2 * 2)', new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))], + ['(2 / 2)', new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))], + ['(5 % 2)', new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))], + ['pow(5, 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))], + ['("a" . "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))], + + ['in_array("a", [0 => "a", 1 => "b"])', new BinaryNode('in', new ConstantNode('a'), $array)], + ['in_array("c", [0 => "a", 1 => "b"])', new BinaryNode('in', new ConstantNode('c'), $array)], + ['!in_array("c", [0 => "a", 1 => "b"])', new BinaryNode('not in', new ConstantNode('c'), $array)], + ['!in_array("a", [0 => "a", 1 => "b"])', new BinaryNode('not in', new ConstantNode('a'), $array)], + + ['range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))], + + ['preg_match("/^[a-z]+/i\$/", "abc")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))], + ]; + } + + public function getDumpData() + { + $array = new ArrayNode(); + $array->addElement(new ConstantNode('a')); + $array->addElement(new ConstantNode('b')); + + return [ + ['(true or false)', new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))], + ['(true || false)', new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))], + ['(true and false)', new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))], + ['(true && false)', new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))], + + ['(2 & 4)', new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))], + ['(2 | 4)', new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))], + ['(2 ^ 4)', new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))], + + ['(1 < 2)', new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 2)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 1)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))], + + ['(1 > 2)', new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 2)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 1)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))], + + ['(true === true)', new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))], + ['(true !== true)', new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))], + + ['(2 == 1)', new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))], + ['(2 != 1)', new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))], + + ['(1 - 2)', new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))], + ['(1 + 2)', new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))], + ['(2 * 2)', new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))], + ['(2 / 2)', new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))], + ['(5 % 2)', new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))], + ['(5 ** 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))], + ['("a" ~ "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))], + + ['("a" in ["a", "b"])', new BinaryNode('in', new ConstantNode('a'), $array)], + ['("c" in ["a", "b"])', new BinaryNode('in', new ConstantNode('c'), $array)], + ['("c" not in ["a", "b"])', new BinaryNode('not in', new ConstantNode('c'), $array)], + ['("a" not in ["a", "b"])', new BinaryNode('not in', new ConstantNode('a'), $array)], + + ['(1 .. 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))], + + ['("abc" matches "/^[a-z]+/i$/")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php new file mode 100644 index 00000000..13b7cbde --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ConditionalNode; +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; + +class ConditionalNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + return [ + [1, new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))], + [2, new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))], + ]; + } + + public function getCompileData() + { + return [ + ['((true) ? (1) : (2))', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))], + ['((false) ? (1) : (2))', new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))], + ]; + } + + public function getDumpData() + { + return [ + ['(true ? 1 : 2)', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))], + ['(false ? 1 : 2)', new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php new file mode 100644 index 00000000..fee9f5bf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; + +class ConstantNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + return [ + [false, new ConstantNode(false)], + [true, new ConstantNode(true)], + [null, new ConstantNode(null)], + [3, new ConstantNode(3)], + [3.3, new ConstantNode(3.3)], + ['foo', new ConstantNode('foo')], + [[1, 'b' => 'a'], new ConstantNode([1, 'b' => 'a'])], + ]; + } + + public function getCompileData() + { + return [ + ['false', new ConstantNode(false)], + ['true', new ConstantNode(true)], + ['null', new ConstantNode(null)], + ['3', new ConstantNode(3)], + ['3.3', new ConstantNode(3.3)], + ['"foo"', new ConstantNode('foo')], + ['[0 => 1, "b" => "a"]', new ConstantNode([1, 'b' => 'a'])], + ]; + } + + public function getDumpData() + { + return [ + ['false', new ConstantNode(false)], + ['true', new ConstantNode(true)], + ['null', new ConstantNode(null)], + ['3', new ConstantNode(3)], + ['3.3', new ConstantNode(3.3)], + ['"foo"', new ConstantNode('foo')], + ['foo', new ConstantNode('foo', true)], + ['{0: 1, "b": "a", 1: true}', new ConstantNode([1, 'b' => 'a', true])], + ['{"a\\"b": "c", "a\\\\b": "d"}', new ConstantNode(['a"b' => 'c', 'a\\b' => 'd'])], + ['["c", "d"]', new ConstantNode(['c', 'd'])], + ['{"a": ["b"]}', new ConstantNode(['a' => ['b']])], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php new file mode 100644 index 00000000..c6cb02c1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\FunctionNode; +use Symfony\Component\ExpressionLanguage\Node\Node; + +class FunctionNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + return [ + ['bar', new FunctionNode('foo', new Node([new ConstantNode('bar')])), [], ['foo' => $this->getCallables()]], + ]; + } + + public function getCompileData() + { + return [ + ['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')])), ['foo' => $this->getCallables()]], + ]; + } + + public function getDumpData() + { + return [ + ['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')])), ['foo' => $this->getCallables()]], + ]; + } + + protected function getCallables() + { + return [ + 'compiler' => function ($arg) { + return sprintf('foo(%s)', $arg); + }, + 'evaluator' => function ($variables, $arg) { + return $arg; + }, + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php new file mode 100644 index 00000000..c790f33a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ArrayNode; +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\GetAttrNode; +use Symfony\Component\ExpressionLanguage\Node\NameNode; + +class GetAttrNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + return [ + ['b', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b']]], + ['a', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b']]], + + ['bar', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]], + + ['baz', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]], + ['a', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b'], 'index' => 'b']], + ]; + } + + public function getCompileData() + { + return [ + ['$foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ['$foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + + ['$foo->foo', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]], + + ['$foo->foo(["b" => "a", 0 => "b"])', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]], + ['$foo[$index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ]; + } + + public function getDumpData() + { + return [ + ['foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ['foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + + ['foo.foo', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]], + + ['foo.foo({"b": "a", 0: "b"})', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]], + ['foo[index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ]; + } + + protected function getArrayNode() + { + $array = new ArrayNode(); + $array->addElement(new ConstantNode('a'), new ConstantNode('b')); + $array->addElement(new ConstantNode('b')); + + return $array; + } +} + +class Obj +{ + public $foo = 'bar'; + + public function foo() + { + return 'baz'; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php new file mode 100644 index 00000000..a30c27b8 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\NameNode; + +class NameNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + return [ + ['bar', new NameNode('foo'), ['foo' => 'bar']], + ]; + } + + public function getCompileData() + { + return [ + ['$foo', new NameNode('foo')], + ]; + } + + public function getDumpData() + { + return [ + ['foo', new NameNode('foo')], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/NodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/NodeTest.php new file mode 100644 index 00000000..351da051 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/NodeTest.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\Node; + +class NodeTest extends TestCase +{ + public function testToString() + { + $node = new Node([new ConstantNode('foo')]); + + $this->assertEquals(<<<'EOF' +Node( + ConstantNode(value: 'foo') +) +EOF + , (string) $node); + } + + public function testSerialization() + { + $node = new Node(['foo' => 'bar'], ['bar' => 'foo']); + + $serializedNode = serialize($node); + $unserializedNode = unserialize($serializedNode); + + $this->assertEquals($node, $unserializedNode); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php new file mode 100644 index 00000000..bac75d24 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests\Node; + +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\UnaryNode; + +class UnaryNodeTest extends AbstractNodeTest +{ + public function getEvaluateData() + { + return [ + [-1, new UnaryNode('-', new ConstantNode(1))], + [3, new UnaryNode('+', new ConstantNode(3))], + [false, new UnaryNode('!', new ConstantNode(true))], + [false, new UnaryNode('not', new ConstantNode(true))], + ]; + } + + public function getCompileData() + { + return [ + ['(-1)', new UnaryNode('-', new ConstantNode(1))], + ['(+3)', new UnaryNode('+', new ConstantNode(3))], + ['(!true)', new UnaryNode('!', new ConstantNode(true))], + ['(!true)', new UnaryNode('not', new ConstantNode(true))], + ]; + } + + public function getDumpData() + { + return [ + ['(- 1)', new UnaryNode('-', new ConstantNode(1))], + ['(+ 3)', new UnaryNode('+', new ConstantNode(3))], + ['(! true)', new UnaryNode('!', new ConstantNode(true))], + ['(not true)', new UnaryNode('not', new ConstantNode(true))], + ]; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParsedExpressionTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParsedExpressionTest.php new file mode 100644 index 00000000..d28101fb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParsedExpressionTest.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\ParsedExpression; + +class ParsedExpressionTest extends TestCase +{ + public function testSerialization() + { + $expression = new ParsedExpression('25', new ConstantNode('25')); + + $serializedExpression = serialize($expression); + $unserializedExpression = unserialize($serializedExpression); + + $this->assertEquals($expression, $unserializedExpression); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php new file mode 100644 index 00000000..f82af92e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Node\Node; +use Symfony\Component\ExpressionLanguage\ParsedExpression; +use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheAdapter; + +/** + * @group legacy + */ +class ParserCacheAdapterTest extends TestCase +{ + public function testGetItem() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + + $key = 'key'; + $value = 'value'; + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + + $poolMock + ->expects($this->once()) + ->method('fetch') + ->with($key) + ->willReturn($value) + ; + + $cacheItem = $parserCacheAdapter->getItem($key); + + $this->assertEquals($value, $cacheItem->get()); + $this->assertTrue($cacheItem->isHit()); + } + + public function testSave() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); + $key = 'key'; + $value = new ParsedExpression('1 + 1', new Node([], [])); + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + + $poolMock + ->expects($this->once()) + ->method('save') + ->with($key, $value) + ; + + $cacheItemMock + ->expects($this->once()) + ->method('getKey') + ->willReturn($key) + ; + + $cacheItemMock + ->expects($this->once()) + ->method('get') + ->willReturn($value) + ; + + $parserCacheAdapter->save($cacheItemMock); + } + + public function testGetItems() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->getItems(); + } + + public function testHasItem() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $key = 'key'; + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->hasItem($key); + } + + public function testClear() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->clear(); + } + + public function testDeleteItem() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $key = 'key'; + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->deleteItem($key); + } + + public function testDeleteItems() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $keys = ['key']; + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->deleteItems($keys); + } + + public function testSaveDeferred() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->saveDeferred($cacheItemMock); + } + + public function testCommit() + { + $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); + $parserCacheAdapter = new ParserCacheAdapter($poolMock); + $this->expectException(\BadMethodCallException::class); + + $parserCacheAdapter->commit(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParserTest.php b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParserTest.php new file mode 100644 index 00000000..2d5a0a6c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Tests/ParserTest.php @@ -0,0 +1,237 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Lexer; +use Symfony\Component\ExpressionLanguage\Node; +use Symfony\Component\ExpressionLanguage\Parser; + +class ParserTest extends TestCase +{ + public function testParseWithInvalidName() + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Variable "foo" is not valid around position 1 for expression `foo`.'); + $lexer = new Lexer(); + $parser = new Parser([]); + $parser->parse($lexer->tokenize('foo')); + } + + public function testParseWithZeroInNames() + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Variable "foo" is not valid around position 1 for expression `foo`.'); + $lexer = new Lexer(); + $parser = new Parser([]); + $parser->parse($lexer->tokenize('foo'), [0]); + } + + /** + * @dataProvider getParseData + */ + public function testParse($node, $expression, $names = []) + { + $lexer = new Lexer(); + $parser = new Parser([]); + $this->assertEquals($node, $parser->parse($lexer->tokenize($expression), $names)); + } + + public function getParseData() + { + $arguments = new Node\ArgumentsNode(); + $arguments->addElement(new Node\ConstantNode('arg1')); + $arguments->addElement(new Node\ConstantNode(2)); + $arguments->addElement(new Node\ConstantNode(true)); + + $arrayNode = new Node\ArrayNode(); + $arrayNode->addElement(new Node\NameNode('bar')); + + return [ + [ + new Node\NameNode('a'), + 'a', + ['a'], + ], + [ + new Node\ConstantNode('a'), + '"a"', + ], + [ + new Node\ConstantNode(3), + '3', + ], + [ + new Node\ConstantNode(false), + 'false', + ], + [ + new Node\ConstantNode(true), + 'true', + ], + [ + new Node\ConstantNode(null), + 'null', + ], + [ + new Node\UnaryNode('-', new Node\ConstantNode(3)), + '-3', + ], + [ + new Node\BinaryNode('-', new Node\ConstantNode(3), new Node\ConstantNode(3)), + '3 - 3', + ], + [ + new Node\BinaryNode('*', + new Node\BinaryNode('-', new Node\ConstantNode(3), new Node\ConstantNode(3)), + new Node\ConstantNode(2) + ), + '(3 - 3) * 2', + ], + [ + new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode('bar', true), new Node\ArgumentsNode(), Node\GetAttrNode::PROPERTY_CALL), + 'foo.bar', + ['foo'], + ], + [ + new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode('bar', true), new Node\ArgumentsNode(), Node\GetAttrNode::METHOD_CALL), + 'foo.bar()', + ['foo'], + ], + [ + new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode('not', true), new Node\ArgumentsNode(), Node\GetAttrNode::METHOD_CALL), + 'foo.not()', + ['foo'], + ], + [ + new Node\GetAttrNode( + new Node\NameNode('foo'), + new Node\ConstantNode('bar', true), + $arguments, + Node\GetAttrNode::METHOD_CALL + ), + 'foo.bar("arg1", 2, true)', + ['foo'], + ], + [ + new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode(3), new Node\ArgumentsNode(), Node\GetAttrNode::ARRAY_CALL), + 'foo[3]', + ['foo'], + ], + [ + new Node\ConditionalNode(new Node\ConstantNode(true), new Node\ConstantNode(true), new Node\ConstantNode(false)), + 'true ? true : false', + ], + [ + new Node\BinaryNode('matches', new Node\ConstantNode('foo'), new Node\ConstantNode('/foo/')), + '"foo" matches "/foo/"', + ], + + // chained calls + [ + $this->createGetAttrNode( + $this->createGetAttrNode( + $this->createGetAttrNode( + $this->createGetAttrNode(new Node\NameNode('foo'), 'bar', Node\GetAttrNode::METHOD_CALL), + 'foo', Node\GetAttrNode::METHOD_CALL), + 'baz', Node\GetAttrNode::PROPERTY_CALL), + '3', Node\GetAttrNode::ARRAY_CALL), + 'foo.bar().foo().baz[3]', + ['foo'], + ], + + [ + new Node\NameNode('foo'), + 'bar', + ['foo' => 'bar'], + ], + + // Operators collisions + [ + new Node\BinaryNode( + 'in', + new Node\GetAttrNode( + new Node\NameNode('foo'), + new Node\ConstantNode('not', true), + new Node\ArgumentsNode(), + Node\GetAttrNode::PROPERTY_CALL + ), + $arrayNode + ), + 'foo.not in [bar]', + ['foo', 'bar'], + ], + [ + new Node\BinaryNode( + 'or', + new Node\UnaryNode('not', new Node\NameNode('foo')), + new Node\GetAttrNode( + new Node\NameNode('foo'), + new Node\ConstantNode('not', true), + new Node\ArgumentsNode(), + Node\GetAttrNode::PROPERTY_CALL + ) + ), + 'not foo or foo.not', + ['foo'], + ], + ]; + } + + private function createGetAttrNode($node, $item, $type) + { + return new Node\GetAttrNode($node, new Node\ConstantNode($item, Node\GetAttrNode::ARRAY_CALL !== $type), new Node\ArgumentsNode(), $type); + } + + /** + * @dataProvider getInvalidPostfixData + */ + public function testParseWithInvalidPostfixData($expr, $names = []) + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $lexer = new Lexer(); + $parser = new Parser([]); + $parser->parse($lexer->tokenize($expr), $names); + } + + public function getInvalidPostfixData() + { + return [ + [ + 'foo."#"', + ['foo'], + ], + [ + 'foo."bar"', + ['foo'], + ], + [ + 'foo.**', + ['foo'], + ], + [ + 'foo.123', + ['foo'], + ], + ]; + } + + public function testNameProposal() + { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Did you mean "baz"?'); + $lexer = new Lexer(); + $parser = new Parser([]); + + $parser->parse($lexer->tokenize('foo > bar'), ['foo', 'baz']); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/Token.php b/modules/empikmarketplace/vendor/symfony/expression-language/Token.php new file mode 100644 index 00000000..60dc32d7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/Token.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Represents a Token. + * + * @author Fabien Potencier + */ +class Token +{ + public $value; + public $type; + public $cursor; + + const EOF_TYPE = 'end of expression'; + const NAME_TYPE = 'name'; + const NUMBER_TYPE = 'number'; + const STRING_TYPE = 'string'; + const OPERATOR_TYPE = 'operator'; + const PUNCTUATION_TYPE = 'punctuation'; + + /** + * @param string $type The type of the token (self::*_TYPE) + * @param string|int|float|null $value The token value + * @param int $cursor The cursor position in the source + */ + public function __construct($type, $value, $cursor) + { + $this->type = $type; + $this->value = $value; + $this->cursor = $cursor; + } + + /** + * Returns a string representation of the token. + * + * @return string A string representation of the token + */ + public function __toString() + { + return sprintf('%3d %-11s %s', $this->cursor, strtoupper($this->type), $this->value); + } + + /** + * Tests the current token for a type and/or a value. + * + * @param string $type The type to test + * @param string|null $value The token value + * + * @return bool + */ + public function test($type, $value = null) + { + return $this->type === $type && (null === $value || $this->value == $value); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/TokenStream.php b/modules/empikmarketplace/vendor/symfony/expression-language/TokenStream.php new file mode 100644 index 00000000..09d3854e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/TokenStream.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\ExpressionLanguage; + +/** + * Represents a token stream. + * + * @author Fabien Potencier + */ +class TokenStream +{ + public $current; + + private $tokens; + private $position = 0; + private $expression; + + /** + * @param array $tokens An array of tokens + * @param string $expression + */ + public function __construct(array $tokens, $expression = '') + { + $this->tokens = $tokens; + $this->current = $tokens[0]; + $this->expression = $expression; + } + + /** + * Returns a string representation of the token stream. + * + * @return string + */ + public function __toString() + { + return implode("\n", $this->tokens); + } + + /** + * Sets the pointer to the next token and returns the old one. + */ + public function next() + { + ++$this->position; + + if (!isset($this->tokens[$this->position])) { + throw new SyntaxError('Unexpected end of expression.', $this->current->cursor, $this->expression); + } + + $this->current = $this->tokens[$this->position]; + } + + /** + * Tests a token. + * + * @param array|int $type The type to test + * @param string|null $value The token value + * @param string|null $message The syntax error message + */ + public function expect($type, $value = null, $message = null) + { + $token = $this->current; + if (!$token->test($type, $value)) { + throw new SyntaxError(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).', $message ? $message.'. ' : '', $token->type, $token->value, $type, $value ? sprintf(' with value "%s"', $value) : ''), $token->cursor, $this->expression); + } + $this->next(); + } + + /** + * Checks if end of stream was reached. + * + * @return bool + */ + public function isEOF() + { + return Token::EOF_TYPE === $this->current->type; + } + + /** + * @internal + * + * @return string + */ + public function getExpression() + { + return $this->expression; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/composer.json b/modules/empikmarketplace/vendor/symfony/expression-language/composer.json new file mode 100644 index 00000000..5d5825b9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/composer.json @@ -0,0 +1,30 @@ +{ + "name": "symfony/expression-language", + "type": "library", + "description": "Symfony ExpressionLanguage Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\ExpressionLanguage\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/modules/empikmarketplace/vendor/symfony/expression-language/phpunit.xml.dist b/modules/empikmarketplace/vendor/symfony/expression-language/phpunit.xml.dist new file mode 100644 index 00000000..ae84dcd9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/expression-language/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/.gitignore b/modules/empikmarketplace/vendor/symfony/filesystem/.gitignore new file mode 100644 index 00000000..c49a5d8d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/CHANGELOG.md b/modules/empikmarketplace/vendor/symfony/filesystem/CHANGELOG.md new file mode 100644 index 00000000..d01f5f45 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/CHANGELOG.md @@ -0,0 +1,53 @@ +CHANGELOG +========= + +3.4.0 +----- + + * support for passing relative paths to `Filesystem::makePathRelative()` is deprecated and will be removed in 4.0 + +3.3.0 +----- + + * added `appendToFile()` to append contents to existing files + +3.2.0 +----- + + * added `readlink()` as a platform independent method to read links + +3.0.0 +----- + + * removed `$mode` argument from `Filesystem::dumpFile()` + +2.8.0 +----- + + * added tempnam() a stream aware version of PHP's native tempnam() + +2.6.0 +----- + + * added LockHandler + +2.3.12 +------ + + * deprecated dumpFile() file mode argument. + +2.3.0 +----- + + * added the dumpFile() method to atomically write files + +2.2.0 +----- + + * added a delete option for the mirror() method + +2.1.0 +----- + + * 24eb396 : BC Break : mkdir() function now throws exception in case of failure instead of returning Boolean value + * created the component diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Exception/ExceptionInterface.php b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/ExceptionInterface.php new file mode 100644 index 00000000..8f4f10aa --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Romain Neutron + */ +interface ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Exception/FileNotFoundException.php b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/FileNotFoundException.php new file mode 100644 index 00000000..bcc8fe81 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/FileNotFoundException.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Exception; + +/** + * Exception class thrown when a file couldn't be found. + * + * @author Fabien Potencier + * @author Christian Gärtner + */ +class FileNotFoundException extends IOException +{ + public function __construct($message = null, $code = 0, \Exception $previous = null, $path = null) + { + if (null === $message) { + if (null === $path) { + $message = 'File could not be found.'; + } else { + $message = sprintf('File "%s" could not be found.', $path); + } + } + + parent::__construct($message, $code, $previous, $path); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Exception/IOException.php b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/IOException.php new file mode 100644 index 00000000..144e0e60 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/IOException.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Exception; + +/** + * Exception class thrown when a filesystem operation failure happens. + * + * @author Romain Neutron + * @author Christian Gärtner + * @author Fabien Potencier + */ +class IOException extends \RuntimeException implements IOExceptionInterface +{ + private $path; + + public function __construct($message, $code = 0, \Exception $previous = null, $path = null) + { + $this->path = $path; + + parent::__construct($message, $code, $previous); + } + + /** + * {@inheritdoc} + */ + public function getPath() + { + return $this->path; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Exception/IOExceptionInterface.php b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/IOExceptionInterface.php new file mode 100644 index 00000000..f9d4644a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Exception/IOExceptionInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Exception; + +/** + * IOException interface for file and input/output stream related exceptions thrown by the component. + * + * @author Christian Gärtner + */ +interface IOExceptionInterface extends ExceptionInterface +{ + /** + * Returns the associated path for the exception. + * + * @return string|null The path + */ + public function getPath(); +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Filesystem.php b/modules/empikmarketplace/vendor/symfony/filesystem/Filesystem.php new file mode 100644 index 00000000..96b2e960 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Filesystem.php @@ -0,0 +1,774 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem; + +use Symfony\Component\Filesystem\Exception\FileNotFoundException; +use Symfony\Component\Filesystem\Exception\IOException; + +/** + * Provides basic utility to manipulate the file system. + * + * @author Fabien Potencier + */ +class Filesystem +{ + private static $lastError; + + /** + * Copies a file. + * + * If the target file is older than the origin file, it's always overwritten. + * If the target file is newer, it is overwritten only when the + * $overwriteNewerFiles option is set to true. + * + * @param string $originFile The original filename + * @param string $targetFile The target filename + * @param bool $overwriteNewerFiles If true, target files newer than origin files are overwritten + * + * @throws FileNotFoundException When originFile doesn't exist + * @throws IOException When copy fails + */ + public function copy($originFile, $targetFile, $overwriteNewerFiles = false) + { + $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://'); + if ($originIsLocal && !is_file($originFile)) { + throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile); + } + + $this->mkdir(\dirname($targetFile)); + + $doCopy = true; + if (!$overwriteNewerFiles && null === parse_url($originFile, \PHP_URL_HOST) && is_file($targetFile)) { + $doCopy = filemtime($originFile) > filemtime($targetFile); + } + + if ($doCopy) { + // https://bugs.php.net/64634 + if (false === $source = @fopen($originFile, 'r')) { + throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading.', $originFile, $targetFile), 0, null, $originFile); + } + + // Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default + if (false === $target = @fopen($targetFile, 'w', null, stream_context_create(['ftp' => ['overwrite' => true]]))) { + throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing.', $originFile, $targetFile), 0, null, $originFile); + } + + $bytesCopied = stream_copy_to_stream($source, $target); + fclose($source); + fclose($target); + unset($source, $target); + + if (!is_file($targetFile)) { + throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile); + } + + if ($originIsLocal) { + // Like `cp`, preserve executable permission bits + @chmod($targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111)); + + if ($bytesCopied !== $bytesOrigin = filesize($originFile)) { + throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile); + } + } + } + } + + /** + * Creates a directory recursively. + * + * @param string|iterable $dirs The directory path + * @param int $mode The directory mode + * + * @throws IOException On any directory creation failure + */ + public function mkdir($dirs, $mode = 0777) + { + foreach ($this->toIterable($dirs) as $dir) { + if (is_dir($dir)) { + continue; + } + + if (!self::box('mkdir', $dir, $mode, true)) { + if (!is_dir($dir)) { + // The directory was not created by a concurrent process. Let's throw an exception with a developer friendly error message if we have one + if (self::$lastError) { + throw new IOException(sprintf('Failed to create "%s": ', $dir).self::$lastError, 0, null, $dir); + } + throw new IOException(sprintf('Failed to create "%s".', $dir), 0, null, $dir); + } + } + } + } + + /** + * Checks the existence of files or directories. + * + * @param string|iterable $files A filename, an array of files, or a \Traversable instance to check + * + * @return bool true if the file exists, false otherwise + */ + public function exists($files) + { + $maxPathLength = \PHP_MAXPATHLEN - 2; + + foreach ($this->toIterable($files) as $file) { + if (\strlen($file) > $maxPathLength) { + throw new IOException(sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file); + } + + if (!file_exists($file)) { + return false; + } + } + + return true; + } + + /** + * Sets access and modification time of file. + * + * @param string|iterable $files A filename, an array of files, or a \Traversable instance to create + * @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used + * @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used + * + * @throws IOException When touch fails + */ + public function touch($files, $time = null, $atime = null) + { + foreach ($this->toIterable($files) as $file) { + $touch = $time ? @touch($file, $time, $atime) : @touch($file); + if (true !== $touch) { + throw new IOException(sprintf('Failed to touch "%s".', $file), 0, null, $file); + } + } + } + + /** + * Removes files or directories. + * + * @param string|iterable $files A filename, an array of files, or a \Traversable instance to remove + * + * @throws IOException When removal fails + */ + public function remove($files) + { + if ($files instanceof \Traversable) { + $files = iterator_to_array($files, false); + } elseif (!\is_array($files)) { + $files = [$files]; + } + $files = array_reverse($files); + foreach ($files as $file) { + if (is_link($file)) { + // See https://bugs.php.net/52176 + if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) { + throw new IOException(sprintf('Failed to remove symlink "%s": ', $file).self::$lastError); + } + } elseif (is_dir($file)) { + $this->remove(new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS)); + + if (!self::box('rmdir', $file) && file_exists($file)) { + throw new IOException(sprintf('Failed to remove directory "%s": ', $file).self::$lastError); + } + } elseif (!self::box('unlink', $file) && (false !== strpos(self::$lastError, 'Permission denied') || file_exists($file))) { + throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError); + } + } + } + + /** + * Change mode for an array of files or directories. + * + * @param string|iterable $files A filename, an array of files, or a \Traversable instance to change mode + * @param int $mode The new mode (octal) + * @param int $umask The mode mask (octal) + * @param bool $recursive Whether change the mod recursively or not + * + * @throws IOException When the change fails + */ + public function chmod($files, $mode, $umask = 0000, $recursive = false) + { + foreach ($this->toIterable($files) as $file) { + if ((\PHP_VERSION_ID < 80000 || \is_int($mode)) && true !== @chmod($file, $mode & ~$umask)) { + throw new IOException(sprintf('Failed to chmod file "%s".', $file), 0, null, $file); + } + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chmod(new \FilesystemIterator($file), $mode, $umask, true); + } + } + } + + /** + * Change the owner of an array of files or directories. + * + * @param string|iterable $files A filename, an array of files, or a \Traversable instance to change owner + * @param string|int $user A user name or number + * @param bool $recursive Whether change the owner recursively or not + * + * @throws IOException When the change fails + */ + public function chown($files, $user, $recursive = false) + { + foreach ($this->toIterable($files) as $file) { + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chown(new \FilesystemIterator($file), $user, true); + } + if (is_link($file) && \function_exists('lchown')) { + if (true !== @lchown($file, $user)) { + throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file); + } + } else { + if (true !== @chown($file, $user)) { + throw new IOException(sprintf('Failed to chown file "%s".', $file), 0, null, $file); + } + } + } + } + + /** + * Change the group of an array of files or directories. + * + * @param string|iterable $files A filename, an array of files, or a \Traversable instance to change group + * @param string|int $group A group name or number + * @param bool $recursive Whether change the group recursively or not + * + * @throws IOException When the change fails + */ + public function chgrp($files, $group, $recursive = false) + { + foreach ($this->toIterable($files) as $file) { + if ($recursive && is_dir($file) && !is_link($file)) { + $this->chgrp(new \FilesystemIterator($file), $group, true); + } + if (is_link($file) && \function_exists('lchgrp')) { + if (true !== @lchgrp($file, $group) || (\defined('HHVM_VERSION') && !posix_getgrnam($group))) { + throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file); + } + } else { + if (true !== @chgrp($file, $group)) { + throw new IOException(sprintf('Failed to chgrp file "%s".', $file), 0, null, $file); + } + } + } + } + + /** + * Renames a file or a directory. + * + * @param string $origin The origin filename or directory + * @param string $target The new filename or directory + * @param bool $overwrite Whether to overwrite the target if it already exists + * + * @throws IOException When target file or directory already exists + * @throws IOException When origin cannot be renamed + */ + public function rename($origin, $target, $overwrite = false) + { + // we check that target does not exist + if (!$overwrite && $this->isReadable($target)) { + throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); + } + + if (true !== @rename($origin, $target)) { + if (is_dir($origin)) { + // See https://bugs.php.net/54097 & https://php.net/rename#113943 + $this->mirror($origin, $target, null, ['override' => $overwrite, 'delete' => $overwrite]); + $this->remove($origin); + + return; + } + throw new IOException(sprintf('Cannot rename "%s" to "%s".', $origin, $target), 0, null, $target); + } + } + + /** + * Tells whether a file exists and is readable. + * + * @param string $filename Path to the file + * + * @return bool + * + * @throws IOException When windows path is longer than 258 characters + */ + private function isReadable($filename) + { + $maxPathLength = \PHP_MAXPATHLEN - 2; + + if (\strlen($filename) > $maxPathLength) { + throw new IOException(sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename); + } + + return is_readable($filename); + } + + /** + * Creates a symbolic link or copy a directory. + * + * @param string $originDir The origin directory path + * @param string $targetDir The symbolic link name + * @param bool $copyOnWindows Whether to copy files if on Windows + * + * @throws IOException When symlink fails + */ + public function symlink($originDir, $targetDir, $copyOnWindows = false) + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $originDir = strtr($originDir, '/', '\\'); + $targetDir = strtr($targetDir, '/', '\\'); + + if ($copyOnWindows) { + $this->mirror($originDir, $targetDir); + + return; + } + } + + $this->mkdir(\dirname($targetDir)); + + if (is_link($targetDir)) { + if (readlink($targetDir) === $originDir) { + return; + } + $this->remove($targetDir); + } + + if (!self::box('symlink', $originDir, $targetDir)) { + $this->linkException($originDir, $targetDir, 'symbolic'); + } + } + + /** + * Creates a hard link, or several hard links to a file. + * + * @param string $originFile The original file + * @param string|string[] $targetFiles The target file(s) + * + * @throws FileNotFoundException When original file is missing or not a file + * @throws IOException When link fails, including if link already exists + */ + public function hardlink($originFile, $targetFiles) + { + if (!$this->exists($originFile)) { + throw new FileNotFoundException(null, 0, null, $originFile); + } + + if (!is_file($originFile)) { + throw new FileNotFoundException(sprintf('Origin file "%s" is not a file.', $originFile)); + } + + foreach ($this->toIterable($targetFiles) as $targetFile) { + if (is_file($targetFile)) { + if (fileinode($originFile) === fileinode($targetFile)) { + continue; + } + $this->remove($targetFile); + } + + if (!self::box('link', $originFile, $targetFile)) { + $this->linkException($originFile, $targetFile, 'hard'); + } + } + } + + /** + * @param string $origin + * @param string $target + * @param string $linkType Name of the link type, typically 'symbolic' or 'hard' + */ + private function linkException($origin, $target, $linkType) + { + if (self::$lastError) { + if ('\\' === \DIRECTORY_SEPARATOR && false !== strpos(self::$lastError, 'error code(1314)')) { + throw new IOException(sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target); + } + } + throw new IOException(sprintf('Failed to create "%s" link from "%s" to "%s".', $linkType, $origin, $target), 0, null, $target); + } + + /** + * Resolves links in paths. + * + * With $canonicalize = false (default) + * - if $path does not exist or is not a link, returns null + * - if $path is a link, returns the next direct target of the link without considering the existence of the target + * + * With $canonicalize = true + * - if $path does not exist, returns null + * - if $path exists, returns its absolute fully resolved final version + * + * @param string $path A filesystem path + * @param bool $canonicalize Whether or not to return a canonicalized path + * + * @return string|null + */ + public function readlink($path, $canonicalize = false) + { + if (!$canonicalize && !is_link($path)) { + return null; + } + + if ($canonicalize) { + if (!$this->exists($path)) { + return null; + } + + if ('\\' === \DIRECTORY_SEPARATOR) { + $path = readlink($path); + } + + return realpath($path); + } + + if ('\\' === \DIRECTORY_SEPARATOR) { + return realpath($path); + } + + return readlink($path); + } + + /** + * Given an existing path, convert it to a path relative to a given starting path. + * + * @param string $endPath Absolute path of target + * @param string $startPath Absolute path where traversal begins + * + * @return string Path of target relative to starting path + */ + public function makePathRelative($endPath, $startPath) + { + if (!$this->isAbsolutePath($endPath) || !$this->isAbsolutePath($startPath)) { + @trigger_error(sprintf('Support for passing relative paths to %s() is deprecated since Symfony 3.4 and will be removed in 4.0.', __METHOD__), \E_USER_DEPRECATED); + } + + // Normalize separators on Windows + if ('\\' === \DIRECTORY_SEPARATOR) { + $endPath = str_replace('\\', '/', $endPath); + $startPath = str_replace('\\', '/', $startPath); + } + + $splitDriveLetter = function ($path) { + return (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0])) + ? [substr($path, 2), strtoupper($path[0])] + : [$path, null]; + }; + + $splitPath = function ($path, $absolute) { + $result = []; + + foreach (explode('/', trim($path, '/')) as $segment) { + if ('..' === $segment && ($absolute || \count($result))) { + array_pop($result); + } elseif ('.' !== $segment && '' !== $segment) { + $result[] = $segment; + } + } + + return $result; + }; + + list($endPath, $endDriveLetter) = $splitDriveLetter($endPath); + list($startPath, $startDriveLetter) = $splitDriveLetter($startPath); + + $startPathArr = $splitPath($startPath, static::isAbsolutePath($startPath)); + $endPathArr = $splitPath($endPath, static::isAbsolutePath($endPath)); + + if ($endDriveLetter && $startDriveLetter && $endDriveLetter != $startDriveLetter) { + // End path is on another drive, so no relative path exists + return $endDriveLetter.':/'.($endPathArr ? implode('/', $endPathArr).'/' : ''); + } + + // Find for which directory the common path stops + $index = 0; + while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) { + ++$index; + } + + // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels) + if (1 === \count($startPathArr) && '' === $startPathArr[0]) { + $depth = 0; + } else { + $depth = \count($startPathArr) - $index; + } + + // Repeated "../" for each level need to reach the common path + $traverser = str_repeat('../', $depth); + + $endPathRemainder = implode('/', \array_slice($endPathArr, $index)); + + // Construct $endPath from traversing to the common path, then to the remaining $endPath + $relativePath = $traverser.('' !== $endPathRemainder ? $endPathRemainder.'/' : ''); + + return '' === $relativePath ? './' : $relativePath; + } + + /** + * Mirrors a directory to another. + * + * Copies files and directories from the origin directory into the target directory. By default: + * + * - existing files in the target directory will be overwritten, except if they are newer (see the `override` option) + * - files in the target directory that do not exist in the source directory will not be deleted (see the `delete` option) + * + * @param string $originDir The origin directory + * @param string $targetDir The target directory + * @param \Traversable|null $iterator Iterator that filters which files and directories to copy, if null a recursive iterator is created + * @param array $options An array of boolean options + * Valid options are: + * - $options['override'] If true, target files newer than origin files are overwritten (see copy(), defaults to false) + * - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false) + * - $options['delete'] Whether to delete files that are not in the source directory (defaults to false) + * + * @throws IOException When file type is unknown + */ + public function mirror($originDir, $targetDir, \Traversable $iterator = null, $options = []) + { + $targetDir = rtrim($targetDir, '/\\'); + $originDir = rtrim($originDir, '/\\'); + $originDirLen = \strlen($originDir); + + // Iterate in destination folder to remove obsolete entries + if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) { + $deleteIterator = $iterator; + if (null === $deleteIterator) { + $flags = \FilesystemIterator::SKIP_DOTS; + $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST); + } + $targetDirLen = \strlen($targetDir); + foreach ($deleteIterator as $file) { + $origin = $originDir.substr($file->getPathname(), $targetDirLen); + if (!$this->exists($origin)) { + $this->remove($file); + } + } + } + + $copyOnWindows = false; + if (isset($options['copy_on_windows'])) { + $copyOnWindows = $options['copy_on_windows']; + } + + if (null === $iterator) { + $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS; + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST); + } + + if ($this->exists($originDir)) { + $this->mkdir($targetDir); + } + + foreach ($iterator as $file) { + $target = $targetDir.substr($file->getPathname(), $originDirLen); + + if ($copyOnWindows) { + if (is_file($file)) { + $this->copy($file, $target, isset($options['override']) ? $options['override'] : false); + } elseif (is_dir($file)) { + $this->mkdir($target); + } else { + throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file); + } + } else { + if (is_link($file)) { + $this->symlink($file->getLinkTarget(), $target); + } elseif (is_dir($file)) { + $this->mkdir($target); + } elseif (is_file($file)) { + $this->copy($file, $target, isset($options['override']) ? $options['override'] : false); + } else { + throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file); + } + } + } + } + + /** + * Returns whether the file path is an absolute path. + * + * @param string $file A file path + * + * @return bool + */ + public function isAbsolutePath($file) + { + return '' !== (string) $file && (strspn($file, '/\\', 0, 1) + || (\strlen($file) > 3 && ctype_alpha($file[0]) + && ':' === $file[1] + && strspn($file, '/\\', 2, 1) + ) + || null !== parse_url($file, \PHP_URL_SCHEME) + ); + } + + /** + * Creates a temporary file with support for custom stream wrappers. + * + * @param string $dir The directory where the temporary filename will be created + * @param string $prefix The prefix of the generated temporary filename + * Note: Windows uses only the first three characters of prefix + * + * @return string The new temporary filename (with path), or throw an exception on failure + */ + public function tempnam($dir, $prefix) + { + list($scheme, $hierarchy) = $this->getSchemeAndHierarchy($dir); + + // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem + if (null === $scheme || 'file' === $scheme || 'gs' === $scheme) { + $tmpFile = @tempnam($hierarchy, $prefix); + + // If tempnam failed or no scheme return the filename otherwise prepend the scheme + if (false !== $tmpFile) { + if (null !== $scheme && 'gs' !== $scheme) { + return $scheme.'://'.$tmpFile; + } + + return $tmpFile; + } + + throw new IOException('A temporary file could not be created.'); + } + + // Loop until we create a valid temp file or have reached 10 attempts + for ($i = 0; $i < 10; ++$i) { + // Create a unique filename + $tmpFile = $dir.'/'.$prefix.uniqid(mt_rand(), true); + + // Use fopen instead of file_exists as some streams do not support stat + // Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability + $handle = @fopen($tmpFile, 'x+'); + + // If unsuccessful restart the loop + if (false === $handle) { + continue; + } + + // Close the file if it was successfully opened + @fclose($handle); + + return $tmpFile; + } + + throw new IOException('A temporary file could not be created.'); + } + + /** + * Atomically dumps content into a file. + * + * @param string $filename The file to be written to + * @param string $content The data to write into the file + * + * @throws IOException if the file cannot be written to + */ + public function dumpFile($filename, $content) + { + $dir = \dirname($filename); + + if (!is_dir($dir)) { + $this->mkdir($dir); + } + + if (!is_writable($dir)) { + throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir); + } + + // Will create a temp file with 0600 access rights + // when the filesystem supports chmod. + $tmpFile = $this->tempnam($dir, basename($filename)); + + if (false === @file_put_contents($tmpFile, $content)) { + throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename); + } + + @chmod($tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask()); + + $this->rename($tmpFile, $filename, true); + } + + /** + * Appends content to an existing file. + * + * @param string $filename The file to which to append content + * @param string $content The content to append + * + * @throws IOException If the file is not writable + */ + public function appendToFile($filename, $content) + { + $dir = \dirname($filename); + + if (!is_dir($dir)) { + $this->mkdir($dir); + } + + if (!is_writable($dir)) { + throw new IOException(sprintf('Unable to write to the "%s" directory.', $dir), 0, null, $dir); + } + + if (false === @file_put_contents($filename, $content, \FILE_APPEND)) { + throw new IOException(sprintf('Failed to write file "%s".', $filename), 0, null, $filename); + } + } + + /** + * @param mixed $files + * + * @return array|\Traversable + */ + private function toIterable($files) + { + return \is_array($files) || $files instanceof \Traversable ? $files : [$files]; + } + + /** + * Gets a 2-tuple of scheme (may be null) and hierarchical part of a filename (e.g. file:///tmp -> [file, tmp]). + * + * @param string $filename The filename to be parsed + * + * @return array The filename scheme and hierarchical part + */ + private function getSchemeAndHierarchy($filename) + { + $components = explode('://', $filename, 2); + + return 2 === \count($components) ? [$components[0], $components[1]] : [null, $components[0]]; + } + + /** + * @param callable $func + * + * @return mixed + */ + private static function box($func) + { + self::$lastError = null; + set_error_handler(__CLASS__.'::handleError'); + try { + $result = \call_user_func_array($func, \array_slice(\func_get_args(), 1)); + restore_error_handler(); + + return $result; + } catch (\Throwable $e) { + } catch (\Exception $e) { + } + restore_error_handler(); + + throw $e; + } + + /** + * @internal + */ + public static function handleError($type, $msg) + { + self::$lastError = $msg; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/LICENSE b/modules/empikmarketplace/vendor/symfony/filesystem/LICENSE new file mode 100644 index 00000000..9e936ec0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2020 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/LockHandler.php b/modules/empikmarketplace/vendor/symfony/filesystem/LockHandler.php new file mode 100644 index 00000000..2aacfa71 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/LockHandler.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem; + +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Lock\Store\FlockStore; +use Symfony\Component\Lock\Store\SemaphoreStore; + +@trigger_error(sprintf('The %s class is deprecated since Symfony 3.4 and will be removed in 4.0. Use %s or %s instead.', LockHandler::class, SemaphoreStore::class, FlockStore::class), \E_USER_DEPRECATED); + +/** + * LockHandler class provides a simple abstraction to lock anything by means of + * a file lock. + * + * A locked file is created based on the lock name when calling lock(). Other + * lock handlers will not be able to lock the same name until it is released + * (explicitly by calling release() or implicitly when the instance holding the + * lock is destroyed). + * + * @author Grégoire Pineau + * @author Romain Neutron + * @author Nicolas Grekas + * + * @deprecated since version 3.4, to be removed in 4.0. Use Symfony\Component\Lock\Store\SemaphoreStore or Symfony\Component\Lock\Store\FlockStore instead. + */ +class LockHandler +{ + private $file; + private $handle; + + /** + * @param string $name The lock name + * @param string|null $lockPath The directory to store the lock. Default values will use temporary directory + * + * @throws IOException If the lock directory could not be created or is not writable + */ + public function __construct($name, $lockPath = null) + { + $lockPath = $lockPath ?: sys_get_temp_dir(); + + if (!is_dir($lockPath)) { + $fs = new Filesystem(); + $fs->mkdir($lockPath); + } + + if (!is_writable($lockPath)) { + throw new IOException(sprintf('The directory "%s" is not writable.', $lockPath), 0, null, $lockPath); + } + + $this->file = sprintf('%s/sf.%s.%s.lock', $lockPath, preg_replace('/[^a-z0-9\._-]+/i', '-', $name), hash('sha256', $name)); + } + + /** + * Lock the resource. + * + * @param bool $blocking Wait until the lock is released + * + * @return bool Returns true if the lock was acquired, false otherwise + * + * @throws IOException If the lock file could not be created or opened + */ + public function lock($blocking = false) + { + if ($this->handle) { + return true; + } + + $error = null; + + // Silence error reporting + set_error_handler(function ($errno, $msg) use (&$error) { + $error = $msg; + }); + + if (!$this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r')) { + if ($this->handle = fopen($this->file, 'x')) { + chmod($this->file, 0666); + } elseif (!$this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r')) { + usleep(100); // Give some time for chmod() to complete + $this->handle = fopen($this->file, 'r+') ?: fopen($this->file, 'r'); + } + } + restore_error_handler(); + + if (!$this->handle) { + throw new IOException($error, 0, null, $this->file); + } + + // On Windows, even if PHP doc says the contrary, LOCK_NB works, see + // https://bugs.php.net/54129 + if (!flock($this->handle, \LOCK_EX | ($blocking ? 0 : \LOCK_NB))) { + fclose($this->handle); + $this->handle = null; + + return false; + } + + return true; + } + + /** + * Release the resource. + */ + public function release() + { + if ($this->handle) { + flock($this->handle, \LOCK_UN | \LOCK_NB); + fclose($this->handle); + $this->handle = null; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/README.md b/modules/empikmarketplace/vendor/symfony/filesystem/README.md new file mode 100644 index 00000000..cb03d43c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/README.md @@ -0,0 +1,13 @@ +Filesystem Component +==================== + +The Filesystem component provides basic utilities for the filesystem. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/filesystem.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Tests/ExceptionTest.php b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/ExceptionTest.php new file mode 100644 index 00000000..300acf10 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/ExceptionTest.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Exception\FileNotFoundException; +use Symfony\Component\Filesystem\Exception\IOException; + +/** + * Test class for Filesystem. + */ +class ExceptionTest extends TestCase +{ + public function testGetPath() + { + $e = new IOException('', 0, null, '/foo'); + $this->assertEquals('/foo', $e->getPath(), 'The pass should be returned.'); + } + + public function testGeneratedMessage() + { + $e = new FileNotFoundException(null, 0, null, '/foo'); + $this->assertEquals('/foo', $e->getPath()); + $this->assertEquals('File "/foo" could not be found.', $e->getMessage(), 'A message should be generated.'); + } + + public function testGeneratedMessageWithoutPath() + { + $e = new FileNotFoundException(); + $this->assertEquals('File could not be found.', $e->getMessage(), 'A message should be generated.'); + } + + public function testCustomMessage() + { + $e = new FileNotFoundException('bar', 0, null, '/foo'); + $this->assertEquals('bar', $e->getMessage(), 'A custom message should be possible still.'); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Tests/FilesystemTest.php b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/FilesystemTest.php new file mode 100644 index 00000000..b157cc4e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/FilesystemTest.php @@ -0,0 +1,1684 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use Symfony\Component\Filesystem\Exception\IOException; + +/** + * Test class for Filesystem. + */ +class FilesystemTest extends FilesystemTestCase +{ + public function testCopyCreatesNewFile() + { + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertStringEqualsFile($targetFilePath, 'SOURCE FILE'); + } + + public function testCopyFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + } + + public function testCopyUnreadableFileFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + // skip test on Windows; PHP can't easily set file as unreadable on Windows + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test cannot run on Windows.'); + } + + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + // make sure target cannot be read + $this->filesystem->chmod($sourceFilePath, 0222); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + } + + public function testCopyOverridesExistingFileIfModified() + { + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + touch($targetFilePath, time() - 1000); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertStringEqualsFile($targetFilePath, 'SOURCE FILE'); + } + + public function testCopyDoesNotOverrideExistingFileByDefault() + { + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFileExists($targetFilePath); + $this->assertStringEqualsFile($targetFilePath, 'TARGET FILE'); + } + + public function testCopyOverridesExistingFileIfForced() + { + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, true); + + $this->assertFileExists($targetFilePath); + $this->assertStringEqualsFile($targetFilePath, 'SOURCE FILE'); + } + + public function testCopyWithOverrideWithReadOnlyTargetFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + // skip test on Windows; PHP can't easily set file as unwritable on Windows + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test cannot run on Windows.'); + } + + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + file_put_contents($targetFilePath, 'TARGET FILE'); + + // make sure both files have the same modification time + $modificationTime = time() - 1000; + touch($sourceFilePath, $modificationTime); + touch($targetFilePath, $modificationTime); + + // make sure target is read-only + $this->filesystem->chmod($targetFilePath, 0444); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, true); + } + + public function testCopyCreatesTargetDirectoryIfItDoesNotExist() + { + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFileDirectory = $this->workspace.\DIRECTORY_SEPARATOR.'directory'; + $targetFilePath = $targetFileDirectory.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertDirectoryExists($targetFileDirectory); + $this->assertFileExists($targetFilePath); + $this->assertStringEqualsFile($targetFilePath, 'SOURCE FILE'); + } + + /** + * @group network + */ + public function testCopyForOriginUrlsAndExistingLocalFileDefaultsToCopy() + { + if (!\in_array('https', stream_get_wrappers())) { + $this->markTestSkipped('"https" stream wrapper is not enabled.'); + } + $sourceFilePath = 'https://symfony.com/images/common/logo/logo_symfony_header.png'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($targetFilePath, 'TARGET FILE'); + + $this->filesystem->copy($sourceFilePath, $targetFilePath, false); + + $this->assertFileExists($targetFilePath); + $this->assertEquals(file_get_contents($sourceFilePath), file_get_contents($targetFilePath)); + } + + public function testMkdirCreatesDirectoriesRecursively() + { + $directory = $this->workspace + .\DIRECTORY_SEPARATOR.'directory' + .\DIRECTORY_SEPARATOR.'sub_directory'; + + $this->filesystem->mkdir($directory); + + $this->assertDirectoryExists($directory); + } + + public function testMkdirCreatesDirectoriesFromArray() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + $directories = [ + $basePath.'1', $basePath.'2', $basePath.'3', + ]; + + $this->filesystem->mkdir($directories); + + $this->assertDirectoryExists($basePath.'1'); + $this->assertDirectoryExists($basePath.'2'); + $this->assertDirectoryExists($basePath.'3'); + } + + public function testMkdirCreatesDirectoriesFromTraversableObject() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + $directories = new \ArrayObject([ + $basePath.'1', $basePath.'2', $basePath.'3', + ]); + + $this->filesystem->mkdir($directories); + + $this->assertDirectoryExists($basePath.'1'); + $this->assertDirectoryExists($basePath.'2'); + $this->assertDirectoryExists($basePath.'3'); + } + + public function testMkdirCreatesDirectoriesFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + $dir = $basePath.'2'; + + file_put_contents($dir, ''); + + $this->filesystem->mkdir($dir); + } + + public function testTouchCreatesEmptyFile() + { + $file = $this->workspace.\DIRECTORY_SEPARATOR.'1'; + + $this->filesystem->touch($file); + + $this->assertFileExists($file); + } + + public function testTouchFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $file = $this->workspace.\DIRECTORY_SEPARATOR.'1'.\DIRECTORY_SEPARATOR.'2'; + + $this->filesystem->touch($file); + } + + public function testTouchCreatesEmptyFilesFromArray() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + $files = [ + $basePath.'1', $basePath.'2', $basePath.'3', + ]; + + $this->filesystem->touch($files); + + $this->assertFileExists($basePath.'1'); + $this->assertFileExists($basePath.'2'); + $this->assertFileExists($basePath.'3'); + } + + public function testTouchCreatesEmptyFilesFromTraversableObject() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + $files = new \ArrayObject([ + $basePath.'1', $basePath.'2', $basePath.'3', + ]); + + $this->filesystem->touch($files); + + $this->assertFileExists($basePath.'1'); + $this->assertFileExists($basePath.'2'); + $this->assertFileExists($basePath.'3'); + } + + public function testRemoveCleansFilesAndDirectoriesIteratively() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR.'directory'.\DIRECTORY_SEPARATOR; + + mkdir($basePath); + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $this->filesystem->remove($basePath); + + $this->assertFileDoesNotExist($basePath); + } + + public function testRemoveCleansArrayOfFilesAndDirectories() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = [ + $basePath.'dir', $basePath.'file', + ]; + + $this->filesystem->remove($files); + + $this->assertFileDoesNotExist($basePath.'dir'); + $this->assertFileDoesNotExist($basePath.'file'); + } + + public function testRemoveCleansTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = new \ArrayObject([ + $basePath.'dir', $basePath.'file', + ]); + + $this->filesystem->remove($files); + + $this->assertFileDoesNotExist($basePath.'dir'); + $this->assertFileDoesNotExist($basePath.'file'); + } + + public function testRemoveIgnoresNonExistingFiles() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + + $files = [ + $basePath.'dir', $basePath.'file', + ]; + + $this->filesystem->remove($files); + + $this->assertFileDoesNotExist($basePath.'dir'); + } + + public function testRemoveThrowsExceptionOnPermissionDenied() + { + $this->markAsSkippedIfChmodIsMissing(); + + $basePath = $this->workspace.\DIRECTORY_SEPARATOR.'dir_permissions'; + mkdir($basePath); + $file = $basePath.\DIRECTORY_SEPARATOR.'file'; + touch($file); + chmod($basePath, 0400); + + try { + $this->filesystem->remove($file); + $this->fail('Filesystem::remove() should throw an exception'); + } catch (IOException $e) { + $this->assertStringContainsString('Failed to remove file "'.$file.'"', $e->getMessage()); + $this->assertStringContainsString('Permission denied', $e->getMessage()); + } finally { + // Make sure we can clean up this file + chmod($basePath, 0777); + } + } + + public function testRemoveCleansInvalidLinks() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $basePath = $this->workspace.\DIRECTORY_SEPARATOR.'directory'.\DIRECTORY_SEPARATOR; + + mkdir($basePath); + mkdir($basePath.'dir'); + // create symlink to nonexistent file + @symlink($basePath.'file', $basePath.'file-link'); + + // create symlink to dir using trailing forward slash + $this->filesystem->symlink($basePath.'dir/', $basePath.'dir-link'); + $this->assertDirectoryExists($basePath.'dir-link'); + + // create symlink to nonexistent dir + rmdir($basePath.'dir'); + $this->assertFalse('\\' === \DIRECTORY_SEPARATOR ? @readlink($basePath.'dir-link') : is_dir($basePath.'dir-link')); + + $this->filesystem->remove($basePath); + + $this->assertFileDoesNotExist($basePath); + } + + public function testFilesExists() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR.'directory'.\DIRECTORY_SEPARATOR; + + mkdir($basePath); + touch($basePath.'file1'); + mkdir($basePath.'folder'); + + $this->assertTrue($this->filesystem->exists($basePath.'file1')); + $this->assertTrue($this->filesystem->exists($basePath.'folder')); + } + + public function testFilesExistsFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + if ('\\' !== \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Long file names are an issue on Windows'); + } + $basePath = $this->workspace.'\\directory\\'; + $maxPathLength = \PHP_MAXPATHLEN - 2; + + $oldPath = getcwd(); + mkdir($basePath); + chdir($basePath); + $file = str_repeat('T', $maxPathLength - \strlen($basePath) + 1); + $path = $basePath.$file; + exec('TYPE NUL >>'.$file); // equivalent of touch, we can not use the php touch() here because it suffers from the same limitation + $this->longPathNamesWindows[] = $path; // save this so we can clean up later + chdir($oldPath); + $this->filesystem->exists($path); + } + + public function testFilesExistsTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + + $files = new \ArrayObject([ + $basePath.'dir', $basePath.'file', + ]); + + $this->assertTrue($this->filesystem->exists($files)); + } + + public function testFilesNotExistsTraversableObjectOfFilesAndDirectories() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR; + + mkdir($basePath.'dir'); + touch($basePath.'file'); + touch($basePath.'file2'); + + $files = new \ArrayObject([ + $basePath.'dir', $basePath.'file', $basePath.'file2', + ]); + + unlink($basePath.'file'); + + $this->assertFalse($this->filesystem->exists($files)); + } + + public function testInvalidFileNotExists() + { + $basePath = $this->workspace.\DIRECTORY_SEPARATOR.'directory'.\DIRECTORY_SEPARATOR; + + $this->assertFalse($this->filesystem->exists($basePath.time())); + } + + public function testChmodChangesFileMode() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.\DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0400); + $this->filesystem->chmod($dir, 0753); + + $this->assertFilePermissions(753, $dir); + $this->assertFilePermissions(400, $file); + } + + public function testChmodWithWrongModLeavesPreviousPermissionsUntouched() + { + $this->markAsSkippedIfChmodIsMissing(); + + if (\defined('HHVM_VERSION')) { + $this->markTestSkipped('chmod() changes permissions even when passing invalid modes on HHVM'); + } + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + touch($dir); + + $permissions = fileperms($dir); + + $this->filesystem->chmod($dir, 'Wrongmode'); + + $this->assertSame($permissions, fileperms($dir)); + } + + public function testChmodRecursive() + { + $this->markAsSkippedIfChmodIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.\DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0400, 0000, true); + $this->filesystem->chmod($dir, 0753, 0000, true); + + $this->assertFilePermissions(753, $dir); + $this->assertFilePermissions(753, $file); + } + + public function testChmodAppliesUmask() + { + $this->markAsSkippedIfChmodIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + touch($file); + + $this->filesystem->chmod($file, 0770, 0022); + $this->assertFilePermissions(750, $file); + } + + public function testChmodChangesModeOfArrayOfFiles() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.\DIRECTORY_SEPARATOR.'directory'; + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $files = [$directory, $file]; + + mkdir($directory); + touch($file); + + $this->filesystem->chmod($files, 0753); + + $this->assertFilePermissions(753, $file); + $this->assertFilePermissions(753, $directory); + } + + public function testChmodChangesModeOfTraversableFileObject() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.\DIRECTORY_SEPARATOR.'directory'; + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $files = new \ArrayObject([$directory, $file]); + + mkdir($directory); + touch($file); + + $this->filesystem->chmod($files, 0753); + + $this->assertFilePermissions(753, $file); + $this->assertFilePermissions(753, $directory); + } + + public function testChmodChangesZeroModeOnSubdirectoriesOnRecursive() + { + $this->markAsSkippedIfChmodIsMissing(); + + $directory = $this->workspace.\DIRECTORY_SEPARATOR.'directory'; + $subdirectory = $directory.\DIRECTORY_SEPARATOR.'subdirectory'; + + mkdir($directory); + mkdir($subdirectory); + chmod($subdirectory, 0000); + + $this->filesystem->chmod($directory, 0753, 0000, true); + + $this->assertFilePermissions(753, $subdirectory); + } + + public function testChown() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $owner = $this->getFileOwner($dir); + $this->filesystem->chown($dir, $owner); + + $this->assertSame($owner, $this->getFileOwner($dir)); + } + + public function testChownRecursive() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.\DIRECTORY_SEPARATOR.'file'; + touch($file); + + $owner = $this->getFileOwner($dir); + $this->filesystem->chown($dir, $owner, true); + + $this->assertSame($owner, $this->getFileOwner($file)); + } + + public function testChownSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $owner = $this->getFileOwner($link); + $this->filesystem->chown($link, $owner); + + $this->assertSame($owner, $this->getFileOwner($link)); + } + + public function testChownLink() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->hardlink($file, $link); + + $owner = $this->getFileOwner($link); + $this->filesystem->chown($link, $owner); + + $this->assertSame($owner, $this->getFileOwner($link)); + } + + public function testChownSymlinkFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChownLinkFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->hardlink($file, $link); + + $this->filesystem->chown($link, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChownFail() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chown($dir, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChgrp() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $group = $this->getFileGroup($dir); + $this->filesystem->chgrp($dir, $group); + + $this->assertSame($group, $this->getFileGroup($dir)); + } + + public function testChgrpRecursive() + { + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + $file = $dir.\DIRECTORY_SEPARATOR.'file'; + touch($file); + + $group = $this->getFileGroup($dir); + $this->filesystem->chgrp($dir, $group, true); + + $this->assertSame($group, $this->getFileGroup($file)); + } + + public function testChgrpSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $group = $this->getFileGroup($link); + $this->filesystem->chgrp($link, $group); + + $this->assertSame($group, $this->getFileGroup($link)); + } + + public function testChgrpLink() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->hardlink($file, $link); + + $group = $this->getFileGroup($link); + $this->filesystem->chgrp($link, $group); + + $this->assertSame($group, $this->getFileGroup($link)); + } + + public function testChgrpSymlinkFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link); + + $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChgrpLinkFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->hardlink($file, $link); + + $this->filesystem->chgrp($link, 'user'.time().mt_rand(1000, 9999)); + } + + public function testChgrpFail() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->markAsSkippedIfPosixIsMissing(); + + $dir = $this->workspace.\DIRECTORY_SEPARATOR.'dir'; + mkdir($dir); + + $this->filesystem->chgrp($dir, 'user'.time().mt_rand(1000, 9999)); + } + + public function testRename() + { + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.\DIRECTORY_SEPARATOR.'new_file'; + touch($file); + + $this->filesystem->rename($file, $newPath); + + $this->assertFileDoesNotExist($file); + $this->assertFileExists($newPath); + } + + public function testRenameThrowsExceptionIfTargetAlreadyExists() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.\DIRECTORY_SEPARATOR.'new_file'; + + touch($file); + touch($newPath); + + $this->filesystem->rename($file, $newPath); + } + + public function testRenameOverwritesTheTargetIfItAlreadyExists() + { + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $newPath = $this->workspace.\DIRECTORY_SEPARATOR.'new_file'; + + touch($file); + touch($newPath); + + $this->filesystem->rename($file, $newPath, true); + + $this->assertFileDoesNotExist($file); + $this->assertFileExists($newPath); + } + + public function testRenameThrowsExceptionOnError() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $file = $this->workspace.\DIRECTORY_SEPARATOR.uniqid('fs_test_', true); + $newPath = $this->workspace.\DIRECTORY_SEPARATOR.'new_file'; + + $this->filesystem->rename($file, $newPath); + } + + public function testSymlink() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Windows does not support creating "broken" symlinks'); + } + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + // $file does not exist right now: creating "broken" links is a wanted feature + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + + // Create the linked file AFTER creating the link + touch($file); + + $this->assertEquals($file, readlink($link)); + } + + /** + * @depends testSymlink + */ + public function testRemoveSymlink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + $this->filesystem->remove($link); + + $this->assertFalse(is_link($link)); + $this->assertFalse(is_file($link)); + $this->assertDirectoryDoesNotExist($link); + } + + public function testSymlinkIsOverwrittenIfPointsToDifferentTarget() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + symlink($this->workspace, $link); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + public function testSymlinkIsNotOverwrittenIfAlreadyCreated() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + symlink($file, $link); + + $this->filesystem->symlink($file, $link); + + $this->assertTrue(is_link($link)); + $this->assertEquals($file, readlink($link)); + } + + public function testSymlinkCreatesTargetDirectoryIfItDoesNotExist() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link1 = $this->workspace.\DIRECTORY_SEPARATOR.'dir'.\DIRECTORY_SEPARATOR.'link'; + $link2 = $this->workspace.\DIRECTORY_SEPARATOR.'dir'.\DIRECTORY_SEPARATOR.'subdir'.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + $this->filesystem->symlink($file, $link1); + $this->filesystem->symlink($file, $link2); + + $this->assertTrue(is_link($link1)); + $this->assertEquals($file, readlink($link1)); + $this->assertTrue(is_link($link2)); + $this->assertEquals($file, readlink($link2)); + } + + public function testLink() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + $this->filesystem->hardlink($file, $link); + + $this->assertTrue(is_file($link)); + $this->assertEquals(fileinode($file), fileinode($link)); + } + + /** + * @depends testLink + */ + public function testRemoveLink() + { + $this->markAsSkippedIfLinkIsMissing(); + + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + $this->filesystem->remove($link); + + $this->assertTrue(!is_file($link)); + } + + public function testLinkIsOverwrittenIfPointsToDifferentTarget() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $file2 = $this->workspace.\DIRECTORY_SEPARATOR.'file2'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + touch($file2); + link($file2, $link); + + $this->filesystem->hardlink($file, $link); + + $this->assertTrue(is_file($link)); + $this->assertEquals(fileinode($file), fileinode($link)); + } + + public function testLinkIsNotOverwrittenIfAlreadyCreated() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + link($file, $link); + + $this->filesystem->hardlink($file, $link); + + $this->assertTrue(is_file($link)); + $this->assertEquals(fileinode($file), fileinode($link)); + } + + public function testLinkWithSeveralTargets() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link1 = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + $link2 = $this->workspace.\DIRECTORY_SEPARATOR.'link2'; + + touch($file); + + $this->filesystem->hardlink($file, [$link1, $link2]); + + $this->assertTrue(is_file($link1)); + $this->assertEquals(fileinode($file), fileinode($link1)); + $this->assertTrue(is_file($link2)); + $this->assertEquals(fileinode($file), fileinode($link2)); + } + + public function testLinkWithSameTarget() + { + $this->markAsSkippedIfLinkIsMissing(); + + $file = $this->workspace.\DIRECTORY_SEPARATOR.'file'; + $link = $this->workspace.\DIRECTORY_SEPARATOR.'link'; + + touch($file); + + // practically same as testLinkIsNotOverwrittenIfAlreadyCreated + $this->filesystem->hardlink($file, [$link, $link]); + + $this->assertTrue(is_file($link)); + $this->assertEquals(fileinode($file), fileinode($link)); + } + + public function testReadRelativeLink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Relative symbolic links are not supported on Windows'); + } + + $file = $this->workspace.'/file'; + $link1 = $this->workspace.'/dir/link'; + $link2 = $this->workspace.'/dir/link2'; + touch($file); + + $this->filesystem->symlink('../file', $link1); + $this->filesystem->symlink('link', $link2); + + $this->assertEquals($this->normalize('../file'), $this->filesystem->readlink($link1)); + $this->assertEquals('link', $this->filesystem->readlink($link2)); + $this->assertEquals($file, $this->filesystem->readlink($link1, true)); + $this->assertEquals($file, $this->filesystem->readlink($link2, true)); + $this->assertEquals($file, $this->filesystem->readlink($file, true)); + } + + public function testReadAbsoluteLink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->normalize($this->workspace.'/file'); + $link1 = $this->normalize($this->workspace.'/dir/link'); + $link2 = $this->normalize($this->workspace.'/dir/link2'); + touch($file); + + $this->filesystem->symlink($file, $link1); + $this->filesystem->symlink($link1, $link2); + + $this->assertEquals($file, $this->filesystem->readlink($link1)); + $this->assertEquals($link1, $this->filesystem->readlink($link2)); + $this->assertEquals($file, $this->filesystem->readlink($link1, true)); + $this->assertEquals($file, $this->filesystem->readlink($link2, true)); + $this->assertEquals($file, $this->filesystem->readlink($file, true)); + } + + public function testReadBrokenLink() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('Windows does not support creating "broken" symlinks'); + } + + $file = $this->workspace.'/file'; + $link = $this->workspace.'/link'; + + $this->filesystem->symlink($file, $link); + + $this->assertEquals($file, $this->filesystem->readlink($link)); + $this->assertNull($this->filesystem->readlink($link, true)); + + touch($file); + $this->assertEquals($file, $this->filesystem->readlink($link, true)); + } + + public function testReadLinkDefaultPathDoesNotExist() + { + $this->assertNull($this->filesystem->readlink($this->normalize($this->workspace.'/invalid'))); + } + + public function testReadLinkDefaultPathNotLink() + { + $file = $this->normalize($this->workspace.'/file'); + touch($file); + + $this->assertNull($this->filesystem->readlink($file)); + } + + public function testReadLinkCanonicalizePath() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $file = $this->normalize($this->workspace.'/file'); + mkdir($this->normalize($this->workspace.'/dir')); + touch($file); + + $this->assertEquals($file, $this->filesystem->readlink($this->normalize($this->workspace.'/dir/../file'), true)); + } + + public function testReadLinkCanonicalizedPathDoesNotExist() + { + $this->assertNull($this->filesystem->readlink($this->normalize($this->workspace.'invalid'), true)); + } + + /** + * @dataProvider providePathsForMakePathRelative + */ + public function testMakePathRelative($endPath, $startPath, $expectedPath) + { + $path = $this->filesystem->makePathRelative($endPath, $startPath); + + $this->assertEquals($expectedPath, $path); + } + + public function providePathsForMakePathRelative() + { + $paths = [ + ['/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component', '../'], + ['/var/lib/symfony/src/Symfony/', '/var/lib/symfony/src/Symfony/Component/', '../'], + ['/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component', '../'], + ['/var/lib/symfony/src/Symfony', '/var/lib/symfony/src/Symfony/Component/', '../'], + ['/usr/lib/symfony/', '/var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'], + ['/var/lib/symfony/src/Symfony/', '/var/lib/symfony/', 'src/Symfony/'], + ['/aa/bb', '/aa/bb', './'], + ['/aa/bb', '/aa/bb/', './'], + ['/aa/bb/', '/aa/bb', './'], + ['/aa/bb/', '/aa/bb/', './'], + ['/aa/bb/cc', '/aa/bb/cc/dd', '../'], + ['/aa/bb/cc', '/aa/bb/cc/dd/', '../'], + ['/aa/bb/cc/', '/aa/bb/cc/dd', '../'], + ['/aa/bb/cc/', '/aa/bb/cc/dd/', '../'], + ['/aa/bb/cc', '/aa', 'bb/cc/'], + ['/aa/bb/cc', '/aa/', 'bb/cc/'], + ['/aa/bb/cc/', '/aa', 'bb/cc/'], + ['/aa/bb/cc/', '/aa/', 'bb/cc/'], + ['/a/aab/bb', '/a/aa', '../aab/bb/'], + ['/a/aab/bb', '/a/aa/', '../aab/bb/'], + ['/a/aab/bb/', '/a/aa', '../aab/bb/'], + ['/a/aab/bb/', '/a/aa/', '../aab/bb/'], + ['/a/aab/bb/', '/', 'a/aab/bb/'], + ['/a/aab/bb/', '/b/aab', '../../a/aab/bb/'], + ['/aab/bb', '/aa', '../aab/bb/'], + ['/aab', '/aa', '../aab/'], + ['/aa/bb/cc', '/aa/dd/..', 'bb/cc/'], + ['/aa/../bb/cc', '/aa/dd/..', '../bb/cc/'], + ['/aa/bb/../../cc', '/aa/../dd/..', 'cc/'], + ['/../aa/bb/cc', '/aa/dd/..', 'bb/cc/'], + ['/../../aa/../bb/cc', '/aa/dd/..', '../bb/cc/'], + ['C:/aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'], + ['C:/aa/bb/cc', 'c:/aa/dd/..', 'bb/cc/'], + ['c:/aa/../bb/cc', 'c:/aa/dd/..', '../bb/cc/'], + ['C:/aa/bb/../../cc', 'C:/aa/../dd/..', 'cc/'], + ['C:/../aa/bb/cc', 'C:/aa/dd/..', 'bb/cc/'], + ['C:/../../aa/../bb/cc', 'C:/aa/dd/..', '../bb/cc/'], + ['D:/', 'C:/aa/../bb/cc', 'D:/'], + ['D:/aa/bb', 'C:/aa', 'D:/aa/bb/'], + ['D:/../../aa/../bb/cc', 'C:/aa/dd/..', 'D:/bb/cc/'], + ]; + + if ('\\' === \DIRECTORY_SEPARATOR) { + $paths[] = ['c:\var\lib/symfony/src/Symfony/', 'c:/var/lib/symfony/', 'src/Symfony/']; + } + + return $paths; + } + + /** + * @group legacy + * @dataProvider provideLegacyPathsForMakePathRelativeWithRelativePaths + * @expectedDeprecation Support for passing relative paths to Symfony\Component\Filesystem\Filesystem::makePathRelative() is deprecated since Symfony 3.4 and will be removed in 4.0. + */ + public function testMakePathRelativeWithRelativePaths($endPath, $startPath, $expectedPath) + { + $path = $this->filesystem->makePathRelative($endPath, $startPath); + + $this->assertEquals($expectedPath, $path); + } + + public function provideLegacyPathsForMakePathRelativeWithRelativePaths() + { + return [ + ['usr/lib/symfony/', 'var/lib/symfony/src/Symfony/Component', '../../../../../../usr/lib/symfony/'], + ['aa/bb', 'aa/cc', '../bb/'], + ['aa/cc', 'bb/cc', '../../aa/cc/'], + ['aa/bb', 'aa/./cc', '../bb/'], + ['aa/./bb', 'aa/cc', '../bb/'], + ['aa/./bb', 'aa/./cc', '../bb/'], + ['../../', '../../', './'], + ['../aa/bb/', 'aa/bb/', '../../../aa/bb/'], + ['../../../', '../../', '../'], + ['', '', './'], + ['', 'aa/', '../'], + ['aa/', '', 'aa/'], + ]; + } + + public function testMirrorCopiesFilesAndDirectoriesRecursively() + { + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + $directory = $sourcePath.'directory'.\DIRECTORY_SEPARATOR; + $file1 = $directory.'file1'; + $file2 = $sourcePath.'file2'; + + mkdir($sourcePath); + mkdir($directory); + file_put_contents($file1, 'FILE1'); + file_put_contents($file2, 'FILE2'); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertDirectoryExists($targetPath); + $this->assertDirectoryExists($targetPath.'directory'); + $this->assertFileEquals($file1, $targetPath.'directory'.\DIRECTORY_SEPARATOR.'file1'); + $this->assertFileEquals($file2, $targetPath.'file2'); + + $this->filesystem->remove($file1); + + $this->filesystem->mirror($sourcePath, $targetPath, null, ['delete' => false]); + $this->assertTrue($this->filesystem->exists($targetPath.'directory'.\DIRECTORY_SEPARATOR.'file1')); + + $this->filesystem->mirror($sourcePath, $targetPath, null, ['delete' => true]); + $this->assertFalse($this->filesystem->exists($targetPath.'directory'.\DIRECTORY_SEPARATOR.'file1')); + + file_put_contents($file1, 'FILE1'); + + $this->filesystem->mirror($sourcePath, $targetPath, null, ['delete' => true]); + $this->assertTrue($this->filesystem->exists($targetPath.'directory'.\DIRECTORY_SEPARATOR.'file1')); + + $this->filesystem->remove($directory); + $this->filesystem->mirror($sourcePath, $targetPath, null, ['delete' => true]); + $this->assertFalse($this->filesystem->exists($targetPath.'directory')); + $this->assertFalse($this->filesystem->exists($targetPath.'directory'.\DIRECTORY_SEPARATOR.'file1')); + } + + public function testMirrorCreatesEmptyDirectory() + { + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertDirectoryExists($targetPath); + + $this->filesystem->remove($sourcePath); + } + + public function testMirrorCopiesLinks() + { + $this->markAsSkippedIfSymlinkIsMissing(); + + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + file_put_contents($sourcePath.'file1', 'FILE1'); + symlink($sourcePath.'file1', $sourcePath.'link1'); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertDirectoryExists($targetPath); + $this->assertFileEquals($sourcePath.'file1', $targetPath.'link1'); + $this->assertTrue(is_link($targetPath.\DIRECTORY_SEPARATOR.'link1')); + } + + public function testMirrorCopiesLinkedDirectoryContents() + { + $this->markAsSkippedIfSymlinkIsMissing(true); + + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + + mkdir($sourcePath.'nested/', 0777, true); + file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); + // Note: We symlink directory, not file + symlink($sourcePath.'nested', $sourcePath.'link1'); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertDirectoryExists($targetPath); + $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt'); + $this->assertTrue(is_link($targetPath.\DIRECTORY_SEPARATOR.'link1')); + } + + public function testMirrorCopiesRelativeLinkedContents() + { + $this->markAsSkippedIfSymlinkIsMissing(true); + + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + $oldPath = getcwd(); + + mkdir($sourcePath.'nested/', 0777, true); + file_put_contents($sourcePath.'/nested/file1.txt', 'FILE1'); + // Note: Create relative symlink + chdir($sourcePath); + symlink('nested', 'link1'); + + chdir($oldPath); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertDirectoryExists($targetPath); + $this->assertFileEquals($sourcePath.'/nested/file1.txt', $targetPath.'link1/file1.txt'); + $this->assertTrue(is_link($targetPath.\DIRECTORY_SEPARATOR.'link1')); + $this->assertEquals('\\' === \DIRECTORY_SEPARATOR ? realpath($sourcePath.'\nested') : 'nested', readlink($targetPath.\DIRECTORY_SEPARATOR.'link1')); + } + + public function testMirrorContentsWithSameNameAsSourceOrTargetWithoutDeleteOption() + { + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + touch($sourcePath.'source'); + touch($sourcePath.'target'); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + $oldPath = getcwd(); + chdir($this->workspace); + + $this->filesystem->mirror('source', $targetPath); + + chdir($oldPath); + + $this->assertDirectoryExists($targetPath); + $this->assertFileExists($targetPath.'source'); + $this->assertFileExists($targetPath.'target'); + } + + public function testMirrorContentsWithSameNameAsSourceOrTargetWithDeleteOption() + { + $sourcePath = $this->workspace.\DIRECTORY_SEPARATOR.'source'.\DIRECTORY_SEPARATOR; + + mkdir($sourcePath); + touch($sourcePath.'source'); + + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'target'.\DIRECTORY_SEPARATOR; + + mkdir($targetPath); + touch($targetPath.'source'); + touch($targetPath.'target'); + + $oldPath = getcwd(); + chdir($this->workspace); + + $this->filesystem->mirror('source', 'target', null, ['delete' => true]); + + chdir($oldPath); + + $this->assertDirectoryExists($targetPath); + $this->assertFileExists($targetPath.'source'); + $this->assertFileDoesNotExist($targetPath.'target'); + } + + public function testMirrorFromSubdirectoryInToParentDirectory() + { + $targetPath = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR; + $sourcePath = $targetPath.'bar'.\DIRECTORY_SEPARATOR; + $file1 = $sourcePath.'file1'; + $file2 = $sourcePath.'file2'; + + $this->filesystem->mkdir($sourcePath); + file_put_contents($file1, 'FILE1'); + file_put_contents($file2, 'FILE2'); + + $this->filesystem->mirror($sourcePath, $targetPath); + + $this->assertFileEquals($file1, $targetPath.'file1'); + } + + /** + * @dataProvider providePathsForIsAbsolutePath + */ + public function testIsAbsolutePath($path, $expectedResult) + { + $result = $this->filesystem->isAbsolutePath($path); + + $this->assertEquals($expectedResult, $result); + } + + public function providePathsForIsAbsolutePath() + { + return [ + ['/var/lib', true], + ['c:\\\\var\\lib', true], + ['\\var\\lib', true], + ['var/lib', false], + ['../var/lib', false], + ['', false], + [null, false], + ]; + } + + public function testTempnam() + { + $dirname = $this->workspace; + + $filename = $this->filesystem->tempnam($dirname, 'foo'); + + $this->assertFileExists($filename); + } + + public function testTempnamWithFileScheme() + { + $scheme = 'file://'; + $dirname = $scheme.$this->workspace; + + $filename = $this->filesystem->tempnam($dirname, 'foo'); + + $this->assertStringStartsWith($scheme, $filename); + $this->assertFileExists($filename); + } + + public function testTempnamWithMockScheme() + { + stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream'); + + $scheme = 'mock://'; + $dirname = $scheme.$this->workspace; + + $filename = $this->filesystem->tempnam($dirname, 'foo'); + + $this->assertStringStartsWith($scheme, $filename); + $this->assertFileExists($filename); + } + + public function testTempnamWithZlibSchemeFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $scheme = 'compress.zlib://'; + $dirname = $scheme.$this->workspace; + + // The compress.zlib:// stream does not support mode x: creates the file, errors "failed to open stream: operation failed" and returns false + $this->filesystem->tempnam($dirname, 'bar'); + } + + public function testTempnamWithPHPTempSchemeFails() + { + $scheme = 'php://temp'; + $dirname = $scheme; + + $filename = $this->filesystem->tempnam($dirname, 'bar'); + + $this->assertStringStartsWith($scheme, $filename); + + // The php://temp stream deletes the file after close + $this->assertFileDoesNotExist($filename); + } + + public function testTempnamWithPharSchemeFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + // Skip test if Phar disabled phar.readonly must be 0 in php.ini + if (!\Phar::canWrite()) { + $this->markTestSkipped('This test cannot run when phar.readonly is 1.'); + } + + $scheme = 'phar://'; + $dirname = $scheme.$this->workspace; + $pharname = 'foo.phar'; + + new \Phar($this->workspace.'/'.$pharname, 0, $pharname); + // The phar:// stream does not support mode x: fails to create file, errors "failed to open stream: phar error: "$filename" is not a file in phar "$pharname"" and returns false + $this->filesystem->tempnam($dirname, $pharname.'/bar'); + } + + public function testTempnamWithHTTPSchemeFails() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $scheme = 'http://'; + $dirname = $scheme.$this->workspace; + + // The http:// scheme is read-only + $this->filesystem->tempnam($dirname, 'bar'); + } + + public function testTempnamOnUnwritableFallsBackToSysTmp() + { + $scheme = 'file://'; + $dirname = $scheme.$this->workspace.\DIRECTORY_SEPARATOR.'does_not_exist'; + + $filename = $this->filesystem->tempnam($dirname, 'bar'); + $realTempDir = realpath(sys_get_temp_dir()); + $this->assertStringStartsWith(rtrim($scheme.$realTempDir, \DIRECTORY_SEPARATOR), $filename); + $this->assertFileExists($filename); + + // Tear down + @unlink($filename); + } + + public function testDumpFile() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + + // skip mode check on Windows + if ('\\' !== \DIRECTORY_SEPARATOR) { + $oldMask = umask(0002); + } + + $this->filesystem->dumpFile($filename, 'bar'); + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'bar'); + + // skip mode check on Windows + if ('\\' !== \DIRECTORY_SEPARATOR) { + $this->assertFilePermissions(664, $filename); + umask($oldMask); + } + } + + public function testDumpFileWithArray() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, ['bar']); + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'bar'); + } + + public function testDumpFileWithResource() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + + $resource = fopen('php://memory', 'rw'); + fwrite($resource, 'bar'); + fseek($resource, 0); + + $this->filesystem->dumpFile($filename, $resource); + + fclose($resource); + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'bar'); + } + + public function testDumpFileOverwritesAnExistingFile() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt'; + file_put_contents($filename, 'FOO BAR'); + + $this->filesystem->dumpFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'bar'); + } + + public function testDumpFileWithFileScheme() + { + if (\defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM does not handle the file:// scheme correctly'); + } + + $scheme = 'file://'; + $filename = $scheme.$this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'bar'); + } + + public function testDumpFileWithZlibScheme() + { + $scheme = 'compress.zlib://'; + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + + $this->filesystem->dumpFile($filename, 'bar'); + + // Zlib stat uses file:// wrapper so remove scheme + $this->assertFileExists(str_replace($scheme, '', $filename)); + $this->assertStringEqualsFile($filename, 'bar'); + } + + public function testAppendToFile() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'bar.txt'; + + // skip mode check on Windows + if ('\\' !== \DIRECTORY_SEPARATOR) { + $oldMask = umask(0002); + } + + $this->filesystem->dumpFile($filename, 'foo'); + + $this->filesystem->appendToFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'foobar'); + + // skip mode check on Windows + if ('\\' !== \DIRECTORY_SEPARATOR) { + $this->assertFilePermissions(664, $filename); + umask($oldMask); + } + } + + public function testAppendToFileWithScheme() + { + if (\defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM does not handle the file:// scheme correctly'); + } + + $scheme = 'file://'; + $filename = $scheme.$this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + $this->filesystem->dumpFile($filename, 'foo'); + + $this->filesystem->appendToFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'foobar'); + } + + public function testAppendToFileWithZlibScheme() + { + $scheme = 'compress.zlib://'; + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'baz.txt'; + $this->filesystem->dumpFile($filename, 'foo'); + + // Zlib stat uses file:// wrapper so remove it + $this->assertStringEqualsFile(str_replace($scheme, '', $filename), 'foo'); + + $this->filesystem->appendToFile($filename, 'bar'); + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'foobar'); + } + + public function testAppendToFileCreateTheFileIfNotExists() + { + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo'.\DIRECTORY_SEPARATOR.'bar.txt'; + + // skip mode check on Windows + if ('\\' !== \DIRECTORY_SEPARATOR) { + $oldMask = umask(0002); + } + + $this->filesystem->appendToFile($filename, 'bar'); + + // skip mode check on Windows + if ('\\' !== \DIRECTORY_SEPARATOR) { + $this->assertFilePermissions(664, $filename); + umask($oldMask); + } + + $this->assertFileExists($filename); + $this->assertStringEqualsFile($filename, 'bar'); + } + + public function testDumpKeepsExistingPermissionsWhenOverwritingAnExistingFile() + { + $this->markAsSkippedIfChmodIsMissing(); + + $filename = $this->workspace.\DIRECTORY_SEPARATOR.'foo.txt'; + file_put_contents($filename, 'FOO BAR'); + chmod($filename, 0745); + + $this->filesystem->dumpFile($filename, 'bar', null); + + $this->assertFilePermissions(745, $filename); + } + + public function testCopyShouldKeepExecutionPermission() + { + $this->markAsSkippedIfChmodIsMissing(); + + $sourceFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_source_file'; + $targetFilePath = $this->workspace.\DIRECTORY_SEPARATOR.'copy_target_file'; + + file_put_contents($sourceFilePath, 'SOURCE FILE'); + chmod($sourceFilePath, 0745); + + $this->filesystem->copy($sourceFilePath, $targetFilePath); + + $this->assertFilePermissions(767, $targetFilePath); + } + + /** + * Normalize the given path (transform each blackslash into a real directory separator). + * + * @param string $path + * + * @return string + */ + private function normalize($path) + { + return str_replace('/', \DIRECTORY_SEPARATOR, $path); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Tests/FilesystemTestCase.php b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/FilesystemTestCase.php new file mode 100644 index 00000000..b7038550 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/FilesystemTestCase.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Filesystem; + +class FilesystemTestCase extends TestCase +{ + private $umask; + + protected $longPathNamesWindows = []; + + /** + * @var Filesystem + */ + protected $filesystem = null; + + /** + * @var string + */ + protected $workspace = null; + + /** + * @var bool|null Flag for hard links on Windows + */ + private static $linkOnWindows = null; + + /** + * @var bool|null Flag for symbolic links on Windows + */ + private static $symlinkOnWindows = null; + + public static function setUpBeforeClass() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + self::$linkOnWindows = true; + $originFile = tempnam(sys_get_temp_dir(), 'li'); + $targetFile = tempnam(sys_get_temp_dir(), 'li'); + if (true !== @link($originFile, $targetFile)) { + $report = error_get_last(); + if (\is_array($report) && false !== strpos($report['message'], 'error code(1314)')) { + self::$linkOnWindows = false; + } + } else { + @unlink($targetFile); + } + + self::$symlinkOnWindows = true; + $originDir = tempnam(sys_get_temp_dir(), 'sl'); + $targetDir = tempnam(sys_get_temp_dir(), 'sl'); + if (true !== @symlink($originDir, $targetDir)) { + $report = error_get_last(); + if (\is_array($report) && false !== strpos($report['message'], 'error code(1314)')) { + self::$symlinkOnWindows = false; + } + } else { + @unlink($targetDir); + } + } + } + + protected function setUp() + { + $this->umask = umask(0); + $this->filesystem = new Filesystem(); + $this->workspace = sys_get_temp_dir().'/'.microtime(true).'.'.mt_rand(); + mkdir($this->workspace, 0777, true); + $this->workspace = realpath($this->workspace); + } + + protected function tearDown() + { + if (!empty($this->longPathNamesWindows)) { + foreach ($this->longPathNamesWindows as $path) { + exec('DEL '.$path); + } + $this->longPathNamesWindows = []; + } + + $this->filesystem->remove($this->workspace); + umask($this->umask); + } + + /** + * @param int $expectedFilePerms Expected file permissions as three digits (i.e. 755) + * @param string $filePath + */ + protected function assertFilePermissions($expectedFilePerms, $filePath) + { + $actualFilePerms = (int) substr(sprintf('%o', fileperms($filePath)), -3); + $this->assertEquals( + $expectedFilePerms, + $actualFilePerms, + sprintf('File permissions for %s must be %s. Actual %s', $filePath, $expectedFilePerms, $actualFilePerms) + ); + } + + protected function getFileOwner($filepath) + { + $this->markAsSkippedIfPosixIsMissing(); + + $infos = stat($filepath); + + return ($datas = posix_getpwuid($infos['uid'])) ? $datas['name'] : null; + } + + protected function getFileGroup($filepath) + { + $this->markAsSkippedIfPosixIsMissing(); + + $infos = stat($filepath); + if ($datas = posix_getgrgid($infos['gid'])) { + return $datas['name']; + } + + $this->markTestSkipped('Unable to retrieve file group name'); + } + + protected function markAsSkippedIfLinkIsMissing() + { + if (!\function_exists('link')) { + $this->markTestSkipped('link is not supported'); + } + + if ('\\' === \DIRECTORY_SEPARATOR && false === self::$linkOnWindows) { + $this->markTestSkipped('link requires "Create hard links" privilege on windows'); + } + } + + protected function markAsSkippedIfSymlinkIsMissing($relative = false) + { + if ('\\' === \DIRECTORY_SEPARATOR && false === self::$symlinkOnWindows) { + $this->markTestSkipped('symlink requires "Create symbolic links" privilege on Windows'); + } + + // https://bugs.php.net/69473 + if ($relative && '\\' === \DIRECTORY_SEPARATOR && 1 === \PHP_ZTS) { + $this->markTestSkipped('symlink does not support relative paths on thread safe Windows PHP versions'); + } + } + + protected function markAsSkippedIfChmodIsMissing() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + } + + protected function markAsSkippedIfPosixIsMissing() + { + if (!\function_exists('posix_isatty')) { + $this->markTestSkipped('Function posix_isatty is required.'); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php new file mode 100644 index 00000000..3d80a905 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/Fixtures/MockStream/MockStream.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests\Fixtures\MockStream; + +/** + * Mock stream class to be used with stream_wrapper_register. + * stream_wrapper_register('mock', 'Symfony\Component\Filesystem\Tests\Fixtures\MockStream\MockStream'). + */ +class MockStream +{ + /** + * Opens file or URL. + * + * @param string $path Specifies the URL that was passed to the original function + * @param string $mode The mode used to open the file, as detailed for fopen() + * @param int $options Holds additional flags set by the streams API + * @param string $opened_path If the path is opened successfully, and STREAM_USE_PATH is set in options, + * opened_path should be set to the full path of the file/resource that was actually opened + * + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path) + { + return true; + } + + /** + * @param string $path The file path or URL to stat + * @param array $flags Holds additional flags set by the streams API + * + * @return array File stats + */ + public function url_stat($path, $flags) + { + return []; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/Tests/LockHandlerTest.php b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/LockHandlerTest.php new file mode 100644 index 00000000..b63e0c22 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/Tests/LockHandlerTest.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Filesystem\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Filesystem\LockHandler; + +/** + * @group legacy + */ +class LockHandlerTest extends TestCase +{ + public function testConstructWhenRepositoryDoesNotExist() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->expectExceptionMessage('Failed to create "/a/b/c/d/e": mkdir(): Permission denied'); + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + new LockHandler('lock', '/a/b/c/d/e'); + } + + public function testConstructWhenRepositoryIsNotWriteable() + { + $this->expectException('Symfony\Component\Filesystem\Exception\IOException'); + $this->expectExceptionMessage('The directory "/" is not writable.'); + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + new LockHandler('lock', '/'); + } + + public function testErrorHandlingInLockIfLockPathBecomesUnwritable() + { + // skip test on Windows; PHP can't easily set file as unreadable on Windows + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('This test cannot run on Windows.'); + } + + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + + $lockPath = sys_get_temp_dir().'/'.uniqid('', true); + $e = null; + $wrongMessage = null; + + try { + mkdir($lockPath); + + $lockHandler = new LockHandler('lock', $lockPath); + + chmod($lockPath, 0444); + + $lockHandler->lock(); + } catch (IOException $e) { + if (false === strpos($e->getMessage(), 'Permission denied')) { + $wrongMessage = $e->getMessage(); + } else { + $this->addToAssertionCount(1); + } + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if (is_dir($lockPath)) { + $fs = new Filesystem(); + $fs->remove($lockPath); + } + + $this->assertInstanceOf('Symfony\Component\Filesystem\Exception\IOException', $e, sprintf('Expected IOException to be thrown, got %s instead.', \get_class($e))); + $this->assertNull($wrongMessage, sprintf('Expected exception message to contain "Permission denied", got "%s" instead.', $wrongMessage)); + } + + public function testConstructSanitizeName() + { + $lock = new LockHandler(''); + + $file = sprintf('%s/sf.-php-echo-hello-word-.4b3d9d0d27ddef3a78a64685dda3a963e478659a9e5240feaf7b4173a8f28d5f.lock', sys_get_temp_dir()); + // ensure the file does not exist before the lock + @unlink($file); + + $lock->lock(); + + $this->assertFileExists($file); + + $lock->release(); + } + + public function testLockRelease() + { + $name = 'symfony-test-filesystem.lock'; + + $l1 = new LockHandler($name); + $l2 = new LockHandler($name); + + $this->assertTrue($l1->lock()); + $this->assertFalse($l2->lock()); + + $l1->release(); + + $this->assertTrue($l2->lock()); + $l2->release(); + } + + public function testLockTwice() + { + $name = 'symfony-test-filesystem.lock'; + + $lockHandler = new LockHandler($name); + + $this->assertTrue($lockHandler->lock()); + $this->assertTrue($lockHandler->lock()); + + $lockHandler->release(); + } + + public function testLockIsReleased() + { + $name = 'symfony-test-filesystem.lock'; + + $l1 = new LockHandler($name); + $l2 = new LockHandler($name); + + $this->assertTrue($l1->lock()); + $this->assertFalse($l2->lock()); + + $l1 = null; + + $this->assertTrue($l2->lock()); + $l2->release(); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/composer.json b/modules/empikmarketplace/vendor/symfony/filesystem/composer.json new file mode 100644 index 00000000..ee48b0b2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/composer.json @@ -0,0 +1,29 @@ +{ + "name": "symfony/filesystem", + "type": "library", + "description": "Symfony Filesystem Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/modules/empikmarketplace/vendor/symfony/filesystem/phpunit.xml.dist b/modules/empikmarketplace/vendor/symfony/filesystem/phpunit.xml.dist new file mode 100644 index 00000000..5515fff1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/filesystem/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-apcu/Apcu.php b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/Apcu.php new file mode 100644 index 00000000..95a65459 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/Apcu.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Apcu; + +/** + * Apcu for Zend Server Data Cache. + * + * @author Kate Gray + * @author Nicolas Grekas + * + * @internal + */ +final class Apcu +{ + public static function apcu_add($key, $var = null, $ttl = 0) + { + if (!\is_array($key)) { + return apc_add($key, $var, $ttl); + } + + $errors = array(); + foreach ($key as $k => $v) { + if (!apc_add($k, $v, $ttl)) { + $errors[$k] = -1; + } + } + + return $errors; + } + + public static function apcu_store($key, $var = null, $ttl = 0) + { + if (!\is_array($key)) { + return apc_store($key, $var, $ttl); + } + + $errors = array(); + foreach ($key as $k => $v) { + if (!apc_store($k, $v, $ttl)) { + $errors[$k] = -1; + } + } + + return $errors; + } + + public static function apcu_exists($keys) + { + if (!\is_array($keys)) { + return apc_exists($keys); + } + + $existing = array(); + foreach ($keys as $k) { + if (apc_exists($k)) { + $existing[$k] = true; + } + } + + return $existing; + } + + public static function apcu_fetch($key, &$success = null) + { + if (!\is_array($key)) { + return apc_fetch($key, $success); + } + + $succeeded = true; + $values = array(); + foreach ($key as $k) { + $v = apc_fetch($k, $success); + if ($success) { + $values[$k] = $v; + } else { + $succeeded = false; + } + } + $success = $succeeded; + + return $values; + } + + public static function apcu_delete($key) + { + if (!\is_array($key)) { + return apc_delete($key); + } + + $success = true; + foreach ($key as $k) { + $success = apc_delete($k) && $success; + } + + return $success; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-apcu/LICENSE b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/LICENSE new file mode 100644 index 00000000..4cd8bdd3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-apcu/README.md b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/README.md new file mode 100644 index 00000000..b8a89975 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / APCu +======================== + +This component provides `apcu_*` functions and the `APCuIterator` class to users of the legacy APC extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-apcu/bootstrap.php b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/bootstrap.php new file mode 100644 index 00000000..90141a64 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/bootstrap.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Apcu as p; + +if (!extension_loaded('apc') && !extension_loaded('apcu')) { + return; +} + +if (extension_loaded('Zend Data Cache')) { + if (!function_exists('apcu_add')) { + function apcu_add($key, $var = null, $ttl = 0) { return p\Apcu::apcu_add($key, $var, $ttl); } + } + if (!function_exists('apcu_delete')) { + function apcu_delete($key) { return p\Apcu::apcu_delete($key); } + } + if (!function_exists('apcu_exists')) { + function apcu_exists($keys) { return p\Apcu::apcu_exists($keys); } + } + if (!function_exists('apcu_fetch')) { + function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); } + } + if (!function_exists('apcu_store')) { + function apcu_store($key, $var = null, $ttl = 0) { return p\Apcu::apcu_store($key, $var, $ttl); } + } +} else { + if (!function_exists('apcu_add')) { + function apcu_add($key, $var = null, $ttl = 0) { return apc_add($key, $var, $ttl); } + } + if (!function_exists('apcu_delete')) { + function apcu_delete($key) { return apc_delete($key); } + } + if (!function_exists('apcu_exists')) { + function apcu_exists($keys) { return apc_exists($keys); } + } + if (!function_exists('apcu_fetch')) { + function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } + } + if (!function_exists('apcu_store')) { + function apcu_store($key, $var = null, $ttl = 0) { return apc_store($key, $var, $ttl); } + } +} + +if (!function_exists('apcu_cache_info')) { + function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } +} +if (!function_exists('apcu_cas')) { + function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } +} +if (!function_exists('apcu_clear_cache')) { + function apcu_clear_cache() { return apc_clear_cache('user'); } +} +if (!function_exists('apcu_dec')) { + function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } +} +if (!function_exists('apcu_inc')) { + function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } +} +if (!function_exists('apcu_sma_info')) { + function apcu_sma_info($limited = false) { return apc_sma_info($limited); } +} + +if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { + class APCuIterator extends APCIterator + { + public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) + { + parent::__construct('user', $search, $format, $chunk_size, $list); + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-apcu/composer.json b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/composer.json new file mode 100644 index 00000000..816b438d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-apcu/composer.json @@ -0,0 +1,35 @@ +{ + "name": "symfony/polyfill-apcu", + "type": "library", + "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable", "apcu"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Apcu\\": "" }, + "files": [ "bootstrap.php" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-ctype/Ctype.php b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/Ctype.php new file mode 100644 index 00000000..58414dc7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/Ctype.php @@ -0,0 +1,227 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Ctype; + +/** + * Ctype implementation through regex. + * + * @internal + * + * @author Gert de Pagter + */ +final class Ctype +{ + /** + * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. + * + * @see https://php.net/ctype-alnum + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_alnum($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is a letter, FALSE otherwise. + * + * @see https://php.net/ctype-alpha + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_alpha($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); + } + + /** + * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. + * + * @see https://php.net/ctype-cntrl + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_cntrl($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); + } + + /** + * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. + * + * @see https://php.net/ctype-digit + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_digit($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. + * + * @see https://php.net/ctype-graph + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_graph($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); + } + + /** + * Returns TRUE if every character in text is a lowercase letter. + * + * @see https://php.net/ctype-lower + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_lower($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); + } + + /** + * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. + * + * @see https://php.net/ctype-print + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_print($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); + } + + /** + * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. + * + * @see https://php.net/ctype-punct + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_punct($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); + } + + /** + * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. + * + * @see https://php.net/ctype-space + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_space($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); + } + + /** + * Returns TRUE if every character in text is an uppercase letter. + * + * @see https://php.net/ctype-upper + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_upper($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); + } + + /** + * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. + * + * @see https://php.net/ctype-xdigit + * + * @param string|int $text + * + * @return bool + */ + public static function ctype_xdigit($text) + { + $text = self::convert_int_to_char_for_ctype($text); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); + } + + /** + * Converts integers to their char versions according to normal ctype behaviour, if needed. + * + * If an integer between -128 and 255 inclusive is provided, + * it is interpreted as the ASCII value of a single character + * (negative values have 256 added in order to allow characters in the Extended ASCII range). + * Any other integer is interpreted as a string containing the decimal digits of the integer. + * + * @param string|int $int + * + * @return mixed + */ + private static function convert_int_to_char_for_ctype($int) + { + if (!\is_int($int)) { + return $int; + } + + if ($int < -128 || $int > 255) { + return (string) $int; + } + + if ($int < 0) { + $int += 256; + } + + return \chr($int); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-ctype/LICENSE b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/LICENSE new file mode 100644 index 00000000..3f853aaf --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-ctype/README.md b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/README.md new file mode 100644 index 00000000..8add1ab0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / Ctype +======================== + +This component provides `ctype_*` functions to users who run php versions without the ctype extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-ctype/bootstrap.php b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/bootstrap.php new file mode 100644 index 00000000..0bc45cfd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/bootstrap.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($input) { return p\Ctype::ctype_alnum($input); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha($input) { return p\Ctype::ctype_alpha($input); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl($input) { return p\Ctype::ctype_cntrl($input); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit($input) { return p\Ctype::ctype_digit($input); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph($input) { return p\Ctype::ctype_graph($input); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower($input) { return p\Ctype::ctype_lower($input); } +} +if (!function_exists('ctype_print')) { + function ctype_print($input) { return p\Ctype::ctype_print($input); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct($input) { return p\Ctype::ctype_punct($input); } +} +if (!function_exists('ctype_space')) { + function ctype_space($input) { return p\Ctype::ctype_space($input); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper($input) { return p\Ctype::ctype_upper($input); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit($input) { return p\Ctype::ctype_xdigit($input); } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-ctype/composer.json b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/composer.json new file mode 100644 index 00000000..d7c9abb6 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-ctype/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/polyfill-ctype", + "type": "library", + "description": "Symfony polyfill for ctype functions", + "keywords": ["polyfill", "compatibility", "portable", "ctype"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-php70/LICENSE b/modules/empikmarketplace/vendor/symfony/polyfill-php70/LICENSE new file mode 100644 index 00000000..4cd8bdd3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-php70/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-php70/Php70.php b/modules/empikmarketplace/vendor/symfony/polyfill-php70/Php70.php new file mode 100644 index 00000000..7f1ad08a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-php70/Php70.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php70; + +/** + * @author Nicolas Grekas + * + * @internal + */ +final class Php70 +{ + public static function intdiv($dividend, $divisor) + { + $dividend = self::intArg($dividend, __FUNCTION__, 1); + $divisor = self::intArg($divisor, __FUNCTION__, 2); + + if (0 === $divisor) { + throw new \DivisionByZeroError('Division by zero'); + } + if (-1 === $divisor && ~PHP_INT_MAX === $dividend) { + throw new \ArithmeticError('Division of PHP_INT_MIN by -1 is not an integer'); + } + + return ($dividend - ($dividend % $divisor)) / $divisor; + } + + public static function preg_replace_callback_array(array $patterns, $subject, $limit = -1, &$count = 0) + { + $count = 0; + $result = (string) $subject; + if (0 === $limit = self::intArg($limit, __FUNCTION__, 3)) { + return $result; + } + + foreach ($patterns as $pattern => $callback) { + $result = preg_replace_callback($pattern, $callback, $result, $limit, $c); + $count += $c; + } + + return $result; + } + + public static function error_clear_last() + { + static $handler; + if (!$handler) { + $handler = function () { return false; }; + } + set_error_handler($handler); + @trigger_error(''); + restore_error_handler(); + } + + private static function intArg($value, $caller, $pos) + { + if (\is_int($value)) { + return $value; + } + if (!\is_numeric($value) || PHP_INT_MAX <= ($value += 0) || ~PHP_INT_MAX >= $value) { + throw new \TypeError(sprintf('%s() expects parameter %d to be integer, %s given', $caller, $pos, \gettype($value))); + } + + return (int) $value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-php70/README.md b/modules/empikmarketplace/vendor/symfony/polyfill-php70/README.md new file mode 100644 index 00000000..abd54882 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-php70/README.md @@ -0,0 +1,28 @@ +Symfony Polyfill / Php70 +======================== + +This component provides features unavailable in releases prior to PHP 7.0: + +- [`intdiv`](https://php.net/intdiv) +- [`preg_replace_callback_array`](https://php.net/preg_replace_callback_array) +- [`error_clear_last`](https://php.net/error_clear_last) +- `random_bytes` and `random_int` (from [paragonie/random_compat](https://github.com/paragonie/random_compat)) +- [`*Error` throwable classes](https://php.net/Error) +- [`PHP_INT_MIN`](https://php.net/reserved.constants#constant.php-int-min) +- `SessionUpdateTimestampHandlerInterface` + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). + +Compatibility notes +=================== + +To write portable code between PHP5 and PHP7, some care must be taken: +- `\*Error` exceptions must be caught before `\Exception`; +- after calling `error_clear_last()`, the result of `$e = error_get_last()` must be + verified using `isset($e['message'][0])` instead of `null !== $e`. + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php b/modules/empikmarketplace/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php new file mode 100644 index 00000000..68191244 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php @@ -0,0 +1,5 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php70 as p; + +if (PHP_VERSION_ID >= 70000) { + return; +} + +if (!defined('PHP_INT_MIN')) { + define('PHP_INT_MIN', ~PHP_INT_MAX); +} + +if (!function_exists('intdiv')) { + function intdiv($num1, $num2) { return p\Php70::intdiv($num1, $num2); } +} +if (!function_exists('preg_replace_callback_array')) { + function preg_replace_callback_array(array $pattern, $subject, $limit = -1, &$count = 0, $flags = null) { return p\Php70::preg_replace_callback_array($pattern, $subject, $limit, $count); } +} +if (!function_exists('error_clear_last')) { + function error_clear_last() { return p\Php70::error_clear_last(); } +} diff --git a/modules/empikmarketplace/vendor/symfony/polyfill-php70/composer.json b/modules/empikmarketplace/vendor/symfony/polyfill-php70/composer.json new file mode 100644 index 00000000..a2b30c07 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/polyfill-php70/composer.json @@ -0,0 +1,37 @@ +{ + "name": "symfony/polyfill-php70", + "type": "library", + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=5.3.3", + "paragonie/random_compat": "~1.0|~2.0|~9.99" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php70\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/.gitignore b/modules/empikmarketplace/vendor/symfony/yaml/.gitignore new file mode 100644 index 00000000..c49a5d8d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/modules/empikmarketplace/vendor/symfony/yaml/CHANGELOG.md b/modules/empikmarketplace/vendor/symfony/yaml/CHANGELOG.md new file mode 100644 index 00000000..fd41c9dd --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/CHANGELOG.md @@ -0,0 +1,149 @@ +CHANGELOG +========= + +3.4.0 +----- + + * added support for parsing YAML files using the `Yaml::parseFile()` or `Parser::parseFile()` method + + * the `Dumper`, `Parser`, and `Yaml` classes are marked as final + + * Deprecated the `!php/object:` tag which will be replaced by the + `!php/object` tag (without the colon) in 4.0. + + * Deprecated the `!php/const:` tag which will be replaced by the + `!php/const` tag (without the colon) in 4.0. + + * Support for the `!str` tag is deprecated, use the `!!str` tag instead. + + * Deprecated using the non-specific tag `!` as its behavior will change in 4.0. + It will force non-evaluating your values in 4.0. Use plain integers or `!!float` instead. + +3.3.0 +----- + + * Starting an unquoted string with a question mark followed by a space is + deprecated and will throw a `ParseException` in Symfony 4.0. + + * Deprecated support for implicitly parsing non-string mapping keys as strings. + Mapping keys that are no strings will lead to a `ParseException` in Symfony + 4.0. Use quotes to opt-in for keys to be parsed as strings. + + Before: + + ```php + $yaml = << new A(), 'bar' => 1], 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE | Yaml::DUMP_OBJECT); + ``` + +3.0.0 +----- + + * Yaml::parse() now throws an exception when a blackslash is not escaped + in double-quoted strings + +2.8.0 +----- + + * Deprecated usage of a colon in an unquoted mapping value + * Deprecated usage of @, \`, | and > at the beginning of an unquoted string + * When surrounding strings with double-quotes, you must now escape `\` characters. Not + escaping those characters (when surrounded by double-quotes) is deprecated. + + Before: + + ```yml + class: "Foo\Var" + ``` + + After: + + ```yml + class: "Foo\\Var" + ``` + +2.1.0 +----- + + * Yaml::parse() does not evaluate loaded files as PHP files by default + anymore (call Yaml::enablePhpParsing() to get back the old behavior) diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Command/LintCommand.php b/modules/empikmarketplace/vendor/symfony/yaml/Command/LintCommand.php new file mode 100644 index 00000000..fb8e3e65 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Command/LintCommand.php @@ -0,0 +1,253 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Yaml; + +/** + * Validates YAML files syntax and outputs encountered errors. + * + * @author Grégoire Pineau + * @author Robin Chalas + */ +class LintCommand extends Command +{ + protected static $defaultName = 'lint:yaml'; + + private $parser; + private $format; + private $displayCorrectFiles; + private $directoryIteratorProvider; + private $isReadableProvider; + + public function __construct($name = null, $directoryIteratorProvider = null, $isReadableProvider = null) + { + parent::__construct($name); + + $this->directoryIteratorProvider = $directoryIteratorProvider; + $this->isReadableProvider = $isReadableProvider; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setDescription('Lints a file and outputs encountered errors') + ->addArgument('filename', null, 'A file or a directory or STDIN') + ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') + ->addOption('parse-tags', null, InputOption::VALUE_NONE, 'Parse custom tags') + ->setHelp(<<%command.name% command lints a YAML file and outputs to STDOUT +the first encountered syntax error. + +You can validates YAML contents passed from STDIN: + + cat filename | php %command.full_name% + +You can also validate the syntax of a file: + + php %command.full_name% filename + +Or of a whole directory: + + php %command.full_name% dirname + php %command.full_name% dirname --format=json + +EOF + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $io = new SymfonyStyle($input, $output); + $filename = $input->getArgument('filename'); + $this->format = $input->getOption('format'); + $this->displayCorrectFiles = $output->isVerbose(); + $flags = $input->getOption('parse-tags') ? Yaml::PARSE_CUSTOM_TAGS : 0; + + if (!$filename) { + if (!$stdin = $this->getStdin()) { + throw new RuntimeException('Please provide a filename or pipe file content to STDIN.'); + } + + return $this->display($io, [$this->validate($stdin, $flags)]); + } + + if (!$this->isReadable($filename)) { + throw new RuntimeException(sprintf('File or directory "%s" is not readable.', $filename)); + } + + $filesInfo = []; + foreach ($this->getFiles($filename) as $file) { + $filesInfo[] = $this->validate(file_get_contents($file), $flags, $file); + } + + return $this->display($io, $filesInfo); + } + + private function validate($content, $flags, $file = null) + { + $prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) { + if (\E_USER_DEPRECATED === $level) { + throw new ParseException($message, $this->getParser()->getRealCurrentLineNb() + 1); + } + + return $prevErrorHandler ? $prevErrorHandler($level, $message, $file, $line) : false; + }); + + try { + $this->getParser()->parse($content, Yaml::PARSE_CONSTANT | $flags); + } catch (ParseException $e) { + return ['file' => $file, 'line' => $e->getParsedLine(), 'valid' => false, 'message' => $e->getMessage()]; + } finally { + restore_error_handler(); + } + + return ['file' => $file, 'valid' => true]; + } + + private function display(SymfonyStyle $io, array $files) + { + switch ($this->format) { + case 'txt': + return $this->displayTxt($io, $files); + case 'json': + return $this->displayJson($io, $files); + default: + throw new InvalidArgumentException(sprintf('The format "%s" is not supported.', $this->format)); + } + } + + private function displayTxt(SymfonyStyle $io, array $filesInfo) + { + $countFiles = \count($filesInfo); + $erroredFiles = 0; + + foreach ($filesInfo as $info) { + if ($info['valid'] && $this->displayCorrectFiles) { + $io->comment('OK'.($info['file'] ? sprintf(' in %s', $info['file']) : '')); + } elseif (!$info['valid']) { + ++$erroredFiles; + $io->text(' ERROR '.($info['file'] ? sprintf(' in %s', $info['file']) : '')); + $io->text(sprintf(' >> %s', $info['message'])); + } + } + + if (0 === $erroredFiles) { + $io->success(sprintf('All %d YAML files contain valid syntax.', $countFiles)); + } else { + $io->warning(sprintf('%d YAML files have valid syntax and %d contain errors.', $countFiles - $erroredFiles, $erroredFiles)); + } + + return min($erroredFiles, 1); + } + + private function displayJson(SymfonyStyle $io, array $filesInfo) + { + $errors = 0; + + array_walk($filesInfo, function (&$v) use (&$errors) { + $v['file'] = (string) $v['file']; + if (!$v['valid']) { + ++$errors; + } + }); + + $io->writeln(json_encode($filesInfo, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES)); + + return min($errors, 1); + } + + private function getFiles($fileOrDirectory) + { + if (is_file($fileOrDirectory)) { + yield new \SplFileInfo($fileOrDirectory); + + return; + } + + foreach ($this->getDirectoryIterator($fileOrDirectory) as $file) { + if (!\in_array($file->getExtension(), ['yml', 'yaml'])) { + continue; + } + + yield $file; + } + } + + /** + * @return string|null + */ + private function getStdin() + { + if (0 !== ftell(\STDIN)) { + return null; + } + + $inputs = ''; + while (!feof(\STDIN)) { + $inputs .= fread(\STDIN, 1024); + } + + return $inputs; + } + + private function getParser() + { + if (!$this->parser) { + $this->parser = new Parser(); + } + + return $this->parser; + } + + private function getDirectoryIterator($directory) + { + $default = function ($directory) { + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($directory, \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + }; + + if (null !== $this->directoryIteratorProvider) { + return \call_user_func($this->directoryIteratorProvider, $directory, $default); + } + + return $default($directory); + } + + private function isReadable($fileOrDirectory) + { + $default = function ($fileOrDirectory) { + return is_readable($fileOrDirectory); + }; + + if (null !== $this->isReadableProvider) { + return \call_user_func($this->isReadableProvider, $fileOrDirectory, $default); + } + + return $default($fileOrDirectory); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Dumper.php b/modules/empikmarketplace/vendor/symfony/yaml/Dumper.php new file mode 100644 index 00000000..336e39c9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Dumper.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Tag\TaggedValue; + +/** + * Dumper dumps PHP variables to YAML strings. + * + * @author Fabien Potencier + * + * @final since version 3.4 + */ +class Dumper +{ + /** + * The amount of spaces to use for indentation of nested nodes. + * + * @var int + */ + protected $indentation; + + /** + * @param int $indentation + */ + public function __construct($indentation = 4) + { + if ($indentation < 1) { + throw new \InvalidArgumentException('The indentation must be greater than zero.'); + } + + $this->indentation = $indentation; + } + + /** + * Sets the indentation. + * + * @param int $num The amount of spaces to use for indentation of nested nodes + * + * @deprecated since version 3.1, to be removed in 4.0. Pass the indentation to the constructor instead. + */ + public function setIndentation($num) + { + @trigger_error('The '.__METHOD__.' method is deprecated since Symfony 3.1 and will be removed in 4.0. Pass the indentation to the constructor instead.', \E_USER_DEPRECATED); + + $this->indentation = (int) $num; + } + + /** + * Dumps a PHP value to YAML. + * + * @param mixed $input The PHP value + * @param int $inline The level where you switch to inline YAML + * @param int $indent The level of indentation (used internally) + * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string + * + * @return string The YAML representation of the PHP value + */ + public function dump($input, $inline = 0, $indent = 0, $flags = 0) + { + if (\is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', \E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (\func_num_args() >= 5) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(4)) { + $flags |= Yaml::DUMP_OBJECT; + } + } + + $output = ''; + $prefix = $indent ? str_repeat(' ', $indent) : ''; + $dumpObjectAsInlineMap = true; + + if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($input instanceof \ArrayObject || $input instanceof \stdClass)) { + $dumpObjectAsInlineMap = empty((array) $input); + } + + if ($inline <= 0 || (!\is_array($input) && !$input instanceof TaggedValue && $dumpObjectAsInlineMap) || empty($input)) { + $output .= $prefix.Inline::dump($input, $flags); + } else { + $dumpAsMap = Inline::isHash($input); + + foreach ($input as $key => $value) { + if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value) && false !== strpos($value, "\n") && false === strpos($value, "\r")) { + // If the first line starts with a space character, the spec requires a blockIndicationIndicator + // http://www.yaml.org/spec/1.2/spec.html#id2793979 + $blockIndentationIndicator = (' ' === substr($value, 0, 1)) ? (string) $this->indentation : ''; + $output .= sprintf("%s%s%s |%s\n", $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', '', $blockIndentationIndicator); + + foreach (explode("\n", $value) as $row) { + $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row); + } + + continue; + } + + if ($value instanceof TaggedValue) { + $output .= sprintf('%s%s !%s', $prefix, $dumpAsMap ? Inline::dump($key, $flags).':' : '-', $value->getTag()); + + if ($inline >= 1 && Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK & $flags && \is_string($value->getValue()) && false !== strpos($value->getValue(), "\n") && false === strpos($value->getValue(), "\r\n")) { + // If the first line starts with a space character, the spec requires a blockIndicationIndicator + // http://www.yaml.org/spec/1.2/spec.html#id2793979 + $blockIndentationIndicator = (' ' === substr($value->getValue(), 0, 1)) ? (string) $this->indentation : ''; + $output .= sprintf(" |%s\n", $blockIndentationIndicator); + + foreach (explode("\n", $value->getValue()) as $row) { + $output .= sprintf("%s%s%s\n", $prefix, str_repeat(' ', $this->indentation), $row); + } + + continue; + } + + if ($inline - 1 <= 0 || null === $value->getValue() || is_scalar($value->getValue())) { + $output .= ' '.$this->dump($value->getValue(), $inline - 1, 0, $flags)."\n"; + } else { + $output .= "\n"; + $output .= $this->dump($value->getValue(), $inline - 1, $dumpAsMap ? $indent + $this->indentation : $indent + 2, $flags); + } + + continue; + } + + $dumpObjectAsInlineMap = true; + + if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \ArrayObject || $value instanceof \stdClass)) { + $dumpObjectAsInlineMap = empty((array) $value); + } + + $willBeInlined = $inline - 1 <= 0 || !\is_array($value) && $dumpObjectAsInlineMap || empty($value); + + $output .= sprintf('%s%s%s%s', + $prefix, + $dumpAsMap ? Inline::dump($key, $flags).':' : '-', + $willBeInlined ? ' ' : "\n", + $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + $this->indentation, $flags) + ).($willBeInlined ? "\n" : ''); + } + } + + return $output; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Escaper.php b/modules/empikmarketplace/vendor/symfony/yaml/Escaper.php new file mode 100644 index 00000000..9413d7a2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Escaper.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +/** + * Escaper encapsulates escaping rules for single and double-quoted + * YAML strings. + * + * @author Matthew Lewinski + * + * @internal + */ +class Escaper +{ + // Characters that would cause a dumped string to require double quoting. + const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\x7f|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9"; + + // Mapping arrays for escaping a double quoted string. The backslash is + // first to ensure proper escaping because str_replace operates iteratively + // on the input arrays. This ordering of the characters avoids the use of strtr, + // which performs more slowly. + private static $escapees = ['\\', '\\\\', '\\"', '"', + "\x00", "\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", + "\x08", "\x09", "\x0a", "\x0b", "\x0c", "\x0d", "\x0e", "\x0f", + "\x10", "\x11", "\x12", "\x13", "\x14", "\x15", "\x16", "\x17", + "\x18", "\x19", "\x1a", "\x1b", "\x1c", "\x1d", "\x1e", "\x1f", + "\x7f", + "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9", + ]; + private static $escaped = ['\\\\', '\\"', '\\\\', '\\"', + '\\0', '\\x01', '\\x02', '\\x03', '\\x04', '\\x05', '\\x06', '\\a', + '\\b', '\\t', '\\n', '\\v', '\\f', '\\r', '\\x0e', '\\x0f', + '\\x10', '\\x11', '\\x12', '\\x13', '\\x14', '\\x15', '\\x16', '\\x17', + '\\x18', '\\x19', '\\x1a', '\\e', '\\x1c', '\\x1d', '\\x1e', '\\x1f', + '\\x7f', + '\\N', '\\_', '\\L', '\\P', + ]; + + /** + * Determines if a PHP value would require double quoting in YAML. + * + * @param string $value A PHP value + * + * @return bool True if the value would require double quotes + */ + public static function requiresDoubleQuoting($value) + { + return 0 < preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value); + } + + /** + * Escapes and surrounds a PHP value with double quotes. + * + * @param string $value A PHP value + * + * @return string The quoted, escaped string + */ + public static function escapeWithDoubleQuotes($value) + { + return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value)); + } + + /** + * Determines if a PHP value would require single quoting in YAML. + * + * @param string $value A PHP value + * + * @return bool True if the value would require single quotes + */ + public static function requiresSingleQuoting($value) + { + // Determines if a PHP value is entirely composed of a value that would + // require single quoting in YAML. + if (\in_array(strtolower($value), ['null', '~', 'true', 'false', 'y', 'n', 'yes', 'no', 'on', 'off'])) { + return true; + } + + // Determines if the PHP value contains any single characters that would + // cause it to require single quoting in YAML. + return 0 < preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ \- ? | < > = ! % @ ` ]/x', $value); + } + + /** + * Escapes and surrounds a PHP value with single quotes. + * + * @param string $value A PHP value + * + * @return string The quoted, escaped string + */ + public static function escapeWithSingleQuotes($value) + { + return sprintf("'%s'", str_replace('\'', '\'\'', $value)); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Exception/DumpException.php b/modules/empikmarketplace/vendor/symfony/yaml/Exception/DumpException.php new file mode 100644 index 00000000..cce972f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Exception/DumpException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during dumping. + * + * @author Fabien Potencier + */ +class DumpException extends RuntimeException +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Exception/ExceptionInterface.php b/modules/empikmarketplace/vendor/symfony/yaml/Exception/ExceptionInterface.php new file mode 100644 index 00000000..ad850eea --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception interface for all exceptions thrown by the component. + * + * @author Fabien Potencier + */ +interface ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Exception/ParseException.php b/modules/empikmarketplace/vendor/symfony/yaml/Exception/ParseException.php new file mode 100644 index 00000000..4207d9ab --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Exception/ParseException.php @@ -0,0 +1,139 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during parsing. + * + * @author Fabien Potencier + */ +class ParseException extends RuntimeException +{ + private $parsedFile; + private $parsedLine; + private $snippet; + private $rawMessage; + + /** + * @param string $message The error message + * @param int $parsedLine The line where the error occurred + * @param string|null $snippet The snippet of code near the problem + * @param string|null $parsedFile The file name where the error occurred + * @param \Exception|null $previous The previous exception + */ + public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, \Exception $previous = null) + { + $this->parsedFile = $parsedFile; + $this->parsedLine = $parsedLine; + $this->snippet = $snippet; + $this->rawMessage = $message; + + $this->updateRepr(); + + parent::__construct($this->message, 0, $previous); + } + + /** + * Gets the snippet of code near the error. + * + * @return string The snippet of code + */ + public function getSnippet() + { + return $this->snippet; + } + + /** + * Sets the snippet of code near the error. + * + * @param string $snippet The code snippet + */ + public function setSnippet($snippet) + { + $this->snippet = $snippet; + + $this->updateRepr(); + } + + /** + * Gets the filename where the error occurred. + * + * This method returns null if a string is parsed. + * + * @return string The filename + */ + public function getParsedFile() + { + return $this->parsedFile; + } + + /** + * Sets the filename where the error occurred. + * + * @param string $parsedFile The filename + */ + public function setParsedFile($parsedFile) + { + $this->parsedFile = $parsedFile; + + $this->updateRepr(); + } + + /** + * Gets the line where the error occurred. + * + * @return int The file line + */ + public function getParsedLine() + { + return $this->parsedLine; + } + + /** + * Sets the line where the error occurred. + * + * @param int $parsedLine The file line + */ + public function setParsedLine($parsedLine) + { + $this->parsedLine = $parsedLine; + + $this->updateRepr(); + } + + private function updateRepr() + { + $this->message = $this->rawMessage; + + $dot = false; + if ('.' === substr($this->message, -1)) { + $this->message = substr($this->message, 0, -1); + $dot = true; + } + + if (null !== $this->parsedFile) { + $this->message .= sprintf(' in %s', json_encode($this->parsedFile, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE)); + } + + if ($this->parsedLine >= 0) { + $this->message .= sprintf(' at line %d', $this->parsedLine); + } + + if ($this->snippet) { + $this->message .= sprintf(' (near "%s")', $this->snippet); + } + + if ($dot) { + $this->message .= '.'; + } + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Exception/RuntimeException.php b/modules/empikmarketplace/vendor/symfony/yaml/Exception/RuntimeException.php new file mode 100644 index 00000000..3f36b73b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Exception/RuntimeException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Exception; + +/** + * Exception class thrown when an error occurs during parsing. + * + * @author Romain Neutron + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Inline.php b/modules/empikmarketplace/vendor/symfony/yaml/Inline.php new file mode 100644 index 00000000..64ac48a9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Inline.php @@ -0,0 +1,927 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\DumpException; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Tag\TaggedValue; + +/** + * Inline implements a YAML parser/dumper for the YAML inline syntax. + * + * @author Fabien Potencier + * + * @internal + */ +class Inline +{ + const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*+(?:\\\\.[^"\\\\]*+)*+)"|\'([^\']*+(?:\'\'[^\']*+)*+)\')'; + + public static $parsedLineNumber = -1; + public static $parsedFilename; + + private static $exceptionOnInvalidType = false; + private static $objectSupport = false; + private static $objectForMap = false; + private static $constantSupport = false; + + /** + * @param int $flags + * @param int|null $parsedLineNumber + * @param string|null $parsedFilename + */ + public static function initialize($flags, $parsedLineNumber = null, $parsedFilename = null) + { + self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags); + self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags); + self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags); + self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags); + self::$parsedFilename = $parsedFilename; + + if (null !== $parsedLineNumber) { + self::$parsedLineNumber = $parsedLineNumber; + } + } + + /** + * Converts a YAML string to a PHP value. + * + * @param string $value A YAML string + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param array $references Mapping of variable names to values + * + * @return mixed A PHP value + * + * @throws ParseException + */ + public static function parse($value, $flags = 0, $references = []) + { + if (\is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', \E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (\func_num_args() >= 3 && !\is_array($references)) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', \E_USER_DEPRECATED); + + if ($references) { + $flags |= Yaml::PARSE_OBJECT; + } + + if (\func_num_args() >= 4) { + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(3)) { + $flags |= Yaml::PARSE_OBJECT_FOR_MAP; + } + } + + if (\func_num_args() >= 5) { + $references = func_get_arg(4); + } else { + $references = []; + } + } + + self::initialize($flags); + + $value = trim($value); + + if ('' === $value) { + return ''; + } + + if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('ASCII'); + } + + try { + $i = 0; + $tag = self::parseTag($value, $i, $flags); + switch ($value[$i]) { + case '[': + $result = self::parseSequence($value, $flags, $i, $references); + ++$i; + break; + case '{': + $result = self::parseMapping($value, $flags, $i, $references); + ++$i; + break; + default: + $result = self::parseScalar($value, $flags, null, $i, null === $tag, $references); + } + + // some comments are allowed at the end + if (preg_replace('/\s*#.*$/A', '', substr($value, $i))) { + throw new ParseException(sprintf('Unexpected characters near "%s".', substr($value, $i)), self::$parsedLineNumber + 1, $value, self::$parsedFilename); + } + + if (null !== $tag) { + return new TaggedValue($tag, $result); + } + + return $result; + } finally { + if (isset($mbEncoding)) { + mb_internal_encoding($mbEncoding); + } + } + } + + /** + * Dumps a given PHP variable to a YAML string. + * + * @param mixed $value The PHP variable to convert + * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string + * + * @return string The YAML string representing the PHP value + * + * @throws DumpException When trying to dump PHP resource + */ + public static function dump($value, $flags = 0) + { + if (\is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', \E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (\func_num_args() >= 3) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::DUMP_OBJECT flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(2)) { + $flags |= Yaml::DUMP_OBJECT; + } + } + + switch (true) { + case \is_resource($value): + if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { + throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value))); + } + + return 'null'; + case $value instanceof \DateTimeInterface: + return $value->format('c'); + case \is_object($value): + if ($value instanceof TaggedValue) { + return '!'.$value->getTag().' '.self::dump($value->getValue(), $flags); + } + + if (Yaml::DUMP_OBJECT & $flags) { + return '!php/object '.self::dump(serialize($value)); + } + + if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { + return self::dumpArray($value, $flags & ~Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE); + } + + if (Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE & $flags) { + throw new DumpException('Object support when dumping a YAML file has been disabled.'); + } + + return 'null'; + case \is_array($value): + return self::dumpArray($value, $flags); + case null === $value: + return 'null'; + case true === $value: + return 'true'; + case false === $value: + return 'false'; + case ctype_digit($value): + return \is_string($value) ? "'$value'" : (int) $value; + case is_numeric($value) && false === strpos($value, "\f") && false === strpos($value, "\n") && false === strpos($value, "\r") && false === strpos($value, "\t") && false === strpos($value, "\v"): + $locale = setlocale(\LC_NUMERIC, 0); + if (false !== $locale) { + setlocale(\LC_NUMERIC, 'C'); + } + if (\is_float($value)) { + $repr = (string) $value; + if (is_infinite($value)) { + $repr = str_ireplace('INF', '.Inf', $repr); + } elseif (floor($value) == $value && $repr == $value) { + // Preserve float data type since storing a whole number will result in integer value. + $repr = '!!float '.$repr; + } + } else { + $repr = \is_string($value) ? "'$value'" : (string) $value; + } + if (false !== $locale) { + setlocale(\LC_NUMERIC, $locale); + } + + return $repr; + case '' == $value: + return "''"; + case self::isBinaryString($value): + return '!!binary '.base64_encode($value); + case Escaper::requiresDoubleQuoting($value): + return Escaper::escapeWithDoubleQuotes($value); + case Escaper::requiresSingleQuoting($value): + case Parser::preg_match('{^[0-9]+[_0-9]*$}', $value): + case Parser::preg_match(self::getHexRegex(), $value): + case Parser::preg_match(self::getTimestampRegex(), $value): + return Escaper::escapeWithSingleQuotes($value); + default: + return $value; + } + } + + /** + * Check if given array is hash or just normal indexed array. + * + * @internal + * + * @param array|\ArrayObject|\stdClass $value The PHP array or array-like object to check + * + * @return bool true if value is hash array, false otherwise + */ + public static function isHash($value) + { + if ($value instanceof \stdClass || $value instanceof \ArrayObject) { + return true; + } + + $expectedKey = 0; + + foreach ($value as $key => $val) { + if ($key !== $expectedKey++) { + return true; + } + } + + return false; + } + + /** + * Dumps a PHP array to a YAML string. + * + * @param array $value The PHP array to dump + * @param int $flags A bit field of Yaml::DUMP_* constants to customize the dumped YAML string + * + * @return string The YAML string representing the PHP array + */ + private static function dumpArray($value, $flags) + { + // array + if (($value || Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE & $flags) && !self::isHash($value)) { + $output = []; + foreach ($value as $val) { + $output[] = self::dump($val, $flags); + } + + return sprintf('[%s]', implode(', ', $output)); + } + + // hash + $output = []; + foreach ($value as $key => $val) { + $output[] = sprintf('%s: %s', self::dump($key, $flags), self::dump($val, $flags)); + } + + return sprintf('{ %s }', implode(', ', $output)); + } + + /** + * Parses a YAML scalar. + * + * @param string $scalar + * @param int $flags + * @param string[] $delimiters + * @param int &$i + * @param bool $evaluate + * @param array $references + * + * @return string + * + * @throws ParseException When malformed inline YAML string is parsed + * + * @internal + */ + public static function parseScalar($scalar, $flags = 0, $delimiters = null, &$i = 0, $evaluate = true, $references = [], $legacyOmittedKeySupport = false) + { + if (\in_array($scalar[$i], ['"', "'"])) { + // quoted scalar + $output = self::parseQuotedScalar($scalar, $i); + + if (null !== $delimiters) { + $tmp = ltrim(substr($scalar, $i), ' '); + if ('' === $tmp) { + throw new ParseException(sprintf('Unexpected end of line, expected one of "%s".', implode('', $delimiters)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + if (!\in_array($tmp[0], $delimiters)) { + throw new ParseException(sprintf('Unexpected characters (%s).', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + } + } else { + // "normal" string + if (!$delimiters) { + $output = substr($scalar, $i); + $i += \strlen($output); + + // remove comments + if (Parser::preg_match('/[ \t]+#/', $output, $match, \PREG_OFFSET_CAPTURE)) { + $output = substr($output, 0, $match[0][1]); + } + } elseif (Parser::preg_match('/^(.'.($legacyOmittedKeySupport ? '+' : '*').'?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) { + $output = $match[1]; + $i += \strlen($output); + } else { + throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $scalar), self::$parsedLineNumber + 1, null, self::$parsedFilename); + } + + // a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >) + if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) { + throw new ParseException(sprintf('The reserved indicator "%s" cannot start a plain scalar; you need to quote the scalar.', $output[0]), self::$parsedLineNumber + 1, $output, self::$parsedFilename); + } + + if ($output && '%' === $output[0]) { + @trigger_error(self::getDeprecationMessage(sprintf('Not quoting the scalar "%s" starting with the "%%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0.', $output)), \E_USER_DEPRECATED); + } + + if ($evaluate) { + $output = self::evaluateScalar($output, $flags, $references); + } + } + + return $output; + } + + /** + * Parses a YAML quoted scalar. + * + * @param string $scalar + * @param int &$i + * + * @return string + * + * @throws ParseException When malformed inline YAML string is parsed + */ + private static function parseQuotedScalar($scalar, &$i) + { + if (!Parser::preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) { + throw new ParseException(sprintf('Malformed inline YAML string: "%s".', substr($scalar, $i)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + $output = substr($match[0], 1, \strlen($match[0]) - 2); + + $unescaper = new Unescaper(); + if ('"' == $scalar[$i]) { + $output = $unescaper->unescapeDoubleQuotedString($output); + } else { + $output = $unescaper->unescapeSingleQuotedString($output); + } + + $i += \strlen($match[0]); + + return $output; + } + + /** + * Parses a YAML sequence. + * + * @param string $sequence + * @param int $flags + * @param int &$i + * @param array $references + * + * @return array + * + * @throws ParseException When malformed inline YAML string is parsed + */ + private static function parseSequence($sequence, $flags, &$i = 0, $references = []) + { + $output = []; + $len = \strlen($sequence); + ++$i; + + // [foo, bar, ...] + while ($i < $len) { + if (']' === $sequence[$i]) { + return $output; + } + if (',' === $sequence[$i] || ' ' === $sequence[$i]) { + ++$i; + + continue; + } + + $tag = self::parseTag($sequence, $i, $flags); + switch ($sequence[$i]) { + case '[': + // nested sequence + $value = self::parseSequence($sequence, $flags, $i, $references); + break; + case '{': + // nested mapping + $value = self::parseMapping($sequence, $flags, $i, $references); + break; + default: + $isQuoted = \in_array($sequence[$i], ['"', "'"]); + $value = self::parseScalar($sequence, $flags, [',', ']'], $i, null === $tag, $references); + + // the value can be an array if a reference has been resolved to an array var + if (\is_string($value) && !$isQuoted && false !== strpos($value, ': ')) { + // embedded mapping? + try { + $pos = 0; + $value = self::parseMapping('{'.$value.'}', $flags, $pos, $references); + } catch (\InvalidArgumentException $e) { + // no, it's not + } + } + + --$i; + } + + if (null !== $tag) { + $value = new TaggedValue($tag, $value); + } + + $output[] = $value; + + ++$i; + } + + throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $sequence), self::$parsedLineNumber + 1, null, self::$parsedFilename); + } + + /** + * Parses a YAML mapping. + * + * @param string $mapping + * @param int $flags + * @param int &$i + * @param array $references + * + * @return array|\stdClass + * + * @throws ParseException When malformed inline YAML string is parsed + */ + private static function parseMapping($mapping, $flags, &$i = 0, $references = []) + { + $output = []; + $len = \strlen($mapping); + ++$i; + $allowOverwrite = false; + + // {foo: bar, bar:foo, ...} + while ($i < $len) { + switch ($mapping[$i]) { + case ' ': + case ',': + ++$i; + continue 2; + case '}': + if (self::$objectForMap) { + return (object) $output; + } + + return $output; + } + + // key + $isKeyQuoted = \in_array($mapping[$i], ['"', "'"], true); + $key = self::parseScalar($mapping, $flags, [':', ' '], $i, false, [], true); + + if ('!php/const' === $key) { + $key .= self::parseScalar($mapping, $flags, [':', ' '], $i, false, [], true); + if ('!php/const:' === $key && ':' !== $mapping[$i]) { + $key = ''; + --$i; + } else { + $key = self::evaluateScalar($key, $flags); + } + } + + if (':' !== $key && false === $i = strpos($mapping, ':', $i)) { + break; + } + + if (':' === $key) { + @trigger_error(self::getDeprecationMessage('Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0.'), \E_USER_DEPRECATED); + } + + if (!$isKeyQuoted) { + $evaluatedKey = self::evaluateScalar($key, $flags, $references); + + if ('' !== $key && $evaluatedKey !== $key && !\is_string($evaluatedKey) && !\is_int($evaluatedKey)) { + @trigger_error(self::getDeprecationMessage('Implicit casting of incompatible mapping keys to strings is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead.'), \E_USER_DEPRECATED); + } + } + + if (':' !== $key && !$isKeyQuoted && (!isset($mapping[$i + 1]) || !\in_array($mapping[$i + 1], [' ', ',', '[', ']', '{', '}'], true))) { + @trigger_error(self::getDeprecationMessage('Using a colon after an unquoted mapping key that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}") is deprecated since Symfony 3.2 and will throw a ParseException in 4.0.'), \E_USER_DEPRECATED); + } + + if ('<<' === $key) { + $allowOverwrite = true; + } + + while ($i < $len) { + if (':' === $mapping[$i] || ' ' === $mapping[$i]) { + ++$i; + + continue; + } + + $tag = self::parseTag($mapping, $i, $flags); + switch ($mapping[$i]) { + case '[': + // nested sequence + $value = self::parseSequence($mapping, $flags, $i, $references); + // Spec: Keys MUST be unique; first one wins. + // Parser cannot abort this mapping earlier, since lines + // are processed sequentially. + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + foreach ($value as $parsedValue) { + $output += $parsedValue; + } + } elseif ($allowOverwrite || !isset($output[$key])) { + if (null !== $tag) { + $output[$key] = new TaggedValue($tag, $value); + } else { + $output[$key] = $value; + } + } elseif (isset($output[$key])) { + @trigger_error(self::getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), \E_USER_DEPRECATED); + } + break; + case '{': + // nested mapping + $value = self::parseMapping($mapping, $flags, $i, $references); + // Spec: Keys MUST be unique; first one wins. + // Parser cannot abort this mapping earlier, since lines + // are processed sequentially. + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + $output += $value; + } elseif ($allowOverwrite || !isset($output[$key])) { + if (null !== $tag) { + $output[$key] = new TaggedValue($tag, $value); + } else { + $output[$key] = $value; + } + } elseif (isset($output[$key])) { + @trigger_error(self::getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), \E_USER_DEPRECATED); + } + break; + default: + $value = self::parseScalar($mapping, $flags, [',', '}'], $i, null === $tag, $references); + // Spec: Keys MUST be unique; first one wins. + // Parser cannot abort this mapping earlier, since lines + // are processed sequentially. + // But overwriting is allowed when a merge node is used in current block. + if ('<<' === $key) { + $output += $value; + } elseif ($allowOverwrite || !isset($output[$key])) { + if (null !== $tag) { + $output[$key] = new TaggedValue($tag, $value); + } else { + $output[$key] = $value; + } + } elseif (isset($output[$key])) { + @trigger_error(self::getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), \E_USER_DEPRECATED); + } + --$i; + } + ++$i; + + continue 2; + } + } + + throw new ParseException(sprintf('Malformed inline YAML string: "%s".', $mapping), self::$parsedLineNumber + 1, null, self::$parsedFilename); + } + + /** + * Evaluates scalars and replaces magic values. + * + * @param string $scalar + * @param int $flags + * @param array $references + * + * @return mixed The evaluated YAML string + * + * @throws ParseException when object parsing support was disabled and the parser detected a PHP object or when a reference could not be resolved + */ + private static function evaluateScalar($scalar, $flags, $references = []) + { + $scalar = trim($scalar); + $scalarLower = strtolower($scalar); + + if (0 === strpos($scalar, '*')) { + if (false !== $pos = strpos($scalar, '#')) { + $value = substr($scalar, 1, $pos - 2); + } else { + $value = substr($scalar, 1); + } + + // an unquoted * + if (false === $value || '' === $value) { + throw new ParseException('A reference must contain at least one character.', self::$parsedLineNumber + 1, $value, self::$parsedFilename); + } + + if (!\array_key_exists($value, $references)) { + throw new ParseException(sprintf('Reference "%s" does not exist.', $value), self::$parsedLineNumber + 1, $value, self::$parsedFilename); + } + + return $references[$value]; + } + + switch (true) { + case 'null' === $scalarLower: + case '' === $scalar: + case '~' === $scalar: + return null; + case 'true' === $scalarLower: + return true; + case 'false' === $scalarLower: + return false; + case '!' === $scalar[0]: + switch (true) { + case 0 === strpos($scalar, '!str'): + @trigger_error(self::getDeprecationMessage('Support for the !str tag is deprecated since Symfony 3.4. Use the !!str tag instead.'), \E_USER_DEPRECATED); + + return (string) substr($scalar, 5); + case 0 === strpos($scalar, '!!str '): + return (string) substr($scalar, 6); + case 0 === strpos($scalar, '! '): + @trigger_error(self::getDeprecationMessage('Using the non-specific tag "!" is deprecated since Symfony 3.4 as its behavior will change in 4.0. It will force non-evaluating your values in 4.0. Use plain integers or !!float instead.'), \E_USER_DEPRECATED); + + return (int) self::parseScalar(substr($scalar, 2), $flags); + case 0 === strpos($scalar, '!php/object:'): + if (self::$objectSupport) { + @trigger_error(self::getDeprecationMessage('The !php/object: tag to indicate dumped PHP objects is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/object (without the colon) tag instead.'), \E_USER_DEPRECATED); + + return unserialize(substr($scalar, 12)); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return null; + case 0 === strpos($scalar, '!!php/object:'): + if (self::$objectSupport) { + @trigger_error(self::getDeprecationMessage('The !!php/object: tag to indicate dumped PHP objects is deprecated since Symfony 3.1 and will be removed in 4.0. Use the !php/object (without the colon) tag instead.'), \E_USER_DEPRECATED); + + return unserialize(substr($scalar, 13)); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return null; + case 0 === strpos($scalar, '!php/object'): + if (self::$objectSupport) { + if (!isset($scalar[12])) { + return false; + } + + return unserialize(self::parseScalar(substr($scalar, 12))); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.', self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return null; + case 0 === strpos($scalar, '!php/const:'): + if (self::$constantSupport) { + @trigger_error(self::getDeprecationMessage('The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead.'), \E_USER_DEPRECATED); + + if (\defined($const = substr($scalar, 11))) { + return \constant($const); + } + + throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + if (self::$exceptionOnInvalidType) { + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return null; + case 0 === strpos($scalar, '!php/const'): + if (self::$constantSupport) { + if (!isset($scalar[11])) { + return ''; + } + + $i = 0; + if (\defined($const = self::parseScalar(substr($scalar, 11), 0, null, $i, false))) { + return \constant($const); + } + + throw new ParseException(sprintf('The constant "%s" is not defined.', $const), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + if (self::$exceptionOnInvalidType) { + throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Did you forget to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return null; + case 0 === strpos($scalar, '!!float '): + return (float) substr($scalar, 8); + case 0 === strpos($scalar, '!!binary '): + return self::evaluateBinaryScalar(substr($scalar, 9)); + default: + @trigger_error(self::getDeprecationMessage(sprintf('Using the unquoted scalar value "%s" is deprecated since Symfony 3.3 and will be considered as a tagged value in 4.0. You must quote it.', $scalar)), \E_USER_DEPRECATED); + } + + // Optimize for returning strings. + // no break + case '+' === $scalar[0] || '-' === $scalar[0] || '.' === $scalar[0] || is_numeric($scalar[0]): + if (Parser::preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar)) { + $scalar = str_replace('_', '', (string) $scalar); + } + + switch (true) { + case ctype_digit($scalar): + if (preg_match('/^0[0-7]+$/', $scalar)) { + return octdec($scalar); + } + + $cast = (int) $scalar; + + return ($scalar === (string) $cast) ? $cast : $scalar; + case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)): + if (preg_match('/^-0[0-7]+$/', $scalar)) { + return -octdec(substr($scalar, 1)); + } + + $cast = (int) $scalar; + + return ($scalar === (string) $cast) ? $cast : $scalar; + case is_numeric($scalar): + case Parser::preg_match(self::getHexRegex(), $scalar): + $scalar = str_replace('_', '', $scalar); + + return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar; + case '.inf' === $scalarLower: + case '.nan' === $scalarLower: + return -log(0); + case '-.inf' === $scalarLower: + return log(0); + case Parser::preg_match('/^(-|\+)?[0-9][0-9,]*(\.[0-9_]+)?$/', $scalar): + case Parser::preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar): + if (false !== strpos($scalar, ',')) { + @trigger_error(self::getDeprecationMessage('Using the comma as a group separator for floats is deprecated since Symfony 3.2 and will be removed in 4.0.'), \E_USER_DEPRECATED); + } + + return (float) str_replace([',', '_'], '', $scalar); + case Parser::preg_match(self::getTimestampRegex(), $scalar): + if (Yaml::PARSE_DATETIME & $flags) { + // When no timezone is provided in the parsed date, YAML spec says we must assume UTC. + return new \DateTime($scalar, new \DateTimeZone('UTC')); + } + + $timeZone = date_default_timezone_get(); + date_default_timezone_set('UTC'); + $time = strtotime($scalar); + date_default_timezone_set($timeZone); + + return $time; + } + } + + return (string) $scalar; + } + + /** + * @param string $value + * @param int &$i + * @param int $flags + * + * @return string|null + */ + private static function parseTag($value, &$i, $flags) + { + if ('!' !== $value[$i]) { + return null; + } + + $tagLength = strcspn($value, " \t\n", $i + 1); + $tag = substr($value, $i + 1, $tagLength); + + $nextOffset = $i + $tagLength + 1; + $nextOffset += strspn($value, ' ', $nextOffset); + + // Is followed by a scalar + if ((!isset($value[$nextOffset]) || !\in_array($value[$nextOffset], ['[', '{'], true)) && 'tagged' !== $tag) { + // Manage non-whitelisted scalars in {@link self::evaluateScalar()} + return null; + } + + // Built-in tags + if ($tag && '!' === $tag[0]) { + throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); + } + + if (Yaml::PARSE_CUSTOM_TAGS & $flags) { + $i = $nextOffset; + + return $tag; + } + + throw new ParseException(sprintf('Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!%s".', $tag), self::$parsedLineNumber + 1, $value, self::$parsedFilename); + } + + /** + * @param string $scalar + * + * @return string + * + * @internal + */ + public static function evaluateBinaryScalar($scalar) + { + $parsedBinaryData = self::parseScalar(preg_replace('/\s/', '', $scalar)); + + if (0 !== (\strlen($parsedBinaryData) % 4)) { + throw new ParseException(sprintf('The normalized base64 encoded data (data without whitespace characters) length must be a multiple of four (%d bytes given).', \strlen($parsedBinaryData)), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + if (!Parser::preg_match('#^[A-Z0-9+/]+={0,2}$#i', $parsedBinaryData)) { + throw new ParseException(sprintf('The base64 encoded data (%s) contains invalid characters.', $parsedBinaryData), self::$parsedLineNumber + 1, $scalar, self::$parsedFilename); + } + + return base64_decode($parsedBinaryData, true); + } + + private static function isBinaryString($value) + { + return !preg_match('//u', $value) || preg_match('/[^\x00\x07-\x0d\x1B\x20-\xff]/', $value); + } + + /** + * Gets a regex that matches a YAML date. + * + * @return string The regular expression + * + * @see http://www.yaml.org/spec/1.2/spec.html#id2761573 + */ + private static function getTimestampRegex() + { + return <<[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[0-9][0-9]))?))?)? + $~x +EOF; + } + + /** + * Gets a regex that matches a YAML number in hexadecimal notation. + * + * @return string + */ + private static function getHexRegex() + { + return '~^0x[0-9a-f_]++$~i'; + } + + private static function getDeprecationMessage($message) + { + $message = rtrim($message, '.'); + + if (null !== self::$parsedFilename) { + $message .= ' in '.self::$parsedFilename; + } + + if (-1 !== self::$parsedLineNumber) { + $message .= ' on line '.(self::$parsedLineNumber + 1); + } + + return $message.'.'; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/LICENSE b/modules/empikmarketplace/vendor/symfony/yaml/LICENSE new file mode 100644 index 00000000..9e936ec0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2020 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Parser.php b/modules/empikmarketplace/vendor/symfony/yaml/Parser.php new file mode 100644 index 00000000..ddd85676 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Parser.php @@ -0,0 +1,1156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Tag\TaggedValue; + +/** + * Parser parses YAML strings to convert them to PHP arrays. + * + * @author Fabien Potencier + * + * @final since version 3.4 + */ +class Parser +{ + const TAG_PATTERN = '(?P![\w!.\/:-]+)'; + const BLOCK_SCALAR_HEADER_PATTERN = '(?P\||>)(?P\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P +#.*)?'; + + private $filename; + private $offset = 0; + private $totalNumberOfLines; + private $lines = []; + private $currentLineNb = -1; + private $currentLine = ''; + private $refs = []; + private $skippedLineNumbers = []; + private $locallySkippedLineNumbers = []; + private $refsBeingParsed = []; + + public function __construct() + { + if (\func_num_args() > 0) { + @trigger_error(sprintf('The constructor arguments $offset, $totalNumberOfLines, $skippedLineNumbers of %s are deprecated and will be removed in 4.0', self::class), \E_USER_DEPRECATED); + + $this->offset = func_get_arg(0); + if (\func_num_args() > 1) { + $this->totalNumberOfLines = func_get_arg(1); + } + if (\func_num_args() > 2) { + $this->skippedLineNumbers = func_get_arg(2); + } + } + } + + /** + * Parses a YAML file into a PHP value. + * + * @param string $filename The path to the YAML file to be parsed + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * + * @return mixed The YAML converted to a PHP value + * + * @throws ParseException If the file could not be read or the YAML is not valid + */ + public function parseFile($filename, $flags = 0) + { + if (!is_file($filename)) { + throw new ParseException(sprintf('File "%s" does not exist.', $filename)); + } + + if (!is_readable($filename)) { + throw new ParseException(sprintf('File "%s" cannot be read.', $filename)); + } + + $this->filename = $filename; + + try { + return $this->parse(file_get_contents($filename), $flags); + } finally { + $this->filename = null; + } + } + + /** + * Parses a YAML string to a PHP value. + * + * @param string $value A YAML string + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * + * @return mixed A PHP value + * + * @throws ParseException If the YAML is not valid + */ + public function parse($value, $flags = 0) + { + if (\is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', \E_USER_DEPRECATED); + + if ($flags) { + $flags = Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (\func_num_args() >= 3) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(2)) { + $flags |= Yaml::PARSE_OBJECT; + } + } + + if (\func_num_args() >= 4) { + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(3)) { + $flags |= Yaml::PARSE_OBJECT_FOR_MAP; + } + } + + if (Yaml::PARSE_KEYS_AS_STRINGS & $flags) { + @trigger_error('Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since Symfony 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead.', \E_USER_DEPRECATED); + } + + if (false === preg_match('//u', $value)) { + throw new ParseException('The YAML value does not appear to be valid UTF-8.', -1, null, $this->filename); + } + + $this->refs = []; + + $mbEncoding = null; + $e = null; + $data = null; + + if (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) { + $mbEncoding = mb_internal_encoding(); + mb_internal_encoding('UTF-8'); + } + + try { + $data = $this->doParse($value, $flags); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + + if (null !== $mbEncoding) { + mb_internal_encoding($mbEncoding); + } + + $this->lines = []; + $this->currentLine = ''; + $this->refs = []; + $this->skippedLineNumbers = []; + $this->locallySkippedLineNumbers = []; + $this->totalNumberOfLines = null; + + if (null !== $e) { + throw $e; + } + + return $data; + } + + private function doParse($value, $flags) + { + $this->currentLineNb = -1; + $this->currentLine = ''; + $value = $this->cleanup($value); + $this->lines = explode("\n", $value); + $this->locallySkippedLineNumbers = []; + + if (null === $this->totalNumberOfLines) { + $this->totalNumberOfLines = \count($this->lines); + } + + if (!$this->moveToNextLine()) { + return null; + } + + $data = []; + $context = null; + $allowOverwrite = false; + + while ($this->isCurrentLineEmpty()) { + if (!$this->moveToNextLine()) { + return null; + } + } + + // Resolves the tag and returns if end of the document + if (null !== ($tag = $this->getLineTag($this->currentLine, $flags, false)) && !$this->moveToNextLine()) { + return new TaggedValue($tag, ''); + } + + do { + if ($this->isCurrentLineEmpty()) { + continue; + } + + // tab? + if ("\t" === $this->currentLine[0]) { + throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + + Inline::initialize($flags, $this->getRealCurrentLineNb(), $this->filename); + + $isRef = $mergeNode = false; + if (self::preg_match('#^\-((?P\s+)(?P.+))?$#u', rtrim($this->currentLine), $values)) { + if ($context && 'mapping' == $context) { + throw new ParseException('You cannot define a sequence item when in a mapping.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + $context = 'sequence'; + + if (isset($values['value']) && self::preg_match('#^&(?P[^ ]+) *(?P.*)#u', $values['value'], $matches)) { + $isRef = $matches['ref']; + $this->refsBeingParsed[] = $isRef; + $values['value'] = $matches['value']; + } + + if (isset($values['value'][1]) && '?' === $values['value'][0] && ' ' === $values['value'][1]) { + @trigger_error($this->getDeprecationMessage('Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.'), \E_USER_DEPRECATED); + } + + // array + if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) { + $data[] = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags); + } elseif (null !== $subTag = $this->getLineTag(ltrim($values['value'], ' '), $flags)) { + $data[] = new TaggedValue( + $subTag, + $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(null, true), $flags) + ); + } else { + if ( + isset($values['leadspaces']) + && ( + '!' === $values['value'][0] + || self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P.+?))?\s*$#u', $this->trimTag($values['value']), $matches) + ) + ) { + // this is a compact notation element, add to next block and parse + $block = $values['value']; + if ($this->isNextLineIndented()) { + $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + \strlen($values['leadspaces']) + 1); + } + + $data[] = $this->parseBlock($this->getRealCurrentLineNb(), $block, $flags); + } else { + $data[] = $this->parseValue($values['value'], $flags, $context); + } + } + if ($isRef) { + $this->refs[$isRef] = end($data); + array_pop($this->refsBeingParsed); + } + } elseif ( + self::preg_match('#^(?P(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P.+))?$#u', rtrim($this->currentLine), $values) + && (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"])) + ) { + if ($context && 'sequence' == $context) { + throw new ParseException('You cannot define a mapping item when in a sequence.', $this->currentLineNb + 1, $this->currentLine, $this->filename); + } + $context = 'mapping'; + + try { + $i = 0; + $evaluateKey = !(Yaml::PARSE_KEYS_AS_STRINGS & $flags); + + // constants in key will be evaluated anyway + if (isset($values['key'][0]) && '!' === $values['key'][0] && Yaml::PARSE_CONSTANT & $flags) { + $evaluateKey = true; + } + + $key = Inline::parseScalar($values['key'], 0, null, $i, $evaluateKey); + } catch (ParseException $e) { + $e->setParsedLine($this->getRealCurrentLineNb() + 1); + $e->setSnippet($this->currentLine); + + throw $e; + } + + if (!\is_string($key) && !\is_int($key)) { + $keyType = is_numeric($key) ? 'numeric key' : 'non-string key'; + @trigger_error($this->getDeprecationMessage(sprintf('Implicit casting of %s to string is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead.', $keyType)), \E_USER_DEPRECATED); + } + + // Convert float keys to strings, to avoid being converted to integers by PHP + if (\is_float($key)) { + $key = (string) $key; + } + + if ('<<' === $key && (!isset($values['value']) || !self::preg_match('#^&(?P[^ ]+)#u', $values['value'], $refMatches))) { + $mergeNode = true; + $allowOverwrite = true; + if (isset($values['value'][0]) && '*' === $values['value'][0]) { + $refName = substr(rtrim($values['value']), 1); + if (!\array_key_exists($refName, $this->refs)) { + if (false !== $pos = array_search($refName, $this->refsBeingParsed, true)) { + throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $refName, $refName), $this->currentLineNb + 1, $this->currentLine, $this->filename); + } + + throw new ParseException(sprintf('Reference "%s" does not exist.', $refName), $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + + $refValue = $this->refs[$refName]; + + if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $refValue instanceof \stdClass) { + $refValue = (array) $refValue; + } + + if (!\is_array($refValue)) { + throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + + $data += $refValue; // array union + } else { + if (isset($values['value']) && '' !== $values['value']) { + $value = $values['value']; + } else { + $value = $this->getNextEmbedBlock(); + } + $parsed = $this->parseBlock($this->getRealCurrentLineNb() + 1, $value, $flags); + + if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsed instanceof \stdClass) { + $parsed = (array) $parsed; + } + + if (!\is_array($parsed)) { + throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + + if (isset($parsed[0])) { + // If the value associated with the merge key is a sequence, then this sequence is expected to contain mapping nodes + // and each of these nodes is merged in turn according to its order in the sequence. Keys in mapping nodes earlier + // in the sequence override keys specified in later mapping nodes. + foreach ($parsed as $parsedItem) { + if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $parsedItem instanceof \stdClass) { + $parsedItem = (array) $parsedItem; + } + + if (!\is_array($parsedItem)) { + throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem, $this->filename); + } + + $data += $parsedItem; // array union + } + } else { + // If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the + // current mapping, unless the key already exists in it. + $data += $parsed; // array union + } + } + } elseif ('<<' !== $key && isset($values['value']) && self::preg_match('#^&(?P[^ ]++) *+(?P.*)#u', $values['value'], $matches)) { + $isRef = $matches['ref']; + $this->refsBeingParsed[] = $isRef; + $values['value'] = $matches['value']; + } + + $subTag = null; + if ($mergeNode) { + // Merge keys + } elseif (!isset($values['value']) || '' === $values['value'] || 0 === strpos($values['value'], '#') || (null !== $subTag = $this->getLineTag($values['value'], $flags)) || '<<' === $key) { + // hash + // if next line is less indented or equal, then it means that the current value is null + if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) { + // Spec: Keys MUST be unique; first one wins. + // But overwriting is allowed when a merge node is used in current block. + if ($allowOverwrite || !isset($data[$key])) { + if (null !== $subTag) { + $data[$key] = new TaggedValue($subTag, ''); + } else { + $data[$key] = null; + } + } else { + @trigger_error($this->getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), \E_USER_DEPRECATED); + } + } else { + $value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags); + if ('<<' === $key) { + $this->refs[$refMatches['ref']] = $value; + + if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && $value instanceof \stdClass) { + $value = (array) $value; + } + + $data += $value; + } elseif ($allowOverwrite || !isset($data[$key])) { + // Spec: Keys MUST be unique; first one wins. + // But overwriting is allowed when a merge node is used in current block. + if (null !== $subTag) { + $data[$key] = new TaggedValue($subTag, $value); + } else { + $data[$key] = $value; + } + } else { + @trigger_error($this->getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), \E_USER_DEPRECATED); + } + } + } else { + $value = $this->parseValue(rtrim($values['value']), $flags, $context); + // Spec: Keys MUST be unique; first one wins. + // But overwriting is allowed when a merge node is used in current block. + if ($allowOverwrite || !isset($data[$key])) { + $data[$key] = $value; + } else { + @trigger_error($this->getDeprecationMessage(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated since Symfony 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key)), \E_USER_DEPRECATED); + } + } + if ($isRef) { + $this->refs[$isRef] = $data[$key]; + array_pop($this->refsBeingParsed); + } + } else { + // multiple documents are not supported + if ('---' === $this->currentLine) { + throw new ParseException('Multiple documents are not supported.', $this->currentLineNb + 1, $this->currentLine, $this->filename); + } + + if ($deprecatedUsage = (isset($this->currentLine[1]) && '?' === $this->currentLine[0] && ' ' === $this->currentLine[1])) { + @trigger_error($this->getDeprecationMessage('Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.'), \E_USER_DEPRECATED); + } + + // 1-liner optionally followed by newline(s) + if (\is_string($value) && $this->lines[0] === trim($value)) { + try { + $value = Inline::parse($this->lines[0], $flags, $this->refs); + } catch (ParseException $e) { + $e->setParsedLine($this->getRealCurrentLineNb() + 1); + $e->setSnippet($this->currentLine); + + throw $e; + } + + return $value; + } + + // try to parse the value as a multi-line string as a last resort + if (0 === $this->currentLineNb) { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = false; + $value = ''; + + foreach ($this->lines as $line) { + if ('' !== ltrim($line) && '#' === ltrim($line)[0]) { + continue; + } + // If the indentation is not consistent at offset 0, it is to be considered as a ParseError + if (0 === $this->offset && !$deprecatedUsage && isset($line[0]) && ' ' === $line[0]) { + throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + if ('' === trim($line)) { + $value .= "\n"; + } elseif (!$previousLineWasNewline && !$previousLineWasTerminatedWithBackslash) { + $value .= ' '; + } + + if ('' !== trim($line) && '\\' === substr($line, -1)) { + $value .= ltrim(substr($line, 0, -1)); + } elseif ('' !== trim($line)) { + $value .= trim($line); + } + + if ('' === trim($line)) { + $previousLineWasNewline = true; + $previousLineWasTerminatedWithBackslash = false; + } elseif ('\\' === substr($line, -1)) { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = true; + } else { + $previousLineWasNewline = false; + $previousLineWasTerminatedWithBackslash = false; + } + } + + try { + return Inline::parse(trim($value)); + } catch (ParseException $e) { + // fall-through to the ParseException thrown below + } + } + + throw new ParseException('Unable to parse.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + } while ($this->moveToNextLine()); + + if (null !== $tag) { + $data = new TaggedValue($tag, $data); + } + + if (Yaml::PARSE_OBJECT_FOR_MAP & $flags && !\is_object($data) && 'mapping' === $context) { + $object = new \stdClass(); + + foreach ($data as $key => $value) { + $object->$key = $value; + } + + $data = $object; + } + + return empty($data) ? null : $data; + } + + private function parseBlock($offset, $yaml, $flags) + { + $skippedLineNumbers = $this->skippedLineNumbers; + + foreach ($this->locallySkippedLineNumbers as $lineNumber) { + if ($lineNumber < $offset) { + continue; + } + + $skippedLineNumbers[] = $lineNumber; + } + + $parser = new self(); + $parser->offset = $offset; + $parser->totalNumberOfLines = $this->totalNumberOfLines; + $parser->skippedLineNumbers = $skippedLineNumbers; + $parser->refs = &$this->refs; + $parser->refsBeingParsed = $this->refsBeingParsed; + + return $parser->doParse($yaml, $flags); + } + + /** + * Returns the current line number (takes the offset into account). + * + * @internal + * + * @return int The current line number + */ + public function getRealCurrentLineNb() + { + $realCurrentLineNumber = $this->currentLineNb + $this->offset; + + foreach ($this->skippedLineNumbers as $skippedLineNumber) { + if ($skippedLineNumber > $realCurrentLineNumber) { + break; + } + + ++$realCurrentLineNumber; + } + + return $realCurrentLineNumber; + } + + /** + * Returns the current line indentation. + * + * @return int The current line indentation + */ + private function getCurrentLineIndentation() + { + return \strlen($this->currentLine) - \strlen(ltrim($this->currentLine, ' ')); + } + + /** + * Returns the next embed block of YAML. + * + * @param int $indentation The indent level at which the block is to be read, or null for default + * @param bool $inSequence True if the enclosing data structure is a sequence + * + * @return string A YAML string + * + * @throws ParseException When indentation problem are detected + */ + private function getNextEmbedBlock($indentation = null, $inSequence = false) + { + $oldLineIndentation = $this->getCurrentLineIndentation(); + + if (!$this->moveToNextLine()) { + return ''; + } + + if (null === $indentation) { + $newIndent = null; + $movements = 0; + + do { + $EOF = false; + + // empty and comment-like lines do not influence the indentation depth + if ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) { + $EOF = !$this->moveToNextLine(); + + if (!$EOF) { + ++$movements; + } + } else { + $newIndent = $this->getCurrentLineIndentation(); + } + } while (!$EOF && null === $newIndent); + + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } + + $unindentedEmbedBlock = $this->isStringUnIndentedCollectionItem(); + + if (!$this->isCurrentLineEmpty() && 0 === $newIndent && !$unindentedEmbedBlock) { + throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + } else { + $newIndent = $indentation; + } + + $data = []; + if ($this->getCurrentLineIndentation() >= $newIndent) { + $data[] = substr($this->currentLine, $newIndent); + } elseif ($this->isCurrentLineEmpty() || $this->isCurrentLineComment()) { + $data[] = $this->currentLine; + } else { + $this->moveToPreviousLine(); + + return ''; + } + + if ($inSequence && $oldLineIndentation === $newIndent && isset($data[0][0]) && '-' === $data[0][0]) { + // the previous line contained a dash but no item content, this line is a sequence item with the same indentation + // and therefore no nested list or mapping + $this->moveToPreviousLine(); + + return ''; + } + + $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); + $isItComment = $this->isCurrentLineComment(); + + while ($this->moveToNextLine()) { + if ($isItComment && !$isItUnindentedCollection) { + $isItUnindentedCollection = $this->isStringUnIndentedCollectionItem(); + $isItComment = $this->isCurrentLineComment(); + } + + $indent = $this->getCurrentLineIndentation(); + + if ($isItUnindentedCollection && !$this->isCurrentLineEmpty() && !$this->isStringUnIndentedCollectionItem() && $newIndent === $indent) { + $this->moveToPreviousLine(); + break; + } + + if ($this->isCurrentLineBlank()) { + $data[] = substr($this->currentLine, $newIndent); + continue; + } + + if ($indent >= $newIndent) { + $data[] = substr($this->currentLine, $newIndent); + } elseif ($this->isCurrentLineComment()) { + $data[] = $this->currentLine; + } elseif (0 == $indent) { + $this->moveToPreviousLine(); + + break; + } else { + throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine, $this->filename); + } + } + + return implode("\n", $data); + } + + /** + * Moves the parser to the next line. + * + * @return bool + */ + private function moveToNextLine() + { + if ($this->currentLineNb >= \count($this->lines) - 1) { + return false; + } + + $this->currentLine = $this->lines[++$this->currentLineNb]; + + return true; + } + + /** + * Moves the parser to the previous line. + * + * @return bool + */ + private function moveToPreviousLine() + { + if ($this->currentLineNb < 1) { + return false; + } + + $this->currentLine = $this->lines[--$this->currentLineNb]; + + return true; + } + + /** + * Parses a YAML value. + * + * @param string $value A YAML value + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * @param string $context The parser context (either sequence or mapping) + * + * @return mixed A PHP value + * + * @throws ParseException When reference does not exist + */ + private function parseValue($value, $flags, $context) + { + if (0 === strpos($value, '*')) { + if (false !== $pos = strpos($value, '#')) { + $value = substr($value, 1, $pos - 2); + } else { + $value = substr($value, 1); + } + + if (!\array_key_exists($value, $this->refs)) { + if (false !== $pos = array_search($value, $this->refsBeingParsed, true)) { + throw new ParseException(sprintf('Circular reference [%s, %s] detected for reference "%s".', implode(', ', \array_slice($this->refsBeingParsed, $pos)), $value, $value), $this->currentLineNb + 1, $this->currentLine, $this->filename); + } + + throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLineNb + 1, $this->currentLine, $this->filename); + } + + return $this->refs[$value]; + } + + if (self::preg_match('/^(?:'.self::TAG_PATTERN.' +)?'.self::BLOCK_SCALAR_HEADER_PATTERN.'$/', $value, $matches)) { + $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : ''; + + $data = $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), abs((int) $modifiers)); + + if ('' !== $matches['tag']) { + if ('!!binary' === $matches['tag']) { + return Inline::evaluateBinaryScalar($data); + } elseif ('tagged' === $matches['tag']) { + return new TaggedValue(substr($matches['tag'], 1), $data); + } elseif ('!' !== $matches['tag']) { + @trigger_error($this->getDeprecationMessage(sprintf('Using the custom tag "%s" for the value "%s" is deprecated since Symfony 3.3. It will be replaced by an instance of %s in 4.0.', $matches['tag'], $data, TaggedValue::class)), \E_USER_DEPRECATED); + } + } + + return $data; + } + + try { + $quotation = '' !== $value && ('"' === $value[0] || "'" === $value[0]) ? $value[0] : null; + + // do not take following lines into account when the current line is a quoted single line value + if (null !== $quotation && self::preg_match('/^'.$quotation.'.*'.$quotation.'(\s*#.*)?$/', $value)) { + return Inline::parse($value, $flags, $this->refs); + } + + $lines = []; + + while ($this->moveToNextLine()) { + // unquoted strings end before the first unindented line + if (null === $quotation && 0 === $this->getCurrentLineIndentation()) { + $this->moveToPreviousLine(); + + break; + } + + $lines[] = trim($this->currentLine); + + // quoted string values end with a line that is terminated with the quotation character + $escapedLine = str_replace(['\\\\', '\\"'], '', $this->currentLine); + if ('' !== $escapedLine && substr($escapedLine, -1) === $quotation) { + break; + } + } + + for ($i = 0, $linesCount = \count($lines), $previousLineBlank = false; $i < $linesCount; ++$i) { + if ('' === $lines[$i]) { + $value .= "\n"; + $previousLineBlank = true; + } elseif ($previousLineBlank) { + $value .= $lines[$i]; + $previousLineBlank = false; + } else { + $value .= ' '.$lines[$i]; + $previousLineBlank = false; + } + } + + Inline::$parsedLineNumber = $this->getRealCurrentLineNb(); + + $parsedValue = Inline::parse($value, $flags, $this->refs); + + if ('mapping' === $context && \is_string($parsedValue) && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($parsedValue, ': ')) { + throw new ParseException('A colon cannot be used in an unquoted mapping value.', $this->getRealCurrentLineNb() + 1, $value, $this->filename); + } + + return $parsedValue; + } catch (ParseException $e) { + $e->setParsedLine($this->getRealCurrentLineNb() + 1); + $e->setSnippet($this->currentLine); + + throw $e; + } + } + + /** + * Parses a block scalar. + * + * @param string $style The style indicator that was used to begin this block scalar (| or >) + * @param string $chomping The chomping indicator that was used to begin this block scalar (+ or -) + * @param int $indentation The indentation indicator that was used to begin this block scalar + * + * @return string The text value + */ + private function parseBlockScalar($style, $chomping = '', $indentation = 0) + { + $notEOF = $this->moveToNextLine(); + if (!$notEOF) { + return ''; + } + + $isCurrentLineBlank = $this->isCurrentLineBlank(); + $blockLines = []; + + // leading blank lines are consumed before determining indentation + while ($notEOF && $isCurrentLineBlank) { + // newline only if not EOF + if ($notEOF = $this->moveToNextLine()) { + $blockLines[] = ''; + $isCurrentLineBlank = $this->isCurrentLineBlank(); + } + } + + // determine indentation if not specified + if (0 === $indentation) { + if (self::preg_match('/^ +/', $this->currentLine, $matches)) { + $indentation = \strlen($matches[0]); + } + } + + if ($indentation > 0) { + $pattern = sprintf('/^ {%d}(.*)$/', $indentation); + + while ( + $notEOF && ( + $isCurrentLineBlank || + self::preg_match($pattern, $this->currentLine, $matches) + ) + ) { + if ($isCurrentLineBlank && \strlen($this->currentLine) > $indentation) { + $blockLines[] = substr($this->currentLine, $indentation); + } elseif ($isCurrentLineBlank) { + $blockLines[] = ''; + } else { + $blockLines[] = $matches[1]; + } + + // newline only if not EOF + if ($notEOF = $this->moveToNextLine()) { + $isCurrentLineBlank = $this->isCurrentLineBlank(); + } + } + } elseif ($notEOF) { + $blockLines[] = ''; + } + + if ($notEOF) { + $blockLines[] = ''; + $this->moveToPreviousLine(); + } elseif (!$notEOF && !$this->isCurrentLineLastLineInDocument()) { + $blockLines[] = ''; + } + + // folded style + if ('>' === $style) { + $text = ''; + $previousLineIndented = false; + $previousLineBlank = false; + + for ($i = 0, $blockLinesCount = \count($blockLines); $i < $blockLinesCount; ++$i) { + if ('' === $blockLines[$i]) { + $text .= "\n"; + $previousLineIndented = false; + $previousLineBlank = true; + } elseif (' ' === $blockLines[$i][0]) { + $text .= "\n".$blockLines[$i]; + $previousLineIndented = true; + $previousLineBlank = false; + } elseif ($previousLineIndented) { + $text .= "\n".$blockLines[$i]; + $previousLineIndented = false; + $previousLineBlank = false; + } elseif ($previousLineBlank || 0 === $i) { + $text .= $blockLines[$i]; + $previousLineIndented = false; + $previousLineBlank = false; + } else { + $text .= ' '.$blockLines[$i]; + $previousLineIndented = false; + $previousLineBlank = false; + } + } + } else { + $text = implode("\n", $blockLines); + } + + // deal with trailing newlines + if ('' === $chomping) { + $text = preg_replace('/\n+$/', "\n", $text); + } elseif ('-' === $chomping) { + $text = preg_replace('/\n+$/', '', $text); + } + + return $text; + } + + /** + * Returns true if the next line is indented. + * + * @return bool Returns true if the next line is indented, false otherwise + */ + private function isNextLineIndented() + { + $currentIndentation = $this->getCurrentLineIndentation(); + $movements = 0; + + do { + $EOF = !$this->moveToNextLine(); + + if (!$EOF) { + ++$movements; + } + } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); + + if ($EOF) { + return false; + } + + $ret = $this->getCurrentLineIndentation() > $currentIndentation; + + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } + + return $ret; + } + + /** + * Returns true if the current line is blank or if it is a comment line. + * + * @return bool Returns true if the current line is empty or if it is a comment line, false otherwise + */ + private function isCurrentLineEmpty() + { + return $this->isCurrentLineBlank() || $this->isCurrentLineComment(); + } + + /** + * Returns true if the current line is blank. + * + * @return bool Returns true if the current line is blank, false otherwise + */ + private function isCurrentLineBlank() + { + return '' == trim($this->currentLine, ' '); + } + + /** + * Returns true if the current line is a comment line. + * + * @return bool Returns true if the current line is a comment line, false otherwise + */ + private function isCurrentLineComment() + { + //checking explicitly the first char of the trim is faster than loops or strpos + $ltrimmedLine = ltrim($this->currentLine, ' '); + + return '' !== $ltrimmedLine && '#' === $ltrimmedLine[0]; + } + + private function isCurrentLineLastLineInDocument() + { + return ($this->offset + $this->currentLineNb) >= ($this->totalNumberOfLines - 1); + } + + /** + * Cleanups a YAML string to be parsed. + * + * @param string $value The input YAML string + * + * @return string A cleaned up YAML string + */ + private function cleanup($value) + { + $value = str_replace(["\r\n", "\r"], "\n", $value); + + // strip YAML header + $count = 0; + $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#u', '', $value, -1, $count); + $this->offset += $count; + + // remove leading comments + $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count); + if (1 === $count) { + // items have been removed, update the offset + $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); + $value = $trimmedValue; + } + + // remove start of the document marker (---) + $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count); + if (1 === $count) { + // items have been removed, update the offset + $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n"); + $value = $trimmedValue; + + // remove end of the document marker (...) + $value = preg_replace('#\.\.\.\s*$#', '', $value); + } + + return $value; + } + + /** + * Returns true if the next line starts unindented collection. + * + * @return bool Returns true if the next line starts unindented collection, false otherwise + */ + private function isNextLineUnIndentedCollection() + { + $currentIndentation = $this->getCurrentLineIndentation(); + $movements = 0; + + do { + $EOF = !$this->moveToNextLine(); + + if (!$EOF) { + ++$movements; + } + } while (!$EOF && ($this->isCurrentLineEmpty() || $this->isCurrentLineComment())); + + if ($EOF) { + return false; + } + + $ret = $this->getCurrentLineIndentation() === $currentIndentation && $this->isStringUnIndentedCollectionItem(); + + for ($i = 0; $i < $movements; ++$i) { + $this->moveToPreviousLine(); + } + + return $ret; + } + + /** + * Returns true if the string is un-indented collection item. + * + * @return bool Returns true if the string is un-indented collection item, false otherwise + */ + private function isStringUnIndentedCollectionItem() + { + return '-' === rtrim($this->currentLine) || 0 === strpos($this->currentLine, '- '); + } + + /** + * A local wrapper for `preg_match` which will throw a ParseException if there + * is an internal error in the PCRE engine. + * + * This avoids us needing to check for "false" every time PCRE is used + * in the YAML engine + * + * @throws ParseException on a PCRE internal error + * + * @see preg_last_error() + * + * @internal + */ + public static function preg_match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0) + { + if (false === $ret = preg_match($pattern, $subject, $matches, $flags, $offset)) { + switch (preg_last_error()) { + case \PREG_INTERNAL_ERROR: + $error = 'Internal PCRE error.'; + break; + case \PREG_BACKTRACK_LIMIT_ERROR: + $error = 'pcre.backtrack_limit reached.'; + break; + case \PREG_RECURSION_LIMIT_ERROR: + $error = 'pcre.recursion_limit reached.'; + break; + case \PREG_BAD_UTF8_ERROR: + $error = 'Malformed UTF-8 data.'; + break; + case \PREG_BAD_UTF8_OFFSET_ERROR: + $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.'; + break; + default: + $error = 'Error.'; + } + + throw new ParseException($error); + } + + return $ret; + } + + /** + * Trim the tag on top of the value. + * + * Prevent values such as `!foo {quz: bar}` to be considered as + * a mapping block. + */ + private function trimTag($value) + { + if ('!' === $value[0]) { + return ltrim(substr($value, 1, strcspn($value, " \r\n", 1)), ' '); + } + + return $value; + } + + /** + * @return string|null + */ + private function getLineTag($value, $flags, $nextLineCheck = true) + { + if ('' === $value || '!' !== $value[0] || 1 !== self::preg_match('/^'.self::TAG_PATTERN.' *( +#.*)?$/', $value, $matches)) { + return null; + } + + if ($nextLineCheck && !$this->isNextLineIndented()) { + return null; + } + + $tag = substr($matches['tag'], 1); + + // Built-in tags + if ($tag && '!' === $tag[0]) { + throw new ParseException(sprintf('The built-in tag "!%s" is not implemented.', $tag), $this->getRealCurrentLineNb() + 1, $value, $this->filename); + } + + if (Yaml::PARSE_CUSTOM_TAGS & $flags) { + return $tag; + } + + throw new ParseException(sprintf('Tags support is not enabled. You must use the flag `Yaml::PARSE_CUSTOM_TAGS` to use "%s".', $matches['tag']), $this->getRealCurrentLineNb() + 1, $value, $this->filename); + } + + private function getDeprecationMessage($message) + { + $message = rtrim($message, '.'); + + if (null !== $this->filename) { + $message .= ' in '.$this->filename; + } + + $message .= ' on line '.($this->getRealCurrentLineNb() + 1); + + return $message.'.'; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/README.md b/modules/empikmarketplace/vendor/symfony/yaml/README.md new file mode 100644 index 00000000..b914e783 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/README.md @@ -0,0 +1,13 @@ +Yaml Component +============== + +The Yaml component loads and dumps YAML files. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/yaml.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tag/TaggedValue.php b/modules/empikmarketplace/vendor/symfony/yaml/Tag/TaggedValue.php new file mode 100644 index 00000000..000c1d99 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tag/TaggedValue.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tag; + +/** + * @author Nicolas Grekas + * @author Guilhem N. + */ +final class TaggedValue +{ + private $tag; + private $value; + + /** + * @param string $tag + * @param mixed $value + */ + public function __construct($tag, $value) + { + $this->tag = $tag; + $this->value = $value; + } + + /** + * @return string + */ + public function getTag() + { + return $this->tag; + } + + /** + * @return mixed + */ + public function getValue() + { + return $this->value; + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Command/LintCommandTest.php b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Command/LintCommandTest.php new file mode 100644 index 00000000..98c63b62 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Command/LintCommandTest.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Yaml\Command\LintCommand; + +/** + * Tests the YamlLintCommand. + * + * @author Robin Chalas + */ +class LintCommandTest extends TestCase +{ + private $files; + + public function testLintCorrectFile() + { + $tester = $this->createCommandTester(); + $filename = $this->createFile('foo: bar'); + + $ret = $tester->execute(['filename' => $filename], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]); + + $this->assertEquals(0, $ret, 'Returns 0 in case of success'); + $this->assertMatchesRegularExpression('/^\/\/ OK in /', trim($tester->getDisplay())); + } + + public function testLintIncorrectFile() + { + $incorrectContent = ' +foo: +bar'; + $tester = $this->createCommandTester(); + $filename = $this->createFile($incorrectContent); + + $ret = $tester->execute(['filename' => $filename], ['decorated' => false]); + + $this->assertEquals(1, $ret, 'Returns 1 in case of error'); + $this->assertStringContainsString('Unable to parse at line 3 (near "bar").', trim($tester->getDisplay())); + } + + public function testConstantAsKey() + { + $yaml = <<createCommandTester()->execute(['filename' => $this->createFile($yaml)], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]); + $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success'); + } + + public function testCustomTags() + { + $yaml = <<createCommandTester()->execute(['filename' => $this->createFile($yaml), '--parse-tags' => true], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]); + $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success'); + } + + public function testCustomTagsError() + { + $yaml = <<createCommandTester()->execute(['filename' => $this->createFile($yaml)], ['verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false]); + $this->assertSame(1, $ret, 'lint:yaml exits with code 1 in case of error'); + } + + public function testLintFileNotReadable() + { + $this->expectException('RuntimeException'); + $tester = $this->createCommandTester(); + $filename = $this->createFile(''); + unlink($filename); + + $tester->execute(['filename' => $filename], ['decorated' => false]); + } + + /** + * @return string Path to the new file + */ + private function createFile($content) + { + $filename = tempnam(sys_get_temp_dir().'/framework-yml-lint-test', 'sf-'); + file_put_contents($filename, $content); + + $this->files[] = $filename; + + return $filename; + } + + /** + * @return CommandTester + */ + protected function createCommandTester() + { + $application = new Application(); + $application->add(new LintCommand()); + $command = $application->find('lint:yaml'); + + return new CommandTester($command); + } + + protected function setUp() + { + $this->files = []; + @mkdir(sys_get_temp_dir().'/framework-yml-lint-test'); + } + + protected function tearDown() + { + foreach ($this->files as $file) { + if (file_exists($file)) { + @unlink($file); + } + } + + @rmdir(sys_get_temp_dir().'/framework-yml-lint-test'); + } +} + +class Foo +{ + const TEST = 'foo'; +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/DumperTest.php b/modules/empikmarketplace/vendor/symfony/yaml/Tests/DumperTest.php new file mode 100644 index 00000000..e4dc49f3 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/DumperTest.php @@ -0,0 +1,655 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Dumper; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; + +class DumperTest extends TestCase +{ + protected $parser; + protected $dumper; + protected $path; + + protected $array = [ + '' => 'bar', + 'foo' => '#bar', + 'foo\'bar' => [], + 'bar' => [1, 'foo'], + 'foobar' => [ + 'foo' => 'bar', + 'bar' => [1, 'foo'], + 'foobar' => [ + 'foo' => 'bar', + 'bar' => [1, 'foo'], + ], + ], + ]; + + protected function setUp() + { + $this->parser = new Parser(); + $this->dumper = new Dumper(); + $this->path = __DIR__.'/Fixtures'; + } + + protected function tearDown() + { + $this->parser = null; + $this->dumper = null; + $this->path = null; + $this->array = null; + } + + public function testIndentationInConstructor() + { + $dumper = new Dumper(7); + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $dumper->dump($this->array, 4, 0)); + } + + /** + * @group legacy + */ + public function testSetIndentation() + { + $this->dumper->setIndentation(7); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 4, 0)); + } + + public function testSpecifications() + { + $files = $this->parser->parse(file_get_contents($this->path.'/index.yml')); + foreach ($files as $file) { + $yamls = file_get_contents($this->path.'/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $this->parser->parse($yaml); + if (isset($test['dump_skip']) && $test['dump_skip']) { + continue; + } elseif (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + $this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']); + } + } + } + } + + public function testInlineLevel() + { + $expected = <<<'EOF' +{ '': bar, foo: '#bar', 'foo''bar': { }, bar: [1, foo], foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } } +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, -10), '->dump() takes an inline level argument'); + $this->assertEquals($expected, $this->dumper->dump($this->array, 0), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: [1, foo] +foobar: { foo: bar, bar: [1, foo], foobar: { foo: bar, bar: [1, foo] } } + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 1), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: [1, foo] + foobar: { foo: bar, bar: [1, foo] } + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 2), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: [1, foo] + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 3), '->dump() takes an inline level argument'); + + $expected = <<<'EOF' +'': bar +foo: '#bar' +'foo''bar': { } +bar: + - 1 + - foo +foobar: + foo: bar + bar: + - 1 + - foo + foobar: + foo: bar + bar: + - 1 + - foo + +EOF; + $this->assertEquals($expected, $this->dumper->dump($this->array, 4), '->dump() takes an inline level argument'); + $this->assertEquals($expected, $this->dumper->dump($this->array, 10), '->dump() takes an inline level argument'); + } + + public function testObjectSupportEnabled() + { + $dump = $this->dumper->dump(['foo' => new A(), 'bar' => 1], 0, 0, Yaml::DUMP_OBJECT); + + $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects'); + } + + /** + * @group legacy + */ + public function testObjectSupportEnabledPassingTrue() + { + $dump = $this->dumper->dump(['foo' => new A(), 'bar' => 1], 0, 0, false, true); + + $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects'); + } + + public function testObjectSupportDisabledButNoExceptions() + { + $dump = $this->dumper->dump(['foo' => new A(), 'bar' => 1]); + + $this->assertEquals('{ foo: null, bar: 1 }', $dump, '->dump() does not dump objects when disabled'); + } + + public function testObjectSupportDisabledWithExceptions() + { + $this->expectException('Symfony\Component\Yaml\Exception\DumpException'); + $this->dumper->dump(['foo' => new A(), 'bar' => 1], 0, 0, Yaml::DUMP_EXCEPTION_ON_INVALID_TYPE); + } + + /** + * @group legacy + */ + public function testObjectSupportDisabledWithExceptionsPassingTrue() + { + $this->expectException('Symfony\Component\Yaml\Exception\DumpException'); + $this->dumper->dump(['foo' => new A(), 'bar' => 1], 0, 0, true); + } + + public function testEmptyArray() + { + $dump = $this->dumper->dump([]); + $this->assertEquals('{ }', $dump); + + $dump = $this->dumper->dump([], 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE); + $this->assertEquals('[]', $dump); + + $dump = $this->dumper->dump([], 9, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE); + $this->assertEquals('[]', $dump); + + $dump = $this->dumper->dump(new \ArrayObject(), 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP); + $this->assertEquals('{ }', $dump); + + $dump = $this->dumper->dump(new \stdClass(), 0, 0, Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE | Yaml::DUMP_OBJECT_AS_MAP); + $this->assertEquals('{ }', $dump); + } + + /** + * @dataProvider getEscapeSequences + */ + public function testEscapedEscapeSequencesInQuotedScalar($input, $expected) + { + $this->assertEquals($expected, $this->dumper->dump($input)); + } + + public function getEscapeSequences() + { + return [ + 'empty string' => ['', "''"], + 'null' => ["\x0", '"\\0"'], + 'bell' => ["\x7", '"\\a"'], + 'backspace' => ["\x8", '"\\b"'], + 'horizontal-tab' => ["\t", '"\\t"'], + 'line-feed' => ["\n", '"\\n"'], + 'vertical-tab' => ["\v", '"\\v"'], + 'form-feed' => ["\xC", '"\\f"'], + 'carriage-return' => ["\r", '"\\r"'], + 'escape' => ["\x1B", '"\\e"'], + 'space' => [' ', "' '"], + 'double-quote' => ['"', "'\"'"], + 'slash' => ['/', '/'], + 'backslash' => ['\\', '\\'], + 'del' => ["\x7f", '"\x7f"'], + 'next-line' => ["\xC2\x85", '"\\N"'], + 'non-breaking-space' => ["\xc2\xa0", '"\\_"'], + 'line-separator' => ["\xE2\x80\xA8", '"\\L"'], + 'paragraph-separator' => ["\xE2\x80\xA9", '"\\P"'], + 'colon' => [':', "':'"], + ]; + } + + public function testBinaryDataIsDumpedBase64Encoded() + { + $binaryData = file_get_contents(__DIR__.'/Fixtures/arrow.gif'); + $expected = '{ data: !!binary '.base64_encode($binaryData).' }'; + + $this->assertSame($expected, $this->dumper->dump(['data' => $binaryData])); + } + + public function testNonUtf8DataIsDumpedBase64Encoded() + { + // "für" (ISO-8859-1 encoded) + $this->assertSame('!!binary ZsM/cg==', $this->dumper->dump("f\xc3\x3fr")); + } + + /** + * @dataProvider objectAsMapProvider + */ + public function testDumpObjectAsMap($object, $expected) + { + $yaml = $this->dumper->dump($object, 0, 0, Yaml::DUMP_OBJECT_AS_MAP); + + $this->assertEquals($expected, Yaml::parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP)); + } + + public function objectAsMapProvider() + { + $tests = []; + + $bar = new \stdClass(); + $bar->class = 'classBar'; + $bar->args = ['bar']; + $zar = new \stdClass(); + $foo = new \stdClass(); + $foo->bar = $bar; + $foo->zar = $zar; + $object = new \stdClass(); + $object->foo = $foo; + $tests['stdClass'] = [$object, $object]; + + $arrayObject = new \ArrayObject(); + $arrayObject['foo'] = 'bar'; + $arrayObject['baz'] = 'foobar'; + $parsedArrayObject = new \stdClass(); + $parsedArrayObject->foo = 'bar'; + $parsedArrayObject->baz = 'foobar'; + $tests['ArrayObject'] = [$arrayObject, $parsedArrayObject]; + + $a = new A(); + $tests['arbitrary-object'] = [$a, null]; + + return $tests; + } + + public function testDumpingArrayObjectInstancesRespectsInlineLevel() + { + $deep = new \ArrayObject(['deep1' => 'd', 'deep2' => 'e']); + $inner = new \ArrayObject(['inner1' => 'b', 'inner2' => 'c', 'inner3' => $deep]); + $outer = new \ArrayObject(['outer1' => 'a', 'outer2' => $inner]); + + $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP); + + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingArrayObjectInstancesWithNumericKeysInlined() + { + $deep = new \ArrayObject(['d', 'e']); + $inner = new \ArrayObject(['b', 'c', $deep]); + $outer = new \ArrayObject(['a', $inner]); + + $yaml = $this->dumper->dump($outer, 0, 0, Yaml::DUMP_OBJECT_AS_MAP); + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingArrayObjectInstancesWithNumericKeysRespectsInlineLevel() + { + $deep = new \ArrayObject(['d', 'e']); + $inner = new \ArrayObject(['b', 'c', $deep]); + $outer = new \ArrayObject(['a', $inner]); + $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP); + $expected = <<assertEquals($expected, $yaml); + } + + public function testDumpEmptyArrayObjectInstanceAsMap() + { + $this->assertSame('{ }', $this->dumper->dump(new \ArrayObject(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP)); + } + + public function testDumpEmptyStdClassInstanceAsMap() + { + $this->assertSame('{ }', $this->dumper->dump(new \stdClass(), 2, 0, Yaml::DUMP_OBJECT_AS_MAP)); + } + + public function testDumpingStdClassInstancesRespectsInlineLevel() + { + $deep = new \stdClass(); + $deep->deep1 = 'd'; + $deep->deep2 = 'e'; + + $inner = new \stdClass(); + $inner->inner1 = 'b'; + $inner->inner2 = 'c'; + $inner->inner3 = $deep; + + $outer = new \stdClass(); + $outer->outer1 = 'a'; + $outer->outer2 = $inner; + + $yaml = $this->dumper->dump($outer, 2, 0, Yaml::DUMP_OBJECT_AS_MAP); + + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingTaggedValueSequenceRespectsInlineLevel() + { + $data = [ + new TaggedValue('user', [ + 'username' => 'jane', + ]), + new TaggedValue('user', [ + 'username' => 'john', + ]), + ]; + + $yaml = $this->dumper->dump($data, 2); + + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingTaggedValueSequenceWithInlinedTagValues() + { + $data = [ + new TaggedValue('user', [ + 'username' => 'jane', + ]), + new TaggedValue('user', [ + 'username' => 'john', + ]), + ]; + + $yaml = $this->dumper->dump($data, 1); + + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingTaggedValueMapRespectsInlineLevel() + { + $data = [ + 'user1' => new TaggedValue('user', [ + 'username' => 'jane', + ]), + 'user2' => new TaggedValue('user', [ + 'username' => 'john', + ]), + ]; + + $yaml = $this->dumper->dump($data, 2); + + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingTaggedValueMapWithInlinedTagValues() + { + $data = [ + 'user1' => new TaggedValue('user', [ + 'username' => 'jane', + ]), + 'user2' => new TaggedValue('user', [ + 'username' => 'john', + ]), + ]; + + $yaml = $this->dumper->dump($data, 1); + + $expected = <<assertSame($expected, $yaml); + } + + public function testDumpingNotInlinedScalarTaggedValue() + { + $data = [ + 'user1' => new TaggedValue('user', 'jane'), + 'user2' => new TaggedValue('user', 'john'), + ]; + $expected = <<assertSame($expected, $this->dumper->dump($data, 2)); + } + + public function testDumpingNotInlinedNullTaggedValue() + { + $data = [ + 'foo' => new TaggedValue('bar', null), + ]; + $expected = <<assertSame($expected, $this->dumper->dump($data, 2)); + } + + public function testDumpingMultiLineStringAsScalarBlockTaggedValue() + { + $data = [ + 'foo' => new TaggedValue('bar', "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz"), + ]; + $expected = <<assertSame($expected, $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + + public function testDumpingInlinedMultiLineIfRnBreakLineInTaggedValue() + { + $data = [ + 'data' => [ + 'foo' => new TaggedValue('bar', "foo\r\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz"), + ], + ]; + + $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block_for_tagged_values.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + + public function testDumpMultiLineStringAsScalarBlock() + { + $data = [ + 'data' => [ + 'single_line' => 'foo bar baz', + 'multi_line' => "foo\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz", + 'multi_line_with_carriage_return' => "foo\nbar\r\nbaz", + 'nested_inlined_multi_line_string' => [ + 'inlined_multi_line' => "foo\nbar\r\nempty line:\n\nbaz", + ], + ], + ]; + + $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + + public function testDumpMultiLineStringAsScalarBlockWhenFirstLineHasLeadingSpace() + { + $data = [ + 'data' => [ + 'multi_line' => " the first line has leading spaces\nThe second line does not.", + ], + ]; + + $this->assertSame(file_get_contents(__DIR__.'/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml'), $this->dumper->dump($data, 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + + public function testCarriageReturnFollowedByNewlineIsMaintainedWhenDumpingAsMultiLineLiteralBlock() + { + $this->assertSame("- \"a\\r\\nb\\nc\"\n", $this->dumper->dump(["a\r\nb\nc"], 2, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + + public function testCarriageReturnNotFollowedByNewlineIsPreservedWhenDumpingAsMultiLineLiteralBlock() + { + $expected = <<<'YAML' +parent: + foo: "bar\n\rbaz: qux" + +YAML; + + $this->assertSame($expected, $this->dumper->dump([ + 'parent' => [ + 'foo' => "bar\n\rbaz: qux", + ], + ], 4, 0, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK)); + } + + public function testZeroIndentationThrowsException() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The indentation must be greater than zero'); + new Dumper(0); + } + + public function testNegativeIndentationThrowsException() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The indentation must be greater than zero'); + new Dumper(-4); + } +} + +class A +{ + public $a = 'foo'; +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml new file mode 100644 index 00000000..81b4129a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsAnchorAlias.yml @@ -0,0 +1,31 @@ +--- %YAML:1.0 +test: Simple Alias Example +brief: > + If you need to refer to the same item of data twice, + you can give that item an alias. The alias is a plain + string, starting with an ampersand. The item may then + be referred to by the alias throughout your document + by using an asterisk before the name of the alias. + This is called an anchor. +yaml: | + - &showell Steve + - Clark + - Brian + - Oren + - *showell +php: | + ['Steve', 'Clark', 'Brian', 'Oren', 'Steve'] + +--- +test: Alias of a Mapping +brief: > + An alias can be used on any item of data, including + sequences, mappings, and other complex data types. +yaml: | + - &hello + Meat: pork + Starch: potato + - banana + - *hello +php: | + [['Meat'=>'pork', 'Starch'=>'potato'], 'banana', ['Meat'=>'pork', 'Starch'=>'potato']] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml new file mode 100644 index 00000000..1a08d8ea --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsBasicTests.yml @@ -0,0 +1,202 @@ +--- %YAML:1.0 +test: Simple Sequence +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - banana + - carrot +php: | + ['apple', 'banana', 'carrot'] +--- +test: Sequence With Item Being Null In The Middle +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - + - carrot +php: | + ['apple', null, 'carrot'] +--- +test: Sequence With Last Item Being Null +brief: | + You can specify a list in YAML by placing each + member of the list on a new line with an opening + dash. These lists are called sequences. +yaml: | + - apple + - banana + - +php: | + ['apple', 'banana', null] +--- +test: Nested Sequences +brief: | + You can include a sequence within another + sequence by giving the sequence an empty + dash, followed by an indented list. +yaml: | + - + - foo + - bar + - baz +php: | + [['foo', 'bar', 'baz']] +--- +test: Mixed Sequences +brief: | + Sequences can contain any YAML data, + including strings and other sequences. +yaml: | + - apple + - + - foo + - bar + - x123 + - banana + - carrot +php: | + ['apple', ['foo', 'bar', 'x123'], 'banana', 'carrot'] +--- +test: Deeply Nested Sequences +brief: | + Sequences can be nested even deeper, with each + level of indentation representing a level of + depth. +yaml: | + - + - + - uno + - dos +php: | + [[['uno', 'dos']]] +--- +test: Simple Mapping +brief: | + You can add a keyed list (also known as a dictionary or + hash) to your document by placing each member of the + list on a new line, with a colon separating the key + from its value. In YAML, this type of list is called + a mapping. +yaml: | + foo: whatever + bar: stuff +php: | + ['foo' => 'whatever', 'bar' => 'stuff'] +--- +test: Sequence in a Mapping +brief: | + A value in a mapping can be a sequence. +yaml: | + foo: whatever + bar: + - uno + - dos +php: | + ['foo' => 'whatever', 'bar' => ['uno', 'dos']] +--- +test: Nested Mappings +brief: | + A value in a mapping can be another mapping. +yaml: | + foo: whatever + bar: + fruit: apple + name: steve + sport: baseball +php: | + [ + 'foo' => 'whatever', + 'bar' => [ + 'fruit' => 'apple', + 'name' => 'steve', + 'sport' => 'baseball' + ] + ] +--- +test: Mixed Mapping +brief: | + A mapping can contain any assortment + of mappings and sequences as values. +yaml: | + foo: whatever + bar: + - + fruit: apple + name: steve + sport: baseball + - more + - + python: rocks + perl: papers + ruby: scissorses +php: | + [ + 'foo' => 'whatever', + 'bar' => [ + [ + 'fruit' => 'apple', + 'name' => 'steve', + 'sport' => 'baseball' + ], + 'more', + [ + 'python' => 'rocks', + 'perl' => 'papers', + 'ruby' => 'scissorses' + ] + ] + ] +--- +test: Mapping-in-Sequence Shortcut +todo: true +brief: | + If you are adding a mapping to a sequence, you + can place the mapping on the same line as the + dash as a shortcut. +yaml: | + - work on YAML.py: + - work on Store +php: | + [['work on YAML.py' => ['work on Store']]] +--- +test: Sequence-in-Mapping Shortcut +todo: true +brief: | + The dash in a sequence counts as indentation, so + you can add a sequence inside of a mapping without + needing spaces as indentation. +yaml: | + allow: + - 'localhost' + - '%.sourceforge.net' + - '%.freepan.org' +php: | + ['allow' => ['localhost', '%.sourceforge.net', '%.freepan.org']] +--- +todo: true +test: Merge key +brief: | + A merge key ('<<') can be used in a mapping to insert other mappings. If + the value associated with the merge key is a mapping, each of its key/value + pairs is inserted into the current mapping. +yaml: | + mapping: + name: Joe + job: Accountant + <<: + age: 38 +php: | + [ + 'mapping' => + [ + 'name' => 'Joe', + 'job' => 'Accountant', + 'age' => 38 + ] + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml new file mode 100644 index 00000000..1f3a2e54 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsBlockMapping.yml @@ -0,0 +1,51 @@ +--- +test: One Element Mapping +brief: | + A mapping with one key/value pair +yaml: | + foo: bar +php: | + ['foo' => 'bar'] +--- +test: Multi Element Mapping +brief: | + More than one key/value pair +yaml: | + red: baron + white: walls + blue: berries +php: | + [ + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ] +--- +test: Values aligned +brief: | + Often times human editors of documents will align the values even + though YAML emitters generally don't. +yaml: | + red: baron + white: walls + blue: berries +php: | + [ + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ] +--- +test: Colons aligned +brief: | + Spaces can come before the ': ' key/value separator. +yaml: | + red : baron + white : walls + blue : berries +php: | + [ + 'red' => 'baron', + 'white' => 'walls', + 'blue' => 'berries', + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml new file mode 100644 index 00000000..67cb47ad --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsDocumentSeparator.yml @@ -0,0 +1,85 @@ +--- %YAML:1.0 +test: Trailing Document Separator +todo: true +brief: > + You can separate YAML documents + with a string of three dashes. +yaml: | + - foo: 1 + bar: 2 + --- + more: stuff +python: | + [ + [ { 'foo': 1, 'bar': 2 } ], + { 'more': 'stuff' } + ] +ruby: | + [ { 'foo' => 1, 'bar' => 2 } ] + +--- +test: Leading Document Separator +todo: true +brief: > + You can explicitly give an opening + document separator to your YAML stream. +yaml: | + --- + - foo: 1 + bar: 2 + --- + more: stuff +python: | + [ + [ {'foo': 1, 'bar': 2}], + {'more': 'stuff'} + ] +ruby: | + [ { 'foo' => 1, 'bar' => 2 } ] + +--- +test: YAML Header +todo: true +brief: > + The opening separator can contain directives + to the YAML parser, such as the version + number. +yaml: | + --- %YAML:1.0 + foo: 1 + bar: 2 +php: | + ['foo' => 1, 'bar' => 2] +documents: 1 + +--- +test: Red Herring Document Separator +brief: > + Separators included in blocks or strings + are treated as blocks or strings, as the + document separator should have no indentation + preceding it. +yaml: | + foo: | + --- +php: | + ['foo' => "---\n"] + +--- +test: Multiple Document Separators in Block +brief: > + This technique allows you to embed other YAML + documents within literal blocks. +yaml: | + foo: | + --- + foo: bar + --- + yo: baz + bar: | + fooness +php: | + [ + 'foo' => "---\nfoo: bar\n---\nyo: baz\n", + 'bar' => "fooness\n" + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml new file mode 100644 index 00000000..e8697f93 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsErrorTests.yml @@ -0,0 +1,25 @@ +--- +test: Missing value for hash item +todo: true +brief: | + Third item in this hash doesn't have a value +yaml: | + okay: value + also okay: ~ + causes error because no value specified + last key: value okay here too +python-error: causes error because no value specified + +--- +test: Not indenting enough +brief: | + There was a bug in PyYaml where it was off by one + in the indentation check. It was allowing the YAML + below. +# This is actually valid YAML now. Someone should tell showell. +yaml: | + foo: + firstline: 1 + secondline: 2 +php: | + ['foo' => null, 'firstline' => 1, 'secondline' => 2] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml new file mode 100644 index 00000000..cc562cd9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsFlowCollections.yml @@ -0,0 +1,60 @@ +--- +test: Simple Inline Array +brief: > + Sequences can be contained on a + single line, using the inline syntax. + Separate each entry with commas and + enclose in square brackets. +yaml: | + seq: [ a, b, c ] +php: | + ['seq' => ['a', 'b', 'c']] +--- +test: Simple Inline Hash +brief: > + Mapping can also be contained on + a single line, using the inline + syntax. Each key-value pair is + separated by a colon, with a comma + between each entry in the mapping. + Enclose with curly braces. +yaml: | + hash: { name: Steve, foo: bar } +php: | + ['hash' => ['name' => 'Steve', 'foo' => 'bar']] +--- +test: Multi-line Inline Collections +todo: true +brief: > + Both inline sequences and inline mappings + can span multiple lines, provided that you + indent the additional lines. +yaml: | + languages: [ Ruby, + Perl, + Python ] + websites: { YAML: yaml.org, + Ruby: ruby-lang.org, + Python: python.org, + Perl: use.perl.org } +php: | + [ + 'languages' => ['Ruby', 'Perl', 'Python'], + 'websites' => [ + 'YAML' => 'yaml.org', + 'Ruby' => 'ruby-lang.org', + 'Python' => 'python.org', + 'Perl' => 'use.perl.org' + ] + ] +--- +test: Commas in Values (not in the spec!) +todo: true +brief: > + List items in collections are delimited by commas, but + there must be a space after each comma. This allows you + to add numbers without quoting. +yaml: | + attendances: [ 45,123, 70,000, 17,222 ] +php: | + ['attendances' => [45123, 70000, 17222]] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml new file mode 100644 index 00000000..2895202a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsFoldedScalars.yml @@ -0,0 +1,176 @@ +--- %YAML:1.0 +test: Single ending newline +brief: > + A pipe character, followed by an indented + block of text is treated as a literal + block, in which newlines are preserved + throughout the block, including the final + newline. +yaml: | + --- + this: | + Foo + Bar +php: | + ['this' => "Foo\nBar\n"] +--- +test: The '+' indicator +brief: > + The '+' indicator says to keep newlines at the end of text + blocks. +yaml: | + normal: | + extra new lines not kept + + preserving: |+ + extra new lines are kept + + + dummy: value +php: | + [ + 'normal' => "extra new lines not kept\n", + 'preserving' => "extra new lines are kept\n\n\n", + 'dummy' => 'value' + ] +--- +test: Three trailing newlines in literals +brief: > + To give you more control over how space + is preserved in text blocks, YAML has + the keep '+' and chomp '-' indicators. + The keep indicator will preserve all + ending newlines, while the chomp indicator + will strip all ending newlines. +yaml: | + clipped: | + This has one newline. + + + + same as "clipped" above: "This has one newline.\n" + + stripped: |- + This has no newline. + + + + same as "stripped" above: "This has no newline." + + kept: |+ + This has four newlines. + + + + same as "kept" above: "This has four newlines.\n\n\n\n" +php: | + [ + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has four newlines.\n\n\n\n", + 'same as "kept" above' => "This has four newlines.\n\n\n\n" + ] +--- +test: Extra trailing newlines with spaces +todo: true +brief: > + Normally, only a single newline is kept + from the end of a literal block, unless the + keep '+' character is used in combination + with the pipe. The following example + will preserve all ending whitespace + since the last line of both literal blocks + contains spaces which extend past the indentation + level. +yaml: | + --- + this: | + Foo + + + kept: |+ + Foo + + +php: | + ['this' => "Foo\n\n \n", + 'kept' => "Foo\n\n \n"] + +--- +test: Folded Block in a Sequence +brief: > + A greater-then character, followed by an indented + block of text is treated as a folded block, in + which lines of text separated by a single newline + are concatenated as a single line. +yaml: | + --- + - apple + - banana + - > + can't you see + the beauty of yaml? + hmm + - dog +php: | + [ + 'apple', + 'banana', + "can't you see the beauty of yaml? hmm\n", + 'dog' + ] +--- +test: Folded Block as a Mapping Value +brief: > + Both literal and folded blocks can be + used in collections, as values in a + sequence or a mapping. +yaml: | + --- + quote: > + Mark McGwire's + year was crippled + by a knee injury. + source: espn +php: | + [ + 'quote' => "Mark McGwire's year was crippled by a knee injury.\n", + 'source' => 'espn' + ] +--- +test: Three trailing newlines in folded blocks +brief: > + The keep and chomp indicators can also + be applied to folded blocks. +yaml: | + clipped: > + This has one newline. + + + + same as "clipped" above: "This has one newline.\n" + + stripped: >- + This has no newline. + + + + same as "stripped" above: "This has no newline." + + kept: >+ + This has four newlines. + + + + same as "kept" above: "This has four newlines.\n\n\n\n" +php: | + [ + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has four newlines.\n\n\n\n", + 'same as "kept" above' => "This has four newlines.\n\n\n\n" + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml new file mode 100644 index 00000000..ea8e36ed --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsNullsAndEmpties.yml @@ -0,0 +1,45 @@ +--- %YAML:1.0 +test: Empty Sequence +brief: > + You can represent the empty sequence + with an empty inline sequence. +yaml: | + empty: [] +php: | + ['empty' => []] +--- +test: Empty Mapping +brief: > + You can represent the empty mapping + with an empty inline mapping. +yaml: | + empty: {} +php: | + ['empty' => []] +--- +test: Empty Sequence as Entire Document +yaml: | + [] +php: | + [] +--- +test: Empty Mapping as Entire Document +yaml: | + {} +php: | + [] +--- +test: Null as Document +yaml: | + ~ +php: | + null +--- +test: Empty String +brief: > + You can represent an empty string + with a pair of quotes. +yaml: | + '' +php: | + '' diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml new file mode 100644 index 00000000..dd2d776f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsSpecificationExamples.yml @@ -0,0 +1,1701 @@ +--- %YAML:1.0 +test: Sequence of scalars +spec: 2.1 +yaml: | + - Mark McGwire + - Sammy Sosa + - Ken Griffey +php: | + ['Mark McGwire', 'Sammy Sosa', 'Ken Griffey'] +--- +test: Mapping of scalars to scalars +spec: 2.2 +yaml: | + hr: 65 + avg: 0.278 + rbi: 147 +php: | + ['hr' => 65, 'avg' => 0.278, 'rbi' => 147] +--- +test: Mapping of scalars to sequences +spec: 2.3 +yaml: | + american: + - Boston Red Sox + - Detroit Tigers + - New York Yankees + national: + - New York Mets + - Chicago Cubs + - Atlanta Braves +php: | + ['american' => + ['Boston Red Sox', 'Detroit Tigers', + 'New York Yankees'], + 'national' => + ['New York Mets', 'Chicago Cubs', + 'Atlanta Braves'] + ] +--- +test: Sequence of mappings +spec: 2.4 +yaml: | + - + name: Mark McGwire + hr: 65 + avg: 0.278 + - + name: Sammy Sosa + hr: 63 + avg: 0.288 +php: | + [ + ['name' => 'Mark McGwire', 'hr' => 65, 'avg' => 0.278], + ['name' => 'Sammy Sosa', 'hr' => 63, 'avg' => 0.288] + ] +--- +test: Legacy A5 +todo: true +spec: legacy_A5 +yaml: | + ? + - New York Yankees + - Atlanta Braves + : + - 2001-07-02 + - 2001-08-12 + - 2001-08-14 + ? + - Detroit Tigers + - Chicago Cubs + : + - 2001-07-23 +perl-busted: > + YAML.pm will be able to emulate this behavior soon. In this regard + it may be somewhat more correct than Python's native behavior which + can only use tuples as mapping keys. PyYAML will also need to figure + out some clever way to roundtrip structured keys. +python: | + [ + { + ('New York Yankees', 'Atlanta Braves'): + [yaml.timestamp('2001-07-02'), + yaml.timestamp('2001-08-12'), + yaml.timestamp('2001-08-14')], + ('Detroit Tigers', 'Chicago Cubs'): + [yaml.timestamp('2001-07-23')] + } + ] +ruby: | + { + [ 'New York Yankees', 'Atlanta Braves' ] => + [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ], + [ 'Detroit Tigers', 'Chicago Cubs' ] => + [ Date.new( 2001, 7, 23 ) ] + } +syck: | + struct test_node seq1[] = { + { T_STR, 0, "New York Yankees" }, + { T_STR, 0, "Atlanta Braves" }, + end_node + }; + struct test_node seq2[] = { + { T_STR, 0, "2001-07-02" }, + { T_STR, 0, "2001-08-12" }, + { T_STR, 0, "2001-08-14" }, + end_node + }; + struct test_node seq3[] = { + { T_STR, 0, "Detroit Tigers" }, + { T_STR, 0, "Chicago Cubs" }, + end_node + }; + struct test_node seq4[] = { + { T_STR, 0, "2001-07-23" }, + end_node + }; + struct test_node map[] = { + { T_SEQ, 0, 0, seq1 }, + { T_SEQ, 0, 0, seq2 }, + { T_SEQ, 0, 0, seq3 }, + { T_SEQ, 0, 0, seq4 }, + end_node + }; + struct test_node stream[] = { + { T_MAP, 0, 0, map }, + end_node + }; + +--- +test: Sequence of sequences +spec: 2.5 +yaml: | + - [ name , hr , avg ] + - [ Mark McGwire , 65 , 0.278 ] + - [ Sammy Sosa , 63 , 0.288 ] +php: | + [ + [ 'name', 'hr', 'avg' ], + [ 'Mark McGwire', 65, 0.278 ], + [ 'Sammy Sosa', 63, 0.288 ] + ] +--- +test: Mapping of mappings +todo: true +spec: 2.6 +yaml: | + Mark McGwire: {hr: 65, avg: 0.278} + Sammy Sosa: { + hr: 63, + avg: 0.288 + } +php: | + [ + 'Mark McGwire' => + [ 'hr' => 65, 'avg' => 0.278 ], + 'Sammy Sosa' => + [ 'hr' => 63, 'avg' => 0.288 ] + ] +--- +test: Two documents in a stream each with a leading comment +todo: true +spec: 2.7 +yaml: | + # Ranking of 1998 home runs + --- + - Mark McGwire + - Sammy Sosa + - Ken Griffey + + # Team ranking + --- + - Chicago Cubs + - St Louis Cardinals +ruby: | + y = YAML::Stream.new + y.add( [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] ) + y.add( [ 'Chicago Cubs', 'St Louis Cardinals' ] ) +documents: 2 + +--- +test: Play by play feed from a game +todo: true +spec: 2.8 +yaml: | + --- + time: 20:03:20 + player: Sammy Sosa + action: strike (miss) + ... + --- + time: 20:03:47 + player: Sammy Sosa + action: grand slam + ... +perl: | + [ 'Mark McGwire', 'Sammy Sosa', 'Ken Griffey' ] +documents: 2 + +--- +test: Single document with two comments +spec: 2.9 +yaml: | + hr: # 1998 hr ranking + - Mark McGwire + - Sammy Sosa + rbi: + # 1998 rbi ranking + - Sammy Sosa + - Ken Griffey +php: | + [ + 'hr' => [ 'Mark McGwire', 'Sammy Sosa' ], + 'rbi' => [ 'Sammy Sosa', 'Ken Griffey' ] + ] +--- +test: Node for Sammy Sosa appears twice in this document +spec: 2.10 +yaml: | + --- + hr: + - Mark McGwire + # Following node labeled SS + - &SS Sammy Sosa + rbi: + - *SS # Subsequent occurrence + - Ken Griffey +php: | + [ + 'hr' => + ['Mark McGwire', 'Sammy Sosa'], + 'rbi' => + ['Sammy Sosa', 'Ken Griffey'] + ] +--- +test: Mapping between sequences +todo: true +spec: 2.11 +yaml: | + ? # PLAY SCHEDULE + - Detroit Tigers + - Chicago Cubs + : + - 2001-07-23 + + ? [ New York Yankees, + Atlanta Braves ] + : [ 2001-07-02, 2001-08-12, + 2001-08-14 ] +ruby: | + { + [ 'Detroit Tigers', 'Chicago Cubs' ] => [ Date.new( 2001, 7, 23 ) ], + [ 'New York Yankees', 'Atlanta Braves' ] => [ Date.new( 2001, 7, 2 ), Date.new( 2001, 8, 12 ), Date.new( 2001, 8, 14 ) ] + } +syck: | + struct test_node seq1[] = { + { T_STR, 0, "New York Yankees" }, + { T_STR, 0, "Atlanta Braves" }, + end_node + }; + struct test_node seq2[] = { + { T_STR, 0, "2001-07-02" }, + { T_STR, 0, "2001-08-12" }, + { T_STR, 0, "2001-08-14" }, + end_node + }; + struct test_node seq3[] = { + { T_STR, 0, "Detroit Tigers" }, + { T_STR, 0, "Chicago Cubs" }, + end_node + }; + struct test_node seq4[] = { + { T_STR, 0, "2001-07-23" }, + end_node + }; + struct test_node map[] = { + { T_SEQ, 0, 0, seq3 }, + { T_SEQ, 0, 0, seq4 }, + { T_SEQ, 0, 0, seq1 }, + { T_SEQ, 0, 0, seq2 }, + end_node + }; + struct test_node stream[] = { + { T_MAP, 0, 0, map }, + end_node + }; + +--- +test: Sequence key shortcut +spec: 2.12 +yaml: | + --- + # products purchased + - item : Super Hoop + quantity: 1 + - item : Basketball + quantity: 4 + - item : Big Shoes + quantity: 1 +php: | + [ + [ + 'item' => 'Super Hoop', + 'quantity' => 1, + ], + [ + 'item' => 'Basketball', + 'quantity' => 4, + ], + [ + 'item' => 'Big Shoes', + 'quantity' => 1, + ] + ] +perl: | + [ + { item => 'Super Hoop', quantity => 1 }, + { item => 'Basketball', quantity => 4 }, + { item => 'Big Shoes', quantity => 1 } + ] + +ruby: | + [ + { 'item' => 'Super Hoop', 'quantity' => 1 }, + { 'item' => 'Basketball', 'quantity' => 4 }, + { 'item' => 'Big Shoes', 'quantity' => 1 } + ] +python: | + [ + { 'item': 'Super Hoop', 'quantity': 1 }, + { 'item': 'Basketball', 'quantity': 4 }, + { 'item': 'Big Shoes', 'quantity': 1 } + ] +syck: | + struct test_node map1[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Super Hoop" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "1" }, + end_node + }; + struct test_node map2[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Basketball" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "4" }, + end_node + }; + struct test_node map3[] = { + { T_STR, 0, "item" }, + { T_STR, 0, "Big Shoes" }, + { T_STR, 0, "quantity" }, + { T_STR, 0, "1" }, + end_node + }; + struct test_node seq[] = { + { T_MAP, 0, 0, map1 }, + { T_MAP, 0, 0, map2 }, + { T_MAP, 0, 0, map3 }, + end_node + }; + struct test_node stream[] = { + { T_SEQ, 0, 0, seq }, + end_node + }; + + +--- +test: Literal perserves newlines +todo: true +spec: 2.13 +yaml: | + # ASCII Art + --- | + \//||\/|| + // || ||_ +perl: | + "\\//||\\/||\n// || ||_\n" +ruby: | + "\\//||\\/||\n// || ||_\n" +python: | + [ + flushLeft( + """ + \//||\/|| + // || ||_ + """ + ) + ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "\\//||\\/||\n// || ||_\n" }, + end_node + }; + +--- +test: Folded treats newlines as a space +todo: true +spec: 2.14 +yaml: | + --- + Mark McGwire's + year was crippled + by a knee injury. +perl: | + "Mark McGwire's year was crippled by a knee injury." +ruby: | + "Mark McGwire's year was crippled by a knee injury." +python: | + [ "Mark McGwire's year was crippled by a knee injury." ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "Mark McGwire's year was crippled by a knee injury." }, + end_node + }; + +--- +test: Newlines preserved for indented and blank lines +todo: true +spec: 2.15 +yaml: | + --- > + Sammy Sosa completed another + fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! +perl: | + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" +ruby: | + "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" +python: | + [ + flushLeft( + """ + Sammy Sosa completed another fine season with great stats. + + 63 Home Runs + 0.288 Batting Average + + What a year! + """ + ) + ] +syck: | + struct test_node stream[] = { + { T_STR, 0, "Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n" }, + end_node + }; + + +--- +test: Indentation determines scope +spec: 2.16 +yaml: | + name: Mark McGwire + accomplishment: > + Mark set a major league + home run record in 1998. + stats: | + 65 Home Runs + 0.278 Batting Average +php: | + [ + 'name' => 'Mark McGwire', + 'accomplishment' => "Mark set a major league home run record in 1998.\n", + 'stats' => "65 Home Runs\n0.278 Batting Average\n" + ] +--- +test: Quoted scalars +todo: true +spec: 2.17 +yaml: | + unicode: "Sosa did fine.\u263A" + control: "\b1998\t1999\t2000\n" + hexesc: "\x0D\x0A is \r\n" + + single: '"Howdy!" he cried.' + quoted: ' # not a ''comment''.' + tie-fighter: '|\-*-/|' +ruby: | + { + "tie-fighter" => "|\\-*-/|", + "control"=>"\0101998\t1999\t2000\n", + "unicode"=>"Sosa did fine." + ["263A".hex ].pack('U*'), + "quoted"=>" # not a 'comment'.", + "single"=>"\"Howdy!\" he cried.", + "hexesc"=>"\r\n is \r\n" + } +--- +test: Multiline flow scalars +todo: true +spec: 2.18 +yaml: | + plain: + This unquoted scalar + spans many lines. + + quoted: "So does this + quoted scalar.\n" +ruby: | + { + 'plain' => 'This unquoted scalar spans many lines.', + 'quoted' => "So does this quoted scalar.\n" + } +--- +test: Integers +spec: 2.19 +yaml: | + canonical: 12345 + octal: 014 + hexadecimal: 0xC +php: | + [ + 'canonical' => 12345, + 'octal' => 014, + 'hexadecimal' => 0xC + ] +--- +test: Decimal Integer +deprecated: true +spec: 2.19 +yaml: | + decimal: +12,345 +php: | + [ + 'decimal' => 12345.0, + ] +--- +# FIX: spec shows parens around -inf and NaN +test: Floating point +spec: 2.20 +yaml: | + canonical: 1.23015e+3 + exponential: 12.3015e+02 + negative infinity: -.inf + not a number: .NaN + float as whole number: !!float 1 +php: | + [ + 'canonical' => 1230.15, + 'exponential' => 1230.15, + 'negative infinity' => log(0), + 'not a number' => -log(0), + 'float as whole number' => (float) 1 + ] +--- +test: Fixed Floating point +deprecated: true +spec: 2.20 +yaml: | + fixed: 1,230.15 +php: | + [ + 'fixed' => 1230.15, + ] +--- +test: Timestamps +todo: true +spec: 2.22 +yaml: | + canonical: 2001-12-15T02:59:43.1Z + iso8601: 2001-12-14t21:59:43.10-05:00 + spaced: 2001-12-14 21:59:43.10 -05:00 + date: 2002-12-14 # Time is noon UTC +php: | + [ + 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), + 'iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'date' => Date.new( 2002, 12, 14 ) + ] +--- +test: legacy Timestamps test +todo: true +spec: legacy D4 +yaml: | + canonical: 2001-12-15T02:59:43.00Z + iso8601: 2001-02-28t21:59:43.00-05:00 + spaced: 2001-12-14 21:59:43.00 -05:00 + date: 2002-12-14 +php: | + [ + 'canonical' => Time::utc( 2001, 12, 15, 2, 59, 43, 0 ), + 'iso8601' => YAML::mktime( 2001, 2, 28, 21, 59, 43, 0, "-05:00" ), + 'spaced' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0, "-05:00" ), + 'date' => Date.new( 2002, 12, 14 ) + ] +--- +test: Various explicit families +todo: true +spec: 2.23 +yaml: | + not-date: !!str 2002-04-28 + picture: !binary | + R0lGODlhDAAMAIQAAP//9/X + 17unp5WZmZgAAAOfn515eXv + Pz7Y6OjuDg4J+fn5OTk6enp + 56enmleECcgggoBADs= + + application specific tag: !!something | + The semantics of the tag + above may be different for + different documents. + +ruby-setup: | + YAML.add_private_type( "something" ) do |type, val| + "SOMETHING: #{val}" + end +ruby: | + { + 'not-date' => '2002-04-28', + 'picture' => "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236i^\020' \202\n\001\000;", + 'application specific tag' => "SOMETHING: The semantics of the tag\nabove may be different for\ndifferent documents.\n" + } +--- +test: Application specific family +todo: true +spec: 2.24 +yaml: | + # Establish a tag prefix + --- !clarkevans.com,2002/graph/^shape + # Use the prefix: shorthand for + # !clarkevans.com,2002/graph/circle + - !^circle + center: &ORIGIN {x: 73, 'y': 129} + radius: 7 + - !^line # !clarkevans.com,2002/graph/line + start: *ORIGIN + finish: { x: 89, 'y': 102 } + - !^label + start: *ORIGIN + color: 0xFFEEBB + value: Pretty vector drawing. +ruby-setup: | + YAML.add_domain_type( "clarkevans.com,2002", 'graph/shape' ) { |type, val| + if Array === val + val << "Shape Container" + val + else + raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect + end + } + one_shape_proc = Proc.new { |type, val| + scheme, domain, type = type.split( /:/, 3 ) + if val.is_a? ::Hash + val['TYPE'] = "Shape: #{type}" + val + else + raise YAML::Error, "Invalid graph of class #{ val.class }: " + val.inspect + end + } + YAML.add_domain_type( "clarkevans.com,2002", 'graph/circle', &one_shape_proc ) + YAML.add_domain_type( "clarkevans.com,2002", 'graph/line', &one_shape_proc ) + YAML.add_domain_type( "clarkevans.com,2002", 'graph/label', &one_shape_proc ) +ruby: | + [ + { + "radius" => 7, + "center"=> + { + "x" => 73, + "y" => 129 + }, + "TYPE" => "Shape: graph/circle" + }, { + "finish" => + { + "x" => 89, + "y" => 102 + }, + "TYPE" => "Shape: graph/line", + "start" => + { + "x" => 73, + "y" => 129 + } + }, { + "TYPE" => "Shape: graph/label", + "value" => "Pretty vector drawing.", + "start" => + { + "x" => 73, + "y" => 129 + }, + "color" => 16772795 + }, + "Shape Container" + ] +# --- +# test: Unordered set +# spec: 2.25 +# yaml: | +# # sets are represented as a +# # mapping where each key is +# # associated with the empty string +# --- !set +# ? Mark McGwire +# ? Sammy Sosa +# ? Ken Griff +--- +test: Ordered mappings +todo: true +spec: 2.26 +yaml: | + # ordered maps are represented as + # a sequence of mappings, with + # each mapping having one key + --- !omap + - Mark McGwire: 65 + - Sammy Sosa: 63 + - Ken Griffy: 58 +ruby: | + YAML::Omap[ + 'Mark McGwire', 65, + 'Sammy Sosa', 63, + 'Ken Griffy', 58 + ] +--- +test: Invoice +dump_skip: true +spec: 2.27 +yaml: | + --- !clarkevans.com,2002/^invoice + invoice: 34843 + date : 2001-01-23 + bill-to: &id001 + given : Chris + family : Dumars + address: + lines: | + 458 Walkman Dr. + Suite #292 + city : Royal Oak + state : MI + postal : 48046 + ship-to: *id001 + product: + - + sku : BL394D + quantity : 4 + description : Basketball + price : 450.00 + - + sku : BL4438H + quantity : 1 + description : Super Hoop + price : 2392.00 + tax : 251.42 + total: 4443.52 + comments: > + Late afternoon is best. + Backup contact is Nancy + Billsmer @ 338-4338. +php: | + [ + 'invoice' => 34843, 'date' => gmmktime(0, 0, 0, 1, 23, 2001), + 'bill-to' => + [ 'given' => 'Chris', 'family' => 'Dumars', 'address' => [ 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ] ] + , 'ship-to' => + [ 'given' => 'Chris', 'family' => 'Dumars', 'address' => [ 'lines' => "458 Walkman Dr.\nSuite #292\n", 'city' => 'Royal Oak', 'state' => 'MI', 'postal' => 48046 ] ] + , 'product' => + [ + [ 'sku' => 'BL394D', 'quantity' => 4, 'description' => 'Basketball', 'price' => 450.00 ], + [ 'sku' => 'BL4438H', 'quantity' => 1, 'description' => 'Super Hoop', 'price' => 2392.00 ] + ], + 'tax' => 251.42, 'total' => 4443.52, + 'comments' => "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.\n" + ] +--- +test: Log file +todo: true +spec: 2.28 +yaml: | + --- + Time: 2001-11-23 15:01:42 -05:00 + User: ed + Warning: > + This is an error message + for the log file + --- + Time: 2001-11-23 15:02:31 -05:00 + User: ed + Warning: > + A slightly different error + message. + --- + Date: 2001-11-23 15:03:17 -05:00 + User: ed + Fatal: > + Unknown variable "bar" + Stack: + - file: TopClass.py + line: 23 + code: | + x = MoreObject("345\n") + - file: MoreClass.py + line: 58 + code: |- + foo = bar +ruby: | + y = YAML::Stream.new + y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 01, 42, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "This is an error message for the log file\n" } ) + y.add( { 'Time' => YAML::mktime( 2001, 11, 23, 15, 02, 31, 00, "-05:00" ), + 'User' => 'ed', 'Warning' => "A slightly different error message.\n" } ) + y.add( { 'Date' => YAML::mktime( 2001, 11, 23, 15, 03, 17, 00, "-05:00" ), + 'User' => 'ed', 'Fatal' => "Unknown variable \"bar\"\n", + 'Stack' => [ + { 'file' => 'TopClass.py', 'line' => 23, 'code' => "x = MoreObject(\"345\\n\")\n" }, + { 'file' => 'MoreClass.py', 'line' => 58, 'code' => "foo = bar" } ] } ) +documents: 3 + +--- +test: Throwaway comments +yaml: | + ### These are four throwaway comment ### + + ### lines (the second line is empty). ### + this: | # Comments may trail lines. + contains three lines of text. + The third one starts with a + # character. This isn't a comment. + + # These are three throwaway comment + # lines (the first line is empty). +php: | + [ + 'this' => "contains three lines of text.\nThe third one starts with a\n# character. This isn't a comment.\n" + ] +--- +test: Document with a single value +todo: true +yaml: | + --- > + This YAML stream contains a single text value. + The next stream is a log file - a sequence of + log entries. Adding an entry to the log is a + simple matter of appending it at the end. +ruby: | + "This YAML stream contains a single text value. The next stream is a log file - a sequence of log entries. Adding an entry to the log is a simple matter of appending it at the end.\n" +--- +test: Document stream +todo: true +yaml: | + --- + at: 2001-08-12 09:25:00.00 Z + type: GET + HTTP: '1.0' + url: '/index.html' + --- + at: 2001-08-12 09:25:10.00 Z + type: GET + HTTP: '1.0' + url: '/toc.html' +ruby: | + y = YAML::Stream.new + y.add( { + 'at' => Time::utc( 2001, 8, 12, 9, 25, 00 ), + 'type' => 'GET', + 'HTTP' => '1.0', + 'url' => '/index.html' + } ) + y.add( { + 'at' => Time::utc( 2001, 8, 12, 9, 25, 10 ), + 'type' => 'GET', + 'HTTP' => '1.0', + 'url' => '/toc.html' + } ) +documents: 2 + +--- +test: Top level mapping +yaml: | + # This stream is an example of a top-level mapping. + invoice : 34843 + date : 2001-01-23 + total : 4443.52 +php: | + [ + 'invoice' => 34843, + 'date' => gmmktime(0, 0, 0, 1, 23, 2001), + 'total' => 4443.52 + ] +--- +test: Single-line documents +todo: true +yaml: | + # The following is a sequence of three documents. + # The first contains an empty mapping, the second + # an empty sequence, and the last an empty string. + --- {} + --- [ ] + --- '' +ruby: | + y = YAML::Stream.new + y.add( {} ) + y.add( [] ) + y.add( '' ) +documents: 3 + +--- +test: Document with pause +todo: true +yaml: | + # A communication channel based on a YAML stream. + --- + sent at: 2002-06-06 11:46:25.10 Z + payload: Whatever + # Receiver can process this as soon as the following is sent: + ... + # Even if the next message is sent long after: + --- + sent at: 2002-06-06 12:05:53.47 Z + payload: Whatever + ... +ruby: | + y = YAML::Stream.new + y.add( + { 'sent at' => YAML::mktime( 2002, 6, 6, 11, 46, 25, 0.10 ), + 'payload' => 'Whatever' } + ) + y.add( + { "payload" => "Whatever", "sent at" => YAML::mktime( 2002, 6, 6, 12, 5, 53, 0.47 ) } + ) +documents: 2 + +--- +test: Explicit typing +deprecated: Using the non-specific tag "!" is deprecated since Symfony 3.4 as its behavior will change in 4.0. +yaml: | + integer: 12 + also int: ! "12" + string: !!str 12 +php: | + [ 'integer' => 12, 'also int' => 12, 'string' => '12' ] +--- +test: Private types +todo: true +yaml: | + # Both examples below make use of the 'x-private:ball' + # type family URI, but with different semantics. + --- + pool: !!ball + number: 8 + color: black + --- + bearing: !!ball + material: steel +ruby: | + y = YAML::Stream.new + y.add( { 'pool' => + YAML::PrivateType.new( 'ball', + { 'number' => 8, 'color' => 'black' } ) } + ) + y.add( { 'bearing' => + YAML::PrivateType.new( 'ball', + { 'material' => 'steel' } ) } + ) +documents: 2 + +--- +test: Type family under yaml.org +yaml: | + # The URI is 'tag:yaml.org,2002:str' + - !!str a Unicode string +php: | + [ 'a Unicode string' ] +--- +test: Type family under perl.yaml.org +todo: true +yaml: | + # The URI is 'tag:perl.yaml.org,2002:Text::Tabs' + - !perl/Text::Tabs {} +ruby: | + [ YAML::DomainType.new( 'perl.yaml.org,2002', 'Text::Tabs', {} ) ] +--- +test: Type family under clarkevans.com +todo: true +yaml: | + # The URI is 'tag:clarkevans.com,2003-02:timesheet' + - !clarkevans.com,2003-02/timesheet {} +ruby: | + [ YAML::DomainType.new( 'clarkevans.com,2003-02', 'timesheet', {} ) ] +--- +test: URI Escaping +todo: true +yaml: | + same: + - !domain.tld,2002/type\x30 value + - !domain.tld,2002/type0 value + different: # As far as the YAML parser is concerned + - !domain.tld,2002/type%30 value + - !domain.tld,2002/type0 value +ruby-setup: | + YAML.add_domain_type( "domain.tld,2002", "type0" ) { |type, val| + "ONE: #{val}" + } + YAML.add_domain_type( "domain.tld,2002", "type%30" ) { |type, val| + "TWO: #{val}" + } +ruby: | + { 'same' => [ 'ONE: value', 'ONE: value' ], 'different' => [ 'TWO: value', 'ONE: value' ] } +--- +test: URI Prefixing +todo: true +yaml: | + # 'tag:domain.tld,2002:invoice' is some type family. + invoice: !domain.tld,2002/^invoice + # 'seq' is shorthand for 'tag:yaml.org,2002:seq'. + # This does not effect '^customer' below + # because it is does not specify a prefix. + customers: !seq + # '^customer' is shorthand for the full + # notation 'tag:domain.tld,2002:customer'. + - !^customer + given : Chris + family : Dumars +ruby-setup: | + YAML.add_domain_type( "domain.tld,2002", /(invoice|customer)/ ) { |type, val| + if val.is_a? ::Hash + scheme, domain, type = type.split( /:/, 3 ) + val['type'] = "domain #{type}" + val + else + raise YAML::Error, "Not a Hash in domain.tld/invoice: " + val.inspect + end + } +ruby: | + { "invoice"=> { "customers"=> [ { "given"=>"Chris", "type"=>"domain customer", "family"=>"Dumars" } ], "type"=>"domain invoice" } } + +--- +test: Overriding anchors +yaml: | + anchor : &A001 This scalar has an anchor. + override : &A001 > + The alias node below is a + repeated use of this value. + alias : *A001 +php: | + [ 'anchor' => 'This scalar has an anchor.', + 'override' => "The alias node below is a repeated use of this value.\n", + 'alias' => "The alias node below is a repeated use of this value.\n"] +--- +test: Flow and block formatting +todo: true +yaml: | + empty: [] + flow: [ one, two, three # May span lines, + , four, # indentation is + five ] # mostly ignored. + block: + - First item in top sequence + - + - Subordinate sequence entry + - > + A folded sequence entry + - Sixth item in top sequence +ruby: | + { 'empty' => [], 'flow' => [ 'one', 'two', 'three', 'four', 'five' ], + 'block' => [ 'First item in top sequence', [ 'Subordinate sequence entry' ], + "A folded sequence entry\n", 'Sixth item in top sequence' ] } +--- +test: Complete mapping test +todo: true +yaml: | + empty: {} + flow: { one: 1, two: 2 } + spanning: { one: 1, + two: 2 } + block: + first : First entry + second: + key: Subordinate mapping + third: + - Subordinate sequence + - { } + - Previous mapping is empty. + - A key: value pair in a sequence. + A second: key:value pair. + - The previous entry is equal to the following one. + - + A key: value pair in a sequence. + A second: key:value pair. + !float 12 : This key is a float. + ? > + ? + : This key had to be protected. + "\a" : This key had to be escaped. + ? > + This is a + multi-line + folded key + : Whose value is + also multi-line. + ? this also works as a key + : with a value at the next line. + ? + - This key + - is a sequence + : + - With a sequence value. + ? + This: key + is a: mapping + : + with a: mapping value. +ruby: | + { 'empty' => {}, 'flow' => { 'one' => 1, 'two' => 2 }, + 'spanning' => { 'one' => 1, 'two' => 2 }, + 'block' => { 'first' => 'First entry', 'second' => + { 'key' => 'Subordinate mapping' }, 'third' => + [ 'Subordinate sequence', {}, 'Previous mapping is empty.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' }, + 'The previous entry is equal to the following one.', + { 'A key' => 'value pair in a sequence.', 'A second' => 'key:value pair.' } ], + 12.0 => 'This key is a float.', "?\n" => 'This key had to be protected.', + "\a" => 'This key had to be escaped.', + "This is a multi-line folded key\n" => "Whose value is also multi-line.", + 'this also works as a key' => 'with a value at the next line.', + [ 'This key', 'is a sequence' ] => [ 'With a sequence value.' ] } } + # Couldn't recreate map exactly, so we'll do a detailed check to be sure it's entact + obj_y['block'].keys.each { |k| + if Hash === k + v = obj_y['block'][k] + if k['This'] == 'key' and k['is a'] == 'mapping' and v['with a'] == 'mapping value.' + obj_r['block'][k] = v + end + end + } +--- +test: Literal explicit indentation +yaml: | + # Explicit indentation must + # be given in all the three + # following cases. + leading spaces: |2 + This value starts with four spaces. + + leading line break: |2 + + This value starts with a line break. + + leading comment indicator: |2 + # first line starts with a + # character. + + # Explicit indentation may + # also be given when it is + # not required. + redundant: |2 + This value is indented 2 spaces. +php: | + [ + 'leading spaces' => " This value starts with four spaces.\n", + 'leading line break' => "\nThis value starts with a line break.\n", + 'leading comment indicator' => "# first line starts with a\n# character.\n", + 'redundant' => "This value is indented 2 spaces.\n" + ] +--- +test: Chomping and keep modifiers +yaml: | + clipped: | + This has one newline. + + same as "clipped" above: "This has one newline.\n" + + stripped: |- + This has no newline. + + same as "stripped" above: "This has no newline." + + kept: |+ + This has two newlines. + + same as "kept" above: "This has two newlines.\n\n" +php: | + [ + 'clipped' => "This has one newline.\n", + 'same as "clipped" above' => "This has one newline.\n", + 'stripped' => 'This has no newline.', + 'same as "stripped" above' => 'This has no newline.', + 'kept' => "This has two newlines.\n\n", + 'same as "kept" above' => "This has two newlines.\n\n" + ] +--- +test: Literal combinations +todo: true +yaml: | + empty: | + + literal: | + The \ ' " characters may be + freely used. Leading white + space is significant. + + Line breaks are significant. + Thus this value contains one + empty line and ends with a + single line break, but does + not start with one. + + is equal to: "The \\ ' \" characters may \ + be\nfreely used. Leading white\n space \ + is significant.\n\nLine breaks are \ + significant.\nThus this value contains \ + one\nempty line and ends with a\nsingle \ + line break, but does\nnot start with one.\n" + + # Comments may follow a block + # scalar value. They must be + # less indented. + + # Modifiers may be combined in any order. + indented and chomped: |2- + This has no newline. + + also written as: |-2 + This has no newline. + + both are equal to: " This has no newline." +php: | + [ + 'empty' => '', + 'literal' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", + 'is equal to' => "The \\ ' \" characters may be\nfreely used. Leading white\n space " + + "is significant.\n\nLine breaks are significant.\nThus this value contains one\n" + + "empty line and ends with a\nsingle line break, but does\nnot start with one.\n", + 'indented and chomped' => ' This has no newline.', + 'also written as' => ' This has no newline.', + 'both are equal to' => ' This has no newline.' + [ +--- +test: Folded combinations +todo: true +yaml: | + empty: > + + one paragraph: > + Line feeds are converted + to spaces, so this value + contains no line breaks + except for the final one. + + multiple paragraphs: >2 + + An empty line, either + at the start or in + the value: + + Is interpreted as a + line break. Thus this + value contains three + line breaks. + + indented text: > + This is a folded + paragraph followed + by a list: + * first entry + * second entry + Followed by another + folded paragraph, + another list: + + * first entry + + * second entry + + And a final folded + paragraph. + + above is equal to: | + This is a folded paragraph followed by a list: + * first entry + * second entry + Followed by another folded paragraph, another list: + + * first entry + + * second entry + + And a final folded paragraph. + + # Explicit comments may follow + # but must be less indented. +php: | + [ + 'empty' => '', + 'one paragraph' => 'Line feeds are converted to spaces, so this value'. + " contains no line breaks except for the final one.\n", + 'multiple paragraphs' => "\nAn empty line, either at the start or in the value:\n". + "Is interpreted as a line break. Thus this value contains three line breaks.\n", + 'indented text' => "This is a folded paragraph followed by a list:\n". + " * first entry\n * second entry\nFollowed by another folded paragraph, ". + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n", + 'above is equal to' => "This is a folded paragraph followed by a list:\n". + " * first entry\n * second entry\nFollowed by another folded paragraph, ". + "another list:\n\n * first entry\n\n * second entry\n\nAnd a final folded paragraph.\n" + ] +--- +test: Single quotes +todo: true +yaml: | + empty: '' + second: '! : \ etc. can be used freely.' + third: 'a single quote '' must be escaped.' + span: 'this contains + six spaces + + and one + line break' + is same as: "this contains six spaces\nand one line break" +php: | + [ + 'empty' => '', + 'second' => '! : \\ etc. can be used freely.', + 'third' => "a single quote ' must be escaped.", + 'span' => "this contains six spaces\nand one line break", + 'is same as' => "this contains six spaces\nand one line break" + ] +--- +test: Double quotes +todo: true +yaml: | + empty: "" + second: "! : etc. can be used freely." + third: "a \" or a \\ must be escaped." + fourth: "this value ends with an LF.\n" + span: "this contains + four \ + spaces" + is equal to: "this contains four spaces" +php: | + [ + 'empty' => '', + 'second' => '! : etc. can be used freely.', + 'third' => 'a " or a \\ must be escaped.', + 'fourth' => "this value ends with an LF.\n", + 'span' => "this contains four spaces", + 'is equal to' => "this contains four spaces" + ] +--- +test: Unquoted strings +todo: true +yaml: | + first: There is no unquoted empty string. + + second: 12 ## This is an integer. + + third: !!str 12 ## This is a string. + + span: this contains + six spaces + + and one + line break + + indicators: this has no comments. + #:foo and bar# are + both text. + + flow: [ can span + lines, # comment + like + this ] + + note: { one-line keys: but multi-line values } + +php: | + [ + 'first' => 'There is no unquoted empty string.', + 'second' => 12, + 'third' => '12', + 'span' => "this contains six spaces\nand one line break", + 'indicators' => "this has no comments. #:foo and bar# are both text.", + 'flow' => [ 'can span lines', 'like this' ], + 'note' => { 'one-line keys' => 'but multi-line values' } + ] +--- +test: Spanning sequences +todo: true +yaml: | + # The following are equal seqs + # with different identities. + flow: [ one, two ] + spanning: [ one, + two ] + block: + - one + - two +php: | + [ + 'flow' => [ 'one', 'two' ], + 'spanning' => [ 'one', 'two' ], + 'block' => [ 'one', 'two' ] + ] +--- +test: Flow mappings +yaml: | + # The following are equal maps + # with different identities. + flow: { one: 1, two: 2 } + block: + one: 1 + two: 2 +php: | + [ + 'flow' => [ 'one' => 1, 'two' => 2 ], + 'block' => [ 'one' => 1, 'two' => 2 ] + ] +--- +test: Representations of 12 +todo: true +yaml: | + - 12 # An integer + # The following scalars + # are loaded to the + # string value '1' '2'. + - !!str 12 + - '12' + - "12" + - "\ + 1\ + 2\ + " + # Strings containing paths and regexps can be unquoted: + - /foo/bar + - d:/foo/bar + - foo/bar + - /a.*b/ +php: | + [ 12, '12', '12', '12', '12', '/foo/bar', 'd:/foo/bar', 'foo/bar', '/a.*b/' ] +--- +test: "Null" +todo: true +yaml: | + canonical: ~ + + english: null + + # This sequence has five + # entries, two with values. + sparse: + - ~ + - 2nd entry + - Null + - 4th entry + - + + four: This mapping has five keys, + only two with values. + +php: | + [ + 'canonical' => null, + 'english' => null, + 'sparse' => [ null, '2nd entry', null, '4th entry', null ]], + 'four' => 'This mapping has five keys, only two with values.' + ] +--- +test: Omap +todo: true +yaml: | + # Explicitly typed dictionary. + Bestiary: !omap + - aardvark: African pig-like ant eater. Ugly. + - anteater: South-American ant eater. Two species. + - anaconda: South-American constrictor snake. Scary. + # Etc. +ruby: | + { + 'Bestiary' => YAML::Omap[ + 'aardvark', 'African pig-like ant eater. Ugly.', + 'anteater', 'South-American ant eater. Two species.', + 'anaconda', 'South-American constrictor snake. Scary.' + ] + } + +--- +test: Pairs +todo: true +yaml: | + # Explicitly typed pairs. + tasks: !pairs + - meeting: with team. + - meeting: with boss. + - break: lunch. + - meeting: with client. +ruby: | + { + 'tasks' => YAML::Pairs[ + 'meeting', 'with team.', + 'meeting', 'with boss.', + 'break', 'lunch.', + 'meeting', 'with client.' + ] + } + +--- +test: Set +todo: true +yaml: | + # Explicitly typed set. + baseball players: !set + Mark McGwire: + Sammy Sosa: + Ken Griffey: +ruby: | + { + 'baseball players' => YAML::Set[ + 'Mark McGwire', nil, + 'Sammy Sosa', nil, + 'Ken Griffey', nil + ] + } + +--- +test: Integer +yaml: | + canonical: 12345 + octal: 014 + hexadecimal: 0xC +php: | + [ + 'canonical' => 12345, + 'octal' => 12, + 'hexadecimal' => 12 + ] +--- +test: Decimal +deprecated: true +yaml: | + decimal: +12,345 +php: | + [ + 'decimal' => 12345.0, + ] +--- +test: Fixed Float +deprecated: true +yaml: | + fixed: 1,230.15 +php: | + [ + 'fixed' => 1230.15, + ] +--- +test: Float +yaml: | + canonical: 1.23015e+3 + exponential: 12.3015e+02 + negative infinity: -.inf + not a number: .NaN +php: | + [ + 'canonical' => 1230.15, + 'exponential' => 1230.15, + 'negative infinity' => log(0), + 'not a number' => -log(0) + ] +--- +test: Timestamp +todo: true +yaml: | + canonical: 2001-12-15T02:59:43.1Z + valid iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 + date (noon UTC): 2002-12-14 +ruby: | + [ + 'canonical' => YAML::mktime( 2001, 12, 15, 2, 59, 43, 0.10 ), + 'valid iso8601' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'space separated' => YAML::mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'date (noon UTC)' => Date.new( 2002, 12, 14 ) + ] +--- +test: Binary +todo: true +yaml: | + canonical: !binary "\ + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\ + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\ + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=" + base64: !binary | + R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 + OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+ + +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC + AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= + description: > + The binary value above is a tiny arrow + encoded as a gif image. +ruby-setup: | + arrow_gif = "GIF89a\f\000\f\000\204\000\000\377\377\367\365\365\356\351\351\345fff\000\000\000\347\347\347^^^\363\363\355\216\216\216\340\340\340\237\237\237\223\223\223\247\247\247\236\236\236iiiccc\243\243\243\204\204\204\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371\377\376\371!\376\016Made with GIMP\000,\000\000\000\000\f\000\f\000\000\005, \216\2010\236\343@\024\350i\020\304\321\212\010\034\317\200M$z\357\3770\205p\270\2601f\r\e\316\001\303\001\036\020' \202\n\001\000;" +ruby: | + { + 'canonical' => arrow_gif, + 'base64' => arrow_gif, + 'description' => "The binary value above is a tiny arrow encoded as a gif image.\n" + } + +--- +test: Merge key +todo: true +yaml: | + --- + - &CENTER { x: 1, y: 2 } + - &LEFT { x: 0, y: 2 } + - &BIG { r: 10 } + - &SMALL { r: 1 } + + # All the following maps are equal: + + - # Explicit keys + x: 1 + y: 2 + r: 10 + label: center/big + + - # Merge one map + << : *CENTER + r: 10 + label: center/big + + - # Merge multiple maps + << : [ *CENTER, *BIG ] + label: center/big + + - # Override + << : [ *BIG, *LEFT, *SMALL ] + x: 1 + label: center/big + +ruby-setup: | + center = { 'x' => 1, 'y' => 2 } + left = { 'x' => 0, 'y' => 2 } + big = { 'r' => 10 } + small = { 'r' => 1 } + node1 = { 'x' => 1, 'y' => 2, 'r' => 10, 'label' => 'center/big' } + node2 = center.dup + node2.update( { 'r' => 10, 'label' => 'center/big' } ) + node3 = big.dup + node3.update( center ) + node3.update( { 'label' => 'center/big' } ) + node4 = small.dup + node4.update( left ) + node4.update( big ) + node4.update( { 'x' => 1, 'label' => 'center/big' } ) + +ruby: | + [ + center, left, big, small, node1, node2, node3, node4 + ] + +--- +test: Default key +todo: true +yaml: | + --- # Old schema + link with: + - library1.dll + - library2.dll + --- # New schema + link with: + - = : library1.dll + version: 1.2 + - = : library2.dll + version: 2.3 +ruby: | + y = YAML::Stream.new + y.add( { 'link with' => [ 'library1.dll', 'library2.dll' ] } ) + obj_h = Hash[ 'version' => 1.2 ] + obj_h.default = 'library1.dll' + obj_h2 = Hash[ 'version' => 2.3 ] + obj_h2.default = 'library2.dll' + y.add( { 'link with' => [ obj_h, obj_h2 ] } ) +documents: 2 + +--- +test: Special keys +todo: true +yaml: | + "!": These three keys + "&": had to be quoted + "=": and are normal strings. + # NOTE: the following node should NOT be serialized this way. + encoded node : + !special '!' : '!type' + !special|canonical '&' : 12 + = : value + # The proper way to serialize the above node is as follows: + node : !!type &12 value +ruby: | + { '!' => 'These three keys', '&' => 'had to be quoted', + '=' => 'and are normal strings.', + 'encoded node' => YAML::PrivateType.new( 'type', 'value' ), + 'node' => YAML::PrivateType.new( 'type', 'value' ) } diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml new file mode 100644 index 00000000..e96b5536 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/YtsTypeTransfers.yml @@ -0,0 +1,266 @@ +--- %YAML:1.0 +test: Strings +brief: > + Any group of characters beginning with an + alphabetic or numeric character is a string, + unless it belongs to one of the groups below + (such as an Integer or Time). +yaml: | + String +php: | + 'String' +--- +test: String characters +brief: > + A string can contain any alphabetic or + numeric character, along with many + punctuation characters, including the + period, dash, space, quotes, exclamation, and + question mark. +yaml: | + - What's Yaml? + - It's for writing data structures in plain text. + - And? + - And what? That's not good enough for you? + - No, I mean, "And what about Yaml?" + - Oh, oh yeah. Uh.. Yaml for Ruby. +php: | + [ + "What's Yaml?", + "It's for writing data structures in plain text.", + "And?", + "And what? That's not good enough for you?", + "No, I mean, \"And what about Yaml?\"", + "Oh, oh yeah. Uh.. Yaml for Ruby." + ] +--- +test: Indicators in Strings +brief: > + Be careful using indicators in strings. In particular, + the comma, colon, and pound sign must be used carefully. +yaml: | + the colon followed by space is an indicator: but is a string:right here + same for the pound sign: here we have it#in a string + the comma can, honestly, be used in most cases: [ but not in, inline collections ] +php: | + [ + 'the colon followed by space is an indicator' => 'but is a string:right here', + 'same for the pound sign' => 'here we have it#in a string', + 'the comma can, honestly, be used in most cases' => ['but not in', 'inline collections'] + ] +--- +test: Forcing Strings +brief: > + Any YAML type can be forced into a string using the + explicit !!str method. +yaml: | + date string: !!str 2001-08-01 + number string: !!str 192 +php: | + [ + 'date string' => '2001-08-01', + 'number string' => '192' + ] +--- +test: Single-quoted Strings +brief: > + You can also enclose your strings within single quotes, + which allows use of slashes, colons, and other indicators + freely. Inside single quotes, you can represent a single + quote in your string by using two single quotes next to + each other. +yaml: | + all my favorite symbols: '#:!/%.)' + a few i hate: '&(*' + why do i hate them?: 'it''s very hard to explain' + entities: '£ me' +php: | + [ + 'all my favorite symbols' => '#:!/%.)', + 'a few i hate' => '&(*', + 'why do i hate them?' => 'it\'s very hard to explain', + 'entities' => '£ me' + ] +--- +test: Double-quoted Strings +brief: > + Enclosing strings in double quotes allows you + to use escapings to represent ASCII and + Unicode characters. +yaml: | + i know where i want my line breaks: "one here\nand another here\n" +php: | + [ + 'i know where i want my line breaks' => "one here\nand another here\n" + ] +--- +test: Multi-line Quoted Strings +todo: true +brief: > + Both single- and double-quoted strings may be + carried on to new lines in your YAML document. + They must be indented a step and indentation + is interpreted as a single space. +yaml: | + i want a long string: "so i'm going to + let it go on and on to other lines + until i end it with a quote." +php: | + ['i want a long string' => "so i'm going to ". + "let it go on and on to other lines ". + "until i end it with a quote." + ] + +--- +test: Plain scalars +todo: true +brief: > + Unquoted strings may also span multiple lines, if they + are free of YAML space indicators and indented. +yaml: | + - My little toe is broken in two places; + - I'm crazy to have skied this way; + - I'm not the craziest he's seen, since there was always the German guy + who skied for 3 hours on a broken shin bone (just below the kneecap); + - Nevertheless, second place is respectable, and he doesn't + recommend going for the record; + - He's going to put my foot in plaster for a month; + - This would impair my skiing ability somewhat for the + duration, as can be imagined. +php: | + [ + "My little toe is broken in two places;", + "I'm crazy to have skied this way;", + "I'm not the craziest he's seen, since there was always ". + "the German guy who skied for 3 hours on a broken shin ". + "bone (just below the kneecap);", + "Nevertheless, second place is respectable, and he doesn't ". + "recommend going for the record;", + "He's going to put my foot in plaster for a month;", + "This would impair my skiing ability somewhat for the duration, ". + "as can be imagined." + ] +--- +test: 'Null' +brief: > + You can use the tilde '~' character for a null value. +yaml: | + name: Mr. Show + hosted by: Bob and David + date of next season: ~ +php: | + [ + 'name' => 'Mr. Show', + 'hosted by' => 'Bob and David', + 'date of next season' => null + ] +--- +test: Boolean +brief: > + You can use 'true' and 'false' for Boolean values. +yaml: | + Is Gus a Liar?: true + Do I rely on Gus for Sustenance?: false +php: | + [ + 'Is Gus a Liar?' => true, + 'Do I rely on Gus for Sustenance?' => false + ] +--- +test: Integers +dump_skip: true +brief: > + An integer is a series of numbers, optionally + starting with a positive or negative sign. Integers + may also contain commas for readability. +yaml: | + zero: 0 + simple: 12 +php: | + [ + 'zero' => 0, + 'simple' => 12, + ] +--- +test: Positive Big Integer +deprecated: true +dump_skip: true +brief: > + An integer is a series of numbers, optionally + starting with a positive or negative sign. Integers + may also contain commas for readability. +yaml: | + one-thousand: 1,000 +php: | + [ + 'one-thousand' => 1000.0, + ] +--- +test: Negative Big Integer +deprecated: true +dump_skip: true +brief: > + An integer is a series of numbers, optionally + starting with a positive or negative sign. Integers + may also contain commas for readability. +yaml: | + negative one-thousand: -1,000 +php: | + [ + 'negative one-thousand' => -1000.0 + ] +--- +test: Floats +dump_skip: true +brief: > + Floats are represented by numbers with decimals, + allowing for scientific notation, as well as + positive and negative infinity and "not a number." +yaml: | + a simple float: 2.00 + scientific notation: 1.00009e+3 +php: | + [ + 'a simple float' => 2.0, + 'scientific notation' => 1000.09 + ] +--- +test: Larger Float +dump_skip: true +deprecated: true +brief: > + Floats are represented by numbers with decimals, + allowing for scientific notation, as well as + positive and negative infinity and "not a number." +yaml: | + larger float: 1,000.09 +php: | + [ + 'larger float' => 1000.09, + ] +--- +test: Time +todo: true +brief: > + You can represent timestamps by using + ISO8601 format, or a variation which + allows spaces between the date, time and + time zone. +yaml: | + iso8601: 2001-12-14t21:59:43.10-05:00 + space separated: 2001-12-14 21:59:43.10 -05:00 +php: | + [ + 'iso8601' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ), + 'space separated' => mktime( 2001, 12, 14, 21, 59, 43, 0.10, "-05:00" ) + ] +--- +test: Date +todo: true +brief: > + A date can be represented by its year, + month and day in ISO8601 order. +yaml: | + 1976-07-31 +php: | + date( 1976, 7, 31 ) diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/arrow.gif b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/arrow.gif new file mode 100644 index 00000000..443aca42 Binary files /dev/null and b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/arrow.gif differ diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml new file mode 100644 index 00000000..88287f1b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/booleanMappingKeys.yml @@ -0,0 +1,11 @@ +--- %YAML:1.0 +test: Miscellaneous +spec: 2.21 +yaml: | + true: true + false: false +php: | + [ + 'true' => true, + 'false' => false, + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml new file mode 100644 index 00000000..ec456ed0 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/embededPhp.yml @@ -0,0 +1 @@ +value: diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml new file mode 100644 index 00000000..87d352db --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/escapedCharacters.yml @@ -0,0 +1,155 @@ +test: outside double quotes +yaml: | + \0 \ \a \b \n +php: | + "\\0 \\ \\a \\b \\n" +--- +test: 'null' +yaml: | + "\0" +php: | + "\x00" +--- +test: bell +yaml: | + "\a" +php: | + "\x07" +--- +test: backspace +yaml: | + "\b" +php: | + "\x08" +--- +test: horizontal tab (1) +yaml: | + "\t" +php: | + "\x09" +--- +test: horizontal tab (2) +yaml: | + "\ " +php: | + "\x09" +--- +test: line feed +yaml: | + "\n" +php: | + "\x0a" +--- +test: vertical tab +yaml: | + "\v" +php: | + "\x0b" +--- +test: form feed +yaml: | + "\f" +php: | + "\x0c" +--- +test: carriage return +yaml: | + "\r" +php: | + "\x0d" +--- +test: escape +yaml: | + "\e" +php: | + "\x1b" +--- +test: space +yaml: | + "\ " +php: | + "\x20" +--- +test: slash +yaml: | + "\/" +php: | + "\x2f" +--- +test: backslash +yaml: | + "\\" +php: | + "\\" +--- +test: Unicode next line +yaml: | + "\N" +php: | + "\xc2\x85" +--- +test: Unicode non-breaking space +yaml: | + "\_" +php: | + "\xc2\xa0" +--- +test: Unicode line separator +yaml: | + "\L" +php: | + "\xe2\x80\xa8" +--- +test: Unicode paragraph separator +yaml: | + "\P" +php: | + "\xe2\x80\xa9" +--- +test: Escaped 8-bit Unicode +yaml: | + "\x42" +php: | + "B" +--- +test: Escaped 16-bit Unicode +yaml: | + "\u20ac" +php: | + "\xe2\x82\xac" +--- +test: Escaped 32-bit Unicode +yaml: | + "\U00000043" +php: | + "C" +--- +test: Example 5.13 Escaped Characters +note: | + Currently throws an error parsing first line. Maybe Symfony Yaml doesn't support + continuation of string across multiple lines? Keeping test here but disabled. +todo: true +yaml: | + "Fun with \\ + \" \a \b \e \f \ + \n \r \t \v \0 \ + \ \_ \N \L \P \ + \x41 \u0041 \U00000041" +php: | + "Fun with \x5C\n\x22 \x07 \x08 \x1B \x0C\n\x0A \x0D \x09 \x0B \x00\n\x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9\nA A A" +--- +test: Double quotes with a line feed +yaml: | + { double: "some value\n \"some quoted string\" and 'some single quotes one'" } +php: | + [ + 'double' => "some value\n \"some quoted string\" and 'some single quotes one'" + ] +--- +test: Backslashes +yaml: | + { single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" } +php: | + [ + 'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var' + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/index.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/index.yml new file mode 100644 index 00000000..3216a89e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/index.yml @@ -0,0 +1,18 @@ +- escapedCharacters +- sfComments +- sfCompact +- sfTests +- sfObjects +- sfMergeKey +- sfQuotes +- YtsAnchorAlias +- YtsBasicTests +- YtsBlockMapping +- YtsDocumentSeparator +- YtsErrorTests +- YtsFlowCollections +- YtsFoldedScalars +- YtsNullsAndEmpties +- YtsSpecificationExamples +- YtsTypeTransfers +- unindentedCollections diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyBooleanMappingKeys.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyBooleanMappingKeys.yml new file mode 100644 index 00000000..db950165 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyBooleanMappingKeys.yml @@ -0,0 +1,23 @@ +--- %YAML:1.0 +test: Miscellaneous +spec: 2.21 +yaml: | + true: true + false: false +php: | + [ + 1 => true, + 0 => false, + ] +--- +test: Boolean +yaml: | + false: used as key + logical: true + answer: false +php: | + [ + false => 'used as key', + 'logical' => true, + 'answer' => false + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyNonStringKeys.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyNonStringKeys.yml new file mode 100644 index 00000000..4e282018 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyNonStringKeys.yml @@ -0,0 +1,2 @@ +- legacyBooleanMappingKeys +- legacyNullMappingKey diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyNullMappingKey.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyNullMappingKey.yml new file mode 100644 index 00000000..14f93c2d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/legacyNullMappingKey.yml @@ -0,0 +1,9 @@ +--- %YAML:1.0 +test: Miscellaneous +spec: 2.21 +yaml: | + null: ~ +php: | + [ + '' => null, + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml new file mode 100644 index 00000000..9d72f09b --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block.yml @@ -0,0 +1,14 @@ +data: + single_line: 'foo bar baz' + multi_line: | + foo + line with trailing spaces: + + bar + integer like line: + 123456789 + empty line: + + baz + multi_line_with_carriage_return: "foo\nbar\r\nbaz" + nested_inlined_multi_line_string: { inlined_multi_line: "foo\nbar\r\nempty line:\n\nbaz" } diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_for_tagged_values.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_for_tagged_values.yml new file mode 100644 index 00000000..f8c9112f --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_for_tagged_values.yml @@ -0,0 +1,2 @@ +data: + foo: !bar "foo\r\nline with trailing spaces:\n \nbar\ninteger like line:\n123456789\nempty line:\n\nbaz" diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml new file mode 100644 index 00000000..3f2dedd1 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/multiple_lines_as_literal_block_leading_space_in_first_line.yml @@ -0,0 +1,4 @@ +data: + multi_line: |4 + the first line has leading spaces + The second line does not. diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml new file mode 100644 index 00000000..354b0791 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/nonStringKeys.yml @@ -0,0 +1,3 @@ +- booleanMappingKeys +- numericMappingKeys +- nullMappingKey diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml new file mode 100644 index 00000000..3216a89e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/not_readable.yml @@ -0,0 +1,18 @@ +- escapedCharacters +- sfComments +- sfCompact +- sfTests +- sfObjects +- sfMergeKey +- sfQuotes +- YtsAnchorAlias +- YtsBasicTests +- YtsBlockMapping +- YtsDocumentSeparator +- YtsErrorTests +- YtsFlowCollections +- YtsFoldedScalars +- YtsNullsAndEmpties +- YtsSpecificationExamples +- YtsTypeTransfers +- unindentedCollections diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml new file mode 100644 index 00000000..cd90f7b4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/nullMappingKey.yml @@ -0,0 +1,9 @@ +--- %YAML:1.0 +test: Miscellaneous +spec: 2.21 +yaml: | + null: ~ +php: | + [ + 'null' => null, + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml new file mode 100644 index 00000000..246447e4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/numericMappingKeys.yml @@ -0,0 +1,23 @@ +--- %YAML:1.0 +test: A sequence with an unordered array +brief: > + A sequence with an unordered array +yaml: | + 1: foo + 0: bar +php: | + [1 => 'foo', 0 => 'bar'] +--- +test: Integers as Map Keys +brief: > + An integer can be used as dictionary key. +yaml: | + 1: one + 2: two + 3: three +php: | + [ + 1 => 'one', + 2 => 'two', + 3 => 'three' + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml new file mode 100644 index 00000000..4b0c91c9 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfComments.yml @@ -0,0 +1,90 @@ +--- %YAML:1.0 +test: Comments at the end of a line +brief: > + Comments at the end of a line +yaml: | + ex1: "foo # bar" + ex2: "foo # bar" # comment + ex3: 'foo # bar' # comment + ex4: foo # comment + ex5: foo # comment with tab before + ex6: foo#foo # comment here + ex7: foo # ignore me # and me +php: | + ['ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo', 'ex5' => 'foo', 'ex6' => 'foo#foo', 'ex7' => 'foo'] +--- +test: Comments in the middle +brief: > + Comments in the middle +yaml: | + foo: + # some comment + # some comment + bar: foo + # some comment + # some comment +php: | + ['foo' => ['bar' => 'foo']] +--- +test: Comments on a hash line +brief: > + Comments on a hash line +yaml: | + foo: # a comment + foo: bar # a comment +php: | + ['foo' => ['foo' => 'bar']] +--- +test: 'Value starting with a #' +brief: > + 'Value starting with a #' +yaml: | + foo: '#bar' +php: | + ['foo' => '#bar'] +--- +test: Document starting with a comment and a separator +brief: > + Commenting before document start is allowed +yaml: | + # document comment + --- + foo: bar # a comment +php: | + ['foo' => 'bar'] +--- +test: Comment containing a colon on a hash line +brief: > + Comment containing a colon on a scalar line +yaml: 'foo # comment: this is also part of the comment' +php: | + 'foo' +--- +test: 'Hash key containing a #' +brief: > + 'Hash key containing a #' +yaml: 'foo#bar: baz' +php: | + ['foo#bar' => 'baz'] +--- +test: 'Hash key ending with a space and a #' +brief: > + 'Hash key ending with a space and a #' +yaml: | + 'foo #': baz +php: | + ['foo #' => 'baz'] +--- +test: Comment before first item in unindented collection +brief: > + Comment directly before unindented collection is allowed +yaml: | + collection1: + # comment + - a + - b + collection2: + - a + - b +php: | + ['collection1' => ['a', 'b'], 'collection2' => ['a', 'b']] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml new file mode 100644 index 00000000..8cadae2c --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfCompact.yml @@ -0,0 +1,159 @@ +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + [ + [ + 'item' => 'Super Hoop', + ], + [ + 'item' => 'Basketball', + 'quantity' => 1, + ], + [ + 'item' => [ + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ], + 'quantity' => 1 + ] + ] +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + [ + 'items' => [ + [ + 'item' => 'Super Hoop', + 'quantity' => 1, + ], + [ + 'Basketball', + 'Big Shoes' + ] + ] + ] +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + [ + [ + 'item' => 'Super Hoop', + ], + [ + 'item' => 'Basketball', + 'quantity' => 1, + ], + [ + 'item' => [ + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ], + 'quantity' => 1 + ] + ] +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + [ + 'items' => [ + [ + 'item' => 'Super Hoop', + 'quantity' => 1, + ], + [ + 'Basketball', + 'Big Shoes' + ] + ] + ] +--- %YAML:1.0 +test: Compact notation +brief: | + Compact notation for sets of mappings with single element +yaml: | + --- + # products purchased + - item : Super Hoop + - item : Basketball + quantity: 1 + - item: + name: Big Shoes + nick: Biggies + quantity: 1 +php: | + [ + [ + 'item' => 'Super Hoop', + ], + [ + 'item' => 'Basketball', + 'quantity' => 1, + ], + [ + 'item' => [ + 'name' => 'Big Shoes', + 'nick' => 'Biggies' + ], + 'quantity' => 1 + ] + ] +--- +test: Compact notation combined with inline notation +brief: | + Combinations of compact and inline notation are allowed +yaml: | + --- + items: + - { item: Super Hoop, quantity: 1 } + - [ Basketball, Big Shoes ] +php: | + [ + 'items' => [ + [ + 'item' => 'Super Hoop', + 'quantity' => 1, + ], + [ + 'Basketball', + 'Big Shoes' + ] + ] + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml new file mode 100644 index 00000000..af787ae4 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfMergeKey.yml @@ -0,0 +1,61 @@ +--- %YAML:1.0 +test: Simple In Place Substitution +brief: > + If you want to reuse an entire alias, only overwriting what is different + you can use a << in place substitution. This is not part of the official + YAML spec, but a widely implemented extension. See the following URL for + details: http://yaml.org/type/merge.html +yaml: | + foo: &foo + a: Steve + b: Clark + c: Brian + e: notnull + bar: + a: before + d: other + e: ~ + <<: *foo + b: new + x: Oren + c: + foo: bar + bar: foo + bar_inline: {a: before, d: other, <<: *foo, b: new, x: Oren, c: { foo: bar, bar: foo}} + foo2: &foo2 + a: Ballmer + ding: &dong [ fi, fei, fo, fam] + check: + <<: + - *foo + - *dong + isit: tested + head: + <<: [ *foo , *dong , *foo2 ] + taz: &taz + a: Steve + w: + p: 1234 + nested: + <<: *taz + d: Doug + w: &nestedref + p: 12345 + z: + <<: *nestedref + head_inline: &head_inline { <<: [ *foo , *dong , *foo2 ] } + recursive_inline: { <<: *head_inline, c: { <<: *foo2 } } +php: | + [ + 'foo' => ['a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull'], + 'bar' => ['a' => 'before', 'd' => 'other', 'e' => null, 'b' => 'new', 'c' => ['foo' => 'bar', 'bar' => 'foo'], 'x' => 'Oren'], + 'bar_inline' => ['a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => ['foo' => 'bar', 'bar' => 'foo'], 'e' => 'notnull', 'x' => 'Oren'], + 'foo2' => ['a' => 'Ballmer'], + 'ding' => ['fi', 'fei', 'fo', 'fam'], + 'check' => ['a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'], + 'head' => ['a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'], + 'taz' => ['a' => 'Steve', 'w' => ['p' => 1234]], + 'nested' => ['a' => 'Steve', 'w' => ['p' => 12345], 'd' => 'Doug', 'z' => ['p' => 12345]], + 'head_inline' => ['a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'], + 'recursive_inline' => ['a' => 'Steve', 'b' => 'Clark', 'c' => ['a' => 'Ballmer'], 'e' => 'notnull', 'fi', 'fei', 'fo', 'fam'], + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml new file mode 100644 index 00000000..144615f2 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfObjects.yml @@ -0,0 +1,11 @@ +--- %YAML:1.0 +test: Objects +brief: > + Comments at the end of a line +yaml: | + ex1: "foo # bar" + ex2: "foo # bar" # comment + ex3: 'foo # bar' # comment + ex4: foo # comment +php: | + ['ex1' => 'foo # bar', 'ex2' => 'foo # bar', 'ex3' => 'foo # bar', 'ex4' => 'foo'] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml new file mode 100644 index 00000000..c8326fdb --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfQuotes.yml @@ -0,0 +1,33 @@ +--- %YAML:1.0 +test: Some characters at the beginning of a string must be escaped +brief: > + Some characters at the beginning of a string must be escaped +yaml: | + foo: '| bar' +php: | + ['foo' => '| bar'] +--- +test: A key can be a quoted string +brief: > + A key can be a quoted string +yaml: | + "foo1": bar + 'foo2': bar + "foo \" bar": bar + 'foo '' bar': bar + 'foo3: ': bar + "foo4: ": bar + foo5: { "foo \" bar: ": bar, 'foo '' bar: ': bar } +php: | + [ + 'foo1' => 'bar', + 'foo2' => 'bar', + 'foo " bar' => 'bar', + 'foo \' bar' => 'bar', + 'foo3: ' => 'bar', + 'foo4: ' => 'bar', + 'foo5' => [ + 'foo " bar: ' => 'bar', + 'foo \' bar: ' => 'bar', + ], + ] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml new file mode 100644 index 00000000..2ea417a7 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/sfTests.yml @@ -0,0 +1,140 @@ +--- %YAML:1.0 +test: Multiple quoted string on one line +brief: > + Multiple quoted string on one line +yaml: | + stripped_title: { name: "foo bar", help: "bar foo" } +php: | + ['stripped_title' => ['name' => 'foo bar', 'help' => 'bar foo']] +--- +test: Empty sequence +yaml: | + foo: [ ] +php: | + ['foo' => []] +--- +test: Empty value +yaml: | + foo: +php: | + ['foo' => null] +--- +test: Inline string parsing +brief: > + Inline string parsing +yaml: | + test: ['complex: string', 'another [string]'] +php: | + ['test' => ['complex: string', 'another [string]']] +--- +test: Boolean +brief: > + Boolean +yaml: | + - false + - true + - null + - ~ + - 'false' + - 'true' + - 'null' + - '~' +php: | + [ + false, + true, + null, + null, + 'false', + 'true', + 'null', + '~', + ] +--- +test: Empty lines in literal blocks +brief: > + Empty lines in literal blocks +yaml: | + foo: + bar: | + foo + + + + bar +php: | + ['foo' => ['bar' => "foo\n\n\n \nbar\n"]] +--- +test: Empty lines in folded blocks +brief: > + Empty lines in folded blocks +yaml: | + foo: + bar: > + + foo + + + bar +php: | + ['foo' => ['bar' => "\nfoo\n\nbar\n"]] +--- +test: IP addresses +brief: > + IP addresses +yaml: | + foo: 10.0.0.2 +php: | + ['foo' => '10.0.0.2'] +--- +test: A sequence with an embedded mapping +brief: > + A sequence with an embedded mapping +yaml: | + - foo + - bar: { bar: foo } +php: | + ['foo', ['bar' => ['bar' => 'foo']]] +--- +test: Octal +brief: as in spec example 2.19, octal value is converted +yaml: | + foo: 0123 +php: | + ['foo' => 83] +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: "0123" +php: | + ['foo' => '0123'] +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: '0123' +php: | + ['foo' => '0123'] +--- +test: Octal strings +brief: Octal notation in a string must remain a string +yaml: | + foo: | + 0123 +php: | + ['foo' => "0123\n"] +--- +test: Document as a simple hash +brief: Document as a simple hash +yaml: | + { foo: bar } +php: | + ['foo' => 'bar'] +--- +test: Document as a simple array +brief: Document as a simple array +yaml: | + [ foo, bar ] +php: | + ['foo', 'bar'] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml new file mode 100644 index 00000000..c85952df --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/Fixtures/unindentedCollections.yml @@ -0,0 +1,82 @@ +--- %YAML:1.0 +test: Unindented collection +brief: > + Unindented collection +yaml: | + collection: + - item1 + - item2 + - item3 +php: | + ['collection' => ['item1', 'item2', 'item3']] +--- +test: Nested unindented collection (two levels) +brief: > + Nested unindented collection +yaml: | + collection: + key: + - a + - b + - c +php: | + ['collection' => ['key' => ['a', 'b', 'c']]] +--- +test: Nested unindented collection (three levels) +brief: > + Nested unindented collection +yaml: | + collection: + key: + subkey: + - one + - two + - three +php: | + ['collection' => ['key' => ['subkey' => ['one', 'two', 'three']]]] +--- +test: Key/value after unindented collection (1) +brief: > + Key/value after unindented collection (1) +yaml: | + collection: + key: + - a + - b + - c + foo: bar +php: | + ['collection' => ['key' => ['a', 'b', 'c']], 'foo' => 'bar'] +--- +test: Key/value after unindented collection (at the same level) +brief: > + Key/value after unindented collection +yaml: | + collection: + key: + - a + - b + - c + foo: bar +php: | + ['collection' => ['key' => ['a', 'b', 'c'], 'foo' => 'bar']] +--- +test: Shortcut Key after unindented collection +brief: > + Key/value after unindented collection +yaml: | + collection: + - key: foo + foo: bar +php: | + ['collection' => [['key' => 'foo', 'foo' => 'bar']]] +--- +test: Shortcut Key after unindented collection with custom spaces +brief: > + Key/value after unindented collection +yaml: | + collection: + - key: foo + foo: bar +php: | + ['collection' => [['key' => 'foo', 'foo' => 'bar']]] diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/InlineTest.php b/modules/empikmarketplace/vendor/symfony/yaml/Tests/InlineTest.php new file mode 100644 index 00000000..f64cc682 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/InlineTest.php @@ -0,0 +1,873 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Exception\ParseException; +use Symfony\Component\Yaml\Inline; +use Symfony\Component\Yaml\Yaml; + +class InlineTest extends TestCase +{ + protected function setUp() + { + Inline::initialize(0, 0); + } + + /** + * @dataProvider getTestsForParse + */ + public function testParse($yaml, $value, $flags = 0) + { + $this->assertSame($value, Inline::parse($yaml, $flags), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml)); + } + + /** + * @dataProvider getTestsForParseWithMapObjects + */ + public function testParseWithMapObjects($yaml, $value, $flags = Yaml::PARSE_OBJECT_FOR_MAP) + { + $actual = Inline::parse($yaml, $flags); + + $this->assertSame(serialize($value), serialize($actual)); + } + + /** + * @dataProvider getTestsForParsePhpConstants + */ + public function testParsePhpConstants($yaml, $value) + { + $actual = Inline::parse($yaml, Yaml::PARSE_CONSTANT); + + $this->assertSame($value, $actual); + } + + public function getTestsForParsePhpConstants() + { + return [ + ['!php/const Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT], + ['!php/const PHP_INT_MAX', \PHP_INT_MAX], + ['[!php/const PHP_INT_MAX]', [\PHP_INT_MAX]], + ['{ foo: !php/const PHP_INT_MAX }', ['foo' => \PHP_INT_MAX]], + ['{ !php/const PHP_INT_MAX: foo }', [\PHP_INT_MAX => 'foo']], + ['!php/const NULL', null], + ]; + } + + public function testParsePhpConstantThrowsExceptionWhenUndefined() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('The constant "WRONG_CONSTANT" is not defined'); + Inline::parse('!php/const WRONG_CONSTANT', Yaml::PARSE_CONSTANT); + } + + public function testParsePhpConstantThrowsExceptionOnInvalidType() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessageMatches('#The string "!php/const PHP_INT_MAX" could not be parsed as a constant.*#'); + Inline::parse('!php/const PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); + } + + /** + * @group legacy + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 1. + * @dataProvider getTestsForParseLegacyPhpConstants + */ + public function testDeprecatedConstantTag($yaml, $expectedValue) + { + $this->assertSame($expectedValue, Inline::parse($yaml, Yaml::PARSE_CONSTANT)); + } + + public function getTestsForParseLegacyPhpConstants() + { + return [ + ['!php/const:Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT], + ['!php/const:PHP_INT_MAX', \PHP_INT_MAX], + ['[!php/const:PHP_INT_MAX]', [\PHP_INT_MAX]], + ['{ foo: !php/const:PHP_INT_MAX }', ['foo' => \PHP_INT_MAX]], + ['{ !php/const:PHP_INT_MAX: foo }', [\PHP_INT_MAX => 'foo']], + ['!php/const:NULL', null], + ]; + } + + /** + * @group legacy + * @dataProvider getTestsForParseWithMapObjects + */ + public function testParseWithMapObjectsPassingTrue($yaml, $value) + { + $actual = Inline::parse($yaml, false, false, true); + + $this->assertSame(serialize($value), serialize($actual)); + } + + /** + * @dataProvider getTestsForDump + */ + public function testDump($yaml, $value, $parseFlags = 0) + { + $this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml)); + + $this->assertSame($value, Inline::parse(Inline::dump($value), $parseFlags), 'check consistency'); + } + + public function testDumpNumericValueWithLocale() + { + $locale = setlocale(\LC_NUMERIC, 0); + if (false === $locale) { + $this->markTestSkipped('Your platform does not support locales.'); + } + + try { + $requiredLocales = ['fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252']; + if (false === setlocale(\LC_NUMERIC, $requiredLocales)) { + $this->markTestSkipped('Could not set any of required locales: '.implode(', ', $requiredLocales)); + } + + $this->assertEquals('1.2', Inline::dump(1.2)); + $this->assertStringContainsStringIgnoringCase('fr', setlocale(\LC_NUMERIC, 0)); + } finally { + setlocale(\LC_NUMERIC, $locale); + } + } + + public function testHashStringsResemblingExponentialNumericsShouldNotBeChangedToINF() + { + $value = '686e444'; + + $this->assertSame($value, Inline::parse(Inline::dump($value))); + } + + public function testParseScalarWithNonEscapedBlackslashShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Found unknown escape character "\V".'); + Inline::parse('"Foo\Var"'); + } + + public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Inline::parse('"Foo\\"'); + } + + public function testParseScalarWithIncorrectlyQuotedStringShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $value = "'don't do somthin' like that'"; + Inline::parse($value); + } + + public function testParseScalarWithIncorrectlyDoubleQuotedStringShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $value = '"don"t do somthin" like that"'; + Inline::parse($value); + } + + public function testParseInvalidMappingKeyShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $value = '{ "foo " bar": "bar" }'; + Inline::parse($value); + } + + /** + * @group legacy + * @expectedDeprecation Using a colon after an unquoted mapping key that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}") is deprecated since Symfony 3.2 and will throw a ParseException in 4.0 on line 1. + * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0 + */ + public function testParseMappingKeyWithColonNotFollowedBySpace() + { + Inline::parse('{1:""}'); + } + + public function testParseInvalidMappingShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Inline::parse('[foo] bar'); + } + + public function testParseInvalidSequenceShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Inline::parse('{ foo: bar } bar'); + } + + public function testParseInvalidTaggedSequenceShouldThrowException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Inline::parse('!foo { bar: baz } qux', Yaml::PARSE_CUSTOM_TAGS); + } + + public function testParseScalarWithCorrectlyQuotedStringShouldReturnString() + { + $value = "'don''t do somthin'' like that'"; + $expect = "don't do somthin' like that"; + + $this->assertSame($expect, Inline::parseScalar($value)); + } + + /** + * @dataProvider getDataForParseReferences + */ + public function testParseReferences($yaml, $expected) + { + $this->assertSame($expected, Inline::parse($yaml, 0, ['var' => 'var-value'])); + } + + /** + * @group legacy + * @dataProvider getDataForParseReferences + */ + public function testParseReferencesAsFifthArgument($yaml, $expected) + { + $this->assertSame($expected, Inline::parse($yaml, false, false, false, ['var' => 'var-value'])); + } + + public function getDataForParseReferences() + { + return [ + 'scalar' => ['*var', 'var-value'], + 'list' => ['[ *var ]', ['var-value']], + 'list-in-list' => ['[[ *var ]]', [['var-value']]], + 'map-in-list' => ['[ { key: *var } ]', [['key' => 'var-value']]], + 'embedded-mapping-in-list' => ['[ key: *var ]', [['key' => 'var-value']]], + 'map' => ['{ key: *var }', ['key' => 'var-value']], + 'list-in-map' => ['{ key: [*var] }', ['key' => ['var-value']]], + 'map-in-map' => ['{ foo: { bar: *var } }', ['foo' => ['bar' => 'var-value']]], + ]; + } + + public function testParseMapReferenceInSequence() + { + $foo = [ + 'a' => 'Steve', + 'b' => 'Clark', + 'c' => 'Brian', + ]; + $this->assertSame([$foo], Inline::parse('[*foo]', 0, ['foo' => $foo])); + } + + /** + * @group legacy + */ + public function testParseMapReferenceInSequenceAsFifthArgument() + { + $foo = [ + 'a' => 'Steve', + 'b' => 'Clark', + 'c' => 'Brian', + ]; + $this->assertSame([$foo], Inline::parse('[*foo]', false, false, false, ['foo' => $foo])); + } + + public function testParseUnquotedAsterisk() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('A reference must contain at least one character at line 1.'); + Inline::parse('{ foo: * }'); + } + + public function testParseUnquotedAsteriskFollowedByAComment() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('A reference must contain at least one character at line 1.'); + Inline::parse('{ foo: * #foo }'); + } + + /** + * @dataProvider getReservedIndicators + */ + public function testParseUnquotedScalarStartingWithReservedIndicator($indicator) + { + $this->expectException(ParseException::class); + $this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator)); + + Inline::parse(sprintf('{ foo: %sfoo }', $indicator)); + } + + public function getReservedIndicators() + { + return [['@'], ['`']]; + } + + /** + * @dataProvider getScalarIndicators + */ + public function testParseUnquotedScalarStartingWithScalarIndicator($indicator) + { + $this->expectException(ParseException::class); + $this->expectExceptionMessage(sprintf('cannot start a plain scalar; you need to quote the scalar at line 1 (near "%sfoo ").', $indicator)); + + Inline::parse(sprintf('{ foo: %sfoo }', $indicator)); + } + + public function getScalarIndicators() + { + return [['|'], ['>']]; + } + + /** + * @group legacy + * @expectedDeprecation Not quoting the scalar "%bar " starting with the "%" indicator character is deprecated since Symfony 3.1 and will throw a ParseException in 4.0 on line 1. + * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0 + */ + public function testParseUnquotedScalarStartingWithPercentCharacter() + { + Inline::parse('{ foo: %bar }'); + } + + /** + * @dataProvider getDataForIsHash + */ + public function testIsHash($array, $expected) + { + $this->assertSame($expected, Inline::isHash($array)); + } + + public function getDataForIsHash() + { + return [ + [[], false], + [[1, 2, 3], false], + [[2 => 1, 1 => 2, 0 => 3], true], + [['foo' => 1, 'bar' => 2], true], + ]; + } + + public function getTestsForParse() + { + return [ + ['', ''], + ['null', null], + ['false', false], + ['true', true], + ['12', 12], + ['-12', -12], + ['1_2', 12], + ['_12', '_12'], + ['12_', 12], + ['"quoted string"', 'quoted string'], + ["'quoted string'", 'quoted string'], + ['12.30e+02', 12.30e+02], + ['123.45_67', 123.4567], + ['0x4D2', 0x4D2], + ['0x_4_D_2_', 0x4D2], + ['02333', 02333], + ['0_2_3_3_3', 02333], + ['.Inf', -log(0)], + ['-.Inf', log(0)], + ["'686e444'", '686e444'], + ['686e444', 646e444], + ['123456789123456789123456789123456789', '123456789123456789123456789123456789'], + ['"foo\r\nbar"', "foo\r\nbar"], + ["'foo#bar'", 'foo#bar'], + ["'foo # bar'", 'foo # bar'], + ["'#cfcfcf'", '#cfcfcf'], + ['::form_base.html.twig', '::form_base.html.twig'], + + // Pre-YAML-1.2 booleans + ["'y'", 'y'], + ["'n'", 'n'], + ["'yes'", 'yes'], + ["'no'", 'no'], + ["'on'", 'on'], + ["'off'", 'off'], + + ['2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)], + ['2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)], + ['2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)], + ['1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)], + ['1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)], + + ['"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''], + ["'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''], + + // sequences + // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon + ['[foo, http://urls.are/no/mappings, false, null, 12]', ['foo', 'http://urls.are/no/mappings', false, null, 12]], + ['[ foo , bar , false , null , 12 ]', ['foo', 'bar', false, null, 12]], + ['[\'foo,bar\', \'foo bar\']', ['foo,bar', 'foo bar']], + + // mappings + ['{foo: bar,bar: foo,"false": false, "null": null,integer: 12}', ['foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12]], + ['{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', ['foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12]], + ['{foo: \'bar\', bar: \'foo: bar\'}', ['foo' => 'bar', 'bar' => 'foo: bar']], + ['{\'foo\': \'bar\', "bar": \'foo: bar\'}', ['foo' => 'bar', 'bar' => 'foo: bar']], + ['{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', ['foo\'' => 'bar', 'bar"' => 'foo: bar']], + ['{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', ['foo: ' => 'bar', 'bar: ' => 'foo: bar']], + ['{"foo:bar": "baz"}', ['foo:bar' => 'baz']], + ['{"foo":"bar"}', ['foo' => 'bar']], + + // nested sequences and mappings + ['[foo, [bar, foo]]', ['foo', ['bar', 'foo']]], + ['[foo, {bar: foo}]', ['foo', ['bar' => 'foo']]], + ['{ foo: {bar: foo} }', ['foo' => ['bar' => 'foo']]], + ['{ foo: [bar, foo] }', ['foo' => ['bar', 'foo']]], + ['{ foo:{bar: foo} }', ['foo' => ['bar' => 'foo']]], + ['{ foo:[bar, foo] }', ['foo' => ['bar', 'foo']]], + + ['[ foo, [ bar, foo ] ]', ['foo', ['bar', 'foo']]], + + ['[{ foo: {bar: foo} }]', [['foo' => ['bar' => 'foo']]]], + + ['[foo, [bar, [foo, [bar, foo]], foo]]', ['foo', ['bar', ['foo', ['bar', 'foo']], 'foo']]], + + ['[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', ['foo', ['bar' => 'foo', 'foo' => ['foo', ['bar' => 'foo']]], ['foo', ['bar' => 'foo']]]], + + ['[foo, bar: { foo: bar }]', ['foo', '1' => ['bar' => ['foo' => 'bar']]]], + ['[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', ['foo', '@foo.baz', ['%foo%' => 'foo is %foo%', 'bar' => '%foo%'], true, '@service_container']], + ]; + } + + public function getTestsForParseWithMapObjects() + { + return [ + ['', ''], + ['null', null], + ['false', false], + ['true', true], + ['12', 12], + ['-12', -12], + ['"quoted string"', 'quoted string'], + ["'quoted string'", 'quoted string'], + ['12.30e+02', 12.30e+02], + ['0x4D2', 0x4D2], + ['02333', 02333], + ['.Inf', -log(0)], + ['-.Inf', log(0)], + ["'686e444'", '686e444'], + ['686e444', 646e444], + ['123456789123456789123456789123456789', '123456789123456789123456789123456789'], + ['"foo\r\nbar"', "foo\r\nbar"], + ["'foo#bar'", 'foo#bar'], + ["'foo # bar'", 'foo # bar'], + ["'#cfcfcf'", '#cfcfcf'], + ['::form_base.html.twig', '::form_base.html.twig'], + + ['2007-10-30', gmmktime(0, 0, 0, 10, 30, 2007)], + ['2007-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 2007)], + ['2007-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 2007)], + ['1960-10-30 02:59:43 Z', gmmktime(2, 59, 43, 10, 30, 1960)], + ['1730-10-30T02:59:43Z', gmmktime(2, 59, 43, 10, 30, 1730)], + + ['"a \\"string\\" with \'quoted strings inside\'"', 'a "string" with \'quoted strings inside\''], + ["'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''], + + // sequences + // urls are no key value mapping. see #3609. Valid yaml "key: value" mappings require a space after the colon + ['[foo, http://urls.are/no/mappings, false, null, 12]', ['foo', 'http://urls.are/no/mappings', false, null, 12]], + ['[ foo , bar , false , null , 12 ]', ['foo', 'bar', false, null, 12]], + ['[\'foo,bar\', \'foo bar\']', ['foo,bar', 'foo bar']], + + // mappings + ['{foo: bar,bar: foo,"false": false,"null": null,integer: 12}', (object) ['foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12], Yaml::PARSE_OBJECT_FOR_MAP], + ['{ foo : bar, bar : foo, "false" : false, "null" : null, integer : 12 }', (object) ['foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12], Yaml::PARSE_OBJECT_FOR_MAP], + ['{foo: \'bar\', bar: \'foo: bar\'}', (object) ['foo' => 'bar', 'bar' => 'foo: bar']], + ['{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) ['foo' => 'bar', 'bar' => 'foo: bar']], + ['{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) ['foo\'' => 'bar', 'bar"' => 'foo: bar']], + ['{\'foo: \': \'bar\', "bar: ": \'foo: bar\'}', (object) ['foo: ' => 'bar', 'bar: ' => 'foo: bar']], + ['{"foo:bar": "baz"}', (object) ['foo:bar' => 'baz']], + ['{"foo":"bar"}', (object) ['foo' => 'bar']], + + // nested sequences and mappings + ['[foo, [bar, foo]]', ['foo', ['bar', 'foo']]], + ['[foo, {bar: foo}]', ['foo', (object) ['bar' => 'foo']]], + ['{ foo: {bar: foo} }', (object) ['foo' => (object) ['bar' => 'foo']]], + ['{ foo: [bar, foo] }', (object) ['foo' => ['bar', 'foo']]], + + ['[ foo, [ bar, foo ] ]', ['foo', ['bar', 'foo']]], + + ['[{ foo: {bar: foo} }]', [(object) ['foo' => (object) ['bar' => 'foo']]]], + + ['[foo, [bar, [foo, [bar, foo]], foo]]', ['foo', ['bar', ['foo', ['bar', 'foo']], 'foo']]], + + ['[foo, {bar: foo, foo: [foo, {bar: foo}]}, [foo, {bar: foo}]]', ['foo', (object) ['bar' => 'foo', 'foo' => ['foo', (object) ['bar' => 'foo']]], ['foo', (object) ['bar' => 'foo']]]], + + ['[foo, bar: { foo: bar }]', ['foo', '1' => (object) ['bar' => (object) ['foo' => 'bar']]]], + ['[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', ['foo', '@foo.baz', (object) ['%foo%' => 'foo is %foo%', 'bar' => '%foo%'], true, '@service_container']], + + ['{}', new \stdClass()], + ['{ foo : bar, bar : {} }', (object) ['foo' => 'bar', 'bar' => new \stdClass()]], + ['{ foo : [], bar : {} }', (object) ['foo' => [], 'bar' => new \stdClass()]], + ['{foo: \'bar\', bar: {} }', (object) ['foo' => 'bar', 'bar' => new \stdClass()]], + ['{\'foo\': \'bar\', "bar": {}}', (object) ['foo' => 'bar', 'bar' => new \stdClass()]], + ['{\'foo\': \'bar\', "bar": \'{}\'}', (object) ['foo' => 'bar', 'bar' => '{}']], + + ['[foo, [{}, {}]]', ['foo', [new \stdClass(), new \stdClass()]]], + ['[foo, [[], {}]]', ['foo', [[], new \stdClass()]]], + ['[foo, [[{}, {}], {}]]', ['foo', [[new \stdClass(), new \stdClass()], new \stdClass()]]], + ['[foo, {bar: {}}]', ['foo', '1' => (object) ['bar' => new \stdClass()]]], + ]; + } + + public function getTestsForDump() + { + return [ + ['null', null], + ['false', false], + ['true', true], + ['12', 12], + ["'1_2'", '1_2'], + ['_12', '_12'], + ["'12_'", '12_'], + ["'quoted string'", 'quoted string'], + ['!!float 1230', 12.30e+02], + ['1234', 0x4D2], + ['1243', 02333], + ["'0x_4_D_2_'", '0x_4_D_2_'], + ["'0_2_3_3_3'", '0_2_3_3_3'], + ['.Inf', -log(0)], + ['-.Inf', log(0)], + ["'686e444'", '686e444'], + ['"foo\r\nbar"', "foo\r\nbar"], + ["'foo#bar'", 'foo#bar'], + ["'foo # bar'", 'foo # bar'], + ["'#cfcfcf'", '#cfcfcf'], + + ["'a \"string\" with ''quoted strings inside'''", 'a "string" with \'quoted strings inside\''], + + ["'-dash'", '-dash'], + ["'-'", '-'], + + // Pre-YAML-1.2 booleans + ["'y'", 'y'], + ["'n'", 'n'], + ["'yes'", 'yes'], + ["'no'", 'no'], + ["'on'", 'on'], + ["'off'", 'off'], + + // sequences + ['[foo, bar, false, null, 12]', ['foo', 'bar', false, null, 12]], + ['[\'foo,bar\', \'foo bar\']', ['foo,bar', 'foo bar']], + + // mappings + ['{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', ['foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12]], + ['{ foo: bar, bar: \'foo: bar\' }', ['foo' => 'bar', 'bar' => 'foo: bar']], + + // nested sequences and mappings + ['[foo, [bar, foo]]', ['foo', ['bar', 'foo']]], + + ['[foo, [bar, [foo, [bar, foo]], foo]]', ['foo', ['bar', ['foo', ['bar', 'foo']], 'foo']]], + + ['{ foo: { bar: foo } }', ['foo' => ['bar' => 'foo']]], + + ['[foo, { bar: foo }]', ['foo', ['bar' => 'foo']]], + + ['[foo, { bar: foo, foo: [foo, { bar: foo }] }, [foo, { bar: foo }]]', ['foo', ['bar' => 'foo', 'foo' => ['foo', ['bar' => 'foo']]], ['foo', ['bar' => 'foo']]]], + + ['[foo, \'@foo.baz\', { \'%foo%\': \'foo is %foo%\', bar: \'%foo%\' }, true, \'@service_container\']', ['foo', '@foo.baz', ['%foo%' => 'foo is %foo%', 'bar' => '%foo%'], true, '@service_container']], + + ['{ foo: { bar: { 1: 2, baz: 3 } } }', ['foo' => ['bar' => [1 => 2, 'baz' => 3]]]], + + // numeric strings with trailing whitespaces + ["'0123 '", '0123 '], + ['"0123\f"', "0123\f"], + ['"0123\n"', "0123\n"], + ['"0123\r"', "0123\r"], + ['"0123\t"', "0123\t"], + ['"0123\v"', "0123\v"], + ]; + } + + /** + * @dataProvider getTimestampTests + */ + public function testParseTimestampAsUnixTimestampByDefault($yaml, $year, $month, $day, $hour, $minute, $second) + { + $this->assertSame(gmmktime($hour, $minute, $second, $month, $day, $year), Inline::parse($yaml)); + } + + /** + * @dataProvider getTimestampTests + */ + public function testParseTimestampAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second, $timezone) + { + $expected = new \DateTime($yaml); + $expected->setTimeZone(new \DateTimeZone('UTC')); + $expected->setDate($year, $month, $day); + + if (\PHP_VERSION_ID >= 70100) { + $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + } else { + $expected->setTime($hour, $minute, $second); + } + + $date = Inline::parse($yaml, Yaml::PARSE_DATETIME); + $this->assertEquals($expected, $date); + $this->assertSame($timezone, $date->format('O')); + } + + public function getTimestampTests() + { + return [ + 'canonical' => ['2001-12-15T02:59:43.1Z', 2001, 12, 15, 2, 59, 43.1, '+0000'], + 'ISO-8601' => ['2001-12-15t21:59:43.10-05:00', 2001, 12, 16, 2, 59, 43.1, '-0500'], + 'spaced' => ['2001-12-15 21:59:43.10 -5', 2001, 12, 16, 2, 59, 43.1, '-0500'], + 'date' => ['2001-12-15', 2001, 12, 15, 0, 0, 0, '+0000'], + ]; + } + + /** + * @dataProvider getTimestampTests + */ + public function testParseNestedTimestampListAsDateTimeObject($yaml, $year, $month, $day, $hour, $minute, $second) + { + $expected = new \DateTime($yaml); + $expected->setTimeZone(new \DateTimeZone('UTC')); + $expected->setDate($year, $month, $day); + if (\PHP_VERSION_ID >= 70100) { + $expected->setTime($hour, $minute, $second, 1000000 * ($second - (int) $second)); + } else { + $expected->setTime($hour, $minute, $second); + } + + $expectedNested = ['nested' => [$expected]]; + $yamlNested = "{nested: [$yaml]}"; + + $this->assertEquals($expectedNested, Inline::parse($yamlNested, Yaml::PARSE_DATETIME)); + } + + /** + * @dataProvider getDateTimeDumpTests + */ + public function testDumpDateTime($dateTime, $expected) + { + $this->assertSame($expected, Inline::dump($dateTime)); + } + + public function getDateTimeDumpTests() + { + $tests = []; + + $dateTime = new \DateTime('2001-12-15 21:59:43', new \DateTimeZone('UTC')); + $tests['date-time-utc'] = [$dateTime, '2001-12-15T21:59:43+00:00']; + + $dateTime = new \DateTimeImmutable('2001-07-15 21:59:43', new \DateTimeZone('Europe/Berlin')); + $tests['immutable-date-time-europe-berlin'] = [$dateTime, '2001-07-15T21:59:43+02:00']; + + return $tests; + } + + /** + * @dataProvider getBinaryData + */ + public function testParseBinaryData($data) + { + $this->assertSame('Hello world', Inline::parse($data)); + } + + public function getBinaryData() + { + return [ + 'enclosed with double quotes' => ['!!binary "SGVsbG8gd29ybGQ="'], + 'enclosed with single quotes' => ["!!binary 'SGVsbG8gd29ybGQ='"], + 'containing spaces' => ['!!binary "SGVs bG8gd 29ybGQ="'], + ]; + } + + /** + * @dataProvider getInvalidBinaryData + */ + public function testParseInvalidBinaryData($data, $expectedMessage) + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessageMatches($expectedMessage); + + Inline::parse($data); + } + + public function getInvalidBinaryData() + { + return [ + 'length not a multiple of four' => ['!!binary "SGVsbG8d29ybGQ="', '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/'], + 'invalid characters' => ['!!binary "SGVsbG8#d29ybGQ="', '/The base64 encoded data \(.*\) contains invalid characters/'], + 'too many equals characters' => ['!!binary "SGVsbG8gd29yb==="', '/The base64 encoded data \(.*\) contains invalid characters/'], + 'misplaced equals character' => ['!!binary "SGVsbG8gd29ybG=Q"', '/The base64 encoded data \(.*\) contains invalid characters/'], + ]; + } + + public function testNotSupportedMissingValue() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Malformed inline YAML string: "{this, is not, supported}" at line 1.'); + Inline::parse('{this, is not, supported}'); + } + + public function testVeryLongQuotedStrings() + { + $longStringWithQuotes = str_repeat("x\r\n\\\"x\"x", 1000); + + $yamlString = Inline::dump(['longStringWithQuotes' => $longStringWithQuotes]); + $arrayFromYaml = Inline::parse($yamlString); + + $this->assertEquals($longStringWithQuotes, $arrayFromYaml['longStringWithQuotes']); + } + + /** + * @group legacy + * @expectedDeprecation Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0 on line 1. + */ + public function testOmittedMappingKeyIsParsedAsColon() + { + $this->assertSame([':' => 'foo'], Inline::parse('{: foo}')); + } + + /** + * @dataProvider getTestsForNullValues + */ + public function testParseMissingMappingValueAsNull($yaml, $expected) + { + $this->assertSame($expected, Inline::parse($yaml)); + } + + public function getTestsForNullValues() + { + return [ + 'null before closing curly brace' => ['{foo:}', ['foo' => null]], + 'null before comma' => ['{foo:, bar: baz}', ['foo' => null, 'bar' => 'baz']], + ]; + } + + public function testTheEmptyStringIsAValidMappingKey() + { + $this->assertSame(['' => 'foo'], Inline::parse('{ "": foo }')); + } + + /** + * @group legacy + * @expectedDeprecation Implicit casting of incompatible mapping keys to strings is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line 1. + * @dataProvider getNotPhpCompatibleMappingKeyData + */ + public function testImplicitStringCastingOfMappingKeysIsDeprecated($yaml, $expected) + { + $this->assertSame($expected, Inline::parse($yaml)); + } + + /** + * @group legacy + * @expectedDeprecation Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since Symfony 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead. + * @expectedDeprecation Implicit casting of incompatible mapping keys to strings is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line 1. + * @dataProvider getNotPhpCompatibleMappingKeyData + */ + public function testExplicitStringCastingOfMappingKeys($yaml, $expected) + { + $this->assertSame($expected, Yaml::parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS)); + } + + public function getNotPhpCompatibleMappingKeyData() + { + return [ + 'boolean-true' => ['{true: "foo"}', ['true' => 'foo']], + 'boolean-false' => ['{false: "foo"}', ['false' => 'foo']], + 'null' => ['{null: "foo"}', ['null' => 'foo']], + 'float' => ['{0.25: "foo"}', ['0.25' => 'foo']], + ]; + } + + /** + * @group legacy + * @expectedDeprecation Support for the !str tag is deprecated since Symfony 3.4. Use the !!str tag instead on line 1. + */ + public function testDeprecatedStrTag() + { + $this->assertSame(['foo' => 'bar'], Inline::parse('{ foo: !str bar }')); + } + + public function testUnfinishedInlineMap() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Unexpected end of line, expected one of ",}" at line 1 (near "{abc: \'def\'").'); + Inline::parse("{abc: 'def'"); + } + + /** + * @dataProvider getTestsForOctalNumbers + */ + public function testParseOctalNumbers($expected, $yaml) + { + self::assertSame($expected, Inline::parse($yaml)); + } + + public function getTestsForOctalNumbers() + { + return [ + 'positive octal number' => [28, '034'], + 'negative octal number' => [-28, '-034'], + ]; + } + + /** + * @dataProvider phpObjectTagWithEmptyValueProvider + */ + public function testPhpObjectWithEmptyValue($expected, $value) + { + $this->assertSame($expected, Inline::parse($value, Yaml::PARSE_OBJECT)); + } + + public function phpObjectTagWithEmptyValueProvider() + { + return [ + [false, '!php/object'], + [false, '!php/object '], + [false, '!php/object '], + [[false], '[!php/object]'], + [[false], '[!php/object ]'], + [[false, 'foo'], '[!php/object , foo]'], + ]; + } + + /** + * @dataProvider phpConstTagWithEmptyValueProvider + */ + public function testPhpConstTagWithEmptyValue($expected, $value) + { + $this->assertSame($expected, Inline::parse($value, Yaml::PARSE_CONSTANT)); + } + + public function phpConstTagWithEmptyValueProvider() + { + return [ + ['', '!php/const'], + ['', '!php/const '], + ['', '!php/const '], + [[''], '[!php/const]'], + [[''], '[!php/const ]'], + [['', 'foo'], '[!php/const , foo]'], + [['' => 'foo'], '{!php/const: foo}'], + [['' => 'foo'], '{!php/const : foo}'], + [['' => 'foo', 'bar' => 'ccc'], '{!php/const : foo, bar: ccc}'], + ]; + } + + public function testParsePositiveOctalNumberContainingInvalidDigits() + { + self::assertSame('0123456789', Inline::parse('0123456789')); + } + + public function testParseNegativeOctalNumberContainingInvalidDigits() + { + self::assertSame('-0123456789', Inline::parse('-0123456789')); + } + + public function testParseCommentNotPrefixedBySpaces() + { + self::assertSame('foo', Inline::parse('"foo"#comment')); + } + + public function testParseUnquotedStringContainingHashTagNotPrefixedBySpace() + { + self::assertSame('foo#nocomment', Inline::parse('foo#nocomment')); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/ParseExceptionTest.php b/modules/empikmarketplace/vendor/symfony/yaml/Tests/ParseExceptionTest.php new file mode 100644 index 00000000..39579ede --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/ParseExceptionTest.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Exception\ParseException; + +class ParseExceptionTest extends TestCase +{ + public function testGetMessage() + { + $exception = new ParseException('Error message', 42, 'foo: bar', '/var/www/app/config.yml'); + $message = 'Error message in "/var/www/app/config.yml" at line 42 (near "foo: bar")'; + + $this->assertEquals($message, $exception->getMessage()); + } + + public function testGetMessageWithUnicodeInFilename() + { + $exception = new ParseException('Error message', 42, 'foo: bar', 'äöü.yml'); + $message = 'Error message in "äöü.yml" at line 42 (near "foo: bar")'; + + $this->assertEquals($message, $exception->getMessage()); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/ParserTest.php b/modules/empikmarketplace/vendor/symfony/yaml/Tests/ParserTest.php new file mode 100644 index 00000000..7fa6ed1a --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/ParserTest.php @@ -0,0 +1,2401 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Parser; +use Symfony\Component\Yaml\Tag\TaggedValue; +use Symfony\Component\Yaml\Yaml; + +class ParserTest extends TestCase +{ + /** @var Parser */ + protected $parser; + + protected function setUp() + { + $this->parser = new Parser(); + } + + protected function tearDown() + { + $this->parser = null; + + chmod(__DIR__.'/Fixtures/not_readable.yml', 0644); + } + + /** + * @dataProvider getDataFormSpecifications + */ + public function testSpecifications($expected, $yaml, $comment, $deprecated) + { + $deprecations = []; + + if ($deprecated) { + set_error_handler(function ($type, $msg) use (&$deprecations) { + if (\E_USER_DEPRECATED !== $type) { + restore_error_handler(); + + return \call_user_func_array('PHPUnit\Util\ErrorHandler::handleError', \func_get_args()); + } + + $deprecations[] = $msg; + + return null; + }); + } + + $this->assertEquals($expected, var_export($this->parser->parse($yaml), true), $comment); + + if ($deprecated) { + restore_error_handler(); + + $this->assertCount(1, $deprecations); + $this->assertStringContainsString(true !== $deprecated ? $deprecated : 'Using the comma as a group separator for floats is deprecated since Symfony 3.2 and will be removed in 4.0 on line 1.', $deprecations[0]); + } + } + + public function getDataFormSpecifications() + { + return $this->loadTestsFromFixtureFiles('index.yml'); + } + + /** + * @group legacy + * @expectedDeprecationMessage Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since Symfony 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable + * @dataProvider getNonStringMappingKeysData + */ + public function testNonStringMappingKeys($expected, $yaml, $comment) + { + $this->assertSame($expected, var_export($this->parser->parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS), true), $comment); + } + + public function getNonStringMappingKeysData() + { + return $this->loadTestsFromFixtureFiles('nonStringKeys.yml'); + } + + /** + * @group legacy + * @dataProvider getLegacyNonStringMappingKeysData + */ + public function testLegacyNonStringMappingKeys($expected, $yaml, $comment) + { + $this->assertSame($expected, var_export($this->parser->parse($yaml), true), $comment); + } + + public function getLegacyNonStringMappingKeysData() + { + return $this->loadTestsFromFixtureFiles('legacyNonStringKeys.yml'); + } + + public function testTabsInYaml() + { + // test tabs in YAML + $yamls = [ + "foo:\n bar", + "foo:\n bar", + "foo:\n bar", + "foo:\n bar", + ]; + + foreach ($yamls as $yaml) { + try { + $this->parser->parse($yaml); + + $this->fail('YAML files must not contain tabs'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, 'YAML files must not contain tabs'); + $this->assertEquals('A YAML file cannot contain tabs as indentation at line 2 (near "'.strpbrk($yaml, "\t").'").', $e->getMessage(), 'YAML files must not contain tabs'); + } + } + } + + public function testEndOfTheDocumentMarker() + { + $yaml = <<<'EOF' +--- %YAML:1.0 +foo +... +EOF; + + $this->assertEquals('foo', $this->parser->parse($yaml)); + } + + public function getBlockChompingTests() + { + $tests = []; + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two + +EOF; + $expected = [ + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ]; + $tests['Literal block chomping strip with single trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: |- + one + two + +bar: |- + one + two + + +EOF; + $expected = [ + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ]; + $tests['Literal block chomping strip with multiple trailing newlines'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +{} + + +EOF; + $expected = []; + $tests['Literal block chomping strip with multiple trailing newlines after a 1-liner'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: |- + one + two +bar: |- + one + two +EOF; + $expected = [ + 'foo' => "one\ntwo", + 'bar' => "one\ntwo", + ]; + $tests['Literal block chomping strip without trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two + +EOF; + $expected = [ + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ]; + $tests['Literal block chomping clip with single trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: | + one + two + +bar: | + one + two + + +EOF; + $expected = [ + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ]; + $tests['Literal block chomping clip with multiple trailing newlines'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: +- bar: | + one + + two +EOF; + $expected = [ + 'foo' => [ + [ + 'bar' => "one\n\ntwo", + ], + ], + ]; + $tests['Literal block chomping clip with embedded blank line inside unindented collection'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: | + one + two +bar: | + one + two +EOF; + $expected = [ + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo", + ]; + $tests['Literal block chomping clip without trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two + +EOF; + $expected = [ + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo\n", + ]; + $tests['Literal block chomping keep with single trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: |+ + one + two + +bar: |+ + one + two + + +EOF; + $expected = [ + 'foo' => "one\ntwo\n\n", + 'bar' => "one\ntwo\n\n", + ]; + $tests['Literal block chomping keep with multiple trailing newlines'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: |+ + one + two +bar: |+ + one + two +EOF; + $expected = [ + 'foo' => "one\ntwo\n", + 'bar' => "one\ntwo", + ]; + $tests['Literal block chomping keep without trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two + +EOF; + $expected = [ + 'foo' => 'one two', + 'bar' => 'one two', + ]; + $tests['Folded block chomping strip with single trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: >- + one + two + +bar: >- + one + two + + +EOF; + $expected = [ + 'foo' => 'one two', + 'bar' => 'one two', + ]; + $tests['Folded block chomping strip with multiple trailing newlines'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: >- + one + two +bar: >- + one + two +EOF; + $expected = [ + 'foo' => 'one two', + 'bar' => 'one two', + ]; + $tests['Folded block chomping strip without trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two + +EOF; + $expected = [ + 'foo' => "one two\n", + 'bar' => "one two\n", + ]; + $tests['Folded block chomping clip with single trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: > + one + two + +bar: > + one + two + + +EOF; + $expected = [ + 'foo' => "one two\n", + 'bar' => "one two\n", + ]; + $tests['Folded block chomping clip with multiple trailing newlines'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: > + one + two +bar: > + one + two +EOF; + $expected = [ + 'foo' => "one two\n", + 'bar' => 'one two', + ]; + $tests['Folded block chomping clip without trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two + +EOF; + $expected = [ + 'foo' => "one two\n", + 'bar' => "one two\n", + ]; + $tests['Folded block chomping keep with single trailing newline'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: >+ + one + two + +bar: >+ + one + two + + +EOF; + $expected = [ + 'foo' => "one two\n\n", + 'bar' => "one two\n\n", + ]; + $tests['Folded block chomping keep with multiple trailing newlines'] = [$expected, $yaml]; + + $yaml = <<<'EOF' +foo: >+ + one + two +bar: >+ + one + two +EOF; + $expected = [ + 'foo' => "one two\n", + 'bar' => 'one two', + ]; + $tests['Folded block chomping keep without trailing newline'] = [$expected, $yaml]; + + return $tests; + } + + /** + * @dataProvider getBlockChompingTests + */ + public function testBlockChomping($expected, $yaml) + { + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * Regression test for issue #7989. + * + * @see https://github.com/symfony/symfony/issues/7989 + */ + public function testBlockLiteralWithLeadingNewlines() + { + $yaml = <<<'EOF' +foo: |- + + + bar + +EOF; + $expected = [ + 'foo' => "\n\nbar", + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testObjectSupportEnabled() + { + $input = <<<'EOF' +foo: !php/object O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $this->assertEquals(['foo' => new B(), 'bar' => 1], $this->parser->parse($input, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); + } + + /** + * @group legacy + */ + public function testObjectSupportEnabledPassingTrue() + { + $input = <<<'EOF' +foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $this->assertEquals(['foo' => new B(), 'bar' => 1], $this->parser->parse($input, false, true), '->parse() is able to parse objects'); + } + + /** + * @group legacy + * @dataProvider deprecatedObjectValueProvider + */ + public function testObjectSupportEnabledWithDeprecatedTag($yaml) + { + $this->assertEquals(['foo' => new B(), 'bar' => 1], $this->parser->parse($yaml, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); + } + + public function deprecatedObjectValueProvider() + { + return [ + [ + <<assertEquals(['foo' => null, 'bar' => 1], $this->parser->parse($input), '->parse() does not parse objects'); + } + + /** + * @dataProvider getObjectForMapTests + */ + public function testObjectForMap($yaml, $expected) + { + $flags = Yaml::PARSE_OBJECT_FOR_MAP; + + $this->assertEquals($expected, $this->parser->parse($yaml, $flags)); + } + + /** + * @group legacy + * @dataProvider getObjectForMapTests + */ + public function testObjectForMapEnabledWithMappingUsingBooleanToggles($yaml, $expected) + { + $this->assertEquals($expected, $this->parser->parse($yaml, false, false, true)); + } + + public function getObjectForMapTests() + { + $tests = []; + + $yaml = <<<'EOF' +foo: + fiz: [cat] +EOF; + $expected = new \stdClass(); + $expected->foo = new \stdClass(); + $expected->foo->fiz = ['cat']; + $tests['mapping'] = [$yaml, $expected]; + + $yaml = '{ "foo": "bar", "fiz": "cat" }'; + $expected = new \stdClass(); + $expected->foo = 'bar'; + $expected->fiz = 'cat'; + $tests['inline-mapping'] = [$yaml, $expected]; + + $yaml = "foo: bar\nbaz: foobar"; + $expected = new \stdClass(); + $expected->foo = 'bar'; + $expected->baz = 'foobar'; + $tests['object-for-map-is-applied-after-parsing'] = [$yaml, $expected]; + + $yaml = <<<'EOT' +array: + - key: one + - key: two +EOT; + $expected = new \stdClass(); + $expected->array = []; + $expected->array[0] = new \stdClass(); + $expected->array[0]->key = 'one'; + $expected->array[1] = new \stdClass(); + $expected->array[1]->key = 'two'; + $tests['nest-map-and-sequence'] = [$yaml, $expected]; + + $yaml = <<<'YAML' +map: + 1: one + 2: two +YAML; + $expected = new \stdClass(); + $expected->map = new \stdClass(); + $expected->map->{1} = 'one'; + $expected->map->{2} = 'two'; + $tests['numeric-keys'] = [$yaml, $expected]; + + $yaml = <<<'YAML' +map: + '0': one + '1': two +YAML; + $expected = new \stdClass(); + $expected->map = new \stdClass(); + $expected->map->{0} = 'one'; + $expected->map->{1} = 'two'; + $tests['zero-indexed-numeric-keys'] = [$yaml, $expected]; + + return $tests; + } + + /** + * @dataProvider invalidDumpedObjectProvider + */ + public function testObjectsSupportDisabledWithExceptions($yaml) + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->parser->parse($yaml, Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); + } + + public function testCanParseContentWithTrailingSpaces() + { + $yaml = "items: \n foo: bar"; + + $expected = [ + 'items' => ['foo' => 'bar'], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + /** + * @group legacy + * @dataProvider invalidDumpedObjectProvider + */ + public function testObjectsSupportDisabledWithExceptionsUsingBooleanToggles($yaml) + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->parser->parse($yaml, true); + } + + public function invalidDumpedObjectProvider() + { + $yamlTag = <<<'EOF' +foo: !!php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + $localTag = <<<'EOF' +foo: !php/object:O:30:"Symfony\Tests\Component\Yaml\B":1:{s:1:"b";s:3:"foo";} +bar: 1 +EOF; + + return [ + 'yaml-tag' => [$yamlTag], + 'local-tag' => [$localTag], + ]; + } + + /** + * @requires extension iconv + */ + public function testNonUtf8Exception() + { + $yamls = [ + iconv('UTF-8', 'ISO-8859-1', "foo: 'äöüß'"), + iconv('UTF-8', 'ISO-8859-15', "euro: '€'"), + iconv('UTF-8', 'CP1252', "cp1252: '©ÉÇáñ'"), + ]; + + foreach ($yamls as $yaml) { + try { + $this->parser->parse($yaml); + + $this->fail('charsets other than UTF-8 are rejected.'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Yaml\Exception\ParseException', $e, 'charsets other than UTF-8 are rejected.'); + } + } + } + + public function testUnindentedCollectionException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $yaml = <<<'EOF' + +collection: +-item1 +-item2 +-item3 + +EOF; + + $this->parser->parse($yaml); + } + + public function testShortcutKeyUnindentedCollectionException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $yaml = <<<'EOF' + +collection: +- key: foo + foo: bar + +EOF; + + $this->parser->parse($yaml); + } + + public function testMultipleDocumentsNotSupportedException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessageMatches('/^Multiple documents are not supported.+/'); + Yaml::parse(<<<'EOL' +# Ranking of 1998 home runs +--- +- Mark McGwire +- Sammy Sosa +- Ken Griffey + +# Team ranking +--- +- Chicago Cubs +- St Louis Cardinals +EOL + ); + } + + public function testSequenceInAMapping() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Yaml::parse(<<<'EOF' +yaml: + hash: me + - array stuff +EOF + ); + } + + public function testSequenceInMappingStartedBySingleDashLine() + { + $yaml = <<<'EOT' +a: +- + b: + - + bar: baz +- foo +d: e +EOT; + $expected = [ + 'a' => [ + [ + 'b' => [ + [ + 'bar' => 'baz', + ], + ], + ], + 'foo', + ], + 'd' => 'e', + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testSequenceFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + - c +# comment + d: e +EOT; + $expected = [ + 'a' => [ + 'b' => ['c'], + 'd' => 'e', + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testNonStringFollowedByCommentEmbeddedInMapping() + { + $yaml = <<<'EOT' +a: + b: + {} +# comment + d: + 1.1 +# another comment +EOT; + $expected = [ + 'a' => [ + 'b' => [], + 'd' => 1.1, + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function getParseExceptionNotAffectedMultiLineStringLastResortParsing() + { + $tests = []; + + $yaml = <<<'EOT' +a + b: +EOT; + $tests['parse error on first line'] = [$yaml]; + + $yaml = <<<'EOT' +a + +b + c: +EOT; + $tests['parse error due to inconsistent indentation'] = [$yaml]; + + $yaml = <<<'EOT' + & * ! | > ' " % @ ` #, { asd a;sdasd }-@^qw3 +EOT; + $tests['symfony/symfony/issues/22967#issuecomment-322067742'] = [$yaml]; + + return $tests; + } + + /** + * @dataProvider getParseExceptionNotAffectedMultiLineStringLastResortParsing + */ + public function testParseExceptionNotAffectedByMultiLineStringLastResortParsing($yaml) + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->parser->parse($yaml); + } + + public function testMultiLineStringLastResortParsing() + { + $yaml = <<<'EOT' +test: + You can have things that don't look like strings here + true + yes you can +EOT; + $expected = [ + 'test' => 'You can have things that don\'t look like strings here true yes you can', + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + + $yaml = <<<'EOT' +a: + b + c +EOT; + $expected = [ + 'a' => 'b c', + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testMappingInASequence() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + Yaml::parse(<<<'EOF' +yaml: + - array stuff + hash: me +EOF + ); + } + + public function testScalarInSequence() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('missing colon'); + Yaml::parse(<<<'EOF' +foo: + - bar +"missing colon" + foo: bar +EOF + ); + } + + /** + * > It is an error for two equal keys to appear in the same mapping node. + * > In such a case the YAML processor may continue, ignoring the second + * > `key: value` pair and issuing an appropriate warning. This strategy + * > preserves a consistent information model for one-pass and random access + * > applications. + * + * @see http://yaml.org/spec/1.2/spec.html#id2759572 + * @see http://yaml.org/spec/1.1/#id932806 + * @group legacy + */ + public function testMappingDuplicateKeyBlock() + { + $input = <<<'EOD' +parent: + child: first + child: duplicate +parent: + child: duplicate + child: duplicate +EOD; + $expected = [ + 'parent' => [ + 'child' => 'first', + ], + ]; + $this->assertSame($expected, Yaml::parse($input)); + } + + /** + * @group legacy + */ + public function testMappingDuplicateKeyFlow() + { + $input = <<<'EOD' +parent: { child: first, child: duplicate } +parent: { child: duplicate, child: duplicate } +EOD; + $expected = [ + 'parent' => [ + 'child' => 'first', + ], + ]; + $this->assertSame($expected, Yaml::parse($input)); + } + + /** + * @group legacy + * @dataProvider getParseExceptionOnDuplicateData + * @expectedDeprecation Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated %s and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line %d. + * throws \Symfony\Component\Yaml\Exception\ParseException in 4.0 + */ + public function testParseExceptionOnDuplicate($input, $duplicateKey, $lineNumber) + { + Yaml::parse($input); + } + + public function getParseExceptionOnDuplicateData() + { + $tests = []; + + $yaml = <<assertEquals(['hash' => null], Yaml::parse($input)); + } + + public function testCommentAtTheRootIndent() + { + $this->assertEquals([ + 'services' => [ + 'app.foo_service' => [ + 'class' => 'Foo', + ], + 'app/bar_service' => [ + 'class' => 'Bar', + ], + ], + ], Yaml::parse(<<<'EOF' +# comment 1 +services: +# comment 2 + # comment 3 + app.foo_service: + class: Foo +# comment 4 + # comment 5 + app/bar_service: + class: Bar +EOF + )); + } + + public function testStringBlockWithComments() + { + $this->assertEquals(['content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + ], Yaml::parse(<<<'EOF' +content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testFoldedStringBlockWithComments() + { + $this->assertEquals([['content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + ]], Yaml::parse(<<<'EOF' +- + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testNestedFoldedStringBlockWithComments() + { + $this->assertEquals([[ + 'title' => 'some title', + 'content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + ]], Yaml::parse(<<<'EOF' +- + title: some title + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOF + )); + } + + public function testReferenceResolvingInInlineStrings() + { + $this->assertEquals([ + 'var' => 'var-value', + 'scalar' => 'var-value', + 'list' => ['var-value'], + 'list_in_list' => [['var-value']], + 'map_in_list' => [['key' => 'var-value']], + 'embedded_mapping' => [['key' => 'var-value']], + 'map' => ['key' => 'var-value'], + 'list_in_map' => ['key' => ['var-value']], + 'map_in_map' => ['foo' => ['bar' => 'var-value']], + ], Yaml::parse(<<<'EOF' +var: &var var-value +scalar: *var +list: [ *var ] +list_in_list: [[ *var ]] +map_in_list: [ { key: *var } ] +embedded_mapping: [ key: *var ] +map: { key: *var } +list_in_map: { key: [*var] } +map_in_map: { foo: { bar: *var } } +EOF + )); + } + + public function testYamlDirective() + { + $yaml = <<<'EOF' +%YAML 1.2 +--- +foo: 1 +bar: 2 +EOF; + $this->assertEquals(['foo' => 1, 'bar' => 2], $this->parser->parse($yaml)); + } + + /** + * @group legacy + * @expectedDeprecation Implicit casting of numeric key to string is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line 2. + */ + public function testFloatKeys() + { + $yaml = <<<'EOF' +foo: + 1.2: "bar" + 1.3: "baz" +EOF; + + $expected = [ + 'foo' => [ + '1.2' => 'bar', + '1.3' => 'baz', + ], + ]; + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + /** + * @group legacy + * @expectedDeprecation Implicit casting of non-string key to string is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Quote your evaluable mapping keys instead on line 1. + */ + public function testBooleanKeys() + { + $yaml = <<<'EOF' +true: foo +false: bar +EOF; + + $expected = [ + 1 => 'foo', + 0 => 'bar', + ]; + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + public function testExplicitStringCasting() + { + $yaml = <<<'EOF' +'1.2': "bar" +!!str 1.3: "baz" + +'true': foo +!!str false: bar + +!!str null: 'null' +'~': 'null' +EOF; + + $expected = [ + '1.2' => 'bar', + '1.3' => 'baz', + 'true' => 'foo', + 'false' => 'bar', + 'null' => 'null', + '~' => 'null', + ]; + + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + public function testColonInMappingValueException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('A colon cannot be used in an unquoted mapping value'); + $yaml = <<<'EOF' +foo: bar: baz +EOF; + + $this->parser->parse($yaml); + } + + public function testColonInMappingValueExceptionNotTriggeredByColonInComment() + { + $yaml = <<<'EOT' +foo: + bar: foobar # Note: a comment after a colon +EOT; + + $this->assertSame(['foo' => ['bar' => 'foobar']], $this->parser->parse($yaml)); + } + + /** + * @dataProvider getCommentLikeStringInScalarBlockData + */ + public function testCommentLikeStringsAreNotStrippedInBlockScalars($yaml, $expectedParserResult) + { + $this->assertSame($expectedParserResult, $this->parser->parse($yaml)); + } + + public function getCommentLikeStringInScalarBlockData() + { + $tests = []; + + $yaml = <<<'EOT' +pages: + - + title: some title + content: | + # comment 1 + header + + # comment 2 + +

title

+ + + footer # comment3 +EOT; + $expected = [ + 'pages' => [ + [ + 'title' => 'some title', + 'content' => <<<'EOT' +# comment 1 +header + + # comment 2 + +

title

+ + +footer # comment3 +EOT + , + ], + ], + ]; + $tests[] = [$yaml, $expected]; + + $yaml = <<<'EOT' +test: | + foo + # bar + baz +collection: + - one: | + foo + # bar + baz + - two: | + foo + # bar + baz +EOT; + $expected = [ + 'test' => <<<'EOT' +foo +# bar +baz + +EOT + , + 'collection' => [ + [ + 'one' => <<<'EOT' +foo +# bar +baz + +EOT + , + ], + [ + 'two' => <<<'EOT' +foo +# bar +baz +EOT + , + ], + ], + ]; + $tests[] = [$yaml, $expected]; + + $yaml = <<<'EOT' +foo: + bar: + scalar-block: > + line1 + line2> + baz: +# comment + foobar: ~ +EOT; + $expected = [ + 'foo' => [ + 'bar' => [ + 'scalar-block' => "line1 line2>\n", + ], + 'baz' => [ + 'foobar' => null, + ], + ], + ]; + $tests[] = [$yaml, $expected]; + + $yaml = <<<'EOT' +a: + b: hello +# c: | +# first row +# second row + d: hello +EOT; + $expected = [ + 'a' => [ + 'b' => 'hello', + 'd' => 'hello', + ], + ]; + $tests[] = [$yaml, $expected]; + + return $tests; + } + + public function testBlankLinesAreParsedAsNewLinesInFoldedBlocks() + { + $yaml = <<<'EOT' +test: > +

A heading

+ +
    +
  • a list
  • +
  • may be a good example
  • +
+EOT; + + $this->assertSame( + [ + 'test' => <<<'EOT' +

A heading

+
  • a list
  • may be a good example
+EOT + , + ], + $this->parser->parse($yaml) + ); + } + + public function testAdditionallyIndentedLinesAreParsedAsNewLinesInFoldedBlocks() + { + $yaml = <<<'EOT' +test: > +

A heading

+ +
    +
  • a list
  • +
  • may be a good example
  • +
+EOT; + + $this->assertSame( + [ + 'test' => <<<'EOT' +

A heading

+
    +
  • a list
  • +
  • may be a good example
  • +
+EOT + , + ], + $this->parser->parse($yaml) + ); + } + + /** + * @dataProvider getBinaryData + */ + public function testParseBinaryData($data) + { + $this->assertSame(['data' => 'Hello world'], $this->parser->parse($data)); + } + + public function getBinaryData() + { + return [ + 'enclosed with double quotes' => ['data: !!binary "SGVsbG8gd29ybGQ="'], + 'enclosed with single quotes' => ["data: !!binary 'SGVsbG8gd29ybGQ='"], + 'containing spaces' => ['data: !!binary "SGVs bG8gd 29ybGQ="'], + 'in block scalar' => [ + <<<'EOT' +data: !!binary | + SGVsbG8gd29ybGQ= +EOT + ], + 'containing spaces in block scalar' => [ + <<<'EOT' +data: !!binary | + SGVs bG8gd 29ybGQ= +EOT + ], + ]; + } + + /** + * @dataProvider getInvalidBinaryData + */ + public function testParseInvalidBinaryData($data, $expectedMessage) + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessageMatches($expectedMessage); + + $this->parser->parse($data); + } + + public function getInvalidBinaryData() + { + return [ + 'length not a multiple of four' => ['data: !!binary "SGVsbG8d29ybGQ="', '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/'], + 'invalid characters' => ['!!binary "SGVsbG8#d29ybGQ="', '/The base64 encoded data \(.*\) contains invalid characters/'], + 'too many equals characters' => ['data: !!binary "SGVsbG8gd29yb==="', '/The base64 encoded data \(.*\) contains invalid characters/'], + 'misplaced equals character' => ['data: !!binary "SGVsbG8gd29ybG=Q"', '/The base64 encoded data \(.*\) contains invalid characters/'], + 'length not a multiple of four in block scalar' => [ + <<<'EOT' +data: !!binary | + SGVsbG8d29ybGQ= +EOT + , + '/The normalized base64 encoded data \(data without whitespace characters\) length must be a multiple of four \(\d+ bytes given\)/', + ], + 'invalid characters in block scalar' => [ + <<<'EOT' +data: !!binary | + SGVsbG8#d29ybGQ= +EOT + , + '/The base64 encoded data \(.*\) contains invalid characters/', + ], + 'too many equals characters in block scalar' => [ + <<<'EOT' +data: !!binary | + SGVsbG8gd29yb=== +EOT + , + '/The base64 encoded data \(.*\) contains invalid characters/', + ], + 'misplaced equals character in block scalar' => [ + <<<'EOT' +data: !!binary | + SGVsbG8gd29ybG=Q +EOT + , + '/The base64 encoded data \(.*\) contains invalid characters/', + ], + ]; + } + + public function testParseDateAsMappingValue() + { + $yaml = <<<'EOT' +date: 2002-12-14 +EOT; + $expectedDate = new \DateTime(); + $expectedDate->setTimeZone(new \DateTimeZone('UTC')); + $expectedDate->setDate(2002, 12, 14); + $expectedDate->setTime(0, 0, 0); + + $this->assertEquals(['date' => $expectedDate], $this->parser->parse($yaml, Yaml::PARSE_DATETIME)); + } + + /** + * @param $lineNumber + * @param $yaml + * @dataProvider parserThrowsExceptionWithCorrectLineNumberProvider + */ + public function testParserThrowsExceptionWithCorrectLineNumber($lineNumber, $yaml) + { + $this->expectException('\Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage(sprintf('Unexpected characters near "," at line %d (near "bar: "123",").', $lineNumber)); + + $this->parser->parse($yaml); + } + + public function parserThrowsExceptionWithCorrectLineNumberProvider() + { + return [ + [ + 4, + <<<'YAML' +foo: + - + # bar + bar: "123", +YAML + ], + [ + 5, + <<<'YAML' +foo: + - + # bar + # bar + bar: "123", +YAML + ], + [ + 8, + <<<'YAML' +foo: + - + # foobar + baz: 123 +bar: + - + # bar + bar: "123", +YAML + ], + [ + 10, + <<<'YAML' +foo: + - + # foobar + # foobar + baz: 123 +bar: + - + # bar + # bar + bar: "123", +YAML + ], + ]; + } + + public function testParseMultiLineQuotedString() + { + $yaml = <<assertSame(['foo' => 'bar baz foobar foo', 'bar' => 'baz'], $this->parser->parse($yaml)); + } + + public function testMultiLineQuotedStringWithTrailingBackslash() + { + $yaml = <<assertSame(['foobar' => 'foobar'], $this->parser->parse($yaml)); + } + + public function testCommentCharactersInMultiLineQuotedStrings() + { + $yaml = << [ + 'foobar' => 'foo #bar', + 'bar' => 'baz', + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testBlankLinesInQuotedMultiLineString() + { + $yaml = << "foo\nbar", + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testEscapedQuoteInQuotedMultiLineString() + { + $yaml = << 'foo "bar" baz', + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testBackslashInQuotedMultiLineString() + { + $yaml = << 'foo bar\\', + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testParseMultiLineUnquotedString() + { + $yaml = <<assertSame(['foo' => 'bar baz foobar foo', 'bar' => 'baz'], $this->parser->parse($yaml)); + } + + public function testParseMultiLineString() + { + $this->assertEquals("foo bar\nbaz", $this->parser->parse("foo\nbar\n\nbaz")); + } + + /** + * @dataProvider multiLineDataProvider + */ + public function testParseMultiLineMappingValue($yaml, $expected, $parseError) + { + $this->assertEquals($expected, $this->parser->parse($yaml)); + } + + public function multiLineDataProvider() + { + $tests = []; + + $yaml = <<<'EOF' +foo: +- bar: + one + + two + three +EOF; + $expected = [ + 'foo' => [ + [ + 'bar' => "one\ntwo three", + ], + ], + ]; + + $tests[] = [$yaml, $expected, false]; + + $yaml = <<<'EOF' +bar +"foo" +EOF; + $expected = 'bar "foo"'; + + $tests[] = [$yaml, $expected, false]; + + $yaml = <<<'EOF' +bar +"foo +EOF; + $expected = 'bar "foo'; + + $tests[] = [$yaml, $expected, false]; + + $yaml = <<<'EOF' +bar + +'foo' +EOF; + $expected = "bar\n'foo'"; + + $tests[] = [$yaml, $expected, false]; + + $yaml = <<<'EOF' +bar + +foo' +EOF; + $expected = "bar\nfoo'"; + + $tests[] = [$yaml, $expected, false]; + + return $tests; + } + + public function testTaggedInlineMapping() + { + $this->assertEquals(new TaggedValue('foo', ['foo' => 'bar']), $this->parser->parse('!foo {foo: bar}', Yaml::PARSE_CUSTOM_TAGS)); + } + + /** + * @dataProvider taggedValuesProvider + */ + public function testCustomTagSupport($expected, $yaml) + { + $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_CUSTOM_TAGS)); + } + + public function taggedValuesProvider() + { + return [ + 'sequences' => [ + [new TaggedValue('foo', ['yaml']), new TaggedValue('quz', ['bar'])], + << [ + new TaggedValue('foo', ['foo' => new TaggedValue('quz', ['bar']), 'quz' => new TaggedValue('foo', ['quz' => 'bar'])]), + << [ + [new TaggedValue('foo', ['foo', 'bar']), new TaggedValue('quz', ['foo' => 'bar', 'quz' => new TaggedValue('bar', ['one' => 'bar'])])], + <<expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Tags support is not enabled. Enable the `Yaml::PARSE_CUSTOM_TAGS` flag to use "!iterator" at line 1 (near "!iterator [foo]").'); + $this->parser->parse('!iterator [foo]'); + } + + /** + * @group legacy + * @expectedDeprecation Using the unquoted scalar value "!iterator foo" is deprecated since Symfony 3.3 and will be considered as a tagged value in 4.0. You must quote it on line 1. + */ + public function testUnsupportedTagWithScalar() + { + $this->assertEquals('!iterator foo', $this->parser->parse('!iterator foo')); + } + + public function testExceptionWhenUsingUnsupportedBuiltInTags() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('The built-in tag "!!foo" is not implemented at line 1 (near "!!foo").'); + $this->parser->parse('!!foo'); + } + + /** + * @group legacy + * @expectedDeprecation Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line 1. + */ + public function testComplexMappingThrowsParseException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @group legacy + * @expectedDeprecation Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line 2. + */ + public function testComplexMappingNestedInMappingThrowsParseException() + { + $yaml = <<parser->parse($yaml); + } + + /** + * @group legacy + * @expectedDeprecation Starting an unquoted string with a question mark followed by a space is deprecated since Symfony 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0 on line 1. + */ + public function testComplexMappingNestedInSequenceThrowsParseException() + { + $yaml = <<parser->parse($yaml); + } + + public function testParsingIniThrowsException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Unable to parse at line 1 (near "[parameters]").'); + $ini = <<parser->parse($ini); + } + + private function loadTestsFromFixtureFiles($testsFile) + { + $parser = new Parser(); + + $tests = []; + $files = $parser->parseFile(__DIR__.'/Fixtures/'.$testsFile); + foreach ($files as $file) { + $yamls = file_get_contents(__DIR__.'/Fixtures/'.$file.'.yml'); + + // split YAMLs documents + foreach (preg_split('/^---( %YAML\:1\.0)?/m', $yamls) as $yaml) { + if (!$yaml) { + continue; + } + + $test = $parser->parse($yaml); + if (isset($test['todo']) && $test['todo']) { + // TODO + } else { + eval('$expected = '.trim($test['php']).';'); + + $tests[] = [var_export($expected, true), $test['yaml'], $test['test'], isset($test['deprecated']) ? $test['deprecated'] : false]; + } + } + } + + return $tests; + } + + public function testCanParseVeryLongValue() + { + $longStringWithSpaces = str_repeat('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ', 20000); + $trickyVal = ['x' => $longStringWithSpaces]; + + $yamlString = Yaml::dump($trickyVal); + $arrayFromYaml = $this->parser->parse($yamlString); + + $this->assertEquals($trickyVal, $arrayFromYaml); + } + + public function testParserCleansUpReferencesBetweenRuns() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Reference "foo" does not exist at line 2'); + $yaml = <<parser->parse($yaml); + + $yaml = <<parser->parse($yaml); + } + + public function testPhpConstantTagMappingKey() + { + $yaml = << [ + 'foo' => [ + 'from' => [ + 'bar', + ], + 'to' => 'baz', + ], + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); + } + + /** + * @group legacy + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 2. + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 4. + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since Symfony 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead on line 5. + */ + public function testDeprecatedPhpConstantTagMappingKey() + { + $yaml = << [ + 'foo' => [ + 'from' => [ + 'bar', + ], + 'to' => 'baz', + ], + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); + } + + /** + * @group legacy + * @expectedDeprecation Using the Yaml::PARSE_KEYS_AS_STRINGS flag is deprecated since Symfony 3.4 as it will be removed in 4.0. Quote your keys when they are evaluable instead. + */ + public function testPhpConstantTagMappingKeyWithKeysCastToStrings() + { + $yaml = << [ + 'foo' => [ + 'from' => [ + 'bar', + ], + 'to' => 'baz', + ], + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS)); + } + + public function testPhpConstantTagMappingAsScalarKey() + { + $yaml = <<assertSame([ + 'map1' => [['foo' => 'value_0', 'bar' => 'value_1']], + 'map2' => [['foo' => 'value_0', 'bar' => 'value_1']], + ], $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); + } + + public function testTagMappingAsScalarKey() + { + $yaml = <<assertSame([ + 'map1' => [['0' => 'value_0', '1' => 'value_1']], + ], $this->parser->parse($yaml)); + } + + public function testMergeKeysWhenMappingsAreParsedAsObjects() + { + $yaml = << (object) [ + 'bar' => 1, + ], + 'bar' => (object) [ + 'baz' => 2, + 'bar' => 1, + ], + 'baz' => (object) [ + 'baz_foo' => 3, + 'baz_bar' => 4, + ], + 'foobar' => (object) [ + 'bar' => null, + 'baz' => 2, + ], + ]; + + $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP)); + } + + public function testFilenamesAreParsedAsStringsWithoutFlag() + { + $file = __DIR__.'/Fixtures/index.yml'; + + $this->assertSame($file, $this->parser->parse($file)); + } + + public function testParseFile() + { + $this->assertIsArray($this->parser->parseFile(__DIR__.'/Fixtures/index.yml')); + } + + public function testParsingNonExistentFilesThrowsException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessageMatches('#^File ".+/Fixtures/nonexistent.yml" does not exist\.$#'); + $this->parser->parseFile(__DIR__.'/Fixtures/nonexistent.yml'); + } + + public function testParsingNotReadableFilesThrowsException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessageMatches('#^File ".+/Fixtures/not_readable.yml" cannot be read\.$#'); + if ('\\' === \DIRECTORY_SEPARATOR) { + $this->markTestSkipped('chmod is not supported on Windows'); + } + + if (!getenv('USER') || 'root' === getenv('USER')) { + $this->markTestSkipped('This test will fail if run under superuser'); + } + + $file = __DIR__.'/Fixtures/not_readable.yml'; + chmod($file, 0200); + + $this->parser->parseFile($file); + } + + public function testParseReferencesOnMergeKeys() + { + $yaml = << [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'baz', + ], + 'mergekeyderef' => [ + 'd' => 'quux', + 'b' => 'bar', + 'c' => 'baz', + ], + ]; + + $this->assertSame($expected, $this->parser->parse($yaml)); + } + + public function testParseReferencesOnMergeKeysWithMappingsParsedAsObjects() + { + $yaml = << (object) [ + 'a' => 'foo', + 'b' => 'bar', + 'c' => 'baz', + ], + 'mergekeyderef' => (object) [ + 'd' => 'quux', + 'b' => 'bar', + 'c' => 'baz', + ], + ]; + + $this->assertEquals($expected, $this->parser->parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP)); + } + + public function testEvalRefException() + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Reference "foo" does not exist'); + $yaml = <<parser->parse($yaml); + } + + /** + * @dataProvider circularReferenceProvider + */ + public function testDetectCircularReferences($yaml) + { + $this->expectException('Symfony\Component\Yaml\Exception\ParseException'); + $this->expectExceptionMessage('Circular reference [foo, bar, foo] detected'); + $this->parser->parse($yaml, Yaml::PARSE_CUSTOM_TAGS); + } + + public function circularReferenceProvider() + { + $tests = []; + + $yaml = <<assertSame($expected, $this->parser->parse($yaml)); + } + + public function indentedMappingData() + { + $tests = []; + + $yaml = << [ + [ + 'bar' => 'foobar', + 'baz' => 'foobaz', + ], + ], + ]; + $tests['comment line is first line in indented block'] = [$yaml, $expected]; + + $yaml = << [ + [ + 'bar' => [ + 'baz' => [1, 2, 3], + ], + ], + ], + ]; + $tests['mapping value on new line starting with a comment line'] = [$yaml, $expected]; + + $yaml = << [ + [ + 'bar' => 'foobar', + ], + ], + ]; + $tests['mapping in sequence starting on a new line'] = [$yaml, $expected]; + + $yaml = << [ + 'bar' => 'baz', + ], + ]; + $tests['blank line at the beginning of an indented mapping value'] = [$yaml, $expected]; + + return $tests; + } + + public function testMultiLineComment() + { + $yaml = <<assertSame(['parameters' => 'abc'], $this->parser->parse($yaml)); + } + + public function testParseValueWithModifiers() + { + $yaml = <<assertSame( + [ + 'parameters' => [ + 'abc' => implode("\n", ['one', 'two', 'three', 'four', 'five']), + ], + ], + $this->parser->parse($yaml) + ); + } + + public function testParseValueWithNegativeModifiers() + { + $yaml = <<assertSame( + [ + 'parameters' => [ + 'abc' => implode("\n", ['one', 'two', 'three', 'four', 'five']), + ], + ], + $this->parser->parse($yaml) + ); + } + + /** + * This is a regression test for a bug where a YAML block with a nested multiline string using | was parsed without + * a trailing \n when a shorter YAML document was parsed before. + * + * When a shorter document was parsed before, the nested string did not have a \n at the end of the string, because + * the Parser thought it was the end of the file, even though it is not. + */ + public function testParsingMultipleDocuments() + { + $shortDocument = 'foo: bar'; + $longDocument = <<parser->parse($shortDocument); + + // After the total number of lines has been reset the result will be the same as if a new parser was used + // (before, there was no \n after row2) + $this->assertSame(['a' => ['b' => "row\nrow2\n"], 'c' => 'd'], $this->parser->parse($longDocument)); + } +} + +class B +{ + public $b = 'foo'; + + const FOO = 'foo'; + const BAR = 'bar'; + const BAZ = 'baz'; +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Tests/YamlTest.php b/modules/empikmarketplace/vendor/symfony/yaml/Tests/YamlTest.php new file mode 100644 index 00000000..7be12664 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Tests/YamlTest.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Yaml\Yaml; + +class YamlTest extends TestCase +{ + public function testParseAndDump() + { + $data = ['lorem' => 'ipsum', 'dolor' => 'sit']; + $yml = Yaml::dump($data); + $parsed = Yaml::parse($yml); + $this->assertEquals($data, $parsed); + } + + public function testZeroIndentationThrowsException() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The indentation must be greater than zero'); + Yaml::dump(['lorem' => 'ipsum', 'dolor' => 'sit'], 2, 0); + } + + public function testNegativeIndentationThrowsException() + { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('The indentation must be greater than zero'); + Yaml::dump(['lorem' => 'ipsum', 'dolor' => 'sit'], 2, -4); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Unescaper.php b/modules/empikmarketplace/vendor/symfony/yaml/Unescaper.php new file mode 100644 index 00000000..6a12999d --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Unescaper.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * Unescaper encapsulates unescaping rules for single and double-quoted + * YAML strings. + * + * @author Matthew Lewinski + * + * @internal + */ +class Unescaper +{ + /** + * Regex fragment that matches an escaped character in a double quoted string. + */ + const REGEX_ESCAPED_CHARACTER = '\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)'; + + /** + * Unescapes a single quoted string. + * + * @param string $value A single quoted string + * + * @return string The unescaped string + */ + public function unescapeSingleQuotedString($value) + { + return str_replace('\'\'', '\'', $value); + } + + /** + * Unescapes a double quoted string. + * + * @param string $value A double quoted string + * + * @return string The unescaped string + */ + public function unescapeDoubleQuotedString($value) + { + $callback = function ($match) { + return $this->unescapeCharacter($match[0]); + }; + + // evaluate the string + return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value); + } + + /** + * Unescapes a character that was found in a double-quoted string. + * + * @param string $value An escaped character + * + * @return string The unescaped character + */ + private function unescapeCharacter($value) + { + switch ($value[1]) { + case '0': + return "\x0"; + case 'a': + return "\x7"; + case 'b': + return "\x8"; + case 't': + return "\t"; + case "\t": + return "\t"; + case 'n': + return "\n"; + case 'v': + return "\xB"; + case 'f': + return "\xC"; + case 'r': + return "\r"; + case 'e': + return "\x1B"; + case ' ': + return ' '; + case '"': + return '"'; + case '/': + return '/'; + case '\\': + return '\\'; + case 'N': + // U+0085 NEXT LINE + return "\xC2\x85"; + case '_': + // U+00A0 NO-BREAK SPACE + return "\xC2\xA0"; + case 'L': + // U+2028 LINE SEPARATOR + return "\xE2\x80\xA8"; + case 'P': + // U+2029 PARAGRAPH SEPARATOR + return "\xE2\x80\xA9"; + case 'x': + return self::utf8chr(hexdec(substr($value, 2, 2))); + case 'u': + return self::utf8chr(hexdec(substr($value, 2, 4))); + case 'U': + return self::utf8chr(hexdec(substr($value, 2, 8))); + default: + throw new ParseException(sprintf('Found unknown escape character "%s".', $value)); + } + } + + /** + * Get the UTF-8 character for the given code point. + * + * @param int $c The unicode code point + * + * @return string The corresponding UTF-8 character + */ + private static function utf8chr($c) + { + if (0x80 > $c %= 0x200000) { + return \chr($c); + } + if (0x800 > $c) { + return \chr(0xC0 | $c >> 6).\chr(0x80 | $c & 0x3F); + } + if (0x10000 > $c) { + return \chr(0xE0 | $c >> 12).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); + } + + return \chr(0xF0 | $c >> 18).\chr(0x80 | $c >> 12 & 0x3F).\chr(0x80 | $c >> 6 & 0x3F).\chr(0x80 | $c & 0x3F); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/Yaml.php b/modules/empikmarketplace/vendor/symfony/yaml/Yaml.php new file mode 100644 index 00000000..87190833 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/Yaml.php @@ -0,0 +1,150 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Yaml; + +use Symfony\Component\Yaml\Exception\ParseException; + +/** + * Yaml offers convenience methods to load and dump YAML. + * + * @author Fabien Potencier + * + * @final since version 3.4 + */ +class Yaml +{ + const DUMP_OBJECT = 1; + const PARSE_EXCEPTION_ON_INVALID_TYPE = 2; + const PARSE_OBJECT = 4; + const PARSE_OBJECT_FOR_MAP = 8; + const DUMP_EXCEPTION_ON_INVALID_TYPE = 16; + const PARSE_DATETIME = 32; + const DUMP_OBJECT_AS_MAP = 64; + const DUMP_MULTI_LINE_LITERAL_BLOCK = 128; + const PARSE_CONSTANT = 256; + const PARSE_CUSTOM_TAGS = 512; + const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024; + + /** + * @deprecated since version 3.4, to be removed in 4.0. Quote your evaluable keys instead. + */ + const PARSE_KEYS_AS_STRINGS = 2048; + + /** + * Parses a YAML file into a PHP value. + * + * Usage: + * + * $array = Yaml::parseFile('config.yml'); + * print_r($array); + * + * @param string $filename The path to the YAML file to be parsed + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * + * @return mixed The YAML converted to a PHP value + * + * @throws ParseException If the file could not be read or the YAML is not valid + */ + public static function parseFile($filename, $flags = 0) + { + $yaml = new Parser(); + + return $yaml->parseFile($filename, $flags); + } + + /** + * Parses YAML into a PHP value. + * + * Usage: + * + * $array = Yaml::parse(file_get_contents('config.yml')); + * print_r($array); + * + * + * @param string $input A string containing YAML + * @param int $flags A bit field of PARSE_* constants to customize the YAML parser behavior + * + * @return mixed The YAML converted to a PHP value + * + * @throws ParseException If the YAML is not valid + */ + public static function parse($input, $flags = 0) + { + if (\is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the PARSE_EXCEPTION_ON_INVALID_TYPE flag instead.', \E_USER_DEPRECATED); + + if ($flags) { + $flags = self::PARSE_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (\func_num_args() >= 3) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the PARSE_OBJECT flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(2)) { + $flags |= self::PARSE_OBJECT; + } + } + + if (\func_num_args() >= 4) { + @trigger_error('Passing a boolean flag to toggle object for map support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the Yaml::PARSE_OBJECT_FOR_MAP flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(3)) { + $flags |= self::PARSE_OBJECT_FOR_MAP; + } + } + + $yaml = new Parser(); + + return $yaml->parse($input, $flags); + } + + /** + * Dumps a PHP value to a YAML string. + * + * The dump method, when supplied with an array, will do its best + * to convert the array into friendly YAML. + * + * @param mixed $input The PHP value + * @param int $inline The level where you switch to inline YAML + * @param int $indent The amount of spaces to use for indentation of nested nodes + * @param int $flags A bit field of DUMP_* constants to customize the dumped YAML string + * + * @return string A YAML string representing the original PHP value + */ + public static function dump($input, $inline = 2, $indent = 4, $flags = 0) + { + if (\is_bool($flags)) { + @trigger_error('Passing a boolean flag to toggle exception handling is deprecated since Symfony 3.1 and will be removed in 4.0. Use the DUMP_EXCEPTION_ON_INVALID_TYPE flag instead.', \E_USER_DEPRECATED); + + if ($flags) { + $flags = self::DUMP_EXCEPTION_ON_INVALID_TYPE; + } else { + $flags = 0; + } + } + + if (\func_num_args() >= 5) { + @trigger_error('Passing a boolean flag to toggle object support is deprecated since Symfony 3.1 and will be removed in 4.0. Use the DUMP_OBJECT flag instead.', \E_USER_DEPRECATED); + + if (func_get_arg(4)) { + $flags |= self::DUMP_OBJECT; + } + } + + $yaml = new Dumper($indent); + + return $yaml->dump($input, $inline, 0, $flags); + } +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/composer.json b/modules/empikmarketplace/vendor/symfony/yaml/composer.json new file mode 100644 index 00000000..b2f0286e --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/composer.json @@ -0,0 +1,38 @@ +{ + "name": "symfony/yaml", + "type": "library", + "description": "Symfony Yaml Component", + "keywords": [], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "autoload": { + "psr-4": { "Symfony\\Component\\Yaml\\": "" }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev" +} diff --git a/modules/empikmarketplace/vendor/symfony/yaml/phpunit.xml.dist b/modules/empikmarketplace/vendor/symfony/yaml/phpunit.xml.dist new file mode 100644 index 00000000..b5d4d914 --- /dev/null +++ b/modules/empikmarketplace/vendor/symfony/yaml/phpunit.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + ./Tests/ + + + + + + ./ + + ./Tests + ./vendor + + + + diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/index.php b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/index.php new file mode 100644 index 00000000..d8f7de2e --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2015 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig new file mode 100644 index 00000000..1b36d5ee --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig @@ -0,0 +1,158 @@ +{#** + * 2007-2018 PrestaShop + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + * versions in the future. If you wish to customize PrestaShop for your + * needs please refer to http://www.prestashop.com for more information. + * + * @author PrestaShop SA + * @copyright 2007-2018 PrestaShop SA + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + *#} + + {% for product in products %} + {% block product_catalog_form_table_row %} + + +
+ +
+ + + + + + {{ product.image|raw }} + + + {{ product.name|default('N/A'|trans({}, 'Admin.Global')) }} + + + {{ product.reference|default('') }} + + + {{ product.name_category|default('') }} + + + {{ product.price|default('N/A'|trans({}, 'Admin.Global')) }} + + + {{ product.price_final|default('N/A'|trans({}, 'Admin.Global')) }} + + + {% if 'PS_STOCK_MANAGEMENT'|configuration %} + + + {% if product.sav_quantity is defined and product.sav_quantity > 0 %} + {{ product.sav_quantity }} + {% else %} + {{ product.sav_quantity|default('N/A'|trans({}, 'Admin.Global')) }} + {% endif %} + + + {% else %} + + {% endif %} + + {% if product.active|default(0) == 0 %} + + clear + + {% else %} + + check + + {% endif %} + + + + + + + + + {{renderhook ('displayAdminCatalogTwigListingProductFields', {'product': product})}} + + + + + + + + {% if product.position is defined %} + + {% if activate_drag_and_drop %} + + {% endif %} + {{ product.position }} + + + + {% endif %} + +
+ + {% set buttons_action = [ + { + "href": product.preview_url|default('#'), + "target": "_blank", + "icon": "remove_red_eye", + "label": "Preview"|trans({}, 'Admin.Actions') + } + ] %} + + {% set buttons_action = buttons_action|merge([ + { + "onclick": "unitProductAction(this, 'duplicate');", + "icon": "content_copy", + "label": "Duplicate"|trans({}, 'Admin.Actions') + } + ]) %} + + {% set buttons_action = buttons_action|merge([ + { + "onclick": "unitProductAction(this, 'delete');", + "icon": "delete", + "label": "Delete"|trans({}, 'Admin.Actions') + } + ]) %} + + {% include '@Product/CatalogPage/Forms/form_edit_dropdown.html.twig' with { + 'button_id': "product_list_id_" ~ product.id_product ~ "_menu", + 'default_item': { + "href": product.url|default('#'), + "icon": "mode_edit" + }, + 'right': true, + 'items': buttons_action + } %} +
+ + + {% endblock %} +{% else %} + + {{ "There is no result for this search. Update your filters to view other products."|trans({}, 'Admin.Catalog.Notification') }} + +{% endfor %} diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig.bak b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig.bak new file mode 100644 index 00000000..12460b59 --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/list.html.twig.bak @@ -0,0 +1,155 @@ +{#** + * 2007-2018 PrestaShop + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + * versions in the future. If you wish to customize PrestaShop for your + * needs please refer to http://www.prestashop.com for more information. + * + * @author PrestaShop SA + * @copyright 2007-2018 PrestaShop SA + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + *#} + + {% for product in products %} + {% block product_catalog_form_table_row %} + + +
+ +
+ + + + + + {{ product.image|raw }} + + + {{ product.name|default('N/A'|trans({}, 'Admin.Global')) }} + + + {{ product.reference|default('') }} + + + {{ product.name_category|default('') }} + + + {{ product.price|default('N/A'|trans({}, 'Admin.Global')) }} + + + {% if 'PS_STOCK_MANAGEMENT'|configuration %} + + + {% if product.sav_quantity is defined and product.sav_quantity > 0 %} + {{ product.sav_quantity }} + {% else %} + {{ product.sav_quantity|default('N/A'|trans({}, 'Admin.Global')) }} + {% endif %} + + + {% else %} + + {% endif %} + + {% if product.active|default(0) == 0 %} + + clear + + {% else %} + + check + + {% endif %} + + + + + + + + + {{renderhook ('displayAdminCatalogTwigListingProductFields', {'product': product})}} + + + + + + + + {% if product.position is defined %} + + {% if activate_drag_and_drop %} + + {% endif %} + {{ product.position }} + + + + {% endif %} + +
+ + {% set buttons_action = [ + { + "href": product.preview_url|default('#'), + "target": "_blank", + "icon": "remove_red_eye", + "label": "Preview"|trans({}, 'Admin.Actions') + } + ] %} + + {% set buttons_action = buttons_action|merge([ + { + "onclick": "unitProductAction(this, 'duplicate');", + "icon": "content_copy", + "label": "Duplicate"|trans({}, 'Admin.Actions') + } + ]) %} + + {% set buttons_action = buttons_action|merge([ + { + "onclick": "unitProductAction(this, 'delete');", + "icon": "delete", + "label": "Delete"|trans({}, 'Admin.Actions') + } + ]) %} + + {% include '@Product/CatalogPage/Forms/form_edit_dropdown.html.twig' with { + 'button_id': "product_list_id_" ~ product.id_product ~ "_menu", + 'default_item': { + "href": product.url|default('#'), + "icon": "mode_edit" + }, + 'right': true, + 'items': buttons_action + } %} +
+ + + {% endblock %} +{% else %} + + {{ "There is no result for this search. Update your filters to view other products."|trans({}, 'Admin.Catalog.Notification') }} + +{% endfor %} diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig new file mode 100644 index 00000000..e0973ffb --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig @@ -0,0 +1,232 @@ +{#** + * 2007-2018 PrestaShop + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + * versions in the future. If you wish to customize PrestaShop for your + * needs please refer to http://www.prestashop.com for more information. + * + * @author PrestaShop SA + * @copyright 2007-2018 PrestaShop SA + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + *#} +{% import '@PrestaShop/Admin/macros.html.twig' as ps %} +
+ + + {% block product_catalog_form_table_header %} + + + + + + + + + + + {% if 'PS_STOCK_MANAGEMENT'|configuration %} + + {% else %} + + {% endif %} + + + + + + + + {{renderhook ('displayAdminCatalogTwigProductHeader')}} + + + + + + {% if has_category_filter == true %} + + {% endif %} + + + {% endblock %} + + {% block product_catalog_form_table_filters %} + {% set filters_disabled = activate_drag_and_drop %} + + + + + + + + + {% if 'PS_STOCK_MANAGEMENT'|configuration %} + + {% else %} + + {% endif %} + + + + + + + {{renderhook ('displayAdminCatalogTwigProductFilter')}} + + + + + + {% if has_category_filter == true %} + + {% endif %} + + + {% endblock %} + + {% block product_catalog_form_table_items %} + {{ render(controller('PrestaShopBundle\\Controller\\Admin\\ProductController::listAction', { + 'limit': limit, + 'offset': offset, + 'orderBy': orderBy, + 'sortOrder': sortOrder, + 'products': products, + 'last_sql': last_sql + })) }} + {% endblock %} +
+ {{ ps.sortable_column_header("ID"|trans({}, 'Admin.Global'), 'id_product', orderBy, sortOrder) }} + + {{ "Image"|trans({}, 'Admin.Global') }} + + {{ ps.sortable_column_header("Name"|trans({}, 'Admin.Global'), 'name', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Reference"|trans({}, 'Admin.Global'), 'reference', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Category"|trans({}, 'Admin.Catalog.Feature'), 'name_category', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Price (tax excl.)"|trans({}, 'Admin.Catalog.Feature'), 'price', orderBy, sortOrder) }} + + {{ "Price (tax incl.)"|trans({}, 'Admin.Catalog.Feature') }} + + {{ ps.sortable_column_header("Quantity"|trans({}, 'Admin.Catalog.Feature'), 'sav_quantity', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Status"|trans({}, 'Admin.Global'), 'active', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Position"|trans({}, 'Admin.Global'), 'position', orderBy, sortOrder) }} + + {{ "Actions"|trans({}, 'Admin.Global') }} +
+ {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { + 'input_name': "filter_column_id_product", + 'min': '0', + 'max': '1000000', + 'minLabel': "Min"|trans({}, 'Admin.Global'), + 'maxLabel': "Max"|trans({}, 'Admin.Global'), + 'value': filter_column_id_product, + 'disabled': filters_disabled, + } %} +   + + + + + + + {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { + 'input_name': "filter_column_price", + 'min': '0', + 'max': '1000000', + 'minLabel': "Min"|trans({}, 'Admin.Global'), + 'maxLabel': "Max"|trans({}, 'Admin.Global'), + 'value': filter_column_price, + 'disabled': filters_disabled, + } %} + + {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { + 'input_name': "filter_column_sav_quantity", + 'min': '-1000000', + 'max': '1000000', + 'minLabel': "Min"|trans({}, 'Admin.Global'), + 'maxLabel': "Max"|trans({}, 'Admin.Global'), + 'value': filter_column_sav_quantity, + 'disabled': filters_disabled, + } %} + +
+ +
+
+ {% if not(activate_drag_and_drop) %} + + {% else %} + + {% endif %} + + + +
+
diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig.bak b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig.bak new file mode 100644 index 00000000..0e9939c1 --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/Lists/products_table.html.twig.bak @@ -0,0 +1,229 @@ +{#** + * 2007-2018 PrestaShop + * + * NOTICE OF LICENSE + * + * This source file is subject to the Open Software License (OSL 3.0) + * that is bundled with this package in the file LICENSE.txt. + * It is also available through the world-wide-web at this URL: + * https://opensource.org/licenses/OSL-3.0 + * If you did not receive a copy of the license and are unable to + * obtain it through the world-wide-web, please send an email + * to license@prestashop.com so we can send you a copy immediately. + * + * DISCLAIMER + * + * Do not edit or add to this file if you wish to upgrade PrestaShop to newer + * versions in the future. If you wish to customize PrestaShop for your + * needs please refer to http://www.prestashop.com for more information. + * + * @author PrestaShop SA + * @copyright 2007-2018 PrestaShop SA + * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) + * International Registered Trademark & Property of PrestaShop SA + *#} +{% import '@PrestaShop/Admin/macros.html.twig' as ps %} +
+ + + {% block product_catalog_form_table_header %} + + + + + + + + + + {% if 'PS_STOCK_MANAGEMENT'|configuration %} + + {% else %} + + {% endif %} + + + + + + + + {{renderhook ('displayAdminCatalogTwigProductHeader')}} + + + + + + {% if has_category_filter == true %} + + {% endif %} + + + {% endblock %} + + {% block product_catalog_form_table_filters %} + {% set filters_disabled = activate_drag_and_drop %} + + + + + + + + + {% if 'PS_STOCK_MANAGEMENT'|configuration %} + + {% else %} + + {% endif %} + + + + + + + {{renderhook ('displayAdminCatalogTwigProductFilter')}} + + + + + + {% if has_category_filter == true %} + + {% endif %} + + + {% endblock %} + + {% block product_catalog_form_table_items %} + {{ render(controller('PrestaShopBundle\\Controller\\Admin\\ProductController::listAction', { + 'limit': limit, + 'offset': offset, + 'orderBy': orderBy, + 'sortOrder': sortOrder, + 'products': products, + 'last_sql': last_sql + })) }} + {% endblock %} +
+ {{ ps.sortable_column_header("ID"|trans({}, 'Admin.Global'), 'id_product', orderBy, sortOrder) }} + + {{ "Image"|trans({}, 'Admin.Global') }} + + {{ ps.sortable_column_header("Name"|trans({}, 'Admin.Global'), 'name', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Reference"|trans({}, 'Admin.Global'), 'reference', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Category"|trans({}, 'Admin.Catalog.Feature'), 'name_category', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Price (tax excl.)"|trans({}, 'Admin.Catalog.Feature'), 'price', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Quantity"|trans({}, 'Admin.Catalog.Feature'), 'sav_quantity', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Status"|trans({}, 'Admin.Global'), 'active', orderBy, sortOrder) }} + + {{ ps.sortable_column_header("Position"|trans({}, 'Admin.Global'), 'position', orderBy, sortOrder) }} + + {{ "Actions"|trans({}, 'Admin.Global') }} +
+ {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { + 'input_name': "filter_column_id_product", + 'min': '0', + 'max': '1000000', + 'minLabel': "Min"|trans({}, 'Admin.Global'), + 'maxLabel': "Max"|trans({}, 'Admin.Global'), + 'value': filter_column_id_product, + 'disabled': filters_disabled, + } %} +   + + + + + + + {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { + 'input_name': "filter_column_price", + 'min': '0', + 'max': '1000000', + 'minLabel': "Min"|trans({}, 'Admin.Global'), + 'maxLabel': "Max"|trans({}, 'Admin.Global'), + 'value': filter_column_price, + 'disabled': filters_disabled, + } %} + + {% include '@PrestaShop/Admin/Helpers/range_inputs.html.twig' with { + 'input_name': "filter_column_sav_quantity", + 'min': '-1000000', + 'max': '1000000', + 'minLabel': "Min"|trans({}, 'Admin.Global'), + 'maxLabel': "Max"|trans({}, 'Admin.Global'), + 'value': filter_column_sav_quantity, + 'disabled': filters_disabled, + } %} + +
+ +
+
+ {% if not(activate_drag_and_drop) %} + + {% else %} + + {% endif %} + + + +
+
diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/index.php b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/index.php new file mode 100644 index 00000000..d8f7de2e --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/CatalogPage/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2015 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/Product/index.php b/modules/empikmarketplace/views/PrestaShop/Admin/Product/index.php new file mode 100644 index 00000000..d8f7de2e --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/Product/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2015 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/modules/empikmarketplace/views/PrestaShop/Admin/index.php b/modules/empikmarketplace/views/PrestaShop/Admin/index.php new file mode 100644 index 00000000..d8f7de2e --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/Admin/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2015 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/modules/empikmarketplace/views/PrestaShop/index.php b/modules/empikmarketplace/views/PrestaShop/index.php new file mode 100644 index 00000000..d8f7de2e --- /dev/null +++ b/modules/empikmarketplace/views/PrestaShop/index.php @@ -0,0 +1,35 @@ + +* @copyright 2007-2015 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*/ + +header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); +header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + +header("Cache-Control: no-store, no-cache, must-revalidate"); +header("Cache-Control: post-check=0, pre-check=0", false); +header("Pragma: no-cache"); + +header("Location: ../"); +exit; diff --git a/modules/empikmarketplace/views/css/admin/empik.css b/modules/empikmarketplace/views/css/admin/empik.css new file mode 100644 index 00000000..9bcf8e7c --- /dev/null +++ b/modules/empikmarketplace/views/css/admin/empik.css @@ -0,0 +1,3 @@ +.icon-AdminEmpik::before { + content: "\f0b1"; +} diff --git a/modules/empikmarketplace/views/css/admin/index.php b/modules/empikmarketplace/views/css/admin/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/views/css/admin/index.php @@ -0,0 +1,11 @@ + { + if (response.success && typeof response.message !== 'undefined') { + showSuccessMessage(response.message); + } + }, + }); + }); +}); diff --git a/modules/empikmarketplace/views/js/admin/index.php b/modules/empikmarketplace/views/js/admin/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/views/js/admin/index.php @@ -0,0 +1,11 @@ + +   + {l s='Export offers' mod='empikmarketplace'} + \ No newline at end of file diff --git a/modules/empikmarketplace/views/templates/admin/_partials/index.php b/modules/empikmarketplace/views/templates/admin/_partials/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/_partials/index.php @@ -0,0 +1,11 @@ + +   + {l s='Manage dedicated EmpikPlace prices' mod='empikmarketplace'} + \ No newline at end of file diff --git a/modules/empikmarketplace/views/templates/admin/_partials/shipping-table.tpl b/modules/empikmarketplace/views/templates/admin/_partials/shipping-table.tpl new file mode 100644 index 00000000..9dfc5746 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/_partials/shipping-table.tpl @@ -0,0 +1,39 @@ + + + + + + + + + + {foreach from=$empik_shipping_types item=empik_shipping_type} + + + + + + {/foreach} + +
{l s='Empik Marketplace carrier' mod='empikmarketplace'}{l s='Shop carrier' mod='empikmarketplace'}{l s='Carrier type' mod='empikmarketplace'}
{$empik_shipping_type.label} ({$empik_shipping_type.code}) + + + +
diff --git a/modules/empikmarketplace/views/templates/admin/_partials/shipping_table.tpl b/modules/empikmarketplace/views/templates/admin/_partials/shipping_table.tpl new file mode 100644 index 00000000..adeab4f4 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/_partials/shipping_table.tpl @@ -0,0 +1,40 @@ + + + + + + + + + + {foreach from=$empik_shipping_types item=empik_shipping_type} + + + + + + {/foreach} + +
{l s='Empik Marketplace carrier' mod='empikmarketplace'}{l s='Shop carrier' mod='empikmarketplace'}{l s='Carrier type' mod='empikmarketplace'}
{$empik_shipping_type.label} ({$empik_shipping_type.code}) + + + +
diff --git a/modules/empikmarketplace/views/templates/admin/_partials/test_connection_button.tpl b/modules/empikmarketplace/views/templates/admin/_partials/test_connection_button.tpl new file mode 100644 index 00000000..7b6d6a7d --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/_partials/test_connection_button.tpl @@ -0,0 +1,3 @@ + diff --git a/modules/empikmarketplace/views/templates/admin/_partials/test_connection_footer.tpl b/modules/empikmarketplace/views/templates/admin/_partials/test_connection_footer.tpl new file mode 100644 index 00000000..0e655291 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/_partials/test_connection_footer.tpl @@ -0,0 +1,3 @@ + + {l s='Przetestuj połączenie' mod='empikmarketplace'} + diff --git a/modules/empikmarketplace/views/templates/admin/help.tpl b/modules/empikmarketplace/views/templates/admin/help.tpl new file mode 100644 index 00000000..4fe00d37 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/help.tpl @@ -0,0 +1,87 @@ +
+
+ {l s='Help' mod='empikmarketplace'} +
+
+
+

{l s='Funkcje:' mod='empikmarketplace'}

+
+
    +
  • {l s='Dwustronne połączenie API PrestaShop - EmpikPlace' mod='empikmarketplace'}
  • +
  • {l s='Wybór środowiska pracy: produkcyjne/testowe' mod='empikmarketplace'}
  • +
  • {l s='Wystawianie produktów' mod='empikmarketplace'}
  • +
  • {l s='Wystawianie ofert' mod='empikmarketplace'}
  • +
  • {l s='Zarządzanie ofertami' mod='empikmarketplace'}
  • +
  • {l s='Synchronizację stanów magazynowych' mod='empikmarketplace'}
  • +
  • {l s='Synchronizację cen i cen promocyjnych' mod='empikmarketplace'}
  • +
  • {l s='Akceptację i pobieranie zamówień' mod='empikmarketplace'}
  • +
  • {l s='Przekazywanie numerów przesyłek' mod='empikmarketplace'}
  • +
  • {l s='Mapowanie statusów zamówień' mod='empikmarketplace'}
  • +
  • {l s='Mapowanie form dostaw' mod='empikmarketplace'}
  • +
  • {l s='Zmianę statusów zamówień' mod='empikmarketplace'}
  • +
  • {l s='Oraz wiele innych funkcjonalności' mod='empikmarketplace'}
  • +
+

{l s='Interwały wymiany informacji:' mod='empikmarketplace'}

+
+
    +
  • {l s='Akceptowanie i pobieranie zamówień - zgodnie z ustawieniami CRON' mod='empikmarketplace'}
  • +
  • {l s='Synchronizację stanów i cen magazynowych - zgodnie z ustawieniami CRON' mod='empikmarketplace'}
  • +
  • {l s='Zmiana statusu zamówienia oraz dodanie listu przewozowego - bezzwłocznie po zmianie statusu w PrestaShop' mod='empikmarketplace'}
  • +
  • {l s='Jednorazowe wystawianie produktów / ofert - bezzwłocznie po wykonaniu akcji' mod='empikmarketplace'}
  • +
+
+ +
+ + +
+
+

{l s='Film instruktażowy:' mod='empikmarketplace'}

+
+
+ +
+
+
+
+ +
+
+ {l s='CRON jobs' mod='empikmarketplace'} +
+
+

{l s='Update offers' mod='empikmarketplace'}

+
{$cron_jobs.exportOffers}
+
+
+

{l s='Import orders' mod='empikmarketplace'}

+
{$cron_jobs.importOrders}
+
+
+

{l s='Export products' mod='empikmarketplace'}

+
{$cron_jobs.exportProducts}
+
+
diff --git a/modules/empikmarketplace/views/templates/admin/hook/admin_order.tpl b/modules/empikmarketplace/views/templates/admin/hook/admin_order.tpl new file mode 100644 index 00000000..474bfcf0 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/hook/admin_order.tpl @@ -0,0 +1,17 @@ +
+
+ {l s='Empik marketplace' mod='empikmarketplace'} +
+
+

{l s='Order reference' mod='empikmarketplace'}: {$empik_order.empik_order_reference}

+

{l s='Empik payment' mod='empikmarketplace'}: {$empik_order.empik_payment}

+

{l s='Empik carrier' mod='empikmarketplace'}: {$empik_order.empik_carrier}

+ + {if $empik_order.empik_pickup_point} +

{l s='Pickup point' mod='empikmarketplace'}: {$empik_order.empik_pickup_point}

+ {/if} + {if $empik_order.empik_vat_number} +

{l s='VAT number' mod='empikmarketplace'}: {$empik_order.empik_vat_number}

+ {/if} +
+
diff --git a/modules/empikmarketplace/views/templates/admin/hook/index.php b/modules/empikmarketplace/views/templates/admin/hook/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/hook/index.php @@ -0,0 +1,11 @@ + + + diff --git a/modules/empikmarketplace/views/templates/admin/list_action_edit_price.tpl b/modules/empikmarketplace/views/templates/admin/list_action_edit_price.tpl new file mode 100644 index 00000000..f15f60e7 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/list_action_edit_price.tpl @@ -0,0 +1,27 @@ +{if !empty($combinations)} + + +{else} +
+ +
+{/if} diff --git a/modules/empikmarketplace/views/templates/admin/list_action_edit_price_reduced.tpl b/modules/empikmarketplace/views/templates/admin/list_action_edit_price_reduced.tpl new file mode 100644 index 00000000..a68f82c4 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/list_action_edit_price_reduced.tpl @@ -0,0 +1,27 @@ +{if !empty($combinations)} + + +{else} +
+ +
+{/if} diff --git a/modules/empikmarketplace/views/templates/admin/list_action_enable.tpl b/modules/empikmarketplace/views/templates/admin/list_action_enable.tpl new file mode 100644 index 00000000..35f67199 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/list_action_enable.tpl @@ -0,0 +1,10 @@ + + {if $enabled} + {l s='Enabled' mod='empikmarketplace'} + {else} + {l s='Disabled' mod='empikmarketplace'} + {/if} + diff --git a/modules/empikmarketplace/views/templates/admin/list_action_original_price.tpl b/modules/empikmarketplace/views/templates/admin/list_action_original_price.tpl new file mode 100644 index 00000000..7b86f4b7 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/list_action_original_price.tpl @@ -0,0 +1,10 @@ + + {if $displayOriginal} + {l s='Yes' mod='empikmarketplace'} + {else} + {l s='No' mod='empikmarketplace'} + {/if} + diff --git a/modules/empikmarketplace/views/templates/admin/list_category_filter.tpl b/modules/empikmarketplace/views/templates/admin/list_category_filter.tpl new file mode 100644 index 00000000..c123e061 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/list_category_filter.tpl @@ -0,0 +1,19 @@ +{$tree} + + diff --git a/modules/empikmarketplace/views/templates/admin/products.tpl b/modules/empikmarketplace/views/templates/admin/products.tpl new file mode 100644 index 00000000..4a550796 --- /dev/null +++ b/modules/empikmarketplace/views/templates/admin/products.tpl @@ -0,0 +1,50 @@ + diff --git a/modules/empikmarketplace/views/templates/index.php b/modules/empikmarketplace/views/templates/index.php new file mode 100644 index 00000000..88355f61 --- /dev/null +++ b/modules/empikmarketplace/views/templates/index.php @@ -0,0 +1,11 @@ +blockModuleCache($modulesToInvoke, $hookName); + } + return !empty($modulesToInvoke) ? $modulesToInvoke : false; + } + /* + * module: cookiesplus + * date: 2025-04-23 19:57:25 + * version: 1.6.0 */ public static function coreCallHook($module, $method, $params) { - if (defined('_LITESPEED_DEBUG_') - && _LITESPEED_DEBUG_ >= LiteSpeedCacheLog::LEVEL_HOOK_DETAIL) { - $mesg = ' in hook coreCallHook ' . get_class($module) . ' - ' . $method; - LiteSpeedCacheLog::log($mesg, LiteSpeedCacheLog::LEVEL_HOOK_DETAIL); + $headersBeforeExecution = headers_list(); + $display = parent::coreCallHook($module, $method, $params); + if (Module::isEnabled('cookiesplus')) { + $forceDisplay = false; + $cookiesPlus = Module::getInstanceByName('cookiesplus'); + $cookiesPlus->blockModuleCode([ + 'display' => &$display, + 'module' => &$module, + 'hookName' => &$method, + 'params' => &$params, + 'forceDisplay' => &$forceDisplay, + 'headersBeforeExecution' => $headersBeforeExecution, + ]); + if ($forceDisplay) { + return $display; + } } - $html = parent::coreCallHook($module, $method, $params); - if (defined('_LITESPEED_CACHE_') - && ($marker = LiteSpeedCache::injectCallHook($module, $method)) !== false) { - $html = $marker . $html . LiteSpeedCache::ESI_MARKER_END; - } - return $html; + return $display; } /* - * module: litespeedcache - * date: 2019-06-29 10:06:58 - * version: 1.2.6 + * module: cookiesplus + * date: 2025-04-23 19:57:25 + * version: 1.6.0 */ public static function coreRenderWidget($module, $hook_name, $params) { - if (defined('_LITESPEED_DEBUG_') - && _LITESPEED_DEBUG_ >= LiteSpeedCacheLog::LEVEL_HOOK_DETAIL) { - $mesg = ' in hook coreRenderWidget module ' . get_class($module) . ' - ' . $hook_name; - LiteSpeedCacheLog::log($mesg, LiteSpeedCacheLog::LEVEL_HOOK_DETAIL); + $headersBeforeExecution = headers_list(); + $display = parent::coreRenderWidget($module, $hook_name, $params); + if (Module::isEnabled('cookiesplus')) { + $forceDisplay = false; + $cookiesPlus = Module::getInstanceByName('cookiesplus'); + $cookiesPlus->blockModuleCode([ + 'display' => &$display, + 'module' => &$module, + 'hookName' => &$hook_name, + 'params' => &$params, + 'forceDisplay' => &$forceDisplay, + 'headersBeforeExecution' => $headersBeforeExecution, + ]); + if ($forceDisplay) { + return $display; + } } - $html = parent::coreRenderWidget($module, $hook_name, $params); - if (defined('_LITESPEED_CACHE_') - && ($marker = LiteSpeedCache::injectRenderWidget($module, $hook_name)) !== false) { - $html = $marker . $html . LiteSpeedCache::ESI_MARKER_END; - } - return $html; + return $display; } }