├── .gitignore ├── .php_cs-fixers.php ├── .php_cs.php ├── .scrutinizer.yml ├── .travis.yml ├── AttributeKeyProvider.php ├── CONTRIBUTING.md ├── Command ├── AbstractGenerateCommand.php ├── GenerateFixtureCommand.php └── GenerateProductCommand.php ├── DependencyInjection ├── Compiler │ └── RegisterGeneratorsPass.php ├── Configuration │ ├── FixtureGeneratorConfiguration.php │ └── ProductGeneratorConfiguration.php └── PimDataGeneratorExtension.php ├── Generator ├── AssetCategoryAccessGenerator.php ├── AssetCategoryGenerator.php ├── AssociationTypeGenerator.php ├── AttributeGenerator.php ├── AttributeGroupAccessGenerator.php ├── AttributeGroupGenerator.php ├── AttributeOptionGenerator.php ├── CategoryGenerator.php ├── ChainedGenerator.php ├── ChannelGenerator.php ├── FamilyGenerator.php ├── GeneratorInterface.php ├── GeneratorRegistry.php ├── GroupTypeGenerator.php ├── JobGenerator.php ├── JobProfileAccessGenerator.php ├── LocaleAccessGenerator.php ├── LocaleGenerator.php ├── Product │ ├── AbstractProductGenerator.php │ ├── ProductRawBuilder.php │ └── ProductValueRawBuilder.php ├── ProductCategoryAccessGenerator.php ├── ProductDraftGenerator.php ├── ProductGenerator.php ├── UserGenerator.php ├── UserGroupGenerator.php ├── UserRoleGenerator.php └── VariantGroupGenerator.php ├── PULL_REQUEST_TEMPLATE.md ├── PimDataGeneratorBundle.php ├── README.md ├── Resources ├── config │ ├── generators.yml │ ├── internal_jobs.yml │ ├── locales.csv │ ├── services.yml │ └── writers.yml ├── examples │ ├── fixtures.yml │ ├── fixtures_enterprise.yml │ ├── fixtures_extra_large.yml │ ├── products.yml │ ├── products_enterprise.yml │ └── products_extra_large.yml └── meta │ └── LICENCE ├── VariantGroupDataProvider.php ├── Writer └── CsvWriter.php ├── composer.json └── spec └── Pim └── Bundle └── DataGeneratorBundle ├── AttributeKeyProviderSpec.php ├── DependencyInjection ├── Compiler │ └── RegisterGeneratorsPassSpec.php ├── Configuration │ ├── FixtureGeneratorConfigurationSpec.php │ └── ProductGeneratorConfigurationSpec.php └── PimDataGeneratorExtensionSpec.php ├── Generator ├── AssetCategoryAccessGeneratorSpec.php ├── AssetCategoryGeneratorSpec.php ├── AssociationTypeGeneratorSpec.php ├── AttributeGeneratorSpec.php ├── AttributeGroupAccessGeneratorSpec.php ├── AttributeOptionGeneratorSpec.php ├── CategoryGeneratorSpec.php ├── ChainedGeneratorSpec.php ├── ChannelGeneratorSpec.php ├── FamilyGeneratorSpec.php ├── GroupTypeGeneratorSpec.php ├── JobGeneratorSpec.php ├── LocaleAccessGeneratorSpec.php ├── LocaleGeneratorSpec.php ├── ProductCategoryAccessGeneratorSpec.php ├── ProductDraftGeneratorSpec.php ├── ProductGeneratorSpec.php ├── UserGeneratorSpec.php ├── UserGroupGeneratorSpec.php ├── UserRoleGeneratorSpec.php └── VariantGroupGeneratorSpec.php ├── PimDataGeneratorBundleSpec.php └── Writer └── CsvWriterSpec.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | /bin 3 | .phpspec/*.tpl 4 | composer.lock 5 | -------------------------------------------------------------------------------- /.php_cs-fixers.php: -------------------------------------------------------------------------------- 1 | name('*.php') 7 | ->notName('*Spec.php') 8 | ->files() 9 | ->in(__DIR__); 10 | 11 | echo __DIR__.'/spec'; 12 | 13 | return \Symfony\CS\Config\Config::create() 14 | ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) 15 | ->fixers($fixers) 16 | ->finder($finder); 17 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | filter: 2 | paths: 3 | - ./* 4 | 5 | tools: 6 | sensiolabs_security_checker: true 7 | php_mess_detector: 8 | filter: 9 | excluded_paths: 10 | - spec/* 11 | - vendor/* 12 | php_analyzer: 13 | filter: 14 | excluded_paths: 15 | - spec/* 16 | - vendor/* 17 | php_code_sniffer: 18 | config: 19 | standard: PSR2 20 | filter: 21 | excluded_paths: 22 | - spec/* 23 | - vendor/* 24 | php_cpd: 25 | filter: 26 | excluded_paths: 27 | - spec/* 28 | - vendor/* 29 | php_loc: 30 | excluded_dirs: 31 | - spec/* 32 | - vendor/* 33 | php_pdepend: 34 | excluded_dirs: 35 | - spec/* 36 | - vendor/* 37 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - "5.6" 4 | - "7.0" 5 | 6 | # Allow to use container infrastructure 7 | sudo: false 8 | 9 | cache: 10 | directories: 11 | - $HOME/.composer/cache/files 12 | 13 | before_install: 14 | - phpenv config-rm xdebug.ini; 15 | - echo "memory_limit=3G" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; 16 | - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config 17 | - composer self-update --no-interaction 18 | 19 | install: 20 | - composer update --prefer-dist --no-interaction 21 | 22 | script: 23 | - bin/phpspec run 24 | - bin/php-cs-fixer fix --dry-run -v --diff --config-file=.php_cs.php 25 | 26 | 27 | notifications: 28 | slack: akeneo:fDZaQeRRj1gVtXCW3f2kQAxo 29 | -------------------------------------------------------------------------------- /AttributeKeyProvider.php: -------------------------------------------------------------------------------- 1 | 19 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 21 | */ 22 | class AttributeKeyProvider 23 | { 24 | const METRIC_UNIT = 'unit'; 25 | 26 | /** @var AttributeRepositoryInterface */ 27 | private $attributeRepository; 28 | 29 | /** @var ChannelRepositoryInterface */ 30 | private $channelRepository; 31 | 32 | /** @var LocaleRepositoryInterface */ 33 | private $localeRepository; 34 | 35 | /** @var CurrencyRepositoryInterface */ 36 | private $currencyRepository; 37 | 38 | /** @var ChannelInterface[] */ 39 | private $channels; 40 | 41 | /** @var CurrencyInterface[] */ 42 | private $currencies; 43 | 44 | /** @var LocaleInterface[] */ 45 | private $locales; 46 | 47 | /** 48 | * ProductValueRawBuilder constructor. 49 | * 50 | * @param AttributeRepositoryInterface $attributeRepository 51 | * @param ChannelRepositoryInterface $channelRepository 52 | * @param LocaleRepositoryInterface $localeRepository 53 | * @param CurrencyRepositoryInterface $currencyRepository 54 | */ 55 | public function __construct( 56 | AttributeRepositoryInterface $attributeRepository, 57 | ChannelRepositoryInterface $channelRepository, 58 | LocaleRepositoryInterface $localeRepository, 59 | CurrencyRepositoryInterface $currencyRepository 60 | ) { 61 | $this->attributeRepository = $attributeRepository; 62 | $this->channelRepository = $channelRepository; 63 | $this->localeRepository = $localeRepository; 64 | $this->currencyRepository = $currencyRepository; 65 | } 66 | 67 | /** 68 | * Generate the list of attribute keys for a given attribute. The keys are sorted so that we always get 69 | * them in the same consistent order. 70 | * 71 | * Example: 72 | * Attribute: description localizable in english and french for ecommerce 73 | * Attributes keys are: 74 | * [ description-en_US-ecommerce, description-fr_FR-ecommerce ] 75 | * 76 | * @param AttributeInterface $attribute 77 | * 78 | * @return array 79 | */ 80 | public function getAttributeKeys(AttributeInterface $attribute) 81 | { 82 | $keys = []; 83 | 84 | $locales = $attribute->isLocalizable() ? $this->getLocales() : [null]; 85 | $channels = $attribute->isScopable() ? $this->getChannels() : [null]; 86 | foreach ($channels as $channel) { 87 | foreach ($locales as $locale) { 88 | $localeInChannel = null === $channel || 89 | null === $locale || 90 | in_array($locale, $channel->getLocales()->toArray()); 91 | $localeInSpecific = !$attribute->isLocaleSpecific() || 92 | null === $locale || 93 | in_array($locale->getCode(), $attribute->getLocaleSpecificCodes()); 94 | 95 | if ($localeInChannel && $localeInSpecific) { 96 | $keys[] = $this->createKey($attribute, $channel, $locale); 97 | } 98 | } 99 | } 100 | 101 | switch ($attribute->getBackendType()) { 102 | case 'prices': 103 | foreach ($keys as $index => $key) { 104 | foreach ($this->getCurrencies() as $currency) { 105 | $keys[] = $key . '-' . $currency->getCode(); 106 | } 107 | unset($keys[$index]); 108 | } 109 | break; 110 | case 'metric': 111 | foreach ($keys as $index => $key) { 112 | $keys[] = $key . '-' . self::METRIC_UNIT; 113 | } 114 | break; 115 | } 116 | 117 | sort($keys); 118 | 119 | return $keys; 120 | } 121 | 122 | /** 123 | * Generate the list of attribute keys for all attributes. The keys are sorted so that we always get 124 | * them in the same consistent order. 125 | * 126 | * @return array 127 | */ 128 | public function getAllAttributesKeys() 129 | { 130 | $keys = []; 131 | foreach ($this->attributeRepository->findAll() as $attribute) { 132 | $keys = array_merge($keys, $this->getAttributeKeys($attribute)); 133 | } 134 | 135 | sort($keys); 136 | 137 | return $keys; 138 | } 139 | 140 | /** 141 | * Get all channels 142 | * 143 | * @return ChannelInterface[] 144 | */ 145 | private function getChannels() 146 | { 147 | if (null === $this->channels) { 148 | $this->channels = []; 149 | $channels = $this->channelRepository->findAll(); 150 | foreach ($channels as $channel) { 151 | $this->channels[$channel->getCode()] = $channel; 152 | } 153 | } 154 | 155 | return $this->channels; 156 | } 157 | 158 | /** 159 | * Get active currencies 160 | * 161 | * @return CurrencyInterface[] 162 | */ 163 | private function getCurrencies() 164 | { 165 | if (null === $this->currencies) { 166 | $this->currencies = []; 167 | $currencies = $this->currencyRepository->findBy(['activated' => 1]); 168 | foreach ($currencies as $currency) { 169 | $this->currencies[$currency->getCode()] = $currency; 170 | } 171 | } 172 | 173 | return $this->currencies; 174 | } 175 | 176 | /** 177 | * Get active locales 178 | * 179 | * @return LocaleInterface[] 180 | */ 181 | private function getLocales() 182 | { 183 | if (null === $this->locales) { 184 | $this->locales = []; 185 | $locales = $this->localeRepository->findBy(['activated' => 1]); 186 | foreach ($locales as $locale) { 187 | $this->locales[$locale->getCode()] = $locale; 188 | } 189 | } 190 | 191 | return $this->locales; 192 | } 193 | 194 | /** 195 | * Return the key for the given attribute, locale and channem. 196 | * 197 | * @param AttributeInterface $attribute 198 | * @param ChannelInterface|null $channel 199 | * @param LocaleInterface|null $locale 200 | * 201 | * @return string 202 | */ 203 | private function createKey( 204 | AttributeInterface $attribute, 205 | ChannelInterface $channel = null, 206 | LocaleInterface $locale = null 207 | ) { 208 | $channelCode = null !== $channel ? '-' . $channel->getCode() : ''; 209 | $localeCode = null !== $locale ? '-' . $locale->getCode() : ''; 210 | 211 | return $attribute->getCode() . $localeCode . $channelCode; 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Thank you to read and sign the following contributor agreement http://www.akeneo.com/contributor-license-agreement/ 2 | 3 | Every PR should start with: 4 | 5 | ``` 6 | | Q | A 7 | | -------------------- | --- 8 | | Bug fix? | 9 | | New feature? | 10 | | BC breaks? | 11 | | Tests pass? | 12 | | Checkstyle issues?* | 13 | | PMD issues?** | 14 | | Changelog updated? | 15 | | Fixed tickets | 16 | | DB schema updated? | 17 | | Migration script? | 18 | | Doc PR | 19 | ``` 20 | 21 | *Use http://cs.sensiolabs.org/ 22 | -------------------------------------------------------------------------------- /Command/AbstractGenerateCommand.php: -------------------------------------------------------------------------------- 1 | 18 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 20 | */ 21 | abstract class AbstractGenerateCommand extends ContainerAwareCommand 22 | { 23 | /** 24 | * Return a processed configuration from the configuration filename provided 25 | * 26 | * @param string $filename 27 | * 28 | * @return array 29 | */ 30 | protected function getConfiguration($filename) 31 | { 32 | $rawConfig = Yaml::parse(file_get_contents($filename)); 33 | $processor = new Processor(); 34 | $processedConfig = $processor->processConfiguration( 35 | $this->getGeneratorConfiguration(), 36 | $rawConfig 37 | ); 38 | 39 | return $processedConfig; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | protected function execute(InputInterface $input, OutputInterface $output) 46 | { 47 | $configFile = $input->getArgument('configuration-file'); 48 | 49 | $config = $this->getConfiguration($configFile); 50 | 51 | $generator = $this->getContainer()->get('pim_data_generator.chained_generator'); 52 | 53 | $totalCount = $this->getTotalCount($config); 54 | 55 | $outputDir = $config['output_dir']; 56 | $this->generateOutputDir($outputDir); 57 | 58 | $output->writeln( 59 | sprintf( 60 | 'Generating %d entities in the %s directory', 61 | $totalCount, 62 | $outputDir 63 | ) 64 | ); 65 | 66 | $progress = new ProgressBar($output, $totalCount); 67 | $progress->setFormat(' %current%/%max% [%bar%] %elapsed:6s%/%estimated:-6s% %memory:6s% - %message%'); 68 | $progress->start(); 69 | $generator->generate($config, $progress); 70 | $progress->finish(); 71 | $output->writeln(''); 72 | $output->writeln('Entities generated!'); 73 | } 74 | 75 | /** 76 | * Get total count from the configuration 77 | * 78 | * @param array $config 79 | * 80 | * @return int 81 | */ 82 | protected function getTotalCount(array $config) 83 | { 84 | $totalCount = 0; 85 | 86 | foreach ($config['entities'] as $entity) { 87 | if (isset($entity['count'])) { 88 | $totalCount += $entity['count']; 89 | } else { 90 | $totalCount += 1; 91 | } 92 | } 93 | 94 | return $totalCount; 95 | } 96 | 97 | /** 98 | * Checks if the output directory exists, creates it if not. 99 | * 100 | * @param string $outputDir 101 | */ 102 | protected function generateOutputDir($outputDir) 103 | { 104 | $fs = new Filesystem(); 105 | if (!$fs->exists($outputDir)) { 106 | mkdir($outputDir, 0777, true); 107 | } 108 | } 109 | 110 | /** 111 | * @return ConfigurationInterface 112 | */ 113 | abstract protected function getGeneratorConfiguration(); 114 | } 115 | -------------------------------------------------------------------------------- /Command/GenerateFixtureCommand.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2014 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class GenerateFixtureCommand extends AbstractGenerateCommand 19 | { 20 | /** 21 | * {@inheritdoc} 22 | */ 23 | protected function configure() 24 | { 25 | $this 26 | ->setName('pim:generate:fixtures') 27 | ->setDescription('Generate test fixtures for PIM entities') 28 | ->addArgument( 29 | 'configuration-file', 30 | InputArgument::REQUIRED, 31 | 'YAML configuration file' 32 | ); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | protected function getGeneratorConfiguration() 39 | { 40 | return new FixtureGeneratorConfiguration(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Command/GenerateProductCommand.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class GenerateProductCommand extends AbstractGenerateCommand 18 | { 19 | /** 20 | * {@inheritdoc} 21 | */ 22 | protected function configure() 23 | { 24 | $this 25 | ->setName('pim:generate:products-file') 26 | ->setDescription('Generate test products and product drafts for PIM entities') 27 | ->addArgument( 28 | 'configuration-file', 29 | InputArgument::REQUIRED, 30 | 'YAML configuration file' 31 | ); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | protected function getGeneratorConfiguration() 38 | { 39 | return new ProductGeneratorConfiguration(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/RegisterGeneratorsPass.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | class RegisterGeneratorsPass implements CompilerPassInterface 17 | { 18 | const GENERATOR_REGISTRY = 'pim_data_generator.generator.registry'; 19 | 20 | const GENERATOR_TAG = 'pim_data_generator.generator'; 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function process(ContainerBuilder $container) 26 | { 27 | $definition = $container->getDefinition(self::GENERATOR_REGISTRY); 28 | $ids = array_keys($container->findTaggedServiceIds(self::GENERATOR_TAG)); 29 | 30 | foreach ($ids as $id) { 31 | $definition->addMethodCall('register', [new Reference($id)]); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /DependencyInjection/Configuration/ProductGeneratorConfiguration.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class ProductGeneratorConfiguration implements ConfigurationInterface 18 | { 19 | /** 20 | * {@inheritdoc} 21 | */ 22 | public function getConfigTreeBuilder() 23 | { 24 | $treeBuilder = new TreeBuilder(); 25 | $rootNode = $treeBuilder->root('data_generator'); 26 | 27 | $productsNode = $this->getDraftAndProductBaseNode('products'); 28 | $productsNode 29 | ->isRequired() 30 | ->children() 31 | ->integerNode('categories_count')->min(0)->defaultValue(0)->info('Number of categories per product')->end() 32 | ->integerNode('products_per_variant_group')->min(0)->defaultValue(0)->info('Number of products in each variant group')->end() 33 | ->integerNode('percentage_complete')->min(0)->max(100)->defaultValue(20)->info('Percentage of complete products')->end() 34 | ->booleanNode('all_attribute_keys')->defaultFalse()->info('If true exports the products with all attribute keys possible')->end() 35 | ->end(); 36 | 37 | $draftsNode = $this->getDraftAndProductBaseNode('product_drafts'); 38 | 39 | $rootNode 40 | ->children() 41 | ->scalarNode('output_dir')->isRequired()->cannotBeEmpty()->info('Directory where files will be generated')->end() 42 | ->integerNode('seed')->defaultValue(null)->info('Seed used to generate random values')->end() 43 | ->arrayNode('entities') 44 | ->isRequired() 45 | ->children() 46 | ->append($productsNode) 47 | ->append($draftsNode) 48 | ->end() 49 | ->end() 50 | ->end() 51 | ->end(); 52 | 53 | return $treeBuilder; 54 | } 55 | 56 | private function getDraftAndProductBaseNode($name) 57 | { 58 | $node = new ArrayNodeDefinition($name); 59 | $node 60 | ->children() 61 | ->scalarNode('filename')->isRequired()->info('Output filename of the CSV that will be generated')->end() 62 | ->integerNode('count')->min(1)->isRequired()->info('Number of items that will be generated')->end() 63 | ->integerNode('filled_attributes_count')->min(1)->isRequired()->info('Mean number of attributes that will be filled in the item')->end() 64 | ->integerNode('filled_attributes_standard_deviation')->min(1)->defaultValue(10)->info('Deviation of the mean number of attributes that will be filled in the item')->end() 65 | ->scalarNode('delimiter')->defaultValue(ProductGenerator::DEFAULT_DELIMITER)->info('Delimiter used in the CSV that will be generated')->end() 66 | ->arrayNode('mandatory_attributes') 67 | ->prototype('scalar')->end() 68 | ->defaultValue([]) 69 | ->info('Properties that will always be filled in with a random value') 70 | ->end() 71 | ->arrayNode('force_values') 72 | ->prototype('scalar')->end() 73 | ->defaultValue([]) 74 | ->info('Properties that, if they are filled in, will be filled in the given value') 75 | ->end() 76 | ->integerNode('start_index')->min(0)->defaultValue(0)->info('Start index of the identifiers')->end() 77 | ->end() 78 | ; 79 | 80 | return $node; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /DependencyInjection/PimDataGeneratorExtension.php: -------------------------------------------------------------------------------- 1 | load('generators.yml'); 30 | $loader->load('services.yml'); 31 | $loader->load('writers.yml'); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Generator/AssetCategoryAccessGenerator.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | class AssetCategoryAccessGenerator implements GeneratorInterface 17 | { 18 | const TYPE = 'asset_category_accesses'; 19 | 20 | const ASSET_CATEGORY_ACCESSES_FILENAME = 'asset_category_accesses.csv'; 21 | 22 | /** @var CsvWriter */ 23 | protected $writer; 24 | 25 | public function __construct(CsvWriter $writer) 26 | { 27 | $this->writer = $writer; 28 | } 29 | 30 | /** 31 | * {@inheritdoc} 32 | */ 33 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 34 | { 35 | $groups = $options['user_groups']; 36 | $assetCategoryCodes = $options['asset_category_codes']; 37 | 38 | $data = []; 39 | $groupNames = []; 40 | foreach ($groups as $group) { 41 | if (User::GROUP_DEFAULT !== $group->getName()) { 42 | $groupNames[] = $group->getName(); 43 | } 44 | } 45 | 46 | foreach ($assetCategoryCodes as $assetCategoryCode) { 47 | $assetCategoryAccess = ['category' => $assetCategoryCode]; 48 | foreach (['view_items', 'edit_items'] as $access) { 49 | $assetCategoryAccess[$access] = implode(',', $groupNames); 50 | } 51 | $data[] = $assetCategoryAccess; 52 | } 53 | $progress->advance(); 54 | 55 | $this->writer 56 | ->setFilename(sprintf( 57 | '%s%s%s', 58 | $globalConfig['output_dir'], 59 | DIRECTORY_SEPARATOR, 60 | self::ASSET_CATEGORY_ACCESSES_FILENAME 61 | )) 62 | ->write($data); 63 | 64 | return []; 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | public function supports($type) 71 | { 72 | return self::TYPE === $type; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Generator/AssetCategoryGenerator.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | class AssetCategoryGenerator implements GeneratorInterface 20 | { 21 | const TYPE = 'asset_categories'; 22 | 23 | const ASSET_CATEGORIES_FILENAME = 'asset_categories.csv'; 24 | 25 | const ASSET_MAIN_CATALOG = 'asset_main_catalog'; 26 | 27 | /** @var CsvWriter */ 28 | protected $writer; 29 | 30 | public function __construct(CsvWriter $writer) 31 | { 32 | $this->writer = $writer; 33 | } 34 | 35 | /** @var Locale[] */ 36 | protected $locales; 37 | 38 | /** 39 | * Returns the codes of the generated asset categories. 40 | * 41 | * {@inheritdoc} 42 | */ 43 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 44 | { 45 | $this->locales = $options['locales']; 46 | 47 | $faker = Factory::create(); 48 | if (isset($globalConfig['seed'])) { 49 | $faker->seed($globalConfig['seed']); 50 | } 51 | 52 | $assetCategories = [['code' => self::ASSET_MAIN_CATALOG, 'parent' => '']]; 53 | 54 | foreach ($this->locales as $locale) { 55 | $key = sprintf('label-%s', $locale->getCode()); 56 | $assetCategories[0][$key] = implode(' ', $faker->words(3)); 57 | } 58 | 59 | $this->writer 60 | ->setFilename(sprintf( 61 | '%s%s%s', 62 | $globalConfig['output_dir'], 63 | DIRECTORY_SEPARATOR, 64 | self::ASSET_CATEGORIES_FILENAME 65 | )) 66 | ->write($assetCategories); 67 | 68 | $progress->advance(); 69 | 70 | return ['asset_category_codes' => [self::ASSET_MAIN_CATALOG]]; 71 | } 72 | 73 | /** 74 | * {@inheritdoc} 75 | */ 76 | public function supports($type) 77 | { 78 | return self::TYPE === $type; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Generator/AssociationTypeGenerator.php: -------------------------------------------------------------------------------- 1 | 19 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 21 | */ 22 | class AssociationTypeGenerator implements GeneratorInterface 23 | { 24 | const TYPE = 'association_types'; 25 | 26 | const ASSOCIATION_TYPES_FILENAME = 'association_types.csv'; 27 | 28 | const ASSOCIATIONS = 'associations'; 29 | 30 | /** @var CsvWriter */ 31 | protected $writer; 32 | 33 | /** @var Locale[] */ 34 | protected $locales = []; 35 | 36 | /** @var Generator */ 37 | protected $faker; 38 | 39 | /** 40 | * @param CsvWriter $writer 41 | */ 42 | public function __construct(CsvWriter $writer) 43 | { 44 | $this->writer = $writer; 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 51 | { 52 | $this->locales = $options['locales']; 53 | 54 | $data = []; 55 | $this->faker = Factory::create(); 56 | if (isset($globalConfig['seed'])) { 57 | $this->faker->seed($globalConfig['seed']); 58 | } 59 | 60 | for ($i = 0; $i < $entitiesConfig['count']; $i++) { 61 | $associationType = $this->generateAssociationType(); 62 | $data[] = $this->normalizeAssociationType($associationType); 63 | 64 | $progress->advance(); 65 | } 66 | 67 | $this->writer 68 | ->setFilename(sprintf( 69 | '%s%s%s', 70 | $globalConfig['output_dir'], 71 | DIRECTORY_SEPARATOR, 72 | self::ASSOCIATION_TYPES_FILENAME 73 | )) 74 | ->write($data); 75 | 76 | $progress->advance(); 77 | 78 | return []; 79 | } 80 | 81 | /** 82 | * Generate fake association type 83 | * 84 | * @return AssociationType 85 | */ 86 | protected function generateAssociationType() 87 | { 88 | $associationType = new AssociationType(); 89 | $associationType->setCode(strtoupper($this->faker->word())); 90 | 91 | foreach ($this->locales as $locale) { 92 | $translation = new AssociationTypeTranslation(); 93 | $translation->setLocale($locale->getCode()); 94 | $translation->setLabel($this->faker->word()); 95 | $associationType->addTranslation($translation); 96 | } 97 | 98 | return $associationType; 99 | } 100 | 101 | /** 102 | * @param AssociationTypeInterface $associationType 103 | * 104 | * @return array 105 | */ 106 | protected function normalizeAssociationType(AssociationTypeInterface $associationType) 107 | { 108 | $result = ['code' => $associationType->getCode()]; 109 | 110 | foreach ($associationType->getTranslations() as $translation) { 111 | $result[sprintf('label-%s', $translation->getLocale())] = $translation->getLabel(); 112 | } 113 | 114 | return $result; 115 | } 116 | 117 | /** 118 | * {@inheritdoc} 119 | */ 120 | public function supports($type) 121 | { 122 | return self::TYPE === $type; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Generator/AttributeGroupAccessGenerator.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class AttributeGroupAccessGenerator implements GeneratorInterface 19 | { 20 | const TYPE = 'attribute_group_accesses'; 21 | 22 | const ASSET_CATEGORY_ACCESSES_FILENAME = 'attribute_group_accesses.csv'; 23 | 24 | /** @var CsvWriter */ 25 | protected $writer; 26 | 27 | /** 28 | * @param CsvWriter $writer 29 | */ 30 | public function __construct(CsvWriter $writer) 31 | { 32 | $this->writer = $writer; 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 39 | { 40 | $groups = $options['user_groups']; 41 | $attributeGroups = $options['attribute_groups']; 42 | 43 | $data = []; 44 | $groupNames = []; 45 | foreach ($groups as $group) { 46 | if (User::GROUP_DEFAULT !== $group->getName()) { 47 | $groupNames[] = $group->getName(); 48 | } 49 | } 50 | 51 | foreach ($attributeGroups as $attributeGroup) { 52 | $assetCategoryAccess = ['attribute_group' => $attributeGroup->getCode()]; 53 | foreach (['view_attributes', 'edit_attributes'] as $access) { 54 | $assetCategoryAccess[$access] = implode(',', $groupNames); 55 | } 56 | $data[] = $assetCategoryAccess; 57 | } 58 | $progress->advance(); 59 | 60 | $this->writer 61 | ->setFilename(sprintf( 62 | '%s%s%s', 63 | $globalConfig['output_dir'], 64 | DIRECTORY_SEPARATOR, 65 | self::ASSET_CATEGORY_ACCESSES_FILENAME 66 | )) 67 | ->write($data); 68 | 69 | return []; 70 | } 71 | 72 | /** 73 | * {@inheritdoc} 74 | */ 75 | public function supports($type) 76 | { 77 | return self::TYPE === $type; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Generator/AttributeGroupGenerator.php: -------------------------------------------------------------------------------- 1 | writer = $writer; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 52 | { 53 | $this->locales = $options['locales']; 54 | $count = (int) $entitiesConfig['count']; 55 | 56 | $this->faker = Factory::create(); 57 | if (isset($globalConfig['seed'])) { 58 | $this->faker->seed($globalConfig['seed']); 59 | } 60 | 61 | $this->attributeGroups = []; 62 | 63 | for ($i = 0; $i < $count; $i++) { 64 | $attributeGroup = []; 65 | $code = self::ATTR_GROUP_CODE_PREFIX.$i; 66 | 67 | $attributeGroup['code'] = $code; 68 | $attributeGroup['sortOrder'] = $this->faker->numberBetween(1, 10); 69 | $attributeGroup['labels'] = $this->getLocalizedRandomLabels(); 70 | 71 | $this->attributeGroups[$code] = $attributeGroup; 72 | $progress->advance(); 73 | } 74 | 75 | $normalizedGroups = $this->normalizeAttributeGroups($this->attributeGroups); 76 | 77 | $this->writer 78 | ->setFilename(sprintf( 79 | '%s%s%s', 80 | $globalConfig['output_dir'], 81 | DIRECTORY_SEPARATOR, 82 | self::ATTRIBUTE_GROUP_FILENAME 83 | )) 84 | ->write($normalizedGroups); 85 | 86 | return ['attribute_groups' => $this->getAttributeGroups()]; 87 | } 88 | 89 | /** 90 | * Return the generated attribute groups as AttributeGroup object. 91 | * 92 | * @return array 93 | */ 94 | public function getAttributeGroups() 95 | { 96 | $attrGroupObjects = []; 97 | 98 | foreach ($this->attributeGroups as $code => $attributeGroup) { 99 | $attrGroupObject = new AttributeGroup(); 100 | 101 | $attrGroupObject->setCode($code); 102 | 103 | $attrGroupObjects[$code] = $attrGroupObject; 104 | } 105 | 106 | return $attrGroupObjects; 107 | } 108 | 109 | /** 110 | * Get localized random labels 111 | * 112 | * @return array 113 | */ 114 | protected function getLocalizedRandomLabels() 115 | { 116 | $labels = []; 117 | 118 | foreach ($this->locales as $locale) { 119 | $labels[$locale->getCode()] = $this->faker->sentence(2); 120 | } 121 | 122 | return $labels; 123 | } 124 | 125 | protected function normalizeAttributeGroups($groups) 126 | { 127 | $result = []; 128 | 129 | foreach ($groups as $group) { 130 | $normalizedGroup = [ 131 | 'code' => $group['code'], 132 | 'sort_order' => $group['sortOrder'], 133 | ]; 134 | foreach ($group['labels'] as $locale => $label) { 135 | $normalizedGroup[sprintf('label-%s', $locale)] = $label; 136 | } 137 | $result[] = $normalizedGroup; 138 | } 139 | 140 | return $result; 141 | } 142 | 143 | /** 144 | * {@inheritdoc} 145 | */ 146 | public function supports($type) 147 | { 148 | return self::TYPE === $type; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Generator/AttributeOptionGenerator.php: -------------------------------------------------------------------------------- 1 | 18 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 20 | */ 21 | class AttributeOptionGenerator implements GeneratorInterface 22 | { 23 | const TYPE = 'attribute_options'; 24 | 25 | const ATTRIBUTE_OPTION_CODE_PREFIX = 'attr_opt_'; 26 | 27 | const ATTRIBUTE_OPTIONS_FILENAME = 'attribute_options.csv'; 28 | 29 | /** @var CsvWriter */ 30 | protected $writer; 31 | 32 | /** @var array */ 33 | protected $locales = []; 34 | 35 | /** @var array */ 36 | protected $attributeOptions = []; 37 | 38 | /** @var array */ 39 | protected $attributes = []; 40 | 41 | /** @var array */ 42 | protected $selectAttributes; 43 | 44 | /** @var Generator */ 45 | protected $faker; 46 | 47 | /** 48 | * @param CsvWriter $writer 49 | */ 50 | public function __construct(CsvWriter $writer) 51 | { 52 | $this->writer = $writer; 53 | } 54 | 55 | /** 56 | * {@inheritdoc} 57 | */ 58 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 59 | { 60 | $this->locales = $options['locales']; 61 | $this->attributes = $options['attributes']; 62 | 63 | $this->faker = Factory::create(); 64 | if (isset($globalConfig['seed'])) { 65 | $this->faker->seed($globalConfig['seed']); 66 | } 67 | 68 | $countPerAttribute = (int) $entitiesConfig['count_per_attribute']; 69 | 70 | foreach ($this->getSelectAttributes() as $attribute) { 71 | for ($i = 0; $i < $countPerAttribute; $i++) { 72 | $attributeOption = []; 73 | $attributeOption['attribute'] = $attribute->getCode(); 74 | $attributeOption['code'] = self::ATTRIBUTE_OPTION_CODE_PREFIX . $attribute->getCode() . $i; 75 | $attributeOption['sort_order'] = $this->faker->numberBetween(1, $countPerAttribute); 76 | 77 | foreach ($this->getLocalizedRandomLabels() as $localeCode => $label) { 78 | $attributeOption['label-'.$localeCode] = $label; 79 | } 80 | 81 | $this->attributeOptions[$attributeOption['code']] = $attributeOption; 82 | }; 83 | } 84 | 85 | $this->writer 86 | ->setFilename(sprintf( 87 | '%s%s%s', 88 | $globalConfig['output_dir'], 89 | DIRECTORY_SEPARATOR, 90 | self::ATTRIBUTE_OPTIONS_FILENAME 91 | )) 92 | ->write($this->attributeOptions); 93 | 94 | $progress->advance(); 95 | 96 | return []; 97 | } 98 | 99 | /** 100 | * Get localized random labels 101 | * 102 | * @return LocaleInterface[] 103 | */ 104 | protected function getLocalizedRandomLabels() 105 | { 106 | $labels = []; 107 | 108 | foreach ($this->locales as $locale) { 109 | $labels[$locale->getCode()] = $this->faker->sentence(2); 110 | } 111 | 112 | return $labels; 113 | } 114 | 115 | /** 116 | * Get attributes that can have options 117 | * 118 | * @return AttributeInterface[] 119 | * 120 | * @throw \LogicException 121 | */ 122 | public function getSelectAttributes() 123 | { 124 | if (null === $this->selectAttributes) { 125 | $this->selectAttributes = []; 126 | 127 | if (null === $this->attributes) { 128 | throw new \LogicException("No attributes have been provided to the attributeOptionGenerator !"); 129 | } 130 | 131 | foreach ($this->attributes as $attribute) { 132 | if (in_array($attribute->getAttributeType(), [ 133 | AttributeTypes::OPTION_SIMPLE_SELECT, 134 | AttributeTypes::OPTION_MULTI_SELECT 135 | ])) { 136 | $this->selectAttributes[$attribute->getCode()] = $attribute; 137 | } 138 | } 139 | } 140 | 141 | return $this->selectAttributes; 142 | } 143 | 144 | /** 145 | * {@inheritdoc} 146 | */ 147 | public function supports($type) 148 | { 149 | return self::TYPE === $type; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /Generator/CategoryGenerator.php: -------------------------------------------------------------------------------- 1 | 17 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 18 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 19 | */ 20 | class CategoryGenerator implements GeneratorInterface 21 | { 22 | const TYPE = 'categories'; 23 | 24 | const CATEGORIES_FILENAME = 'categories.csv'; 25 | 26 | const CATEGORIES_CODE_PREFIX = 'cat_'; 27 | 28 | const LABEL_LENGTH = 2; 29 | 30 | /** @var CsvWriter */ 31 | protected $writer; 32 | 33 | /** @var LocaleInterface[] */ 34 | protected $locales = []; 35 | 36 | /** @var Generator */ 37 | protected $faker; 38 | 39 | /** 40 | * @param CsvWriter $writer 41 | */ 42 | public function __construct(CsvWriter $writer) 43 | { 44 | $this->writer = $writer; 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 51 | { 52 | $this->locales = $options['locales']; 53 | 54 | $this->faker = Factory::create(); 55 | if (isset($globalConfig['seed'])) { 56 | $this->faker->seed($globalConfig['seed']); 57 | } 58 | 59 | $count = (int) $entitiesConfig['count']; 60 | $levelMax = (int) $entitiesConfig['levels']; 61 | 62 | $countByLevel = $this->calculateNodeCountPerLevel($levelMax, $count); 63 | 64 | $rootCategory = $this->generateCategory('master', 'Master Catalog'); 65 | $categories = $this->generateCategories($rootCategory, 1, $countByLevel, $levelMax); 66 | 67 | $normalizedCategories = $this->normalizeCategories($categories); 68 | 69 | $this->writer 70 | ->setFilename(sprintf( 71 | '%s%s%s', 72 | $globalConfig['output_dir'], 73 | DIRECTORY_SEPARATOR, 74 | self::CATEGORIES_FILENAME 75 | )) 76 | ->write($normalizedCategories); 77 | 78 | $progress->advance($count); 79 | 80 | return ['categories' => $this->flattenCategories($categories)]; 81 | } 82 | 83 | /** 84 | * Generate categories in a tree structure 85 | * 86 | * @param Category $parent 87 | * @param int $level 88 | * @param int $count 89 | * @param int $levelMax 90 | * 91 | * @return Category 92 | */ 93 | protected function generateCategories(Category $parent, $level, $count, $levelMax) 94 | { 95 | for ($i = 0; $i < $count; $i++) { 96 | $categoryCode = $parent->getCode().'_'.$i; 97 | 98 | $category = $this->generateCategory($categoryCode); 99 | 100 | if ($level < $levelMax) { 101 | $this->generateCategories($category, $level + 1, $count, $levelMax); 102 | } 103 | 104 | $parent->addChild($category); 105 | } 106 | 107 | return $parent; 108 | } 109 | 110 | /** 111 | * Generate a category object 112 | * 113 | * @param string $code 114 | * @param string $forcedLabel 115 | * 116 | * @return Category $category 117 | */ 118 | protected function generateCategory($code, $forcedLabel = null) 119 | { 120 | $category = new Category(); 121 | $category->setCode($code); 122 | 123 | foreach ($this->locales as $locale) { 124 | $translation = new CategoryTranslation(); 125 | $translation->setLocale($locale); 126 | 127 | if (null === $forcedLabel) { 128 | $translation->setLabel($this->faker->sentence(self::LABEL_LENGTH)); 129 | } else { 130 | $translation->setLabel($forcedLabel); 131 | } 132 | $category->addTranslation($translation); 133 | } 134 | 135 | return $category; 136 | } 137 | 138 | /** 139 | * Normalize Categories objects into a flat array 140 | * 141 | * @param Category $category 142 | * @param array $normalizedCategories 143 | * 144 | * @return array 145 | */ 146 | protected function normalizeCategories(Category $category, array $normalizedCategories = []) 147 | { 148 | $normalizedCategory = $this->normalizeCategory($category); 149 | 150 | $normalizedCategories[] = $normalizedCategory; 151 | 152 | foreach ($category->getChildren() as $child) { 153 | $normalizedCategories = $this->normalizeCategories($child, $normalizedCategories); 154 | } 155 | 156 | return $normalizedCategories; 157 | } 158 | 159 | /** 160 | * Normalize a category object into a flat array 161 | * 162 | * @param Category $category 163 | * 164 | * @return array 165 | */ 166 | protected function normalizeCategory(Category $category) 167 | { 168 | $normalizedCategory = [ 169 | 'code' => $category->getCode() 170 | ]; 171 | 172 | if (null !== $category->getParent()) { 173 | $normalizedCategory['parent'] = $category->getParent()->getCode(); 174 | } else { 175 | $normalizedCategory['parent'] = ""; 176 | } 177 | 178 | foreach ($category->getTranslations() as $translation) { 179 | $labelCode = 'label-'.$translation->getLocale()->getCode(); 180 | 181 | $normalizedCategory[$labelCode] = $translation->getLabel(); 182 | } 183 | 184 | return $normalizedCategory; 185 | } 186 | 187 | /** 188 | * Flatten the category tree into an array 189 | * 190 | * @param Category $category 191 | * @param array $flatCategories 192 | * 193 | * @return array 194 | */ 195 | protected function flattenCategories(Category $category, array $flatCategories = []) 196 | { 197 | $flatCategories[$category->getCode()] = $category; 198 | 199 | foreach ($category->getChildren() as $child) { 200 | $flatCategories = $this->flattenCategories($child, $flatCategories); 201 | } 202 | 203 | return $flatCategories; 204 | } 205 | 206 | /** 207 | * Calculate on approximation for the average number of nodes per level needed from the 208 | * provided node count and level count 209 | * 210 | * @param int $levelCount 211 | * @param int $nodeCount 212 | * 213 | * @return int 214 | */ 215 | protected function calculateNodeCountPerLevel($levelCount, $nodeCount) 216 | { 217 | $lowerLimit = 1; 218 | 219 | $upperLimit = round(pow($nodeCount, 1/$levelCount)); 220 | 221 | $approximationFound = false; 222 | $avgNodeCount = $lowerLimit; 223 | 224 | $prevDistance = PHP_INT_MAX; 225 | $prevAvgNodeCount = null; 226 | 227 | while (!$approximationFound && $avgNodeCount < $upperLimit) { 228 | $distance = abs($nodeCount - $this->calculateTotalNodesNumber($levelCount, $avgNodeCount)); 229 | 230 | if ($distance > $prevDistance) { 231 | $approximationFound = true; 232 | } else { 233 | $prevAvgNodeCount = $avgNodeCount; 234 | $avgNodeCount++; 235 | } 236 | } 237 | 238 | return $prevAvgNodeCount; 239 | } 240 | 241 | /** 242 | * Get the total number of nodes based on levels count and average node count 243 | * per level 244 | * 245 | * @param int $levelCount 246 | * @param int $avgNodeCount 247 | * 248 | * @return int 249 | */ 250 | protected function calculateTotalNodesNumber($levelCount, $avgNodeCount) 251 | { 252 | $totalNodeCount = 0; 253 | 254 | for ($level = 1; $level <= $levelCount; $level++) { 255 | $totalNodeCount += pow($avgNodeCount, $level); 256 | } 257 | 258 | return $totalNodeCount; 259 | } 260 | 261 | /** 262 | * {@inheritdoc} 263 | */ 264 | public function supports($type) 265 | { 266 | return self::TYPE === $type; 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /Generator/ChainedGenerator.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class ChainedGenerator 15 | { 16 | /** @var GeneratorRegistry */ 17 | protected $registry; 18 | 19 | /** 20 | * @param GeneratorRegistry $registry 21 | */ 22 | public function __construct(GeneratorRegistry $registry) 23 | { 24 | $this->registry = $registry; 25 | } 26 | 27 | /** 28 | * Generates a set of files 29 | * 30 | * @param array $globalConfig 31 | * @param ProgressBar $progress 32 | * 33 | * @throws \Exception 34 | */ 35 | public function generate(array $globalConfig, ProgressBar $progress) 36 | { 37 | $entitiesConfig = $globalConfig['entities']; 38 | unset($globalConfig['entities']); 39 | 40 | // Insert axes count and attributes count for attributes generation to have consistency 41 | if (isset($entitiesConfig['attributes'])) { 42 | if (isset($entitiesConfig['variant_groups']['axes_count'])) { 43 | $variantGroupAxisCount = $entitiesConfig['variant_groups']['axes_count']; 44 | $entitiesConfig['attributes']['min_variant_axes'] = $variantGroupAxisCount; 45 | } 46 | if (isset($entitiesConfig['variant_groups']['attributes_count'])) { 47 | $variantGroupAttributesCount = $entitiesConfig['variant_groups']['attributes_count']; 48 | $entitiesConfig['attributes']['min_variant_attributes'] = $variantGroupAttributesCount; 49 | } 50 | } 51 | 52 | $generatedValues = []; 53 | foreach ($entitiesConfig as $entity => $entityConfig) { 54 | $progress->setMessage(sprintf('Generating %s...', $entity)); 55 | $generator = $this->registry->getGenerator($entity); 56 | if (null !== $generator) { 57 | $generatedValues = array_merge( 58 | $generatedValues, 59 | $generator->generate($globalConfig, $entityConfig, $progress, $generatedValues) 60 | ); 61 | } else { 62 | throw new \Exception(sprintf('Generator for "%s" not found', $entity)); 63 | } 64 | } 65 | $progress->setMessage(''); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Generator/ChannelGenerator.php: -------------------------------------------------------------------------------- 1 | 19 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 21 | */ 22 | class ChannelGenerator implements GeneratorInterface 23 | { 24 | const TYPE = 'channels'; 25 | 26 | const CHANNEL_FILENAME = 'channels.csv'; 27 | 28 | const CURRENCY_FILENAME = 'currencies.csv'; 29 | 30 | const DEFAULT_TREE = 'master'; 31 | 32 | /** @var CsvWriter */ 33 | protected $writer; 34 | 35 | /** @var string */ 36 | protected $channelsFilePath; 37 | 38 | /** @var string */ 39 | protected $currenciesFilePath; 40 | 41 | /** @var ChannelInterface[] */ 42 | protected $channels = []; 43 | 44 | /** @var CurrencyInterface[] */ 45 | protected $currencies = []; 46 | 47 | /** @var LocaleInterface[] */ 48 | protected $locales = []; 49 | 50 | /** 51 | * @param CsvWriter $writer 52 | */ 53 | public function __construct(CsvWriter $writer) 54 | { 55 | $this->writer = $writer; 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 62 | { 63 | $this->channelsFilePath = sprintf( 64 | '%s%s%s', 65 | $globalConfig['output_dir'], 66 | DIRECTORY_SEPARATOR, 67 | self::CHANNEL_FILENAME 68 | ); 69 | $this->currenciesFilePath = sprintf( 70 | '%s%s%s', 71 | $globalConfig['output_dir'], 72 | DIRECTORY_SEPARATOR, 73 | self::CURRENCY_FILENAME 74 | ); 75 | 76 | $this->locales = $this->generateLocales($entitiesConfig); 77 | 78 | $this->currencies = $this->generateCurrencies($entitiesConfig); 79 | 80 | $this->channels = $this->generateChannels($entitiesConfig); 81 | 82 | $this->writeCurrenciesFile(); 83 | 84 | $this->writeChannelsFile($entitiesConfig); 85 | 86 | $progress->advance(); 87 | 88 | return [ 89 | 'locales' => $this->locales, 90 | 'channels' => $this->channels, 91 | ]; 92 | } 93 | 94 | /** 95 | * Generate locales objects from channels configuration 96 | * 97 | * @param array $channelsConfig 98 | * 99 | * @return LocaleInterface[] 100 | */ 101 | protected function generateLocales(array $channelsConfig) 102 | { 103 | $locales = []; 104 | $localeCodes = []; 105 | 106 | foreach ($channelsConfig as $channelConfig) { 107 | $localeCodes = array_merge($localeCodes, $channelConfig['locales']); 108 | } 109 | 110 | $localeCodes = array_unique($localeCodes); 111 | 112 | foreach ($localeCodes as $localeCode) { 113 | $locale = new Locale(); 114 | $locale->setCode($localeCode); 115 | 116 | $locales[$localeCode] = $locale; 117 | } 118 | 119 | return $locales; 120 | } 121 | 122 | /** 123 | * @return LocaleInterface[] 124 | */ 125 | public function getLocales() 126 | { 127 | return $this->locales; 128 | } 129 | 130 | /** 131 | * @return CurrencyInterface[] 132 | */ 133 | public function getCurrencies() 134 | { 135 | return $this->currencies; 136 | } 137 | 138 | /** 139 | * @return ChannelInterface[] 140 | */ 141 | public function getChannels() 142 | { 143 | return $this->channels; 144 | } 145 | 146 | /** 147 | * Generate currencies objects from channels configuration 148 | * 149 | * @param array $channelsConfig 150 | * 151 | * @return CurrencyInterface[] 152 | */ 153 | protected function generateCurrencies(array $channelsConfig) 154 | { 155 | $currencies = []; 156 | $currencyCodes = []; 157 | 158 | foreach ($channelsConfig as $channelConfig) { 159 | $currencyCodes = array_merge($currencyCodes, $channelConfig['currencies']); 160 | } 161 | 162 | $currencyCodes = array_unique($currencyCodes); 163 | 164 | foreach ($currencyCodes as $currencyCode) { 165 | $currency = new Currency(); 166 | $currency->setCode($currencyCode); 167 | $currency->setActivated(true); 168 | 169 | $currencies[$currencyCode] = $currency; 170 | } 171 | 172 | return $currencies; 173 | } 174 | 175 | /** 176 | * Generate channels objects from channels configuration 177 | * 178 | * @param array $channelsConfig 179 | * 180 | * @return ChannelInterface[] 181 | */ 182 | protected function generateChannels(array $channelsConfig) 183 | { 184 | $channels = []; 185 | 186 | foreach ($channelsConfig as $channelConfig) { 187 | $channel = new Channel(); 188 | 189 | $channel->setCode($channelConfig['code']); 190 | $channel->setLabel($channelConfig['label']); 191 | 192 | foreach ($channelConfig['locales'] as $localeCode) { 193 | $locale = $this->locales[$localeCode]; 194 | $channel->addLocale($locale); 195 | } 196 | 197 | foreach ($channelConfig['currencies'] as $currencyCode) { 198 | $currency = $this->currencies[$currencyCode]; 199 | $channel->addCurrency($currency); 200 | } 201 | 202 | $channels[] = $channel; 203 | } 204 | 205 | 206 | return $channels; 207 | } 208 | 209 | /** 210 | * Write the currencies fixture file 211 | */ 212 | protected function writeCurrenciesFile() 213 | { 214 | $data = []; 215 | foreach ($this->currencies as $currency) { 216 | $data[] = [ 217 | 'code' => $currency->getCode(), 218 | 'activated' => 1 219 | ]; 220 | } 221 | 222 | $this->writer 223 | ->setFilename($this->currenciesFilePath) 224 | ->write($data); 225 | } 226 | 227 | /** 228 | * Write the channels fixture file 229 | */ 230 | protected function writeChannelsFile() 231 | { 232 | $data = []; 233 | foreach ($this->channels as $channel) { 234 | $localeCodes = []; 235 | $currencyCodes = []; 236 | 237 | foreach ($channel->getLocales() as $locale) { 238 | $localeCodes[] = $locale->getCode(); 239 | } 240 | 241 | foreach ($channel->getCurrencies() as $currency) { 242 | $currencyCodes[] = $currency->getCode(); 243 | } 244 | 245 | $data[] = [ 246 | 'code' => $channel->getCode(), 247 | 'label' => $channel->getLabel(), 248 | 'tree' => self::DEFAULT_TREE, 249 | 'locales' => implode(',', $localeCodes), 250 | 'currencies' => implode(',', $currencyCodes), 251 | ]; 252 | } 253 | 254 | $this->writer 255 | ->setFilename($this->channelsFilePath) 256 | ->write($data); 257 | } 258 | 259 | /** 260 | * {@inheritdoc} 261 | */ 262 | public function supports($type) 263 | { 264 | return self::TYPE === $type; 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /Generator/FamilyGenerator.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2014 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | class FamilyGenerator implements GeneratorInterface 20 | { 21 | const TYPE = 'families'; 22 | 23 | const FAMILIES_FILENAME = 'families.csv'; 24 | 25 | const FAMILY_CODE_PREFIX = 'fam_'; 26 | 27 | const ATTRIBUTE_DELIMITER = ','; 28 | 29 | /** @var CsvWriter */ 30 | protected $writer; 31 | 32 | /** @var string */ 33 | protected $identifierAttribute; 34 | 35 | /** @var string */ 36 | protected $labelAttribute; 37 | 38 | /** @var array */ 39 | protected $locales = []; 40 | 41 | /** @var array */ 42 | protected $channels = []; 43 | 44 | /** @var Generator */ 45 | protected $faker; 46 | 47 | /** @var array */ 48 | protected $families = []; 49 | 50 | /** @var array */ 51 | protected $attributes = []; 52 | 53 | /** @var array */ 54 | protected $filteredAttrCodes; 55 | 56 | /** 57 | * @param CsvWriter $writer 58 | */ 59 | public function __construct(CsvWriter $writer) 60 | { 61 | $this->writer = $writer; 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | */ 67 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 68 | { 69 | $this->locales = $options['locales']; 70 | $this->attributes = $options['attributes']; 71 | $this->channels = $options['channels']; 72 | 73 | $count = (int) $entitiesConfig['count']; 74 | $attributesCount = (int) $entitiesConfig['attributes_count'] - 1; 75 | $requirementsCount = (int) $entitiesConfig['requirements_count'] - 1; 76 | $this->identifierAttribute = $entitiesConfig['identifier_attribute']; 77 | $this->labelAttribute = $entitiesConfig['label_attribute']; 78 | 79 | $this->faker = Factory::create(); 80 | if (isset($globalConfig['seed'])) { 81 | $this->faker->seed($globalConfig['seed']); 82 | } 83 | 84 | $families = []; 85 | 86 | for ($i = 0; $i < $count; $i++) { 87 | $family = []; 88 | 89 | $family['code'] =self::FAMILY_CODE_PREFIX.$i; 90 | 91 | foreach ($this->getLocalizedRandomLabels() as $localeCode => $label) { 92 | $family['label-'.$localeCode] = $label; 93 | } 94 | 95 | $family['attribute_as_label'] = $this->labelAttribute; 96 | 97 | $attributes = $this->faker->randomElements($this->getAttributeCodes(), $attributesCount); 98 | $attributes = array_unique(array_merge([$this->identifierAttribute, $this->labelAttribute], $attributes)); 99 | $nonMediaAttributeCodes = array_diff($attributes, $options['media_attribute_codes']); 100 | 101 | $family['attributes'] = implode(self::ATTRIBUTE_DELIMITER, $attributes); 102 | 103 | foreach ($this->channels as $channel) { 104 | // non media attributes can't be set to required to avoid to have to generate for complete products 105 | $attributeReqs = $this->faker->randomElements($nonMediaAttributeCodes, $requirementsCount); 106 | $attributeReqs = array_merge([$this->identifierAttribute], $attributeReqs); 107 | 108 | $family['requirements-'.$channel->getCode()] = implode(self::ATTRIBUTE_DELIMITER, $attributeReqs); 109 | } 110 | 111 | $families[$family['code']] = $family; 112 | $progress->advance(); 113 | } 114 | 115 | $this->families = $families; 116 | 117 | $this->writer 118 | ->setFilename(sprintf( 119 | '%s%s%s', 120 | $globalConfig['output_dir'], 121 | DIRECTORY_SEPARATOR, 122 | self::FAMILIES_FILENAME 123 | )) 124 | ->write($families); 125 | 126 | return []; 127 | } 128 | 129 | /** 130 | * Return the generated families as Family object 131 | * 132 | * @return array 133 | */ 134 | public function getFamilyObjects() 135 | { 136 | $familyObjects = []; 137 | 138 | foreach ($this->families as $code => $family) { 139 | $familyObject = new Family(); 140 | 141 | $familyObject->setCode($code); 142 | 143 | $familyObjects[] = $familyObject; 144 | } 145 | 146 | return $familyObjects; 147 | } 148 | 149 | /** 150 | * Get localized random labels 151 | * 152 | * @return array 153 | */ 154 | protected function getLocalizedRandomLabels() 155 | { 156 | $labels = []; 157 | 158 | foreach ($this->locales as $locale) { 159 | $labels[$locale->getCode()] = $this->faker->sentence(2); 160 | } 161 | 162 | return $labels; 163 | } 164 | 165 | /** 166 | * Get attributes codes 167 | * 168 | * @return array 169 | */ 170 | protected function getAttributeCodes() 171 | { 172 | if (null === $this->filteredAttrCodes) { 173 | $this->filteredAttrCodes = []; 174 | foreach (array_keys($this->attributes) as $code) { 175 | if ($code !== $this->identifierAttribute && $code !== $this->labelAttribute) { 176 | $this->filteredAttrCodes[] = $code; 177 | } 178 | } 179 | } 180 | 181 | return $this->filteredAttrCodes; 182 | } 183 | 184 | /** 185 | * {@inheritdoc} 186 | */ 187 | public function supports($type) 188 | { 189 | return self::TYPE === $type; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /Generator/GeneratorInterface.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2014 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | interface GeneratorInterface 15 | { 16 | /** 17 | * Generate the amount of entity 18 | * 19 | * @param array $globalConfig 20 | * @param array $entitiesConfig 21 | * @param ProgressBar $progress 22 | * @param array $options 23 | * 24 | * @return array 25 | */ 26 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []); 27 | 28 | /** 29 | * Check if the Generator can generate type 30 | * 31 | * @param string $type 32 | * 33 | * @return bool 34 | */ 35 | public function supports($type); 36 | } 37 | -------------------------------------------------------------------------------- /Generator/GeneratorRegistry.php: -------------------------------------------------------------------------------- 1 | 9 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 10 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 11 | */ 12 | class GeneratorRegistry 13 | { 14 | /** @var GeneratorInterface[] */ 15 | protected $generators = []; 16 | 17 | /** 18 | * Register a new Generator 19 | * 20 | * @param GeneratorInterface $generator 21 | * 22 | * @return GeneratorRegistryInterface 23 | */ 24 | public function register(GeneratorInterface $generator) 25 | { 26 | $this->generators[] = $generator; 27 | 28 | return $this; 29 | } 30 | 31 | /** 32 | * Get a generator supported by type 33 | * 34 | * @param string $type 35 | * 36 | * @return GeneratorInterface|null 37 | */ 38 | public function getGenerator($type) 39 | { 40 | foreach ($this->generators as $generator) { 41 | if ($generator->supports($type)) { 42 | return $generator; 43 | } 44 | } 45 | 46 | return null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Generator/GroupTypeGenerator.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class GroupTypeGenerator implements GeneratorInterface 19 | { 20 | const TYPE = 'group_types'; 21 | 22 | const GROUP_TYPES_FILENAME = 'group_types.csv'; 23 | 24 | /** @var CsvWriter */ 25 | protected $writer; 26 | 27 | /** 28 | * @param CsvWriter $writer 29 | */ 30 | public function __construct(CsvWriter $writer) 31 | { 32 | $this->writer = $writer; 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 39 | { 40 | $variantGroupType = new GroupType(); 41 | $variantGroupType->setVariant(true); 42 | $variantGroupType->setCode('VARIANT'); 43 | 44 | $relatedGroupType = new GroupType(); 45 | $relatedGroupType->setVariant(false); 46 | $relatedGroupType->setCode('RELATED'); 47 | 48 | $groupTypes = [$variantGroupType, $relatedGroupType]; 49 | 50 | $data = []; 51 | foreach ($groupTypes as $groupType) { 52 | $data[] = $this->normalizeGroupType($groupType); 53 | } 54 | 55 | $progress->advance(); 56 | 57 | $this->writer 58 | ->setFilename(sprintf( 59 | '%s%s%s', 60 | $globalConfig['output_dir'], 61 | DIRECTORY_SEPARATOR, 62 | self::GROUP_TYPES_FILENAME 63 | )) 64 | ->write($data); 65 | 66 | return ['group_types' => $groupTypes]; 67 | } 68 | 69 | /** 70 | * @param GroupTypeInterface $groupType 71 | * 72 | * @return array 73 | */ 74 | public function normalizeGroupType(GroupTypeInterface $groupType) 75 | { 76 | return [ 77 | 'code' => $groupType->getCode(), 78 | 'is_variant' => $groupType->isVariant() ? 1 : 0 79 | ]; 80 | } 81 | 82 | /** 83 | * {@inheritdoc} 84 | */ 85 | public function supports($type) 86 | { 87 | return self::TYPE === $type; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Generator/JobGenerator.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class JobGenerator implements GeneratorInterface 18 | { 19 | const TYPE = 'jobs'; 20 | 21 | const JOB_FILENAME = 'jobs.yml'; 22 | 23 | const INTERNAL_JOBS_FILE = 'Resources/config/internal_jobs.yml'; 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 29 | { 30 | $jobs = $this->generateJobs($entitiesConfig); 31 | 32 | $normalizedJobs = $this->normalizeJobs($jobs); 33 | if (!isset($normalizedJobs['jobs'])) { 34 | $normalizedJobs['jobs'] = []; 35 | } 36 | 37 | $normalizedJobs['jobs'] = array_merge( 38 | $normalizedJobs['jobs'], 39 | $this->getInternalJobs() 40 | ); 41 | 42 | $this->writeYamlFile( 43 | $normalizedJobs, 44 | sprintf('%s%s%s', $globalConfig['output_dir'], DIRECTORY_SEPARATOR, self::JOB_FILENAME) 45 | ); 46 | 47 | $progress->advance(); 48 | 49 | return ['job_codes' => array_keys($normalizedJobs['jobs'])]; 50 | } 51 | 52 | /** 53 | * Generate jobs objects 54 | * 55 | * @param array $jobsConfig 56 | * 57 | * @return JobInstance[] 58 | */ 59 | protected function generateJobs(array $jobsConfig) 60 | { 61 | $jobs = []; 62 | foreach ($jobsConfig as $jobCode => $jobConfig) { 63 | $job = $this->generateJob($jobCode, $jobConfig); 64 | $jobs[$job->getCode()] = $job; 65 | } 66 | 67 | return $jobs; 68 | } 69 | 70 | /** 71 | * Generate a job object from the data provided 72 | * 73 | * @param string $code 74 | * @param array $jobConfig 75 | * 76 | * @return JobInstance 77 | */ 78 | protected function generateJob($code, array $jobConfig) 79 | { 80 | $job = new JobInstance(); 81 | $job->setCode($code); 82 | $job->setConnector($jobConfig['connector']); 83 | $job->setJobName($jobConfig['alias']); 84 | $job->setLabel($jobConfig['label']); 85 | $job->setType($jobConfig['type']); 86 | 87 | if (isset($jobConfig['configuration'])) { 88 | $job->setRawParameters($jobConfig['configuration']); 89 | } 90 | 91 | return $job; 92 | } 93 | 94 | /** 95 | * Normalize jobs objects into a structured array 96 | * 97 | * @param JobInstance[] $jobs 98 | * 99 | * @return array 100 | */ 101 | protected function normalizeJobs(array $jobs) 102 | { 103 | $normalizedJobs = []; 104 | 105 | foreach ($jobs as $job) { 106 | $normalizedJobs[$job->getCode()] = $this->normalizeJob($job); 107 | } 108 | 109 | return [ "jobs" => $normalizedJobs ]; 110 | } 111 | 112 | /** 113 | * Normalize job object into a structured array 114 | * 115 | * @param JobInstance $job 116 | * 117 | * @return array 118 | */ 119 | protected function normalizeJob(JobInstance $job) 120 | { 121 | $normalizeJob = [ 122 | "connector" => $job->getConnector(), 123 | "alias" => $job->getJobName(), 124 | "label" => $job->getLabel(), 125 | "type" => $job->getType() 126 | ]; 127 | 128 | if (count($job->getRawParameters()) > 0) { 129 | $normalizeJob["configuration"] = $job->getRawParameters(); 130 | } 131 | 132 | return $normalizeJob; 133 | } 134 | 135 | /** 136 | * Get the internal jobs definition as an array 137 | * 138 | * @return array 139 | */ 140 | protected function getInternalJobs() 141 | { 142 | $internalJobsPath = sprintf( 143 | '%s%s..%s%s', 144 | __DIR__, 145 | DIRECTORY_SEPARATOR, 146 | DIRECTORY_SEPARATOR, 147 | self::INTERNAL_JOBS_FILE 148 | ); 149 | $yamlParser = new Parser(); 150 | 151 | return $yamlParser->parse(file_get_contents($internalJobsPath))['jobs']; 152 | } 153 | 154 | /** 155 | * Write a YAML file 156 | * 157 | * @param array $data 158 | * @param string $filename 159 | */ 160 | protected function writeYamlFile(array $data, $filename) 161 | { 162 | $dumper = new Dumper(); 163 | $yamlData = $dumper->dump($data, 5, 0, true, true); 164 | 165 | file_put_contents($filename, $yamlData); 166 | } 167 | 168 | /** 169 | * {@inheritdoc} 170 | */ 171 | public function supports($type) 172 | { 173 | return self::TYPE === $type; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /Generator/JobProfileAccessGenerator.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class JobProfileAccessGenerator implements GeneratorInterface 18 | { 19 | const TYPE = 'job_profile_accesses'; 20 | 21 | const JOB_PROFILE_ACCESSES_FILENAME = 'job_profile_accesses.csv'; 22 | 23 | const JOB_PROFILE_ACCESSES = 'job_profile_accesses'; 24 | 25 | /** @var CsvWriter */ 26 | protected $writer; 27 | 28 | /** 29 | * @param CsvWriter $writer 30 | */ 31 | public function __construct(CsvWriter $writer) 32 | { 33 | $this->writer = $writer; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 40 | { 41 | $groups = $options['user_groups']; 42 | $jobCodes = $options['job_codes']; 43 | 44 | $groupNames = []; 45 | foreach ($groups as $group) { 46 | if (User::GROUP_DEFAULT !== $group->getName()) { 47 | $groupNames[] = $group->getName(); 48 | } 49 | } 50 | 51 | $data = []; 52 | foreach ($jobCodes as $jobCode) { 53 | $data[] = [ 54 | 'job_profile' => $jobCode, 55 | 'execute_job_profile' => implode(',', $groupNames), 56 | 'edit_job_profile' => implode(',', $groupNames), 57 | ]; 58 | } 59 | 60 | $progress->advance(); 61 | 62 | $this->writer 63 | ->setFilename(sprintf( 64 | '%s%s%s', 65 | $globalConfig['output_dir'], 66 | DIRECTORY_SEPARATOR, 67 | self::JOB_PROFILE_ACCESSES_FILENAME 68 | )) 69 | ->write($data); 70 | 71 | return []; 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | public function supports($type) 78 | { 79 | return self::TYPE === $type; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Generator/LocaleAccessGenerator.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class LocaleAccessGenerator implements GeneratorInterface 19 | { 20 | const TYPE = 'locale_accesses'; 21 | 22 | const LOCALE_ACCESSES_FILENAME = 'locale_accesses.csv'; 23 | 24 | const LOCALE_ACCESSES = 'locale_accesses'; 25 | 26 | /** @var CsvWriter */ 27 | protected $writer; 28 | 29 | /** 30 | * @param CsvWriter $writer 31 | */ 32 | public function __construct(CsvWriter $writer) 33 | { 34 | $this->writer = $writer; 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 41 | { 42 | $groups = $options['user_groups']; 43 | $locales = $options['locales']; 44 | 45 | $groupNames = []; 46 | foreach ($groups as $group) { 47 | if (User::GROUP_DEFAULT !== $group->getName()) { 48 | $groupNames[] = $group->getName(); 49 | } 50 | } 51 | 52 | $data = []; 53 | foreach ($locales as $locale) { 54 | $data[] = [ 55 | 'locale' => $locale->getCode(), 56 | 'view_products' => implode(',', $groupNames), 57 | 'edit_products' => implode(',', $groupNames), 58 | ]; 59 | } 60 | $progress->advance(); 61 | 62 | $this->writer 63 | ->setFilename(sprintf( 64 | '%s%s%s', 65 | $globalConfig['output_dir'], 66 | DIRECTORY_SEPARATOR, 67 | self::LOCALE_ACCESSES_FILENAME 68 | )) 69 | ->write($data); 70 | 71 | return []; 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | public function supports($type) 78 | { 79 | return self::TYPE === $type; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Generator/LocaleGenerator.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class LocaleGenerator implements GeneratorInterface 15 | { 16 | const TYPE = 'locales'; 17 | 18 | const LOCALES_FILENAME = 'locales.csv'; 19 | 20 | const INTERNAL_LOCALES_FILE = 'Resources/config/locales.csv'; 21 | 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 26 | { 27 | copy( 28 | sprintf( 29 | '%s%s..%s%s', 30 | dirname(__FILE__), 31 | DIRECTORY_SEPARATOR, 32 | DIRECTORY_SEPARATOR, 33 | self::INTERNAL_LOCALES_FILE 34 | ), 35 | sprintf( 36 | '%s%s%s', 37 | $globalConfig['output_dir'], 38 | DIRECTORY_SEPARATOR, 39 | self::LOCALES_FILENAME 40 | ) 41 | ); 42 | 43 | $progress->advance(); 44 | 45 | return []; 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | public function supports($type) 52 | { 53 | return self::TYPE === $type; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Generator/Product/AbstractProductGenerator.php: -------------------------------------------------------------------------------- 1 | 15 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 16 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 17 | */ 18 | class AbstractProductGenerator 19 | { 20 | const IDENTIFIER_PREFIX = 'id-'; 21 | 22 | const DEFAULT_DELIMITER = ';'; 23 | 24 | /** @var FamilyRepositoryInterface */ 25 | private $familyRepository; 26 | 27 | /** @var ProductRawBuilder */ 28 | protected $productRawBuilder; 29 | 30 | /** @var FamilyInterface[] */ 31 | protected $families; 32 | 33 | /** @var array */ 34 | protected $headers; 35 | 36 | /** 37 | * AbstractProductGenerator constructor. 38 | * 39 | * @param ProductRawBuilder $productRawBuilder 40 | * @param FamilyRepositoryInterface $familyRepository 41 | */ 42 | public function __construct( 43 | ProductRawBuilder $productRawBuilder, 44 | FamilyRepositoryInterface $familyRepository 45 | ) { 46 | $this->productRawBuilder = $productRawBuilder; 47 | $this->familyRepository = $familyRepository; 48 | $this->headers = []; 49 | } 50 | 51 | /** 52 | * @param Faker\Generator $faker 53 | * @param array $forcedValues 54 | * @param array $mandatoryAttributes 55 | * @param int $id 56 | * @param int $nbAttr 57 | * @param int $nbAttrDeviation 58 | * @param int $nbCategories 59 | * 60 | * @return array 61 | */ 62 | protected function buildRawProduct( 63 | Faker\Generator $faker, 64 | array $forcedValues, 65 | array $mandatoryAttributes, 66 | $id, 67 | $nbAttr, 68 | $nbAttrDeviation, 69 | $nbCategories 70 | ) { 71 | $family = $this->getRandomFamily($faker); 72 | $product = $this->productRawBuilder->buildBaseProduct($family, $id, ''); 73 | 74 | $this->productRawBuilder->fillInRandomCategories($product, $nbCategories); 75 | $this->productRawBuilder->fillInRandomAttributes($family, $product, $forcedValues, $nbAttr, $nbAttrDeviation); 76 | $this->productRawBuilder->fillInMandatoryAttributes($family, $product, $forcedValues, $mandatoryAttributes); 77 | 78 | return $product; 79 | } 80 | 81 | /** 82 | * @param Faker\Generator $faker 83 | * @param array $forcedValues 84 | * @param int $id 85 | * @param int $nbCategories 86 | * 87 | * @return array 88 | */ 89 | protected function buildCompleteRawProduct( 90 | Faker\Generator $faker, 91 | array $forcedValues, 92 | $id, 93 | $nbCategories 94 | ) { 95 | $family = $this->getRandomFamily($faker); 96 | $product = $this->productRawBuilder->buildBaseProduct($family, $id, ''); 97 | 98 | $this->productRawBuilder->fillInRandomCategories($product, $nbCategories); 99 | $this->productRawBuilder->fillInAllRequirementAttributes($family, $product, $forcedValues); 100 | 101 | return $product; 102 | } 103 | 104 | 105 | /** 106 | * Write the CSV file from data coming from the buffer 107 | * 108 | * @param array $headers 109 | * @param string $outputFile 110 | * @param string $tmpFile 111 | * @param string $delimiter 112 | */ 113 | protected function writeCsvFile(array $headers, $outputFile, $tmpFile, $delimiter) 114 | { 115 | $buffer = fopen($tmpFile, 'r'); 116 | 117 | $csvFile = fopen($outputFile, 'w'); 118 | 119 | fputcsv($csvFile, $headers, $delimiter); 120 | $headersAsKeys = array_fill_keys($headers, ""); 121 | 122 | while ($bufferedProduct = fgets($buffer)) { 123 | $product = unserialize($bufferedProduct); 124 | $productData = array_merge($headersAsKeys, $product); 125 | fputcsv($csvFile, $productData, $delimiter); 126 | } 127 | fclose($csvFile); 128 | fclose($buffer); 129 | } 130 | 131 | /** 132 | * Bufferize the product for latter use and set the headers 133 | * 134 | * @param array $product 135 | * @param string $tmpFile 136 | */ 137 | protected function bufferizeProduct(array $product, $tmpFile) 138 | { 139 | $this->headers = array_unique(array_merge($this->headers, array_keys($product))); 140 | 141 | file_put_contents($tmpFile, serialize($product) . "\n", FILE_APPEND); 142 | } 143 | 144 | /** 145 | * Get a random item from a repo 146 | * 147 | * @param Faker\Generator $faker 148 | * @param ObjectRepository $repo 149 | * @param array &$items 150 | * 151 | * @return mixed 152 | */ 153 | protected function getRandomItem(Faker\Generator $faker, ObjectRepository $repo, array &$items = null) 154 | { 155 | if (null === $items) { 156 | $items = []; 157 | $loadedItems = $repo->findAll(); 158 | foreach ($loadedItems as $item) { 159 | $items[$item->getCode()] = $item; 160 | } 161 | } 162 | 163 | return $faker->randomElement($items); 164 | } 165 | 166 | /** 167 | * @param string $seed 168 | * 169 | * @return Faker\Generator 170 | */ 171 | protected function initFaker($seed) 172 | { 173 | $faker = Faker\Factory::create(); 174 | $faker->seed($seed); 175 | $this->productRawBuilder->setFakerGenerator($faker); 176 | 177 | return $faker; 178 | } 179 | 180 | /** 181 | * Get a random family 182 | * 183 | * @param Faker\Generator $faker 184 | * 185 | * @return FamilyInterface 186 | */ 187 | private function getRandomFamily(Faker\Generator $faker) 188 | { 189 | return $this->getRandomItem($faker, $this->familyRepository, $this->families); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /Generator/Product/ProductValueRawBuilder.php: -------------------------------------------------------------------------------- 1 | 20 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 21 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 22 | */ 23 | class ProductValueRawBuilder 24 | { 25 | const METRIC_UNIT = 'unit'; 26 | const DEFAULT_NUMBER_MIN = '0'; 27 | const DEFAULT_NUMBER_MAX = '1000'; 28 | const DEFAULT_NB_DECIMALS = '4'; 29 | 30 | /** @var AttributeKeyProvider */ 31 | private $attributeKeyProvider; 32 | 33 | /** @var Faker\Generator */ 34 | private $faker; 35 | 36 | /** @var AttributeOptionInterface[] */ 37 | private $attributeOptions; 38 | 39 | /** 40 | * ProductValueRawBuilder constructor. 41 | * 42 | * @param AttributeKeyProvider $attributeKeyProvider 43 | */ 44 | public function __construct(AttributeKeyProvider $attributeKeyProvider) 45 | { 46 | $this->attributeKeyProvider = $attributeKeyProvider; 47 | } 48 | 49 | /** 50 | * @param Faker\Generator $faker 51 | * 52 | * @return ProductValueRawBuilder 53 | */ 54 | public function setFakerGenerator(Faker\Generator $faker) 55 | { 56 | $this->faker = $faker; 57 | 58 | return $this; 59 | } 60 | 61 | /** 62 | * Generate a value in term of one or several entries in the product array 63 | * 64 | * @param AttributeInterface $attribute 65 | * 66 | * @return array 67 | */ 68 | public function build(AttributeInterface $attribute) 69 | { 70 | if (null === $this->faker) { 71 | throw new \LogicException('Please set the faker generator before using this method.'); 72 | } 73 | 74 | $valueData = []; 75 | $keys = $this->attributeKeyProvider->getAttributeKeys($attribute); 76 | 77 | foreach ($keys as $key) { 78 | $valueData[$key] = $this->generateValueData($attribute, $key); 79 | } 80 | 81 | return $valueData; 82 | } 83 | 84 | /** 85 | * Generate value content based on backend type 86 | * 87 | * @param AttributeInterface $attribute 88 | * @param string $key 89 | * 90 | * @return string 91 | */ 92 | private function generateValueData(AttributeInterface $attribute, $key) 93 | { 94 | if (preg_match('/-' . self::METRIC_UNIT . '$/', $key)) { 95 | return $attribute->getDefaultMetricUnit(); 96 | } 97 | 98 | switch ($attribute->getBackendType()) { 99 | case "varchar": 100 | $data = $this->generateVarcharData($attribute); 101 | break; 102 | case "text": 103 | $data = $this->generateTextData(); 104 | break; 105 | case "date": 106 | $data = $this->generateDateData($attribute); 107 | break; 108 | case "metric": 109 | case "decimal": 110 | case "prices": 111 | $data = $this->generateNumberData($attribute); 112 | break; 113 | case "boolean": 114 | $data = $this->generateBooleanData(); 115 | break; 116 | case "option": 117 | case "options": 118 | $data = $this->generateOptionData($attribute); 119 | break; 120 | default: 121 | $data = ''; 122 | break; 123 | } 124 | 125 | return (string) $data; 126 | } 127 | 128 | /** 129 | * Generate a varchar product value data 130 | * 131 | * @param AttributeInterface $attribute 132 | * 133 | * @return string 134 | */ 135 | private function generateVarcharData(AttributeInterface $attribute) 136 | { 137 | $validationRule = $attribute->getValidationRule(); 138 | switch ($validationRule) { 139 | case 'url': 140 | $varchar = $this->faker->url(); 141 | break; 142 | default: 143 | $varchar = $this->faker->sentence(); 144 | break; 145 | } 146 | 147 | return $varchar; 148 | } 149 | 150 | /** 151 | * Generate a text product value data 152 | * 153 | * @return string 154 | */ 155 | private function generateTextData() 156 | { 157 | return $this->faker->sentence(); 158 | } 159 | 160 | /** 161 | * Generate a date product value data 162 | * 163 | * @param AttributeInterface $attribute 164 | * 165 | * @return string 166 | */ 167 | private function generateDateData(AttributeInterface $attribute) 168 | { 169 | $date = $this->faker->dateTimeBetween($attribute->getDateMin(), $attribute->getDateMax()); 170 | 171 | return $date->format('Y-m-d'); 172 | } 173 | 174 | /** 175 | * Generate number data 176 | * 177 | * @param AttributeInterface $attribute 178 | * 179 | * @return string 180 | */ 181 | private function generateNumberData(AttributeInterface $attribute) 182 | { 183 | $min = ($attribute->getNumberMin() != null) ? $attribute->getNumberMin() : self::DEFAULT_NUMBER_MIN; 184 | $max = ($attribute->getNumberMax() != null) ? $attribute->getNumberMax() : self::DEFAULT_NUMBER_MAX; 185 | 186 | $decimals = $attribute->isDecimalsAllowed() ? self::DEFAULT_NB_DECIMALS : 0; 187 | 188 | $number = $this->faker->randomFloat($decimals, $min, $max); 189 | 190 | return (string) $number; 191 | } 192 | 193 | /** 194 | * Generate a boolean product value data 195 | * 196 | * @return string 197 | */ 198 | private function generateBooleanData() 199 | { 200 | return $this->faker->boolean() ? "1" : "0"; 201 | } 202 | 203 | /** 204 | * Generate option data 205 | * 206 | * @param AttributeInterface $attribute 207 | * 208 | * @return string 209 | */ 210 | private function generateOptionData(AttributeInterface $attribute) 211 | { 212 | $optionCode = ""; 213 | 214 | $option = $this->getRandomOptionFromAttribute($attribute); 215 | 216 | if (is_object($option)) { 217 | $optionCode = $option->getCode(); 218 | } 219 | 220 | return $optionCode; 221 | } 222 | 223 | /** 224 | * Get a random option from an attribute 225 | * 226 | * @param AttributeInterface $attribute 227 | * 228 | * @return AttributeOptionInterface 229 | */ 230 | private function getRandomOptionFromAttribute(AttributeInterface $attribute) 231 | { 232 | if (!isset($this->attributeOptions[$attribute->getCode()])) { 233 | $this->attributeOptions[$attribute->getCode()] = []; 234 | 235 | foreach ($attribute->getOptions() as $option) { 236 | $this->attributeOptions[$attribute->getCode()][] = $option; 237 | } 238 | } 239 | 240 | return $this->faker->randomElement($this->attributeOptions[$attribute->getCode()]); 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /Generator/ProductCategoryAccessGenerator.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class ProductCategoryAccessGenerator implements GeneratorInterface 18 | { 19 | const TYPE = 'product_category_accesses'; 20 | 21 | const PRODUCT_CATEGORY_ACCESSES_FILENAME = 'product_category_accesses.csv'; 22 | 23 | const PRODUCT_CATEGORY_ACCESSES = 'product_category_accesses'; 24 | 25 | /** @var CsvWriter */ 26 | protected $writer; 27 | 28 | /** 29 | * @param CsvWriter $writer 30 | */ 31 | public function __construct(CsvWriter $writer) 32 | { 33 | $this->writer = $writer; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 40 | { 41 | $groups = $options['user_groups']; 42 | $categories = $options['categories']; 43 | 44 | $groupNames = []; 45 | foreach ($groups as $group) { 46 | if (User::GROUP_DEFAULT !== $group->getName()) { 47 | $groupNames[] = $group->getName(); 48 | } 49 | } 50 | 51 | $data = []; 52 | foreach ($categories as $category) { 53 | $data[] = [ 54 | 'category' => $category->getCode(), 55 | 'view_items' => implode(',', $groupNames), 56 | 'edit_items' => implode(',', $groupNames), 57 | 'own_items' => implode(',', $groupNames), 58 | ]; 59 | } 60 | $progress->advance(); 61 | 62 | $this->writer 63 | ->setFilename(sprintf( 64 | '%s%s%s', 65 | $globalConfig['output_dir'], 66 | DIRECTORY_SEPARATOR, 67 | self::PRODUCT_CATEGORY_ACCESSES_FILENAME 68 | )) 69 | ->write($data); 70 | 71 | return []; 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | public function supports($type) 78 | { 79 | return self::TYPE === $type; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Generator/ProductDraftGenerator.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | class ProductDraftGenerator extends AbstractProductGenerator implements GeneratorInterface 17 | { 18 | const TYPE = 'product_drafts'; 19 | 20 | /** 21 | * {@inheritdoc} 22 | */ 23 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 24 | { 25 | $tmpFile = tempnam(sys_get_temp_dir(), 'data-gene'); 26 | $outputFile = $globalConfig['output_dir'] . DIRECTORY_SEPARATOR . trim($entitiesConfig['filename']); 27 | 28 | $seed = $globalConfig['seed']; 29 | $count = (int) $entitiesConfig['count']; 30 | $nbAttrBase = (int) $entitiesConfig['filled_attributes_count']; 31 | $nbAttrDeviation = (int) $entitiesConfig['filled_attributes_standard_deviation']; 32 | $startIndex = (int) $entitiesConfig['start_index']; 33 | $mandatoryAttributes = $entitiesConfig['mandatory_attributes']; 34 | $forcedValues = $entitiesConfig['force_values']; 35 | $delimiter = $entitiesConfig['delimiter']; 36 | 37 | $faker = $this->initFaker($seed); 38 | 39 | for ($i = $startIndex; $i < ($startIndex + $count); $i++) { 40 | $product = $this->buildRawProduct( 41 | $faker, 42 | $forcedValues, 43 | $mandatoryAttributes, 44 | self::IDENTIFIER_PREFIX . $i, 45 | $nbAttrBase, 46 | $nbAttrDeviation, 47 | 0 48 | ); 49 | 50 | $this->bufferizeProduct($product, $tmpFile); 51 | $progress->advance(); 52 | } 53 | 54 | $this->writeCsvFile($this->headers, $outputFile, $tmpFile, $delimiter); 55 | unlink($tmpFile); 56 | 57 | return []; 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function supports($type) 64 | { 65 | return self::TYPE === $type; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Generator/ProductGenerator.php: -------------------------------------------------------------------------------- 1 | 19 | * @copyright 2014 Akeneo SAS (http://www.akeneo.com) 20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 21 | */ 22 | class ProductGenerator extends AbstractProductGenerator implements GeneratorInterface 23 | { 24 | const TYPE = 'products'; 25 | 26 | /** @var GroupRepositoryInterface */ 27 | private $groupRepository; 28 | 29 | /** @var VariantGroupDataProvider[] */ 30 | private $variantGroupDataProviders = []; 31 | 32 | /** @var AttributeKeyProvider */ 33 | private $attributeKeyProvider; 34 | 35 | /** 36 | * @param ProductRawBuilder $productRawBuilder 37 | * @param FamilyRepositoryInterface $familyRepository 38 | * @param GroupRepositoryInterface $groupRepository 39 | * @param AttributeKeyProvider $attributeKeyProvider 40 | */ 41 | public function __construct( 42 | ProductRawBuilder $productRawBuilder, 43 | FamilyRepositoryInterface $familyRepository, 44 | GroupRepositoryInterface $groupRepository, 45 | AttributeKeyProvider $attributeKeyProvider 46 | ) { 47 | parent::__construct($productRawBuilder, $familyRepository); 48 | $this->groupRepository = $groupRepository; 49 | $this->variantGroupDataProviders = []; 50 | $this->attributeKeyProvider = $attributeKeyProvider; 51 | } 52 | 53 | /** 54 | * {@inheritdoc} 55 | */ 56 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 57 | { 58 | $tmpFile = tempnam(sys_get_temp_dir(), 'data-gene'); 59 | $outputFile = $globalConfig['output_dir'] . DIRECTORY_SEPARATOR . trim($entitiesConfig['filename']); 60 | 61 | $seed = $globalConfig['seed']; 62 | $count = (int) $entitiesConfig['count']; 63 | $nbAttrBase = (int) $entitiesConfig['filled_attributes_count']; 64 | $nbAttrDeviation = (int) $entitiesConfig['filled_attributes_standard_deviation']; 65 | $startIndex = (int) $entitiesConfig['start_index']; 66 | $categoriesCount = (int) $entitiesConfig['categories_count']; 67 | $variantGroupCount = (int) $entitiesConfig['products_per_variant_group']; 68 | $mandatoryAttributes = $entitiesConfig['mandatory_attributes']; 69 | $forcedValues = $entitiesConfig['force_values']; 70 | $delimiter = $entitiesConfig['delimiter']; 71 | $percentageComplete = $entitiesConfig['percentage_complete']; 72 | $allAttributeKeys = $entitiesConfig['all_attribute_keys']; 73 | 74 | if ($variantGroupCount > 0) { 75 | foreach ($this->groupRepository->getAllVariantGroups() as $variantGroup) { 76 | $this->variantGroupDataProviders[] = new VariantGroupDataProvider($variantGroup, $variantGroupCount); 77 | } 78 | } 79 | 80 | if (count($this->variantGroupDataProviders) * $variantGroupCount > $count) { 81 | throw new \Exception(sprintf( 82 | 'You require too much products per variant group (%s). '. 83 | 'There is only %s variant groups for %s required products', 84 | $variantGroupCount, 85 | count($this->variantGroupDataProviders), 86 | $count 87 | )); 88 | } 89 | 90 | $faker = $this->initFaker($seed); 91 | 92 | for ($i = $startIndex; $i < ($startIndex + $count); $i++) { 93 | $isComplete = (bool)($faker->numberBetween(0, 100) < $percentageComplete); 94 | $variantGroupDataProvider = $this->getNextVariantGroupProvider($faker); 95 | $variantGroupAttributes = []; 96 | 97 | if (null !== $variantGroupDataProvider) { 98 | $variantGroupAttributes = $variantGroupDataProvider->getAttributes(); 99 | $product['groups'] = $variantGroupDataProvider->getCode(); 100 | } 101 | 102 | if (!$isComplete) { 103 | $product = $this->buildRawProduct( 104 | $faker, 105 | $forcedValues, 106 | $mandatoryAttributes, 107 | self::IDENTIFIER_PREFIX . $i, 108 | $nbAttrBase - count($variantGroupAttributes), 109 | $nbAttrDeviation, 110 | $categoriesCount 111 | ); 112 | } else { 113 | $product = $this->buildCompleteRawProduct( 114 | $faker, 115 | $forcedValues, 116 | self::IDENTIFIER_PREFIX . $i, 117 | $categoriesCount 118 | ); 119 | } 120 | 121 | if (null !== $variantGroupDataProvider) { 122 | $product = array_merge($product, $variantGroupDataProvider->getData()); 123 | } 124 | 125 | $this->bufferizeProduct($product, $tmpFile); 126 | $progress->advance(); 127 | } 128 | 129 | if (true === $allAttributeKeys) { 130 | $keys = array_unique(array_merge($this->attributeKeyProvider->getAllAttributesKeys(), $this->headers)); 131 | sort($keys); 132 | $this->headers = $keys; 133 | } 134 | 135 | $this->writeCsvFile($this->headers, $outputFile, $tmpFile, $delimiter); 136 | unlink($tmpFile); 137 | 138 | return []; 139 | } 140 | 141 | /** 142 | * Get a random variantGroupProvider. If this is the last usage of it, removes it from the list. 143 | * If there is no remaining VariantGroupProvider, returns null. 144 | * 145 | * @param Faker\Generator $faker 146 | * 147 | * @return null|VariantGroupDataProvider 148 | */ 149 | private function getNextVariantGroupProvider(Faker\Generator $faker) 150 | { 151 | $variantGroupProvider = null; 152 | 153 | if (count($this->variantGroupDataProviders) > 0) { 154 | $variantGroupProviderIndex = $faker->numberBetween(0, count($this->variantGroupDataProviders) - 1); 155 | $variantGroupProvider = $this->variantGroupDataProviders[$variantGroupProviderIndex]; 156 | 157 | if ($variantGroupProvider->isLastUsage()) { 158 | array_splice($this->variantGroupDataProviders, $variantGroupProviderIndex, 1); 159 | } 160 | } 161 | 162 | return $variantGroupProvider; 163 | } 164 | 165 | /** 166 | * {@inheritdoc} 167 | */ 168 | public function supports($type) 169 | { 170 | return self::TYPE === $type; 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /Generator/UserGenerator.php: -------------------------------------------------------------------------------- 1 | 22 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 23 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 24 | */ 25 | class UserGenerator implements GeneratorInterface 26 | { 27 | const TYPE = 'users'; 28 | 29 | const USERS_FILENAME = 'users.csv'; 30 | 31 | /** @var CsvWriter */ 32 | protected $writer; 33 | 34 | /** @var ChannelInterface[] */ 35 | protected $channels = []; 36 | 37 | /** @var LocaleInterface[] */ 38 | protected $locales = []; 39 | 40 | /** @var Group[] */ 41 | protected $userGroups = []; 42 | 43 | /** @var RoleInterface[] */ 44 | protected $userRoles = []; 45 | 46 | /** @var string[] */ 47 | protected $assetCategoryCodes = []; 48 | 49 | /** @var CategoryInterface[] */ 50 | protected $categories = []; 51 | 52 | /** @var Generator */ 53 | protected $faker; 54 | 55 | /** 56 | * @param CsvWriter $writer 57 | */ 58 | public function __construct(CsvWriter $writer) 59 | { 60 | $this->writer = $writer; 61 | } 62 | 63 | /** 64 | * {@inheritdoc} 65 | */ 66 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 67 | { 68 | $this->locales = $options['locales']; 69 | $this->channels = $options['channels']; 70 | $this->categories = $options['categories']; 71 | $this->userRoles = $options['user_roles']; 72 | $this->userGroups = $options['user_groups']; 73 | $this->assetCategoryCodes = isset($options['asset_category_codes']) ? $options['asset_category_codes'] : []; 74 | 75 | $this->faker = Factory::create(); 76 | if (isset($globalConfig['seed'])) { 77 | $this->faker->seed($globalConfig['seed']); 78 | } 79 | $users = $this->generateUsers($entitiesConfig); 80 | 81 | $normalizedUsers = $this->normalizeUsers($users); 82 | 83 | $this->writer 84 | ->setFilename(sprintf( 85 | '%s%s%s', 86 | $globalConfig['output_dir'], 87 | DIRECTORY_SEPARATOR, 88 | self::USERS_FILENAME 89 | )) 90 | ->write($normalizedUsers); 91 | 92 | $progress->advance(); 93 | 94 | return ['users' => $users]; 95 | } 96 | 97 | /** 98 | * Generate users objects 99 | * 100 | * @param array $usersConfig 101 | * 102 | * @return UserInterface[] 103 | */ 104 | protected function generateUsers(array $usersConfig) 105 | { 106 | $users = []; 107 | foreach ($usersConfig as $userConfig) { 108 | $user = $this->generateUser($userConfig); 109 | $users[$user->getUsername()] = $user; 110 | } 111 | 112 | return $users; 113 | } 114 | 115 | /** 116 | * Generate a user object from the data provided 117 | * 118 | * @param array $userConfig 119 | * 120 | * @return UserInterface 121 | */ 122 | protected function generateUser(array $userConfig) 123 | { 124 | $user = new User(); 125 | $user->setUsername($userConfig['username']); 126 | $user->setPassword($userConfig['password']); 127 | $user->setEmail($userConfig['email']); 128 | $user->setFirstname($userConfig['firstname']); 129 | $user->setLastname($userConfig['lastname']); 130 | $user->setEnabled($userConfig['enable']); 131 | 132 | foreach ($userConfig['groups'] as $groupCode) { 133 | $user->addGroup($this->userGroups[$groupCode]); 134 | } 135 | 136 | foreach ($userConfig['roles'] as $roleCode) { 137 | $user->addRole($this->userRoles[$roleCode]); 138 | } 139 | 140 | if (isset($userConfig['catalog_locale'])) { 141 | $localeCode = $userConfig['catalog_locale']; 142 | $user->setCatalogLocale($this->locales[$localeCode]); 143 | } else { 144 | $user->setCatalogLocale(reset($this->locales)); 145 | } 146 | 147 | if (isset($userConfig['catalog_scope'])) { 148 | $channelCode = $userConfig['catalog_scope']; 149 | $user->setCatalogScope($this->channels[$channelCode]); 150 | } else { 151 | $user->setCatalogScope(reset($this->channels)); 152 | } 153 | 154 | if (isset($userConfig['default_tree'])) { 155 | $categoryCode = $userConfig['default_tree']; 156 | $user->setDefaultTree($this->categories[$categoryCode]); 157 | } else { 158 | $user->setDefaultTree($this->categories[ChannelGenerator::DEFAULT_TREE]); 159 | } 160 | 161 | return $user; 162 | } 163 | 164 | /** 165 | * Normalize users objects into a structured array 166 | * 167 | * @param UserInterface[] $users 168 | * 169 | * @return array 170 | */ 171 | protected function normalizeUsers(array $users) 172 | { 173 | $normalizedUsers = []; 174 | foreach ($users as $user) { 175 | $normalizedUsers[] = $this->normalizeUser($user); 176 | } 177 | 178 | return $normalizedUsers; 179 | } 180 | 181 | /** 182 | * Normalize user object into a structured array 183 | * 184 | * @param UserInterface $user 185 | * 186 | * @return array 187 | */ 188 | protected function normalizeUser(UserInterface $user) 189 | { 190 | $userGroupCodes = []; 191 | foreach ($user->getGroups() as $userGroup) { 192 | $userGroupCodes[] = $userGroup->getName(); 193 | } 194 | 195 | $userRoleCodes = []; 196 | foreach ($user->getRoles() as $userRole) { 197 | $userRoleCodes[] = $userRole->getRole(); 198 | } 199 | 200 | $result = [ 201 | 'username' => $user->getUsername(), 202 | 'password' => $user->getPassword(), 203 | 'email' => $user->getEmail(), 204 | 'first_name' => $user->getFirstname(), 205 | 'last_name' => $user->getLastname(), 206 | 'catalog_locale' => $user->getCatalogLocale()->getCode(), 207 | 'catalog_scope' => $user->getCatalogScope()->getCode(), 208 | 'default_tree' => $user->getDefaultTree()->getCode(), 209 | 'roles' => implode(',', $userRoleCodes), 210 | 'groups' => implode(',', $userGroupCodes), 211 | 'enabled' => $user->isEnabled() ? '1' : '0', 212 | 'user_locale' => 'en_US', 213 | ]; 214 | 215 | if (count($this->assetCategoryCodes) > 0) { 216 | $result["default_asset_tree"] = $this->faker->randomElement($this->assetCategoryCodes); 217 | } 218 | 219 | return $result; 220 | } 221 | 222 | /** 223 | * {@inheritdoc} 224 | */ 225 | public function supports($type) 226 | { 227 | return self::TYPE === $type; 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /Generator/UserGroupGenerator.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | class UserGroupGenerator implements GeneratorInterface 20 | { 21 | const TYPE = 'user_groups'; 22 | 23 | const GROUPS_FILENAME = 'user_groups.csv'; 24 | 25 | /** @var CsvWriter */ 26 | protected $writer; 27 | 28 | /** 29 | * @param CsvWriter $writer 30 | */ 31 | public function __construct(CsvWriter $writer) 32 | { 33 | $this->writer = $writer; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 40 | { 41 | $groups = $this->generateGroups($entitiesConfig); 42 | 43 | $normalizedGroups = $this->normalizeGroups(array_values($groups)); 44 | 45 | $this->writer 46 | ->setFilename(sprintf( 47 | '%s%s%s', 48 | $globalConfig['output_dir'], 49 | DIRECTORY_SEPARATOR, 50 | self::GROUPS_FILENAME 51 | )) 52 | ->write($normalizedGroups); 53 | 54 | $progress->advance(); 55 | 56 | return ['user_groups' => $groups]; 57 | } 58 | 59 | /** 60 | * Generate groups objects 61 | * 62 | * @param array $groupsConfig 63 | * 64 | * @return GroupInterface[] 65 | */ 66 | protected function generateGroups(array $groupsConfig) 67 | { 68 | $allGroup = $this->generateGroup(['name' => User::GROUP_DEFAULT]); 69 | $groups = [User::GROUP_DEFAULT => $allGroup]; 70 | 71 | foreach ($groupsConfig as $groupConfig) { 72 | $group = $this->generateGroup($groupConfig); 73 | $groups[$group->getName()] = $group; 74 | } 75 | 76 | return $groups; 77 | } 78 | 79 | /** 80 | * Generate a group object from the data provided 81 | * 82 | * @param array $groupConfig 83 | * 84 | * @return Group 85 | */ 86 | protected function generateGroup(array $groupConfig) 87 | { 88 | $group = new Group(); 89 | $group->setName($groupConfig['name']); 90 | 91 | return $group; 92 | } 93 | 94 | /** 95 | * Normalize groups objects into a structured array 96 | * 97 | * @param Group[] $groups 98 | * 99 | * @return array 100 | */ 101 | protected function normalizeGroups(array $groups) 102 | { 103 | $normalizedGroups = []; 104 | foreach ($groups as $group) { 105 | $normalizedGroups[] = $this->normalizeGroup($group); 106 | } 107 | 108 | return $normalizedGroups; 109 | } 110 | 111 | /** 112 | * Normalize group object into a structured array 113 | * 114 | * @param Group $group 115 | * 116 | * @return array 117 | */ 118 | protected function normalizeGroup(Group $group) 119 | { 120 | return ['name' => $group->getName()]; 121 | } 122 | 123 | /** 124 | * {@inheritdoc} 125 | */ 126 | public function supports($type) 127 | { 128 | return self::TYPE === $type; 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /Generator/UserRoleGenerator.php: -------------------------------------------------------------------------------- 1 | 14 | * @copyright 2015 Akeneo SAS (http://www.akeneo.com) 15 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 16 | */ 17 | class UserRoleGenerator implements GeneratorInterface 18 | { 19 | const TYPE = 'user_roles'; 20 | 21 | const ROLES_FILENAME = 'user_roles.csv'; 22 | 23 | /** @var CsvWriter */ 24 | protected $writer; 25 | 26 | /** 27 | * @param CsvWriter $writer 28 | */ 29 | public function __construct(CsvWriter $writer) 30 | { 31 | $this->writer = $writer; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function generate(array $globalConfig, array $entitiesConfig, ProgressBar $progress, array $options = []) 38 | { 39 | $roles = $this->generateRoles($entitiesConfig); 40 | 41 | $normalizedRoles = $this->normalizeRoles($roles); 42 | 43 | $this->writer 44 | ->setFilename(sprintf( 45 | '%s%s%s', 46 | $globalConfig['output_dir'], 47 | DIRECTORY_SEPARATOR, 48 | self::ROLES_FILENAME 49 | )) 50 | ->write($normalizedRoles); 51 | 52 | $progress->advance(); 53 | 54 | return ['user_roles' => $roles]; 55 | } 56 | 57 | /** 58 | * Generate roles objects 59 | * 60 | * @param array $rolesConfig 61 | * 62 | * @return Role[] 63 | */ 64 | protected function generateRoles(array $rolesConfig) 65 | { 66 | foreach ($rolesConfig as $roleKey => $roleConfig) { 67 | $role = $this->generateRole($roleKey, $roleConfig); 68 | $roles[$role->getRole()] = $role; 69 | } 70 | 71 | return $roles; 72 | } 73 | 74 | /** 75 | * Generate a role object from the data provided 76 | * 77 | * @param string $key 78 | * @param array $roleConfig 79 | * 80 | * @return Role 81 | */ 82 | public function generateRole($key, array $roleConfig) 83 | { 84 | $role = new Role(); 85 | $role->setRole($key); 86 | $role->setLabel($roleConfig['label']); 87 | 88 | return $role; 89 | } 90 | 91 | /** 92 | * Normalize roles objects into a structured array 93 | * 94 | * @param Role[] $roles 95 | * 96 | * @return array 97 | */ 98 | public function normalizeRoles(array $roles) 99 | { 100 | $normalizedRoles = []; 101 | 102 | foreach ($roles as $role) { 103 | $normalizedRoles[] = $this->normalizeRole($role); 104 | } 105 | 106 | return $normalizedRoles; 107 | } 108 | 109 | /** 110 | * Normalize role object into a structured array 111 | * 112 | * @param Role $role 113 | * 114 | * @return array 115 | */ 116 | public function normalizeRole(Role $role) 117 | { 118 | return [ 119 | 'label' => $role->getLabel(), 120 | 'role' => $role->getRole(), 121 | ]; 122 | } 123 | 124 | /** 125 | * {@inheritdoc} 126 | */ 127 | public function supports($type) 128 | { 129 | return self::TYPE === $type; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **Description** 2 | 3 | What does this Pull Request do? reference the related issue? 4 | 5 | **Definition Of Done** 6 | 7 | 8 | | Q | A 9 | | --------------------------------- | --- 10 | | Added Specs | 11 | | Generate fixtures and install | 12 | | Generate products and import | 13 | | Review and 2 GTM | 14 | | Tech Doc | 15 | -------------------------------------------------------------------------------- /PimDataGeneratorBundle.php: -------------------------------------------------------------------------------- 1 | 13 | * @copyright 2014 Akeneo SAS (http://www.akeneo.com) 14 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 15 | */ 16 | class PimDataGeneratorBundle extends Bundle 17 | { 18 | /** 19 | * {@inheritdoc} 20 | */ 21 | public function build(ContainerBuilder $container) 22 | { 23 | $container->addCompilerPass(new RegisterGeneratorsPass()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DataGeneratorBundle 2 | =================== 3 | 4 | [![Build Status](https://travis-ci.org/akeneo-labs/DataGeneratorBundle.svg?branch=master)](https://travis-ci.org/akeneo-labs/DataGeneratorBundle) 5 | 6 | This bundle generates file data in the native Akeneo CSV format. 7 | 8 | It's able to generate products and attributes information (including families and attributes options). 9 | 10 | So you need a PIM system with channels, locales and currency already setup. 11 | 12 | From that, this bundle will generate valid product and attribute data. 13 | 14 | Compatibility 15 | ------------- 16 | 17 | This bundle is compatible with Akeneo PIM 1.3, 1.4, 1.5 & 1.6. 18 | 19 | As Akeneo PIM 1.7 exposes a Web API, this Web API can be used to inject data without having to install a bundle in it. 20 | 21 | Here is an example of a [simple command line tool](https://github.com/nidup/akeneo-data-generator) which generates & injects data through the Web API. 22 | 23 | Installation 24 | ------------ 25 | ```bash 26 | $ composer.phar require akeneo-labs/data-generator-bundle ~0.3 27 | ``` 28 | and update your ``app/AppKernel.php`` as follow: 29 | 30 | ```php 31 | $bundles[] = new Pim\Bundle\DataGeneratorBundle\PimDataGeneratorBundle(); 32 | ``` 33 | 34 | How to use it 35 | ------------- 36 | The catalog generation is done in two phases: 37 | 1. generating the catalog fixtures 38 | 2. generating the product CSV import files 39 | 40 | ```bash 41 | Usage: 42 | pim:generate:fixtures 43 | pim:generate:products-file 44 | 45 | Arguments: 46 | configuration-file YAML configuration file 47 | ``` 48 | 49 | 50 | Configuration file examples 51 | --------------------------- 52 | Generating base fixtures: 53 | 54 | ```yaml 55 | data_generator: 56 | output_dir: /tmp/fixtures/ 57 | entities: 58 | attributes: 59 | count: 200 60 | identifier_attribute: "sku" 61 | families: 62 | count: 30 63 | attributes_count: 60 64 | identifier_attribute: "sku" 65 | label_attribute: "label" 66 | ``` 67 | 68 | Generating products: 69 | ```yaml 70 | data_generator: 71 | output_dir: /tmp/ 72 | entities: 73 | products: 74 | count: 1000 75 | filled_attributes_count: 50 76 | filled_attributes_standard_deviation: 10 77 | mandatory_attributes: [sku, name] # properties that will always be filled in with a random value 78 | delimiter: , 79 | force_values: { manufacturer: 'FactoryInc', brand: 'SuperProd' } # properties that if they are filled in, will be filled in the given value 80 | start_index: 0 81 | categories_count: 10 82 | ``` 83 | 84 | More configuration examples are available in the ``Resources\examples`` directory. 85 | 86 | ## Warning 87 | Products data cannot be generated at the same time as the base fixtures (families, categories, attributes, etc...). 88 | Indeed, to generate products data, we use the objects available in the PIM (families, attributes, etc). 89 | 90 | So if you need to generate a full catalog, you need to: 91 | 1. generate the fixtures 92 | 2. copy the minimal data set fixtures into a new fixtures set 93 | 3. copy the generated fixtures into this new set 94 | 4. install the new fixtures set by changing the `installer_data` configuration 95 | 5. generate the products data 96 | 97 | How to use the generated attributes and families data 98 | ----------------------------------------------------- 99 | The generated files are meant to be used in the fixtures. Only the generated products CSV file 100 | must be imported by the import profiles. 101 | 102 | Compatibility 103 | ------------- 104 | This version is only compatible with Akeneo PIM with latest builds. 105 | 106 | Credits 107 | ------- 108 | Thanks @fzaninotto for Faker ! (https://github.com/fzaninotto/Faker) 109 | -------------------------------------------------------------------------------- /Resources/config/locales.csv: -------------------------------------------------------------------------------- 1 | code 2 | af_ZA 3 | am_ET 4 | ar_AE 5 | ar_BH 6 | ar_DZ 7 | ar_EG 8 | ar_IQ 9 | ar_JO 10 | ar_KW 11 | ar_LB 12 | ar_LY 13 | ar_MA 14 | arn_CL 15 | ar_OM 16 | ar_QA 17 | ar_SA 18 | ar_SY 19 | ar_TN 20 | ar_YE 21 | as_IN 22 | az_Cyrl_AZ 23 | az_Latn_AZ 24 | ba_RU 25 | be_BY 26 | bg_BG 27 | bn_BD 28 | bn_IN 29 | bo_CN 30 | br_FR 31 | bs_Cyrl_BA 32 | bs_Latn_BA 33 | ca_ES 34 | co_FR 35 | cs_CZ 36 | cy_GB 37 | da_DK 38 | de_AT 39 | de_CH 40 | de_DE 41 | de_LI 42 | de_LU 43 | dsb_DE 44 | dv_MV 45 | el_GR 46 | en_029 47 | en_AU 48 | en_BZ 49 | en_CA 50 | en_GB 51 | en_IE 52 | en_IN 53 | en_JM 54 | en_MY 55 | en_NZ 56 | en_PH 57 | en_SG 58 | en_TT 59 | en_US 60 | en_ZA 61 | en_ZW 62 | es_AR 63 | es_BO 64 | es_CL 65 | es_CO 66 | es_CR 67 | es_DO 68 | es_EC 69 | es_ES 70 | es_GT 71 | es_HN 72 | es_MX 73 | es_NI 74 | es_PA 75 | es_PE 76 | es_PR 77 | es_PY 78 | es_SV 79 | es_US 80 | es_UY 81 | es_VE 82 | et_EE 83 | eu_ES 84 | fa_IR 85 | fi_FI 86 | fil_PH 87 | fo_FO 88 | fr_BE 89 | fr_CA 90 | fr_CH 91 | fr_FR 92 | fr_LU 93 | fr_MC 94 | fy_NL 95 | ga_IE 96 | gd_GB 97 | gl_ES 98 | gsw_FR 99 | gu_IN 100 | ha_Latn_NG 101 | he_IL 102 | hi_IN 103 | hr_BA 104 | hr_HR 105 | hsb_DE 106 | hu_HU 107 | hy_AM 108 | id_ID 109 | ig_NG 110 | ii_CN 111 | is_IS 112 | it_CH 113 | it_IT 114 | iu_Cans_CA 115 | iu_Latn_CA 116 | ja_JP 117 | ka_GE 118 | kk_KZ 119 | kl_GL 120 | km_KH 121 | kn_IN 122 | kok_IN 123 | ko_KR 124 | ky_KG 125 | lb_LU 126 | lo_LA 127 | lt_LT 128 | lv_LV 129 | mi_NZ 130 | mk_MK 131 | ml_IN 132 | mn_MN 133 | mn_Mong_CN 134 | moh_CA 135 | mr_IN 136 | ms_BN 137 | ms_MY 138 | mt_MT 139 | nb_NO 140 | ne_NP 141 | nl_BE 142 | nl_NL 143 | nn_NO 144 | nso_ZA 145 | oc_FR 146 | or_IN 147 | pa_IN 148 | pl_PL 149 | prs_AF 150 | ps_AF 151 | pt_BR 152 | pt_PT 153 | qut_GT 154 | quz_BO 155 | quz_EC 156 | quz_PE 157 | rm_CH 158 | ro_RO 159 | ru_RU 160 | rw_RW 161 | sah_RU 162 | sa_IN 163 | se_FI 164 | se_NO 165 | se_SE 166 | si_LK 167 | sk_SK 168 | sl_SI 169 | sma_NO 170 | sma_SE 171 | smj_NO 172 | smj_SE 173 | smn_FI 174 | sms_FI 175 | sq_AL 176 | sr_Cyrl_BA 177 | sr_Cyrl_CS 178 | sr_Cyrl_ME 179 | sr_Cyrl_RS 180 | sr_Latn_BA 181 | sr_Latn_CS 182 | sr_Latn_ME 183 | sr_Latn_RS 184 | sv_FI 185 | sv_SE 186 | sw_KE 187 | syr_SY 188 | ta_IN 189 | te_IN 190 | tg_Cyrl_TJ 191 | th_TH 192 | tk_TM 193 | tn_ZA 194 | tr_TR 195 | tt_RU 196 | tzm_Latn_DZ 197 | ug_CN 198 | uk_UA 199 | ur_PK 200 | uz_Cyrl_UZ 201 | uz_Latn_UZ 202 | vi_VN 203 | wo_SN 204 | xh_ZA 205 | yo_NG 206 | zh_CN 207 | zh_HK 208 | zh_MO 209 | zh_SG 210 | zh_TW 211 | zu_ZA 212 | -------------------------------------------------------------------------------- /Resources/config/services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | pim_data_generator.attribute_key_provider: 3 | class: 'Pim\Bundle\DataGeneratorBundle\AttributeKeyProvider' 4 | arguments: 5 | - '@pim_catalog.repository.attribute' 6 | - '@pim_catalog.repository.channel' 7 | - '@pim_catalog.repository.locale' 8 | - '@pim_catalog.repository.currency' 9 | 10 | pim_data_generator.product.product_value_raw_builder: 11 | class: 'Pim\Bundle\DataGeneratorBundle\Generator\Product\ProductValueRawBuilder' 12 | arguments: 13 | - '@pim_data_generator.attribute_key_provider' 14 | 15 | pim_data_generator.product.product_raw_builder: 16 | class: 'Pim\Bundle\DataGeneratorBundle\Generator\Product\ProductRawBuilder' 17 | arguments: 18 | - '@pim_data_generator.product.product_value_raw_builder' 19 | - '@pim_catalog.repository.attribute' 20 | - '@pim_catalog.repository.category' 21 | 22 | pim_data_generator.generator.registry: 23 | class: 'Pim\Bundle\DataGeneratorBundle\Generator\GeneratorRegistry' 24 | 25 | -------------------------------------------------------------------------------- /Resources/config/writers.yml: -------------------------------------------------------------------------------- 1 | services: 2 | pim_data_generator.writer.csv_writer: 3 | class: 'Pim\Bundle\DataGeneratorBundle\Writer\CsvWriter' 4 | -------------------------------------------------------------------------------- /Resources/examples/fixtures.yml: -------------------------------------------------------------------------------- 1 | data_generator: 2 | output_dir: /tmp/fixtures 3 | seed: 20160218 4 | entities: 5 | locales: ~ 6 | group_types: ~ 7 | channels: 8 | ecommerce: 9 | code: ecommerce 10 | label: Ecommerce 11 | locales: 12 | - fr_FR 13 | - en_US 14 | currencies: 15 | - USD 16 | - EUR 17 | print: 18 | code: print 19 | label: Print 20 | locales: 21 | - fr_FR 22 | - de_DE 23 | currencies: 24 | - USD 25 | - GBP 26 | attribute_groups: 27 | count: 10 28 | attributes: 29 | count: 100 30 | identifier_attribute: sku 31 | localizable_probability: 10 32 | scopable_probability: 5 33 | localizable_and_scopable_probability: 2 34 | useable_as_grid_filter_probability: 10 35 | force_attributes: 36 | - name = pim_catalog_text 37 | attribute_options: 38 | count_per_attribute: 10 39 | families: 40 | count: 40 41 | attributes_count: 50 42 | identifier_attribute: sku 43 | label_attribute: name 44 | requirements_count: 5 45 | categories: 46 | delimiter: ; 47 | count: 50 48 | levels: 3 49 | jobs: 50 | product_import: 51 | connector: Akeneo CSV Connector 52 | alias: csv_product_import 53 | label: Product import 54 | type: import 55 | configuration: 56 | uploadAllowed: true 57 | delimiter: ; 58 | enclosure: '"' 59 | escape: '\' 60 | enabled: true 61 | categoriesColumn: categories 62 | familyColumn: family 63 | groupsColumn: groups 64 | realTimeVersioning: true 65 | product_export: 66 | connector: Akeneo CSV Connector 67 | alias: csv_product_export 68 | label: Product export 69 | type: export 70 | configuration: 71 | delimiter: ; 72 | enclosure: '"' 73 | withHeader: true 74 | filePath: /tmp/product.csv 75 | filters: 76 | data: [] 77 | structure: 78 | scope: ecommerce 79 | locales: 80 | - fr_FR 81 | - en_US 82 | user_groups: 83 | it_support: 84 | name: IT support 85 | manager: 86 | name: Manager 87 | user_roles: 88 | ROLE_ADMINISTRATOR: 89 | label: Administrator 90 | users: 91 | - username: admin 92 | password: admin 93 | email: admin@example.com 94 | firstname: Peter 95 | lastname: Doe 96 | roles: [ ROLE_ADMINISTRATOR ] 97 | groups: [ IT support ] 98 | enable: true 99 | variant_groups: 100 | count: 10 101 | axes_count: 3 102 | attributes_count: 3 103 | -------------------------------------------------------------------------------- /Resources/examples/fixtures_extra_large.yml: -------------------------------------------------------------------------------- 1 | data_generator: 2 | output_dir: /tmp/large_100M 3 | seed: 20160430 4 | entities: 5 | group_types: ~ 6 | channels: 7 | ecommerce: 8 | code: ecommerce 9 | label: Ecommerce 10 | locales: 11 | - fr_FR 12 | - en_US 13 | - de_DE 14 | - ru_RU 15 | - it_IT 16 | currencies: 17 | - USD 18 | - EUR 19 | print: 20 | code: print 21 | label: Print 22 | locales: 23 | - fr_FR 24 | - en_US 25 | - de_DE 26 | - ru_RU 27 | - it_IT 28 | currencies: 29 | - USD 30 | - EUR 31 | attribute_groups: 32 | count: 20 33 | attributes: 34 | count: 1000 35 | identifier_attribute: sku 36 | localizable_probability: 2 37 | scopable_probability: 1 38 | localizable_and_scopable_probability: 0.5 39 | useable_as_grid_filter_probability: 10 40 | force_attributes: 41 | - name = pim_catalog_text 42 | attribute_options: 43 | count_per_attribute: 10 44 | families: 45 | count: 400 46 | attributes_count: 100 47 | identifier_attribute: sku 48 | label_attribute: name 49 | requirements_count: 5 50 | categories: 51 | delimiter: ; 52 | count: 4000 53 | levels: 3 54 | jobs: 55 | csv_product_import: 56 | connector: Akeneo CSV Connector 57 | alias: csv_product_import 58 | label: CSV product import 59 | type: import 60 | configuration: 61 | filePath: /tmp/product.csv 62 | uploadAllowed: true 63 | delimiter: ; 64 | enclosure: '"' 65 | escape: '\' 66 | enabled: true 67 | categoriesColumn: categories 68 | familyColumn: family 69 | groupsColumn: groups 70 | realTimeVersioning: true 71 | decimalSeparator: . 72 | dateFormat: yyyy-MM-dd 73 | csv_product_export: 74 | connector: Akeneo CSV Connector 75 | alias: csv_product_export 76 | label: CSV product export 77 | type: export 78 | configuration: 79 | delimiter: ; 80 | enclosure: '"' 81 | withHeader: true 82 | filePath: /tmp/product.csv 83 | filters: 84 | data: [] 85 | structure: 86 | scope: ecommerce 87 | locales: 88 | - fr_FR 89 | - en_US 90 | - de_DE 91 | - ru_RU 92 | - it_IT 93 | user_groups: 94 | it_support: 95 | name: IT support 96 | manager: 97 | name: Manager 98 | user_roles: 99 | ROLE_ADMINISTRATOR: 100 | label: Administrator 101 | users: 102 | - username: admin 103 | password: admin 104 | email: admin@example.com 105 | firstname: Peter 106 | lastname: Doe 107 | roles: [ ROLE_ADMINISTRATOR ] 108 | groups: [ IT support ] 109 | enable: true 110 | variant_groups: 111 | count: 10000 112 | axes_count: 3 113 | attributes_count: 5 114 | -------------------------------------------------------------------------------- /Resources/examples/products.yml: -------------------------------------------------------------------------------- 1 | # With this configuration, product data are generated from existing attributes 2 | # in Akeneo PIM 3 | data_generator: 4 | output_dir: /tmp 5 | seed: 20160218 6 | entities: 7 | products: 8 | filename: product.csv 9 | count: 1000 10 | filled_attributes_count: 50 11 | filled_attributes_standard_deviation: 10 12 | mandatory_attributes: [sku, name] 13 | delimiter: ; 14 | force_values: { manufacturer: 'FactoryInc', brand: 'SuperProd' } 15 | start_index: 0 16 | categories_count: 10 17 | products_per_variant_group: 20 18 | -------------------------------------------------------------------------------- /Resources/examples/products_enterprise.yml: -------------------------------------------------------------------------------- 1 | # With this configuration, product data are generated from existing attributes 2 | # in Akeneo PIM 3 | data_generator: 4 | output_dir: /tmp 5 | seed: 20160218 6 | entities: 7 | products: 8 | filename: product.csv 9 | count: 1000 10 | filled_attributes_count: 50 11 | filled_attributes_standard_deviation: 10 12 | mandatory_attributes: [sku, name] 13 | delimiter: ; 14 | force_values: { manufacturer: 'FactoryInc', brand: 'SuperProd' } 15 | start_index: 0 16 | categories_count: 10 17 | products_per_variant_group: 20 18 | product_drafts: 19 | filename: product_draft.csv 20 | count: 100 21 | filled_attributes_count: 11 22 | filled_attributes_standard_deviation: 3 23 | delimiter: ; 24 | start_index: 0 25 | -------------------------------------------------------------------------------- /Resources/examples/products_extra_large.yml: -------------------------------------------------------------------------------- 1 | # With this configuration, product data are generated from existing attributes 2 | # in Akeneo PIM 3 | data_generator: 4 | output_dir: /tmp/large_100M 5 | seed: 20160430 6 | entities: 7 | products: 8 | filename: products.csv 9 | count: 100000000 10 | filled_attributes_count: 75 11 | filled_attributes_standard_deviation: 10 12 | mandatory_attributes: [sku, name] 13 | percentage_complete: 50 14 | delimiter: ; 15 | force_values: { attr_59: 'Hello world!' } 16 | start_index: 0 17 | categories_count: 4 18 | -------------------------------------------------------------------------------- /Resources/meta/LICENCE: -------------------------------------------------------------------------------- 1 | Akeneo PIM 2 | 3 | The Open Software License version 3.0 4 | 5 | Copyright (c) 2016, Akeneo SAS. 6 | 7 | Full license is at: http://opensource.org/licenses/OSL-3.0 8 | -------------------------------------------------------------------------------- /VariantGroupDataProvider.php: -------------------------------------------------------------------------------- 1 | 16 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 17 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 18 | */ 19 | class VariantGroupDataProvider 20 | { 21 | /** @var GroupInterface */ 22 | protected $variantGroup; 23 | 24 | /** @var int */ 25 | protected $remainingCount; 26 | 27 | /** @var array */ 28 | protected $attributeValues; 29 | 30 | /** 31 | * @param GroupInterface $variantGroup 32 | * @param int $remainingCount 33 | * 34 | * @throws Exception 35 | */ 36 | public function __construct(GroupInterface $variantGroup, $remainingCount) 37 | { 38 | $this->variantGroup = $variantGroup; 39 | $this->remainingCount = $remainingCount; 40 | $this->attributeValues = []; 41 | 42 | $availableCombinations = 1; 43 | /** @var AttributeInterface $attribute */ 44 | foreach ($variantGroup->getAxisAttributes() as $attribute) { 45 | $attributeCode = $attribute->getCode(); 46 | $this->attributeValues[$attributeCode] = []; 47 | 48 | /** @var AttributeOptionInterface $option */ 49 | foreach ($attribute->getOptions() as $option) { 50 | $this->attributeValues[$attributeCode][] = $option->getCode(); 51 | } 52 | $availableCombinations *= count($this->attributeValues[$attributeCode]); 53 | } 54 | 55 | if ($availableCombinations < $remainingCount) { 56 | throw new Exception(sprintf( 57 | 'Variant group %s have only %s value combinations, %s are needed.', 58 | $variantGroup->getLabel(), 59 | $availableCombinations, 60 | $remainingCount 61 | )); 62 | } 63 | } 64 | 65 | /** 66 | * Returns the data for every attribute from the current index. 67 | * For example, with 3 attributes, each having 2 attribute values (0 and 1), it returns: 68 | * 69 | * +-------+---------+---------+---------+ 70 | * | index | index_1 | index_2 | index_3 | 71 | * +-------+---------+---------+---------+ 72 | * | 0 | 0 | 0 | 0 | 73 | * | 1 | 1 | 0 | 0 | 74 | * | 2 | 0 | 1 | 0 | 75 | * | 3 | 1 | 1 | 0 | 76 | * | 4 | 0 | 0 | 1 ... | 77 | * +-------+---------+---------+---------+ 78 | * 79 | * @return array 80 | */ 81 | public function getData() 82 | { 83 | $attributeCodes = array_keys($this->attributeValues); 84 | $data = []; 85 | $multiplier = 1; 86 | 87 | for ($i = 0; $i < count($attributeCodes); $i++) { 88 | $attributeCode = $attributeCodes[$i]; 89 | $valuesCount = count($this->attributeValues[$attributeCode]); 90 | $valueIndex = floor($this->remainingCount/$multiplier) % $valuesCount; 91 | 92 | $data[$attributeCode] = $this->attributeValues[$attributeCode][$valueIndex]; 93 | $multiplier *= $valuesCount; 94 | } 95 | 96 | $this->remainingCount--; 97 | 98 | return $data; 99 | } 100 | 101 | public function isLastUsage() 102 | { 103 | return ($this->remainingCount <= 1); 104 | } 105 | 106 | /** 107 | * @return string 108 | */ 109 | public function getCode() 110 | { 111 | return $this->variantGroup->getCode(); 112 | } 113 | 114 | /** 115 | * @return ArrayCollection 116 | */ 117 | public function getAttributes() 118 | { 119 | return $this->variantGroup->getAxisAttributes(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Writer/CsvWriter.php: -------------------------------------------------------------------------------- 1 | 11 | * @copyright 2016 Akeneo SAS (http://www.akeneo.com) 12 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 13 | */ 14 | class CsvWriter implements ItemWriterInterface 15 | { 16 | /** @var string */ 17 | protected $outputFile; 18 | 19 | /** 20 | * Set filename 21 | * 22 | * @param string $filename 23 | * 24 | * @return CsvWriter 25 | */ 26 | public function setFilename($filename) 27 | { 28 | $this->outputFile = $filename; 29 | 30 | return $this; 31 | } 32 | 33 | /** 34 | * Write the CSV file from products and headers 35 | * 36 | * @param array $data 37 | */ 38 | public function write(array $data) 39 | { 40 | if (0 === count($data)) { 41 | return; 42 | } 43 | 44 | $csvFile = fopen($this->outputFile, 'w'); 45 | 46 | $headers = $this->getHeaders($data); 47 | fputcsv($csvFile, $headers, ';'); 48 | 49 | $headersAsKeys = array_fill_keys($headers, ''); 50 | 51 | foreach ($data as $item) { 52 | $filledItem = array_merge($headersAsKeys, $item); 53 | fputcsv($csvFile, $filledItem, ';'); 54 | } 55 | fclose($csvFile); 56 | } 57 | 58 | /** 59 | * Return the headers for CSV generation. 60 | * 61 | * @param array $data 62 | * 63 | * @return array 64 | */ 65 | protected function getHeaders(array $data) 66 | { 67 | $headers = []; 68 | foreach ($data as $item) { 69 | foreach ($item as $key => $value) { 70 | if (!in_array($key, $headers)) { 71 | $headers[] = $key; 72 | } 73 | } 74 | } 75 | 76 | return $headers; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "akeneo-labs/data-generator-bundle", 3 | "type": "symfony-bundle", 4 | "description": "Akeneo PIM Bundle to generate data in order to test high volume operations", 5 | "keywords": ["pim", "akeneo", "ecommerce", "e-commerce", "data", "performances", "csv"], 6 | "homepage": "http://akeneo.com", 7 | "license": "OSL-3.0", 8 | "authors": [ 9 | { 10 | "name": "Benoit Jacquemont", 11 | "email": "benoit@akeneo.com", 12 | "homepage": "http://www.akeneo.com/" 13 | } 14 | ], 15 | "repositories": [ 16 | { 17 | "type": "vcs", 18 | "url": "https://github.com/akeneo/pim-community-dev.git" 19 | }, 20 | { 21 | "type": "vcs", 22 | "url": "https://github.com/akeneo/platform.git" 23 | } 24 | ], 25 | "require": { 26 | "php": ">=5.4.4", 27 | "fzaninotto/faker": "1.4.0" 28 | }, 29 | "require-dev": { 30 | "akeneo/pim-community-dev": "dev-master@dev", 31 | "friendsofphp/php-cs-fixer": "~1.11", 32 | "phpspec/phpspec": "~2.1" 33 | }, 34 | "config": { 35 | "bin-dir": "bin" 36 | }, 37 | "autoload": { 38 | "psr-0": {"Pim\\Bundle\\DataGeneratorBundle\\": ""} 39 | }, 40 | "minimum-stability": "stable", 41 | "target-dir": "Pim/Bundle/DataGeneratorBundle" 42 | } 43 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/AttributeKeyProviderSpec.php: -------------------------------------------------------------------------------- 1 | findBy(["activated" => 1])->willReturn([$euro, $dollar]); 34 | 35 | $euro->getCode()->willReturn('eur'); 36 | $dollar->getCode()->willReturn('usd'); 37 | 38 | $ecommerceLocales->toArray()->willReturn([$en, $fr, $de]); 39 | $printLocales->toArray()->willReturn([$en]); 40 | 41 | $ecommerce->getLocales()->willReturn($ecommerceLocales); 42 | $print->getLocales()->willReturn($printLocales); 43 | 44 | $localeRepository->findBy(["activated" => 1])->willReturn([$en, $fr, $de]); 45 | 46 | $en->getCode()->willReturn('en_US'); 47 | $fr->getCode()->willReturn('fr_FR'); 48 | $de->getCode()->willReturn('de_DE'); 49 | 50 | $channelRepository->findAll()->willReturn([$ecommerce, $print]); 51 | 52 | $ecommerce->getCode()->willReturn('ecommerce'); 53 | $print->getCode()->willReturn('print'); 54 | 55 | $this->beConstructedWith($attributeRepository, $channelRepository, $localeRepository, $currencyRepository); 56 | } 57 | 58 | function it_provides_keys_for_simple_attribute(AttributeInterface $attribute) 59 | { 60 | $attribute->getCode()->willReturn('attr'); 61 | $attribute->isScopable()->willReturn(false); 62 | $attribute->isLocalizable()->willReturn(false); 63 | $attribute->isLocaleSpecific()->willReturn(false); 64 | $attribute->getBackendType()->willReturn('text'); 65 | 66 | $this->getAttributeKeys($attribute)->shouldReturn([ 67 | 'attr', 68 | ]); 69 | } 70 | 71 | function it_provides_keys_for_scopable_attribute(AttributeInterface $attribute) 72 | { 73 | $attribute->getCode()->willReturn('attr'); 74 | $attribute->isScopable()->willReturn(true); 75 | $attribute->isLocalizable()->willReturn(false); 76 | $attribute->isLocaleSpecific()->willReturn(false); 77 | $attribute->getBackendType()->willReturn('text'); 78 | 79 | $this->getAttributeKeys($attribute)->shouldReturn([ 80 | 'attr-ecommerce', 81 | 'attr-print', 82 | ]); 83 | } 84 | 85 | function it_provides_keys_for_localizable_attribute(AttributeInterface $attribute) 86 | { 87 | $attribute->getCode()->willReturn('attr'); 88 | $attribute->isScopable()->willReturn(false); 89 | $attribute->isLocalizable()->willReturn(true); 90 | $attribute->isLocaleSpecific()->willReturn(false); 91 | $attribute->getBackendType()->willReturn('text'); 92 | 93 | $this->getAttributeKeys($attribute)->shouldReturn([ 94 | 'attr-de_DE', 95 | 'attr-en_US', 96 | 'attr-fr_FR', 97 | ]); 98 | } 99 | 100 | function it_provides_keys_for_scopable_and_localizable_attribute(AttributeInterface $attribute) 101 | { 102 | $attribute->getCode()->willReturn('attr'); 103 | $attribute->isScopable()->willReturn(true); 104 | $attribute->isLocalizable()->willReturn(true); 105 | $attribute->isLocaleSpecific()->willReturn(false); 106 | $attribute->getBackendType()->willReturn('text'); 107 | 108 | $this->getAttributeKeys($attribute)->shouldReturn([ 109 | 'attr-de_DE-ecommerce', 110 | 'attr-en_US-ecommerce', 111 | 'attr-en_US-print', 112 | 'attr-fr_FR-ecommerce', 113 | ]); 114 | } 115 | 116 | function it_provides_keys_for_scopable_metric(AttributeInterface $attribute) 117 | { 118 | $attribute->getCode()->willReturn('attr'); 119 | $attribute->isScopable()->willReturn(true); 120 | $attribute->isLocalizable()->willReturn(false); 121 | $attribute->isLocaleSpecific()->willReturn(false); 122 | $attribute->getBackendType()->willReturn('metric'); 123 | 124 | $this->getAttributeKeys($attribute)->shouldReturn([ 125 | 'attr-ecommerce', 126 | 'attr-ecommerce-unit', 127 | 'attr-print', 128 | 'attr-print-unit', 129 | ]); 130 | } 131 | 132 | function it_provides_keys_for_localizable_prices(AttributeInterface $attribute) 133 | { 134 | $attribute->getCode()->willReturn('attr'); 135 | $attribute->isScopable()->willReturn(false); 136 | $attribute->isLocalizable()->willReturn(true); 137 | $attribute->isLocaleSpecific()->willReturn(false); 138 | $attribute->getBackendType()->willReturn('prices'); 139 | 140 | $this->getAttributeKeys($attribute)->shouldHaveAttributeKeys([ 141 | 'attr-de_DE-eur', 142 | 'attr-de_DE-usd', 143 | 'attr-en_US-eur', 144 | 'attr-en_US-usd', 145 | 'attr-fr_FR-eur', 146 | 'attr-fr_FR-usd', 147 | ]); 148 | } 149 | 150 | function it_provides_keys_for_scopable_and_specific_localizable_prices(AttributeInterface $attribute) 151 | { 152 | $attribute->getCode()->willReturn('attr'); 153 | $attribute->isScopable()->willReturn(true); 154 | $attribute->isLocalizable()->willReturn(true); 155 | $attribute->isLocaleSpecific()->willReturn(true); 156 | $attribute->getLocaleSpecificCodes()->willReturn(['en_US']); 157 | 158 | $attribute->getBackendType()->willReturn('prices'); 159 | 160 | $this->getAttributeKeys($attribute)->shouldHaveAttributeKeys([ 161 | 'attr-en_US-ecommerce-eur', 162 | 'attr-en_US-ecommerce-usd', 163 | 'attr-en_US-print-eur', 164 | 'attr-en_US-print-usd', 165 | ]); 166 | } 167 | 168 | function it_provides_the_keys_of_all_attributes( 169 | $attributeRepository, 170 | AttributeInterface $attribute1, 171 | AttributeInterface $attribute2 172 | ) { 173 | $attributeRepository->findAll()->willReturn([$attribute1, $attribute2]); 174 | 175 | $attribute1->getCode()->willReturn('name'); 176 | $attribute1->isScopable()->willReturn(false); 177 | $attribute1->isLocalizable()->willReturn(false); 178 | $attribute1->isLocaleSpecific()->willReturn(false); 179 | $attribute1->getBackendType()->willReturn('text'); 180 | 181 | $attribute2->getCode()->willReturn('description'); 182 | $attribute2->isScopable()->willReturn(true); 183 | $attribute2->isLocalizable()->willReturn(true); 184 | $attribute2->isLocaleSpecific()->willReturn(false); 185 | $attribute2->getBackendType()->willReturn('text'); 186 | 187 | $this->getAllAttributesKeys()->shouldReturn([ 188 | 'description-de_DE-ecommerce', 189 | 'description-en_US-ecommerce', 190 | 'description-en_US-print', 191 | 'description-fr_FR-ecommerce', 192 | 'name', 193 | ]); 194 | } 195 | 196 | public function getMatchers() 197 | { 198 | return [ 199 | 'haveAttributeKeys' => function ($result, $expected) { 200 | return count($result) && count($expected) && 201 | [] === array_diff($result, $expected) && 202 | [] === array_diff($expected, $result); 203 | }, 204 | ]; 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/DependencyInjection/Compiler/RegisterGeneratorsPassSpec.php: -------------------------------------------------------------------------------- 1 | shouldBeAnInstanceOf('Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface'); 16 | } 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\DependencyInjection\Compiler\RegisterGeneratorsPass'); 21 | } 22 | 23 | function it_register_every_generators(ContainerBuilder $container, Definition $registryDefinition) 24 | { 25 | $container->getDefinition('pim_data_generator.generator.registry')->willReturn($registryDefinition); 26 | $container->findTaggedServiceIds('pim_data_generator.generator')->willReturn([ 27 | 'generator_id' => 'tags', 28 | 'other_generator_id' => 'tags', 29 | ]); 30 | 31 | $registryDefinition->addMethodCall('register', Argument::that(function ($params) { 32 | $check = 33 | $params[0] instanceof Reference && 34 | 'generator_id' === $params[0]->__toString() 35 | ; 36 | return $check; 37 | })); 38 | 39 | $registryDefinition->addMethodCall('register', Argument::that(function ($params) { 40 | $check = 41 | $params[0] instanceof Reference && 42 | 'other_generator_id' === $params[0]->__toString() 43 | ; 44 | return $check; 45 | })); 46 | 47 | $this->process($container); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/DependencyInjection/Configuration/FixtureGeneratorConfigurationSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\DependencyInjection\Configuration\FixtureGeneratorConfiguration'); 13 | } 14 | 15 | function it_is_a_configuration() 16 | { 17 | $this->shouldImplement('Symfony\Component\Config\Definition\ConfigurationInterface'); 18 | } 19 | 20 | function it_has_a_configuration_tree_builder() 21 | { 22 | $this->getConfigTreeBuilder()->shouldHaveType('Symfony\Component\Config\Definition\Builder\TreeBuilder'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/DependencyInjection/Configuration/ProductGeneratorConfigurationSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\DependencyInjection\Configuration\ProductGeneratorConfiguration'); 13 | } 14 | 15 | function it_is_a_configuration() 16 | { 17 | $this->shouldImplement('Symfony\Component\Config\Definition\ConfigurationInterface'); 18 | } 19 | 20 | function it_has_a_configuration_tree_builder() 21 | { 22 | $this->getConfigTreeBuilder()->shouldHaveType('Symfony\Component\Config\Definition\Builder\TreeBuilder'); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/DependencyInjection/PimDataGeneratorExtensionSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\DependencyInjection\PimDataGeneratorExtension'); 14 | } 15 | 16 | function it_is_a_configuration() 17 | { 18 | $this->shouldHaveType('Symfony\Component\HttpKernel\DependencyInjection\Extension'); 19 | } 20 | 21 | function it_load_configuration(ContainerBuilder $container) 22 | { 23 | $this->load([], $container); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/AssetCategoryAccessGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 16 | } 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\AssetCategoryAccessGenerator'); 21 | } 22 | 23 | function it_should_be_a_generator() 24 | { 25 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 26 | } 27 | 28 | function it_should_support_asset_category_accesses() 29 | { 30 | $this->supports('asset_category_accesses')->shouldReturn(true); 31 | $this->supports('yolo')->shouldReturn(false); 32 | } 33 | 34 | function it_should_generate_accesses_for_all_groups( 35 | $writer, 36 | Group $userGroup1, 37 | Group $userGroup2, 38 | Group $userGroupAll, 39 | ProgressBar $progress 40 | ) { 41 | $userGroup1->getName()->willReturn('UserGroup1'); 42 | $userGroup2->getName()->willReturn('UserGroup2'); 43 | $userGroupAll->getName()->willReturn('All'); 44 | 45 | $globalConfig = ['output_dir' => '/']; 46 | $entitiesConfig = []; 47 | $options = [ 48 | 'user_groups' => [ $userGroup1, $userGroup2 ], 49 | 'asset_category_codes' => [ 'code1', 'code2' ] 50 | ]; 51 | 52 | $writer->setFilename(Argument::any())->willReturn($writer); 53 | $writer->write( 54 | [ 55 | [ 56 | 'category' => 'code1', 57 | 'view_items' => 'UserGroup1,UserGroup2', 58 | 'edit_items' => 'UserGroup1,UserGroup2' 59 | ], [ 60 | 'category' => 'code2', 61 | 'view_items' => 'UserGroup1,UserGroup2', 62 | 'edit_items' => 'UserGroup1,UserGroup2' 63 | ] 64 | ] 65 | )->shouldBeCalled(); 66 | 67 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/AssetCategoryGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 16 | } 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\AssetCategoryGenerator'); 21 | } 22 | 23 | function it_is_a_generator() 24 | { 25 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 26 | } 27 | 28 | function it_should_support_asset_category_accesses() 29 | { 30 | $this->supports('asset_categories')->shouldReturn(true); 31 | $this->supports('yolo')->shouldReturn(false); 32 | } 33 | 34 | function it_should_generate_an_asset_category( 35 | $writer, 36 | ProgressBar $progress, 37 | LocaleInterface $locale1, 38 | LocaleInterface $locale2 39 | ) { 40 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 41 | $entitiesConfig = []; 42 | $options = ['locales' => [$locale1, $locale2]]; 43 | $locale1->getCode()->willReturn('fr_FR'); 44 | $locale2->getCode()->willReturn('en_US'); 45 | 46 | $writer->setFilename(Argument::any())->willReturn($writer); 47 | 48 | $writer->write([ 49 | [ 50 | 'code' => 'asset_main_catalog', 51 | 'parent' => '', 52 | 'label-fr_FR' => 'laudantium aut sed', 53 | 'label-en_US' => 'doloribus molestias minima', 54 | ] 55 | ])->shouldBeCalled(); 56 | 57 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/AssociationTypeGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 16 | } 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\AssociationTypeGenerator'); 21 | } 22 | 23 | function it_is_a_generator() 24 | { 25 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 26 | } 27 | 28 | function it_supports_association_types() 29 | { 30 | $this->supports('association_types')->shouldReturn(true); 31 | $this->supports('yolo')->shouldReturn(false); 32 | } 33 | 34 | function it_generates_association_types( 35 | $writer, 36 | ProgressBar $progress, 37 | LocaleInterface $locale1, 38 | LocaleInterface $locale2 39 | ) { 40 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 41 | $entitiesConfig = ['count' => 2]; 42 | $options = ['locales' => [$locale1, $locale2]]; 43 | $locale1->getCode()->willReturn('fr_FR'); 44 | $locale2->getCode()->willReturn('en_US'); 45 | 46 | $writer->setFilename(Argument::any())->willReturn($writer); 47 | 48 | $writer->write([ 49 | [ 50 | 'code' => 'LAUDANTIUM', 51 | 'label-fr_FR' => 'aut', 52 | 'label-en_US' => 'sed' 53 | ], [ 54 | 'code' => 'DOLORIBUS', 55 | 'label-fr_FR' => 'molestias', 56 | 'label-en_US' => 'minima' 57 | ] 58 | ])->shouldBeCalled(); 59 | 60 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/AttributeGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer, $typeRegistry); 20 | } 21 | 22 | function it_is_initializable() 23 | { 24 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\AttributeGenerator'); 25 | } 26 | 27 | function it_is_a_generator() 28 | { 29 | $this->shouldImplement('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 30 | } 31 | 32 | function it_supports_attributes() 33 | { 34 | $this->supports('attributes')->shouldReturn(true); 35 | $this->supports('yolo')->shouldReturn(false); 36 | } 37 | 38 | function it_generates_attributes( 39 | $writer, 40 | $typeRegistry, 41 | ProgressBar $progress, 42 | LocaleInterface $locale1, 43 | LocaleInterface $locale2, 44 | AttributeGroupInterface $attributeGroup1, 45 | AttributeGroupInterface $attributeGroup2 46 | ) { 47 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 48 | $entitiesConfig = [ 49 | 'localizable_probability' => 0, 50 | 'scopable_probability' => 0, 51 | 'localizable_and_scopable_probability' => 0, 52 | 'useable_as_grid_filter_probability' => 0, 53 | 'min_variant_axes' => 0, 54 | 'min_variant_attributes' => 0, 55 | 'identifier_attribute' => 'sku', 56 | 'force_attributes' => [], 57 | 'count' => 1, 58 | ]; 59 | $options = [ 60 | 'locales' => [$locale1, $locale2], 61 | 'attribute_groups' => [ 62 | 'attributeGroup1' => $attributeGroup1, 63 | 'attributeGroup2' => $attributeGroup2, 64 | ], 65 | ]; 66 | 67 | $locale1->getCode()->willReturn('fr_FR'); 68 | $locale2->getCode()->willReturn('en_US'); 69 | $typeRegistry->getAliases()->willReturn(['pim_text']); 70 | 71 | $writer->setFilename(Argument::any())->willReturn($writer); 72 | $writer->write([ 73 | 'sku' => [ 74 | 'code' => 'sku', 75 | 'type' => 'pim_catalog_identifier', 76 | 'group' => 'attributeGroup1', 77 | 'useable_as_grid_filter' => 1, 78 | 'label-fr_FR' => 'identifier veniam dolores', 79 | 'label-en_US' => 'identifier placeat aut' 80 | ], 81 | 'attr_0' => [ 82 | 'code' => 'attr_0', 83 | 'type' => 'pim_text', 84 | 'group' => 'attributeGroup2', 85 | 'localizable' => 0, 86 | 'scopable' => 0, 87 | 'label-fr_FR' => 'pim_text et recusandae', 88 | 'label-en_US' => 'pim_text fugit dolores', 89 | 'useable_as_grid_filter' => 0 90 | ] 91 | ])->shouldBeCalled(); 92 | 93 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/AttributeGroupAccessGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 18 | } 19 | 20 | function it_is_initializable() 21 | { 22 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\AttributeGroupAccessGenerator'); 23 | } 24 | 25 | function it_is_a_generator() 26 | { 27 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 28 | } 29 | 30 | function it_supports_attribute_group_accesses() 31 | { 32 | $this->supports('attribute_group_accesses')->shouldReturn(true); 33 | $this->supports('yolo')->shouldReturn(false); 34 | } 35 | 36 | function it_generates_attribute_group_accesses( 37 | $writer, 38 | ProgressBar $progress, 39 | Group $userGroup1, 40 | Group $userGroup2, 41 | Group $userGroupAll, 42 | AttributeGroupInterface $attributeGroup1, 43 | AttributeGroupInterface $attributeGroup2 44 | ) { 45 | $userGroup1->getName()->willReturn('UserGroup1'); 46 | $userGroup2->getName()->willReturn('UserGroup2'); 47 | $userGroupAll->getName()->willReturn('All'); 48 | $attributeGroup1->getCode()->willReturn('code1'); 49 | $attributeGroup2->getCode()->willReturn('code2'); 50 | 51 | $globalConfig = ['output_dir' => '/']; 52 | $entitiesConfig = []; 53 | $options = [ 54 | 'user_groups' => [ $userGroup1, $userGroup2 ], 55 | 'attribute_groups' => [ $attributeGroup1, $attributeGroup2 ] 56 | ]; 57 | 58 | $writer->setFilename(Argument::any())->willReturn($writer); 59 | $writer->write( 60 | [ 61 | [ 62 | 'attribute_group' => 'code1', 63 | 'view_attributes' => 'UserGroup1,UserGroup2', 64 | 'edit_attributes' => 'UserGroup1,UserGroup2' 65 | ], [ 66 | 'attribute_group' => 'code2', 67 | 'view_attributes' => 'UserGroup1,UserGroup2', 68 | 'edit_attributes' => 'UserGroup1,UserGroup2' 69 | ] 70 | ] 71 | )->shouldBeCalled(); 72 | 73 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/AttributeOptionGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 17 | } 18 | 19 | function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\AttributeOptionGenerator'); 22 | } 23 | 24 | function it_is_a_generator() 25 | { 26 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 27 | } 28 | 29 | function it_supports_attribute_options() 30 | { 31 | $this->supports('attribute_options')->shouldReturn(true); 32 | $this->supports('yolo')->shouldReturn(false); 33 | } 34 | 35 | function it_generate_attribute_options( 36 | $writer, 37 | ProgressBar $progress, 38 | LocaleInterface $locale1, 39 | LocaleInterface $locale2, 40 | AttributeInterface $attributeText, 41 | AttributeInterface $attributeSelect 42 | ) { 43 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 44 | $entitiesConfig = ['count_per_attribute' => 2]; 45 | $options = [ 46 | 'locales' => [$locale1, $locale2], 47 | 'attributes' => [$attributeText, $attributeSelect], 48 | ]; 49 | 50 | $locale1->getCode()->willReturn('fr_FR'); 51 | $locale2->getCode()->willReturn('en_US'); 52 | 53 | $attributeText->getAttributeType()->willReturn('pim_catalog_text'); 54 | $attributeSelect->getAttributeType()->willReturn('pim_catalog_simpleselect'); 55 | $attributeSelect->getCode()->willReturn('code_select'); 56 | 57 | $writer->setFilename(Argument::any())->willReturn($writer); 58 | $writer->write([ 59 | 'attr_opt_code_select0' => [ 60 | 'attribute' => 'code_select', 61 | 'code' => 'attr_opt_code_select0', 62 | 'sort_order' => 1, 63 | 'label-fr_FR' => 'Sed doloribus.', 64 | 'label-en_US' => 'Minima veniam dolores.' 65 | ], 66 | 'attr_opt_code_select1' => [ 67 | 'attribute' => 'code_select', 68 | 'code' => 'attr_opt_code_select1', 69 | 'sort_order' => 2, 70 | 'label-fr_FR' => 'Et recusandae fugit.', 71 | 'label-en_US' => 'Sequi beatae.' 72 | ] 73 | ])->shouldBeCalled(); 74 | 75 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/CategoryGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 16 | } 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\CategoryGenerator'); 21 | } 22 | 23 | function it_is_a_generator() 24 | { 25 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 26 | } 27 | 28 | function it_supports_categories() 29 | { 30 | $this->supports('categories')->shouldReturn(true); 31 | $this->supports('yolo')->shouldReturn(false); 32 | } 33 | 34 | function it_generates_categories( 35 | $writer, 36 | ProgressBar $progress, 37 | LocaleInterface $locale 38 | ) { 39 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 40 | $entitiesConfig = [ 41 | 'count' => 3, 42 | 'levels' => 2, 43 | ]; 44 | $options = ['locales' => [$locale]]; 45 | $locale->getCode()->willReturn('fr_FR'); 46 | 47 | $writer->setFilename(Argument::any())->willReturn($writer); 48 | $writer->write([ 49 | [ 50 | 'code' => 'master', 51 | 'parent' => '', 52 | 'label-fr_FR' => 'Master Catalog', 53 | ], [ 54 | 'code' => 'master_0', 55 | 'parent' => 'master', 56 | 'label-fr_FR' => 'Aut sed.', 57 | ], [ 58 | 'code' => 'master_0_0', 59 | 'parent' => 'master_0', 60 | 'label-fr_FR' => 'Molestias minima veniam.', 61 | ] 62 | ])->shouldBeCalled(); 63 | 64 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/ChainedGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($registry); 16 | } 17 | 18 | function it_is_initializable() 19 | { 20 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\ChainedGenerator'); 21 | } 22 | 23 | function it_should_generate_entities( 24 | $registry, 25 | ProgressBar $progress, 26 | GeneratorInterface $generator1, 27 | GeneratorInterface $generator2 28 | ) { 29 | $globalConfig = [ 30 | 'output_dir' => '/', 31 | 'entities' => [ 32 | 'entity1' => ['configEntity1' => 'valueEntity1'], 33 | 'entity2' => ['configEntity2' => 'valueEntity2'], 34 | ], 35 | ]; 36 | 37 | $registry->getGenerator('entity1')->willReturn($generator1); 38 | $registry->getGenerator('entity2')->willReturn($generator2); 39 | 40 | $generator1 41 | ->generate(['output_dir' => '/'], ['configEntity1' => 'valueEntity1'], $progress, []) 42 | ->shouldBeCalled() 43 | ->willReturn(['entity1' => ['value1']]); 44 | $generator2 45 | ->generate(['output_dir' => '/'], ['configEntity2' => 'valueEntity2'], $progress, ['entity1' => ['value1']]) 46 | ->shouldBeCalled() 47 | ->willReturn([]); 48 | 49 | $this->generate($globalConfig, $progress); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/ChannelGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 15 | } 16 | 17 | function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\ChannelGenerator'); 20 | } 21 | 22 | function it_is_a_generator() 23 | { 24 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 25 | } 26 | 27 | function it_supports_channels() 28 | { 29 | $this->supports('channels')->shouldReturn(true); 30 | $this->supports('yolo')->shouldReturn(false); 31 | } 32 | 33 | function it_generates_channel( 34 | $writer, 35 | ProgressBar $progress 36 | ) { 37 | $globalConfig = ['output_dir' => '/']; 38 | $entitiesConfig = [ 39 | 'ecommerce' => [ 40 | 'code' => 'ecommerce', 41 | 'label' => 'Ecommerce', 42 | 'locales' => ['fr_FR', 'en_US'], 43 | 'currencies' => ['USD', 'EUR'], 44 | ] 45 | ]; 46 | $options = []; 47 | 48 | $writer->setFilename(Argument::any())->willReturn($writer); 49 | $writer->write([ 50 | [ 51 | 'code' => 'USD', 52 | 'activated' => 1 53 | ], [ 54 | 'code' => 'EUR', 55 | 'activated' => 1 56 | ] 57 | ])->shouldBeCalled(); 58 | $writer->write([ 59 | [ 60 | 'code' => 'ecommerce', 61 | 'label' => 'Ecommerce', 62 | 'tree' => 'master', 63 | 'locales' => 'fr_FR,en_US', 64 | 'currencies' => 'USD,EUR' 65 | ] 66 | ])->shouldBeCalled(); 67 | 68 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/FamilyGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 18 | } 19 | 20 | function it_is_initializable() 21 | { 22 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\FamilyGenerator'); 23 | } 24 | 25 | function it_is_a_generator() 26 | { 27 | $this->shouldImplement('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 28 | } 29 | 30 | function it_should_support_families() 31 | { 32 | $this->supports('families')->shouldReturn(true); 33 | $this->supports('yolo')->shouldReturn(false); 34 | } 35 | 36 | function it_should_generate_families( 37 | $writer, 38 | ProgressBar $progress, 39 | LocaleInterface $locale, 40 | AttributeInterface $attribute, 41 | AttributeInterface $attributeFoo, 42 | AttributeInterface $attributeMedia, 43 | ChannelInterface $channel 44 | ) { 45 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 46 | $entitiesConfig = [ 47 | 'count' => 1, 48 | 'attributes_count' => 2, 49 | 'requirements_count' => 2, 50 | 'identifier_attribute' => 'sku', 51 | 'label_attribute' => 'foo', 52 | ]; 53 | $options = [ 54 | 'locales' => [$locale], 55 | 'attributes' => [ 56 | 'attribute1' => $attribute, 57 | 'foo' => $attributeFoo, 58 | 'media' => $attributeMedia, 59 | ], 60 | 'channels' => [$channel], 61 | 'media_attribute_codes' => ['media'], 62 | ]; 63 | $locale->getCode()->willReturn('fr_FR'); 64 | 65 | $writer->setFilename(Argument::any())->willReturn($writer); 66 | 67 | $writer->write([ 68 | 'fam_0' => [ 69 | 'code' => 'fam_0', 70 | 'label-fr_FR' => 'Aut sed.', 71 | 'attribute_as_label' => 'foo', 72 | 'attributes' => 'sku,foo,media', 73 | 'requirements-' => 'sku,foo' 74 | ] 75 | ])->shouldBeCalled(); 76 | 77 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/GroupTypeGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 15 | } 16 | 17 | function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GroupTypeGenerator'); 20 | } 21 | 22 | function it_is_a_generator() 23 | { 24 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 25 | } 26 | 27 | function it_supports_group_types() 28 | { 29 | $this->supports('group_types')->shouldReturn(true); 30 | $this->supports('yolo')->shouldReturn(false); 31 | } 32 | 33 | function it_generates_group_types( 34 | $writer, 35 | ProgressBar $progress 36 | ) { 37 | $globalConfig = ['output_dir' => '/']; 38 | $entitiesConfig = []; 39 | $options = []; 40 | 41 | $writer->setFilename(Argument::any())->willReturn($writer); 42 | 43 | $writer->write([ 44 | ['code' => 'VARIANT', 'is_variant' => 1], 45 | ['code' => 'RELATED', 'is_variant' => 0] 46 | ])->shouldBeCalled(); 47 | 48 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/JobGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\JobGenerator'); 14 | } 15 | 16 | function it_is_a_generator() 17 | { 18 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\JobGenerator'); 19 | } 20 | 21 | function it_supports_jobs() 22 | { 23 | $this->supports('jobs')->shouldReturn(true); 24 | $this->supports('yolo')->shouldReturn(false); 25 | } 26 | 27 | function it_generates_jobs( 28 | ProgressBar $progress 29 | ) { 30 | $globalConfig = ['output_dir' => '/tmp/']; 31 | $entitiesConfig = []; 32 | $options = []; 33 | 34 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/LocaleAccessGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 17 | } 18 | 19 | function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\LocaleAccessGenerator'); 22 | } 23 | 24 | function it_is_a_generator() 25 | { 26 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 27 | } 28 | 29 | function it_supports_locale_accesses() 30 | { 31 | $this->supports('locale_accesses')->shouldReturn(true); 32 | $this->supports('yolo')->shouldReturn(false); 33 | } 34 | 35 | function it_generates_locale_accesses( 36 | $writer, 37 | Group $userGroup1, 38 | Group $userGroup2, 39 | Group $userGroupAll, 40 | LocaleInterface $locale1, 41 | LocaleInterface $locale2, 42 | ProgressBar $progress 43 | ) { 44 | $userGroup1->getName()->willReturn('UserGroup1'); 45 | $userGroup2->getName()->willReturn('UserGroup2'); 46 | $userGroupAll->getName()->willReturn('All'); 47 | $locale1->getCode()->willReturn('fr_FR'); 48 | $locale2->getCode()->willReturn('en_US'); 49 | 50 | $globalConfig = ['output_dir' => '/']; 51 | $entitiesConfig = []; 52 | $options = [ 53 | 'user_groups' => [$userGroup1, $userGroup2], 54 | 'locales' => [$locale1, $locale2], 55 | ]; 56 | 57 | $writer->setFilename(Argument::any())->willReturn($writer); 58 | $writer->write( 59 | [ 60 | [ 61 | 'locale' => 'fr_FR', 62 | 'view_products' => 'UserGroup1,UserGroup2', 63 | 'edit_products' => 'UserGroup1,UserGroup2' 64 | ], [ 65 | 'locale' => 'en_US', 66 | 'view_products' => 'UserGroup1,UserGroup2', 67 | 'edit_products' => 'UserGroup1,UserGroup2' 68 | ] 69 | ] 70 | )->shouldBeCalled(); 71 | 72 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/LocaleGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\LocaleGenerator'); 14 | } 15 | 16 | function it_is_a_generator() 17 | { 18 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 19 | } 20 | 21 | function it_supports_locales() 22 | { 23 | $this->supports('locales')->shouldReturn(true); 24 | $this->supports('yolo')->shouldReturn(false); 25 | } 26 | 27 | function it_generates_locales( 28 | ProgressBar $progress 29 | ) { 30 | $globalConfig = ['output_dir' => '/tmp/']; 31 | $entitiesConfig = []; 32 | $options = []; 33 | 34 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/ProductCategoryAccessGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 17 | } 18 | 19 | function it_is_initializable() 20 | { 21 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\ProductCategoryAccessGenerator'); 22 | } 23 | 24 | function it_is_a_generator() 25 | { 26 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 27 | } 28 | 29 | function it_supports_product_category_accesses() 30 | { 31 | $this->supports('product_category_accesses')->shouldReturn(true); 32 | $this->supports('yolo')->shouldReturn(false); 33 | } 34 | 35 | function it_generates_locale_accesses( 36 | $writer, 37 | Group $userGroup1, 38 | Group $userGroup2, 39 | Group $userGroupAll, 40 | CategoryInterface $category1, 41 | CategoryInterface $category2, 42 | ProgressBar $progress 43 | ) { 44 | $userGroup1->getName()->willReturn('UserGroup1'); 45 | $userGroup2->getName()->willReturn('UserGroup2'); 46 | $userGroupAll->getName()->willReturn('All'); 47 | $category1->getCode()->willReturn('categ1'); 48 | $category2->getCode()->willReturn('categ2'); 49 | 50 | $globalConfig = ['output_dir' => '/']; 51 | $entitiesConfig = []; 52 | $options = [ 53 | 'user_groups' => [$userGroup1, $userGroup2], 54 | 'categories' => [$category1, $category2], 55 | ]; 56 | 57 | $writer->setFilename(Argument::any())->willReturn($writer); 58 | $writer->write( 59 | [ 60 | [ 61 | 'category' => 'categ1', 62 | 'view_items' => 'UserGroup1,UserGroup2', 63 | 'edit_items' => 'UserGroup1,UserGroup2', 64 | 'own_items' => 'UserGroup1,UserGroup2', 65 | ], [ 66 | 'category' => 'categ2', 67 | 'view_items' => 'UserGroup1,UserGroup2', 68 | 'edit_items' => 'UserGroup1,UserGroup2', 69 | 'own_items' => 'UserGroup1,UserGroup2', 70 | ] 71 | ] 72 | )->shouldBeCalled(); 73 | 74 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/ProductDraftGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($rawBuilder, $familyRepo); 19 | } 20 | 21 | function it_is_initializable() 22 | { 23 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\ProductDraftGenerator'); 24 | } 25 | 26 | function it_is_a_generator() 27 | { 28 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 29 | } 30 | 31 | function it_generates_products( 32 | $rawBuilder, 33 | $familyRepo, 34 | ProgressBar $progress, 35 | FamilyInterface $family 36 | ) { 37 | $globalConfig = ['output_dir' => '/tmp/', 'seed' => 123456789]; 38 | $entitiesConfig = [ 39 | 'count' => 1, 40 | 'filled_attributes_count' => 1, 41 | 'filled_attributes_standard_deviation' => 0, 42 | 'start_index' => 0, 43 | 'mandatory_attributes' => [], 44 | 'force_values' => [], 45 | 'delimiter' => ';', 46 | 'filename' => 'product.csv', 47 | ]; 48 | $options = []; 49 | $raw = [ 50 | 'sku' => 'id-0', 51 | 'family' => 'family_code', 52 | 'groups' => '', 53 | ]; 54 | 55 | $familyRepo->findAll()->willReturn([$family]); 56 | $family->getCode()->willReturn('family_code'); 57 | $rawBuilder->buildBaseProduct($family, 'id-0', '')->willReturn($raw); 58 | $rawBuilder->setFakerGenerator(Argument::any())->willReturn(null); 59 | $rawBuilder->fillInRandomCategories($raw, 0)->willReturn(null); 60 | $rawBuilder->fillInRandomAttributes($family, $raw, [], 1, 0)->willReturn(null); 61 | $rawBuilder->fillInMandatoryAttributes($family, $raw, [], [])->willReturn(null); 62 | 63 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/ProductGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($rawBuilder, $familyRepo, $groupRepo, $attributeKeyProvider); 25 | } 26 | 27 | function it_is_initializable() 28 | { 29 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\ProductGenerator'); 30 | } 31 | 32 | function it_is_a_generator() 33 | { 34 | $this->shouldImplement('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 35 | } 36 | 37 | function it_supports_products() 38 | { 39 | $this->supports('products')->shouldReturn(true); 40 | $this->supports('yolo')->shouldReturn(false); 41 | } 42 | 43 | function it_generates_products( 44 | $rawBuilder, 45 | $familyRepo, 46 | ProgressBar $progress, 47 | FamilyInterface $family 48 | ) { 49 | $globalConfig = ['output_dir' => '/tmp/', 'seed' => 123456789]; 50 | $entitiesConfig = [ 51 | 'count' => 1, 52 | 'filled_attributes_count' => 1, 53 | 'filled_attributes_standard_deviation' => 0, 54 | 'start_index' => 0, 55 | 'categories_count' => 0, 56 | 'products_per_variant_group' => 0, 57 | 'mandatory_attributes' => [], 58 | 'force_values' => [], 59 | 'percentage_complete' => 0, 60 | 'filename' => 'product_draft.csv', 61 | 'delimiter' => ';', 62 | 'all_attribute_keys' => false 63 | ]; 64 | $options = []; 65 | $raw = [ 66 | 'sku' => 'id-0', 67 | 'family' => 'family_code', 68 | 'groups' => '', 69 | ]; 70 | 71 | $familyRepo->findAll()->willReturn([$family]); 72 | $family->getCode()->willReturn('family_code'); 73 | $rawBuilder->buildBaseProduct($family, 'id-0', '')->willReturn($raw); 74 | $rawBuilder->setFakerGenerator(Argument::any())->willReturn(null); 75 | $rawBuilder->fillInRandomCategories($raw, 0)->willReturn(null); 76 | $rawBuilder->fillInRandomAttributes($family, $raw, [], 1, 0)->willReturn(null); 77 | $rawBuilder->fillInMandatoryAttributes($family, $raw, [], [])->willReturn(null); 78 | 79 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 80 | } 81 | 82 | function it_generates_products_with_all_attribute_keys( 83 | $rawBuilder, 84 | $familyRepo, 85 | $attributeKeyProvider, 86 | ProgressBar $progress, 87 | FamilyInterface $family 88 | ) { 89 | $globalConfig = ['output_dir' => '/tmp/', 'seed' => 123456789]; 90 | $entitiesConfig = [ 91 | 'count' => 1, 92 | 'filled_attributes_count' => 1, 93 | 'filled_attributes_standard_deviation' => 0, 94 | 'start_index' => 0, 95 | 'categories_count' => 0, 96 | 'products_per_variant_group' => 0, 97 | 'mandatory_attributes' => [], 98 | 'force_values' => [], 99 | 'percentage_complete' => 0, 100 | 'filename' => 'product_draft.csv', 101 | 'delimiter' => ';', 102 | 'all_attribute_keys' => true 103 | ]; 104 | $options = []; 105 | $raw = [ 106 | 'sku' => 'id-0', 107 | 'family' => 'family_code', 108 | 'groups' => '', 109 | ]; 110 | 111 | $familyRepo->findAll()->willReturn([$family]); 112 | $family->getCode()->willReturn('family_code'); 113 | $rawBuilder->buildBaseProduct($family, 'id-0', '')->willReturn($raw); 114 | $rawBuilder->setFakerGenerator(Argument::any())->willReturn(null); 115 | $rawBuilder->fillInRandomCategories($raw, 0)->willReturn(null); 116 | $rawBuilder->fillInRandomAttributes($family, $raw, [], 1, 0)->willReturn(null); 117 | $rawBuilder->fillInMandatoryAttributes($family, $raw, [], [])->willReturn(null); 118 | $attributeKeyProvider->getAllAttributesKeys()->shouldBeCalled()->willReturn([]); 119 | 120 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/UserGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 22 | } 23 | 24 | function it_is_initializable() 25 | { 26 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\UserGenerator'); 27 | } 28 | 29 | function it_is_a_generator() 30 | { 31 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 32 | } 33 | 34 | function it_supports_users() 35 | { 36 | $this->supports('users')->shouldReturn(true); 37 | $this->supports('yolo')->shouldReturn(false); 38 | } 39 | 40 | function it_generates_users( 41 | $writer, 42 | ProgressBar $progress, 43 | LocaleInterface $locale, 44 | ChannelInterface $channel, 45 | CategoryInterface $categoryMaster, 46 | Role $roleAdministrator, 47 | Group $groupItSupport, 48 | Collection $rolesCollection 49 | ) { 50 | $globalOptions = ['output_dir' => '/']; 51 | $options = [ 52 | 'locales' => [$locale], 53 | 'channels' => [$channel], 54 | 'categories' => ['master' => $categoryMaster], 55 | 'user_roles' => ['ROLE_ADMINISTRATOR' => $roleAdministrator], 56 | 'user_groups' => ['IT support' => $groupItSupport], 57 | ]; 58 | $entitiesConfig = [ 59 | [ 60 | 'username' => 'admin', 61 | 'password' => 'admin', 62 | 'email' => 'admin@example.com', 63 | 'firstname' => 'Peter', 64 | 'lastname' => 'Doe', 65 | 'roles' => [ 'ROLE_ADMINISTRATOR' ], 66 | 'groups' => [ 'IT support' ], 67 | 'enable' => true, 68 | ] 69 | ]; 70 | $groupItSupport->getName()->willReturn('IT Support'); 71 | $groupItSupport->getRoles()->willReturn($rolesCollection); 72 | $rolesCollection->toArray()->willReturn([$roleAdministrator]); 73 | $categoryMaster->getCode()->willReturn('Master'); 74 | $locale->getCode()->willReturn('fr_FR'); 75 | $channel->getCode()->willReturn('Channel'); 76 | $roleAdministrator->getRole()->willReturn('ROLE_ADMINISTRATOR'); 77 | 78 | $writer->setFilename(Argument::any())->willReturn($writer); 79 | 80 | $writer->write([ 81 | [ 82 | 'username' => 'admin', 83 | 'password' => 'admin', 84 | 'email' => 'admin@example.com', 85 | 'first_name' => 'Peter', 86 | 'last_name' => 'Doe', 87 | 'catalog_locale' => 'fr_FR', 88 | 'catalog_scope' => 'Channel', 89 | 'default_tree' => 'Master', 90 | 'roles' => 'ROLE_ADMINISTRATOR', 91 | 'groups' => 'IT Support', 92 | 'enabled' => '1', 93 | 'user_locale' => 'en_US' 94 | ] 95 | ])->shouldBeCalled(); 96 | 97 | $this->generate($globalOptions, $entitiesConfig, $progress, $options); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/UserGroupGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 15 | } 16 | 17 | function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\UserGroupGenerator'); 20 | } 21 | 22 | function it_is_a_generator() 23 | { 24 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 25 | } 26 | 27 | function it_supports_user_groups() 28 | { 29 | $this->supports('user_groups')->shouldReturn(true); 30 | $this->supports('yolo')->shouldReturn(false); 31 | } 32 | 33 | function it_generates_user_groups( 34 | $writer, 35 | ProgressBar $progress 36 | ) { 37 | $globalConfig = ['output_dir' => '/']; 38 | $entitiesConfig = [['name' => 'Group']]; 39 | $config = []; 40 | 41 | $writer->setFilename(Argument::any())->willReturn($writer); 42 | $writer->write([ 43 | ['name' => 'All'], 44 | ['name' => 'Group'] 45 | ])->shouldBeCalled(); 46 | 47 | $this->generate($globalConfig, $entitiesConfig, $progress, $config); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/UserRoleGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 15 | } 16 | 17 | function it_is_initializable() 18 | { 19 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\UserRoleGenerator'); 20 | } 21 | 22 | function it_is_a_generator() 23 | { 24 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 25 | } 26 | 27 | function it_supports_user_roles() 28 | { 29 | $this->supports('user_roles')->shouldReturn(true); 30 | $this->supports('yolo')->shouldReturn(false); 31 | } 32 | 33 | function it_generates_user_roles( 34 | $writer, 35 | ProgressBar $progress 36 | ) { 37 | $globalConfig = ['output_dir' => '/']; 38 | $entitiesConfig = [ 39 | 'ROLE_ADMINISTRATOR' => ['label' => 'Administrator'], 40 | 'ROLE_REDACTOR' => ['label' => 'Redactor'], 41 | ]; 42 | $options = []; 43 | 44 | $writer->setFilename(Argument::any())->willReturn($writer); 45 | 46 | $writer->write([ 47 | ['label' => 'Administrator', 'role' => 'ROLE_ADMINISTRATOR'], 48 | ['label' => 'Redactor', 'role' => 'ROLE_REDACTOR'] 49 | ])->shouldBeCalled(); 50 | 51 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Generator/VariantGroupGeneratorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($writer); 18 | } 19 | 20 | function it_is_initializable() 21 | { 22 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\VariantGroupGenerator'); 23 | } 24 | 25 | function it_is_a_generator() 26 | { 27 | $this->shouldHaveType('Pim\Bundle\DataGeneratorBundle\Generator\GeneratorInterface'); 28 | } 29 | 30 | function it_supports_variant_groups() 31 | { 32 | $this->supports('variant_groups')->shouldReturn(true); 33 | $this->supports('yolo')->shouldReturn(false); 34 | } 35 | 36 | function it_generates_variant_groups( 37 | $writer, 38 | ProgressBar $progress, 39 | AttributeInterface $axeAttribute, 40 | AttributeInterface $availableAttribute, 41 | LocaleInterface $locale, 42 | GroupTypeInterface $variantGroupType 43 | ) { 44 | $globalConfig = ['output_dir' => '/', 'seed' => 123456789]; 45 | $entitiesConfig = [ 46 | 'count' => 1, 47 | 'axes_count' => 1, 48 | 'attributes_count' => 1 49 | ]; 50 | $options = [ 51 | 'attributes' => [$axeAttribute, $availableAttribute], 52 | 'locales' => [$locale], 53 | 'group_types' => [$variantGroupType], 54 | ]; 55 | 56 | $variantGroupType->getCode()->willReturn('VARIANT'); 57 | $axeAttribute->getAttributeType()->willReturn('pim_catalog_simpleselect'); 58 | $axeAttribute->isLocalizable()->willReturn(false); 59 | $axeAttribute->isScopable()->willReturn(false); 60 | $availableAttribute->getAttributeType()->willReturn('pim_catalog_text'); 61 | $availableAttribute->isLocalizable()->willReturn(false); 62 | $availableAttribute->isScopable()->willReturn(false); 63 | $locale->getCode()->willReturn('fr_FR'); 64 | $axeAttribute->getCode()->willReturn('Axe Attribute'); 65 | $availableAttribute->getCode()->willReturn('Available Attribute'); 66 | 67 | $writer->setFilename(Argument::any())->willReturn($writer); 68 | $writer->write([ 69 | [ 70 | 'code' => 'variant_group_0', 71 | 'axis' => 'Axe Attribute', 72 | 'type' => 'VARIANT', 73 | 'label-fr_FR' => 'molestias', 74 | 'Available Attribute' => 'aut sed doloribus' 75 | ] 76 | ])->shouldBeCalled(); 77 | 78 | $this->generate($globalConfig, $entitiesConfig, $progress, $options); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/PimDataGeneratorBundleSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\PimDataGeneratorBundle'); 14 | } 15 | 16 | function it_is_a_bundle() 17 | { 18 | $this->shouldHaveType('Symfony\Component\HttpKernel\Bundle\Bundle'); 19 | } 20 | 21 | function it_builds(ContainerBuilder $container) 22 | { 23 | $container->addCompilerPass( 24 | Argument::type('Pim\Bundle\DataGeneratorBundle\DependencyInjection\Compiler\RegisterGeneratorsPass') 25 | )->shouldBeCalled(); 26 | 27 | $this->build($container); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /spec/Pim/Bundle/DataGeneratorBundle/Writer/CsvWriterSpec.php: -------------------------------------------------------------------------------- 1 | shouldHaveType('Pim\Bundle\DataGeneratorBundle\Writer\CsvWriter'); 13 | } 14 | 15 | function it_is_a_writer() 16 | { 17 | $this->shouldImplement('Akeneo\Component\Batch\Item\ItemWriterInterface'); 18 | } 19 | 20 | function it_has_a_filename() 21 | { 22 | $this->setFileName('filename.csv')->shouldReturn($this); 23 | } 24 | 25 | function it_writes_a_csv_filename() 26 | { 27 | $file = '/tmp/filename.csv'; 28 | $this->setFileName($file); 29 | 30 | $this->write([ 31 | [ 32 | 'column' => 'value', 33 | 'other_column' => 'other_value', 34 | ] 35 | ]); 36 | 37 | assert(is_file($file), 'Impossible to generate the csv file'); 38 | } 39 | } 40 | --------------------------------------------------------------------------------