/** * @param ConfigInterface $extendConfig * * @return bool */ protected function updateStateValues(ConfigInterface $extendConfig) { $hasChanges = false; $extendProvider = $this->em->getExtendConfigProvider(); $className = $extendConfig->getId()->getClassName(); $fieldConfigs = $extendProvider->getConfigs($className, true); if ($extendConfig->is('state', ExtendScope::STATE_DELETE)) { // mark entity as deleted if (!$extendConfig->is('is_deleted')) { $extendConfig->set('is_deleted', true); $extendProvider->persist($extendConfig); $hasChanges = true; } // mark all fields as deleted foreach ($fieldConfigs as $fieldConfig) { if (!$fieldConfig->is('is_deleted')) { $fieldConfig->set('is_deleted', true); $extendProvider->persist($fieldConfig); $hasChanges = true; } } } elseif (!$extendConfig->is('state', ExtendScope::STATE_ACTIVE)) { $hasNotActiveFields = false; foreach ($fieldConfigs as $fieldConfig) { if (!$fieldConfig->is('state', ExtendScope::STATE_DELETE) && !$fieldConfig->is('state', ExtendScope::STATE_ACTIVE)) { $hasNotActiveFields = true; break; } } // Set entity state to active if all fields are active or deleted if (!$hasNotActiveFields) { $extendConfig->set('state', ExtendScope::STATE_ACTIVE); $extendProvider->persist($extendConfig); } $hasChanges = true; } if ($hasChanges) { $extendProvider->flush(); } }
/** * @param ConfigProvider $provider * @param ConfigInterface $config * @param array $data * @param string $state * @return array */ protected function processData(ConfigProvider $provider, ConfigInterface $config, array $data, $state) { if ($provider->getScope() === 'enum' && $config->get('enum_code')) { return []; } $translatable = $provider->getPropertyConfig()->getTranslatableValues($config->getId()); $translations = []; foreach ($data as $code => $value) { if (in_array($code, $translatable, true)) { // check if a label text was changed $labelKey = $config->get($code); if ($state === ExtendScope::STATE_NEW || !$this->translationHelper->isTranslationEqual($labelKey, $value)) { $translations[$labelKey] = $value; } // replace label text with label name in $value variable $value = $labelKey; } $config->set($code, $value); } $this->configManager->persist($config); return $translations; }
/** * @param ConfigInterface $extendConfig * * @return bool */ protected function checkState(ConfigInterface $extendConfig) { $hasChanges = false; $extendProvider = $this->em->getExtendConfigProvider(); $className = $extendConfig->getId()->getClassName(); if ($extendConfig->is('state', ExtendScope::STATE_DELETE)) { // mark entity as deleted if (!$extendConfig->is('is_deleted')) { $extendConfig->set('is_deleted', true); $extendProvider->persist($extendConfig); $hasChanges = true; } // mark all fields as deleted $fieldConfigs = $extendProvider->getConfigs($className, true); foreach ($fieldConfigs as $fieldConfig) { if (!$fieldConfig->is('is_deleted')) { $fieldConfig->set('is_deleted', true); $extendProvider->persist($fieldConfig); $hasChanges = true; } } } elseif (!$extendConfig->is('state', ExtendScope::STATE_ACTIVE)) { $extendConfig->set('state', ExtendScope::STATE_ACTIVE); $extendProvider->persist($extendConfig); $hasChanges = true; } return $hasChanges; }
/** * @param ConfigInterface $fieldConfig */ protected function createSelfRelation(ConfigInterface $fieldConfig) { /** @var FieldConfigId $fieldConfigId */ $fieldConfigId = $fieldConfig->getId(); $targetEntityClass = $fieldConfig->get('target_entity'); $selfFieldId = new FieldConfigId('extend', $fieldConfigId->getClassName(), $fieldConfigId->getFieldName(), $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType())); $selfConfig = $this->extendConfigProvider->getConfig($selfFieldId->getClassName()); $relationKey = ExtendHelper::buildRelationKey($selfFieldId->getClassName(), $selfFieldId->getFieldName(), $selfFieldId->getFieldType(), $targetEntityClass); /** * in case of oneToMany relation * automatically create target field (type: manyToOne) */ $targetFieldId = false; $owner = true; $targetOwner = false; if (in_array($selfFieldId->getFieldType(), RelationType::$toManyRelations)) { $classNameArray = explode('\\', $selfFieldId->getClassName()); $relationFieldName = strtolower(array_pop($classNameArray)) . '_' . $selfFieldId->getFieldName(); if ($selfFieldId->getFieldType() === RelationType::ONE_TO_MANY) { $owner = false; $targetOwner = true; } $targetFieldId = new FieldConfigId('extend', $targetEntityClass, $relationFieldName, ExtendHelper::getReverseRelationType($selfFieldId->getFieldType())); } $selfRelationConfig = ['assign' => false, 'field_id' => $selfFieldId, 'owner' => $owner, 'target_entity' => $targetEntityClass, 'target_field_id' => $targetFieldId]; if ($fieldConfig->has('cascade')) { $selfRelationConfig['cascade'] = $fieldConfig->get('cascade'); } $selfRelations = $selfConfig->get('relation') ?: []; $selfRelations[$relationKey] = $selfRelationConfig; $selfConfig->set('relation', $selfRelations); $this->extendConfigProvider->persist($selfConfig); $targetConfig = $this->extendConfigProvider->getConfig($targetEntityClass); $targetRelationConfig = ['assign' => false, 'field_id' => $targetFieldId, 'owner' => $targetOwner, 'target_entity' => $selfFieldId->getClassName(), 'target_field_id' => $selfFieldId]; $targetRelations = $targetConfig->get('relation') ?: []; $targetRelations[$relationKey] = $targetRelationConfig; $targetConfig->set('relation', $targetRelations); $fieldConfig->set('relation_key', $relationKey); $this->extendConfigProvider->persist($targetConfig); }
/** * Updates values of the given config based on the given default values and $force flag * * @param ConfigInterface $config * @param array $defaultValues * @param bool $force * * @return bool TRUE if at least one config value was updated; otherwise, FALSE */ protected function updateConfigValues(ConfigInterface $config, array $defaultValues, $force) { $hasChanges = false; foreach ($defaultValues as $code => $value) { if (!$config->has($code) || $force) { $config->set($code, $value); $hasChanges = true; } } return $hasChanges; }
/** * @param ConfigInterface $sourceEntityConfig The 'extend' config of the source entity * @param string $targetEntityName * @param string $relationName * @param string $targetFieldName A field name is used to show related entity * @param array $options * @param string $fieldType The field type. By default the field type is manyToOne, * but you can specify another type if it is based on manyToOne. * In this case this type should be registered * in entity_extend.yml under underlying_types section * * @return string The relation key */ public function addManyToOneRelation(ConfigInterface $sourceEntityConfig, $targetEntityName, $relationName, $targetFieldName, $options = [], $fieldType = RelationType::MANY_TO_ONE) { $sourceEntityName = $sourceEntityConfig->getId()->getClassName(); $relationKey = ExtendHelper::buildRelationKey($sourceEntityName, $relationName, RelationType::MANY_TO_ONE, $targetEntityName); // add a relation field config if (!$this->configManager->hasConfigFieldModel($sourceEntityName, $relationName)) { $this->configManager->createConfigFieldModel($sourceEntityName, $relationName, $fieldType); $options['extend']['state'] = ExtendScope::STATE_NEW; } else { $configFieldModel = $this->configManager->getConfigFieldModel($sourceEntityName, $relationName); if ($configFieldModel->getType() !== $fieldType) { $this->configManager->changeFieldType($sourceEntityName, $relationName, $fieldType); } } $options['extend']['is_extend'] = true; $options['extend']['relation_key'] = $relationKey; $options['extend']['target_entity'] = $targetEntityName; $options['extend']['target_field'] = $targetFieldName; $this->updateFieldConfigs($sourceEntityName, $relationName, $options); // add relation to config $relations = $sourceEntityConfig->get('relation', false, []); if (!isset($relations[$relationKey])) { $fieldId = new FieldConfigId('extend', $sourceEntityName, $relationName, RelationType::MANY_TO_ONE); $relations[$relationKey] = ['assign' => false, 'field_id' => $fieldId, 'owner' => true, 'target_entity' => $targetEntityName, 'target_field_id' => false]; if (isset($options['extend']['cascade'])) { $relations[$relationKey]['cascade'] = $options['extend']['cascade']; } $sourceEntityConfig->set('relation', $relations); $extendConfigProvider = $this->configManager->getProvider('extend'); $extendConfigProvider->persist($sourceEntityConfig); } return $relationKey; }
/** * @param ConfigInterface $entityConfig * @param ConfigProvider $configProvider */ protected function updateStateValues(ConfigInterface $entityConfig, ConfigProvider $configProvider) { if ($entityConfig->is('state', ExtendScope::STATE_DELETE)) { // mark entity as deleted if (!$entityConfig->is('is_deleted')) { $entityConfig->set('is_deleted', true); $this->configManager->persist($entityConfig); } // mark all fields as deleted $fieldConfigs = $configProvider->getConfigs($entityConfig->getId()->getClassName(), true); foreach ($fieldConfigs as $fieldConfig) { if (!$fieldConfig->is('is_deleted')) { $fieldConfig->set('is_deleted', true); $this->configManager->persist($fieldConfig); } } } elseif (!$entityConfig->is('state', ExtendScope::STATE_ACTIVE)) { $hasNotActiveFields = false; $fieldConfigs = $configProvider->getConfigs($entityConfig->getId()->getClassName(), true); foreach ($fieldConfigs as $fieldConfig) { if (!$fieldConfig->in('state', [ExtendScope::STATE_ACTIVE, ExtendScope::STATE_DELETE])) { $hasNotActiveFields = true; break; } } // Set entity state to active if all fields are active or deleted if (!$hasNotActiveFields) { $entityConfig->set('state', ExtendScope::STATE_ACTIVE); $this->configManager->persist($entityConfig); } } }
/** * @param ConfigInterface $fieldConfig */ protected function setRelationKeyToFieldConfig(ConfigInterface $fieldConfig) { /** @var FieldConfigId $fieldConfigId */ $fieldConfigId = $fieldConfig->getId(); $relationKey = ExtendHelper::buildRelationKey($fieldConfigId->getClassName(), $fieldConfigId->getFieldName(), $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType()), $fieldConfig->get('target_entity')); $fieldConfig->set('relation_key', $relationKey); $this->configManager->persist($fieldConfig); }
/** * @param ConfigInterface $entityConfig * * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ protected function checkSchema(ConfigInterface $entityConfig) { $extendProvider = $this->em->getExtendManager()->getConfigProvider(); $className = $entityConfig->getId()->getClassName(); $doctrine = []; if (strpos($className, self::ENTITY) !== false) { $entityName = $className; $type = 'Custom'; $doctrine[$entityName] = ['type' => 'entity', 'table' => 'oro_extend_' . strtolower(str_replace('\\', '', $entityName)), 'fields' => ['id' => ['type' => 'integer', 'id' => true, 'generator' => ['strategy' => 'AUTO']]]]; } else { $entityName = $entityConfig->get('extend_class'); $type = 'Extend'; $doctrine[$entityName] = ['type' => 'mappedSuperclass', 'fields' => []]; } $entityState = $entityConfig->get('state'); $schema = $entityConfig->get('schema'); $properties = array(); $relationProperties = $schema ? $schema['relation'] : array(); $defaultProperties = array(); $addRemoveMethods = array(); if ($fieldConfigs = $extendProvider->getConfigs($className)) { foreach ($fieldConfigs as $fieldConfig) { if ($fieldConfig->is('extend')) { $fieldName = self::FIELD_PREFIX . $fieldConfig->getId()->getFieldName(); $fieldType = $fieldConfig->getId()->getFieldType(); if (in_array($fieldType, ['oneToMany', 'manyToOne', 'manyToMany', 'optionSet'])) { $relationProperties[$fieldName] = $fieldConfig->getId()->getFieldName(); if ($fieldType != 'manyToOne') { $defaultName = self::DEFAULT_PREFIX . $fieldConfig->getId()->getFieldName(); $defaultProperties[$defaultName] = $defaultName; } } else { $properties[$fieldName] = $fieldConfig->getId()->getFieldName(); $doctrine[$entityName]['fields'][$fieldName]['code'] = $fieldName; $doctrine[$entityName]['fields'][$fieldName]['type'] = $fieldType; $doctrine[$entityName]['fields'][$fieldName]['nullable'] = true; $doctrine[$entityName]['fields'][$fieldName]['length'] = $fieldConfig->get('length'); $doctrine[$entityName]['fields'][$fieldName]['precision'] = $fieldConfig->get('precision'); $doctrine[$entityName]['fields'][$fieldName]['scale'] = $fieldConfig->get('scale'); } } if ($fieldConfig->get('state') != ExtendManager::STATE_DELETED) { $fieldConfig->set('state', ExtendManager::STATE_ACTIVE); } if ($fieldConfig->get('state') == ExtendManager::STATE_DELETED) { $fieldConfig->set('is_deleted', true); } $extendProvider->persist($fieldConfig); } } $extendProvider->flush(); $entityConfig->set('state', $entityState); if ($entityConfig->get('state') == ExtendManager::STATE_DELETED) { $entityConfig->set('is_deleted', true); $extendProvider->map(function (Config $config) use($extendProvider) { $config->set('is_deleted', true); $extendProvider->persist($config); }, $className); } else { $entityConfig->set('state', ExtendManager::STATE_ACTIVE); } $relations = $entityConfig->get('relation') ?: []; foreach ($relations as &$relation) { if ($relation['field_id']) { $relation['assign'] = true; if ($relation['field_id']->getFieldType() != 'manyToOne' && $relation['target_field_id']) { $fieldName = self::FIELD_PREFIX . $relation['field_id']->getFieldName(); $addRemoveMethods[$fieldName]['self'] = $relation['field_id']->getFieldName(); $addRemoveMethods[$fieldName]['target'] = $relation['target_field_id']->getFieldName(); $addRemoveMethods[$fieldName]['is_target_addremove'] = $relation['field_id']->getFieldType() == 'manyToMany'; } $this->checkRelation($relation['target_entity'], $relation['field_id']); } } $entityConfig->set('relation', $relations); $schema = ['class' => $className, 'entity' => $entityName, 'type' => $type, 'property' => $properties, 'relation' => $relationProperties, 'default' => $defaultProperties, 'addremove' => $addRemoveMethods, 'doctrine' => $doctrine]; if ($type == 'Extend') { $schema['parent'] = get_parent_class($className); $schema['inherit'] = get_parent_class($schema['parent']); } $entityConfig->set('schema', $schema); $extendProvider->persist($entityConfig); $extendProvider->flush(); }