/** * @param LoggerInterface $logger * @param bool $dryRun */ protected function addActivityContactColumns(LoggerInterface $logger, $dryRun = false) { $hasSchemaChanges = false; $toSchema = clone $this->schema; $contactingActivityClasses = $this->activityContactProvider->getSupportedActivityClasses(); $entities = $this->getConfigurableEntitiesData($logger); foreach ($entities as $entityClassName => $config) { // Skipp excluded entity if (TargetExcludeList::isExcluded($entityClassName)) { continue; } if ($this->canAddField($config, $contactingActivityClasses)) { $tableName = $this->getTableName($config, $entityClassName); // Process only existing tables if (!$toSchema->hasTable($tableName)) { continue; } $table = $toSchema->getTable($tableName); $tableColumns = $table->getColumns(); /** * Check if entity already has all needed columns. * If at least one is not present we should check and add it. */ if ($this->hasEntityNeededColumns($tableColumns)) { continue; } foreach (ActivityScope::$fieldsConfiguration as $fieldName => $fieldConfig) { if (!$table->hasColumn($fieldName)) { $hasSchemaChanges = $this->addColumn($table, $fieldName, $fieldConfig); } } } } $this->runSchemaRelated($logger, $dryRun, $hasSchemaChanges, $toSchema); }
public function setUp() { $this->provider = new ActivityContactProvider(); $directionProvider = new TestDirectionProvider(); $this->provider->addProvider($directionProvider); $this->doctrineHelper = $this->getMockBuilder('Oro\\Bundle\\EntityBundle\\ORM\\DoctrineHelper')->disableOriginalConstructor()->getMock(); $this->listener = new ActivityListener($this->provider, $this->doctrineHelper); }
/** * @param EntityManager $em * @param PropertyAccessorInterface $accessor */ protected function processUpdatedEntities(EntityManager $em, PropertyAccessorInterface $accessor) { foreach ($this->updatedEntities as $activityData) { foreach ($activityData['targets'] as $targetInfo) { $direction = $targetInfo['direction']; $isDirectionChanged = $targetInfo['is_direction_changed']; $target = $em->getRepository($targetInfo['class'])->find($targetInfo['id']); /** process dates */ if ($direction === DirectionProviderInterface::DIRECTION_INCOMING) { $contactDatePath = ActivityScope::LAST_CONTACT_DATE_IN; $oppositeContactDatePath = ActivityScope::LAST_CONTACT_DATE_OUT; $oppositeDirection = DirectionProviderInterface::DIRECTION_OUTGOING; } else { $contactDatePath = ActivityScope::LAST_CONTACT_DATE_OUT; $oppositeContactDatePath = ActivityScope::LAST_CONTACT_DATE_IN; $oppositeDirection = DirectionProviderInterface::DIRECTION_INCOMING; } $lastActivityDate = $this->activityContactProvider->getLastContactActivityDate($em, $target, $direction); if ($lastActivityDate) { $accessor->setValue($target, ActivityScope::LAST_CONTACT_DATE, $lastActivityDate['all']); $accessor->setValue($target, $contactDatePath, $lastActivityDate['direction']); $accessor->setValue($target, $oppositeContactDatePath, $this->activityContactProvider->getLastContactActivityDate($em, $target, $oppositeDirection)['direction']); } /** process counts (in case direction was changed) */ if ($isDirectionChanged) { list($oldDirection, $newDirection) = $this->getDirectionProperties($direction, $isDirectionChanged); $accessor->setValue($target, $newDirection, (int) $accessor->getValue($target, $newDirection) + 1); $accessor->setValue($target, $oldDirection, (int) $accessor->getValue($target, $oldDirection) - 1); } $em->persist($target); } } $this->updatedEntities = []; }
/** * @param LoggerInterface $logger * @param bool $dryRun */ protected function addActivityContactColumns(LoggerInterface $logger, $dryRun = false) { $hasSchemaChanges = false; $toSchema = clone $this->schema; $contactingActivityClasses = $this->activityContactProvider->getSupportedActivityClasses(); $entities = $this->getConfigurableEntitiesData($logger); foreach ($entities as $entityClassName => $config) { if (isset($config['extend']['is_extend'], $config['activity']['activities']) && $config['extend']['is_extend'] == true && $config['activity']['activities'] && array_intersect($contactingActivityClasses, $config['activity']['activities'])) { if (isset($config['extend']['schema']['doctrine'][$entityClassName]['table'])) { $tableName = $config['extend']['schema']['doctrine'][$entityClassName]['table']; } else { $tableName = $this->metadataHelper->getTableNameByEntityClass($entityClassName); } // Process only existing tables if (!$toSchema->hasTable($tableName)) { continue; } $table = $toSchema->getTable($tableName); $tableColumns = $table->getColumns(); /** * Check if entity already has all needed columns. * If at least one is not present we should check and add it. */ if (false === (bool) array_diff(array_keys(ActivityScope::$fieldsConfiguration), array_intersect(array_keys($tableColumns), array_keys(ActivityScope::$fieldsConfiguration)))) { continue; } foreach (ActivityScope::$fieldsConfiguration as $fieldName => $fieldConfig) { if (!$table->hasColumn($fieldName)) { $hasSchemaChanges = true; $table->addColumn($fieldName, $fieldConfig['type'], ['notnull' => false, OroOptions::KEY => array_merge([ExtendOptionsManager::MODE_OPTION => $fieldConfig['mode']], $fieldConfig['options'])]); } } } } if ($hasSchemaChanges) { // Run schema related SQLs manually because this query run when diff is already calculated by schema tool $comparator = new Comparator(); $platform = $this->connection->getDatabasePlatform(); $schemaDiff = $comparator->compare($this->schema, $toSchema); foreach ($schemaDiff->toSql($platform) as $query) { $this->logQuery($logger, $query); if (!$dryRun) { $this->connection->query($query); } } } }
/** * {@inheritdoc} */ public function preUpdate() { /** @var ConfigProvider $extendConfigProvider */ $extendConfigProvider = $this->configManager->getProvider('extend'); /** @var ConfigProvider $activityConfigProvider */ $activityConfigProvider = $this->configManager->getProvider('activity'); $contactingActivityClasses = $this->activityContactProvider->getSupportedActivityClasses(); $entityConfigs = $extendConfigProvider->getConfigs(); foreach ($entityConfigs as $entityConfig) { if ($entityConfig->is('is_extend')) { $entityClassName = $entityConfig->getId()->getClassName(); // Skipp excluded entity if (TargetExcludeList::isExcluded($entityClassName)) { continue; } /** * Check if entity has any activity from contact activities group */ $entityActivities = $activityConfigProvider->getConfig($entityClassName)->get('activities'); if (!$entityActivities || !array_intersect($contactingActivityClasses, $entityActivities)) { continue; } /** @var ConfigInterface[] $entityFields */ $entityFields = $extendConfigProvider->getConfigs($entityClassName); $entityFieldNames = array_map(function (ConfigInterface $item) { return $item->getId()->getFieldName(); }, $entityFields); /** * Check if entity already has all needed fields. * If at least one is not present we should check and add it too. */ if (false === (bool) array_diff(array_keys(ActivityScope::$fieldsConfiguration), array_intersect($entityFieldNames, array_keys(ActivityScope::$fieldsConfiguration)))) { continue; } foreach (ActivityScope::$fieldsConfiguration as $fieldName => $fieldConfig) { if (!in_array($fieldName, $entityFieldNames)) { $this->configManager->createConfigFieldModel($entityClassName, $fieldName, $fieldConfig['type'], $fieldConfig['mode']); $this->updateConfigs($entityClassName, $fieldName, $fieldConfig['options']); } } } } }
/** * Save collected changes * * @param PostFlushEventArgs $args */ public function postFlush(PostFlushEventArgs $args) { $em = $args->getEntityManager(); if (!empty($this->deletedEntities) || !empty($this->updatedEntities)) { $accessor = PropertyAccess::createPropertyAccessor(); /** process deleted entities */ foreach ($this->deletedEntities as $activityData) { foreach ($activityData['targets'] as $targetInfo) { $direction = $targetInfo['direction']; $target = $em->getRepository($targetInfo['class'])->find($targetInfo['id']); $accessor->setValue($target, ActivityScope::CONTACT_COUNT, (int) $accessor->getValue($target, ActivityScope::CONTACT_COUNT) - 1); $directionCountPath = ActivityScope::CONTACT_COUNT_OUT; $contactDatePath = ActivityScope::LAST_CONTACT_DATE_OUT; if ($direction === DirectionProviderInterface::DIRECTION_INCOMING) { $directionCountPath = ActivityScope::CONTACT_COUNT_IN; $contactDatePath = ActivityScope::LAST_CONTACT_DATE_IN; } $accessor->setValue($target, $directionCountPath, (int) $accessor->getValue($target, $directionCountPath) - 1); $activityDate = $this->activityContactProvider->getLastContactActivityDate($em, $target, $direction, $activityData['id'], $activityData['class']); if ($activityDate) { $accessor->setValue($target, ActivityScope::LAST_CONTACT_DATE, $activityDate['all']); $accessor->setValue($target, $contactDatePath, $activityDate['direction']); } $em->persist($target); } } /** process updated entities */ foreach ($this->updatedEntities as $activityData) { foreach ($activityData['targets'] as $targetInfo) { $direction = $targetInfo['direction']; $isDirectionChanged = $targetInfo['is_direction_changed']; $target = $em->getRepository($targetInfo['class'])->find($targetInfo['id']); /** process dates */ if ($direction === DirectionProviderInterface::DIRECTION_INCOMING) { $contactDatePath = ActivityScope::LAST_CONTACT_DATE_IN; $oppositeContactDatePath = ActivityScope::LAST_CONTACT_DATE_OUT; $oppositeDirection = DirectionProviderInterface::DIRECTION_OUTGOING; } else { $contactDatePath = ActivityScope::LAST_CONTACT_DATE_OUT; $oppositeContactDatePath = ActivityScope::LAST_CONTACT_DATE_IN; $oppositeDirection = DirectionProviderInterface::DIRECTION_INCOMING; } $lastActivityDate = $this->activityContactProvider->getLastContactActivityDate($em, $target, $direction); if ($lastActivityDate) { $accessor->setValue($target, ActivityScope::LAST_CONTACT_DATE, $lastActivityDate['all']); $accessor->setValue($target, $contactDatePath, $lastActivityDate['direction']); $accessor->setValue($target, $oppositeContactDatePath, $this->activityContactProvider->getLastContactActivityDate($em, $target, $oppositeDirection)['direction']); } /** process counts (in case direction was changed) */ if ($isDirectionChanged) { $increment = ActivityScope::CONTACT_COUNT_OUT; $decrement = ActivityScope::CONTACT_COUNT_IN; if ($direction === DirectionProviderInterface::DIRECTION_INCOMING) { $increment = ActivityScope::CONTACT_COUNT_IN; $decrement = ActivityScope::CONTACT_COUNT_OUT; } $accessor->setValue($target, $increment, (int) $accessor->getValue($target, $increment) + 1); $accessor->setValue($target, $decrement, (int) $accessor->getValue($target, $decrement) - 1); } $em->persist($target); } } $this->deletedEntities = []; $this->updatedEntities = []; $em->flush(); } }