Last active
November 20, 2023 14:12
-
-
Save Brewal/4a623208e7cd60c4dfb5ab9ab56bcb2e to your computer and use it in GitHub Desktop.
Doctrine : ignore table columns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Doctrine\EventListener; | |
use Doctrine\DBAL\Exception; | |
use Doctrine\DBAL\Schema\AbstractSchemaManager; | |
use Doctrine\DBAL\Schema\Schema; | |
use Doctrine\DBAL\Schema\SchemaException; | |
use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; | |
final class IgnoreFieldsListener | |
{ | |
private ?Schema $schema = null; | |
// @phpstan-ignore-next-line | |
private ?AbstractSchemaManager $schemaManager = null; | |
/** | |
* @param array{string: array<string>} $ignoreFields | |
*/ | |
public function __construct(private array $ignoreFields) | |
{ | |
} | |
/** | |
* @throws SchemaException | |
* @throws Exception | |
*/ | |
public function postGenerateSchema(GenerateSchemaEventArgs $args): void | |
{ | |
$this->schema = $args->getSchema(); | |
$this->schemaManager = $args->getEntityManager()->getConnection()->createSchemaManager(); | |
foreach ($this->ignoreFields as $tableToFilter => $columnsToIgnore) { | |
$this->ignoreColumns($tableToFilter, $columnsToIgnore); | |
$this->ignoreIndexes($tableToFilter, $columnsToIgnore); | |
$this->ignoreForeignKeys($tableToFilter, $columnsToIgnore); | |
} | |
} | |
/** | |
* @param array<array-key, string> $columnsToIgnore | |
*/ | |
private function ignoreColumns(string $table, array $columnsToIgnore): void | |
{ | |
$columns = $this->getSchemaManager()->listTableColumns($table); | |
foreach ($columns as $column) { | |
$columnName = $column->getName(); | |
if (!in_array($columnName, $columnsToIgnore)) { | |
continue; | |
} | |
$columnType = $column->getType(); | |
$typeName = $columnType->getTypeRegistry()->lookupName($columnType); | |
$this->getSchema()->getTable($table)->addColumn($columnName, $typeName); | |
} | |
} | |
/** | |
* @param array<array-key, string> $columnsToIgnore | |
*/ | |
private function ignoreForeignKeys(string $table, array $columnsToIgnore): void | |
{ | |
$foreignKeys = $this->getSchemaManager()->listTableForeignKeys($table); | |
foreach ($foreignKeys as $foreignKey) { | |
$foreignKeyColumns = $foreignKey->getLocalColumns(); | |
if (!empty(array_diff($foreignKeyColumns, $columnsToIgnore))) { | |
continue; | |
} | |
$this->getSchema()->getTable($table)->addForeignKeyConstraint( | |
$table, | |
$foreignKey->getLocalColumns(), | |
$foreignKey->getForeignColumns(), | |
$foreignKey->getOptions(), | |
$foreignKey->getName(), | |
); | |
} | |
} | |
/** | |
* @param array<array-key, string> $columnsToIgnore | |
*/ | |
private function ignoreIndexes(string $table, array $columnsToIgnore): void | |
{ | |
$indexes = $this->getSchemaManager()->listTableIndexes($table); | |
foreach ($indexes as $index) { | |
$indexColumns = $index->getColumns(); | |
if (!empty(array_diff($indexColumns, $columnsToIgnore))) { | |
continue; | |
} | |
if ($index->isUnique()) { | |
$this->getSchema()->getTable($table)->addUniqueIndex( | |
$indexColumns, | |
$index->getName(), | |
$index->getOptions(), | |
); | |
continue; | |
} | |
$this->getSchema()->getTable($table)->addIndex( | |
$indexColumns, | |
$index->getName(), | |
$index->getFlags(), | |
$index->getOptions(), | |
); | |
} | |
} | |
private function getSchema(): Schema | |
{ | |
if (null === $this->schema) { | |
throw new \LogicException('schema should be set in postGenerateSchema'); | |
} | |
return $this->schema; | |
} | |
// @phpstan-ignore-next-line | |
private function getSchemaManager(): AbstractSchemaManager | |
{ | |
if (null === $this->schemaManager) { | |
throw new \LogicException('schemaManager should be set in postGenerateSchema'); | |
} | |
return $this->schemaManager; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// *** | |
$services->set(App\Doctrine\EventListerner\IgnoreFieldsListener::class) | |
->autoconfigure(false) | |
->arg('$ignoreFields', [ | |
'a_table_name' => ['a_field_to_ignore', 'another_field_to_ignore'], | |
'another_table_name' => ['a_field_to_ignore'], | |
]) | |
->tag('doctrine.event_listener', ['event' => 'postGenerateSchema']); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
services: | |
# *** | |
App\Doctrine\EventListerner\IgnoreFieldsListener: | |
arguments: | |
$ignoreFields: | |
- my_table_name: ['a_field_to_ignore', 'another_field_to_ignore'] | |
- another_table_name: ['a_field_to_ignore'], | |
tags: | |
- name: 'doctrine.event_listener' | |
event: 'postGenerateSchema' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment