public function testGenerateWorkflowFields() { $entityClass = 'TestEntity'; $this->entityConnector->expects($this->once())->method('isWorkflowAware')->with($entityClass)->will($this->returnValue(false)); $extendConfigProvider = $this->getMock('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProviderInterface'); $entityConfigProvider = $this->getMock('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProviderInterface'); $formConfigProvider = $this->getMock('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProviderInterface'); $viewConfigProvider = $this->getMock('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProviderInterface'); $importExportConfigProvider = $this->getMock('Oro\\Bundle\\EntityConfigBundle\\Provider\\ConfigProviderInterface'); $providerMap = array(array('extend', $extendConfigProvider), array('entity', $entityConfigProvider), array('form', $formConfigProvider), array('view', $viewConfigProvider), array('importexport', $importExportConfigProvider)); $this->configManager->expects($this->any())->method('getProvider')->will($this->returnValueMap($providerMap)); $entityConfig = $this->getMock('Oro\\Bundle\\EntityConfigBundle\\Config\\ConfigInterface'); $entityConfig->expects($this->at(0))->method('is')->with('is_extend')->will($this->returnValue(true)); $extendConfigProvider->expects($this->at(0))->method('getConfig')->with($entityClass)->will($this->returnValue($entityConfig)); $workflowItemClass = 'Oro\\Bundle\\WorkflowBundle\\Entity\\WorkflowItem'; $workflowStepClass = 'Oro\\Bundle\\WorkflowBundle\\Entity\\WorkflowStep'; $this->addFieldAssertions($entityConfigProvider, $extendConfigProvider, $formConfigProvider, $viewConfigProvider, $importExportConfigProvider, $entityClass, FieldGenerator::PROPERTY_WORKFLOW_ITEM, ConfigHelper::getTranslationKey('entity', 'label', $workflowItemClass, 'related_entity'), ConfigHelper::getTranslationKey('entity', 'description', $workflowItemClass, 'related_entity'), 'Oro\\Bundle\\WorkflowBundle\\Entity\\WorkflowItem', 'id', 0); $this->addFieldAssertions($entityConfigProvider, $extendConfigProvider, $formConfigProvider, $viewConfigProvider, $importExportConfigProvider, $entityClass, FieldGenerator::PROPERTY_WORKFLOW_STEP, ConfigHelper::getTranslationKey('entity', 'label', $workflowStepClass, 'related_entity'), ConfigHelper::getTranslationKey('entity', 'description', $workflowStepClass, 'related_entity'), 'Oro\\Bundle\\WorkflowBundle\\Entity\\WorkflowStep', 'label', 1); $entityConfig->expects($this->at(1))->method('set')->with('state', ExtendScope::STATE_UPDATE); $entityConfig->expects($this->at(2))->method('set')->with('upgradeable', true); $this->configManager->expects($this->at(15))->method('persist')->with($entityConfig); $this->configManager->expects($this->at(16))->method('flush'); $this->entityProcessor->expects($this->once())->method('updateDatabase'); /* $this->addHideAssertions($entityClass, FieldGenerator::PROPERTY_WORKFLOW_ITEM, 0); $this->addHideAssertions($entityClass, FieldGenerator::PROPERTY_WORKFLOW_STEP, 1); $this->configManager->expects($this->at(17))->method('flush'); */ // run test $this->generator->generateWorkflowFields($entityClass); }
protected function getEntityChoiceList($entityClassName, $relationType) { $configManager = $this->configProvider->getConfigManager(); $choices = array(); if ($this->targetEntity) { $entityIds = array($this->configProvider->getId($this->targetEntity)); } else { $entityIds = $configManager->getIds('extend'); } if (in_array($relationType, array('oneToMany', 'manyToMany'))) { $entityIds = array_filter($entityIds, function (EntityConfigId $configId) use($configManager) { $config = $configManager->getConfig($configId); return $config->is('is_extend'); }); } $entityIds = array_filter($entityIds, function (EntityConfigId $configId) use($configManager) { $config = $configManager->getConfig($configId); return $config->is('is_extend', false) || !$config->is('state', ExtendScope::STATE_NEW); }); foreach ($entityIds as $entityId) { $className = $entityId->getClassName(); if ($className != $entityClassName) { list($moduleName, $entityName) = ConfigHelper::getModuleAndEntityNames($className); $choices[$className] = $moduleName . ':' . $entityName; } } return $choices; }
/** * {@inheritdoc} */ public function doExecute(LoggerInterface $logger, $dryRun = false) { $getSql = 'SELECT id, class_name FROM oro_entity_config'; $this->logQuery($logger, $getSql); $configs = $this->connection->fetchAll($getSql); $indexes = $this->getIndexes($logger); $insertSql = 'INSERT INTO oro_entity_config_index_value ' . '(entity_id, scope, code, value) ' . 'VALUES (:entity_id, :scope, :code, :value)'; foreach ($configs as $config) { $id = (int) $config['id']; $className = $config['class_name']; list($moduleName, $entityName) = ConfigHelper::getModuleAndEntityNames($className); if (!isset($indexes[$id]['module_name'])) { $params = ['entity_id' => $id, 'scope' => 'entity_config', 'code' => 'module_name', 'value' => $moduleName]; $types = ['entity_id' => 'integer', 'scope' => 'string', 'code' => 'string', 'value' => 'string']; $this->logQuery($logger, $insertSql, $params, $types); if (!$dryRun) { $this->connection->executeUpdate($insertSql, $params, $types); } } if (!isset($indexes[$id]['entity_name'])) { $params = ['entity_id' => $id, 'scope' => 'entity_config', 'code' => 'entity_name', 'value' => $entityName]; $types = ['entity_id' => 'integer', 'scope' => 'string', 'code' => 'string', 'value' => 'string']; $this->logQuery($logger, $insertSql, $params, $types); if (!$dryRun) { $this->connection->executeUpdate($insertSql, $params, $types); } } } }
/** * @param string $className * @return $this */ public function setClassName($className) { $this->className = $className; list($moduleName, $entityName) = ConfigHelper::getModuleAndEntityNames($className); $this->addToIndex('entity_config', 'module_name', $moduleName); $this->addToIndex('entity_config', 'entity_name', $entityName); return $this; }
/** * @param string $sourceEntityClass * @param string $targetEntityClass * @param string $associationKind */ public function createManyToOneAssociation($sourceEntityClass, $targetEntityClass, $associationKind) { $relationName = ExtendHelper::buildAssociationName($targetEntityClass, $associationKind); $entityConfigProvider = $this->configManager->getProvider('entity'); $targetEntityConfig = $entityConfigProvider->getConfig($targetEntityClass); $label = $targetEntityConfig->get('label', false, ConfigHelper::getTranslationKey('entity', 'label', $targetEntityClass, $relationName)); $description = ConfigHelper::getTranslationKey('entity', 'description', $targetEntityClass, $relationName); $targetEntityPrimaryKeyColumns = $this->getPrimaryKeyColumnNames($targetEntityClass); $targetFieldName = array_shift($targetEntityPrimaryKeyColumns); // add relation to owning entity $this->relationBuilder->addManyToOneRelation($this->configManager->getProvider('extend')->getConfig($sourceEntityClass), $targetEntityClass, $relationName, $targetFieldName, ['entity' => ['label' => $label, 'description' => $description], 'view' => ['is_displayable' => false], 'form' => ['is_enabled' => false]]); }
/** * @param string $entityClass * @throws WorkflowException */ public function generateWorkflowFields($entityClass) { if ($this->entityConnector->isWorkflowAware($entityClass)) { return; } $extendConfigProvider = $this->configManager->getProvider('extend'); $entityConfig = $extendConfigProvider->getConfig($entityClass); if (!$entityConfig || !$entityConfig->is('is_extend')) { throw new WorkflowException(sprintf('Class %s can not be extended', $entityClass)); } $workflowItemClass = 'Oro\\Bundle\\WorkflowBundle\\Entity\\WorkflowItem'; $workflowStepClass = 'Oro\\Bundle\\WorkflowBundle\\Entity\\WorkflowStep'; // add fields $hasWorkflowItemField = $this->configManager->hasConfig($entityClass, self::PROPERTY_WORKFLOW_ITEM); if (!$hasWorkflowItemField) { $this->addRelationField($entityClass, self::PROPERTY_WORKFLOW_ITEM, ConfigHelper::getTranslationKey('entity', 'label', $workflowItemClass, 'related_entity'), ConfigHelper::getTranslationKey('entity', 'description', $workflowItemClass, 'related_entity'), $workflowItemClass, 'id'); } $hasWorkflowStepField = $this->configManager->hasConfig($entityClass, self::PROPERTY_WORKFLOW_STEP); if (!$hasWorkflowStepField) { $this->addRelationField($entityClass, self::PROPERTY_WORKFLOW_STEP, ConfigHelper::getTranslationKey('entity', 'label', $workflowStepClass, 'related_entity'), ConfigHelper::getTranslationKey('entity', 'description', $workflowStepClass, 'related_entity'), $workflowStepClass, 'label'); } // update entity config $entityConfig->set('state', ExtendScope::STATE_UPDATE); $entityConfig->set('upgradeable', true); $this->configManager->persist($entityConfig); $this->configManager->flush(); // update database $this->entityProcessor->updateDatabase(); // make fields hidden // TODO: Fields can be hidden only after schema update due to a bug in DoctrineSubscriber // TODO: Should be fixed in scope of https://magecore.atlassian.net/browse/BAP-3621 // TODO: If make fields hidden then these fields will be created only for the first extended entity // TODO: Should be fixed in scope of https://magecore.atlassian.net/browse/BAP-3632 /* if (!$hasWorkflowItemField) { $this->hideRelationField($entityClass, self::PROPERTY_WORKFLOW_ITEM); } if (!$hasWorkflowStepField) { $this->hideRelationField($entityClass, self::PROPERTY_WORKFLOW_STEP); } $this->configManager->flush(); */ }
/** * Extracts field default values from an annotation and config file * * @param string $scope * @param string $className * @param string $fieldName * @param string $fieldType * @param FieldMetadata|null $metadata * * @return array */ protected function getFieldDefaultValues($scope, $className, $fieldName, $fieldType, $metadata = null) { $propertyConfig = $this->getPropertyConfig($scope); // try to get default values from an annotation if ($metadata && isset($metadata->defaultValues[$scope])) { // combine them with default values from a config file $defaultValues = array_merge($propertyConfig->getDefaultValues(PropertyConfigContainer::TYPE_FIELD, $fieldType), $metadata->defaultValues[$scope]); } else { $defaultValues = $propertyConfig->getDefaultValues(PropertyConfigContainer::TYPE_FIELD, $fieldType); } // process translatable values $translatablePropertyNames = $propertyConfig->getTranslatableValues(PropertyConfigContainer::TYPE_FIELD); foreach ($translatablePropertyNames as $propertyName) { if (empty($defaultValues[$propertyName])) { $defaultValues[$propertyName] = ConfigHelper::getTranslationKey($scope, $propertyName, $className, $fieldName); } } return $defaultValues; }
/** * Makes sure virtual fields for the given entity were loaded * * @param string $className */ protected function ensureVirtualFieldsInitialized($className) { if (!isset($this->virtualFields[$className])) { $this->ensureDictionariesInitialized(); $this->virtualFields[$className] = []; $metadata = $this->getManagerForClass($className)->getClassMetadata($className); $associationNames = $metadata->getAssociationNames(); foreach ($associationNames as $associationName) { $targetClassName = $metadata->getAssociationTargetClass($associationName); if ($metadata->isSingleValuedAssociation($associationName) && isset($this->dictionaries[$targetClassName])) { $fields = $this->dictionaries[$targetClassName]; $isCombinedLabelName = count($fields) > 1; foreach ($fields as $fieldName => $fieldType) { $virtualFieldName = Inflector::tableize(sprintf('%s_%s', $associationName, $fieldName)); $label = $isCombinedLabelName ? $virtualFieldName : Inflector::tableize($associationName); $label = ConfigHelper::getTranslationKey('entity', 'label', $className, $label); $this->virtualFields[$className][$virtualFieldName] = ['query' => ['select' => ['expr' => sprintf('target.%s', $fieldName), 'return_type' => $fieldType, 'label' => $label], 'join' => ['left' => [['join' => sprintf('entity.%s', $associationName), 'alias' => 'target']]]]]; } } } } }
/** * Gets a field label * * @param ClassMetadata $metadata * @param string $fieldName * * @return string */ protected function getFieldLabel(ClassMetadata $metadata, $fieldName) { $className = $metadata->getName(); if (!$metadata->hasField($fieldName) && !$metadata->hasAssociation($fieldName)) { // virtual field or relation return ConfigHelper::getTranslationKey('entity', 'label', $className, $fieldName); } $label = $this->entityConfigProvider->hasConfig($className, $fieldName) ? $this->entityConfigProvider->getConfig($className, $fieldName)->get('label') : null; return !empty($label) ? $label : ConfigHelper::getTranslationKey('entity', 'label', $className, $fieldName); }
/** * @param string $labelKey * @param string $entityClass * @param string $relationName * @param ConfigInterface $targetEntityConfig * * @return string */ protected function getAssociationLabel($labelKey, $entityClass, $relationName, ConfigInterface $targetEntityConfig) { $label = $targetEntityConfig->get($labelKey); if (!$label) { $label = ConfigHelper::getTranslationKey('entity', $labelKey, $entityClass, $relationName); } return $label; }
/** * Gets a field label * * @param string $className * @param string $fieldName * * @return string */ protected function getFieldLabel($className, $fieldName) { $label = $this->entityConfigProvider->hasConfig($className, $fieldName) ? $this->entityConfigProvider->getConfig($className, $fieldName)->get('label') : null; return !empty($label) ? $label : ConfigHelper::getTranslationKey('entity', 'label', $className, $fieldName); }
/** * @Route("/widget/info/{id}", name="oro_entityconfig_widget_info") * @Template * * @param EntityConfigModel $entity * * @return array */ public function infoAction(EntityConfigModel $entity) { list($moduleName, $entityName) = ConfigHelper::getModuleAndEntityNames($entity->getClassName()); /** @var ConfigProvider $entityConfigProvider */ $entityConfigProvider = $this->get('oro_entity_config.provider.entity'); /** @var ConfigProvider $extendConfigProvider */ $extendConfigProvider = $this->get('oro_entity_config.provider.extend'); $extendConfig = $extendConfigProvider->getConfig($entity->getClassName()); /** @var ConfigProvider $securityConfigProvider */ $securityConfigProvider = $this->get('oro_entity_config.provider.security'); $securityConfig = $securityConfigProvider->getConfig($entity->getClassName()); /** @var ConfigProvider $ownershipConfigProvider */ $ownershipConfigProvider = $this->get('oro_entity_config.provider.ownership'); $ownerTypes = $this->get('oro_organization.form.type.ownership_type')->getOwnershipsArray(); $ownerType = $ownershipConfigProvider->getConfig($entity->getClassName())->get('owner_type'); $ownerType = $ownerTypes[empty($ownerType) ? 'NONE' : $ownerType]; return ['entity' => $entity, 'entity_config' => $entityConfigProvider->getConfig($entity->getClassName()), 'entity_extend' => $extendConfig, 'entity_owner_type' => $ownerType, 'entity_name' => $entityName, 'module_name' => $moduleName, 'security_config' => $securityConfig]; }
/** * @param string $className * @return bool */ public function supports($className) { return !ConfigHelper::isConfigModelEntity($className) && $this->extendConfigProvider->hasConfig($className) && $this->extendConfigProvider->getConfig($className)->is('is_extend'); }
/** * @dataProvider getModuleAndEntityNamesProvider */ public function testGetModuleAndEntityNames($className, $expectedModuleName, $expectedEntityName) { list($moduleName, $entityName) = ConfigHelper::getModuleAndEntityNames($className); $this->assertEquals($expectedModuleName, $moduleName); $this->assertEquals($expectedEntityName, $entityName); }
/** * @param FormBuilderInterface|FormInterface $builder * @param $dataClass * @param string $permission * @param array $data * @param int $entityId */ protected function addUserOwnerField($builder, $dataClass, $permission = "CREATE", $data = null, $entityId = 0) { /** * Showing user owner box for entities with owner type USER if assign permission is * granted. */ if ($this->isAssignGranted || $permission == 'ASSIGN') { $formBuilder = $builder instanceof FormInterface ? $builder->getConfig() : $builder; $isRequired = $formBuilder->getOption('required'); $options = ['label' => ConfigHelper::getTranslationKey('entity', 'label', $dataClass, $this->fieldName), 'required' => true, 'constraints' => $isRequired ? [new NotBlank()] : [], 'autocomplete_alias' => 'acl_users', 'configs' => ['placeholder' => 'oro.user.form.choose_user', 'result_template_twig' => 'OroUserBundle:User:Autocomplete/result.html.twig', 'selection_template_twig' => 'OroUserBundle:User:Autocomplete/selection.html.twig', 'component' => 'acl-user-autocomplete', 'permission' => $permission, 'entity_name' => str_replace('\\', '_', $dataClass), 'entity_id' => $entityId]]; if (null !== $data) { $options['data'] = $data; } $builder->add($this->fieldName, 'oro_user_acl_select', $options); } }
/** * Finds a model for an entity field * * @param string $className * @param string $fieldName * * @return FieldConfigModel|null An instance of FieldConfigModel or null if a model was not found */ public function findFieldModel($className, $fieldName) { if (empty($className) || empty($fieldName) || ConfigHelper::isConfigModelEntity($className)) { return null; } $this->ensureFieldCacheWarmed($className); $result = null; // check if a model exists in the local cache if (isset($this->fields[$className]) && array_key_exists($fieldName, $this->fields[$className])) { $result = $this->fields[$className][$fieldName]; if ($result && $this->isEntityDetached($result)) { // the detached model must be reloaded $this->entities[$className] = false; unset($this->fields[$className]); $result = $this->findFieldModel($className, $fieldName); } } return $result; }
/** * @param string $labelKey * @param string $className * @param string|null $fieldName * * @return string */ protected function getLabel($labelKey, $className, $fieldName = null) { return ConfigHelper::getTranslationKey('entity', $labelKey, $className, $fieldName); }
/** * Makes sure virtual fields for the given entity were loaded * * @param string $className */ protected function ensureVirtualFieldsInitialized($className) { if (!isset($this->virtualFields[$className])) { $this->ensureDictionariesInitialized(); $this->virtualFields[$className] = []; $metadata = $this->getManagerForClass($className)->getClassMetadata($className); $associationNames = $metadata->getAssociationNames(); foreach ($associationNames as $associationName) { $targetClassName = $metadata->getAssociationTargetClass($associationName); if (isset($this->dictionaries[$targetClassName])) { $fields = $this->dictionaries[$targetClassName]; $isCombinedLabelName = count($fields) > 1; $fieldNames = array_keys($fields); $target = Inflector::tableize(uniqid(sprintf('t_%s', $associationName), false)); foreach ($fieldNames as $fieldName) { $virtualFieldName = Inflector::tableize(sprintf('%s_%s', $associationName, $fieldName)); $fieldName = Inflector::tableize($fieldName); $label = $isCombinedLabelName ? $virtualFieldName : Inflector::tableize($associationName); $label = ConfigHelper::getTranslationKey('entity', 'label', $className, $label); $this->virtualFields[$className][$virtualFieldName] = ['query' => ['select' => ['expr' => sprintf('%s.%s', $target, $fieldName), 'return_type' => GroupingScope::GROUP_DICTIONARY, 'related_entity_name' => $targetClassName, 'label' => $label], 'join' => ['left' => [['join' => sprintf('entity.%s', $associationName), 'alias' => $target]]]]]; } } } } }