Skip to content

Instantly share code, notes, and snippets.

@Brewal
Last active November 20, 2023 14:12
Show Gist options
  • Save Brewal/4a623208e7cd60c4dfb5ab9ab56bcb2e to your computer and use it in GitHub Desktop.
Save Brewal/4a623208e7cd60c4dfb5ab9ab56bcb2e to your computer and use it in GitHub Desktop.
Doctrine : ignore table columns
<?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;
}
}
<?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']);
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