vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/SingleTablePersister.php line 148

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\ORM\Persisters\Entity;
  4. use Doctrine\Common\Collections\Criteria;
  5. use Doctrine\ORM\Internal\SQLResultCasing;
  6. use Doctrine\ORM\Mapping\ClassMetadata;
  7. use Doctrine\ORM\Utility\PersisterHelper;
  8. use function array_flip;
  9. use function implode;
  10. /**
  11.  * Persister for entities that participate in a hierarchy mapped with the
  12.  * SINGLE_TABLE strategy.
  13.  *
  14.  * @link https://martinfowler.com/eaaCatalog/singleTableInheritance.html
  15.  */
  16. class SingleTablePersister extends AbstractEntityInheritancePersister
  17. {
  18.     use SQLResultCasing;
  19.     /**
  20.      * {@inheritdoc}
  21.      */
  22.     protected function getDiscriminatorColumnTableName()
  23.     {
  24.         return $this->class->getTableName();
  25.     }
  26.     /**
  27.      * {@inheritdoc}
  28.      */
  29.     protected function getSelectColumnsSQL()
  30.     {
  31.         if ($this->currentPersisterContext->selectColumnListSql !== null) {
  32.             return $this->currentPersisterContext->selectColumnListSql;
  33.         }
  34.         $columnList[] = parent::getSelectColumnsSQL();
  35.         $rootClass  $this->em->getClassMetadata($this->class->rootEntityName);
  36.         $tableAlias $this->getSQLTableAlias($rootClass->name);
  37.         // Append discriminator column
  38.         $discrColumn     $this->class->getDiscriminatorColumn();
  39.         $discrColumnName $discrColumn['name'];
  40.         $discrColumnType $discrColumn['type'];
  41.         $columnList[] = $tableAlias '.' $discrColumnName;
  42.         $resultColumnName $this->getSQLResultCasing($this->platform$discrColumnName);
  43.         $this->currentPersisterContext->rsm->setDiscriminatorColumn('r'$resultColumnName);
  44.         $this->currentPersisterContext->rsm->addMetaResult('r'$resultColumnName$discrColumnNamefalse$discrColumnType);
  45.         // Append subclass columns
  46.         foreach ($this->class->subClasses as $subClassName) {
  47.             $subClass $this->em->getClassMetadata($subClassName);
  48.             // Regular columns
  49.             foreach ($subClass->fieldMappings as $fieldName => $mapping) {
  50.                 if (isset($mapping['inherited'])) {
  51.                     continue;
  52.                 }
  53.                 $columnList[] = $this->getSelectColumnSQL($fieldName$subClass);
  54.             }
  55.             // Foreign key columns
  56.             foreach ($subClass->associationMappings as $assoc) {
  57.                 if (! $assoc['isOwningSide'] || ! ($assoc['type'] & ClassMetadata::TO_ONE) || isset($assoc['inherited'])) {
  58.                     continue;
  59.                 }
  60.                 $targetClass $this->em->getClassMetadata($assoc['targetEntity']);
  61.                 foreach ($assoc['joinColumns'] as $joinColumn) {
  62.                     $columnList[] = $this->getSelectJoinColumnSQL(
  63.                         $tableAlias,
  64.                         $joinColumn['name'],
  65.                         $this->quoteStrategy->getJoinColumnName($joinColumn$subClass$this->platform),
  66.                         PersisterHelper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass$this->em)
  67.                     );
  68.                 }
  69.             }
  70.         }
  71.         $this->currentPersisterContext->selectColumnListSql implode(', '$columnList);
  72.         return $this->currentPersisterContext->selectColumnListSql;
  73.     }
  74.     /**
  75.      * {@inheritdoc}
  76.      */
  77.     protected function getInsertColumnList()
  78.     {
  79.         $columns parent::getInsertColumnList();
  80.         // Add discriminator column to the INSERT SQL
  81.         $columns[] = $this->class->getDiscriminatorColumn()['name'];
  82.         return $columns;
  83.     }
  84.     /**
  85.      * {@inheritdoc}
  86.      */
  87.     protected function getSQLTableAlias($className$assocName '')
  88.     {
  89.         return parent::getSQLTableAlias($this->class->rootEntityName$assocName);
  90.     }
  91.     /**
  92.      * {@inheritdoc}
  93.      */
  94.     protected function getSelectConditionSQL(array $criteria$assoc null)
  95.     {
  96.         $conditionSql parent::getSelectConditionSQL($criteria$assoc);
  97.         if ($conditionSql) {
  98.             $conditionSql .= ' AND ';
  99.         }
  100.         return $conditionSql $this->getSelectConditionDiscriminatorValueSQL();
  101.     }
  102.     /**
  103.      * {@inheritdoc}
  104.      */
  105.     protected function getSelectConditionCriteriaSQL(Criteria $criteria)
  106.     {
  107.         $conditionSql parent::getSelectConditionCriteriaSQL($criteria);
  108.         if ($conditionSql) {
  109.             $conditionSql .= ' AND ';
  110.         }
  111.         return $conditionSql $this->getSelectConditionDiscriminatorValueSQL();
  112.     }
  113.     /**
  114.      * @return string
  115.      */
  116.     protected function getSelectConditionDiscriminatorValueSQL()
  117.     {
  118.         $values = [];
  119.         if ($this->class->discriminatorValue !== null) { // discriminators can be 0
  120.             $values[] = $this->conn->quote($this->class->discriminatorValue);
  121.         }
  122.         $discrValues array_flip($this->class->discriminatorMap);
  123.         foreach ($this->class->subClasses as $subclassName) {
  124.             $values[] = $this->conn->quote($discrValues[$subclassName]);
  125.         }
  126.         $discColumnName $this->class->getDiscriminatorColumn()['name'];
  127.         $values     implode(', '$values);
  128.         $tableAlias $this->getSQLTableAlias($this->class->name);
  129.         return $tableAlias '.' $discColumnName ' IN (' $values ')';
  130.     }
  131.     /**
  132.      * {@inheritdoc}
  133.      */
  134.     protected function generateFilterConditionSQL(ClassMetadata $targetEntity$targetTableAlias)
  135.     {
  136.         // Ensure that the filters are applied to the root entity of the inheritance tree
  137.         $targetEntity $this->em->getClassMetadata($targetEntity->rootEntityName);
  138.         // we don't care about the $targetTableAlias, in a STI there is only one table.
  139.         return parent::generateFilterConditionSQL($targetEntity$targetTableAlias);
  140.     }
  141. }