From bbccc036173fc9c68380cb6c5840e2be03417dda Mon Sep 17 00:00:00 2001 From: Tobias Feijten Date: Tue, 30 Jul 2024 21:40:18 +0200 Subject: [PATCH] Allow higher Doctrine and Symfony dependencies --- Configuration/HistoryConfiguration.php | 6 ++-- .../BobvEntityHistoryExtension.php | 4 +-- DependencyInjection/Configuration.php | 4 +-- EventSubscriber/CreateSchemaSubscriber.php | 13 ++++---- EventSubscriber/LogHistorySubscriber.php | 26 ++++++++------- Reader/HistoryCollection.php | 4 +-- Reader/HistoryReader.php | 32 +++++++++---------- composer.json | 8 +++-- 8 files changed, 51 insertions(+), 46 deletions(-) diff --git a/Configuration/HistoryConfiguration.php b/Configuration/HistoryConfiguration.php index 2e5082d..418417f 100644 --- a/Configuration/HistoryConfiguration.php +++ b/Configuration/HistoryConfiguration.php @@ -2,6 +2,8 @@ namespace Bobv\EntityHistoryBundle\Configuration; +use Exception; +use LogicException; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; /** @@ -80,8 +82,8 @@ public function getDeletedByValue(): mixed { $method = $this->deletedByMethod; try { return $this->authorizationChecker->$method(); - } catch (\Exception $e) { - throw new \LogicException(sprintf('The method "%s" could not be called on "%s" to generate the deleted by value', $method, get_class($this->authorizationChecker))); + } catch (Exception) { + throw new LogicException(sprintf('The method "%s" could not be called on "%s" to generate the deleted by value', $method, get_class($this->authorizationChecker))); } } diff --git a/DependencyInjection/BobvEntityHistoryExtension.php b/DependencyInjection/BobvEntityHistoryExtension.php index 0425560..5f3e18f 100644 --- a/DependencyInjection/BobvEntityHistoryExtension.php +++ b/DependencyInjection/BobvEntityHistoryExtension.php @@ -25,7 +25,7 @@ public function load(array $configs, ContainerBuilder $container): void { $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.yml'); - $configurables = array( + $configurables = [ 'table_prefix', 'table_suffix', 'revision_field_name', @@ -34,7 +34,7 @@ public function load(array $configs, ContainerBuilder $container): void { 'deleted_at_field', 'deleted_by_field', 'deleted_by_method', - ); + ]; foreach ($configurables as $key) { $container->setParameter("bobv.entityhistory." . $key, $config[$key]); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 97c2393..ca20286 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -23,11 +23,11 @@ public function getConfigTreeBuilder(): TreeBuilder ->children() ->arrayNode('entities') ->prototype('scalar')->end() - ->defaultValue(array()) + ->defaultValue([]) ->end() ->arrayNode('connections') ->prototype('scalar')->end() - ->defaultValue(array('default')) + ->defaultValue(['default']) ->end() ->scalarNode('table_prefix') ->defaultValue('_HISTORY_') diff --git a/EventSubscriber/CreateSchemaSubscriber.php b/EventSubscriber/CreateSchemaSubscriber.php index 05d53c0..b6dbc38 100644 --- a/EventSubscriber/CreateSchemaSubscriber.php +++ b/EventSubscriber/CreateSchemaSubscriber.php @@ -4,6 +4,7 @@ use Bobv\EntityHistoryBundle\Configuration\HistoryConfiguration; use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Types\Type; use Doctrine\ORM\Tools\Event\GenerateSchemaTableEventArgs; /** @@ -38,25 +39,23 @@ public function postGenerateSchemaTable(GenerateSchemaTableEventArgs $eventArgs) // Get id column (if any) if ($entityTable->hasColumn('id')) { - /* @var $column Column */ $column = $entityTable->getColumn('id'); - $revisionTable->addColumn($column->getName(), $column->getType()->getName(), array_merge( + $revisionTable->addColumn($column->getName(), Type::lookupName($column->getType()), array_merge( $this->getColumnOptions($column), - array('notnull' => false, 'autoincrement' => false) + ['notnull' => false, 'autoincrement' => false] )); } // Add revision info $revisionTable->addColumn($this->configuration->getRevisionFieldName(), 'integer'); - $revisionTable->addColumn($this->configuration->getRevisionTypeFieldName(), 'string', array('length' => 4)); + $revisionTable->addColumn($this->configuration->getRevisionTypeFieldName(), 'string', ['length' => 4]); // Get each column (except id) and add it to the table foreach ($entityTable->getColumns() AS $column) { if ($column->getName() == 'id') continue; - /* @var $column Column */ - $revisionTable->addColumn($column->getName(), $column->getType()->getName(), array_merge( + $revisionTable->addColumn($column->getName(), Type::lookupName($column->getType()), array_merge( $this->getColumnOptions($column), - array('notnull' => false, 'autoincrement' => false) + ['notnull' => false, 'autoincrement' => false] )); } diff --git a/EventSubscriber/LogHistorySubscriber.php b/EventSubscriber/LogHistorySubscriber.php index c9e46c7..1196721 100644 --- a/EventSubscriber/LogHistorySubscriber.php +++ b/EventSubscriber/LogHistorySubscriber.php @@ -3,6 +3,7 @@ namespace Bobv\EntityHistoryBundle\EventSubscriber; use Bobv\EntityHistoryBundle\Configuration\HistoryConfiguration; +use DateTime; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; @@ -12,6 +13,9 @@ use Doctrine\ORM\Event\PostUpdateEventArgs; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\UnitOfWork; +use Doctrine\ORM\Utility\PersisterHelper; +use LogicException; +use PDO; /** * Based on the work of @@ -65,7 +69,7 @@ public function onFlush(OnFlushEventArgs $eventArgs): void { // Check if there is a deletedAt field configured which we can set if (null !== ($deletedAtField = $this->config->getDeletedAtField())) { $deletedAtValue = []; - $deletedAtValue[$deletedAtField] = new \DateTime(); + $deletedAtValue[$deletedAtField] = new DateTime(); $entityData = array_merge($entityData, $deletedAtValue); } @@ -102,7 +106,7 @@ public function postUpdate(PostUpdateEventArgs $eventArgs): void { return; } - $entityData = array_merge($this->getOriginalEntityData($entity), $this->uow->getEntityIdentifier($entity)); + $entityData = array_merge($this->getOriginalEntityData($entity), $this->uow->getEntityIdentifier($entity)); // Check if the deleted field was set before, if so, it if and REVERT if ($this->config->isReverted($class->name, $entityData['id'])) { $this->saveRevisionEntityData($class, $entityData, 'REV'); @@ -113,13 +117,13 @@ public function postUpdate(PostUpdateEventArgs $eventArgs): void { private function getInsertRevisionSQL(ClassMetadata $class): string { if (!isset($this->insertRevisionSQL[$class->name])) { - $placeholders = array('?', '?'); + $placeholders = ['?', '?']; $tableName = $this->config->getTableName($class->table['name']); $sql = "INSERT INTO " . $tableName . " (" . $this->config->getRevisionFieldName() . ", " . $this->config->getRevisionTypeFieldName(); - $fields = array(); + $fields = []; // Find associations and copy the data foreach ($class->associationMappings AS $assoc) { @@ -178,7 +182,7 @@ private function getRevisionId(ClassMetadata $class, $entityData, $revType): int // Get identifier info and use it in the select query $count = 1; - $where = " WHERE "; + $where = ' WHERE '; foreach ($identifiers as $identifier) { if ($count > 1) { $where .= ' AND '; @@ -198,17 +202,17 @@ private function getRevisionId(ClassMetadata $class, $entityData, $revType): int if ($result->rowCount() == 1) { return $result->fetchAssociative()[$this->config->getRevisionFieldName()] + 1; } elseif ($result->rowCount() > 1) { - throw new \LogicException('Error while selecting new rev number'); + throw new LogicException('Error while selecting new rev number'); } else { return 1; } } private function saveRevisionEntityData(ClassMetadata $class, array $entityData, string $revType): void { - $params = array($this->getRevisionId($class, $entityData, $revType), $revType); - $types = array(\PDO::PARAM_INT, \PDO::PARAM_STR); + $params = [$this->getRevisionId($class, $entityData, $revType), $revType]; + $types = [PDO::PARAM_INT, PDO::PARAM_STR]; - $fields = array(); + $fields = []; foreach ($class->associationMappings AS $field => $assoc) { if (($assoc['type'] & ClassMetadata::TO_ONE) > 0 && $assoc['isOwningSide']) { @@ -224,10 +228,10 @@ private function saveRevisionEntityData(ClassMetadata $class, array $entityData, $fields[$sourceColumn] = true; if ($entityData[$field] === NULL) { $params[] = NULL; - $types[] = \PDO::PARAM_STR; + $types[] = PDO::PARAM_STR; } else { $params[] = $relatedId[$targetClass->fieldNames[$targetColumn]]; - $types[] = $targetClass->getTypeOfColumn($targetColumn); + $types[] = PersisterHelper::getTypeOfColumn($targetColumn, $targetClass, $this->em); } } } diff --git a/Reader/HistoryCollection.php b/Reader/HistoryCollection.php index 2889af5..5705a01 100644 --- a/Reader/HistoryCollection.php +++ b/Reader/HistoryCollection.php @@ -14,7 +14,7 @@ class HistoryCollection * order, as otherwise you will have to sort them. */ public function addRevision(HistoryRevision $revision): self { - if(!isset($this->revisions[$revision->getEntityId()])){ + if (!isset($this->revisions[$revision->getEntityId()])) { $this->revisions[$revision->getEntityId()] = []; } @@ -36,7 +36,7 @@ public function getAllRevisions(): array { } public function getRevisionCount($entityId = null): int { - if($entityId === null){ + if ($entityId === null) { $count = 0; foreach ($this->revisions as $revisions) { $count += count($revisions); diff --git a/Reader/HistoryReader.php b/Reader/HistoryReader.php index 37a681f..1321c47 100644 --- a/Reader/HistoryReader.php +++ b/Reader/HistoryReader.php @@ -12,9 +12,9 @@ use Doctrine\DBAL\Types\Type; use Doctrine\ORM\EntityManager; use Doctrine\ORM\Mapping\ClassMetadata; -use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\Persisters\Entity\EntityPersister; +use RuntimeException; /** * Based on the work of @@ -80,15 +80,15 @@ public function findRevisionsByCriteria(string $className, array $criteria): His // Check if the given criteria are indeed available in the object // and create the actual where query - $whereSql = ""; + $whereSql = ''; foreach ($criteria as $criterium => $data) { if ($whereSql) { - $whereSql .= " AND "; + $whereSql .= ' AND '; } if ($metadata->hasField($criterium)) { - $whereSql .= "h." . $metadata->getFieldMapping($criterium)['columnName'] . " = ?"; + $whereSql .= 'h.' . $metadata->getFieldMapping($criterium)['columnName'] . ' = ?'; } else if ($metadata->hasAssociation($criterium)) { - $whereSql .= "h." . $metadata->getAssociationMapping($criterium)['joinColumns'][0]['name'] . " = ?"; + $whereSql .= 'h.' . $metadata->getAssociationMapping($criterium)['joinColumns'][0]['name'] . ' = ?'; } else { throw new IncorrectCriteriaException($criterium, $className); } @@ -96,7 +96,7 @@ public function findRevisionsByCriteria(string $className, array $criteria): His // Create the query with the where statement $tableName = $this->config->getTableName($metadata->getTableName()); - $query = 'SELECT * FROM ' . $tableName . ' h WHERE ' . $whereSql . " ORDER BY h.id DESC"; + $query = 'SELECT * FROM ' . $tableName . ' h WHERE ' . $whereSql . ' ORDER BY h.id DESC'; // Execute query $revisions = $this->em->getConnection()->fetchAllAssociative($query, array_values($criteria)); @@ -131,7 +131,7 @@ public function restoreObject(string $className, &$dbObject, HistoryRevision $re if ($oldValue != $newValue) { $metadata->setFieldValue($dbObject, $associationName, $newValue); $uow->propertyChanged($dbObject, $associationName, $oldValue, $newValue); - $changeset[$associationName] = array($oldValue, $newValue); + $changeset[$associationName] = [$oldValue, $newValue]; } } @@ -143,7 +143,7 @@ public function restoreObject(string $className, &$dbObject, HistoryRevision $re $oldValue = $metadata->getFieldValue($dbObject, $this->config->getDeletedAtField()); $metadata->setFieldValue($dbObject, $this->config->getDeletedAtField(), null); $uow->propertyChanged($dbObject, $this->config->getDeletedAtField(), $oldValue, null); - $changeset[$this->config->getDeletedAtField()] = array($oldValue, null); + $changeset[$this->config->getDeletedAtField()] = [$oldValue, null]; } // Check if there is a deletedBy field configured which we can clear @@ -151,7 +151,7 @@ public function restoreObject(string $className, &$dbObject, HistoryRevision $re $oldValue = $metadata->getFieldValue($dbObject, $this->config->getDeletedByField()); $metadata->setFieldValue($dbObject, $this->config->getDeletedByField(), null); $uow->propertyChanged($dbObject, $this->config->getDeletedByField(), $oldValue, null); - $changeset[$this->config->getDeletedByField()] = array($oldValue, null); + $changeset[$this->config->getDeletedByField()] = [$oldValue, null]; } } @@ -201,7 +201,6 @@ private function getMetadata(string $className): false|ClassMetadata { * Simplified and stolen code from UnitOfWork::createEntity. */ private function createEntity(string $className, array $data, $revision): object { - /** @var ClassMetadataInfo|ClassMetadata $class */ $class = $this->em->getClassMetadata($className); //lookup revisioned entity cache $keyParts = []; @@ -215,22 +214,22 @@ private function createEntity(string $className, array $data, $revision): object if (!$class->isInheritanceTypeNone()) { if (!isset($data[$class->discriminatorColumn['name']])) { - throw new \RuntimeException('Expecting discriminator value in data set.'); + throw new RuntimeException('Expecting discriminator value in data set.'); } $discriminator = $data[$class->discriminatorColumn['name']]; if (!isset($class->discriminatorMap[$discriminator])) { - throw new \RuntimeException("No mapping found for [{$discriminator}]."); + throw new RuntimeException("No mapping found for [{$discriminator}]."); } if ($class->discriminatorValue) { $entity = $this->em->getClassMetadata($class->discriminatorMap[$discriminator])->newInstance(); } else { //a complex case when ToOne binding is against AbstractEntity having no discriminator - $pk = array(); + $pk = []; foreach ($class->identifier as $field) { $pk[$class->getColumnName($field)] = $data[$field]; } // return $this->find($class->discriminatorMap[$discriminator], $pk, $revision); - throw new \RuntimeException("This is not supported"); + throw new RuntimeException("This is not supported"); } } else { $entity = $class->newInstance(); @@ -249,9 +248,8 @@ private function createEntity(string $className, array $data, $revision): object if (isset($hints['fetched'][$className][$field])) { continue; } - /** @var ClassMetadataInfo|ClassMetadata $targetClass */ $targetClass = $this->em->getClassMetadata($assoc['targetEntity']); - if ($assoc['type'] & ClassMetadataInfo::TO_ONE) { + if ($assoc['type'] & ClassMetadata::TO_ONE) { if ($assoc['isOwningSide']) { $associatedId = array(); foreach ($assoc['targetToSourceKeyColumns'] as $targetColumn => $srcColumn) { @@ -272,7 +270,7 @@ private function createEntity(string $className, array $data, $revision): object $class->reflFields[$field]->setValue($entity, $this->getEntityPersister($assoc['targetEntity']) ->loadOneToOneEntity($assoc, $entity)); } - } elseif ($assoc['type'] & ClassMetadataInfo::ONE_TO_MANY) { + } elseif ($assoc['type'] & ClassMetadata::ONE_TO_MANY) { $collection = new PersistentCollection($this->em, $targetClass, new ArrayCollection()); $this->getEntityPersister($assoc['targetEntity']) ->loadOneToManyCollection($assoc, $entity, $collection); diff --git a/composer.json b/composer.json index 683f74d..31d6bd0 100644 --- a/composer.json +++ b/composer.json @@ -13,9 +13,11 @@ ], "require": { "php": "^8.1", - "doctrine/orm": "^2.16", - "symfony/framework-bundle": "^5.4|^6.4", - "symfony/security-core": "^5.4|^6.4" + "ext-pdo": "*", + "doctrine/orm": "^2.16|^3.0", + "doctrine/dbal": "^3.0|^4.0", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/security-core": "^5.4|^6.4|^7.0" }, "autoload": { "psr-4": {