예제 #1
0
 /**
  * @param string $tableName
  * @param string $columnName
  * @param array  $options
  *
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function addColumnOptions($tableName, $columnName, $options)
 {
     $entityClassName = $this->getEntityClassName($tableName, null, false);
     if (!$entityClassName) {
         return;
     }
     $newColumnName = $this->getAndRemoveOption($options, ExtendOptionsManager::NEW_NAME_OPTION);
     if ($newColumnName) {
         $this->result[ExtendConfigProcessor::RENAME_CONFIGS][$entityClassName][$columnName] = $newColumnName;
         if (empty($options)) {
             return;
         }
     }
     $fieldName = $this->getAndRemoveOption($options, ExtendOptionsManager::FIELD_NAME_OPTION);
     if (!$fieldName) {
         $fieldName = $this->getFieldName($tableName, $columnName);
     }
     $columnType = $this->getAndRemoveOption($options, ExtendOptionsManager::TYPE_OPTION);
     $columnMode = $this->getAndRemoveOption($options, ExtendOptionsManager::MODE_OPTION);
     $columnUnderlyingType = $this->fieldTypeHelper->getUnderlyingType($columnType);
     if (in_array($columnUnderlyingType, ['oneToMany', 'manyToOne', 'manyToMany'])) {
         if (!isset($options['extend'])) {
             $options['extend'] = [];
         }
         $target = $this->getAndRemoveOption($options, ExtendOptionsManager::TARGET_OPTION);
         foreach ($target as $optionName => $optionValue) {
             switch ($optionName) {
                 case 'table_name':
                     $options['extend']['target_entity'] = $this->getEntityClassName($optionValue);
                     break;
                 case 'column':
                     $options['extend']['target_field'] = $this->getFieldName($target['table_name'], $optionValue);
                     break;
                 case 'columns':
                     foreach ($optionValue as $group => $columns) {
                         $values = [];
                         foreach ($columns as $column) {
                             $values[] = $this->getFieldName($target['table_name'], $column);
                         }
                         $options['extend']['target_' . $group] = $values;
                     }
                     break;
             }
         }
         $options['extend']['relation_key'] = ExtendHelper::buildRelationKey($entityClassName, $fieldName, $columnUnderlyingType, $options['extend']['target_entity']);
     }
     $this->result[$entityClassName]['fields'][$fieldName] = [];
     if (!empty($options)) {
         $this->result[$entityClassName]['fields'][$fieldName]['configs'] = $options;
     }
     if ($columnType) {
         $this->result[$entityClassName]['fields'][$fieldName]['type'] = $columnType;
     }
     if ($columnMode) {
         $this->result[$entityClassName]['fields'][$fieldName]['mode'] = $columnMode;
     }
 }
 /**
  * {@inheritdoc}
  */
 public function beforeValueRender(ValueRenderEvent $event)
 {
     $value = $event->getFieldValue();
     $type = $event->getFieldConfigId()->getFieldType();
     /** Prepare Relation field type */
     if ($value && $value instanceof Collection) {
         $viewData = $this->getValueForCollection($value, $event->getFieldConfigId());
         $event->setFieldViewValue($viewData);
         return;
     }
     $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($type);
     if ($value && $underlyingFieldType === RelationType::MANY_TO_ONE) {
         $viewData = $this->getValueForManyToOne($value, $this->extendProvider->getConfigById($event->getFieldConfigId()));
         $event->setFieldViewValue($viewData);
     }
 }
예제 #3
0
 /**
  * Check fields parameters and update field config
  *
  * @param string          $entityName
  * @param ConfigInterface $fieldConfig
  * @param array           $relationProperties
  * @param array           $defaultProperties
  * @param array           $properties
  * @param array           $doctrine
  */
 protected function checkFields($entityName, ConfigInterface $fieldConfig, array &$relationProperties, array &$defaultProperties, array &$properties, array &$doctrine)
 {
     if ($fieldConfig->is('is_extend')) {
         /** @var FieldConfigId $fieldConfigId */
         $fieldConfigId = $fieldConfig->getId();
         $fieldName = $fieldConfigId->getFieldName();
         $fieldType = $fieldConfigId->getFieldType();
         $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($fieldType);
         if (in_array($underlyingFieldType, array_merge(RelationType::$anyToAnyRelations, ['optionSet']))) {
             $relationProperties[$fieldName] = $fieldName;
             if ($underlyingFieldType !== RelationType::MANY_TO_ONE && !$fieldConfig->is('without_default')) {
                 $defaultName = self::DEFAULT_PREFIX . $fieldName;
                 $defaultProperties[$defaultName] = $defaultName;
             }
         } else {
             $properties[$fieldName] = $fieldName;
             $doctrine[$entityName]['fields'][$fieldName] = ['column' => $fieldName, 'type' => $fieldType, 'nullable' => true, 'length' => $fieldConfig->get('length'), 'precision' => $fieldConfig->get('precision'), 'scale' => $fieldConfig->get('scale')];
         }
     }
     if ($fieldConfig->is('state', ExtendScope::STATE_DELETE)) {
         $fieldConfig->set('is_deleted', true);
     } else {
         $fieldConfig->set('state', ExtendScope::STATE_ACTIVE);
     }
 }
예제 #4
0
 /**
  * Check fields parameters and update field config
  *
  * @param string          $entityName
  * @param ConfigInterface $fieldConfig
  * @param array           $relationProperties
  * @param array           $defaultProperties
  * @param array           $properties
  * @param array           $doctrine
  */
 protected function checkFieldSchema($entityName, ConfigInterface $fieldConfig, array &$relationProperties, array &$defaultProperties, array &$properties, array &$doctrine)
 {
     if ($fieldConfig->is('is_extend')) {
         /** @var FieldConfigId $fieldConfigId */
         $fieldConfigId = $fieldConfig->getId();
         $fieldName = $fieldConfigId->getFieldName();
         $fieldType = $fieldConfigId->getFieldType();
         $isDeleted = $fieldConfig->is('is_deleted');
         $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($fieldType);
         if (in_array($underlyingFieldType, RelationType::$anyToAnyRelations, true)) {
             $relationProperties[$fieldName] = [];
             if ($isDeleted) {
                 $relationProperties[$fieldName]['private'] = true;
             }
             if ($underlyingFieldType !== RelationType::MANY_TO_ONE && !$fieldConfig->is('without_default')) {
                 $defaultName = self::DEFAULT_PREFIX . $fieldName;
                 $defaultProperties[$defaultName] = [];
                 if ($isDeleted) {
                     $defaultProperties[$defaultName]['private'] = true;
                 }
             }
         } else {
             $properties[$fieldName] = [];
             if ($isDeleted) {
                 $properties[$fieldName]['private'] = true;
             }
             $doctrine[$entityName]['fields'][$fieldName] = ['column' => $fieldName, 'type' => $fieldType, 'nullable' => true, 'length' => $fieldConfig->get('length'), 'precision' => $fieldConfig->get('precision'), 'scale' => $fieldConfig->get('scale')];
         }
     }
 }
 /**
  * {@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);
             }
         }
     }
 }
 /**
  * Determines whether the index for the given field is needed or not.
  * All relation type fields should be excluded.
  * Index requirement is determined by visibility of a field on a grid.
  *
  * @param string $className
  * @param string $fieldName
  * @param string $fieldType
  *
  * @return bool
  */
 protected function isIndexRequired($className, $fieldName, $fieldType)
 {
     $underlyingType = $this->fieldTypeHelper->getUnderlyingType($fieldType);
     if (!$this->fieldTypeHelper->isRelation($underlyingType)) {
         $datagridConfigProvider = $this->configManager->getProvider('datagrid');
         if ($datagridConfigProvider->hasConfig($className, $fieldName)) {
             $datagridConfig = $datagridConfigProvider->getConfig($className, $fieldName);
             return $datagridConfig->get('is_visible', false, false);
         }
     }
     return false;
 }
 /**
  * @param string $columnName
  * @param array $options
  * @param string $className
  * @param Table $table
  */
 protected function buildIndex($columnName, $options, $className, $table)
 {
     $columnType = $this->fieldTypeHelper->getUnderlyingType($options[ExtendOptionsManager::TYPE_OPTION]);
     if ($this->fieldTypeHelper->isRelation($columnType) || in_array($columnType, [Type::TEXT])) {
         return;
     }
     $indexName = $this->nameGenerator->generateIndexNameForExtendFieldVisibleInGrid($className, $columnName);
     if ($this->isEnabled($options) && $this->isExtended($options) && !$table->hasIndex($indexName)) {
         $table->addIndex([$columnName], $indexName);
     } elseif (!$this->isEnabled($options) && $table->hasIndex($indexName)) {
         $table->dropIndex($indexName);
     }
 }
 /**
  * @param LoggerInterface $logger
  * @param bool            $dryRun
  */
 public function doExecute(LoggerInterface $logger, $dryRun = false)
 {
     $classNames = $this->getAllConfigurableEntities($logger);
     foreach ($classNames as $className) {
         $fieldConfigs = $this->loadFieldConfigs($logger, $className);
         foreach ($fieldConfigs as $fieldConfig) {
             $data = $fieldConfig['data'];
             if (!isset($data['extend'])) {
                 // skip because this field has no any attributes in 'extend' scope
                 continue;
             }
             if (isset($data['extend']['is_extend']) || array_key_exists('is_extend', $data['extend'])) {
                 // remove old extend.is_extend attribute
                 unset($data['extend']['is_extend']);
             }
             if (isset($data['extend']['extend']) || array_key_exists('extend', $data['extend'])) {
                 // rename extend.extend to extend.is_extend
                 $data['extend']['is_extend'] = $data['extend']['extend'];
                 unset($data['extend']['extend']);
             }
             if (isset($data['extend']['relation_key']) && is_string($data['extend']['relation_key'])) {
                 $parts = explode('|', $data['extend']['relation_key']);
                 if (count($parts) === 4 && $parts[0] !== $this->fieldTypeHelper->getUnderlyingType($parts[0])) {
                     // change field type to relation type in extend.relation_key attribute
                     $parts[0] = $this->fieldTypeHelper->getUnderlyingType($parts[0]);
                     $data['extend']['relation_key'] = implode('|', $parts);
                 }
             }
             $query = 'UPDATE oro_entity_config_field SET data = :data WHERE id = :id';
             $params = ['data' => $data, 'id' => $fieldConfig['id']];
             $types = ['data' => 'array', 'id' => 'integer'];
             $this->logQuery($logger, $query, $params, $types);
             if (!$dryRun) {
                 $this->connection->executeUpdate($query, $params, $types);
             }
         }
     }
 }
 /**
  * Determines whether the index for the given field is needed or not
  *
  * @param string $className
  * @param string $fieldName
  * @param string $fieldType
  *
  * @return bool
  */
 protected function isIndexRequired($className, $fieldName, $fieldType)
 {
     $underlyingType = $this->fieldTypeHelper->getUnderlyingType($fieldType);
     if (in_array($underlyingType, ['oneToMany', 'manyToOne', 'manyToMany'])) {
         // relation fields already have an index
         return false;
     }
     $result = false;
     $datagridConfigProvider = $this->configManager->getProvider('datagrid');
     if ($datagridConfigProvider->hasConfig($className, $fieldName)) {
         $datagridConfig = $datagridConfigProvider->getConfig($className, $fieldName);
         if ($datagridConfig->get('is_visible')) {
             $result = true;
         }
     }
     return $result;
 }
 /**
  * @param ConfigInterface $fieldConfig
  * @param string $relationKey
  */
 protected function createTargetRelation(ConfigInterface $fieldConfig, $relationKey)
 {
     /** @var FieldConfigId $fieldConfigId */
     $fieldConfigId = $fieldConfig->getId();
     $selfFieldId = new FieldConfigId('extend', $fieldConfigId->getClassName(), $fieldConfigId->getFieldName(), $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType()));
     $targetEntityClass = $fieldConfig->get('target_entity');
     $selfConfig = $this->extendConfigProvider->getConfig($selfFieldId->getClassName());
     $selfRelations = $selfConfig->get('relation');
     $selfRelationConfig =& $selfRelations[$relationKey];
     $selfRelationConfig['field_id'] = $selfFieldId;
     $targetConfig = $this->extendConfigProvider->getConfig($targetEntityClass);
     $targetRelations = $targetConfig->get('relation');
     $targetRelationConfig =& $targetRelations[$relationKey];
     $targetRelationConfig['target_field_id'] = $selfFieldId;
     $selfConfig->set('relation', $selfRelations);
     $targetConfig->set('relation', $targetRelations);
     $this->extendConfigProvider->persist($targetConfig);
 }
 /**
  * @param ConfigInterface $config
  * @return bool
  */
 public function filterFields(ConfigInterface $config)
 {
     $extendConfig = $this->extendProvider->getConfigById($config->getId());
     /** @var FieldConfigId $fieldConfigId */
     $fieldConfigId = $extendConfig->getId();
     // skip system, new and deleted fields
     if (!$config->is('owner', ExtendScope::OWNER_CUSTOM) || $config->is('state', ExtendScope::STATE_NEW) || $config->is('is_deleted')) {
         return false;
     }
     // skip invisible fields
     if (!$this->viewProvider->getConfigById($config->getId())->is('is_displayable')) {
         return false;
     }
     // skip relations if they are referenced to deleted entity
     $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType());
     if (in_array($underlyingFieldType, RelationType::$anyToAnyRelations) && $this->extendProvider->getConfig($extendConfig->get('target_entity'))->is('is_deleted', true)) {
         return false;
     }
     return true;
 }
예제 #12
0
 /**
  * @param ConfigInterface $config
  * @return bool
  */
 public function filterFields(ConfigInterface $config)
 {
     $extendConfig = $this->extendProvider->getConfigById($config->getId());
     /** @var FieldConfigId $fieldConfigId */
     $fieldConfigId = $extendConfig->getId();
     // skip system and not accessible fields
     if (!$config->is('owner', ExtendScope::OWNER_CUSTOM) || !ExtendHelper::isFieldAccessible($config)) {
         return false;
     }
     // skip invisible fields
     if (!$this->viewProvider->getConfigById($config->getId())->is('is_displayable')) {
         return false;
     }
     // skip relations if they are referenced to not accessible entity
     $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType());
     if (in_array($underlyingFieldType, RelationType::$anyToAnyRelations, true) && !ExtendHelper::isEntityAccessible($this->extendProvider->getConfig($extendConfig->get('target_entity')))) {
         return false;
     }
     return true;
 }
예제 #13
0
 /**
  * @return string[]
  */
 public function getFields()
 {
     if (empty($this->fields)) {
         $this->fields = [];
         $fieldConfigs = $this->configManager->getConfigs('extend', self::CALENDAR_PROPERTY_CLASS);
         foreach ($fieldConfigs as $fieldConfig) {
             if (!ExtendHelper::isFieldAccessible($fieldConfig)) {
                 continue;
             }
             /** @var FieldConfigId $fieldId */
             $fieldId = $fieldConfig->getId();
             $fieldType = $fieldId->getFieldType();
             $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($fieldType);
             if (in_array($underlyingFieldType, RelationType::$toManyRelations, true)) {
                 // ignore to-many relations
                 continue;
             }
             $this->fields[$fieldId->getFieldName()] = $fieldType;
         }
     }
     return $this->fields;
 }
 /**
  * @return string[]
  */
 public function getFields()
 {
     if (empty($this->fields)) {
         $this->fields = [];
         $fieldConfigs = $this->configManager->getConfigs('extend', self::CALENDAR_PROPERTY_CLASS);
         foreach ($fieldConfigs as $fieldConfig) {
             if ($fieldConfig->is('state', ExtendScope::STATE_NEW) || $fieldConfig->is('is_deleted')) {
                 continue;
             }
             /** @var FieldConfigId $fieldId */
             $fieldId = $fieldConfig->getId();
             $fieldType = $fieldId->getFieldType();
             $underlyingFieldType = $this->fieldTypeHelper->getUnderlyingType($fieldType);
             if (in_array($underlyingFieldType, ['ref-many', 'manyToMany', 'oneToMany'])) {
                 // ignore multiple relations
                 continue;
             }
             $this->fields[$fieldId->getFieldName()] = $fieldType;
         }
     }
     return $this->fields;
 }
 /**
  * Makes sure that both source and target entities know about a reverse relation
  *
  * @param ConfigInterface $fieldConfig
  */
 protected function ensureReverseRelationCompleted(ConfigInterface $fieldConfig)
 {
     /** @var FieldConfigId $fieldConfigId */
     $fieldConfigId = $fieldConfig->getId();
     $relationKey = $fieldConfig->get('relation_key');
     $selfConfig = $this->extendConfigProvider->getConfig($fieldConfigId->getClassName());
     $selfRelations = $selfConfig->get('relation', false, []);
     if (isset($selfRelations[$relationKey]['field_id']) && $selfRelations[$relationKey]['field_id']) {
         return;
     }
     $targetConfig = $this->extendConfigProvider->getConfig($fieldConfig->get('target_entity'));
     $targetRelations = $targetConfig->get('relation', false, []);
     if (!isset($targetRelations[$relationKey])) {
         return;
     }
     $selfFieldId = new FieldConfigId('extend', $fieldConfigId->getClassName(), $fieldConfigId->getFieldName(), $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType()));
     $selfRelations[$relationKey]['field_id'] = $selfFieldId;
     $targetRelations[$relationKey]['target_field_id'] = $selfFieldId;
     $selfConfig->set('relation', $selfRelations);
     $targetConfig->set('relation', $targetRelations);
     $this->configManager->persist($selfConfig);
     $this->configManager->persist($targetConfig);
 }
예제 #16
0
 /**
  * Gets a relation type
  *
  * @param string $relationFieldType
  *
  * @return string
  */
 protected function getRelationType($relationFieldType)
 {
     return $this->fieldTypeHelper->getUnderlyingType($relationFieldType);
 }
예제 #17
0
 /**
  * @param array $field
  * @return bool
  */
 public function isMultipleRelation(array $field)
 {
     return $this->isRelation($field) && in_array($this->fieldTypeHelper->getUnderlyingType($field['relation_type']), ['ref-many', 'oneToMany', 'manyToMany']);
 }
예제 #18
0
 /**
  * Return "false" if can't find config for field, "null" if field type is unknown for given field
  * or array with config data for given field
  *
  * @param ClassMetadata $metadata
  * @param $field
  * @return array|bool
  */
 protected function guessAttributeParametersScalarField(ClassMetadata $metadata, $field)
 {
     if ($metadata->hasField($field)) {
         $doctrineType = $metadata->getTypeOfField($field);
         if (!isset($this->doctrineTypeMapping[$doctrineType])) {
             return null;
         }
         return $this->formatResult($this->getLabel($metadata->getName(), $field), $this->doctrineTypeMapping[$doctrineType]['type'], $this->doctrineTypeMapping[$doctrineType]['options']);
     } elseif ($this->entityConfigProvider->hasConfig($metadata->getName(), $field)) {
         $entityConfig = $this->entityConfigProvider->getConfig($metadata->getName(), $field);
         $fieldType = $entityConfig->getId()->getFieldType();
         if (!FieldTypeHelper::isRelation($fieldType)) {
             return $this->formatResult($entityConfig->get('label'), $this->doctrineTypeMapping[$fieldType]['type'], $this->doctrineTypeMapping[$fieldType]['options']);
         }
     }
     return false;
 }
예제 #19
0
 /**
  * @dataProvider relationCHeckTestProvider
  */
 public function testIsRelation($fieldType, $expected)
 {
     $this->assertSame($expected, FieldTypeHelper::isRelation($fieldType));
 }
 /**
  * @param ConfigInterface $fieldConfig
  *
  * @return FieldConfigId
  */
 protected function createFieldConfigId(ConfigInterface $fieldConfig)
 {
     /** @var FieldConfigId $fieldConfigId */
     $fieldConfigId = $fieldConfig->getId();
     return new FieldConfigId('extend', $fieldConfigId->getClassName(), $fieldConfigId->getFieldName(), $this->fieldTypeHelper->getUnderlyingType($fieldConfigId->getFieldType()));
 }