/** * {@inheritdoc} * * @SuppressWarnings(PHPMD.NPathComplexity) */ public function preUpdate() { $enumConfigProvider = $this->configManager->getProvider('enum'); $extendConfigProvider = $this->configManager->getProvider('extend'); $entityConfigs = $extendConfigProvider->getConfigs(); foreach ($entityConfigs as $entityConfig) { if (!$entityConfig->is('is_extend')) { continue; } $fieldConfigs = $extendConfigProvider->getConfigs($entityConfig->getId()->getClassName()); foreach ($fieldConfigs as $fieldConfig) { if (!$fieldConfig->in('state', [ExtendScope::STATE_NEW, ExtendScope::STATE_UPDATE])) { continue; } /** @var FieldConfigId $fieldConfigId */ $fieldConfigId = $fieldConfig->getId(); $fieldType = $fieldConfigId->getFieldType(); if (!in_array($fieldType, ['enum', 'multiEnum'])) { continue; } // prepare input parameters $fieldOptions = []; $enumFieldConfig = $enumConfigProvider->getConfig($fieldConfigId->getClassName(), $fieldConfigId->getFieldName()); $enumCode = $enumFieldConfig->get('enum_code'); $enumName = $enumFieldConfig->get('enum_name'); $isPublic = $enumFieldConfig->get('enum_public'); if (empty($enumCode) && $isPublic && empty($enumName)) { throw new \LogicException(sprintf('Both "enum_code" and "enum_name" cannot be empty for a public enum. Field: %s::%s.', $fieldConfigId->getClassName(), $fieldConfigId->getFieldName())); } if (empty($enumCode)) { $enumCode = $enumName !== null ? ExtendHelper::buildEnumCode($enumName) : ExtendHelper::generateEnumCode($fieldConfigId->getClassName(), $fieldConfigId->getFieldName()); $fieldOptions['enum']['enum_code'] = $enumCode; } $isMultiple = $this->fieldTypeHelper->getUnderlyingType($fieldType) === RelationType::MANY_TO_MANY; $enumValueClassName = ExtendHelper::buildEnumValueClassName($enumCode); // create an entity is used to store enum values $this->createEnumValueConfigEntityModel($enumValueClassName, $enumCode, $isMultiple, $isPublic); // create a relation if ($isMultiple) { $fieldOptions['extend']['without_default'] = true; $this->relationBuilder->addManyToManyRelation($entityConfig, $enumValueClassName, $fieldConfigId->getFieldName(), ['name'], ['name'], ['name'], $fieldOptions, $fieldType); } else { $this->relationBuilder->addManyToOneRelation($entityConfig, $enumValueClassName, $fieldConfigId->getFieldName(), 'name', $fieldOptions, $fieldType); } } } }
/** * Post submit event handler * * @param FormEvent $event * * @SuppressWarnings(PHPMD.NPathComplexity) */ public function postSubmit(FormEvent $event) { $form = $event->getForm(); $configModel = $form->getConfig()->getOption('config_model'); if (!$configModel instanceof FieldConfigModel) { return; } if (!in_array($configModel->getType(), ['enum', 'multiEnum'])) { return; } if (!$form->isValid()) { return; } $data = $event->getData(); $enumConfig = $configModel->toArray('enum'); $enumName = $this->getValue($data['enum'], 'enum_name'); $enumCode = $this->getValue($enumConfig, 'enum_code'); if (empty($enumCode)) { $enumCode = $enumName !== null ? ExtendHelper::buildEnumCode($enumName) : ExtendHelper::generateEnumCode($configModel->getEntity()->getClassName(), $configModel->getFieldName()); } $locale = $this->translator->getLocale(); $enumValueClassName = ExtendHelper::buildEnumValueClassName($enumCode); $enumConfigProvider = $this->configManager->getProvider('enum'); if ($enumConfigProvider->hasConfig($enumValueClassName)) { // existing enum if ($configModel->getId()) { if ($enumName !== null) { $this->enumSynchronizer->applyEnumNameTrans($enumCode, $enumName, $locale); } $enumOptions = $this->getValue($data['enum'], 'enum_options'); if ($enumOptions !== null) { $this->enumSynchronizer->applyEnumOptions($enumValueClassName, $enumOptions, $locale); } $enumPublic = $this->getValue($data['enum'], 'enum_public'); if ($enumPublic !== null) { $this->enumSynchronizer->applyEnumEntityOptions($enumValueClassName, $enumPublic); } } unset($data['enum']['enum_name']); unset($data['enum']['enum_options']); unset($data['enum']['enum_public']); $event->setData($data); } else { // new enum $this->sortOptions($data['enum']['enum_options']); $data['enum']['enum_locale'] = $locale; $event->setData($data); } }
/** * @param string $entityClassName * @param string $fieldName * @param string[] $existingEnumTables * * @return string */ protected function buildEnumCode($entityClassName, $fieldName, $existingEnumTables) { $nameGenerator = $this->extendExtension->getNameGenerator(); $enumCode = ExtendHelper::generateEnumCode($entityClassName, $fieldName, $nameGenerator->getMaxEnumCodeSize()); // check if an enum with that code is already exist and generate new code if so while (in_array($nameGenerator->generateEnumTableName($enumCode), $existingEnumTables, true)) { $enumCode = sprintf('enum_%s_%s', dechex(crc32(ExtendHelper::getShortClassName($entityClassName))), dechex(crc32(microtime()))); } return $enumCode; }
/** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function testPreUpdateForNewEnumWithLongEnumCode() { $entityConfig1 = new Config(new EntityConfigId('extend', 'Test\\EnumValue1')); $entityConfig1->set('is_extend', true); $fieldConfig1 = new Config(new FieldConfigId('extend', 'Test\\EnumValue1', 'field1', 'enum')); $fieldConfig1->set('state', ExtendScope::STATE_NEW); $enumFieldConfig1 = new Config(new FieldConfigId('enum', 'Test\\EnumValue1', 'field1', 'enum')); $entityConfigs = [$entityConfig1]; $fieldConfigs = [$fieldConfig1]; $enumCode1 = ExtendHelper::generateEnumCode('Test\\EnumValue1', 'field1'); $enumValueClassName1 = ExtendHelper::buildEnumValueClassName($enumCode1); $extendConfigProvider = $this->getMockBuilder('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProvider')->disableOriginalConstructor()->getMock(); $enumConfigProvider = $this->getMockBuilder('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProvider')->disableOriginalConstructor()->getMock(); $this->configManager->expects($this->any())->method('getProvider')->will($this->returnValueMap([['extend', $extendConfigProvider], ['enum', $enumConfigProvider]])); $extendConfigProvider->expects($this->at(0))->method('getConfigs')->will($this->returnValue($entityConfigs)); $extendConfigProvider->expects($this->at(1))->method('getConfigs')->with($entityConfig1->getId()->getClassName())->will($this->returnValue($fieldConfigs)); $enumConfigProvider->expects($this->at(0))->method('getConfig')->with($entityConfig1->getId()->getClassName(), 'field1')->will($this->returnValue($enumFieldConfig1)); $this->configManager->expects($this->once())->method('hasConfigEntityModel')->will($this->returnValueMap([[$enumValueClassName1, false]])); $configManagerAt = 3; $this->configManager->expects($this->at($configManagerAt++))->method('createConfigEntityModel')->with($enumValueClassName1, ConfigModelManager::MODE_HIDDEN); $relationBuilderAt = 0; $this->relationBuilder->expects($this->at($relationBuilderAt++))->method('updateEntityConfigs')->with($enumValueClassName1, ['entity' => ['label' => ExtendHelper::getEnumTranslationKey('label', $enumCode1), 'plural_label' => ExtendHelper::getEnumTranslationKey('plural_label', $enumCode1), 'description' => ExtendHelper::getEnumTranslationKey('description', $enumCode1)], 'extend' => ['owner' => ExtendScope::OWNER_SYSTEM, 'is_extend' => true, 'table' => $this->nameGenerator->generateEnumTableName($enumCode1, true), 'inherit' => ExtendHelper::BASE_ENUM_VALUE_CLASS], 'enum' => ['code' => $enumCode1, 'public' => false, 'multiple' => false]]); $this->setAddEnumValueEntityFieldsExpectations($enumValueClassName1, $enumCode1, $configManagerAt, $relationBuilderAt); $this->relationBuilder->expects($this->at($relationBuilderAt++))->method('addManyToOneRelation')->with($this->identicalTo($entityConfig1), $enumValueClassName1, 'field1', 'name', ['enum' => ['enum_code' => $enumCode1]], 'enum'); $this->extension->preUpdate(); }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage $fieldName must not be empty. */ public function testGenerateEnumCodeForEmptyFieldName() { ExtendHelper::generateEnumCode('Test\\Entity', ''); }
/** * @dataProvider enumTypeProvider */ public function testPostSubmitForNewEnumWithoutNameAndPublic($dataType) { $entityClassName = 'Test\\Entity'; $fieldName = 'testField'; $enumCode = ExtendHelper::generateEnumCode($entityClassName, $fieldName); $enumValueClassName = ExtendHelper::buildEnumValueClassName($enumCode); $locale = 'fr'; $entityConfigModel = $this->getMockBuilder('Oro\\Bundle\\EntityConfigBundle\\Entity\\EntityConfigModel')->disableOriginalConstructor()->getMock(); $entityConfigModel->expects($this->once())->method('getClassName')->will($this->returnValue($entityClassName)); $configModel = $this->getMockBuilder('Oro\\Bundle\\EntityConfigBundle\\Entity\\FieldConfigModel')->disableOriginalConstructor()->getMock(); $configModel->expects($this->never())->method('getId'); $configModel->expects($this->once())->method('getType')->will($this->returnValue($dataType)); $configModel->expects($this->once())->method('getEntity')->will($this->returnValue($entityConfigModel)); $configModel->expects($this->once())->method('getFieldName')->will($this->returnValue($fieldName)); $form = $this->getMock('Symfony\\Component\\Form\\Test\\FormInterface'); $form->expects($this->once())->method('isValid')->will($this->returnValue(true)); $event = $this->getFormEventMock($configModel, $form); $enumOptions = [['id' => 'val1', 'label' => 'Value 1', 'priority' => 1]]; $submittedData = ['enum' => ['enum_options' => $enumOptions]]; $expectedData = ['enum' => ['enum_options' => $enumOptions, 'enum_locale' => $locale]]; $event->expects($this->once())->method('getData')->will($this->returnValue($submittedData)); $configModel->expects($this->once())->method('toArray')->with('enum')->will($this->returnValue([])); $this->translator->expects($this->once())->method('getLocale')->will($this->returnValue($locale)); $enumConfigProvider = $this->getConfigProviderMock(); $this->configManager->expects($this->once())->method('getProvider')->with('enum')->will($this->returnValue($enumConfigProvider)); $enumConfigProvider->expects($this->once())->method('hasConfig')->with($enumValueClassName)->will($this->returnValue(false)); $event->expects($this->once())->method('setData')->with($expectedData); $this->extension->postSubmit($event); }