AbstractEntityInheritancePersister.php 3.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
<?php
/*
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many individuals
 * and is licensed under the LGPL. For more information, see
 * <http://www.doctrine-project.org>.
 */

namespace Doctrine\ORM\Persisters;

use Doctrine\ORM\Mapping\ClassMetadata,
    Doctrine\DBAL\Types\Type;

/**
 * Base class for entity persisters that implement a certain inheritance mapping strategy.
 * All these persisters are assumed to use a discriminator column to discriminate entity
 * types in the hierarchy.
 * 
 * @author Roman Borschel <roman@code-factory.org>
 * @since 2.0
 */
33
abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
34 35 36 37 38 39
{
    /**
     * Map from column names to class names that declare the field the column is mapped to.
     * 
     * @var array
     */
40
    private $_declaringClassMap = array();
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

    /**
     * {@inheritdoc}
     */
    protected function _prepareInsertData($entity)
    {
        $data = parent::_prepareInsertData($entity);
        // Populate the discriminator column
        $discColumn = $this->_class->discriminatorColumn;
        $this->_columnTypes[$discColumn['name']] = $discColumn['type'];
        $data[$this->_getDiscriminatorColumnTableName()][$discColumn['name']] = $this->_class->discriminatorValue;
        return $data;
    }

    /**
     * Gets the name of the table that contains the discriminator column.
     * 
     * @return string The table name.
     */
    abstract protected function _getDiscriminatorColumnTableName();

    /**
     * {@inheritdoc}
     */
    protected function _processSQLResult(array $sqlResult)
    {
        $data = array();
        $discrColumnName = $this->_platform->getSQLResultCasing($this->_class->discriminatorColumn['name']);
        $entityName = $this->_class->discriminatorMap[$sqlResult[$discrColumnName]];
        unset($sqlResult[$discrColumnName]);
        foreach ($sqlResult as $column => $value) {
            $realColumnName = $this->_resultColumnNames[$column];
            if (isset($this->_declaringClassMap[$column])) {
                $class = $this->_declaringClassMap[$column];
                if ($class->name == $entityName || is_subclass_of($entityName, $class->name)) {
                    $field = $class->fieldNames[$realColumnName];
                    $data[$field] = Type::getType($class->fieldMappings[$field]['type'])
                            ->convertToPHPValue($value, $this->_platform);
                }
            } else {
                $data[$realColumnName] = $value;
            }
        }

        return array($entityName, $data);
    }

    /**
     * {@inheritdoc}
     */
    protected function _getSelectColumnSQL($field, ClassMetadata $class)
    {
        $columnName = $class->columnNames[$field];
94
        $sql = $this->_getSQLTableAlias($class->name) . '.' . $class->getQuotedColumnName($field, $this->_platform);
95 96 97 98 99 100 101 102 103
        $columnAlias = $this->_platform->getSQLResultCasing($columnName . $this->_sqlAliasCounter++);
        if ( ! isset($this->_resultColumnNames[$columnAlias])) {
            $this->_resultColumnNames[$columnAlias] = $columnName;
            $this->_declaringClassMap[$columnAlias] = $class;
        }

        return "$sql AS $columnAlias";
    }
}