From f7b54ad6fed8f943e7c1a389f0da6728522a7474 Mon Sep 17 00:00:00 2001 From: Ji Lu Date: Thu, 7 Jan 2016 16:18:56 -0600 Subject: [PATCH 1/5] MAGETWO-46577: HTTPS header options configuration test. --- .../Backend/Test/Block/System/Config/Form.php | 109 +++++++++++++++--- .../Test/Block/System/Config/Form/Group.php | 76 ++++++------ .../AssertHttpsHeaderOptionsAvailable.php | 77 +++++++++++++ .../AssertHttpsHeaderOptionsNotAvailable.php | 71 ++++++++++++ .../Constraint/AssertStoreCanBeLocalized.php | 5 +- .../Test/Page/Adminhtml/SystemConfigEdit.xml | 15 +++ .../Backend/Test/Repository/ConfigData.xml | 45 ++++++++ .../Test/TestCase/HttpsHeadersDisableTest.php | 52 +++++++++ .../Test/TestCase/HttpsHeadersDisableTest.xml | 18 +++ .../Test/TestCase/HttpsHeadersEnableTest.php | 52 +++++++++ .../Test/TestCase/HttpsHeadersEnableTest.xml | 18 +++ 11 files changed, 484 insertions(+), 54 deletions(-) create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsAvailable.php create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsNotAvailable.php create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfigEdit.xml create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.xml create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php create mode 100644 dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.xml diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form.php index 86ae1d8d66a06..35250af124192 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form.php @@ -1,53 +1,130 @@ baseUrl = $this->browser->getUrl(); + if (substr($this->baseUrl, -1) !== '/') { + $this->baseUrl = $this->baseUrl . '/'; + } + } + + /** + * Obtain store configuration form group. + * + * @param string $tabName + * @param string $groupName * @return Form\Group */ - public function getGroup($name) + public function getGroup($tabName, $groupName) { - $blockFactory = Factory::getBlockFactory(); - $element = $this->_rootElement->find( - sprintf($this->groupBlock, $name), - Locator::SELECTOR_XPATH + $tabUrl = $this->baseUrl . 'section/' . $tabName; + if ($this->getBrowserUrl() !== $tabUrl) { + $this->browser->open($tabUrl); + } + $this->waitForElementNotVisible($this->tabReadiness); + + $groupElement = $this->_rootElement->find( + sprintf($this->groupBlock, $tabName, $groupName), + Locator::SELECTOR_CSS ); - return $blockFactory->getMagentoBackendSystemConfigFormGroup($element); + + if (!$groupElement->isVisible()) { + $this->_rootElement->find( + sprintf($this->groupBlockLink, $tabName, $groupName), + Locator::SELECTOR_CSS + )->click(); + + $this->waitForElementNotVisible($this->tabReadiness); + + $groupElement = $this->_rootElement->find( + sprintf($this->groupBlock, $tabName, $groupName), + Locator::SELECTOR_CSS + ); + } + + $blockFactory = Factory::getBlockFactory(); + return $blockFactory->getMagentoBackendSystemConfigFormGroup($groupElement); + } + + /** + * Retrieve url associated with the form. + */ + public function getBrowserUrl() + { + return $this->browser->getUrl(); } /** - * Save store configuration + * Save store configuration. */ public function save() { - $this->_rootElement->find($this->saveButton, Locator::SELECTOR_XPATH)->click(); + $this->_rootElement->find($this->saveButton, Locator::SELECTOR_CSS)->click(); } } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form/Group.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form/Group.php index 09123d09767bf..efaf58fed1584 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form/Group.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/Form/Group.php @@ -1,6 +1,6 @@ _rootElement->find($this->fieldset)->isVisible()) { - $this->_rootElement->find($this->toogleLink)->click(); - } - } - - /** - * Set store configuration value by element data-ui-id - * - * @param string $field + * @param string $tabName + * @param string $groupName + * @param string $fieldName * @param mixed $value */ - public function setValue($field, $value) + public function setValue($tabName, $groupName, $fieldName, $value) { $input = null; - $fieldParts = explode('-', $field); - if (in_array($fieldParts[0], ['select', 'checkbox'])) { - $input = $fieldParts[0]; + $attribute = $this->_rootElement->find( + sprintf($this->field, $tabName, $groupName, $fieldName), + Locator::SELECTOR_CSS + )->getAttribute('data-ui-id'); + + $parts = explode('-', $attribute, 2); + if (in_array($parts[0], ['select', 'text', 'checkbox'])) { + $input = $parts[0]; } $element = $this->_rootElement->find( - sprintf($this->element, $field), - Locator::SELECTOR_XPATH, + sprintf($this->field, $tabName, $groupName, $fieldName), + Locator::SELECTOR_CSS, $input ); if ($element->isDisabled()) { $checkbox = $this->_rootElement->find( - sprintf($this->defaultCheckbox, $field), - Locator::SELECTOR_XPATH, + sprintf($this->defaultCheckbox, $tabName, $groupName, $fieldName), + Locator::SELECTOR_CSS, 'checkbox' ); $checkbox->setValue('No'); @@ -85,4 +75,20 @@ public function setValue($field, $value) $element->setValue($value); } + + /** + * Check if a field is visible in a given group. + * + * @param string $tabName + * @param string $groupName + * @param string $fieldName + * @return bool + */ + public function isFieldVisible($tabName, $groupName, $fieldName) + { + $this->_rootElement->find( + sprintf($this->field, $tabName, $groupName, $fieldName), + Locator::SELECTOR_CSS + )->isVisible(); + } } diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsAvailable.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsAvailable.php new file mode 100644 index 0000000000000..fc670da5b445f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsAvailable.php @@ -0,0 +1,77 @@ +verifyConfiguration($systemConfigEdit, $hsts); + $this->verifyConfiguration($systemConfigEdit, $upgradeInsecure); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'HTTPS headers configuration verification successfully.'; + } + + /** + * Verify configurations. + * + * @param SystemConfigEdit $systemConfigEdit + * @param ConfigData $config + * @return void + */ + private function verifyConfiguration(SystemConfigEdit $systemConfigEdit, ConfigData $config) + { + $section = $config->getSection(); + $keys = array_keys($section); + foreach ($keys as $key) { + $parts = explode('/', $key, 3); + $tabName = $parts[0]; + $groupName = $parts[1]; + $fieldName = $parts[2]; + try { + $group = $systemConfigEdit->getForm()->getGroup($tabName, $groupName); + $group->setValue($tabName, $groupName, $fieldName, 'Yes'); + $group->setValue($tabName, $groupName, $fieldName, 'No'); + \PHPUnit_Framework_Assert::assertTrue( + true, + $fieldName . " configuration is enabled with options Yes & No." + ); + } catch (\PHPUnit_Extensions_Selenium2TestCase_WebDriverException $e) { + \PHPUnit_Framework_Assert::assertFalse( + true, + $fieldName . " configuration is not enabled with options Yes & No." + ); + } + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsNotAvailable.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsNotAvailable.php new file mode 100644 index 0000000000000..e1c9215997900 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertHttpsHeaderOptionsNotAvailable.php @@ -0,0 +1,71 @@ +verifyConfiguration($systemConfigEdit, $hsts); + $this->verifyConfiguration($systemConfigEdit, $upgradeInsecure); + } + + /** + * Returns a string representation of the object. + * + * @return string + */ + public function toString() + { + return 'HTTPS headers not visible verification successfully.'; + } + + /** + * Verify configurations. + * + * @param SystemConfigEdit $systemConfigEdit + * @param ConfigData $config + * @return void + */ + private function verifyConfiguration( + SystemConfigEdit $systemConfigEdit, + ConfigData $config + ) { + $section = $config->getSection(); + $keys = array_keys($section); + foreach ($keys as $key) { + $parts = explode('/', $key, 3); + $tabName = $parts[0]; + $groupName = $parts[1]; + $fieldName = $parts[2]; + $isVisible = $systemConfigEdit->getForm()->getGroup($tabName, $groupName) + ->isFieldVisible($tabName, $groupName, $fieldName); + \PHPUnit_Framework_Assert::assertTrue( + !$isVisible, + $fieldName . " configuration is not visible." + ); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php index fd241121f62fc..97d98e8c33289 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertStoreCanBeLocalized.php @@ -39,9 +39,8 @@ public function processAssert( $systemConfig->open(); $systemConfig->getPageActions()->selectStore($store->getGroupId() . "/" . $store->getName()); $systemConfig->getModalBlock()->acceptAlert(); - $configGroup = $systemConfig->getForm()->getGroup('Locale Options'); - $configGroup->open(); - $configGroup->setValue('select-groups-locale-fields-code-value', $locale); + $configGroup = $systemConfig->getForm()->getGroup('general', 'locale', 'code'); + $configGroup->setValue('general', 'locale', 'code', $locale); $systemConfig->getPageActions()->save(); $systemConfig->getMessagesBlock()->waitSuccessMessage(); diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfigEdit.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfigEdit.xml new file mode 100644 index 0000000000000..2d9ad23671175 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfigEdit.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Repository/ConfigData.xml index 107555040bc1d..9ac49e41ebb6f 100644 --- a/dev/tests/functional/tests/app/Magento/Backend/Test/Repository/ConfigData.xml +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Repository/ConfigData.xml @@ -132,5 +132,50 @@ 0 + + + + default + 0 + Yes + 1 + + + default + 0 + Yes + 1 + + + + + default + 0 + Yes + 1 + + + + + default + 0 + Yes + 1 + + + + + default + 0 + Yes + 1 + + + default + 0 + No + 0 + + diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php new file mode 100644 index 0000000000000..0a296699acb7e --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.php @@ -0,0 +1,52 @@ + Configuration -> General -> Web. + * 3. Set "Use Secure URLs on Storefront" to Yes. + * 4. Set "Use Secure URLs in Admin" to No. + * 5. Perform asserts. + * + * @ZephyrId MAGETWO-46903 + */ +class HttpsHeadersDisableTest extends Injectable +{ + /* tags */ + const MVP = 'no'; + const DOMAIN = 'PS'; + /* end tags */ + + /** + * Open backend system config and set configuration values. + * + * @param SystemConfigEdit $systemConfigEdit + * @param ConfigData $httpsConfig + * @return void + */ + public function test(SystemConfigEdit $systemConfigEdit, ConfigData $httpsConfig) + { + $systemConfigEdit->open(); + $section = $httpsConfig->getSection(); + $keys = array_keys($section); + foreach ($keys as $key) { + $parts = explode('/', $key, 3); + $tabName = $parts[0]; + $groupName = $parts[1]; + $fieldName = $parts[2]; + $systemConfigEdit->getForm()->getGroup($tabName, $groupName) + ->setValue($tabName, $groupName, $fieldName, $section[$key]['label']); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.xml new file mode 100644 index 0000000000000..b043ed89adcc3 --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersDisableTest.xml @@ -0,0 +1,18 @@ + + + + + + enable_https_frontend_only + enable_hsts + enable_upgrade_insecure + + + + + diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php new file mode 100644 index 0000000000000..f6269a49a212f --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.php @@ -0,0 +1,52 @@ + Configuration -> General -> Web. + * 3. Set "Use Secure URLs on Storefront" to Yes. + * 4. Set "Use Secure URLs in Admin" to Yes. + * 5. Perform asserts. + * + * @ZephyrId MAGETWO-46903 + */ +class HttpsHeadersEnableTest extends Injectable +{ + /* tags */ + const MVP = 'no'; + const DOMAIN = 'PS'; + /* end tags */ + + /** + * Open backend system config and set configuration values. + * + * @param SystemConfigEdit $systemConfigEdit + * @param ConfigData $httpsConfig + * @return void + */ + public function test(SystemConfigEdit $systemConfigEdit, ConfigData $httpsConfig) + { + $systemConfigEdit->open(); + $section = $httpsConfig->getSection(); + $keys = array_keys($section); + foreach ($keys as $key) { + $parts = explode('/', $key, 3); + $tabName = $parts[0]; + $groupName = $parts[1]; + $fieldName = $parts[2]; + $systemConfigEdit->getForm()->getGroup($tabName, $groupName) + ->setValue($tabName, $groupName, $fieldName, $section[$key]['label']); + } + } +} diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.xml new file mode 100644 index 0000000000000..492aed203098b --- /dev/null +++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/HttpsHeadersEnableTest.xml @@ -0,0 +1,18 @@ + + + + + + enable_https_frontend_admin + enable_hsts + enable_upgrade_insecure + + + + + From cab5e06c159c71087f7a3bbb66c8454d227a8495 Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Wed, 20 Jan 2016 15:01:33 -0600 Subject: [PATCH 2/5] MAGETWO-47958: Include Redis generic session adapter in Magento 2 Including generic session adapter library --- app/etc/di.xml | 9 + composer.json | 4 +- composer.lock | 171 ++- lib/internal/Credis/Client.php | 1113 ----------------- .../Config/ConfigOptionsListConstants.php | 1 + .../Magento/Framework/Session/Config.php | 40 +- .../Session/Config/ConfigInterface.php | 15 + .../Magento/Framework/Session/SaveHandler.php | 9 +- .../Framework/Session/SaveHandler/Redis.php | 51 + .../Session/SaveHandler/Redis/Config.php | 247 ++++ .../Session/SaveHandler/Redis/Logger.php | 93 ++ .../Session/Test/Unit/ConfigTest.php | 6 +- .../Unit/SaveHandler/Redis/ConfigTest.php | 214 ++++ .../Unit/SaveHandler/Redis/LoggerTest.php | 95 ++ .../ConfigOptionsListTest.php | 4 +- 15 files changed, 900 insertions(+), 1172 deletions(-) delete mode 100644 lib/internal/Credis/Client.php create mode 100644 lib/internal/Magento/Framework/Session/SaveHandler/Redis.php create mode 100644 lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php create mode 100644 lib/internal/Magento/Framework/Session/SaveHandler/Redis/Logger.php create mode 100644 lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php create mode 100644 lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/LoggerTest.php rename setup/src/Magento/Setup/Test/Unit/{Module => Model}/ConfigOptionsListTest.php (99%) diff --git a/app/etc/di.xml b/app/etc/di.xml index 99b0ddbbe3878..256a424f14f93 100755 --- a/app/etc/di.xml +++ b/app/etc/di.xml @@ -142,6 +142,8 @@ + + @@ -187,9 +189,16 @@ Magento\Framework\Session\SaveHandler\DbTable + Magento\Framework\Session\SaveHandler\Redis + + + Cm\RedisSession\Handler\ConfigInterface + Cm\RedisSession\Handler\LoggerInterface + + global diff --git a/composer.json b/composer.json index 2690ac011a465..6de9572c2a958 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,8 @@ "zendframework/zend-log": "~2.4.6", "zendframework/zend-http": "~2.4.6", "magento/zendframework1": "1.12.16", + "colinmollenhour/credis": "1.6", + "colinmollenhour/php-redis-session-abstract": "1.0", "composer/composer": "1.0.0-alpha10", "monolog/monolog": "1.16.0", "oyejorge/less.php": "1.7.0.3", @@ -183,7 +185,6 @@ "magento/framework": "100.0.2", "trentrichardson/jquery-timepicker-addon": "1.4.3", "colinmollenhour/cache-backend-redis": "1.8", - "colinmollenhour/credis": "1.5", "components/jquery": "1.11.0", "blueimp/jquery-file-upload": "5.6.14", "components/jqueryui": "1.10.4", @@ -194,7 +195,6 @@ "component_paths": { "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js", "colinmollenhour/cache-backend-redis": "lib/internal/Cm/Cache/Backend/Redis.php", - "colinmollenhour/credis": "lib/internal/Credis", "components/jquery": [ "lib/web/jquery.js", "lib/web/jquery/jquery.min.js", diff --git a/composer.lock b/composer.lock index 7fefee4db0231..777447de96424 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "80d81327a228d96ed4512c92e09d5b02", - "content-hash": "7a457b69136c2954644691bd92ca7cc6", + "hash": "14cde9a911c97dfb8b8d65aa2fc37a9f", + "content-hash": "3ca6f21142f50665ed50595bfb546c41", "packages": [ { "name": "braintree/braintree_php", @@ -54,6 +54,83 @@ "description": "Braintree PHP Client Library", "time": "2015-11-19 19:14:47" }, + { + "name": "colinmollenhour/credis", + "version": "1.6", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/credis.git", + "reference": "409edfd0ea81f5cb74afbdb86df54890c207b5e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/credis/zipball/409edfd0ea81f5cb74afbdb86df54890c207b5e4", + "reference": "409edfd0ea81f5cb74afbdb86df54890c207b5e4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "Client.php", + "Cluster.php", + "Sentinel.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Colin Mollenhour", + "email": "colin@mollenhour.com" + } + ], + "description": "Credis is a lightweight interface to the Redis key-value store which wraps the phpredis library when available for better performance.", + "homepage": "https://github.com/colinmollenhour/credis", + "time": "2015-11-28 01:20:04" + }, + { + "name": "colinmollenhour/php-redis-session-abstract", + "version": "v1.0", + "source": { + "type": "git", + "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git", + "reference": "1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9", + "reference": "1308ddc08e2adbe303f7f8b8ead9beb5f2f2adf9", + "shasum": "" + }, + "require": { + "colinmollenhour/credis": "1.6", + "magento/zendframework1": "1.12.16", + "php": "~5.5.0|~5.6.0|~7.0.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Cm\\RedisSession\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin Mollenhour" + } + ], + "description": "A Redis-based session handler with optimistic locking", + "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract", + "time": "2016-01-14 16:04:27" + }, { "name": "composer/composer", "version": "1.0.0-alpha10", @@ -200,7 +277,7 @@ "type": "zip", "url": "https://api.github.com/repos/magento/composer/zipball/1be267e71debac6e0d9fae4e5144f6095cffbe89", "reference": null, - "shasum": "79156c3e7317af1ff64a482ba90ec81c66b82c73" + "shasum": "6bfdbff4c23aace1e6d14ab598c81c790375aba0" }, "require": { "composer/composer": "1.0.0-alpha10", @@ -304,12 +381,12 @@ "source": { "type": "git", "url": "https://github.com/magento/zf1.git", - "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f" + "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/magento/zf1/zipball/c9d607bfd9454bc18b9deff737ccd5d044e2ab10", - "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f", + "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10", "shasum": "" }, "require": { @@ -343,7 +420,7 @@ "ZF1", "framework" ], - "time": "2015-09-30 13:04:03" + "time": "2015-10-29 14:34:55" }, { "name": "monolog/monolog", @@ -720,7 +797,7 @@ }, { "name": "symfony/console", - "version": "v2.6.12", + "version": "v2.6.13", "target-dir": "Symfony/Component/Console", "source": { "type": "git", @@ -778,16 +855,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc" + "reference": "ee278f7c851533e58ca307f66305ccb9188aceda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5eb815363c0388e83247e7e9853e5dbc14999cc", - "reference": "a5eb815363c0388e83247e7e9853e5dbc14999cc", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ee278f7c851533e58ca307f66305ccb9188aceda", + "reference": "ee278f7c851533e58ca307f66305ccb9188aceda", "shasum": "" }, "require": { @@ -834,20 +911,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2015-10-30 20:15:42" + "time": "2016-01-13 10:28:07" }, { "name": "symfony/finder", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "dd41ae57f4f737be271d944a0cc5f5f21203a7c6" + "reference": "c90fabdd97e431ee19b6383999cf35334dff27da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/dd41ae57f4f737be271d944a0cc5f5f21203a7c6", - "reference": "dd41ae57f4f737be271d944a0cc5f5f21203a7c6", + "url": "https://api.github.com/repos/symfony/finder/zipball/c90fabdd97e431ee19b6383999cf35334dff27da", + "reference": "c90fabdd97e431ee19b6383999cf35334dff27da", "shasum": "" }, "require": { @@ -883,20 +960,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2015-12-05 11:09:21" + "time": "2016-01-14 08:26:52" }, { "name": "symfony/process", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "62c254438b5040bc2217156e1570cf2206e8540c" + "reference": "6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/62c254438b5040bc2217156e1570cf2206e8540c", - "reference": "62c254438b5040bc2217156e1570cf2206e8540c", + "url": "https://api.github.com/repos/symfony/process/zipball/6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac", + "reference": "6f1979c3b0f4c22c77a8a8971afaa7dd07f082ac", "shasum": "" }, "require": { @@ -932,7 +1009,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2015-12-23 11:03:46" + "time": "2016-01-06 09:59:23" }, { "name": "tedivm/jshrink", @@ -2581,16 +2658,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.11", + "version": "v1.11.1", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef" + "reference": "2c9f8298181f059c5077abda78019b9a0c9a7cc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef", - "reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/2c9f8298181f059c5077abda78019b9a0c9a7cc0", + "reference": "2c9f8298181f059c5077abda78019b9a0c9a7cc0", "shasum": "" }, "require": { @@ -2631,7 +2708,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-12-01 22:34:33" + "time": "2016-01-20 19:00:28" }, { "name": "league/climate", @@ -3672,16 +3749,16 @@ }, { "name": "symfony/config", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "17d4b2e64ce1c6ba7caa040f14469b3c44d7f7d2" + "reference": "41ee6c70758f40fa1dbf90d019ae0a66c4a09e74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/17d4b2e64ce1c6ba7caa040f14469b3c44d7f7d2", - "reference": "17d4b2e64ce1c6ba7caa040f14469b3c44d7f7d2", + "url": "https://api.github.com/repos/symfony/config/zipball/41ee6c70758f40fa1dbf90d019ae0a66c4a09e74", + "reference": "41ee6c70758f40fa1dbf90d019ae0a66c4a09e74", "shasum": "" }, "require": { @@ -3718,20 +3795,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2015-12-26 13:37:56" + "time": "2016-01-03 15:33:41" }, { "name": "symfony/dependency-injection", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "c5086d186f538c2711b9af6f727be7b0446979cd" + "reference": "ba94a914e244e0d05f0aaef460d5558d5541d2b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/c5086d186f538c2711b9af6f727be7b0446979cd", - "reference": "c5086d186f538c2711b9af6f727be7b0446979cd", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/ba94a914e244e0d05f0aaef460d5558d5541d2b1", + "reference": "ba94a914e244e0d05f0aaef460d5558d5541d2b1", "shasum": "" }, "require": { @@ -3780,20 +3857,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2015-12-26 13:37:56" + "time": "2016-01-12 17:46:01" }, { "name": "symfony/filesystem", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc" + "reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/a7ad724530a764d70c168d321ac226ba3d2f10fc", - "reference": "a7ad724530a764d70c168d321ac226ba3d2f10fc", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/637b64d0ee10f44ae98dbad651b1ecdf35a11e8c", + "reference": "637b64d0ee10f44ae98dbad651b1ecdf35a11e8c", "shasum": "" }, "require": { @@ -3829,7 +3906,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2015-12-22 10:25:57" + "time": "2016-01-13 10:28:07" }, { "name": "symfony/stopwatch", @@ -3882,16 +3959,16 @@ }, { "name": "symfony/yaml", - "version": "v2.8.1", + "version": "v2.8.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966" + "reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966", - "reference": "ac84cbb98b68a6abbc9f5149eb96ccc7b07b8966", + "url": "https://api.github.com/repos/symfony/yaml/zipball/34c8a4b51e751e7ea869b8262f883d008a2b81b8", + "reference": "34c8a4b51e751e7ea869b8262f883d008a2b81b8", "shasum": "" }, "require": { @@ -3927,7 +4004,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2015-12-26 13:37:56" + "time": "2016-01-13 10:28:07" } ], "aliases": [], diff --git a/lib/internal/Credis/Client.php b/lib/internal/Credis/Client.php deleted file mode 100644 index 5945709b837c8..0000000000000 --- a/lib/internal/Credis/Client.php +++ /dev/null @@ -1,1113 +0,0 @@ - - * @copyright 2011 Colin Mollenhour - * @license http://www.opensource.org/licenses/mit-license.php The MIT License - * @package Credis_Client - */ - -if( ! defined('CRLF')) define('CRLF', sprintf('%s%s', chr(13), chr(10))); - -/** - * Credis-specific errors, wraps native Redis errors - */ -class CredisException extends Exception -{ - - const CODE_TIMED_OUT = 1; - const CODE_DISCONNECTED = 2; - - public function __construct($message, $code = 0, $exception = NULL) - { - if ($exception && get_class($exception) == 'RedisException' && $message == 'read error on connection') { - $code = CredisException::CODE_DISCONNECTED; - } - parent::__construct($message, $code, $exception); - } - -} - -/** - * Credis_Client, a lightweight Redis PHP standalone client and phpredis wrapper - * - * Server/Connection: - * @method Credis_Client pipeline() - * @method Credis_Client multi() - * @method array exec() - * @method string flushAll() - * @method string flushDb() - * @method array info() - * @method bool|array config(string $setGet, string $key, string $value = null) - * - * Keys: - * @method int del(string $key) - * @method int exists(string $key) - * @method int expire(string $key, int $seconds) - * @method int expireAt(string $key, int $timestamp) - * @method array keys(string $key) - * @method int persist(string $key) - * @method bool rename(string $key, string $newKey) - * @method bool renameNx(string $key, string $newKey) - * @method array sort(string $key, string $arg1, string $valueN = null) - * @method int ttl(string $key) - * @method string type(string $key) - * - * Scalars: - * @method int append(string $key, string $value) - * @method int decr(string $key) - * @method int decrBy(string $key, int $decrement) - * @method bool|string get(string $key) - * @method int getBit(string $key, int $offset) - * @method string getRange(string $key, int $start, int $end) - * @method string getSet(string $key, string $value) - * @method int incr(string $key) - * @method int incrBy(string $key, int $decrement) - * @method array mGet(array $keys) - * @method bool mSet(array $keysValues) - * @method int mSetNx(array $keysValues) - * @method bool set(string $key, string $value) - * @method int setBit(string $key, int $offset, int $value) - * @method bool setEx(string $key, int $seconds, string $value) - * @method int setNx(string $key, string $value) - * @method int setRange(string $key, int $offset, int $value) - * @method int strLen(string $key) - * - * Sets: - * @method int sAdd(string $key, mixed $value, string $valueN = null) - * @method int sRem(string $key, mixed $value, string $valueN = null) - * @method array sMembers(string $key) - * @method array sUnion(mixed $keyOrArray, string $valueN = null) - * @method array sInter(mixed $keyOrArray, string $valueN = null) - * @method array sDiff(mixed $keyOrArray, string $valueN = null) - * @method string sPop(string $key) - * @method int sCard(string $key) - * @method int sIsMember(string $key, string $member) - * @method int sMove(string $source, string $dest, string $member) - * @method string|array sRandMember(string $key, int $count = null) - * @method int sUnionStore(string $dest, string $key1, string $key2 = null) - * @method int sInterStore(string $dest, string $key1, string $key2 = null) - * @method int sDiffStore(string $dest, string $key1, string $key2 = null) - * - * Hashes: - * @method bool|int hSet(string $key, string $field, string $value) - * @method bool hSetNx(string $key, string $field, string $value) - * @method bool|string hGet(string $key, string $field) - * @method bool|int hLen(string $key) - * @method bool hDel(string $key, string $field) - * @method array hKeys(string $key, string $field) - * @method array hVals(string $key, string $field) - * @method array hGetAll(string $key) - * @method bool hExists(string $key, string $field) - * @method int hIncrBy(string $key, string $field, int $value) - * @method bool hMSet(string $key, array $keysValues) - * @method array hMGet(string $key, array $fields) - * - * Lists: - * @method array|null blPop(string $keyN, int $timeout) - * @method array|null brPop(string $keyN, int $timeout) - * @method array|null brPoplPush(string $source, string $destination, int $timeout) - * @method string|null lIndex(string $key, int $index) - * @method int lInsert(string $key, string $beforeAfter, string $pivot, string $value) - * @method int lLen(string $key) - * @method string|null lPop(string $key) - * @method int lPush(string $key, mixed $value, mixed $valueN = null) - * @method int lPushX(string $key, mixed $value) - * @method array lRange(string $key, int $start, int $stop) - * @method int lRem(string $key, int $count, mixed $value) - * @method bool lSet(string $key, int $index, mixed $value) - * @method bool lTrim(string $key, int $start, int $stop) - * @method string|null rPop(string $key) - * @method string|null rPoplPush(string $source, string $destination) - * @method int rPush(string $key, mixed $value, mixed $valueN = null) - * @method int rPushX(string $key, mixed $value) - * - * Sorted Sets: - * TODO - * - * Pub/Sub - * @method array pUnsubscribe(mixed $pattern, string $patternN = NULL)) - * @method array unsubscribe(mixed $channel, string $channelN = NULL)) - * @method int publish(string $channel, string $message) - * @method int|array pubsub(string $subCommand, $arg = NULL) - * - * Scripting: - * @method string|int script(string $command, string $arg1 = null) - * @method string|int|array|bool eval(string $script, array $keys = NULL, array $args = NULL) - * @method string|int|array|bool evalSha(string $script, array $keys = NULL, array $args = NULL) - */ -class Credis_Client { - - const TYPE_STRING = 'string'; - const TYPE_LIST = 'list'; - const TYPE_SET = 'set'; - const TYPE_ZSET = 'zset'; - const TYPE_HASH = 'hash'; - const TYPE_NONE = 'none'; - const FREAD_BLOCK_SIZE = 8192; - - /** - * Socket connection to the Redis server or Redis library instance - * @var resource|Redis - */ - protected $redis; - protected $redisMulti; - - /** - * Host of the Redis server - * @var string - */ - protected $host; - - /** - * Port on which the Redis server is running - * @var integer - */ - protected $port; - - /** - * Timeout for connecting to Redis server - * @var float - */ - protected $timeout; - - /** - * Timeout for reading response from Redis server - * @var float - */ - protected $readTimeout; - - /** - * Unique identifier for persistent connections - * @var string - */ - protected $persistent; - - /** - * @var bool - */ - protected $closeOnDestruct = TRUE; - - /** - * @var bool - */ - protected $connected = FALSE; - - /** - * @var bool - */ - protected $standalone; - - /** - * @var int - */ - protected $maxConnectRetries = 0; - - /** - * @var int - */ - protected $connectFailures = 0; - - /** - * @var bool - */ - protected $usePipeline = FALSE; - - /** - * @var array - */ - protected $commandNames; - - /** - * @var string - */ - protected $commands; - - /** - * @var bool - */ - protected $isMulti = FALSE; - - /** - * @var bool - */ - protected $isWatching = FALSE; - - /** - * @var string - */ - protected $authPassword; - - /** - * @var int - */ - protected $selectedDb = 0; - - /** - * Aliases for backwards compatibility with phpredis - * @var array - */ - protected $wrapperMethods = array('delete' => 'del', 'getkeys' => 'keys', 'sremove' => 'srem'); - - /** - * @var array - */ - protected $renamedCommands; - - /** - * @var int - */ - protected $requests = 0; - - /** - * Creates a Redisent connection to the Redis server on host {@link $host} and port {@link $port}. - * $host may also be a path to a unix socket or a string in the form of tcp://[hostname]:[port] or unix://[path] - * - * @param string $host The hostname of the Redis server - * @param integer $port The port number of the Redis server - * @param float $timeout Timeout period in seconds - * @param string $persistent Flag to establish persistent connection - * @param int $db The selected datbase of the Redis server - * @param string $password The authentication password of the Redis server - */ - public function __construct($host = '127.0.0.1', $port = 6379, $timeout = null, $persistent = '', $db = 0, $password = null) - { - $this->host = (string) $host; - $this->port = (int) $port; - $this->timeout = $timeout; - $this->persistent = (string) $persistent; - $this->standalone = ! extension_loaded('redis'); - $this->authPassword = $password; - $this->selectedDb = (int)$db; - $this->convertHost(); - } - - public function __destruct() - { - if ($this->closeOnDestruct) { - $this->close(); - } - } - /** - * Return the host of the Redis instance - * @return string - */ - public function getHost() - { - return $this->host; - } - /** - * Return the port of the Redis instance - * @return int - */ - public function getPort() - { - return $this->port; - } - - /** - * Return the selected database - * @return int - */ - public function getSelectedDb() - { - return $this->selectedDb; - } - /** - * @return string - */ - public function getPersistence() - { - return $this->persistent; - } - /** - * @throws CredisException - * @return Credis_Client - */ - public function forceStandalone() - { - if($this->connected) { - throw new CredisException('Cannot force Credis_Client to use standalone PHP driver after a connection has already been established.'); - } - $this->standalone = TRUE; - return $this; - } - - /** - * @param int $retries - * @return Credis_Client - */ - public function setMaxConnectRetries($retries) - { - $this->maxConnectRetries = $retries; - return $this; - } - - /** - * @param bool $flag - * @return Credis_Client - */ - public function setCloseOnDestruct($flag) - { - $this->closeOnDestruct = $flag; - return $this; - } - protected function convertHost() - { - if (preg_match('#^(tcp|unix)://(.*)$#', $this->host, $matches)) { - if($matches[1] == 'tcp') { - if ( ! preg_match('#^([^:]+)(:([0-9]+))?(/(.+))?$#', $matches[2], $matches)) { - throw new CredisException('Invalid host format; expected tcp://host[:port][/persistence_identifier]'); - } - $this->host = $matches[1]; - $this->port = (int) (isset($matches[3]) ? $matches[3] : 6379); - $this->persistent = isset($matches[5]) ? $matches[5] : ''; - } else { - $this->host = $matches[2]; - $this->port = NULL; - if (substr($this->host,0,1) != '/') { - throw new CredisException('Invalid unix socket format; expected unix:///path/to/redis.sock'); - } - } - } - if ($this->port !== NULL && substr($this->host,0,1) == '/') { - $this->port = NULL; - } - } - /** - * @throws CredisException - * @return Credis_Client - */ - public function connect() - { - if ($this->connected) { - return $this; - } - if ($this->standalone) { - $flags = STREAM_CLIENT_CONNECT; - $remote_socket = $this->port === NULL - ? 'unix://'.$this->host - : 'tcp://'.$this->host.':'.$this->port; - if ($this->persistent) { - if ($this->port === NULL) { // Unix socket - throw new CredisException('Persistent connections to UNIX sockets are not supported in standalone mode.'); - } - $remote_socket .= '/'.$this->persistent; - $flags = $flags | STREAM_CLIENT_PERSISTENT; - } - $result = $this->redis = @stream_socket_client($remote_socket, $errno, $errstr, $this->timeout !== null ? $this->timeout : 2.5, $flags); - } - else { - if ( ! $this->redis) { - $this->redis = new Redis; - } - $result = $this->persistent - ? $this->redis->pconnect($this->host, $this->port, $this->timeout, $this->persistent) - : $this->redis->connect($this->host, $this->port, $this->timeout); - } - - // Use recursion for connection retries - if ( ! $result) { - $this->connectFailures++; - if ($this->connectFailures <= $this->maxConnectRetries) { - return $this->connect(); - } - $failures = $this->connectFailures; - $this->connectFailures = 0; - throw new CredisException("Connection to Redis failed after $failures failures." . (isset($errno) && isset($errstr) ? "Last Error : ({$errno}) {$errstr}" : "")); - } - - $this->connectFailures = 0; - $this->connected = TRUE; - - // Set read timeout - if ($this->readTimeout) { - $this->setReadTimeout($this->readTimeout); - } - - if($this->authPassword !== null) { - $this->auth($this->authPassword); - } - if($this->selectedDb !== 0) { - $this->select($this->selectedDb); - } - return $this; - } - /** - * @return bool - */ - public function isConnected() - { - return $this->connected; - } - /** - * Set the read timeout for the connection. Use 0 to disable timeouts entirely (or use a very long timeout - * if not supported). - * - * @param int $timeout 0 (or -1) for no timeout, otherwise number of seconds - * @throws CredisException - * @return Credis_Client - */ - public function setReadTimeout($timeout) - { - if ($timeout < -1) { - throw new CredisException('Timeout values less than -1 are not accepted.'); - } - $this->readTimeout = $timeout; - if ($this->connected) { - if ($this->standalone) { - $timeout = $timeout <= 0 ? 315360000 : $timeout; // Ten-year timeout - stream_set_blocking($this->redis, TRUE); - stream_set_timeout($this->redis, (int) floor($timeout), ($timeout - floor($timeout)) * 1000000); - } else if (defined('Redis::OPT_READ_TIMEOUT')) { - // supported in phpredis 2.2.3 - // a timeout value of -1 means reads will not timeout - $timeout = $timeout == 0 ? -1 : $timeout; - $this->redis->setOption(Redis::OPT_READ_TIMEOUT, $timeout); - } - } - return $this; - } - - /** - * @return bool - */ - public function close() - { - $result = TRUE; - if ($this->connected && ! $this->persistent) { - try { - $result = $this->standalone ? fclose($this->redis) : $this->redis->close(); - $this->connected = FALSE; - } catch (Exception $e) { - ; // Ignore exceptions on close - } - } - return $result; - } - - /** - * Enabled command renaming and provide mapping method. Supported methods are: - * - * 1. renameCommand('foo') // Salted md5 hash for all commands -> md5('foo'.$command) - * 2. renameCommand(function($command){ return 'my'.$command; }); // Callable - * 3. renameCommand('get', 'foo') // Single command -> alias - * 4. renameCommand(['get' => 'foo', 'set' => 'bar']) // Full map of [command -> alias] - * - * @param string|callable|array $command - * @param string|null $alias - * @return $this - */ - public function renameCommand($command, $alias = NULL) - { - if ( ! $this->standalone) { - $this->forceStandalone(); - } - if ($alias === NULL) { - $this->renamedCommands = $command; - } else { - if ( ! $this->renamedCommands) { - $this->renamedCommands = array(); - } - $this->renamedCommands[$command] = $alias; - } - return $this; - } - - /** - * @param $command - */ - public function getRenamedCommand($command) - { - static $map; - - // Command renaming not enabled - if ($this->renamedCommands === NULL) { - return $command; - } - - // Initialize command map - if ($map === NULL) { - if (is_array($this->renamedCommands)) { - $map = $this->renamedCommands; - } else { - $map = array(); - } - } - - // Generate and return cached result - if ( ! isset($map[$command])) { - // String means all commands are hashed with salted md5 - if (is_string($this->renamedCommands)) { - $map[$command] = md5($this->renamedCommands.$command); - } - // Would already be set in $map if it was intended to be renamed - else if (is_array($this->renamedCommands)) { - return $command; - } - // User-supplied function - else if (is_callable($this->renamedCommands)) { - $map[$command] = call_user_func($this->renamedCommands, $command); - } - } - return $map[$command]; - } - - /** - * @param string $password - * @return bool - */ - public function auth($password) - { - $response = $this->__call('auth', array($password)); - $this->authPassword = $password; - return $response; - } - - /** - * @param int $index - * @return bool - */ - public function select($index) - { - $response = $this->__call('select', array($index)); - $this->selectedDb = (int) $index; - return $response; - } - - /** - * @param string|array $patterns - * @param $callback - * @return $this|array|bool|Credis_Client|mixed|null|string - * @throws CredisException - */ - public function pSubscribe($patterns, $callback) - { - if ( ! $this->standalone) { - return $this->__call('pSubscribe', array((array)$patterns, $callback)); - } - - // Standalone mode: use infinite loop to subscribe until timeout - $patternCount = is_array($patterns) ? count($patterns) : 1; - while ($patternCount--) { - if (isset($status)) { - list($command, $pattern, $status) = $this->read_reply(); - } else { - list($command, $pattern, $status) = $this->__call('psubscribe', array($patterns)); - } - if ( ! $status) { - throw new CredisException('Invalid pSubscribe response.'); - } - } - try { - while (1) { - list($type, $pattern, $channel, $message) = $this->read_reply(); - if ($type != 'pmessage') { - throw new CredisException('Received non-pmessage reply.'); - } - $callback($this, $pattern, $channel, $message); - } - } catch (CredisException $e) { - if ($e->getCode() == CredisException::CODE_TIMED_OUT) { - try { - list($command, $pattern, $status) = $this->pUnsubscribe($patterns); - while ($status !== 0) { - list($command, $pattern, $status) = $this->read_reply(); - } - } catch (CredisException $e2) { - throw $e2; - } - } - throw $e; - } - } - - /** - * @param string|array $channels - * @param $callback - * @throws CredisException - * @return $this|array|bool|Credis_Client|mixed|null|string - */ - public function subscribe($channels, $callback) - { - if ( ! $this->standalone) { - return $this->__call('subscribe', array((array)$channels, $callback)); - } - - // Standalone mode: use infinite loop to subscribe until timeout - $channelCount = is_array($channels) ? count($channels) : 1; - while ($channelCount--) { - if (isset($status)) { - list($command, $channel, $status) = $this->read_reply(); - } else { - list($command, $channel, $status) = $this->__call('subscribe', array($channels)); - } - if ( ! $status) { - throw new CredisException('Invalid subscribe response.'); - } - } - try { - while (1) { - list($type, $channel, $message) = $this->read_reply(); - if ($type != 'message') { - throw new CredisException('Received non-message reply.'); - } - $callback($this, $channel, $message); - } - } catch (CredisException $e) { - if ($e->getCode() == CredisException::CODE_TIMED_OUT) { - try { - list($command, $channel, $status) = $this->unsubscribe($channels); - while ($status !== 0) { - list($command, $channel, $status) = $this->read_reply(); - } - } catch (CredisException $e2) { - throw $e2; - } - } - throw $e; - } - } - - public function __call($name, $args) - { - // Lazy connection - $this->connect(); - - $name = strtolower($name); - - // Send request via native PHP - if($this->standalone) - { - switch ($name) { - case 'eval': - case 'evalsha': - $script = array_shift($args); - $keys = (array) array_shift($args); - $eArgs = (array) array_shift($args); - $args = array($script, count($keys), $keys, $eArgs); - break; - } - // Flatten arguments - $argsFlat = NULL; - foreach($args as $index => $arg) { - if(is_array($arg)) { - if($argsFlat === NULL) { - $argsFlat = array_slice($args, 0, $index); - } - if($name == 'mset' || $name == 'msetnx' || $name == 'hmset') { - foreach($arg as $key => $value) { - $argsFlat[] = $key; - $argsFlat[] = $value; - } - } else { - $argsFlat = array_merge($argsFlat, $arg); - } - } else if($argsFlat !== NULL) { - $argsFlat[] = $arg; - } - } - if($argsFlat !== NULL) { - $args = $argsFlat; - $argsFlat = NULL; - } - - // In pipeline mode - if($this->usePipeline) - { - if($name == 'pipeline') { - throw new CredisException('A pipeline is already in use and only one pipeline is supported.'); - } - else if($name == 'exec') { - if($this->isMulti) { - $this->commandNames[] = $name; - $this->commands .= self::_prepare_command(array($this->getRenamedCommand($name))); - } - - // Write request - if($this->commands) { - $this->write_command($this->commands); - } - $this->commands = NULL; - - // Read response - $response = array(); - foreach($this->commandNames as $command) { - $response[] = $this->read_reply($command); - } - $this->commandNames = NULL; - - if($this->isMulti) { - $response = array_pop($response); - } - $this->usePipeline = $this->isMulti = FALSE; - return $response; - } - else { - if($name == 'multi') { - $this->isMulti = TRUE; - } - array_unshift($args, $this->getRenamedCommand($name)); - $this->commandNames[] = $name; - $this->commands .= self::_prepare_command($args); - return $this; - } - } - - // Start pipeline mode - if($name == 'pipeline') - { - $this->usePipeline = TRUE; - $this->commandNames = array(); - $this->commands = ''; - return $this; - } - - // If unwatching, allow reconnect with no error thrown - if($name == 'unwatch') { - $this->isWatching = FALSE; - } - - // Non-pipeline mode - array_unshift($args, $this->getRenamedCommand($name)); - $command = self::_prepare_command($args); - $this->write_command($command); - $response = $this->read_reply($name); - - // Watch mode disables reconnect so error is thrown - if($name == 'watch') { - $this->isWatching = TRUE; - } - // Transaction mode - else if($this->isMulti && ($name == 'exec' || $name == 'discard')) { - $this->isMulti = FALSE; - } - // Started transaction - else if($this->isMulti || $name == 'multi') { - $this->isMulti = TRUE; - $response = $this; - } - } - - // Send request via phpredis client - else - { - // Tweak arguments - switch($name) { - case 'get': // optimize common cases - case 'set': - case 'hget': - case 'hset': - case 'setex': - case 'mset': - case 'msetnx': - case 'hmset': - case 'hmget': - case 'del': - break; - case 'mget': - if(isset($args[0]) && ! is_array($args[0])) { - $args = array($args); - } - break; - case 'lrem': - $args = array($args[0], $args[2], $args[1]); - break; - case 'eval': - case 'evalsha': - if (isset($args[1]) && is_array($args[1])) { - $cKeys = $args[1]; - } elseif (isset($args[1]) && is_string($args[1])) { - $cKeys = array($args[1]); - } else { - $cKeys = array(); - } - if (isset($args[2]) && is_array($args[2])) { - $cArgs = $args[2]; - } elseif (isset($args[2]) && is_string($args[2])) { - $cArgs = array($args[2]); - } else { - $cArgs = array(); - } - $args = array($args[0], array_merge($cKeys, $cArgs), count($cKeys)); - break; - case 'subscribe': - case 'psubscribe': - break; - default: - // Flatten arguments - $argsFlat = NULL; - foreach($args as $index => $arg) { - if(is_array($arg)) { - if($argsFlat === NULL) { - $argsFlat = array_slice($args, 0, $index); - } - $argsFlat = array_merge($argsFlat, $arg); - } else if($argsFlat !== NULL) { - $argsFlat[] = $arg; - } - } - if($argsFlat !== NULL) { - $args = $argsFlat; - $argsFlat = NULL; - } - } - - try { - // Proxy pipeline mode to the phpredis library - if($name == 'pipeline' || $name == 'multi') { - if($this->isMulti) { - return $this; - } else { - $this->isMulti = TRUE; - $this->redisMulti = call_user_func_array(array($this->redis, $name), $args); - } - } - else if($name == 'exec' || $name == 'discard') { - $this->isMulti = FALSE; - $response = $this->redisMulti->$name(); - $this->redisMulti = NULL; - #echo "> $name : ".substr(print_r($response, TRUE),0,100)."\n"; - return $response; - } - - // Use aliases to be compatible with phpredis wrapper - if(isset($this->wrapperMethods[$name])) { - $name = $this->wrapperMethods[$name]; - } - - // Multi and pipeline return self for chaining - if($this->isMulti) { - call_user_func_array(array($this->redisMulti, $name), $args); - return $this; - } - - // Send request, retry one time when using persistent connections on the first request only - $this->requests++; - try { - $response = call_user_func_array(array($this->redis, $name), $args); - } catch (RedisException $e) { - if ($this->persistent && $this->requests == 1 && $e->getMessage() == 'read error on connection') { - $this->connected = FALSE; - $this->connect(); - $response = call_user_func_array(array($this->redis, $name), $args); - } else { - throw $e; - } - } - } - // Wrap exceptions - catch(RedisException $e) { - $code = 0; - if ( ! ($result = $this->redis->IsConnected())) { - $this->connected = FALSE; - $code = CredisException::CODE_DISCONNECTED; - } - throw new CredisException($e->getMessage(), $code, $e); - } - - #echo "> $name : ".substr(print_r($response, TRUE),0,100)."\n"; - - // change return values where it is too difficult to minim in standalone mode - switch($name) - { - case 'hmget': - $response = array_values($response); - break; - - case 'type': - $typeMap = array( - self::TYPE_NONE, - self::TYPE_STRING, - self::TYPE_SET, - self::TYPE_LIST, - self::TYPE_ZSET, - self::TYPE_HASH, - ); - $response = $typeMap[$response]; - break; - - // Handle scripting errors - case 'eval': - case 'evalsha': - case 'script': - $error = $this->redis->getLastError(); - $this->redis->clearLastError(); - if ($error && substr($error,0,8) == 'NOSCRIPT') { - $response = NULL; - } else if ($error) { - throw new CredisException($error); - } - break; - default: - $error = $this->redis->getLastError(); - $this->redis->clearLastError(); - if ($error) { - throw new CredisException($error); - } - break; - } - } - - return $response; - } - - protected function write_command($command) - { - // Reconnect on lost connection (Redis server "timeout" exceeded since last command) - if(feof($this->redis)) { - $this->close(); - // If a watch or transaction was in progress and connection was lost, throw error rather than reconnect - // since transaction/watch state will be lost. - if(($this->isMulti && ! $this->usePipeline) || $this->isWatching) { - $this->isMulti = $this->isWatching = FALSE; - throw new CredisException('Lost connection to Redis server during watch or transaction.'); - } - $this->connected = FALSE; - $this->connect(); - if($this->authPassword) { - $this->auth($this->authPassword); - } - if($this->selectedDb != 0) { - $this->select($this->selectedDb); - } - } - - $commandLen = strlen($command); - for ($written = 0; $written < $commandLen; $written += $fwrite) { - $fwrite = fwrite($this->redis, substr($command, $written)); - if ($fwrite === FALSE || $fwrite == 0 ) { - $this->connected = FALSE; - throw new CredisException('Failed to write entire command to stream'); - } - } - } - - protected function read_reply($name = '') - { - $reply = fgets($this->redis); - if($reply === FALSE) { - $info = stream_get_meta_data($this->redis); - if ($info['timed_out']) { - throw new CredisException('Read operation timed out.', CredisException::CODE_TIMED_OUT); - } else { - $this->connected = FALSE; - throw new CredisException('Lost connection to Redis server.', CredisException::CODE_DISCONNECTED); - } - } - $reply = rtrim($reply, CRLF); - #echo "> $name: $reply\n"; - $replyType = substr($reply, 0, 1); - switch ($replyType) { - /* Error reply */ - case '-': - if($this->isMulti || $this->usePipeline) { - $response = FALSE; - } else if ($name == 'evalsha' && substr($reply,0,9) == '-NOSCRIPT') { - $response = NULL; - } else { - throw new CredisException(substr($reply,0,4) == '-ERR' ? substr($reply, 5) : substr($reply,1)); - } - break; - /* Inline reply */ - case '+': - $response = substr($reply, 1); - if($response == 'OK' || $response == 'QUEUED') { - return TRUE; - } - break; - /* Bulk reply */ - case '$': - if ($reply == '$-1') return FALSE; - $size = (int) substr($reply, 1); - $response = stream_get_contents($this->redis, $size + 2); - if( ! $response) { - $this->connected = FALSE; - throw new CredisException('Error reading reply.'); - } - $response = substr($response, 0, $size); - break; - /* Multi-bulk reply */ - case '*': - $count = substr($reply, 1); - if ($count == '-1') return FALSE; - - $response = array(); - for ($i = 0; $i < $count; $i++) { - $response[] = $this->read_reply(); - } - break; - /* Integer reply */ - case ':': - $response = intval(substr($reply, 1)); - break; - default: - throw new CredisException('Invalid response: '.print_r($reply, TRUE)); - break; - } - - // Smooth over differences between phpredis and standalone response - switch($name) - { - case '': // Minor optimization for multi-bulk replies - break; - case 'config': - case 'hgetall': - $keys = $values = array(); - while($response) { - $keys[] = array_shift($response); - $values[] = array_shift($response); - } - $response = count($keys) ? array_combine($keys, $values) : array(); - break; - case 'info': - $lines = explode(CRLF, trim($response,CRLF)); - $response = array(); - foreach($lines as $line) { - if ( ! $line || substr($line, 0, 1) == '#') { - continue; - } - list($key, $value) = explode(':', $line, 2); - $response[$key] = $value; - } - break; - case 'ttl': - if($response === -1) { - $response = FALSE; - } - break; - } - - return $response; - } - - /** - * Build the Redis unified protocol command - * - * @param array $args - * @return string - */ - private static function _prepare_command($args) - { - return sprintf('*%d%s%s%s', count($args), CRLF, implode(array_map(array('self', '_map'), $args), CRLF), CRLF); - } - - private static function _map($arg) - { - return sprintf('$%d%s%s', strlen($arg), CRLF, $arg); - } - -} diff --git a/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php b/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php index c49d92ee281ce..4fbeaecc85d18 100644 --- a/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php +++ b/lib/internal/Magento/Framework/Config/ConfigOptionsListConstants.php @@ -56,6 +56,7 @@ class ConfigOptionsListConstants */ const SESSION_SAVE_FILES = 'files'; const SESSION_SAVE_DB = 'db'; + const SESSION_SAVE_REDIS = 'redis'; /**#@-*/ /** diff --git a/lib/internal/Magento/Framework/Session/Config.php b/lib/internal/Magento/Framework/Session/Config.php index f006da9dcf7b3..793794b61826e 100644 --- a/lib/internal/Magento/Framework/Session/Config.php +++ b/lib/internal/Magento/Framework/Session/Config.php @@ -15,8 +15,6 @@ /** * Magento session configuration - * - * @method Config setSaveHandler() */ class Config implements ConfigInterface { @@ -99,6 +97,11 @@ class Config implements ConfigInterface */ protected $_scopeType; + /** + * @var string + */ + private $saveHandlerName; + /** @var \Magento\Framework\ValidatorFactory */ protected $_validatorFactory; @@ -141,7 +144,6 @@ public function __construct( self::PARAM_SESSION_SAVE_METHOD, $defaultSaveHandler ); - $saveMethod = $saveMethod === 'db' ? 'user' : $saveMethod; $this->setSaveHandler($saveMethod); /** @@ -292,6 +294,38 @@ public function getName() return (string)$this->getOption('session.name'); } + /** + * {@inheritdoc} + */ + public function setSaveHandler($saveHandler) + { + $this->setSaveHandlerName($saveHandler); + if ($saveHandler === 'db' || $saveHandler === 'redis') { + $saveHandler = 'user'; + } + $this->setOption('session.save_handler', $saveHandler); + return $this; + } + + /** + * Set save handler name + * + * @param string $saveHandlerName + * @return void + */ + private function setSaveHandlerName($saveHandlerName) + { + $this->saveHandlerName = $saveHandlerName; + } + + /** + * {@inheritdoc} + */ + public function getSaveHandlerName() + { + return $this->saveHandlerName; + } + /** * Set session.save_path * diff --git a/lib/internal/Magento/Framework/Session/Config/ConfigInterface.php b/lib/internal/Magento/Framework/Session/Config/ConfigInterface.php index 6c2372d20be4f..8182a7638efd3 100644 --- a/lib/internal/Magento/Framework/Session/Config/ConfigInterface.php +++ b/lib/internal/Magento/Framework/Session/Config/ConfigInterface.php @@ -170,4 +170,19 @@ public function setUseCookies($useCookies); * @SuppressWarnings(PHPMD.BooleanGetMethodName) */ public function getUseCookies(); + + /** + * Get save handler name + * + * @return string + */ + public function getSaveHandlerName(); + + /** + * Set session.save_handler + * + * @param string $saveHandler + * @return $this + */ + public function setSaveHandler($saveHandler); } diff --git a/lib/internal/Magento/Framework/Session/SaveHandler.php b/lib/internal/Magento/Framework/Session/SaveHandler.php index 3e7b593dfcf5e..e4ec505a2cea8 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler.php @@ -5,8 +5,8 @@ */ namespace Magento\Framework\Session; -use Magento\Framework\App\DeploymentConfig; use Magento\Framework\Exception\SessionException; +use Magento\Framework\Session\Config\ConfigInterface; /** * Magento session save handler @@ -24,19 +24,20 @@ class SaveHandler implements SaveHandlerInterface * Constructor * * @param SaveHandlerFactory $saveHandlerFactory - * @param DeploymentConfig $deploymentConfig + * @param ConfigInterface $config * @param string $default */ public function __construct( SaveHandlerFactory $saveHandlerFactory, - DeploymentConfig $deploymentConfig, + ConfigInterface $config, $default = self::DEFAULT_HANDLER ) { - $saveMethod = $deploymentConfig->get(\Magento\Framework\Session\Config::PARAM_SESSION_SAVE_METHOD); + $saveMethod = $config->getSaveHandlerName(); try { $connection = $saveHandlerFactory->create($saveMethod); } catch (SessionException $e) { $connection = $saveHandlerFactory->create($default); + $config->setSaveHandler($default); } $this->saveHandlerAdapter = $connection; } diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis.php new file mode 100644 index 0000000000000..56ce5cc075d7f --- /dev/null +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis.php @@ -0,0 +1,51 @@ +filesystem = $filesystem; + try { + parent::__construct($config, $logger); + } catch (ConnectionFailedException $e) { + throw new SessionException(new Phrase($e->getMessage())); + } + } + + /** + * {@inheritdoc} + */ + public function read($sessionId) + { + try { + return parent::read($sessionId); + } catch (ConcurrentConnectionsExceededException $e) { + require $this->filesystem->getDirectoryRead(DirectoryList::PUB)->getAbsolutePath('errors/503.php'); + } + } +} diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php new file mode 100644 index 0000000000000..718521a45b220 --- /dev/null +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -0,0 +1,247 @@ +deploymentConfig = $deploymentConfig; + $this->appState = $appState; + } + + /** + * {@inheritdoc} + */ + public function getLogLevel() + { + return $this->deploymentConfig->get(self::PARAM_LOG_LEVEL); + } + + /** + * {@inheritdoc} + */ + public function getHost() + { + return $this->deploymentConfig->get(self::PARAM_HOST); + } + + /** + * {@inheritdoc} + */ + public function getPort() + { + return $this->deploymentConfig->get(self::PARAM_PORT); + } + + /** + * {@inheritdoc} + */ + public function getDatabase() + { + return $this->deploymentConfig->get(self::PARAM_DATABASE); + } + + /** + * {@inheritdoc} + */ + public function getPassword() + { + return $this->deploymentConfig->get(self::PARAM_PASSWORD); + } + + /** + * {@inheritdoc} + */ + public function getTimeout() + { + return $this->deploymentConfig->get(self::PARAM_TIMEOUT); + } + + /** + * {@inheritdoc} + */ + public function getPersistentIdentifier() + { + return $this->deploymentConfig->get(self::PARAM_PERSISTENT_IDENTIFIER); + } + + /** + * {@inheritdoc} + */ + public function getCompressionThreshold() + { + return $this->deploymentConfig->get(self::PARAM_COMPRESSION_THRESHOLD); + } + + /** + * {@inheritdoc} + */ + public function getCompressionLibrary() + { + return $this->deploymentConfig->get(self::PARAM_COMPRESSION_LIBRARY); + } + + /** + * {@inheritdoc} + */ + public function getMaxConcurrency() + { + return $this->deploymentConfig->get(self::PARAM_MAX_CONCURRENCY); + } + + /** + * {@inheritdoc} + */ + public function getMaxLifetime() + { + return $this->deploymentConfig->get(self::PARAM_MAX_LIFETIME); + } + + /** + * {@inheritdoc} + */ + public function getMinLifetime() + { + return $this->deploymentConfig->get(self::PARAM_MIN_LIFETIME); + } + + /** + * {@inheritdoc} + */ + public function getDisableLocking() + { + return $this->deploymentConfig->get(self::PARAM_DISABLE_LOCKING); + } + + /** + * {@inheritdoc} + */ + public function getBotLifetime() + { + return $this->deploymentConfig->get(self::PARAM_BOT_LIFETIME); + } + + /** + * {@inheritdoc} + */ + public function getBotFirstLifetime() + { + return $this->deploymentConfig->get(self::PARAM_BOT_FIRST_LIFETIME); + } + + /** + * {@inheritdoc} + */ + public function getFirstLifetime() + { + return $this->deploymentConfig->get(self::PARAM_FIRST_LIFETIME); + } + + /** + * {@inheritdoc} + */ + public function getBreakAfter() + { + return $this->deploymentConfig->get(self::PARAM_BREAK_AFTER . '_' . $this->appState->getAreaCode()); + } +} diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Logger.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Logger.php new file mode 100644 index 0000000000000..8684f475de5f6 --- /dev/null +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Logger.php @@ -0,0 +1,93 @@ +logger = $logger; + $this->request = $request; + $this->logLevel = $config->getLogLevel() ?: self::ALERT; + } + + /** + * {@inheritdoc} + */ + public function setLogLevel($level) + { + $this->logLevel = $level; + } + + /** + * {@inheritdoc} + */ + public function log($message, $level) + { + $message .= ' ' . $this->request->getRequestUri(); + if ($this->logLevel >= $level) { + switch ($level) { + case self::EMERGENCY: + $this->logger->emergency($message); + break; + case self::ALERT: + $this->logger->alert($message); + break; + case self::CRITICAL: + $this->logger->critical($message); + break; + case self::ERROR: + $this->logger->error($message); + break; + case self::WARNING: + $this->logger->warning($message); + break; + case self::NOTICE: + $this->logger->notice($message); + break; + case self::INFO: + $this->logger->info($message); + break; + default: + $this->logger->debug($message); + } + } + } + + /** + * {@inheritdoc} + */ + public function logException(\Exception $e) + { + $this->logger->critical($e->getMessage()); + } +} diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php index 6c43bf72c0d01..3c50426ce2234 100644 --- a/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php +++ b/lib/internal/Magento/Framework/Session/Test/Unit/ConfigTest.php @@ -148,8 +148,12 @@ public function testSaveHandlerFromConfig() public function testSaveHandlerIsMutable() { $this->getModel($this->validatorMock); - $this->config->setSaveHandler('user'); + $this->config->setSaveHandler('redis'); $this->assertEquals('user', $this->config->getSaveHandler()); + $this->assertEquals('redis', $this->config->getSaveHandlerName()); + $this->config->setSaveHandler('files'); + $this->assertEquals('files', $this->config->getSaveHandler()); + $this->assertEquals('files', $this->config->getSaveHandlerName()); } public function testCookieLifetimeIsMutable() diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php new file mode 100644 index 0000000000000..30b8787753c0e --- /dev/null +++ b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/ConfigTest.php @@ -0,0 +1,214 @@ +deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false); + $this->appState = $this->getMock('Magento\Framework\App\State', [], [], '', false); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->config = $objectManager->getObject( + 'Magento\Framework\Session\SaveHandler\Redis\Config', + [ + 'deploymentConfig' => $this->deploymentConfig, + 'appState' => $this->appState + ] + ); + } + + public function testGetLogLevel() + { + $expected = 2; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_LOG_LEVEL) + ->willReturn($expected); + $this->assertEquals($this->config->getLogLevel(), $expected); + } + + public function testGetHost() + { + $expected = '127.0.0.1'; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_HOST) + ->willReturn($expected); + $this->assertEquals($this->config->getHost(), $expected); + } + + public function testGetPort() + { + $expected = 1234; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_PORT) + ->willReturn($expected); + $this->assertEquals($this->config->getPort(), $expected); + } + + public function testGetDatabase() + { + $expected = 2; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_DATABASE) + ->willReturn($expected); + $this->assertEquals($this->config->getDatabase(), $expected); + } + + public function testGetPassword() + { + $expected = 'password'; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_PASSWORD) + ->willReturn($expected); + $this->assertEquals($this->config->getPassword(), $expected); + } + + public function testGetTimeout() + { + $expected = 10; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_TIMEOUT) + ->willReturn($expected); + $this->assertEquals($this->config->getTimeout(), $expected); + } + + public function testGetPersistentIdentifier() + { + $expected = 'sess01'; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_PERSISTENT_IDENTIFIER) + ->willReturn($expected); + $this->assertEquals($this->config->getPersistentIdentifier(), $expected); + } + + public function testGetCompressionThreshold() + { + $expected = 2; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_COMPRESSION_THRESHOLD) + ->willReturn($expected); + $this->assertEquals($this->config->getCompressionThreshold(), $expected); + } + + public function testGetCompressionLibrary() + { + $expected = 'gzip'; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_COMPRESSION_LIBRARY) + ->willReturn($expected); + $this->assertEquals($this->config->getCompressionLibrary(), $expected); + } + + public function testGetMaxConcurrency() + { + $expected = 6; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_MAX_CONCURRENCY) + ->willReturn($expected); + $this->assertEquals($this->config->getMaxConcurrency(), $expected); + } + + public function testGetMaxLifetime() + { + $expected = 30; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_MAX_LIFETIME) + ->willReturn($expected); + $this->assertEquals($this->config->getMaxLifetime(), $expected); + } + + public function testGetMinLifetime() + { + $expected = 30; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_MIN_LIFETIME) + ->willReturn($expected); + $this->assertEquals($this->config->getMinLifetime(), $expected); + } + + public function testGetDisableLocking() + { + $expected = false; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_DISABLE_LOCKING) + ->willReturn($expected); + $this->assertEquals($this->config->getDisableLocking(), $expected); + } + + public function testGetBotLifetime() + { + $expected = 30; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_BOT_LIFETIME) + ->willReturn($expected); + $this->assertEquals($this->config->getBotLifetime(), $expected); + } + + public function testGetBotFirstLifetime() + { + $expected = 30; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_BOT_FIRST_LIFETIME) + ->willReturn($expected); + $this->assertEquals($this->config->getBotFirstLifetime(), $expected); + } + + public function testGetFirstLifetime() + { + $expected = 30; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_FIRST_LIFETIME) + ->willReturn($expected); + $this->assertEquals($this->config->getFirstLifetime(), $expected); + } + + public function testBreakAfter() + { + $areaCode = 'frontend'; + $breakAfter = 5; + $this->deploymentConfig->expects($this->once()) + ->method('get') + ->with(Config::PARAM_BREAK_AFTER . '_' . $areaCode) + ->willReturn($breakAfter); + $this->appState->expects($this->once()) + ->method('getAreaCode') + ->willReturn($areaCode); + $this->assertEquals($this->config->getBreakAfter(), $breakAfter); + } +} diff --git a/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/LoggerTest.php b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/LoggerTest.php new file mode 100644 index 0000000000000..d48bea62b5429 --- /dev/null +++ b/lib/internal/Magento/Framework/Session/Test/Unit/SaveHandler/Redis/LoggerTest.php @@ -0,0 +1,95 @@ +config = $this->getMock('Cm\RedisSession\Handler\ConfigInterface', [], [], '', false); + $this->config->expects($this->once()) + ->method('getLogLevel') + ->willReturn(LoggerInterface::DEBUG); + $this->psrLogger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false); + $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false); + //$this->logger = new Logger($this->config, $this->psrLogger, $this->request); + $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $this->logger = $objectManager->getObject( + 'Magento\Framework\Session\SaveHandler\Redis\Logger', + [ + 'config' => $this->config, + 'logger' => $this->psrLogger, + 'request' => $this->request + ] + ); + } + + /** + * @dataProvider logDataProvider + */ + public function testLog($logLevel, $method) + { + $message = 'Error message'; + $this->request->expects($this->once()) + ->method('getRequestUri') + ->willReturn($this->requestUri); + $this->psrLogger->expects($this->once()) + ->method($method) + ->with($message . ' ' . $this->requestUri); + $this->logger->log($message, $logLevel); + } + + public function logDataProvider() + { + return [ + [LoggerInterface::EMERGENCY, 'emergency'], + [LoggerInterface::ALERT, 'alert'], + [LoggerInterface::CRITICAL, 'critical'], + [LoggerInterface::ERROR, 'error'], + [LoggerInterface::WARNING, 'warning'], + [LoggerInterface::NOTICE, 'notice'], + [LoggerInterface::INFO, 'info'], + [LoggerInterface::DEBUG, 'debug'], + ]; + } + + public function testLogException() + { + $exception = new \Exception('Error message'); + $this->psrLogger->expects($this->once()) + ->method('critical') + ->with($exception->getMessage()); + $this->logger->logException($exception); + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Module/ConfigOptionsListTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php similarity index 99% rename from setup/src/Magento/Setup/Test/Unit/Module/ConfigOptionsListTest.php rename to setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php index 27454c09f6177..f3f55090dee5e 100644 --- a/setup/src/Magento/Setup/Test/Unit/Module/ConfigOptionsListTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigOptionsListTest.php @@ -4,7 +4,7 @@ * See COPYING.txt for license details. */ -namespace Magento\Setup\Test\Unit\Module; +namespace Magento\Setup\Test\Unit\Model; use Magento\Setup\Model\ConfigGenerator; use Magento\Setup\Model\ConfigOptionsList; @@ -149,7 +149,7 @@ private function prepareValidationMocks() $this->dbValidator->expects($this->once())->method('checkDatabaseTablePrefix')->willReturn($configDataMock); $this->dbValidator->expects($this->once())->method('checkDatabaseConnection')->willReturn($configDataMock); } - + /** * @param string $hosts * @param bool $expectedError From e5247ffe0b151befeb57492bc815e254462886f0 Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Wed, 20 Jan 2016 17:05:15 -0600 Subject: [PATCH 3/5] MAGETWO-47958: Include Redis generic session adapter in Magento 2 Fixing annotation --- .../Magento/Framework/Session/SaveHandler/Redis/Config.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php index 718521a45b220..e45fff134ed73 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -99,10 +99,15 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface * Deployment config * * @var DeploymentConfig $deploymentConfig - * @var State $appState */ private $deploymentConfig; + /** + * Constructor + * + * @param DeploymentConfig $deploymentConfig + * @param State $appState + */ public function __construct(DeploymentConfig $deploymentConfig, State $appState) { $this->deploymentConfig = $deploymentConfig; From 22e60bd328253b8f6d6aaa48317c170c7697c78a Mon Sep 17 00:00:00 2001 From: Igor Melnikov Date: Wed, 20 Jan 2016 17:07:14 -0600 Subject: [PATCH 4/5] MAGETWO-47958: Include Redis generic session adapter in Magento 2 Fixing annotation --- .../Magento/Framework/Session/SaveHandler/Redis/Config.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php index e45fff134ed73..a20878c402601 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php +++ b/lib/internal/Magento/Framework/Session/SaveHandler/Redis/Config.php @@ -103,8 +103,6 @@ class Config implements \Cm\RedisSession\Handler\ConfigInterface private $deploymentConfig; /** - * Constructor - * * @param DeploymentConfig $deploymentConfig * @param State $appState */ From 453b3b84579cf7ee60835e7da7060ec6fcfe104a Mon Sep 17 00:00:00 2001 From: Joan He Date: Mon, 25 Jan 2016 09:40:31 -0600 Subject: [PATCH 5/5] MAGETWO-46577: HTTPS header options configuration test - resolve merge conflict --- composer.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.lock b/composer.lock index 777447de96424..a8c2a9acb5732 100644 --- a/composer.lock +++ b/composer.lock @@ -277,7 +277,7 @@ "type": "zip", "url": "https://api.github.com/repos/magento/composer/zipball/1be267e71debac6e0d9fae4e5144f6095cffbe89", "reference": null, - "shasum": "6bfdbff4c23aace1e6d14ab598c81c790375aba0" + "shasum": "79156c3e7317af1ff64a482ba90ec81c66b82c73" }, "require": { "composer/composer": "1.0.0-alpha10", @@ -381,12 +381,12 @@ "source": { "type": "git", "url": "https://github.com/magento/zf1.git", - "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10" + "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/magento/zf1/zipball/c9d607bfd9454bc18b9deff737ccd5d044e2ab10", - "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10", + "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f", "shasum": "" }, "require": { @@ -420,7 +420,7 @@ "ZF1", "framework" ], - "time": "2015-10-29 14:34:55" + "time": "2015-09-30 13:04:03" }, { "name": "monolog/monolog",