diff --git a/setup/performance-toolkit/profiles/ce/attributeSets.xml b/setup/performance-toolkit/profiles/ce/attributeSets.xml new file mode 100644 index 0000000000000000000000000000000000000000..0db403e9969c079da00562f119233d24ea208a6b --- /dev/null +++ b/setup/performance-toolkit/profiles/ce/attributeSets.xml @@ -0,0 +1,132 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<attribute_sets> <!-- Content of Attribute Sets --> + <attribute_set> + <name>Attribute Set 1</name> + <attributes> + <attribute> + <is_required>1</is_required> + <is_visible_on_front>1</is_visible_on_front> + <is_visible_in_advanced_search>1</is_visible_in_advanced_search> + <attribute_code>mycolor</attribute_code> + <backend_type></backend_type> + <is_searchable>1</is_searchable> + <is_filterable>1</is_filterable> + <is_filterable_in_search>1</is_filterable_in_search> + <frontend_label>my color</frontend_label> + <frontend_input>select</frontend_input> + <default_value>my yellow</default_value> + <options> + <option> + <label>my green</label> + <value>my green</value> + </option> + <option> + <label>my red</label> + <value>my red</value> + </option> + <option> + <label>my yellow</label> + <value>my yellow</value> + </option> + </options> + </attribute> + <attribute> + <is_required>1</is_required> + <is_visible_on_front>1</is_visible_on_front> + <is_visible_in_advanced_search>1</is_visible_in_advanced_search> + <attribute_code>mysize</attribute_code> + <backend_type></backend_type> + <is_searchable>1</is_searchable> + <is_filterable>1</is_filterable> + <is_filterable_in_search>1</is_filterable_in_search> + <frontend_label>my size</frontend_label> + <frontend_input>select</frontend_input> + <default_value>my large</default_value> + <options> + <option> + <label>my small</label> + <value>my small</value> + </option> + <option> + <label>my medium</label> + <value>my medium</value> + </option> + <option> + <label>my large</label> + <value>my large</value> + </option> + </options> + </attribute> + </attributes> + </attribute_set> + <attribute_set> + <name>Attribute Set 2</name> + <attributes> + <attribute> + <is_required>1</is_required> + <is_visible_on_front>1</is_visible_on_front> + <is_visible_in_advanced_search>1</is_visible_in_advanced_search> + <attribute_code>attributeset2attribute1</attribute_code> + <backend_type></backend_type> + <is_searchable>1</is_searchable> + <is_filterable>1</is_filterable> + <is_filterable_in_search>1</is_filterable_in_search> + <frontend_label>Attribute Set 2 - Attribute 1</frontend_label> + <frontend_input>select</frontend_input> + <default_value>attributeset2attribute1option1</default_value> + <options> + <option> + <label>Attribute Set 2 - Attribute 1 - Option a</label> + <value>attributeset2attribute1option1</value> + </option> + <option> + <label>Attribute Set 2 - Attribute 1 - Option b</label> + <value>attributeset2attribute1option2</value> + </option> + <option> + <label>Attribute Set 2 - Attribute 1 - Option c</label> + <value>attributeset2attribute1option3</value> + </option> + </options> + </attribute> + </attributes> + </attribute_set> + <attribute_set> + <name>Attribute Set 3</name> + <attributes> + <attribute> + <is_required>1</is_required> + <is_visible_on_front>1</is_visible_on_front> + <is_visible_in_advanced_search>1</is_visible_in_advanced_search> + <attribute_code>attributeset3attribute1</attribute_code> + <backend_type></backend_type> + <is_searchable>1</is_searchable> + <is_filterable>1</is_filterable> + <is_filterable_in_search>1</is_filterable_in_search> + <frontend_label>Attribute Set 3 - Attribute 1</frontend_label> + <frontend_input>select</frontend_input> + <default_value>attributeset3attribute1option1</default_value> + <options> + <option> + <label>Attribute Set 3 - Attribute 1 - Option a</label> + <value>attributeset3attribute1option1</value> + </option> + <option> + <label>Attribute Set 3 - Attribute 1 - Option b</label> + <value>attributeset3attribute1option2</value> + </option> + <option> + <label>Attribute Set 3 - Attribute 1 - Option c</label> + <value>attributeset3attribute1option3</value> + </option> + </options> + </attribute> + </attributes> + </attribute_set> +</attribute_sets> \ No newline at end of file diff --git a/setup/performance-toolkit/profiles/ce/extra_large.xml b/setup/performance-toolkit/profiles/ce/extra_large.xml index 41561e54f787b417ec5be855e607a2436b1d0abe..c9bf96ad4f4cab4cb8a6c1aacbe6e89a673e842c 100644 --- a/setup/performance-toolkit/profiles/ce/extra_large.xml +++ b/setup/performance-toolkit/profiles/ce/extra_large.xml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -<config> +<config xmlns:xi="http://www.w3.org/2001/XInclude"> <profile> <websites>5</websites> <!-- Number of websites to generate --> <store_groups>5</store_groups> <!--Number of stores--> @@ -68,5 +68,8 @@ <set_scheduled>true</set_scheduled> </indexer> </indexers> + <xi:include href="searchTerms.xml" /> + <xi:include href="searchConfig.xml" /> + <xi:include href="attributeSets.xml" /> </profile> </config> diff --git a/setup/performance-toolkit/profiles/ce/large.xml b/setup/performance-toolkit/profiles/ce/large.xml index ec521527a438406cf08b0211944347612bca5743..07e7ac33023b17d5d626986b76d84e88b3f7314b 100644 --- a/setup/performance-toolkit/profiles/ce/large.xml +++ b/setup/performance-toolkit/profiles/ce/large.xml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -<config> +<config xmlns:xi="http://www.w3.org/2001/XInclude"> <profile> <websites>3</websites> <!-- Number of websites to generate --> <store_groups>3</store_groups> <!--Number of stores--> @@ -68,5 +68,8 @@ <set_scheduled>true</set_scheduled> </indexer> </indexers> + <xi:include href="searchTerms.xml" /> + <xi:include href="searchConfig.xml" /> + <xi:include href="attributeSets.xml" /> </profile> </config> diff --git a/setup/performance-toolkit/profiles/ce/medium.xml b/setup/performance-toolkit/profiles/ce/medium.xml index d2125b0586b1244553277c5cafdbe30e7bb5020a..6b1b289e823bab41a6d637350037b64c39e96935 100644 --- a/setup/performance-toolkit/profiles/ce/medium.xml +++ b/setup/performance-toolkit/profiles/ce/medium.xml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -<config> +<config xmlns:xi="http://www.w3.org/2001/XInclude"> <profile> <websites>1</websites> <!-- Number of websites to generate --> <store_groups>2</store_groups> <!--Number of stores--> @@ -68,5 +68,8 @@ <set_scheduled>false</set_scheduled> </indexer> </indexers> + <xi:include href="searchTerms.xml" /> + <xi:include href="searchConfig.xml" /> + <xi:include href="attributeSets.xml" /> </profile> </config> diff --git a/setup/performance-toolkit/profiles/ce/searchConfig.xml b/setup/performance-toolkit/profiles/ce/searchConfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..55c2caea2482c271af5cc2aa97e243fea9c6f6e3 --- /dev/null +++ b/setup/performance-toolkit/profiles/ce/searchConfig.xml @@ -0,0 +1,13 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<search_config> <!-- Search configuration for Simple/Configurable products --> + <max_amount_of_words_description>200</max_amount_of_words_description> + <max_amount_of_words_short_description>20</max_amount_of_words_short_description> + <min_amount_of_words_description>20</min_amount_of_words_description> + <min_amount_of_words_short_description>5</min_amount_of_words_short_description> +</search_config> diff --git a/setup/performance-toolkit/profiles/ce/searchTerms.xml b/setup/performance-toolkit/profiles/ce/searchTerms.xml new file mode 100644 index 0000000000000000000000000000000000000000..b5713ac4644f661a586564827283c6b7c973b51e --- /dev/null +++ b/setup/performance-toolkit/profiles/ce/searchTerms.xml @@ -0,0 +1,17 @@ +<?xml version="1.0"?> +<!-- +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<search_terms> <!-- Content of Search Terms --> + <search_term> + <term>iphone 6</term> + <count>50</count> + </search_term> + <search_term> + <term>galaxy s3</term> + <count>100</count> + </search_term> +</search_terms> \ No newline at end of file diff --git a/setup/performance-toolkit/profiles/ce/small.xml b/setup/performance-toolkit/profiles/ce/small.xml index d935a90299b6063d1b06d995647044c9d0a5b23d..4f9b436666f8c743c0fd0058c6fc747944506c9d 100644 --- a/setup/performance-toolkit/profiles/ce/small.xml +++ b/setup/performance-toolkit/profiles/ce/small.xml @@ -5,7 +5,7 @@ * See COPYING.txt for license details. */ --> -<config> +<config xmlns:xi="http://www.w3.org/2001/XInclude"> <profile> <websites>1</websites> <!-- Number of websites to generate --> <store_groups>1</store_groups> <!--Number of stores--> @@ -68,5 +68,8 @@ <set_scheduled>false</set_scheduled> </indexer> </indexers> + <xi:include href="searchTerms.xml" /> + <xi:include href="searchConfig.xml" /> + <xi:include href="attributeSets.xml" /> </profile> </config> diff --git a/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php b/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php index d91a1633ef03848eb1a73a123b9e5f87d6f253d4..f70c36cec65dcd5fb868f12b7144fb46e58c3a7c 100644 --- a/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php +++ b/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php @@ -78,7 +78,12 @@ class GenerateFixturesCommand extends Command $output->writeln('<info>Generating profile with following params:</info>'); foreach ($fixtureModel->getParamLabels() as $configKey => $label) { - $output->writeln('<info> |- ' . $label . ': ' . $fixtureModel->getValue($configKey) . '</info>'); + $output->writeln( + '<info> |- ' . $label . ': ' . (is_array($fixtureModel->getValue($configKey)) === true + ? sizeof( + $fixtureModel->getValue($configKey)[array_keys($fixtureModel->getValue($configKey))[0]] + ) : $fixtureModel->getValue($configKey)) . '</info>' + ); } /** @var $config \Magento\Indexer\Model\Config */ diff --git a/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php b/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php new file mode 100644 index 0000000000000000000000000000000000000000..5617eca9a0e7e24694c151d508ed09a4cd547999 --- /dev/null +++ b/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php @@ -0,0 +1,122 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Setup\Fixtures; + +/** + * Class AttributeSetFixture + */ +class AttributeSetsFixture extends Fixture +{ + /** + * @var int + */ + protected $priority = 25; + + /** + * {@inheritdoc} + */ + public function execute() + { + $attributeSets = $this->fixtureModel->getValue('attribute_sets', null); + if ($attributeSets === null) { + return; + } + $this->fixtureModel->resetObjectManager(); + /** @var \Magento\Catalog\Api\AttributeSetManagementInterface $attributeSetManagement */ + $attributeSetManagement = $this->fixtureModel->getObjectManager()->create( + \Magento\Catalog\Api\AttributeSetManagementInterface::class + ); + /** @var \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface $attributeGroupRepository */ + $attributeGroupRepository = $this->fixtureModel->getObjectManager()->create( + \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class + ); + + foreach ($attributeSets['attribute_set'] as $attributeSetData) { + //Create Attribute Set + /** @var \Magento\Eav\Api\Data\AttributeSetInterfaceFactory $attributeSetFactory */ + $attributeSetFactory = $this->fixtureModel->getObjectManager()->create( + \Magento\Eav\Api\Data\AttributeSetInterfaceFactory::class + ); + $attributeSet = $attributeSetFactory->create(); + $attributeSet->setAttributeSetName($attributeSetData['name']); + $attributeSet->setEntityTypeId(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE); + + $result = $attributeSetManagement->create($attributeSet, 4); + $attributeSetId = $result->getAttributeSetId(); + + //Create Attribute Group + /** @var \Magento\Eav\Api\Data\AttributeGroupInterfaceFactory $attributeGroupFactory */ + $attributeGroupFactory = $this->fixtureModel->getObjectManager()->create( + \Magento\Eav\Api\Data\AttributeGroupInterfaceFactory::class + ); + $attributeGroup = $attributeGroupFactory->create(); + $attributeGroup->setAttributeGroupName($result->getAttributeSetName() . ' - Group'); + $attributeGroup->setAttributeSetId($attributeSetId); + $attributeGroupRepository->save($attributeGroup); + $attributeGroupId = $attributeGroup->getAttributeGroupId(); + + /** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository */ + $attributeRepository = $this->fixtureModel->getObjectManager()->create( + \Magento\Catalog\Api\ProductAttributeRepositoryInterface::class + ); + /** @var \Magento\Catalog\Api\ProductAttributeManagementInterface $attributeManagementManagement */ + $attributeManagement = $this->fixtureModel->getObjectManager()->create( + \Magento\Catalog\Api\ProductAttributeManagementInterface::class + ); + + $attributesData = array_key_exists(0, $attributeSetData['attributes']['attribute']) + ? $attributeSetData['attributes']['attribute'] : [$attributeSetData['attributes']['attribute']]; + foreach ($attributesData as $attributeData) { + //Create Attribute + /** @var \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory $attributeFactory */ + $attributeFactory = $this->fixtureModel->getObjectManager()->create( + \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory::class + ); + + $optionsData = array_key_exists(0, $attributeData['options']['option']) + ? $attributeData['options']['option'] : [$attributeData['options']['option']]; + $options = []; + foreach ($optionsData as $optionData) { + /** @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory */ + $optionFactory = $this->fixtureModel->getObjectManager()->create( + \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class + ); + $option = $optionFactory->create(['data' => $optionData]); + $options[] = $option; + } + + $attribute = $attributeFactory->create(['data' => $attributeData]); + $attribute->setOptions($options); + + $result = $attributeRepository->save($attribute); + $attributeId = $result->getAttributeId(); + + //Associate Attribute to Attribute Set + $sortOrder = 3; + $attributeManagement->assign($attributeSetId, $attributeGroupId, $attributeId, $sortOrder); + } + } + } + + /** + * {@inheritdoc} + */ + public function getActionTitle() + { + return 'Generating attribute sets'; + } + + /** + * {@inheritdoc} + */ + public function introduceParamLabels() + { + return [ + 'attribute_sets' => 'Attribute Sets' + ]; + } +} diff --git a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php index 5142efc2da6614cfd6253b02cf7a30b69fc07663..2340de71cf78363ed00fd9248577e7479b6dc012 100644 --- a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php @@ -6,19 +6,25 @@ namespace Magento\Setup\Fixtures; -use Magento\Setup\Model\Complex\Generator; +use Magento\Setup\Model\DataGenerator; use Magento\Setup\Model\Complex\Pattern; +use Magento\Setup\Model\Complex\Generator; /** * Class ConfigurableProductsFixture */ -class ConfigurableProductsFixture extends Fixture +class ConfigurableProductsFixture extends SimpleProductsFixture { /** * @var int */ protected $priority = 50; + /** + * @var array + */ + protected $searchConfig; + //@codingStandardsIgnoreStart /** * Get CSV template headers @@ -31,6 +37,7 @@ class ConfigurableProductsFixture extends Fixture 'sku', 'store_view_code', 'attribute_set_code', + 'additional_attributes', 'product_type', 'categories', 'product_websites', @@ -137,22 +144,38 @@ class ConfigurableProductsFixture extends Fixture } /** - * @param callable $productCategory - * @param callable $productWebsite - * @param string $variation + * @param Closure|mixed $productCategoryClosure + * @param Closure|mixed $productWebsiteClosure + * @param Closure|mixed $shortDescriptionClosure + * @param Closure|mixed $descriptionClosure + * @param Closure|mixed $priceClosure + * @param Closure|mixed $attributeSetClosure + * @param Closure|mixed $additionalAttributesClosure + * @param string $variationClosure * @param string $suffix * @return array * @SuppressWarnings(PHPMD) */ - private function generateConfigurableProduct($productCategory, $productWebsite, $variation, $suffix) + private function generateConfigurableProduct( + $productCategoryClosure, + $productWebsiteClosure, + $shortDescriptionClosure, + $descriptionClosure, + $priceClosure, + $attributeSetClosure, + $additionalAttributesClosure, + $variationClosure, + $suffix + ) { return [ 'sku' => 'Configurable Product %s' . $suffix, 'store_view_code' => '', - 'attribute_set_code' => 'Default', + 'attribute_set_code' => $attributeSetClosure, + 'additional_attributes' => $additionalAttributesClosure, 'product_type' => 'configurable', - 'categories' => $productCategory, - 'product_websites' => $productWebsite, + 'categories' => $productCategoryClosure, + 'product_websites' => $productWebsiteClosure, 'color' => '', 'configurable_variation' => '', 'cost' => '', @@ -162,7 +185,7 @@ class ConfigurableProductsFixture extends Fixture 'custom_design_from' => '', 'custom_design_to' => '', 'custom_layout_update' => '', - 'description' => '<p>Configurable product description %s</p>', + 'description' => $descriptionClosure, 'enable_googlecheckout' => '1', 'gallery' => '', 'gift_message_available' => '', @@ -184,12 +207,12 @@ class ConfigurableProductsFixture extends Fixture 'news_to_date' => '', 'options_container' => 'Block after Info Column', 'page_layout' => '', - 'price' => '10', + 'price' => $priceClosure, 'quantity_and_stock_status' => 'In Stock', 'related_tgtr_position_behavior' => '', 'related_tgtr_position_limit' => '', 'required_options' => '1', - 'short_description' => '', + 'short_description' => $shortDescriptionClosure, 'small_image' => '', 'small_image_label' => '', 'special_from_date' => '', @@ -244,32 +267,51 @@ class ConfigurableProductsFixture extends Fixture '_media_label' => '', '_media_position' => '', '_media_is_disabled' => '', - 'configurable_variations' => $variation, + 'configurable_variations' => $variationClosure, ]; } /** * Get CSV template rows * - * @param Closure|mixed $productCategory - * @param Closure|mixed $productWebsite + * @param Closure|mixed $productCategoryClosure + * @param Closure|mixed $productWebsiteClosure + * @param Closure|mixed $shortDescriptionClosure + * @param Closure|mixed $descriptionClosure + * @param Closure|mixed $priceClosure + * @param Closure|mixed $attributeSetClosure + * @param Closure|mixed $additionalAttributesClosure + * @param Closure|mixed $variationClosure + * @param int $optionsNumber + * @param string $suffix * * @SuppressWarnings(PHPMD) * * @return array */ - protected function getRows($productCategory, $productWebsite, $optionsNumber, $suffix = '') + protected function getRows( + $productCategoryClosure, + $productWebsiteClosure, + $shortDescriptionClosure, + $descriptionClosure, + $priceClosure, + $attributeSetClosure, + $additionalAttributesClosure, + $variationClosure, + $optionsNumber, + $suffix = '' + ) { $data = []; - $variation = []; for ($i = 1; $i <= $optionsNumber; $i++) { $productData = [ 'sku' => "Configurable Product %s-option {$i}{$suffix}", 'store_view_code' => '', - 'attribute_set_code' => 'Default', + 'attribute_set_code' => $attributeSetClosure, + 'additional_attributes' => $additionalAttributesClosure, 'product_type' => 'simple', - 'categories' => $productCategory, - 'product_websites' => $productWebsite, + 'categories' => $productCategoryClosure, + 'product_websites' => $productWebsiteClosure, 'color' => '', 'configurable_variation' => "option {$i}", 'cost' => '', @@ -279,7 +321,7 @@ class ConfigurableProductsFixture extends Fixture 'custom_design_from' => '', 'custom_design_to' => '', 'custom_layout_update' => '', - 'description' => '<p>Configurable product description %s</p>', + 'description' => $descriptionClosure, 'enable_googlecheckout' => '1', 'gallery' => '', 'gift_message_available' => '', @@ -301,12 +343,12 @@ class ConfigurableProductsFixture extends Fixture 'news_to_date' => '', 'options_container' => 'Block after Info Column', 'page_layout' => '', - 'price' => function () { return mt_rand(1, 1000) / 10; }, + 'price' => $priceClosure, 'quantity_and_stock_status' => 'In Stock', 'related_tgtr_position_behavior' => '', 'related_tgtr_position_limit' => '', 'required_options' => '0', - 'short_description' => '', + 'short_description' => $shortDescriptionClosure, 'small_image' => '', 'small_image_label' => '', 'special_from_date' => '', @@ -366,21 +408,18 @@ class ConfigurableProductsFixture extends Fixture '_media_position' => '', '_media_is_disabled' => '', ]; - - $variation[] = implode( - ',', - [ - 'sku=' . $productData['sku'], - 'configurable_variation=' . $productData['configurable_variation'], - ] - ); $data[] = $productData; } $data[] = $this->generateConfigurableProduct( - $productCategory, - $productWebsite, - implode('|', $variation), + $productCategoryClosure, + $productWebsiteClosure, + $shortDescriptionClosure, + $descriptionClosure, + $priceClosure, + $attributeSetClosure, + $additionalAttributesClosure, + $variationClosure, $suffix ); return $data; @@ -388,26 +427,141 @@ class ConfigurableProductsFixture extends Fixture /** * {@inheritdoc} + * @SuppressWarnings(PHPMD) */ public function execute() { - $configurableCount = $this->fixtureModel->getValue('configurable_products', 0); - if (!$configurableCount) { + $configurableProductsCount = $this->fixtureModel->getValue('configurable_products', 0); + if (!$configurableProductsCount) { return; } - $this->fixtureModel->resetObjectManager(); + $simpleProductsCount = $this->fixtureModel->getValue('simple_products', 0); + $maxAmountOfWordsDescription = $this->getSearchConfigValue('max_amount_of_words_description'); + $maxAmountOfWordsShortDescription = $this->getSearchConfigValue('max_amount_of_words_short_description'); + $minAmountOfWordsDescription = $this->getSearchConfigValue('min_amount_of_words_description'); + $minAmountOfWordsShortDescription = $this->getSearchConfigValue('min_amount_of_words_short_description'); + $attributes = $this->getAttributes(); + $searchTerms = $this->getSearchTerms(); + $this->fixtureModel->resetObjectManager(); $result = $this->getCategoriesAndWebsites(); - + $variationCount = $this->fixtureModel->getValue('configurable_products_variation', 3); $result = array_values($result); + $dataGenerator = new DataGenerator(realpath(__DIR__ . '/' . 'dictionary.csv')); - $productWebsite = function ($index) use ($result) { + $productWebsiteClosure = function ($index) use ($result) { return $result[$index % count($result)][0]; }; - $productCategory = function ($index) use ($result) { + $productCategoryClosure = function ($index) use ($result) { return $result[$index % count($result)][2] . '/' . $result[$index % count($result)][1]; }; - + $shortDescriptionClosure = function ($index) + use ( + $searchTerms, + $simpleProductsCount, + $configurableProductsCount, + $dataGenerator, + $maxAmountOfWordsShortDescription, + $minAmountOfWordsShortDescription + ) + { + $count = $searchTerms === null + ? 0 + : round( + $searchTerms[$index % count($searchTerms)]['count'] * ( + $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) + ) + ); + mt_srand($index); + return $dataGenerator->generate( + $minAmountOfWordsShortDescription, + $maxAmountOfWordsShortDescription, + 'shortDescription-' . $index + ) . ($index <= ($count * count($searchTerms)) ? ' ' + . $searchTerms[$index % count($searchTerms)]['term'] : ''); + }; + $descriptionClosure = function ($index) + use ( + $searchTerms, + $simpleProductsCount, + $configurableProductsCount, + $dataGenerator, + $maxAmountOfWordsDescription, + $minAmountOfWordsDescription + ) + { + $count = $searchTerms === null + ? 0 + : round( + $searchTerms[$index % count($searchTerms)]['count'] * ( + $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount) + ) + ); + mt_srand($index); + return $dataGenerator->generate( + $minAmountOfWordsDescription, + $maxAmountOfWordsDescription, + 'description-' . $index + ) . ($index <= ($count * count($searchTerms)) + ? ' ' . $searchTerms[$index % count($searchTerms)]['term'] : ''); + }; + $priceClosure = function($index) { + mt_srand($index); + switch (mt_rand(0,3)) { + case 0: return 9.99; + case 1: return 5; + case 2: return 1; + case 3: return mt_rand(1,10000)/10; + } + }; + $attributeSetClosure = function($index) use ($attributes, $result) { + mt_srand($index); + $attributeSet = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + return $attributeSet; + }; + $variationClosure = function($index, $variationIndex) use ($attributes, $result, $variationCount) { + mt_srand($index); + $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + $skus = []; + for ($i=1; $i <= $variationCount; $i++) { + $skus[] = 'sku=Configurable Product ' . $index . '-option ' . $i; + } + $values = []; + if ($attributeSetCode == 'Default') { + for ($i=1; $i <= $variationCount; $i++) { + $values[] = 'configurable_variation=option ' . $i; + } + } else { + for ($i=$variationCount; $i > 0; $i--) { + $attributeValues = ''; + foreach ($attributes[$attributeSetCode] as $attribute) { + $attributeValues = $attributeValues . $attribute['name'] . "=" . + $attribute['values'][($variationIndex - $i) % count($attribute['values'])] . ","; + } + $values [] = $attributeValues; + } + } + $variations = []; + for ($i=0; $i < $variationCount; $i++) { + $variations[] = trim(implode(",",[$skus[$i],$values[$i]]), ","); + } + return implode("|",$variations); + }; + $additionalAttributesClosure = function($index, $variationIndex) use ($attributes, $result) { + $attributeValues = ''; + mt_srand($index); + $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + if ($attributeSetCode !== 'Default' ) { + foreach ($attributes[$attributeSetCode] as $attribute) { + $attributeValues = $attributeValues . $attribute['name'] . "=" . + $attribute['values'][$variationIndex % count($attribute['values'])] . ","; + } + } + return trim($attributeValues, ","); + }; /** * Create configurable products */ @@ -415,9 +569,15 @@ class ConfigurableProductsFixture extends Fixture $pattern->setHeaders($this->getHeaders()); $pattern->setRowsSet( $this->getRows( - $productCategory, - $productWebsite, - $this->fixtureModel->getValue('configurable_products_variation', 3) + $productCategoryClosure, + $productWebsiteClosure, + $shortDescriptionClosure, + $descriptionClosure, + $priceClosure, + $attributeSetClosure, + $additionalAttributesClosure, + $variationClosure, + $variationCount ) ); @@ -435,7 +595,7 @@ class ConfigurableProductsFixture extends Fixture $source = $this->fixtureModel->getObjectManager()->create( Generator::class, - ['rowPattern' => $pattern, 'count' => $configurableCount] + ['rowPattern' => $pattern, 'count' => $configurableProductsCount] ); // it is not obvious, but the validateSource() will actually save import queue data to DB if (!$import->validateSource($source)) { @@ -467,9 +627,10 @@ class ConfigurableProductsFixture extends Fixture } /** + * @override * @return array */ - private function getCategoriesAndWebsites() + protected function getCategoriesAndWebsites() { /** @var \Magento\Store\Model\StoreManager $storeManager */ $storeManager = $this->fixtureModel->getObjectManager()->get(\Magento\Store\Model\StoreManager::class); diff --git a/setup/src/Magento/Setup/Fixtures/FixtureModel.php b/setup/src/Magento/Setup/Fixtures/FixtureModel.php index 118b29cb4306bb6e05580eea3bc0da207a72835d..44173a32c3e771ec2c43480a73c380ad2a2691ab 100644 --- a/setup/src/Magento/Setup/Fixtures/FixtureModel.php +++ b/setup/src/Magento/Setup/Fixtures/FixtureModel.php @@ -206,7 +206,9 @@ class FixtureModel if (!is_readable($filename)) { throw new \Exception("Profile configuration file `{$filename}` is not readable or does not exists."); } - $this->config = $this->fileParser->load($filename)->xmlToArray(); + $this->fileParser->getDom()->load($filename); + $this->fileParser->getDom()->xinclude(); + $this->config = $this->fileParser->xmlToArray(); } /** diff --git a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php index 6de4eaf91529fb3bc12cffe4d78aba238bc2fc05..fbb28d35269b177762410e8da7560612dd64db9c 100644 --- a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php +++ b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php @@ -6,6 +6,7 @@ namespace Magento\Setup\Fixtures; +use Magento\Setup\Model\DataGenerator; use Magento\Setup\Model\Generator; /** @@ -18,8 +19,14 @@ class SimpleProductsFixture extends Fixture */ protected $priority = 30; + /** + * @var array + */ + protected $searchConfig; + /** * {@inheritdoc} + * @SuppressWarnings(PHPMD) */ public function execute() { @@ -27,48 +34,16 @@ class SimpleProductsFixture extends Fixture if (!$simpleProductsCount) { return; } + $configurableProductsCount = $this->fixtureModel->getValue('configurable_products', 0); + $maxAmountOfWordsDescription = $this->getSearchConfigValue('max_amount_of_words_description'); + $maxAmountOfWordsShortDescription = $this->getSearchConfigValue('max_amount_of_words_short_description'); + $minAmountOfWordsDescription = $this->getSearchConfigValue('min_amount_of_words_description'); + $minAmountOfWordsShortDescription = $this->getSearchConfigValue('min_amount_of_words_short_description'); + $searchTerms = $this->getSearchTerms(); + $attributes = $this->getAttributes(); $this->fixtureModel->resetObjectManager(); - - /** @var \Magento\Store\Model\StoreManager $storeManager */ - $storeManager = $this->fixtureModel->getObjectManager()->create(\Magento\Store\Model\StoreManager::class); - /** @var $category \Magento\Catalog\Model\Category */ - $category = $this->fixtureModel->getObjectManager()->get(\Magento\Catalog\Model\Category::class); - - $result = []; - //Get all websites - $websites = $storeManager->getWebsites(); - foreach ($websites as $website) { - $websiteCode = $website->getCode(); - //Get all groups - $websiteGroups = $website->getGroups(); - foreach ($websiteGroups as $websiteGroup) { - $websiteGroupRootCategory = $websiteGroup->getRootCategoryId(); - $category->load($websiteGroupRootCategory); - $categoryResource = $category->getResource(); - //Get all categories - $resultsCategories = $categoryResource->getAllChildren($category); - foreach ($resultsCategories as $resultsCategory) { - $category->load($resultsCategory); - $structure = explode('/', $category->getPath()); - $pathSize = count($structure); - if ($pathSize > 1) { - $path = []; - for ($i = 0; $i < $pathSize; $i++) { - $path[] = $category->load($structure[$i])->getName(); - } - array_shift($path); - $resultsCategoryName = implode('/', $path); - } else { - $resultsCategoryName = $category->getName(); - } - //Deleted root categories - if (trim($resultsCategoryName) != '') { - $result[$resultsCategory] = [$websiteCode, $resultsCategoryName]; - } - } - } - } - $result = array_values($result); + $result = $this->getCategoriesAndWebsites(); + $dataGenerator = new DataGenerator(realpath(__DIR__ . '/' . 'dictionary.csv')); $productWebsite = function ($index) use ($result) { return $result[$index % count($result)][0]; @@ -76,10 +51,92 @@ class SimpleProductsFixture extends Fixture $productCategory = function ($index) use ($result) { return $result[$index % count($result)][1]; }; - - $generator = new Generator( - $this->getPattern($productWebsite, $productCategory), - $simpleProductsCount + $shortDescription = function ($index) use ( + $searchTerms, + $simpleProductsCount, + $configurableProductsCount, + $dataGenerator, + $maxAmountOfWordsShortDescription, + $minAmountOfWordsShortDescription + ) { + $count = $searchTerms === null + ? 0 + : round( + $searchTerms[$index % count($searchTerms)]['count'] * ( + $simpleProductsCount / ($simpleProductsCount + $configurableProductsCount) + ) + ); + return $dataGenerator->generate( + $minAmountOfWordsShortDescription, + $maxAmountOfWordsShortDescription + ) . ($index <= ($count * count($searchTerms)) ? ' ' + . $searchTerms[$index % count($searchTerms)]['term'] : ''); + }; + $description = function ($index) use ( + $searchTerms, + $simpleProductsCount, + $configurableProductsCount, + $dataGenerator, + $maxAmountOfWordsDescription, + $minAmountOfWordsDescription + ) { + $count = $searchTerms === null + ? 0 + : round( + $searchTerms[$index % count($searchTerms)]['count'] * ( + $simpleProductsCount / ($simpleProductsCount + $configurableProductsCount) + ) + ); + return $dataGenerator->generate( + $minAmountOfWordsDescription, + $maxAmountOfWordsDescription + ) . ($index <= ($count * count($searchTerms)) ? ' ' + . $searchTerms[$index % count($searchTerms)]['term'] : ''); + }; + $price = function () { + switch (mt_rand(0, 3)) { + case 0: + return 9.99; + case 1: + return 5; + case 2: + return 1; + case 3: + return mt_rand(1, 10000)/10; + } + }; + $attributeSet = function ($index) use ($attributes, $result) { + mt_srand($index); + return (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + }; + $additionalAttributes = function ($index) use ($attributes, $result) { + $attributeValues = ''; + mt_srand($index); + $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result)) + ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default'); + if ($attributeSetCode !== 'Default') { + foreach ($attributes[$attributeSetCode] as $attribute) { + $attributeValues = $attributeValues . $attribute['name'] . "=" . + $attribute['values'][mt_rand(0, count($attribute['values']) - 1)] . ","; + } + } + return trim($attributeValues, ","); + }; + $generator = $this->fixtureModel->getObjectManager()->create( + Generator::class, + [ + 'rowPattern' => $this->getPattern( + $productWebsite, + $productCategory, + $shortDescription, + $description, + $price, + $attributeSet, + $additionalAttributes + ), + 'limit' => $simpleProductsCount + ] ); /** @var \Magento\ImportExport\Model\Import $import */ $import = $this->fixtureModel->getObjectManager()->create( @@ -93,9 +150,13 @@ class SimpleProductsFixture extends Fixture ] ); // it is not obvious, but the validateSource() will actually save import queue data to DB - $import->validateSource($generator); + if (!$import->validateSource($generator)) { + throw new \Exception($import->getFormatedLogTrace()); + } // this converts import queue into actual entities - $import->importSource(); + if (!$import->importSource()) { + throw new \Exception($import->getFormatedLogTrace()); + } } /** @@ -103,21 +164,34 @@ class SimpleProductsFixture extends Fixture * * @param Closure|int|string $productWebsiteClosure * @param Closure|int|string $productCategoryClosure + * @param Closure|int|string $shortDescriptionClosure + * @param Closure|int|string $descriptionClosure + * @param Closure|int|string $priceClosure + * @param Closure|int|string $attributeSetClosure + * @param Closure|int|string $additionalAttributesClosure * @return array */ - protected function getPattern($productWebsiteClosure, $productCategoryClosure) - { + protected function getPattern( + $productWebsiteClosure, + $productCategoryClosure, + $shortDescriptionClosure, + $descriptionClosure, + $priceClosure, + $attributeSetClosure, + $additionalAttributesClosure + ) { return [ - 'attribute_set_code' => 'Default', + 'attribute_set_code' => $attributeSetClosure, + 'additional_attributes' => $additionalAttributesClosure, 'product_type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE, 'product_websites' => $productWebsiteClosure, 'categories' => $productCategoryClosure, 'name' => 'Simple Product %s', - 'short_description' => 'Short simple product description %s', + 'short_description' => $shortDescriptionClosure, 'weight' => 1, - 'description' => 'Full simple product Description %s', + 'description' => $descriptionClosure, 'sku' => 'product_dynamic_%s', - 'price' => 10, + 'price' => $priceClosure, 'visibility' => 'Catalog, Search', 'product_online' => \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED, 'tax_class_name' => 'Taxable Goods', @@ -155,4 +229,112 @@ class SimpleProductsFixture extends Fixture 'simple_products' => 'Simple products' ]; } + + /** + * @return array + */ + protected function getAttributes() + { + $attributeSets = $this->fixtureModel->getValue('attribute_sets', null); + $attributes = []; + + if ($attributeSets !== null && array_key_exists('attribute_set', $attributeSets)) { + foreach ($attributeSets['attribute_set'] as $attributeSet) { + $attributesData = array_key_exists(0, $attributeSet['attributes']['attribute']) + ? $attributeSet['attributes']['attribute'] : [$attributeSet['attributes']['attribute']]; + foreach ($attributesData as $attributeData) { + $values = []; + $optionsData = array_key_exists(0, $attributeData['options']['option']) + ? $attributeData['options']['option'] : [$attributeData['options']['option']]; + foreach ($optionsData as $optionData) { + $values[] = $optionData['label']; + } + $attributes[$attributeSet['name']][] = + ['name' => $attributeData['attribute_code'], 'values' => $values]; + } + } + } + return $attributes; + } + + /** + * @return array + */ + protected function getCategoriesAndWebsites() + { + /** @var \Magento\Store\Model\StoreManager $storeManager */ + $storeManager = $this->fixtureModel->getObjectManager()->create(\Magento\Store\Model\StoreManager::class); + /** @var $category \Magento\Catalog\Model\Category */ + $category = $this->fixtureModel->getObjectManager()->get(\Magento\Catalog\Model\Category::class); + + $result = []; + //Get all websites + $websites = $storeManager->getWebsites(); + foreach ($websites as $website) { + $websiteCode = $website->getCode(); + //Get all groups + $websiteGroups = $website->getGroups(); + foreach ($websiteGroups as $websiteGroup) { + $websiteGroupRootCategory = $websiteGroup->getRootCategoryId(); + $category->load($websiteGroupRootCategory); + $categoryResource = $category->getResource(); + //Get all categories + $resultsCategories = $categoryResource->getAllChildren($category); + foreach ($resultsCategories as $resultsCategory) { + $category->load($resultsCategory); + $structure = explode('/', $category->getPath()); + $pathSize = count($structure); + if ($pathSize > 1) { + $path = []; + for ($i = 0; $i < $pathSize; $i++) { + $path[] = $category->load($structure[$i])->getName(); + } + array_shift($path); + $resultsCategoryName = implode('/', $path); + } else { + $resultsCategoryName = $category->getName(); + } + //Deleted root categories + if (trim($resultsCategoryName) != '') { + $result[$resultsCategory] = [$websiteCode, $resultsCategoryName]; + } + } + } + } + return array_values($result); + } + + /** + * @return array + */ + protected function getSearchConfig() + { + if (!$this->searchConfig) { + $this->searchConfig = $this->fixtureModel->getValue('search_config', null); + } + return $this->searchConfig; + } + + /** + * @param string $name + * @return int|mixed + */ + protected function getSearchConfigValue($name) + { + return $this->getSearchConfig() === null + ? 0 : ($this->getSearchConfig()[$name] === null ? 0: $this->getSearchConfig()[$name]); + } + + /** + * @return array + */ + protected function getSearchTerms() + { + $searchTerms = $this->fixtureModel->getValue('search_terms', null); + if ($searchTerms !== null) { + $searchTerms = array_key_exists(0, $searchTerms['search_term']) + ? $searchTerms['search_term'] : [$searchTerms['search_term']]; + } + return $searchTerms; + } } diff --git a/setup/src/Magento/Setup/Fixtures/dictionary.csv b/setup/src/Magento/Setup/Fixtures/dictionary.csv new file mode 100644 index 0000000000000000000000000000000000000000..c839b7c46f51c25b1cda3afe4bfb7466e4ef082e --- /dev/null +++ b/setup/src/Magento/Setup/Fixtures/dictionary.csv @@ -0,0 +1,7373 @@ +the +of +and +a +in +to +it +is +to +was +I +for +that +you +he +be +with +on +by +at +have +are +not +this +but +had +they +his +from +she +that +which +or +we +an +were +as +do +been +their +has +would +there +what +will +all +if +can +her +said +who +one +so +up +as +them +some +when +could +him +into +its +then +two +out +time +my +about +did +your +now +me +no +other +only +just +more +these +also +people +know +any +first +see +very +new +may +well +should +like +than +how +get +way +one +our +made +got +after +think +between +many +years +er +those +go +being +because +down +yeah +three +good +back +make +such +on +there +through +year +over +must +still +even +take +too +more +here +own +come +last +does +oh +say +no +going +work +where +erm +us +government +same +man +might +day +yes +however +put +world +over +another +in +want +as +life +most +against +again +never +under +old +much +something +Mr +why +each +while +house +part +number +found +off +different +went +really +thought +came +used +children +always +four +where +without +give +few +within +about +system +local +place +great +during +although +small +before +look +next +when +case +end +things +social +most +find +group +quite +mean +five +party +every +company +women +says +important +took +much +men +information +both +national +often +seen +given +school +fact +money +told +away +high +point +night +state +business +second +British +need +taken +done +right +having +thing +looked +London +area +perhaps +head +water +right +family +long +hand +like +already +possible +nothing +yet +large +left +side +asked +set +whether +days +mm +home +called +John +development +week +use +country +power +later +almost +young +council +himself +far +both +use +room +together +tell +little +political +before +able +become +six +general +service +eyes +members +since +times +problem +anything +market +towards +court +public +others +face +full +doing +war +car +felt +police +keep +held +problems +road +probably +help +interest +available +law +best +form +looking +early +making +today +mother +saw +knew +education +work +actually +policy +ever +so +at least +office +am +research +feel +big +body +door +let +Britain +name +person +services +months +report +question +using +health +turned +lot +million +main +though +words +enough +child +less +book +period +until +several +sure +father +level +control +known +society +major +seemed +around +began +itself +themselves +minister +economic +wanted +upon +areas +after +therefore +woman +England +city +community +only +including +centre +gave +job +among +position +effect +likely +real +clear +staff +black +kind +read +provide +particular +became +line +moment +international +action +special +difficult +certain +particularly +either +open +management +taking +across +idea +further +whole +age +process +act +around +evidence +view +better +off +mind +sense +rather +seems +believe +morning +third +else +half +white +death +sometimes +thus +brought +getting +ten +shall +try +behind +heard +table +change +support +back +sort +Mrs +whose +industry +ago +free +care +order +century +range +European +gone +yesterday +training +working +ask +street +home +word +groups +history +central +all +study +usually +remember +trade +hundred +programme +food +committee +air +hours +experience +rate +hands +indeed +sir +language +land +result +course +someone +everything +certainly +based +team +section +leave +trying +coming +similar +once +minutes +authority +human +changes +little +cases +common +role +Europe +necessary +nature +class +reason +long +saying +town +show +subject +voice +companies +since +simply +especially +department +single +short +personal +pay +value +member +started +run +patients +paper +private +seven +UK +eight +systems +herself +practice +wife +price +type +seem +figure +former +lost +right +need +matter +decision +bank +countries +until +makes +union +terms +financial +needed +south +university +club +president +friend +parents +quality +cos +building +north +stage +meeting +foreign +soon +strong +situation +comes +late +bed +recent +date +low +US +concerned +girl +hard +American +David +according to +twenty +higher +tax +production +various +understand +led +bring +schools +ground +conditions +secretary +weeks +clearly +bad +art +start +include +poor +hospital +friends +decided +shown +music +month +English +tried +game +1990 +May +anyone +wrong +ways +chapter +followed +cost +play +present +love +issue +goes +described +award +Mr. +king +royal +results +workers +April +expected +amount +students +despite +knowledge +June +moved +news +light +March +approach +cut +basis +hair +required +further +paid +series +better +before +field +allowed +easy +kept +questions +natural +live +future +rest +project +greater +feet +meet +simple +died +for +happened +added +manager +computer +security +near +met +evening +means +round +carried +hear +bit +heart +forward +sent +above +attention +labour +story +structure +move +agreed +nine +letter +individual +force +studies +movement +account +per +call +board +success +1989 +French +following +considered +current +everyone +fire +agreement +please +boy +capital +stood +analysis +whatever +population +modern +theory +books +stop +legal +Scotland +material +son +received +model +chance +environment +finally +performance +sea +rights +growth +authorities +provided +nice +whom +produced +relationship +talk +turn +built +final +east +1991 +talking +fine +worked +west +parties +size +record +red +close +property +myself +example +space +giving +normal +nor +reached +buy +serious +quickly +Peter +along +plan +behaviour +France +recently +term +previous +couple +included +pounds +anyway +cup +treatment +energy +total +thank +director +prime +levels +significant +issues +sat +income +top +choice +costs +design +pressure +scheme +July +change +a bit +list +suddenly +continue +technology +hall +takes +ones +details +happy +consider +won +defence +following +parts +loss +industrial +activities +throughout +spent +outside +teachers +generally +opened +floor +round +activity +hope +points +association +nearly +United +allow +rates +sun +army +sorry +wall +hotel +forces +contract +dead +Paul +stay +reported +as well +hour +difference +meant +summer +county +specific +numbers +wide +appropriate +husband +top +played +relations +Dr +figures +chairman +set +lower +product +colour +ideas +George +St +look +arms +obviously +unless +produce +changed +season +developed +unit +appear +investment +test +basic +write +village +reasons +military +original +successful +garden +effects +aware +yourself +exactly +help +suppose +showed +style +employment +passed +appeared +page +hold +suggested +Germany +continued +October +offered +products +popular +science +New +window +expect +beyond +resources +rules +professional +announced +economy +picture +okay +needs +doctor +maybe +events +direct +gives +advice +running +circumstances +sales +risk +interests +September +dark +event +thousand +involved +written +park +1988 +returned +ensure +America +fish +wish +opportunity +commission +1992 +oil +sound +ready +lines +shop +looks +James +immediately +worth +college +press +January +fell +blood +goods +playing +carry +less +film +prices +useful +conference +operation +follows +extent +designed +application +station +television +access +Richard +response +degree +majority +effective +established +wrote +region +green +York +ah +western +traditional +easily +cold +shows +offer +though +statement +Scottish +published +forms +German +down +accept +miles +independent +election +support +importance +lady +site +jobs +needs +plans +earth +earlier +title +parliament +standards +leaving +interesting +houses +planning +considerable +girls +involved +Ireland +increase +species +stopped +concern +public +means +caused +raised +through +glass +physical +thought +Michael +eye +left +heavy +walked +daughter +existing +competition +speak +responsible +up to +river +follow +software +complete +above +November +December +purpose +mouth +medical +responsibility +Sunday +Wales +leader +tomorrow +piece +thirty +lay +officer +task +blue +answer +stand +thinking +extra +highly +places +arm +eventually +campaign +ability +appeal +whole +Charles +skills +opposition +remained +pattern +method +miss +hot +lead +source +bought +baby +lack +once +bill +division +remain +surface +older +charge +methods +trouble +fully +equipment +moving +suggest +disease +officers +past +peace +male +slightly +demand +failed +wants +attempt +types +Christmas +hit +post +policies +hardly +ii +arrived +compared +below +otherwise +windows +West +deal +directly +interested +sale +like +firm +status +happen +box +even if +teacher +radio +provision +variety +show +ran +sector +return +factors +essential +direction +beautiful +civil +base +waiting +caught +sit +develop +character +safety +placed +past +completely +tea +introduced +killed +love +mum +context +fifty +primary +animals +culture +Oxford +brother +obvious +weight +discussion +created +1987 +future +other +start +States +none +sold +let's +machine +afternoon +knows +environmental +fair +William +February +provides +wait +league +trees +positive +organisation +win +condition +families +argument +Saturday +learn +up +normally +claimed +truth +senior +kitchen +works +add +lived +library +minute +believed +enough +transport +share +principle +create +agree +born +players +cash +exchange +rule +budget +turn +pupils +nuclear +sitting +version +English +best +features +duty +annual +balance +front +send +boys +presence +protection +dog +courses +individuals +matters +media +avoid +influence +presented +speaker +stone +relevant +apply +August +explain +deep +Robert +1986 +achieved +slowly +relatively +shares +letters +finished +survey +huge +accepted +covered +review +Smith +closed +form +marriage +commercial +aid +lives +collection +living +speech +Africa +regional +differences +benefit +apparently +effort +gets +executive +later +latter +function +failure +return +chair +reference +horse +becomes +attack +reports +practical +queen +subjects +career +bar +official +text +appears +separate +student +names +sell +holiday +larger +cells +open +progress +early +states +helped +visit +smiled +stock +memory +merely +studio +key +putting +eat +opinion +understanding +regular +decisions +chief +drawn +firms +remains +facilities +values +district +cars +due +mhm +begin +managed +receive +corner +image +edge +sister +politics +expression +instead +impact +quarter +forced +inside +views +scale +plant +race +ball +gold +join +Henry +spend +voice +alone +additional +benefits +1985 +trust +for instance +largely +advantage +associated +increased +standing +dad +foot +somebody +pain +gas +clothes +smaller +aspects +active +affairs +possibly +increase +railway +ended +feeling +network +leaders +nevertheless +cause +half +powerful +step +complex +joined +plants +standard +holding +carefully +length +mind +rise +strength +crime +hard +wind +Mary +possibility +becoming +damage +records +reduce +examples +mainly +credit +winter +impossible +insurance +explained +units +currently +forest +formed +somewhere +earlier +beginning +regarded +fall +confidence +discussed +speed +legislation +mentioned +along +pulled +spoke +debate +intended +bodies +message +middle +plus +supply +100 +skin +Edward +stuff +providing +entirely +front +domestic +require +proved +expressed +treated +match +solution +previously +tonight +patient +actual +difficulties +farm +united +far +build +reach +proposals +extremely +choose +ministers +technical +fresh +ordinary +scene +materials +museum +Thomas +move +article +prevent +achieve +customers +includes +powers +band +items +justice +play +animal +internal +suggests +excellent +face +rich +assessment +save +phone +fairly +football +watched +telephone +steps +decide +South +traffic +watch +coffee +deal +sources +past +buildings +increasingly +relief +distance +introduction +forty +administration +no +safe +applied +sight +Mark +island +potential +banks +housing +meaning +existence +claim +northern +enjoy +reduced +twelve +equally +in front of +walk +very +apart from +watching +cultural +famous +latest +users +TV +cabinet +legs +institutions +Japan +measures +reality +proper +video +worse +lose +argued +train +spirit +programmes +accounts +trial +target +fear +joint +doubt +formal +unemployment +prison +accident +concept +limited +elements +strange +served +papers +discovered +conservative +rock +cover +usual +tree +smile +unable +warm +surely +organization +battle +proportion +difficulty +sides +refused +weekend +construction +picked +distribution +dinner +wine +while +works +obtained +exercise +writing +asking +showing +ahead +rural +lovely +applications +twice +factor +path +games +funds +whereas +nobody +shape +initial +substantial +referred +tend +seat +improve +onto +thanks +aircraft +light +contact +quiet +rain +background +identified +contrast +officials +strategy +average +master +forget +leading +soft +reasonable +seeing +pound +grounds +raise +immediate +communication +client +Paris +star +fourth +suitable +determined +ought +detail +everybody +noted +equal +imagine +appointed +manner +homes +classes +freedom +operations +detailed +keeping +selection +requirements +pair +draw +walls +talks +working +call +danger +attitude +user +overall +offer +female +relationships +Edinburgh +note +afraid +pick +charges +democratic +elections +entered +courts +growing +goal +straight +techniques +sufficient +middle +agency +scientific +eastern +crisis +rose +correct +removed +prince +theatre +Irish +laid +act +expensive +markets +sign +educational +capacity +telling +happens +absolutely +patterns +whilst +managers +purposes +employees +1984 +totally +opportunities +cause +break +will +procedure +feeling +output +mental +frequently +bridge +dangerous +either +fingers +recognition +largest +turning +arrangements +sites +profits +quick +absence +sentence +beside +pass +fields +critical +pointed +prove +listen +inc +recorded +cost +signed +hill +dropped +card +tour +understood +notes +track +1983 +partly +replaced +increased +weather +principles +seriously +familiar +related +package +elsewhere +teaching +bottom +necessarily +commitment +player +double +birds +properly +1993 +Jack +threat +notice +unlikely +admitted +1981 +replied +silence +route +file +liked +supported +issued +perfect +victory +discuss +widely +occur +second +violence +efforts +element +neck +carrying +conflict +pieces +Darlington +under +profit +reaction +colleagues +historical +standard +end +Friday +finance +hope +rooms +projects +closely +fund +daily +below +cell +Liverpool +Tom +southern +expenditure +increasing +discipline +completed +occurred +individual +spring +audience +lead +thousands +grow +conversation +tiny +congress +emphasis +finding +exist +check +alone +consideration +speaking +learning +defined +seek +1979 +appearance +maintain +option +dry +bright +urban +pictures +estate +debt +youth +neither +affected +married +feature +payment +exhibition +liberal +supposed +assembly +reform +empty +boat +suffered +bus +hell +remembered +driver +lunch +flowers +heat +processes +upper +volume +share +captain +murder +North +fifteen +represented +meetings +contribution +drugs +die +feelings +outside +Ian +arts +leg +serve +dealing +writing +curriculum +bag +sought +apparent +branch +beginning +noticed +procedures +models +Martin +enter +revealed +institute +establish +object +occasion +waste +facts +membership +requires +shook +Monday +claims +control +prepared +younger +faith +shops +challenge +answer +Russian +moral +pleasure +orders +Alan +heads +bloody +careful +filled +Corp +literature +birth +1980 +leading +code +centres +broke +prepared +that +professor +1982 +aye +wood +gentleman +flight +entry +pretty +attractive +wild +investigation +crown +protect +nodded +greatest +subject to +functions +encourage +belief +care +developments +description +tradition +Japanese +thin +adopted +vital +document +conclusion +hoped +Italy +enjoyed +engineering +coal +transfer +address +breath +along with +Ltd +alternative +total +schemes +copy +desire +search +effectively +organisations +demands +pushed +visit +etc +planning +farmers +ancient +released +opening +lips +iii +treaty +newspaper +aim +drug +identify +engine +Manchester +USA +tests +owner +sky +Tony +wearing +depends +elderly +ministry +Australia +busy +inside +anybody +reading +external +capable +marketing +streets +partner +respect +shot +institution +generation +acid +realised +chosen +wider +his +narrow +horses +broad +ordered +wonderful +key +contained +laughed +bringing +clients +typical +drink +Stephen +employed +atmosphere +slow +wondered +clean +actions +entire +troops +Leeds +vote +definition +welfare +reduction +row +walking +laws +visitors +release +meanwhile +confirmed +examination +doors +leadership +attitudes +East +enable +beneath +journey +milk +stated +hence +IBM +machines +affect +grey +screen +criticism +surprise +reading +nineteen +stories +billion +constant +teeth +brain +explanation +brief +signs +married +highest +cover +starting +knowing +claim +creation +castle +governments +goals +intention +India +vast +flat +guide +drive +surprised +easier +ideal +shut +readers +run +Bill +magazine +bound +terrible +thoughts +kinds +academic +worry +minor +seats +customer +significance +measure +pleased +unfortunately +o'clock +revolution +attempts +noise +charged +rare +biggest +rather than +somewhat +sections +stared +seeking +paying +meeting +encouraged +thick +Jones +loved +metal +grand +plenty +note +phase +coast +injury +China +granted +motion +observed +technique +ill +drew +potential +factory +lying +severe +mine +lights +wonder +Harry +spread +contains +strongly +offers +afterwards +committed +tape +shoulder +bear +corporate +obtain +kill +that is +worst +learned +settlement +ooh +grew +represent +rapidly +tall +hole +living +adult +iron +amongst +faced +negative +afford +lots +index +permanent +beat +trip +contain +fundamental +doctors +desk +ourselves +sport +unions +implications +fashion +content +similarly +elected +proposed +judge +pool +inflation +brown +Brian +originally +funny +via +practices +somehow +payments +odd +Andrew +pension +pay +crucial +fit +inner +appointment +used +flow +launched +Chris +independence +Spain +objects +setting +little +least +colours +palace +perfectly +combination +contracts +criminal +consequences +pages +contemporary +UN +talked +session +sharp +structures +planned +drive +Wednesday +Kingdom +falling +sample +virtually +fast +sick +movements +dogs +Anne +Yorkshire +Roman +accommodation +nation +temperature +massive +societies +consumer +cities +offices +documents +valley +indicated +breakfast +stayed +kids +display +named +bedroom +sports +aspect +unique +Steve +sixty +author +lane +objectives +secondary +wear +republic +agent +interpretation +assistance +directors +badly +alright +parliamentary +African +Joe +unknown +industries +assets +selling +moreover +Northern +nose +Jim +Russia +subsequent +place +describe +declared +gallery +allowing +ship +other than +visited +cross +grown +crowd +recognised +interview +broken +Simon +argue +BBC +naturally +thinking +general +Mike +meal +catch +representatives +proceedings +tears +alive +involving +shoulders +employers +begun +departments +vision +yours +unix +beauty +guilty +proposal +impression +square +angry +regulations +regions +vehicle +Jane +democracy +sequence +offering +Graham +enormous +invited +cancer +sheet +struck +Glasgow +rarely +involve +involvement +improvement +ninety +motor +shock +tone +significantly +contact +manufacturing +close +seconds +dress +assumed +well +quietly +grass +nations +provisions +communities +roof +yellow +indicate +distinction +present +statements +comments +allows +late +pollution +fruit +acting +involves +unusual +assume +towns +lucky +fuel +spot +properties +touch +fall +Major +bottle +except +anywhere +net +buying +long-term +soil +sum +stages +decline +missed +reader +extensive +manage +calling +talk +heavily +containing +plate +advertising +revenue +remaining +glad +diet +agricultural +artist +plastic +artists +gently +Bob +alright +location +ring +ice +operate +lies +candidates +Italian +pull +passage +principal +cope +linked +tired +periods +firmly +occasionally +identity +persons +limited +warned +efficient +runs +hundreds +maintenance +divided +unlike +establishment +channel +producing +fight +happening +song +map +expert +formation +comfortable +border +constitution +weapons +emergency +Chinese +waited +continues +arranged +link +Wilson +spokesman +extended +rail +Philip +candidate +believes +funding +promised +positions +mostly +household +remove +performed +cat +sleep +abroad +teams +mountain +program +countryside +stars +victim +studied +relative +criteria +conventional +parish +framework +willing +strike +cheap +ref +sudden +approval +concentration +partners +autumn +maintained +warning +cards +roads +approved +lake +starts +determine +liability +editor +realise +thinks +helping +longer +proposed +voluntary +settled +grant +characters +valuable +situations +deputy +walk +regularly +occasions +trading +rejected +agriculture +premises +dramatic +fill +theme +silver +golden +duties +friendly +arguments +accused +driving +losses +error +reflected +dream +shortly +wealth +working +temporary +federal +stress +painting +request +initially +reflect +lifted +eighty +hello +pub +recovery +loan +electricity +1980s +chest +Margaret +refer +taught +silent +Brown +beach +Indian +eleven +answered +learning +recession +focus +facing +video-taped +height +clubs +item +characteristics +emerged +options +matter +hurt +forgotten +worried +bread +admit +chief +specifically +owners +Lewis +statutory +mirror +agents +writer +deeply +Welsh +foundation +struggle +1978 +parent +dependent +mistake +reputation +Frank +eggs +decade +steel +gain +leads +publication +resistance +offence +incident +Thursday +prefer +stations +denied +examine +lifespan +wages +tasks +gained +acquired +outcome +claims +travel +competitive +marked +panel +resolution +wished +dear +efficiency +demanded +flat +yards +subsequently +gradually +businesses +chancellor +chain +specialist +1977 +dressed +tells +negotiations +relating +supporters +armed +radical +sleep +representation +agencies +theories +outside +shoes +threatened +spending +keen +drove +gardens +acceptable +notion +initiative +stairs +Cambridge +advance +leaves +recognise +worker +essentially +empire +shared +sensitive +uses +clause +attached +Taylor +living +fallen +Belfast +fighting +dear +controlled +sugar +Elizabeth +block +global +delivery +changing +Lee +computers +ages +meat +mass +emotional +brothers +bird +expansion +islands +healthy +Middlesbrough +aside +attend +secret +store +1976 +break +writers +self +rising +travel +bigger +alternative +rapid +instructions +wet +adequate +weak +licence +fixed +soldiers +examined +aimed +owned +average +awareness +centuries +images +drama +notice +Tuesday +handed +furniture +gate +scientists +administrative +sees +pocket +wooden +uncle +remarkable +co-operation +creating +Adam +Luke +newspapers +currency +comprehensive +intelligence +charity +fifth +links +hoping +respond +surprising +extension +solid +survive +growing +apart +restaurant +churches +precisely +pale +skill +close +connection +mass +dealt +brilliant +maximum +losing +depend +200 +experienced +across +introduce +philosophy +convention +gun +films +sons +eh +communications +regime +miss +attended +suffer +copies +councils +round +partnership +inquiry +Sarah +residents +absolute +firm +French +corporation +arrested +reports +minority +arrival +in addition to +listening +taste +sad +gap +plane +scope +experiences +coat +command +consequence +left +fun +Birmingham +tory +golf +electronic +behind +visual +retirement +replace +rise +darkness +fault +directed +complete +1970s +enemy +comment +electric +priority +metres +database +Tim +pure +Spanish +Nigel +rough +core +circle +result +literary +bay +championship +guests +1975 +insisted +mere +bits +successfully +limit +imposed +continuing +Rome +sounds +abuse +categories +languages +tower +Thatcher +anger +accompanied +category +collected +present +need +comparison +supreme +supplied +chemical +fans +greatly +sweet +wedding +teaching +represents +duke +mark +personnel +genuine +adults +mail +politicians +occurs +exciting +written +returning +promotion +longer +preparation +defendant +presumably +DNA +derived +Washington +paintings +fitted +mothers +affair +stupid +cricket +advanced +tank +arise +photographs +point +disappeared +expectations +findings +illness +citizens +mood +faces +tension +Commons +ladies +briefly +stones +mixture +classical +arrangement +extreme +Williams +nineteenth +discover +favourite +shot +causing +yard +begins +socialist +judgment +landscape +fail +feels +consumption +mill +1974 +informed +birthday +widespread +consent +confident +acts +Gloucester +sake +estimated +requirement +catholic +experts +Israel +numerous +throat +permission +ignored +guidance +moments +brings +costs +module +opposite +respectively +altogether +input +presentation +everywhere +distinct +statistics +repeated +tough +earnings +saved +finger +branches +fishing +components +truly +drink +turns +luck +boss +exists +champion +MP +answers +tools +cycle +recommended +intervention +mile +Scott +whenever +AIDS +promote +helpful +prospect +definitely +Johnson +organised +controls +Ben +express +Iraq +nurse +frame +perform +cottage +wave +adding +proud +by +winner +solicitor +neighbours +pilot +calls +mad +alliance +given +straight +survival +winning +votes +primarily +attacks +compensation +Sam +destroyed +camp +hat +territory +symptoms +prior to +ownership +wage +concluded +discussions +developing +cream +achievement +drawing +entrance +basically +poverty +disabled +extend +fast +suggestion +consistent +shareholders +degrees +mention +anxious +fewer +delivered +dark +transferred +employee +throw +assumption +inevitably +nervous +profession +awful +cool +hang +threw +vehicles +stable +realized +suit +hills +prize +drop +constitutional +perspective +Neil +satisfied +bid +aunt +festival +constantly +conscious +developing +connected +concerning +savings +reasonably +concentrate +pace +novel +operating +breach +purchase +crossed +Asia +chances +depth +calls +strategic +thrown +bills +Jean +Ken +reply +ha +Ruth +treat +green +sheep +dominant +phrase +push +eating +now that +conducted +employer +ears +contents +touched +prepare +sounded +Moscow +theoretical +setting +soul +wore +study +1960s +outstanding +benefit +vary +jacket +except +holy +processing +sand +clinical +prisoners +dispute +shadow +minimum +organizations +plaintiff +snow +cried +fit +driven +Joseph +port +recognized +servants +limits +pink +et al +sound +hearing +measured +dance +eighteen +sorts +Patrick +trained +stomach +slight +fought +points +storage +breaking +impressive +honest +provided +dismissed +glanced +related +cast +crew +defeat +hold +gift +enthusiasm +princess +press +spending +advantages +reaching +articles +resulted +files +hung +cuts +residential +extraordinary +visible +shouted +reducing +experiments +tables +finish +tendency +conduct +objective +report +ring +hospitals +mechanism +seventy +exception +poetry +inspector +1973 +covering +stepped +accurate +percent +victims +approached +distant +alongside +airport +furthermore +considerably +pressed +missing +origin +salt +personality +fight +Canada +arrive +fly +Greek +receiving +still +rocks +fees +fee +complicated +ends +musical +stands +moon +chamber +puts +turnover +attacked +ultimately +routine +observation +precise +plain +gentle +watch +staring +since +leisure +economics +device +broken +mortgage +live +leaves +confusion +cut +finds +instruments +secondly +Bush +certificate +ear +remote +satisfaction +responsibilities +ratio +coach +fears +sentences +holder +shopping +possession +selected +Bristol +sets +smoke +rugby +songs +clock +summary +implementation +protein +housing +escape +wing +fixed +helps +poll +Arthur +scored +chose +column +holidays +contributions +architecture +Nick +approximately +disaster +minds +Keith +marks +trust +neither +monetary +mountains +White +discovery +collect +spoken +steam +smooth +silly +childhood +teach +Kong +unity +staying +climate +percentage +villages +attracted +Americans +designs +secure +cutting +iv +Hong +last +taxes +tennis +peak +relation +readily +evaluation +frequency +Andy +shirt +cake +nights +bishop +test +pretty +Charlie +deliberately +round +determination +applies +automatically +standing +rent +psychological +violent +medicine +boards +protest +Anna +unemployed +final +being +Rose +reforms +inevitable +junior +signal +building +till +welcome +fat +roles +headquarters +sensible +visits +manufacturers +restrictions +samples +Pacific +improved +Berlin +grateful +strategies +score +tended +expense +loans +addressed +mode +structural +dozen +pride +newly +founded +variation +aged +rely +investors +infection +dominated +combined +survived +Helen +string +Lucy +experiment +fourteen +undertaken +committees +buyer +agreements +participation +welcome +match +complaints +ships +critics +guitar +camera +laboratory +waves +landlord +rang +hate +demonstrated +bomb +engaged +knife +so-called +modules +pleasant +headed +surgery +universities +millions +concepts +proof +marry +Maggie +operating +pressures +lives +sixteen +repeat +host +Dave +pitch +attempted +assess +penalty +tail +boxes +holes +deep +contribute +passing +reveal +cleared +thereby +acceptance +1972 +anxiety +above +Newcastle +formula +personally +Howard +mission +deaf +relatives +imagination +apple +dirty +rid +abandoned +appreciate +continuous +describes +suffering +circuit +stronger +responses +excitement +approaches +supply +plan +Zealand +tested +disk +holds +replacement +instrument +universe +memories +overseas +expertise +causes +solicitors +comfort +sergeant +trend +treasury +entitled +sounds +acquisition +opening +tickets +bath +delighted +sending +increasing +confirm +loose +state +targets +occasional +paragraph +writes +evident +Kent +desperate +handle +fellow +blind +occupied +overcome +dust +burden +psychology +relate +drivers +surprisingly +1970 +Matthew +cheese +consciousness +considering +universal +Gordon +aha +square +succeeded +knees +1971 +boots +smell +closer +mummy +slipped +component +regulation +Roger +attempt +locked +keeps +wheel +classic +MPs +cattle +consists +touch +illustrated +platform +shift +draft +purely +load +influenced +passengers +recommendations +preparing +solutions +Alexander +injuries +tenant +commonly +Victoria +leather +gathered +zone +sufficiently +like +Laura +squad +recall +steady +retain +checked +existed +attract +conservation +flesh +pack +publicity +rose +mean +variations +split +sixth +edition +concerns +tied +summit +engineers +Terry +listed +judges +researchers +equivalent +assist +upstairs +hers +Francis +located +nurses +fear +mark +suggesting +whispered +serving +intellectual +influence +stream +generated +consequently +San +authors +wondering +judgement +experience +Victorian +egg +supplies +level +produces +councillor +roots +taxation +bathroom +ultimate +awarded +stick +glasses +raising +qualities +layer +lost +creative +medieval +risks +assumptions +displayed +dreams +Germans +accounting +curve +drawing +backed +adopt +colleges +guard +evolution +sign +aims +sharply +constructed +advised +softly +settle +decades +completion +linguistic +ignore +convinced +Colin +judicial +photograph +sophisticated +Alice +asleep +paused +amounts +poem +recording +carbon +Durham +possibilities +good +explains +equation +NHS +vulnerable +raw +net +deaths +babies +illegal +outer +topic +medium +till +promise +tends +hopes +angle +interviews +ban +feed +potentially +machinery +tongue +coalition +travelling +define +consultation +reception +pulling +Nicholas +integration +revolutionary +quoted +compare +surrounded +bitter +attempting +guess +improvements +climbed +cathedral +heaven +wanting +painted +Australian +changing +grammar +jumped +Ulster +Gulf +native +imperial +persuade +voices +conclusions +laughing +lift +1968 +Gary +boundaries +favour +guy +studying +Jimmy +beliefs +undoubtedly +wings +retained +joy +bone +informal +demonstrate +Douglas +regard +clear +calculated +flexible +meals +announcement +lawyers +ruled +account +sheets +tunnel +exercise +bars +carpet +quantity +catalogue +reminded +shrugged +notably +Anthony +schedule +petrol +investigate +hotels +buried +once more +journal +nowhere +considerations +concentrated +collective +destruction +frequent +versions +offences +agenda +clever +experimental +plays +Kate +listened +La +texts +plates +deficit +transition +Norman +spiritual +intense +indication +flew +pushing +rational +hanging +entitled +excluded +knocked +professionals +tight +composition +indicates +conservatives +Kevin +interaction +ceiling +guidelines +cold +roughly +Governor +qualifications +ethnic +me +argues +Dublin +inches +opera +pupil +cheaper +generous +prominent +inadequate +accordingly +welcomed +instruction +logical +passion +drawings +exposure +departure +blame +racing +mixed +historic +guest +Mrs. +pipe +modest +Dutch +lessons +hero +Lloyd +sectors +Diana +barely +logic +Essex +acute +harm +representing +discourse +voted +electrical +hearing +consumers +jury +Grant +weekly +acted +delay +valid +wherever +representative +transaction +bowl +increases +contributed +Christopher +record +leaned +lesson +lit +admission +stores +awards +automatic +timber +trousers +vote +habit +Oliver +arrange +red +matches +punishment +bones +cross +deny +rubbish +hide +mortality +complex +pc +earl +explore +urged +occupation +storm +darling +keys +customs +profile +gross +depression +classroom +glance +mystery +mutual +reliable +wholly +entering +bare +liable +facility +stressed +stuck +realize +engineer +smiling +confined +province +registration +males +laughter +humour +resource +multiple +Albert +ruling +silk +waters +Rachel +paint +cotton +Atlantic +identification +claiming +sole +coverage +arising +Owen +honour +poet +prospects +travelled +divisions +posts +avoided +in case +charter +managing +pregnant +obligation +win +adds +formally +flying +Latin +nearby +Egypt +exact +directions +curious +bother +participants +lawyer +resignation +bearing +sets +pointing +tool +damages +speakers +fate +daddy +devices +phenomenon +strain +substance +bags +wire +Wood +underlying +responded +enjoying +visitor +joining +uncertainty +but +drop +submitted +flower +Ford +California +perception +identical +farming +letting +audit +satisfactory +Billy +ticket +lists +preference +Great +thirteen +Van +secret +pop +album +federation +learnt +deliver +Westminster +chemicals +farmer +variables +male +assault +marginal +leave +namely +fed +distinctive +kingdom +assessed +refuse +electoral +urgent +allowance +observations +libraries +Lawrence +reflects +force +sympathy +running +falls +publishing +recovered +stability +canal +funeral +singing +titles +beds +sessions +restricted +Sheffield +Nottingham +expecting +clothing +drinks +disposal +failing +joke +focus +succeed +Maria +typically +official +conversion +presidential +generations +mayor +sharing +Clare +worth +transactions +era +policeman +Fred +gaze +controversial +count +proceed +Young +folk +fabric +oral +horror +Kelly +everyday +emperor +viewed +sing +belt +fortune +demand +doubt +crash +encouraging +interpreted +Louis +organic +maintaining +removal +female +routes +continued +trials +enables +print +laugh +bent +expected +connections +magistrates +errors +statistical +resolved +desirable +recognize +Stuart +thoroughly +injured +van +blocks +prosecution +register +trends +preferred +reckon +innocent +ideology +belong +improved +past +corridor +exclusive +tale +pairs +prayer +collapse +lease +talent +gains +separated +marked +experienced +persuaded +sighed +butter +suggestions +Russell +unexpected +foods +picking +banking +sciences +superb +contacts +operated +alarm +go +Poland +gene +daughters +sheer +guardian +count +cloud +disappointed +Bernard +format +scenes +frightened +hardware +traditionally +gastric +genes +effectiveness +full-time +intend +concentrations +defend +strict +fighting +creatures +closer +Swindon +capitalist +Walker +addition +chocolate +emerge +Hugh +hidden +likes +Susan +Stewart +reactions +lands +establishing +swept +anniversary +permitted +export +1967 +justify +tissue +Davies +bet +specified +romantic +garage +conviction +declined +resigned +Clarke +advise +scientist +root +asset +warmth +bulk +bands +knee +minimum +humans +references +any +associations +muscles +withdrawal +registered +distributed +regarding +exposed +declaration +graphics +reluctant +actor +switched +sisters +winners +eighteenth +chemistry +rest +justified +stop +converted +boundary +suspect +magnificent +stretched +convenient +friendship +established +recover +destroy +Jackson +mess +correspondent +navy +dollar +craft +reflection +chicken +plans +tin +Miller +curtains +gesture +tourist +diary +protected +ocean +discussing +practitioners +bloody +entertainment +nearest +mechanisms +closed +expenses +uncertain +artificial +democrats +damaged +composed +heating +diplomatic +drinking +discrimination +rows +bench +councillors +acquire +installed +guns +killing +Microsoft +blow +salary +Baker +tip +1950s +physically +estates +tremendous +marine +ease +institutional +mechanical +retail +resist +mixed +literally +chapel +distinguish +wildlife +Rivers +Iran +tories +doubts +formerly +priorities +reserves +publications +commented +gender +passenger +Sussex +strictly +boats +causes +pen +chapters +cheque +required +testing +carriage +weapon +generate +Clinton +asks +earn +supporting +mentally +judge +messages +females +biological +applying +implies +known +Emily +rolled +tube +functional +accidents +flexibility +chairs +Phil +styles +cap +straightforward +moves +wise +fired +organized +inspection +Derek +mathematics +heritage +superior +1969 +specially +finance +cloth +sociology +desperately +fiction +equity +satisfy +Lords +shell +Wright +lad +whereby +forests +suit +pursue +digital +increases +tenants +refers +voters +piano +productivity +part-time +lightly +assistant +Commander +address +situated +restoration +outlined +imports +comment +stolen +Harris +clerk +cinema +Ann +covers +capitalism +spectacular +shapes +controversy +Marx +gates +escaped +Robin +continuing +trains +ensuring +colonel +confused +grants +remarks +bonds +wives +computing +constraints +solve +aggressive +availability +unfair +sadly +invasion +tracks +compete +closure +spare +painful +earned +venture +topics +wonder +equivalent +grade +Korea +pot +emotions +washed +escape +abstract +Eric +murmured +stake +lift +states +breeding +securities +asian +mud +Joan +estimates +cheek +stored +correctly +refugees +Moore +obligations +spirits +unhappy +Ross +networks +beaten +snapped +initiatives +understanding +alter +shame +pensions +oxygen +therapy +associated +courage +discretion +dates +deposits +hopefully +exports +legislative +Eliot +ward +monthly +deciding +describing +assuming +opposed +Alex +searching +intelligent +impose +explicit +jurisdiction +designer +tie +fellow +quantities +fleet +Barry +seller +RAF +borough +stand +flats +virtue +constituency +complained +coloured +midnight +taxi +engines +railways +display +just +ridiculous +Caroline +debts +comparable +amazing +acknowledged +appeal +wars +successive +refusal +incorporated +creature +secured +economies +isolation +Leicester +succession +signals +working-class +physics +feared +concert +tonnes +realistic +hungry +launch +Evans +resort +burst +sort +back +Walter +gear +Shakespeare +surveys +volunteers +stick +separation +la +demonstration +fails +conception +decent +discount +unnecessary +prevented +flying +worn +dictionary +twentieth +fat +random +retired +local +origins +packed +achieving +heading +forever +influential +masters +channels +harbour +producers +duration +Thames +cable +1945 +desert +terrace +assured +allocation +check +diseases +merchant +constable +Vietnam +Dean +recalled +lifetime +chips +Ray +genetic +complaint +near +visiting +explaining +order +marvellous +Malcolm +Morgan +restored +earliest +enabled +release +Cardiff +assurance +bottles +brick +essence +autonomy +giant +requiring +hunting +consensus +differ +vegetables +junction +workshop +measure +purchaser +secure +attendance +necessity +bottom +demanding +skilled +shaking +subtle +select +attack +questioned +sooner +producer +planet +elegant +amendment +hopes +carries +recommend +lesser +farms +parallel +limitations +locally +Marie +tragedy +instance +cousin +collections +backwards +grain +resulting +fraud +swung +landed +quarters +liberation +seventeen +referring +interior +bike +suspended +officially +journalists +nasty +movie +suppliers +dealer +shows +soldier +intensive +kit +witness +delight +symbol +forum +casual +tropical +shorter +Allen +crimes +printed +miners +feeding +relax +pass +manufacturer +chip +crazy +forming +kissed +swimming +happily +copper +arguing +shots +landing +nursery +entries +preliminary +besides +arises +partial +households +damp +wool +1964 +servant +Pakistan +attending +Guy +plot +muscle +beings +inch +simultaneously +concrete +Roy +roll +bell +neighbour +reign +analysed +tide +expand +alleged +guilt +rank +introducing +transfer +uses +ceremony +Morris +separately +opinions +enquiry +grinned +lover +slept +choices +assistant +severely +finest +poured +vertical +Easter +upset +hey +allegations +IRA +justification +detective +programs +throwing +strike +ate +appendix +Jenny +districts +commonwealth +dealers +delicate +forms +advisers +lonely +dull +mouse +Pat +occupational +pity +behave +complexity +youngsters +riding +weakness +excessive +Clark +progressive +captured +stance +undertake +exceptional +faster +Iraqi +remind +counter +Greece +triumph +remarked +continental +striking +integrated +pit +encountered +implemented +sizes +directive +participate +safely +lowest +lighting +villa +okay +downstairs +portrait +alternatively +edges +focused +bye +residence +panic +label +aims +magazines +neat +combined +transformation +theft +lecture +incidence +scores +radiation +perceived +spread +firstly +interface +doctrine +shouting +affecting +ours +excuse +accepting +risen +Lancashire +approach +deposit +pond +substantially +innovation +diagnosis +gifts +allocated +regard +remainder +speculation +approaching +dialogue +estimate +wash +supervision +dying +exclusively +happiness +politically +timing +chronic +Geoffrey +peasants +tightly +characteristic +accuracy +compulsory +wrapped +interim +objective +Benjamin +walking +infant +Bruce +judged +splendid +ride +divorce +magic +Cleveland +bond +review +short-term +ambulance +brave +investigations +systematic +Green +seized +cry +laugh +advanced +obliged +opens +eaten +relevance +1930s +careers +Liz +withdrawn +Barbara +no +payable +handsome +fun +Ms +instances +governors +horrible +measurement +employ +primitive +steadily +switch +fascinating +Brazil +ideological +pile +mounted +metropolitan +alternatives +dollars +north-east +explosion +starting +glory +scarcely +Harriet +surrounding +coup +domain +fence +threatening +dragged +breast +habits +mine +hierarchy +grip +socialism +enquiries +particles +Sweden +choosing +colleague +monitoring +Midlands +restore +printer +imagined +doorway +prisoner +juice +classification +estimated +equilibrium +solely +with regard to +serves +peaceful +observer +explanations +circles +rescue +maps +hated +observe +Hughes +premier +mate +hypothesis +1966 +ride +companion +liver +factories +buyers +reward +controlling +satellite +loyalty +operational +pardon +improving +jump +potatoes +intervals +technological +near +fortunately +hostile +advisory +cook +precious +opponents +peasant +insist +geography +button +consistently +cultures +seeds +monopoly +accessible +tournament +moves +excited +determined +owed +pockets +belonged +Hollywood +dining +switch +traditions +compromise +intensity +chaos +obtaining +Mexico +King +combine +altered +nonsense +clouds +themes +suspicion +ranks +disorder +stocks +Kuwait +1965 +2000 +consultant +collapsed +purchased +impressed +half +Catherine +provincial +sterling +performances +instantly +Bell +constitute +arrest +dose +exercises +issue +competitors +spectrum +dangers +allies +travellers +plc +kid +disc +Donald +nowadays +Surrey +cheeks +endless +isolated +dimension +twin +bedrooms +clean +columns +privilege +post-war +volumes +broadcasting +commerce +historians +train +geographical +oak +actors +step +like +dynamic +freely +checking +equipped +inspired +density +1994 +forthcoming +HIV +boring +handled +poems +recording +unfortunate +banned +Karen +own +suspected +boom +tribunal +kicked +possessed +Jonathan +broadly +publicly +attributed +definite +challenged +extending +cooking +pause +strip +predicted +super +barrier +pregnancy +loud +menu +preserved +Avenue +restaurants +acres +prompted +senses +essay +lip +recruitment +defendants +presents +guarantee +invest +cats +maximum +notable +upwards +arose +cry +fierce +detected +indirect +German +witnesses +patch +sensitivity +Le +mistakes +receiver +crops +chin +wheels +rice +Dec +forgot +illustrate +reveals +Freud +limit +chap +Campbell +races +awkward +Turkey +implied +climb +widow +varied +slid +stopping +rope +steep +neutral +Oxfordshire +finish +debut +seed +challenge +promoted +delegation +hitherto +artistic +muttered +adoption +architect +dear +Kenneth +portfolio +continent +transformed +couples +probability +content +Robinson +struggling +mild +counties +wish +mention +fitness +tackle +dish +statute +invariably +Charlotte +prey +view +consultants +gather +arriving +corners +delegates +Holland +archbishop +Sue +withdraw +replacing +Milton +meaning +mature +differently +chart +technologies +woods +possess +cab +grace +toilet +grabbed +prevention +equality +wishes +bases +operator +regardless +harsh +colonial +ambitious +exploration +lords +investigated +collecting +Switzerland +shadows +Corbett +evil +Johnny +dramatically +Marshall +indicating +orchestra +lock +inhabitants +defeated +disappointment +magnetic +washing +fibre +correspondence +verbal +legitimate +requested +emotion +odds +workforce +vessels +brass +pursued +ph +balls +adviser +faint +handling +appointments +grandfather +motivation +sympathetic +publishers +peoples +socially +investments +rhythm +variable +Chelsea +memorial +well-known +empirical +roses +ceased +fluid +descriptions +incidents +DC +dismissal +appreciated +communicate +rushed +bronze +wisdom +Daniel +supper +adventure +tribute +seeks +promise +head +ye +1960 +crop +beef +suited +exercised +respects +terror +circulation +identifying +achievements +fool +intentions +proportions +lads +directory +Brighton +inn +promoting +flag +separate +Roberts +Ward +Dennis +clay +Cook +Norway +attraction +ends +disability +championships +vague +virus +shift +ranging +competence +examining +inform +spaces +goodness +gang +favourite +preserve +remembering +naval +molecules +hearts +trapped +actively +leaf +Brussels +distress +resolve +custody +packages +drinking +operators +myth +gain +voting +Mick +returns +tourists +encouragement +lacking +seldom +processor +sums +integrity +acknowledge +shortage +depressed +rightly +Louise +remarkably +repair +shoot +electronics +wishing +Kinnock +imprisonment +kings +waved +shared +shocked +uniform +added +reject +implement +pays +hesitated +seventh +magic +mid +populations +worthwhile +filling +crystal +fraction +qualified +Newton +Sally +server +Nato +specimens +kiss +reflecting +shower +missing +roll +sword +varieties +clinic +imply +ie +rivals +Julia +breakdown +Anderson +scales +fan +operates +blank +whoever +scandal +oldest +smart +favourable +filter +interviewed +absent +mining +gentlemen +enemies +champions +Duncan +exclusion +boot +locations +Hamilton +transmission +custom +tanks +tries +Gloucestershire +publisher +beating +evidently +Netherlands +Polish +lively +exceptions +Emma +appeals +Israeli +mobility +reviewed +buses +conclude +mix +shore +commissioner +absorbed +Norwich +dawn +developed +guards +incomes +parking +vendor +wishes +republics +loads +barriers +translation +evenings +Hungary +lectures +stimulus +conflicts +remains +margin +question +bothered +neighbourhood +tourism +meanings +FA +desktop +reportedly +risk +zero +demonstrations +dividend +opponent +wake +stiff +rejection +flavour +relates +borrow +emissions +representative +Midland +thereafter +enthusiastic +observers +cited +quid +fortnight +dreadful +guarantee +reduced +rigid +killer +ending +trick +successor +execution +influences +temperatures +mines +drank +coastal +greeted +nightmare +peculiar +corruption +tray +speaks +cupboard +creates +Jordan +Aberdeen +harder +burned +appearing +Swiss +rabbit +environments +comedy +referendum +bureau +avoiding +just about +matrix +honestly +profound +journalist +extended +Julie +tapes +suspension +delayed +eager +comply +selected +skirt +matched +feminist +Davis +Canadian +closing +acts +grief +relaxed +insight +deck +sensation +placing +sequences +temple +parks +tactics +verdict +adapted +enhance +corresponding +strings +accurately +running +pray +accent +envelope +interference +grandmother +examinations +phone +planned +shelf +deemed +waist +waste +onwards +applicable +futures +sauce +immense +purchase +breathing +allied +Norfolk +contest +expects +supports +km +blacks +decision-making +coins +genuinely +accounted +expressing +assessing +dance +scheduled +adjustment +charge +winds +meets +practically +merger +comparative +permit +celebrate +vessel +belonging +affection +outline +albeit +Lily +leaning +lounge +raises +Cheltenham +workshops +refusing +shallow +dishes +monitor +propose +blamed +dioxide +kind +broader +handling +bastard +uncomfortable +affects +proposition +representations +conservation +ya +makers +Yugoslavia +Fox +citizen +forcing +productive +woke +bored +beneficial +slip +campaigns +handful +aged +collar +curtain +diversity +hint +Thompson +disappear +charming +bonus +secrets +interrupted +specialists +accommodate +frustration +recommendation +meantime +coffin +daily +condemned +minimal +mobile +academy +testing +independently +appealed +museums +cruel +faces +murdered +on board +Turkish +aim +Will +territories +pressing +Churchill +commit +verse +research +orange +interval +threats +passive +suspicious +forgive +liberty +ghost +rear +believing +correlation +measurements +1963 +investigating +shade +layers +bias +overwhelming +certainty +Sunderland +cow +commissioned +trusts +maturity +resulting +fatal +surrounding +crying +planted +symbolic +isle +historian +enabling +removing +slope +excuse +angel +nearby +rats +straw +1962 +surfaces +gods +foundations +honours +Belgium +disputes +insects +inspiration +draw +presenting +registered +pavement +telephone +reserve +keeper +dimensions +predict +neighbouring +validity +breeze +ugly +expanded +lasted +irrelevant +complain +shelter +patient +driving +wealthy +upset +hostility +profitable +rod +fled +compact +lamp +shifted +supplier +crossing +phenomena +IT +measuring +horizon +rival +making +clergy +marble +pensioners +fragments +loyal +Alison +Stanley +conscience +sixties +Hill +saving +tune +moderate +1961 +soup +paths +struggled +popularity +score +singer +distinguished +climbing +kick +Betty +characteristic +interior +episode +oven +basket +noble +forwards +consisted +crowds +positively +pole +burning +pet +insufficient +evil +mysterious +jet +eligible +behalf +passes +nails +collaboration +lorry +nest +varying +enforcement +Spencer +Denmark +make-up +molecular +managerial +raid +ambition +middle-class +brand +migration +embassy +neatly +looks +worship +Olympic +devised +exclude +organ +favoured +linear +Samuel +cared +manor +detect +interpret +Kennedy +substances +crude +fantasy +counselling +abilities +treating +blew +embarrassment +executed +implication +Ron +printed +prospective +importantly +Preston +continually +Barnes +executives +catching +forehead +Ali +diverse +parental +elaborate +furious +definitions +appreciation +fiscal +Kim +commitments +sculpture +runs +striker +beans +brush +soccer +spell +reductions +contrary +soap +dated +stretch +publish +russians +pig +stroke +ladder +Greater +burning +expressions +useless +nerve +pence +Gabriel +rumours +relied +Edwards +semantic +inherent +embarrassed +1948 +specification +despair +yep +name +serum +Maxwell +Dick +apartment +Vienna +deliberate +stranger +philosophical +criterion +trap +pubs +utterly +link +frowned +awake +bureaucracy +nonetheless +sunshine +bloke +partially +remedy +battery +variable +within +forth +barn +ties +settlements +installation +crashed +negotiate +Somerset +nursing +dignity +promising +minus +criticised +sacred +analyse +senate +incentive +unpleasant +varied +selective +qualified +Devon +powder +clauses +expectation +tender +inclined +funded +alleged +hidden +ridge +exhibitions +lengths +Joyce +posed +explicitly +symbols +exploitation +receives +1950 +intermediate +Isabel +blocked +trophy +launch +spotted +manufacture +diesel +masses +protective +paint +budgets +Lisa +grows +fortunate +deserve +lap +concerns +varies +compliance +defensive +damage +objections +qualify +featured +suite +salmon +reach +requests +objection +devoted +thesis +repeatedly +blow +palm +Austria +Rover +parked +Carter +Guinness +temporarily +Land +south-east +chains +worthy +ozone +pursuit +valued +divine +react +deals +head +phoned +carrier +jeans +feedback +dancing +tales +rally +grant +performing +rush +handicap +consisting +counted +qualification +guaranteed +negligence +continuity +lend +offers +educated +stuck +surplus +swallowed +eagle +printing +land +Willie +novels +driving +dependence +1st +eighth +Craig +organise +Cornwall +orange +diameter +1939 +toward +auction +eating +Max +invisible +determining +construct +faculty +offenders +occurring +Pete +charm +Don +suffering +contempt +Wimbledon +reinforced +specify +misery +dropping +breasts +overall +Sara +jewellery +bacteria +sin +comparisons +privatisation +owe +squadron +grave +codes +circular +misleading +centred +sunlight +lowered +invested +mathematical +proteins +sanctions +aggression +caution +loch +reply +direct +subjected +inappropriate +diagram +terribly +St +human +liquid +solar +angles +sorted +persistent +poles +laying +inherited +phrases +doubtful +calcium +shake +ingredients +Sophie +admits +black +BR +monster +flames +allowances +sustain +needle +telecommunications +sphere +revenues +guessed +bowel +doubled +prints +rangers +accountants +screaming +legend +petition +predominantly +manual +lies +premium +photo +surroundings +spots +gravel +19th +architectural +bold +Maastricht +inheritance +Harvey +knock +blues +beyond +Day +emergence +beautifully +deeper +intact +cooperation +convince +incredible +sound +devoted +conduct +united +celebration +abruptly +considers +flights +explored +loves +blue +Derby +restriction +prior +submit +gaining +Santa +morality +tragic +musicians +invite +Ipswich +selling +script +coupled +tap +remark +consist +respectable +pint +optimistic +humanity +layout +openly +breed +policemen +Scots +invented +linking +convincing +Harold +guide +vocabulary +Rob +unacceptable +competent +Carrie +spatial +ignoring +applicant +swiftly +easier +painter +decisive +traders +pretend +bargaining +depended +modes +preventing +rage +respective +elite +permanently +seemingly +bunch +carers +fathers +engagement +liquid +Canterbury +binding +fires +sentenced +rebels +founder +ballet +erosion +Gould +syndrome +relieved +nursing +harmony +Coventry +protested +hut +sits +stops +Lamont +bore +instructed +fertility +toxic +testament +1957 +sickness +stretch +Bath +lemon +practise +mix +faster +integral +select +redundant +handle +throne +conceived +polytechnic +nerves +belongs +privately +burn +gravity +labelled +Alfred +bishops +basin +rings +holders +swing +flood +Christie +evolved +sovereignty +then +applicants +cows +lion +Virginia +trail +smoking +trading +Murray +boxing +amateur +probable +scrutiny +tempted +borders +pan +fix +hydrogen +accountability +consulted +echo +sponsorship +fame +El +lakes +protests +patience +documentation +Geoff +backing +search +Mozart +silently +passing +seasons +recipe +fetch +auditors +territorial +specified +abandon +bombs +Los +mineral +horizontal +lined +Robyn +booked +du +cleaning +bear +old-fashioned +inland +youngest +envisaged +floors +thrust +likewise +strengthen +penny +wake +Bradford +overseas +consult +cognitive +Ralph +dock +reaches +disturbed +communists +slim +synthesis +contexts +revival +Reading +regulatory +hurried +defender +dry +miserable +walks +debates +dancing +isolated +venue +Hampshire +resident +rounds +deals +packet +likelihood +remaining +induced +guys +temper +comparatively +calculations +protecting +holdings +corn +1947 +Yeltsin +fusion +Marxist +conferences +creditors +questionnaire +gothic +scared +willingness +civilian +shelves +reporting +precision +divide +Phillips +overnight +Intel +Linda +deputies +Indians +Trevor +Juliet +Watson +conventions +modified +instant +praise +Des +coin +blown +hiding +galleries +1940 +Constance +outlook +incurred +adverse +subsidiary +tiles +seventeenth +Korean +emphasised +Eddie +bile +1959 +fancy +accounting +leaflet +headmaster +crack +heels +truck +engage +reporter +plays +Steven +calm +initiated +brigade +Dorothy +unconscious +convicted +illustration +trustees +sustained +alike +End +ideally +entity +tons +sang +telegraph +negotiation +opposite +smell +aesthetic +wiped +concentrating +anonymous +trace +usage +orthodox +fulfil +polite +girlfriend +lovers +translated +static +intent +cancelled +inside +unaware +presidency +corps +assigned +appearances +exploit +margins +worldwide +cups +solved +panels +halt +EEC +Suffolk +developers +fantastic +Lancaster +seminar +fashionable +criticisms +Cooper +motorway +zones +foolish +intake +advances +receipt +rule +regiment +trades +manual +backs +duck +causal +convey +Tommy +wee +cleaning +fond +compatible +Southampton +inclusion +Herbert +finding +lengthy +two-thirds +tent +shed +implicit +cameras +dare +abolition +Romania +pigs +lace +dedicated +cuts +perceptions +ft +counts +earning +kiss +confirmation +dual +confronted +twenty-five +mistress +assignment +propaganda +toys +Arsenal +Eleanor +critic +curiosity +republican +pipes +reduces +shooting +cheerful +reporting +plea +distinguished +subjective +pie +priests +returns +tel +labels +width +relaxation +advertisement +white +smoke +pencil +legally +following +lacked +surviving +disadvantage +ruling +forward +sleeping +owl +adequately +reproduction +rewards +architects +rear +Shelley +exotic +ambassador +1914 +camps +displays +passages +gazed +timetable +salad +purple +cautious +visiting +Turner +aggregate +ignorance +anticipated +Parker +redundancy +array +penalties +renaissance +theology +try +warn +process +ethical +major +proving +plain +protestant +grid +tenth +takeover +canvas +Ted +skull +highlighted +jokes +beat +pools +twins +borne +criticized +chemical +omitted +revision +sincerely +prizes +salvation +teenage +responding +indicators +repairs +amnesty +comparing +large-scale +yield +Claire +photography +disastrous +thumb +dying +jointly +kilometres +scholars +ace +lump +delicious +confidential +clash +market +underground +Blanche +armed +destination +witnessed +parameters +costly +restraint +bit +1958 +shaped +rode +tips +prosperity +diamond +fury +instinct +reserved +valuation +contacted +subsidies +Hunt +collector +Darwin +sponsored +compound +strengths +sank +defences +lifestyle +prejudice +announce +apparatus +dot +shoe +blanket +wound +Christine +hunger +cabin +photographer +stay +preservation +calendar +assessments +colony +Katherine +thorough +medal +trips +washing +eliminate +breathe +actress +provinces +helicopter +mist +clue +dominance +relaxed +analysts +searched +grin +Czechoslovakia +hitting +inability +portion +restrict +Gray +conspiracy +Nicholson +mercy +log +autonomous +intends +solidarity +jail +genius +1920s +pilots +incorporate +atomic +blade +frozen +1956 +colourful +discharge +injured +mask +provided that +Trent +ease +draws +retire +supposed +ml +angrily +sigh +stamp +adjust +ferry +concessions +majesty +Gilbert +pylori +uniform +adjusted +ashamed +admired +alpha +referee +1944 +Lebanon +respondents +Collins +rested +reconstruction +flown +individually +jaw +submission +efficiently +bitterly +glorious +pour +illustrates +Angeles +amid +convert +wicked +provoked +Chapman +elbow +videos +coherent +annually +le +rising +disciplines +cliff +boyfriend +novel +controls +sweat +depths +Claudia +cave +balanced +strikes +stretching +pains +Close +Tokyo +Portugal +racism +priced +delightful +evaluate +arbitrary +Chicago +Richards +signature +reversed +heroes +clarity +hit +screamed +adjacent +lid +psychiatric +comprising +honey +temptation +beam +immigration +recordings +worrying +weird +practitioner +unchanged +calculation +tutor +politician +rolling +Athens +expedition +electorate +evolutionary +scattered +abolished +researcher +ports +Chester +dilemma +Carl +loaded +IMF +flung +intimate +fever +parallel +tight +miracle +including +lawn +biology +Lothian +failures +breaks +Angela +shy +appraisal +sporting +wines +cleaned +disciplinary +occurrence +smile +formidable +lexical +graduates +fined +cooking +privacy +needles +Reagan +Black +Ed +sink +march +equations +grim +narrative +HP +charts +polls +Paula +express +OK +limbs +decorated +high +addressing +proceeds +pact +Madame +Merseyside +revenge +vice-president +far from +proceeded +airline +minerals +killing +accused +double +gradual +descent +mount +homeless +courtesy +enhanced +supermarket +Blake +Cheshire +interfere +organisers +managing +monitoring +coming +rat +supporting +Marcus +trace +approve +delays +pm +Reynolds +please +yo +programming +training +renewed +Hull +invention +writings +back +excess +planes +legacy +challenges +gaps +dug +Jason +interpretations +smallest +pulse +analyses +Ashley +rubber +retired +specimen +outdoor +shooting +chosen +embarrassing +wrist +atoms +Hereford +smoking +incidentally +preferred +renewal +Japanese +vanished +hook +loudly +bride +Annie +interactions +bizarre +gospel +realm +mainland +knit +appalling +exchanges +surgeon +crews +orientation +twisted +occupy +flame +hatred +exceed +Maurice +laboratories +reviews +Bosnia +agreed +Butler +utility +conversations +imaginative +pursuing +flour +accepted +wartime +governing +Reid +object +cutting +indirectly +governed +palestinian +vocational +von +modification +slopes +allegedly +parade +free +aluminium +Al +movies +biscuits +motive +register +merchants +hip +print +rabbits +remedies +stress +trainer +welcome +wound +Geneva +configuration +boost +puzzled +encounter +axis +no matter how +Clive +worldwide +Arnold +Allan +lamb +laser +vegetation +reluctance +jazz +databases +strengthened +protocol +enjoyment +organisational +knitting +census +calculate +handicapped +mucosa +theirs +1951 +advertisements +eldest +Carol +1936 +eventual +husbands +fur +followers +wasted +pump +lifting +practised +yacht +toes +stimulate +speeches +1953 +traced +ensured +arrow +journals +weekends +spontaneous +appoint +1949 +binding +superintendent +vivid +corporations +organisms +celebrated +mice +motives +torn +tie +dies +1954 +waiting +classified +organs +lack +worlds +nineteenth-century +faithful +shield +withdrew +reckoned +north-west +rolling +missiles +noisy +hire +organising +quote +sofa +reminder +Venice +ministerial +A +daylight +injection +graph +exchanged +prayers +boost +preparations +borrowing +innovative +strongest +audiences +disclosure +confrontation +constitutes +burnt +liaison +armies +strangely +wounds +Hewlett-Packard +controlled +Newman +cease +incentives +extends +Mitchell +echoed +facilitate +resentment +shout +cage +gloves +1990s +exploring +saving +Leonard +crossing +choir +Gibson +exit +Sydney +assumes +woodland +fog +underneath +promises +Ellen +nationalism +Kenya +commentators +Ferguson +metals +reasoning +acids +hunt +pop +1946 +dirt +Texas +Keynes +conceptual +aiming +stating +technically +heading +economically +constituted +Union +maker +blowing +touching +tours +erected +ambitions +spare +chorus +Bond +bladder +settings +dividends +18th +Gaulle +unusually +phases +adapt +colitis +exploded +Nelson +civic +bells +gall +Macdonald +unwilling +retreat +booklet +enforce +defining +goodbye +meaningful +Gregory +pine +borrowed +bow +disturbing \ No newline at end of file diff --git a/setup/src/Magento/Setup/Model/Complex/Pattern.php b/setup/src/Magento/Setup/Model/Complex/Pattern.php index ee1356ff4d174ea03ad144d2db8b2b6a2ed951d7..a6569b3657de9373b4d459650087a9b177ef5658 100644 --- a/setup/src/Magento/Setup/Model/Complex/Pattern.php +++ b/setup/src/Magento/Setup/Model/Complex/Pattern.php @@ -104,7 +104,7 @@ class Pattern foreach ($this->getHeaders() as $key) { if (isset($row[$key])) { if (is_callable($row[$key])) { - $row[$key] = call_user_func($row[$key], $index); + $row[$key] = call_user_func($row[$key], $index, $generatorKey); } else { $row[$key] = str_replace('%s', $index, $row[$key]); } diff --git a/setup/src/Magento/Setup/Model/DataGenerator.php b/setup/src/Magento/Setup/Model/DataGenerator.php new file mode 100644 index 0000000000000000000000000000000000000000..7ea52bdb26aea5067d98726c52aab00ad8366d6b --- /dev/null +++ b/setup/src/Magento/Setup/Model/DataGenerator.php @@ -0,0 +1,87 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +/** + * A custom adapter that allows generating arbitrary descriptions + */ +namespace Magento\Setup\Model; + +class DataGenerator +{ + /** + * Location for dictionary file. + * + * @var string + */ + private $dictionaryFile; + + /** + * Dictionary data. + * + * @var array + */ + private $dictionaryData; + + /** + * Map of generated values + * + * @var array + */ + private $generatedValues; + + /** + * DataGenerator constructor. + * + * @param string $dictionaryFile + */ + public function __construct($dictionaryFile) + { + $this->dictionaryFile = $dictionaryFile; + $this->readData(); + $this->generatedValues = []; + } + + /** + * Read data from file. + * + * @return void + */ + protected function readData() + { + $f = fopen($this->dictionaryFile, 'r'); + while (!feof($f) && is_array($line = fgetcsv($f))) { + $this->dictionaryData[] = $line[0]; + } + } + + /** + * Generate string of random word data. + * + * @param int $minAmountOfWords + * @param int $maxAmountOfWords + * @param string|null $key + * @return string + */ + public function generate($minAmountOfWords, $maxAmountOfWords, $key = null) + { + $numberOfWords = mt_rand($minAmountOfWords, $maxAmountOfWords); + $result = ''; + + if ($key === null || !array_key_exists($key, $this->generatedValues)) { + for ($i = 0; $i < $numberOfWords; $i++) { + $result .= ' ' . $this->dictionaryData[mt_rand(0, count($this->dictionaryData) - 1)]; + } + $result = trim($result); + + if ($key !== null) { + $this->generatedValues[$key] = $result; + } + } else { + $result = $this->generatedValues[$key]; + } + return $result; + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php new file mode 100644 index 0000000000000000000000000000000000000000..674f444fbde10666b75aa5dadfef3719e3177152 --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php @@ -0,0 +1,288 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Setup\Test\Unit\Fixtures; + +use \Magento\Setup\Fixtures\AttributeSetsFixture; + +/** + * @SuppressWarnings(PHPMD) + */ +class AttributeSetsFixtureTest extends \PHPUnit_Framework_TestCase +{ + + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel + */ + private $fixtureModelMock; + + /** + * @var \Magento\Setup\Fixtures\AttributeSetsFixture + */ + private $model; + + public function setUp() + { + $this->fixtureModelMock = $this->getMockBuilder(\Magento\Setup\Fixtures\FixtureModel::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new AttributeSetsFixture($this->fixtureModelMock); + } + + public function testExecute() + { + $attributeSets = [ + 'attribute_set' => [ + [ + 'name' => 'attribute set name', + 'attributes' => [ + 'attribute' => [ + [ + 'is_required' => 1, + 'is_visible_on_front' => 1, + 'is_visible_in_advanced_search' => 1, + 'is_filterable' => 1, + 'is_filterable_in_search' => 1, + 'default_value' => 'yellow1', + 'attribute_code' => 'mycolor', + 'is_searchable' => '1', + 'frontend_label' => 'mycolor', + 'frontend_input' => 'select', + 'options' => [ + 'option' => [ + [ + 'label' => 'yellow1', + 'value' => '' + ] + ] + ] + ] + ] + ] + ] + ] + ]; + $attributeSet = $attributeSets['attribute_set'][0]; + + // Mock Attribute Sets + $attributeSetMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSetInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $attributeSetMock->expects($this->once()) + ->method('setAttributeSetName') + ->with("attribute set name"); + $attributeSetMock->expects($this->once()) + ->method('setEntityTypeId') + ->with(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE); + $attributeSetMock->expects($this->any()) + ->method('getAttributeSetName') + ->willReturn($attributeSet['name']); + + $attributeSetFactoryMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSetInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $attributeSetFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($attributeSetMock); + + $attributeSetManagementMock = $this->getMockBuilder(\Magento\Catalog\Api\AttributeSetManagementInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $attributeSetManagementMock->expects($this->once()) + ->method('create') + ->with($attributeSetMock, '4') + ->willReturn($attributeSetMock); + + //Mock Attribute Groups + $attributeGroupMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeGroupInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $attributeGroupMock->expects($this->once()) + ->method('setAttributeGroupName') + ->with($attributeSetMock->getAttributeSetName() . ' - Group'); + $attributeGroupMock->expects($this->once()) + ->method('setAttributeSetId') + ->with($attributeSetMock->getAttributeSetId()); + + $attributeGroupFactoryMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeGroupInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $attributeGroupFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($attributeGroupMock); + + $productAttributeGroupRepoMock = $this->getMockBuilder( + \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); + $productAttributeGroupRepoMock->expects($this->once()) + ->method('save') + ->with($attributeGroupMock) + ->willReturn($attributeGroupMock); + + // Mock Attributes + $attributeMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductAttributeInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $attributeFactoryMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $attributeFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($attributeMock); + + //Mock Attribute Options + $optionMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeOptionInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $optionFactoryMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $optionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($optionMock); + + $productAttributeRepoMock = $this->getMockBuilder( + \Magento\Catalog\Api\ProductAttributeRepositoryInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); + $productAttributeRepoMock->expects($this->once()) + ->method('save') + ->with($attributeMock) + ->willReturn($attributeMock); + + $productAttributeManagementMock = $this->getMockBuilder( + \Magento\Catalog\Api\ProductAttributeManagementInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); + $productAttributeManagementMock->expects($this->once()) + ->method('assign') + ->willReturn($attributeMock->getAttributeId()); + + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); + + $objectManagerMock->expects($this->at(0)) + ->method('create') + ->willReturn($attributeSetManagementMock); + $objectManagerMock->expects($this->at(1)) + ->method('create') + ->willReturn($productAttributeGroupRepoMock); + $objectManagerMock->expects($this->at(2)) + ->method('create') + ->willReturn($attributeSetFactoryMock); + $objectManagerMock->expects($this->at(3)) + ->method('create') + ->willReturn($attributeGroupFactoryMock); + $objectManagerMock->expects($this->at(4)) + ->method('create') + ->willReturn($productAttributeRepoMock); + $objectManagerMock->expects($this->at(5)) + ->method('create') + ->willReturn($productAttributeManagementMock); + $objectManagerMock->expects($this->at(6)) + ->method('create') + ->willReturn($attributeFactoryMock); + $objectManagerMock->expects($this->at(7)) + ->method('create') + ->willReturn($optionFactoryMock); + + $this->fixtureModelMock + ->expects($this->once()) + ->method('getValue') + ->willReturn($attributeSets); + + $this->fixtureModelMock + ->expects($this->any()) + ->method('getObjectManager') + ->will($this->returnValue($objectManagerMock)); + + $this->model->execute(); + } + + public function testNoFixtureConfigValue() + { + $attributeSetManagementMock = $this->getMockBuilder(\Magento\Catalog\Api\AttributeSetManagementInterface::class) + ->disableOriginalConstructor() + ->getMock(); + $attributeSetManagementMock->expects($this->never())->method('create'); + + $productAttributeGroupRepoMock = $this->getMockBuilder( + \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); + $productAttributeGroupRepoMock->expects($this->never())->method('save'); + + $productAttributeRepoMock = $this->getMockBuilder( + \Magento\Catalog\Api\ProductAttributeRepositoryInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); + $productAttributeRepoMock->expects($this->never())->method('save'); + + $productAttributeManagementMock = $this->getMockBuilder( + \Magento\Catalog\Api\ProductAttributeManagementInterface::class + ) + ->disableOriginalConstructor() + ->getMock(); + $productAttributeManagementMock->expects($this->never())->method('assign'); + + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManagerMock->expects($this->never()) + ->method('create') + ->with($this->equalTo(\Magento\Catalog\Api\AttributeSetManagementInterface::class)) + ->willReturn($attributeSetManagementMock); + $objectManagerMock->expects($this->never()) + ->method('create') + ->with($this->equalTo(\Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class)) + ->willReturn($productAttributeGroupRepoMock); + $objectManagerMock->expects($this->never()) + ->method('create') + ->with($this->equalTo(\Magento\Catalog\Api\ProductAttributeRepositoryInterface::class)) + ->willReturn($productAttributeRepoMock); + $objectManagerMock->expects($this->never()) + ->method('create') + ->with($this->equalTo(\Magento\Catalog\Api\ProductAttributeManagementInterface::class)) + ->willReturn($productAttributeManagementMock); + + $this->fixtureModelMock + ->expects($this->never()) + ->method('getObjectManager') + ->will($this->returnValue($objectManagerMock)); + $this->fixtureModelMock + ->expects($this->once()) + ->method('getValue') + ->willReturn(null); + + $this->model->execute(); + } + + public function testGetActionTitle() + { + $this->assertSame('Generating attribute sets', $this->model->getActionTitle()); + } + + public function testIntroduceParamLabels() + { + $this->assertSame([ + 'attribute_sets' => 'Attribute Sets' + ], $this->model->introduceParamLabels()); + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php index 7e89f7d807ed8704156fcffd5252185c0a2e0e54..7f2676c53e232ef152b9ad23a990b40f891e7115 100644 --- a/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php @@ -23,16 +23,25 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->fixtureModelMock = $this->getMock(\Magento\Setup\Fixtures\FixtureModel::class, [], [], '', false); + $this->fixtureModelMock = $this->getMockBuilder(\Magento\Setup\Fixtures\FixtureModel::class) + ->disableOriginalConstructor() + ->getMock(); $this->model = new ConfigurableProductsFixture($this->fixtureModelMock); } + /** + * @SuppressWarnings(PHPMD) + */ public function testExecute() { - $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false); + $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class) + ->disableOriginalConstructor() + ->getMock(); - $contextMock = $this->getMock(\Magento\Framework\Model\ResourceModel\Db\Context::class, [], [], '', false); + $contextMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\Context::class) + ->disableOriginalConstructor() + ->getMock(); $abstractDbMock = $this->getMockForAbstractClass( \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class, [$contextMock], @@ -46,7 +55,9 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getAllChildren') ->will($this->returnValue([1])); - $categoryMock = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false); + $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) + ->disableOriginalConstructor() + ->getMock(); $categoryMock->expects($this->once()) ->method('getResource') ->will($this->returnValue($abstractDbMock)); @@ -60,12 +71,16 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('load') ->willReturnSelf(); - $storeMock = $this->getMock(\Magento\Store\Model\Store::class, [], [], '', false); + $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + ->disableOriginalConstructor() + ->getMock(); $storeMock->expects($this->once()) ->method('getRootCategoryId') ->will($this->returnValue([2])); - $websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false); + $websiteMock = $this->getMockBuilder(\Magento\Store\Model\Website::class) + ->disableOriginalConstructor() + ->getMock(); $websiteMock->expects($this->once()) ->method('getCode') ->will($this->returnValue('website_code')); @@ -73,15 +88,18 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getGroups') ->will($this->returnValue([$storeMock])); - $storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManager::class, [], [], '', false); + $storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManager::class) + ->disableOriginalConstructor() + ->getMock(); $storeManagerMock->expects($this->once()) ->method('getWebsites') ->will($this->returnValue([$websiteMock])); $source = $this->getMockBuilder(Generator::class)->disableOriginalConstructor()->getMock(); - $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false); - + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); $objectManagerMock->expects($this->at(0)) ->method('get') ->with(\Magento\Store\Model\StoreManager::class) @@ -103,14 +121,61 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase $importMock->expects($this->once())->method('validateSource')->with($source)->willReturn(1); $importMock->expects($this->once())->method('importSource')->willReturn(1); + $valuesMap = [ + ['configurable_products', 0, 1], + ['simple_products', 0, 1], + ['search_terms', null, ['search_term' =>[['term' => 'iphone 6', 'count' => '1']]]], + ['configurable_products_variation', 3, 1], + [ + 'search_config', + null, + [ + 'max_amount_of_words_description' => '200', + 'max_amount_of_words_short_description' => '20', + 'min_amount_of_words_description' => '20', + 'min_amount_of_words_short_description' => '5' + ] + ], + ['attribute_sets', + null, + [ + 'attribute_set' => [ + [ + 'name' => 'attribute set name', + 'attributes' => [ + 'attribute' => [ + [ + 'is_required' => 1, + 'is_visible_on_front' => 1, + 'is_visible_in_advanced_search' => 1, + 'is_filterable' => 1, + 'is_filterable_in_search' => 1, + 'default_value' => 'yellow1', + 'attribute_code' => 'mycolor', + 'is_searchable' => '1', + 'frontend_label' => 'mycolor', + 'frontend_input' => 'select', + 'options' => [ + 'option' => [ + [ + 'label' => 'yellow1', + 'value' => '' + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ]; + $this->fixtureModelMock ->expects($this->any()) ->method('getValue') - ->willReturnMap([ - ['configurable_products', 0, 1], - ['configurable_products_variation', 3, 1], - ]); - + ->will($this->returnValueMap($valuesMap)); $this->fixtureModelMock ->expects($this->atLeastOnce()) ->method('getObjectManager') @@ -121,11 +186,15 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase public function testNoFixtureConfigValue() { - $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false); + $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class) + ->disableOriginalConstructor() + ->getMock(); $importMock->expects($this->never())->method('validateSource'); $importMock->expects($this->never())->method('importSource'); - $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false); + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); $objectManagerMock->expects($this->never()) ->method('create') ->with($this->equalTo(\Magento\ImportExport\Model\Import::class)) @@ -151,7 +220,7 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase public function testIntroduceParamLabels() { $this->assertSame([ - 'configurable_products' => 'Configurable products', + 'configurable_products' => 'Configurable products' ], $this->model->introduceParamLabels()); } } diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php index ee1369bd15d5a46f084a504fdfedbf61eb53f8bc..32b00312880dee07e0f172f97df4668596088abd 100644 --- a/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php @@ -55,11 +55,19 @@ class FixtureModelTest extends \PHPUnit_Framework_TestCase false ); - $fileParserMock = $this->getMock(\Magento\Framework\Xml\Parser::class, ['load', 'xmlToArray'], [], '', false); - $fileParserMock->expects($this->once())->method('xmlToArray')->willReturn( + $fileParserMock = $this->getMock(\Magento\Framework\Xml\Parser::class, ['getDom', 'xmlToArray'], [], '', false); + $fileParserMock->expects($this->exactly(2))->method('xmlToArray')->willReturn( ['config' => [ 'profile' => ['some_key' => 'some_value']]] ); - $fileParserMock->expects($this->once())->method('load')->with('config.file')->willReturn($fileParserMock); + + $domMock = $this->getMock(\DOMDocument::class, ['load', 'xinclude'], [], '', false); + $domMock->expects($this->once())->method('load')->with('config.file')->willReturn( + $fileParserMock->xmlToArray() + ); + $domMock->expects($this->once())->method('xinclude'); + + $fileParserMock->expects($this->exactly(2))->method('getDom')->willReturn($domMock); + $this->model = new FixtureModel($reindexCommandMock, $fileParserMock); $this->model->loadConfig('config.file'); $this->assertSame('some_value', $this->model->getValue('some_key')); diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php index 913b2a1e3f02048ac4c61b894e287791ce421207..5e24863483992ce4ada367846fc9c3350a5082b7 100644 --- a/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php @@ -22,19 +22,28 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->fixtureModelMock = $this->getMock(\Magento\Setup\Fixtures\FixtureModel::class, [], [], '', false); + $this->fixtureModelMock = $this->getMockBuilder(\Magento\Setup\Fixtures\FixtureModel::class) + ->disableOriginalConstructor() + ->getMock(); $this->model = new SimpleProductsFixture($this->fixtureModelMock); } + /** + * @SuppressWarnings(PHPMD) + */ public function testExecute() { - $storeMock = $this->getMock(\Magento\Store\Model\Store::class, [], [], '', false); + $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) + ->disableOriginalConstructor() + ->getMock(); $storeMock->expects($this->once()) ->method('getRootCategoryId') ->willReturn(1); - $websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false); + $websiteMock = $this->getMockBuilder(\Magento\Store\Model\Website::class) + ->disableOriginalConstructor() + ->getMock(); $websiteMock->expects($this->once()) ->method('getCode') ->willReturn('website_code'); @@ -42,14 +51,24 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getGroups') ->willReturn([$storeMock]); - $storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManager::class, [], [], '', false); + $storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManager::class) + ->disableOriginalConstructor() + ->getMock(); $storeManagerMock->expects($this->once()) ->method('getWebsites') ->willReturn([$websiteMock]); - $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false); + $source = $this->getMockBuilder(\Magento\Setup\Model\Generator::class)->disableOriginalConstructor()->getMock(); + + $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class) + ->disableOriginalConstructor() + ->getMock(); + $importMock->expects($this->once())->method('validateSource')->with($source)->willReturn(1); + $importMock->expects($this->once())->method('importSource')->willReturn(1); - $contextMock = $this->getMock(\Magento\Framework\Model\ResourceModel\Db\Context::class, [], [], '', false); + $contextMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\Context::class) + ->disableOriginalConstructor() + ->getMock(); $abstractDbMock = $this->getMockForAbstractClass( \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class, [$contextMock], @@ -63,7 +82,9 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getAllChildren') ->will($this->returnValue([1])); - $categoryMock = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false); + $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class) + ->disableOriginalConstructor() + ->getMock(); $categoryMock->expects($this->once()) ->method('getResource') ->willReturn($abstractDbMock); @@ -77,35 +98,81 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getName') ->willReturn('category_name'); - $valueMap = [ - [ - \Magento\ImportExport\Model\Import::class, - [ - 'data' => [ - 'entity' => 'catalog_product', - 'behavior' => 'append', - 'validation_strategy' => 'validation-stop-on-errors' - ] - ], - $importMock - ], - [\Magento\Store\Model\StoreManager::class, [], $storeManagerMock] - ]; - - $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false); - $objectManagerMock->expects($this->exactly(2)) + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); + $objectManagerMock->expects($this->at(0)) ->method('create') - ->will($this->returnValueMap($valueMap)); - $objectManagerMock->expects($this->once()) + ->with(\Magento\Store\Model\StoreManager::class) + ->willReturn($storeManagerMock); + $objectManagerMock->expects($this->at(1)) ->method('get') ->willReturn($categoryMock); + $objectManagerMock->expects($this->at(2)) + ->method('create') + ->with(\Magento\Setup\Model\Generator::class) + ->willReturn($source); + $objectManagerMock->expects($this->at(3)) + ->method('create') + ->with(\Magento\ImportExport\Model\Import::class) + ->willReturn($importMock); + $valuesMap = [ + ['simple_products', 0, 1], + ['configurable_products', 0, 1], + ['search_terms', null, ['search_term' =>[['term' => 'iphone 6', 'count' => '1']]]], + [ + 'search_config', + null, + [ + 'max_amount_of_words_description' => '200', + 'max_amount_of_words_short_description' => '20', + 'min_amount_of_words_description' => '20', + 'min_amount_of_words_short_description' => '5' + ] + ], + [ + 'attribute_sets', + null, + [ + 'attribute_set' => [ + [ + 'name' => 'attribute set name', + 'attributes' => [ + 'attribute' => [ + [ + 'is_required' => 1, + 'is_visible_on_front' => 1, + 'is_visible_in_advanced_search' => 1, + 'is_filterable' => 1, + 'is_filterable_in_search' => 1, + 'default_value' => 'yellow1', + 'attribute_code' => 'mycolor', + 'is_searchable' => '1', + 'frontend_label' => 'mycolor', + 'frontend_input' => 'select', + 'options' => [ + 'option' => [ + [ + 'label' => 'yellow1', + 'value' => '' + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ]; $this->fixtureModelMock - ->expects($this->once()) + ->expects($this->any()) ->method('getValue') - ->willReturn(1); + ->will($this->returnValueMap($valuesMap)); $this->fixtureModelMock - ->expects($this->exactly(3)) + ->expects($this->any()) ->method('getObjectManager') ->willReturn($objectManagerMock); @@ -114,11 +181,15 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase public function testNoFixtureConfigValue() { - $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false); + $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class) + ->disableOriginalConstructor() + ->getMock(); $importMock->expects($this->never())->method('validateSource'); $importMock->expects($this->never())->method('importSource'); - $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false); + $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); $objectManagerMock->expects($this->never()) ->method('create') ->with($this->equalTo(\Magento\ImportExport\Model\Import::class)) @@ -129,7 +200,7 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase ->method('getObjectManager') ->will($this->returnValue($objectManagerMock)); $this->fixtureModelMock - ->expects($this->once()) + ->expects($this->any()) ->method('getValue') ->willReturn(false); diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php index 4adac2b0fb0edadf4a22d36f4fcd6f44d5357e35..0123fcd8ca032a79ff0b4ff5616747d8fb517bc7 100644 --- a/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php +++ b/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php @@ -42,8 +42,8 @@ class PatternTest extends \PHPUnit_Framework_TestCase [ 'id' => '%s', 'name' => 'Static', - 'calculated' => function ($index) { - return $index * 10; + 'calculated' => function ($index, $generatedKey) { + return $index * 10 + $generatedKey; }, ], [ @@ -53,7 +53,7 @@ class PatternTest extends \PHPUnit_Framework_TestCase 'name' => 'yyy %s' ], ], - 'ecpectedCount' => 3, + 'expectedCount' => 3, 'expectedRowsResult' => [ ['id' => '1', 'name' => 'Static', 'calculated' => 10], ['id' => '', 'name' => 'xxx 1', 'calculated' => ''], @@ -68,7 +68,7 @@ class PatternTest extends \PHPUnit_Framework_TestCase 'calculated' => 'calc %s', ], ], - 'ecpectedCount' => 1, + 'expectedCount' => 1, 'expectedRowsResult' => [ ['id' => '1', 'name' => 'Dynamic 1', 'calculated' => 'calc 1'], ], diff --git a/setup/src/Magento/Setup/Test/Unit/Model/DataGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/DataGeneratorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..65f92488c1a62fc62a4f36be3d8140ffe118eecd --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Model/DataGeneratorTest.php @@ -0,0 +1,50 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Setup\Test\Unit\Model; + +use Magento\Setup\Model\DataGenerator; + +class DataGeneratorTest extends \PHPUnit_Framework_TestCase +{ + + const PATH_TO_CSV_FILE = '/_files/dictionary.csv'; + + /** + * @test + * + * @return void + */ + public function testGenerate() + { + $data = file(__DIR__ . self::PATH_TO_CSV_FILE); + $wordCount = count($data); + $model = new DataGenerator(__DIR__ . self::PATH_TO_CSV_FILE); + $result = $model->generate($wordCount, $wordCount); + + $found = false; + foreach ($data as $word) { + $found = (strpos($result, $word[0]) !== false) || $found; + } + $this->assertTrue($found); + $this->assertEquals($wordCount, count(explode(" ", $result))); + } + + public function testGenerateWithKey() + { + $key = 'generate-test'; + + $data = file(__DIR__ . self::PATH_TO_CSV_FILE); + $wordCount = mt_rand(1, count($data)); + $model = new DataGenerator(__DIR__ . self::PATH_TO_CSV_FILE); + $result = $model->generate($wordCount, $wordCount, $key); + + $foundResult = $model->generate($wordCount, $wordCount, $key); + + $this->assertEquals($wordCount, count(explode(" ", $result))); + $this->assertEquals($result, $foundResult); + } +} diff --git a/setup/src/Magento/Setup/Test/Unit/Model/_files/dictionary.csv b/setup/src/Magento/Setup/Test/Unit/Model/_files/dictionary.csv new file mode 100644 index 0000000000000000000000000000000000000000..da9dfd0f0ca08670a550cbfcd2af61526f9eede1 --- /dev/null +++ b/setup/src/Magento/Setup/Test/Unit/Model/_files/dictionary.csv @@ -0,0 +1,5 @@ +one +two +three +four +five \ No newline at end of file