diff --git a/.travis.yml b/.travis.yml index 19fe6377984837242a736f1c60618a4ac52bfd60..a99b22b1ebd4f7c911a96ef9b066011f5ab8671a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: php php: - 5.5 - 5.6 + - 7.0 env: - TEST_SUITE=unit - TEST_SUITE=integration_part_1 @@ -37,13 +38,7 @@ before_script: # Mock mail - sudo service postfix stop - smtp-sink -d "%d.%H.%M.%S" localhost:2500 1000 & - - echo -e '#!/usr/bin/env bash\nexit 0' | sudo tee /usr/sbin/sendmail - - > - echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' - | sudo tee "/home/travis/.phpenv/versions/`php -i - | grep "PHP Version" - | head -n 1 - | grep -o -P '\d+\.\d+\.\d+.*'`/etc/conf.d/sendmail.ini" + - echo 'sendmail_path = "/usr/sbin/sendmail -t -i "' > $(php --ini|grep -m 1 "ini files in:"|cut -d ":" -f 2)/sendmail.ini # Disable xDebug - echo '' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini # Install MySQL 5.6, create DB for integration tests diff --git a/app/autoload.php b/app/autoload.php index 79674e9c46e45153570ae0180377af94e385f620..d2b57dfb1f7b3782f57689063d467fc757cb0641 100644 --- a/app/autoload.php +++ b/app/autoload.php @@ -13,7 +13,16 @@ use Magento\Framework\Autoload\ClassLoaderWrapper; */ define('BP', dirname(__DIR__)); -$vendorDir = require BP . '/app/etc/vendor_path.php'; +define('VENDOR_PATH', BP . '/app/etc/vendor_path.php'); + +if (!file_exists(VENDOR_PATH)) { + throw new \Exception( + 'We can\'t read some files that are required to run the Magento application. ' + . 'This usually means file permissions are set incorrectly.' + ); +} + +$vendorDir = require VENDOR_PATH; $vendorAutoload = BP . "/{$vendorDir}/autoload.php"; /* 'composer install' validation */ diff --git a/app/code/Magento/Backend/Block/Store/Switcher.php b/app/code/Magento/Backend/Block/Store/Switcher.php index 60a6245ef49ba23c36a6eb89884f45c998f4c50b..1874d4fb768a201f9e21811b52192452c23ebec5 100644 --- a/app/code/Magento/Backend/Block/Store/Switcher.php +++ b/app/code/Magento/Backend/Block/Store/Switcher.php @@ -4,14 +4,11 @@ * See COPYING.txt for license details. */ -/** - * Store switcher block - * - * @author Magento Core Team <core@magentocommerce.com> - */ namespace Magento\Backend\Block\Store; /** + * Store switcher block + * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Switcher extends \Magento\Backend\Block\Template @@ -19,7 +16,7 @@ class Switcher extends \Magento\Backend\Block\Template /** * URL for store switcher hint */ - const HINT_URL = 'http://www.magentocommerce.com/knowledge-base/entry/understanding-store-scopes'; + const HINT_URL = 'http://docs.magento.com/m2/ce/user_guide/stores/configuration.html'; /** * Name of website variable diff --git a/app/code/Magento/Search/Api/SynonymAnalyzerInterface.php b/app/code/Magento/Search/Api/SynonymAnalyzerInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..7bc45d8d6ab0f02d95af1c0d256134dbef59ede6 --- /dev/null +++ b/app/code/Magento/Search/Api/SynonymAnalyzerInterface.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Search\Api; + +/** + * @api + */ +interface SynonymAnalyzerInterface +{ + /** + * Get synonyms for specified phrase + * + * For phrase: "Elizabeth is the English queen" correct output is an array of arrays containing synonyms for each + * word in the phrase: + * + * [ + * 0 => [ 0 => "elizabeth" ], + * 1 => [ 0 => "is" ], + * 2 => [ 0 => "the" ], + * 3 => [ 0 => "british", 1 => "english" ], + * 4 => [ 0 => "queen", 1 => "monarch" ] + * ] + * + * @param string $phrase + * @return array + */ + public function getSynonymsForPhrase($phrase); +} diff --git a/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php b/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php new file mode 100644 index 0000000000000000000000000000000000000000..f9d3eebafccb377fdc624ffee0d54eb98cab677a --- /dev/null +++ b/app/code/Magento/Search/Model/ResourceModel/SynonymReader.php @@ -0,0 +1,98 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Search\Model\ResourceModel; + +use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\ResourceModel\Db\AbstractDb; +use Magento\Search\Model\SynonymReader as SynReaderModel; +use Magento\Framework\DB\Helper\Mysql\Fulltext; + +/** + * Synonym Reader resource model + */ +class SynonymReader extends AbstractDb +{ + /** + * @var Fulltext $fullTextSelect + */ + private $fullTextSelect; + + /** + * @param \Magento\Framework\Model\ResourceModel\Db\Context $context + * @param Fulltext $fulltext + * @param string $connectionName + */ + public function __construct( + \Magento\Framework\Model\ResourceModel\Db\Context $context, + Fulltext $fulltext, + $connectionName = null + ) { + parent::__construct($context, $connectionName); + $this->fullTextSelect = $fulltext; + } + + /** + * Custom load model: Get data by store view id + * + * @param AbstractModel $object + * @param int $value + * @return $this + */ + public function loadByStoreViewId(AbstractModel $object, $value) + { + $select = $this->getConnection()->select()->from( + $this->getMainTable() + )->where( + 'store_id = ?', + $value + ); + $data = $this->getConnection()->fetchAll($select); + if ($data) { + $object->setData($data); + $this->_afterLoad($object); + } + return $this; + } + + /** + * Custom load model: Get data by user query phrase and store view id + * + * @param SynReaderModel $object + * @param string $value + * @return $this + */ + public function loadByPhrase(SynReaderModel $object, $value) + { + $phrase = strtolower($value); + $matchQuery = $this->fullTextSelect->getMatchQuery( + ['synonyms' => 'synonyms'], + $phrase, + Fulltext::FULLTEXT_MODE_BOOLEAN + ); + $query = $this->getConnection()->select()->from( + $this->getMainTable() + )->where( + 'store_id = ?', + $object->getStoreViewId() + )->where($matchQuery); + + $rows = $this->getConnection()->fetchAll($query); + $object->setData($rows); + $this->_afterLoad($object); + return $this; + } + + /** + * Init resource data + * + * @return void + */ + protected function _construct() + { + $this->_init('search_synonyms', 'group_id'); + } +} diff --git a/app/code/Magento/Search/Model/SynonymAnalyzer.php b/app/code/Magento/Search/Model/SynonymAnalyzer.php new file mode 100644 index 0000000000000000000000000000000000000000..9da5d82abf3a542e5f3646927e482ef83a4698a6 --- /dev/null +++ b/app/code/Magento/Search/Model/SynonymAnalyzer.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Search\Model; + +use Magento\Search\Api\SynonymAnalyzerInterface; +use Magento\Search\Model\SynonymsReader; + +class SynonymAnalyzer implements SynonymAnalyzerInterface +{ + /** + * @var SynonymReader $synReaderModel + */ + protected $synReaderModel; + + /** + * Constructor + * + * @param SynonymReader $synReader + */ + public function __construct(SynonymReader $synReader) + { + $this->synReaderModel = $synReader; + } + + /** + * Returns an array of arrays consisting of the synonyms found for each word in the input phrase + * + * @param string $phrase + * @return array + */ + public function getSynonymsForPhrase($phrase) + { + $synGroups = []; + + if (empty($phrase)) { + return $synGroups; + } + + // strip off all the white spaces, comma, semicolons, and other such + // "non-word" characters. Then implode it into a single string using white space as delimiter + //$words = preg_split('/\W+/', strtolower($phrase), -1, PREG_SPLIT_NO_EMPTY); + $words = preg_split( + '/[~`!@#$%^&*()_+={}\[\]:"\',\s\.<>?\/\;\\\]+/', + strtolower($phrase), + -1, + PREG_SPLIT_NO_EMPTY + ); + $phrase = implode(' ', $words); + + $rows = $this->synReaderModel->loadByPhrase($phrase)->getData(); + $synonyms = []; + foreach ($rows as $row) { + $synonyms [] = $row['synonyms']; + } + + // Go through every returned record looking for presence of the actual phrase. If there were no matching + // records found in DB then create a new entry for it in the returned array + foreach ($words as $w) { + $position = $this->findInArray($w, $synonyms); + if ($position !== false) { + $synGroups[] = explode(',', $synonyms[$position]); + } else { + // No synonyms were found. Return the original word in this position + $synGroups[] = [$w]; + } + } + return $synGroups; + } + + /** + * Helper method to find the presence of $word in $wordsArray. If found, the particular array index is returned. + * Otherwise false will be returned. + * + * @param string $word + * @param $array $wordsArray + * @return boolean | int + */ + private function findInArray($word, $wordsArray) + { + if (empty($wordsArray)) { + return false; + } + $position = 0; + foreach ($wordsArray as $wordsLine) { + $pattern = '/^' . $word . ',|,' . $word . ',|,' . $word . '$/'; + $rv = preg_match($pattern, $wordsLine); + if ($rv != 0) { + return $position; + } + $position++; + } + return false; + } +} diff --git a/app/code/Magento/Search/Model/SynonymReader.php b/app/code/Magento/Search/Model/SynonymReader.php new file mode 100644 index 0000000000000000000000000000000000000000..d24fdf62cfa2b677ee6196192fa2d619416799c1 --- /dev/null +++ b/app/code/Magento/Search/Model/SynonymReader.php @@ -0,0 +1,120 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Search\Model; + +use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Data\Collection\AbstractDb as DbCollection; +use Magento\Framework\Model\AbstractModel; +use Magento\Framework\Model\ResourceModel\AbstractResource; +use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\Registry; + +/** + * Data model to retrieve synonyms by passed in phrase + * + * @method \Magento\Search\Model\ResourceModel\SynonymReader _getResource() + * @method \Magento\Search\Model\ResourceModel\SynonymReader getResource() + * @method \Magento\Search\Model\SynonymReader setGroupId(int $value) + * @method int getGroupId() + * @method \Magento\Search\Model\SynonymReader setStoreId(int $value) + * @method int getStoreId() + * @method \Magento\Search\Model\SynonymReader setSynonyms(string $value) + * @method string getSynonyms() + */ +class SynonymReader extends AbstractModel +{ + /** + * Event prefix + * + * @var string + */ + protected $_eventPrefix = 'search_synonyms'; + + /** + * Event object key name + * + * @var string + */ + protected $_eventObject = 'search_synonyms'; + + /** + * Store manager + * + * @var StoreManagerInterface + */ + protected $storeManager; + + /** + * Construct + * + * @param \Magento\Framework\Model\Context $context + * @param Registry $registry + * @param StoreManagerInterface $storeManager + * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource + * @param DbCollection $resourceCollection + * @param array $data + */ + public function __construct( + \Magento\Framework\Model\Context $context, + Registry $registry, + StoreManagerInterface $storeManager, + AbstractResource $resource = null, + DbCollection $resourceCollection = null, + array $data = [] + ) { + $this->storeManager = $storeManager; + parent::__construct($context, $registry, $resource, $resourceCollection, $data); + } + + /** + * Init resource model + * + * @return void + */ + protected function _construct() + { + $this->_init('Magento\Search\Model\ResourceModel\SynonymReader'); + } + + /** + * Load synonyms by user query phrase in context of current store view + * + * @param string $phrase + * @return $this + */ + public function loadByPhrase($phrase) + { + $this->_getResource()->loadByPhrase($this, strtolower($phrase)); + $this->_afterLoad(); + $this->setOrigData(); + return $this; + } + + /** + * Load synonyms object by store view Id + * + * @param int $storeViewId + * @return $this + */ + public function loadByStoreViewId($storeViewId) + { + $this->_getResource()->loadByStoreViewId($this, $storeViewId); + $this->_afterLoad(); + $this->setOrigData(); + return $this; + } + + /** + * Retrieve store view Id + * + * @return int + */ + public function getStoreViewId() + { + $storeId = $this->storeManager->getStore()->getId(); + return $storeId; + } +} diff --git a/app/code/Magento/Search/Setup/UpgradeSchema.php b/app/code/Magento/Search/Setup/UpgradeSchema.php index 5cd6840dea86083ce158fc955cc65a923f2b6b3f..b8e1b744adcf6a847d21f939d153282aac3edceb 100644 --- a/app/code/Magento/Search/Setup/UpgradeSchema.php +++ b/app/code/Magento/Search/Setup/UpgradeSchema.php @@ -8,6 +8,7 @@ namespace Magento\Search\Setup; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; use Magento\Framework\Setup\UpgradeSchemaInterface; +use Magento\Framework\DB\Adapter\AdapterInterface; /** * @codeCoverageIgnore @@ -38,5 +39,58 @@ class UpgradeSchema implements UpgradeSchemaInterface \Magento\Framework\DB\Adapter\AdapterInterface::INDEX_TYPE_UNIQUE ); } + + if (version_compare($context->getVersion(), '2.0.2') < 0) { + /** + * Create table 'search_synonyms' + */ + $table = $connection + ->newTable($installer->getTable('search_synonyms')) + ->addColumn( + 'group_id', + \Magento\Framework\DB\Ddl\Table::TYPE_BIGINT, + null, + ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true], + 'Synonyms Group Id' + ) + ->addColumn( + 'synonyms', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 65535, + ['nullable' => false], + 'list of synonyms making up this group' + ) + ->addColumn( + 'store_id', + \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT, + null, + ['unsigned' => true, 'nullable' => false, 'default' => '0'], + 'Store Id - identifies the store view these synonyms belong to' + ) + ->addIndex( + $setup->getIdxName( + $installer->getTable('search_synonyms'), + ['synonyms'], + AdapterInterface::INDEX_TYPE_FULLTEXT + ), + ['synonyms'], + ['type' => AdapterInterface::INDEX_TYPE_FULLTEXT] + ) + ->addIndex( + $installer->getIdxName('search_synonyms', 'store_id'), + ['store_id'], + ['type' => AdapterInterface::INDEX_TYPE_INDEX] + ) + ->addForeignKey( + $installer->getFkName('search_synonyms', 'store_id', 'store', 'store_id'), + 'store_id', + $installer->getTable('store'), + 'store_id', + \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE + ) + ->setComment('table storing various synonyms groups per store view'); + + $connection->createTable($table); + } } } diff --git a/app/code/Magento/Search/etc/di.xml b/app/code/Magento/Search/etc/di.xml index c6e0caf84c23ce4919e876452587e1dc9d741ea8..089a406c111555bfb24e403da1c9f246521e2235 100755 --- a/app/code/Magento/Search/etc/di.xml +++ b/app/code/Magento/Search/etc/di.xml @@ -24,6 +24,7 @@ </type> <preference for="Magento\Search\Model\QueryFactoryInterface" type="Magento\Search\Model\QueryFactory" /> <preference for="Magento\Search\Model\QueryInterface" type="Magento\Search\Model\Query" /> + <preference for="Magento\Search\Api\SynonymAnalyzerInterface" type="Magento\Search\Model\SynonymAnalyzer" /> <type name="Magento\Search\Model\Adminhtml\System\Config\Source\Engine"> <arguments> <argument name="engines" xsi:type="array"> diff --git a/app/code/Magento/Search/etc/module.xml b/app/code/Magento/Search/etc/module.xml index 0ec900964420c3242f7937eb941b94d9606790c3..06d53db9a7ddb6dccc10b4bcf72cd3eb47729633 100644 --- a/app/code/Magento/Search/etc/module.xml +++ b/app/code/Magento/Search/etc/module.xml @@ -7,7 +7,7 @@ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Search" setup_version="2.0.1"> + <module name="Magento_Search" setup_version="2.0.2"> <sequence> <module name="Magento_Backend" /> </sequence> diff --git a/composer.json b/composer.json index fa2861ed66a3de2793ab5a1bc79b741c8253dab8..6612d3bed0d5f2e07da7c1765194ffa3dc087897 100644 --- a/composer.json +++ b/composer.json @@ -63,7 +63,7 @@ "phpunit/phpunit": "4.1.0", "squizlabs/php_codesniffer": "1.5.3", "phpmd/phpmd": "@stable", - "pdepend/pdepend": "2.0.6", + "pdepend/pdepend": "2.2.2", "sjparkinson/static-review": "~4.1", "fabpot/php-cs-fixer": "~1.2", "lusitanian/oauth": "~0.3 <=0.7.0" diff --git a/composer.lock b/composer.lock index 9611708f43f35ad33d962f645ac74dbc77ed87f9..da9a0fc11514ea4959690e5fcb064eb19ab3c7a8 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,11 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "4a08b8e4d026f17a34b9660fef416097", + "hash": "b69b31db9306befcb77bfd832e05697f", + "content-hash": "1c2956e41c0b5e2d3a52783a07f4564a", "packages": [ { "name": "braintree/braintree_php", @@ -198,8 +199,8 @@ "dist": { "type": "zip", "url": "https://api.github.com/repos/magento/composer/zipball/1be267e71debac6e0d9fae4e5144f6095cffbe89", - "reference": "1be267e71debac6e0d9fae4e5144f6095cffbe89", - "shasum": "" + "reference": null, + "shasum": "6bfdbff4c23aace1e6d14ab598c81c790375aba0" }, "require": { "composer/composer": "1.0.0-alpha10", @@ -215,13 +216,11 @@ "Magento\\Composer\\": "src" } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "OSL-3.0", "AFL-3.0" ], - "description": "Magento composer library helps to instantiate Composer application and run composer commands.", - "time": "2015-10-01 14:39:10" + "description": "Magento composer library helps to instantiate Composer application and run composer commands." }, { "name": "magento/magento-composer-installer", @@ -2752,26 +2751,27 @@ }, { "name": "pdepend/pdepend", - "version": "2.0.6", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "a15ffcbfbcc4570d4a733ca7b76e9cac0a56c3f4" + "reference": "d3ae0d084d526cdc6c3f1b858fb7148de77b41c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/a15ffcbfbcc4570d4a733ca7b76e9cac0a56c3f4", - "reference": "a15ffcbfbcc4570d4a733ca7b76e9cac0a56c3f4", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/d3ae0d084d526cdc6c3f1b858fb7148de77b41c5", + "reference": "d3ae0d084d526cdc6c3f1b858fb7148de77b41c5", "shasum": "" }, "require": { - "symfony/config": ">=2.4", - "symfony/dependency-injection": ">=2.4", - "symfony/filesystem": ">=2.4" + "php": ">=5.3.7", + "symfony/config": "^2.3.0", + "symfony/dependency-injection": "^2.3.0", + "symfony/filesystem": "^2.3.0" }, "require-dev": { - "phpunit/phpunit": "4.*@stable", - "squizlabs/php_codesniffer": "@stable" + "phpunit/phpunit": "^4.0.0,<4.8", + "squizlabs/php_codesniffer": "^2.0.0" }, "bin": [ "src/bin/pdepend" @@ -2787,7 +2787,7 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2015-03-02 08:06:43" + "time": "2015-10-16 08:49:58" }, { "name": "phpmd/phpmd", @@ -3672,26 +3672,26 @@ }, { "name": "symfony/config", - "version": "v3.0.0", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290" + "reference": "f21c97aec1b5302d2dc0d17047ea8f4e4ff93aae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/40bae8658dbbb500ebc19aa9fde22dc4295fc290", - "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290", + "url": "https://api.github.com/repos/symfony/config/zipball/f21c97aec1b5302d2dc0d17047ea8f4e4ff93aae", + "reference": "f21c97aec1b5302d2dc0d17047ea8f4e4ff93aae", "shasum": "" }, "require": { - "php": ">=5.5.9", - "symfony/filesystem": "~2.8|~3.0" + "php": ">=5.3.9", + "symfony/filesystem": "~2.3|~3.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -3718,29 +3718,32 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2015-11-02 20:34:04" + "time": "2015-11-23 20:38:01" }, { "name": "symfony/dependency-injection", - "version": "v3.0.0", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "b8e19bafc334ee0a9edca028b666f4cd3bba2233" + "reference": "1ac8ce1a1cff7ff9467d44bc71b0f71dfa751ba4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b8e19bafc334ee0a9edca028b666f4cd3bba2233", - "reference": "b8e19bafc334ee0a9edca028b666f4cd3bba2233", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1ac8ce1a1cff7ff9467d44bc71b0f71dfa751ba4", + "reference": "1ac8ce1a1cff7ff9467d44bc71b0f71dfa751ba4", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=5.3.9" + }, + "conflict": { + "symfony/expression-language": "<2.6" }, "require-dev": { - "symfony/config": "~2.8|~3.0", - "symfony/expression-language": "~2.8|~3.0", - "symfony/yaml": "~2.8|~3.0" + "symfony/config": "~2.2|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/yaml": "~2.1|~3.0.0" }, "suggest": { "symfony/config": "", @@ -3750,7 +3753,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -3777,29 +3780,29 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2015-11-30 08:18:52" + "time": "2015-11-30 06:56:28" }, { "name": "symfony/filesystem", - "version": "v3.0.0", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884" + "reference": "3e661a0d521ac67496515fa6e6704bd61bcfff60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/692d98d813e4ef314b9c22775c86ddbeb0f44884", - "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/3e661a0d521ac67496515fa6e6704bd61bcfff60", + "reference": "3e661a0d521ac67496515fa6e6704bd61bcfff60", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=5.3.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "2.8-dev" } }, "autoload": { @@ -3826,7 +3829,7 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2015-11-23 10:41:47" + "time": "2015-11-23 10:19:46" }, { "name": "symfony/stopwatch", diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.json b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.json index 55c5e6591f0852005ee04990db7f24fa935369d4..53009187a595a63758776b3f90b50845221d638d 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.json +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testFromCreateProject/composer.json @@ -39,11 +39,5 @@ } }, "minimum-stability": "alpha", - "prefer-stable": true, - "repositories": [ - { - "type": "composer", - "url": "https://repo.magento.com/" - } - ] + "prefer-stable": true } diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.json b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.json index a8f4e398d2609c051a74824b8d4eafe01a994b78..2625b60abff4f6dc7dabfcbc1e4582e4e054c8e3 100644 --- a/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.json +++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/_files/testSkeleton/composer.json @@ -4,12 +4,6 @@ "magento/product-community-edition": "0.74.0-beta2", "magento/sample-module-minimal" : "*" }, - "repositories": [ - { - "type": "composer", - "url": "https://repo.magento.com/" - } - ], "autoload": { "psr-4": { "Magento\\Framework\\": "htdocs/lib/internal/Magento/Framework/", diff --git a/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3a44ec63eb1437f5af48d2c04532f84aa48e3bf3 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymAnalyzerTest.php @@ -0,0 +1,97 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Search\Model; + +/** + * @magentoDataFixture Magento/Search/_files/synonym_reader.php + * @magentoDbIsolation disabled + */ +class SynonymAnalyzerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Search\Model\SynonymAnalyzer + */ + private $synAnalyzer; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->synAnalyzer = $objectManager->get('Magento\Search\Model\SynonymAnalyzer'); + } + + /** + * Data provider for the test + * + * @return array + */ + public static function loadGetSynonymsForPhraseDataProvider() + { + return [ + 'withSynonyms' => [ + 'phrase' => 'Elizabeth is the English queen.', + 'expectedResult' => [['elizabeth'],['is'],['the'],['british', 'english'],['queen', 'monarch']] + ], + 'noSynonyms' => [ + 'phrase' => 'This sentence has no synonyms', + 'expectedResult' => [['this'], ['sentence'], ['has'], ['no'], ['synonyms']] + ], + 'specialCharacters' => [ + 'phrase' => '~tilde`backtic! exclamation@ at#hash\$dollar%percent^carat&ersand*star(leftparan' + . ')rightparan_underscore+plus=equal{leftcurly}rightcurly[leftbracket]rightbracket:colon' + . '"doublequote\'singlequote,comma space.period<leftangle>rightangle?questionmark\\backslash' + . '/forwardslash tab;semicolon', + 'expectedResult' => [ + ['tilde'], + ['backtic'], + ['exclamation'], + ['at'], + ['hash'], + ['dollar'], + ['percent'], + ['carat'], + ['ampersand'], + ['star'], + ['leftparan'], + ['rightparan'], + ['underscore'], + ['plus'], + ['equal'], + ['leftcurly'], + ['rightcurly'], + ['leftbracket'], + ['rightbracket'], + ['colon'], + ['doublequote'], + ['singlequote'], + ['comma'], + ['space'], + ['period'], + ['leftangle'], + ['rightangle'], + ['questionmark'], + ['backslash'], + ['forwardslash'], + ['tab'], + ['semicolon'] + ] + ], + 'oneMoreTest' => [ + 'phrase' => 'schlicht', + 'expectedResult' => [['schlicht', 'natürlich']]] + ]; + } + + /** + * @param string $phrase + * @param array $expectedResult + * @dataProvider loadGetSynonymsForPhraseDataProvider + */ + public function testGetSynonymsForPhrase($phrase, $expectedResult) + { + $synonyms = $this->synAnalyzer->getSynonymsForPhrase($phrase); + $this->assertEquals($expectedResult, $synonyms); + } +} diff --git a/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a16b9308872979c29db48acfe22baf9dca9bbf58 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Search/Model/SynonymReaderTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Search\Model; + +/** + * @magentoDbIsolation disabled + * @magentoDataFixture Magento/Search/_files/synonym_reader.php + */ +class SynonymReaderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Search\Model\SynonymReader + */ + private $model; + + protected function setUp() + { + $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + $this->model = $objectManager->get('Magento\Search\Model\SynonymReader'); + } + + /** + * @return array + */ + public static function loadByStoreViewIdDataProvider() + { + return [ + [ + 1, + [ + ['synonyms' => 'queen,monarch', 'store_id' => 1], + ['synonyms' => 'british,english', 'store_id' => 1] + ] + ], + [ + 0, + [ + ['synonyms' => 'universe,cosmos', 'store_id' => 0], + ['synonyms' => 'big,huge,large,enormous', 'store_id' => 0] + ] + ] + ]; + } + + /** + * @param int $storeviewId + * @param array $expectedResult + * @dataProvider loadByStoreViewIdDataProvider + */ + public function testloadByStoreViewId($storeViewId, $expectedResult) + { + $data = $this->model->loadByStoreViewId($storeViewId)->getData(); + $this->assertEquals($expectedResult[0]['synonyms'], $data[0]['synonyms']); + $this->assertEquals($expectedResult[0]['store_id'], $data[0]['store_id']); + $this->assertEquals($expectedResult[1]['synonyms'], $data[1]['synonyms']); + $this->assertEquals($expectedResult[1]['store_id'], $data[1]['store_id']); + } + + /** + * @return array + */ + public static function loadByPhraseDataProvider() + { + return [ + [ + 'ELIZABETH', [] + ], + [ + 'ENGLISH', [['synonyms' => 'british,english', 'store_id' => 1]] + ], + [ + 'English', [['synonyms' => 'british,english', 'store_id' => 1]] + ], + [ + 'QUEEN', [['synonyms' => 'queen,monarch', 'store_id' => 1]] + ], + [ + 'Monarch', [['synonyms' => 'queen,monarch', 'store_id' => 1]] + ], + [ + 'MONARCH English', [ + ['synonyms' => 'queen,monarch', 'store_id' => 1], + ['synonyms' => 'british,english', 'store_id' => 1] + ] + ] + ]; + } + + /** + * @param string $phrase + * @param array $expectedResult + * @dataProvider loadByPhraseDataProvider + */ + public function testLoadByPhrase($phrase, $expectedResult) + { + $data = $this->model->loadByPhrase($phrase)->getData(); + + $i = 0; + foreach ($expectedResult as $r) { + $this->assertEquals($r['synonyms'], $data[$i]['synonyms']); + $this->assertEquals($r['store_id'], $data[$i]['store_id']); + ++$i; + } + } +} diff --git a/dev/tests/integration/testsuite/Magento/Search/_files/synonym_reader.php b/dev/tests/integration/testsuite/Magento/Search/_files/synonym_reader.php new file mode 100644 index 0000000000000000000000000000000000000000..41fca6287cf05dfdb708fb07f9dc9aa0754c40ae --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Search/_files/synonym_reader.php @@ -0,0 +1,23 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var $synonymsModel \Magento\Search\Model\SynonymReader */ +$synonymsModel = $objectManager->create('Magento\Search\Model\SynonymReader'); +$synonymsModel->setSynonyms('queen,monarch')->setStoreId(1)->save(); + +$synonymsModel = $objectManager->create('Magento\Search\Model\SynonymReader'); +$synonymsModel->setSynonyms('british,english')->setStoreId(1)->save(); + +$synonymsModel = $objectManager->create('Magento\Search\Model\SynonymReader'); +$synonymsModel->setSynonyms('schlicht,natürlich')->setStoreId(1)->save(); + +$synonymsModel = $objectManager->create('Magento\Search\Model\SynonymReader'); +$synonymsModel->setSynonyms('universe,cosmos')->setStoreId(0)->save(); + +$synonymsModel = $objectManager->create('Magento\Search\Model\SynonymReader'); +$synonymsModel->setSynonyms('big,huge,large,enormous')->setStoreId(0)->save(); diff --git a/dev/tests/integration/testsuite/Magento/Search/_files/synonym_reader_rollback.php b/dev/tests/integration/testsuite/Magento/Search/_files/synonym_reader_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..169a53d8f8afc383d4ec75afb142703409ba9e46 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Search/_files/synonym_reader_rollback.php @@ -0,0 +1,12 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var \Magento\Framework\App\ResourceConnection $resource */ +$resource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->get('\Magento\Framework\App\ResourceConnection'); + +$connection = $resource->getConnection('default'); +$connection->truncateTable($resource->getTableName('search_synonyms')); diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php index 939054260269b772aab61c5a04601b6ed5373f32..690f7e6a4dbd27ea9895545c841fadd79d7a6e5a 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php +++ b/dev/tests/integration/testsuite/Magento/Setup/Model/UpdatePackagesCacheTest.php @@ -6,11 +6,10 @@ namespace Magento\Setup\Model; -use Magento\Framework\App\Filesystem\DirectoryList; use Magento\TestFramework\Helper\Bootstrap; use Magento\Framework\Composer\ComposerJsonFinder; use Magento\Framework\Composer\MagentoComposerApplicationFactory; -use Magento\Framework\Stdlib\DateTime\DateTime; +use Magento\Setup\Model\UpdatePackagesCache; /** * Tests Magento\Framework\ComposerInformation @@ -88,19 +87,19 @@ class UpdatePackagesCacheTest extends \PHPUnit_Framework_TestCase ->method('get') ->willReturn($this->objectManager); - /** @var \Magento\Setup\Model\UpdatePackagesCache $updatePackagesCache */ - $updatePackagesCache = $this->objectManager->create( - 'Magento\Setup\Model\UpdatePackagesCache', - [ - 'applicationFactory' => new MagentoComposerApplicationFactory( - $this->composerJsonFinder, - $this->directoryList - ), - 'filesystem' => $this->filesystem, - 'composerInformation' => $this->composerInformation, - 'objectManagerProvider' => $objectManagerProvider, + /** @var UpdatePackagesCache $updatePackagesCache|\PHPUnit_Framework_MockObject_MockObject */ + $updatePackagesCache = $this->getMock('Magento\Setup\Model\UpdatePackagesCache', [], [], '', false); + + $packages = [ + 'packages' => [ + $packageName => [ + 'latestVersion' => '1000.100.200' + ] ] - ); + ]; + + $updatePackagesCache->expects($this->once())->method('syncPackagesForUpdate')->willReturn(true); + $updatePackagesCache->expects($this->once())->method('getPackagesForUpdate')->willReturn($packages); $requiredPackages = $this->composerInformation->getInstalledMagentoPackages(); $this->assertArrayHasKey($packageName, $requiredPackages); diff --git a/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json index a8f4e398d2609c051a74824b8d4eafe01a994b78..2625b60abff4f6dc7dabfcbc1e4582e4e054c8e3 100644 --- a/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json +++ b/dev/tests/integration/testsuite/Magento/Setup/Model/_files/testSkeleton/composer.json @@ -4,12 +4,6 @@ "magento/product-community-edition": "0.74.0-beta2", "magento/sample-module-minimal" : "*" }, - "repositories": [ - { - "type": "composer", - "url": "https://repo.magento.com/" - } - ], "autoload": { "psr-4": { "Magento\\Framework\\": "htdocs/lib/internal/Magento/Framework/", diff --git a/lib/internal/Magento/Framework/App/Test/Unit/_files/test.composer.json b/lib/internal/Magento/Framework/App/Test/Unit/_files/test.composer.json index 0704e81598d4c61e7055caf27b8087cdcfb3d677..f80398a3f1fcb6f334707a358c1431f9d2ef22a5 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/_files/test.composer.json +++ b/lib/internal/Magento/Framework/App/Test/Unit/_files/test.composer.json @@ -7,12 +7,6 @@ "OSL-3.0", "AFL-3.0" ], - "repositories": [ - { - "type": "composer", - "url": "https://repo.magento.com/" - } - ], "require": { "php": "~5.5.0|~5.6.0|~7.0.0", "ext-openssl": "*" diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php index a84de426be517ac0fc29637d982dea25047e1134..c68ff653cb3df539ba61dd6e5b749d7cbeef4e2b 100644 --- a/setup/src/Magento/Setup/Model/Installer.php +++ b/setup/src/Magento/Setup/Model/Installer.php @@ -356,11 +356,9 @@ class Installer private function createModulesConfig($request) { $all = array_keys($this->moduleLoader->load()); - $currentModules = []; - if ($this->deploymentConfig->isAvailable()) { - $deploymentConfig = $this->deploymentConfigReader->load(); - $currentModules = isset($deploymentConfig['modules']) ? $deploymentConfig['modules'] : [] ; - } + $deploymentConfig = $this->deploymentConfigReader->load(); + $currentModules = isset($deploymentConfig[ConfigOptionsListConstants::KEY_MODULES]) + ? $deploymentConfig[ConfigOptionsListConstants::KEY_MODULES] : [] ; $enable = $this->readListOfModules($all, $request, self::ENABLE_MODULES); $disable = $this->readListOfModules($all, $request, self::DISABLE_MODULES); $result = []; diff --git a/setup/src/Magento/Setup/Test/Unit/Controller/MaintenanceTest.php b/setup/src/Magento/Setup/Test/Unit/Controller/MaintenanceTest.php index cf9d74b0eda13564c834123a49696afe16966a1f..b3adfabd493d3241dcc10987092ab8ef4112cc80 100644 --- a/setup/src/Magento/Setup/Test/Unit/Controller/MaintenanceTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Controller/MaintenanceTest.php @@ -20,7 +20,7 @@ class MaintenanceTest extends \PHPUnit_Framework_TestCase /** * Controller * - * @var \Magento\Setup\Controller\CompleteBackup + * @var \Magento\Setup\Controller\Maintenance */ private $controller; @@ -28,6 +28,21 @@ class MaintenanceTest extends \PHPUnit_Framework_TestCase { $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', [], [], '', false); $this->controller = new Maintenance($this->maintenanceMode); + + $request = $this->getMock('\Zend\Http\PhpEnvironment\Request', [], [], '', false); + $response = $this->getMock('\Zend\Http\PhpEnvironment\Response', [], [], '', false); + $routeMatch = $this->getMock('\Zend\Mvc\Router\RouteMatch', [], [], '', false); + + $mvcEvent = $this->getMock('\Zend\Mvc\MvcEvent', [], [], '', false); + $mvcEvent->expects($this->any())->method('setRequest')->with($request)->willReturn($mvcEvent); + $mvcEvent->expects($this->any())->method('setResponse')->with($response)->willReturn($mvcEvent); + $mvcEvent->expects($this->any())->method('setTarget')->with($this->controller)->willReturn($mvcEvent); + $mvcEvent->expects($this->any())->method('getRouteMatch')->willReturn($routeMatch); + $contentArray = '{"disable":false}'; + $request->expects($this->any())->method('getContent')->willReturn($contentArray); + + $this->controller->setEvent($mvcEvent); + $this->controller->dispatch($request, $response); } public function testIndexAction() diff --git a/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php b/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php index 29b559a0f6276843b06454a9b92b3c782bd4bc8f..3c24f18df7735f13b513be11f34380edf0058fd5 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/PhpReadinessCheckTest.php @@ -193,7 +193,6 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 50 ); - $this->setUpNoPrettyVersionParser(); $rawPostMessage = sprintf( 'Your PHP Version is %s, but always_populate_raw_post_data = -1. $HTTP_RAW_POST_DATA is deprecated from PHP 5.6 onwards and will be removed in PHP 7.0. @@ -209,13 +208,16 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 'message' => $xdebugMessage, 'error' => false, ], - 'always_populate_raw_post_data' => [ - 'message' => $rawPostMessage, - 'helpUrl' => 'http://php.net/manual/en/ini.core.php#ini.always-populate-settings-data', - 'error' => false - ] ] ]; + if (!$this->isPhp7OrHhvm()) { + $this->setUpNoPrettyVersionParser(); + $expected['data']['always_populate_raw_post_data'] = [ + 'message' => $rawPostMessage, + 'helpUrl' => 'http://php.net/manual/en/ini.core.php#ini.always-populate-settings-data', + 'error' => false + ]; + } $this->assertEquals($expected, $this->phpReadinessCheck->checkPhpSettings()); } @@ -231,7 +233,6 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 200 ); - $this->setUpNoPrettyVersionParser(); $rawPostMessage = sprintf( 'Your PHP Version is %s, but always_populate_raw_post_data = -1. $HTTP_RAW_POST_DATA is deprecated from PHP 5.6 onwards and will be removed in PHP 7.0. @@ -246,14 +247,17 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase 'xdebug_max_nesting_level' => [ 'message' => $xdebugMessage, 'error' => true, - ], - 'always_populate_raw_post_data' => [ - 'message' => $rawPostMessage, - 'helpUrl' => 'http://php.net/manual/en/ini.core.php#ini.always-populate-settings-data', - 'error' => false ] ] ]; + if (!$this->isPhp7OrHhvm()) { + $this->setUpNoPrettyVersionParser(); + $expected['data']['always_populate_raw_post_data'] = [ + 'message' => $rawPostMessage, + 'helpUrl' => 'http://php.net/manual/en/ini.core.php#ini.always-populate-settings-data', + 'error' => false + ]; + } $this->assertEquals($expected, $this->phpReadinessCheck->checkPhpSettings()); } @@ -261,7 +265,6 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase { $this->phpInfo->expects($this->once())->method('getCurrent')->willReturn([]); - $this->setUpNoPrettyVersionParser(); $rawPostMessage = sprintf( 'Your PHP Version is %s, but always_populate_raw_post_data = -1. $HTTP_RAW_POST_DATA is deprecated from PHP 5.6 onwards and will be removed in PHP 7.0. @@ -272,14 +275,18 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase ); $expected = [ 'responseType' => ResponseTypeInterface::RESPONSE_TYPE_SUCCESS, - 'data' => [ + 'data' => [] + ]; + if (!$this->isPhp7OrHhvm()) { + $this->setUpNoPrettyVersionParser(); + $expected['data'] = [ 'always_populate_raw_post_data' => [ 'message' => $rawPostMessage, 'helpUrl' => 'http://php.net/manual/en/ini.core.php#ini.always-populate-settings-data', 'error' => false ] - ] - ]; + ]; + } $this->assertEquals($expected, $this->phpReadinessCheck->checkPhpSettings()); } @@ -333,6 +340,14 @@ class PhpReadinessCheckTest extends \PHPUnit_Framework_TestCase ]; $this->assertEquals($expected, $this->phpReadinessCheck->checkPhpExtensions()); } + + /** + * @return bool + */ + protected function isPhp7OrHhvm() + { + return version_compare(PHP_VERSION, '7.0.0-beta') >= 0 || defined('HHVM_VERSION'); + } } namespace Magento\Setup\Model;