Commit bcf01102 authored by romanb's avatar romanb

replaced code driver with annotation driver using addendum.

parent efaaf83e
<?php
#namespace Doctrine\Common;
/**
* The ClassMetadata class represents a generic container for metadata of a class.
*
* @author robo
*/
class Doctrine_Common_ClassMetadata
{
/** The metadata that applies to the class. */
protected $_classMetadata = array();
/** The metadata that applies to properties of the class. */
protected $_fieldMetadata = array();
protected $_entityName;
/**
*
*
* @param <type> $className
*/
public function __construct($className)
{
$this->_entityName = $className;
}
/**
* Adds metadata to a property of the class.
*
* @param string $fieldName
* @param array $fieldMetadata
*/
public function addFieldMetadata($fieldName, array $fieldMetadata)
{
$this->_fieldMetadata[$fieldName] = array_merge(
isset($this->_fieldMetadata[$fieldName]) ? $this->_fieldMetadata[$fieldName] : array(),
$fieldMetadata);
}
/**
*
*
* @param <type> $fieldName
* @param <type> $metadata
*/
public function setFieldMetadata($fieldName, array $metadata)
{
$this->_fieldMetadata[$fieldName] = $metadata;
}
/**
*
* @param <type> $fieldName
* @param <type> $metadataKey
* @param <type> $value
*/
public function setFieldMetadataEntry($fieldName, $metadataKey, $value)
{
$this->_fieldMetadata[$fieldName][$metadataKey] = $value;
}
/**
* Gets metadata of a property of the class.
*
* @param string $fieldName
* @param string $metadataKey
* @return mixed
*/
public function getFieldMetadata($fieldName)
{
return $this->_fieldMetadata[$fieldName];
}
/**
*
* @param <type> $fieldName
* @param <type> $metadataKey
* @return <type>
*/
public function getFieldMetadataEntry($fieldName, $metadataKey)
{
return isset($this->_fieldMetadata[$fieldName][$metadataKey]) ?
$this->_fieldMetadata[$fieldName][$metadataKey] : null;
}
/**
* Gets metadata of the class.
*
* @param string $metadataKey
* @return mixed
*/
public function getClassMetadata()
{
return $this->_classMetadata;
}
/**
*
*
* @param <type> $metadataKey
*/
public function getClassMetadataEntry($metadataKey)
{
return isset($this->_classMetadata[$metadataKey]) ?
$this->_classMetadata[$metadataKey] : null;
}
/**
* Adds metadata to the class.
*
* @param array $classMetadata
*/
public function addClassMetadata(array $classMetadata)
{
$this->_classMetadata = array_merge($this->_classMetadata, $classMetadata);
}
/**
*
*
* @param <type> $metadata
*/
public function setClassMetadata(array $metadata)
{
$this->_classMetadata = $metadata;
}
/**
*
* @param <type> $metadataKey
* @param <type> $value
*/
public function setClassMetadataEntry($metadataKey, $value)
{
$this->_classMetadata[$metadataKey] = $value;
}
}
?>
<?php
#namespace Doctrine\Common;
/**
* Description of ClassMetadataFactory
*
* @author robo
*/
class Doctrine_Common_ClassMetadataFactory {
/** The factory driver. */
protected $_driver;
/** Map of the already loaded ClassMetadata instances, indexed by class name. */
protected $_loadedMetadata = array();
/**
* Creates a new factory instance that uses the given metadata driver implementation.
*
* @param $driver The metadata driver to use.
*/
public function __construct($driver)
{
$this->_driver = $driver;
}
/**
* Returns the metadata object for a class.
*
* @param string $className The name of the class.
* @return Doctrine_Metadata
*/
public function getMetadataFor($className)
{
if ( ! isset($this->_loadedMetadata[$className])) {
$this->_loadMetadata($className);
$this->_validateAndCompleteMetadata($className);
}
return $this->_loadedMetadata[$className];
}
/**
* Loads the metadata for the given class.
*
* @param <type> $className
* @return <type>
*/
protected function _loadMetadata($className)
{
$classMetadata = new Doctrine_Common_ClassMetadata();
$this->_driver->loadMetadataForClass($className, $classMetadata);
return $classMetadata;
}
/** Template method for subclasses */
protected function _validateAndCompleteMetadata($className)
{ /*empty*/ }
}
?>
......@@ -19,7 +19,7 @@
* <http://www.phpdoctrine.org>.
*/
#namespace Doctrine::Common::Events;
#namespace Doctrine\Common\Events;
/**
* Doctrine_Event
......
......@@ -160,7 +160,7 @@ class Doctrine_ORM_EntityManager
$this->_config = $config;
$this->_eventManager = $eventManager;
$this->_metadataFactory = new Doctrine_ORM_Mapping_ClassMetadataFactory(
new Doctrine_ORM_Mapping_Driver_CodeDriver(),
new Doctrine_ORM_Mapping_Driver_AnnotationDriver(),
$this->_conn->getDatabasePlatform());
$this->_unitOfWork = new Doctrine_ORM_UnitOfWork($this);
$this->_nullObject = Doctrine_ORM_Internal_Null::$INSTANCE;
......
......@@ -177,7 +177,7 @@ abstract class Doctrine_ORM_Mapping_AssociationMapping implements Serializable
$this->_sourceEntityName = $mapping['sourceEntity'];
if ( ! isset($mapping['targetEntity'])) {
throw Doctrine_MappingException::missingTargetEntity($mapping['fieldName']);
throw Doctrine_ORM_Exceptions_MappingException::missingTargetEntity($mapping['fieldName']);
}
$this->_targetEntityName = $mapping['targetEntity'];
......
......@@ -32,7 +32,7 @@
* @author Roman Borschel <roman@code-factory.org>
* @since 2.0
*/
class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata implements Serializable
class Doctrine_ORM_Mapping_ClassMetadata implements Serializable
{
/* The inheritance mapping types */
/**
......@@ -101,6 +101,9 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
*/
const ENTITY_TYPE_MAPPED_SUPERCLASS = 'mappedSuperclass';
/** The name of the entity class. */
protected $_entityName;
/**
* The name of the entity class that is at the root of the entity inheritance
* hierarchy. If the entity is not part of an inheritance hierarchy this is the same
......@@ -243,10 +246,10 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
* Inheritance options.
*/
protected $_inheritanceOptions = array(
// JOINED & TABLE_PER_CLASS options
// JOINED & TABLE_PER_CLASS options
'discriminatorColumn' => null,
'discriminatorMap' => array(),
// JOINED options
// JOINED options
'joinSubclasses' => true
);
......@@ -321,7 +324,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
*/
public function __construct($entityName)
{
parent::__construct($entityName);
$this->_entityName = $entityName;
$this->_rootEntityName = $entityName;
$this->_reflectionClass = new ReflectionClass($entityName);
$reflectionProps = $this->_reflectionClass->getProperties();
......@@ -362,6 +365,10 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
return $this->_reflectionProperties[$name];
}
/**
*
* @return <type>
*/
public function getSingleIdReflectionProperty()
{
if ($this->_isIdentifierComposite) {
......@@ -451,38 +458,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
return false;
}
/**
* Sets a table option.
*/
public function setTableOption($name, $value)
{
if ( ! array_key_exists($name, $this->_tableOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown table option: '$name'.");
}
$this->_tableOptions[$name] = $value;
}
/**
* Gets a table option.
*/
public function getTableOption($name)
{
if ( ! array_key_exists($name, $this->_tableOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown table option: '$name'.");
}
return $this->_tableOptions[$name];
}
/**
* returns all table options.
*
* @return array all options and their values
*/
public function getTableOptions()
{
return $this->_tableOptions;
}
/**
* Gets a column name for a field name.
* If the column name for the field cannot be found, the given field name
......@@ -610,27 +585,13 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
return isset($this->_lcColumnToFieldNames[$lcColumnName]);
}
/**
* Adds a field mapping.
*
* @param array $mapping
*/
public function mapField(array $mapping)
{
$mapping = $this->_validateAndCompleteFieldMapping($mapping);
if (isset($this->_fieldMappings[$mapping['fieldName']])) {
throw Doctrine_MappingException::duplicateFieldMapping();
}
$this->_fieldMappings[$mapping['fieldName']] = $mapping;
}
/**
* Validates & completes the field mapping.
*
* @param array $mapping The field mapping to validated & complete.
* @return array The validated and completed field mapping.
*/
private function _validateAndCompleteFieldMapping(array $mapping)
private function _validateAndCompleteFieldMapping(array &$mapping)
{
// Check mandatory fields
if ( ! isset($mapping['fieldName'])) {
......@@ -658,7 +619,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
if (isset($mapping['idGenerator'])) {
if ( ! $this->_isIdGeneratorType($mapping['idGenerator'])) {
//TODO: check if the idGenerator specifies an existing generator by name
throw Doctrine_MappingException::invalidGeneratorType($mapping['generatorType']);
throw Doctrine_MappingException::invalidGeneratorType($mapping['idGenerator']);
} else if (count($this->_identifier) > 1) {
throw Doctrine_MappingException::generatorNotAllowedWithCompositeId();
}
......@@ -671,8 +632,11 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
$this->_isIdentifierComposite = true;
}
}
}
private function _validateAndCompleteClassMapping(array &$mapping)
{
return $mapping;
}
/**
......@@ -761,10 +725,11 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
* Gets all field mappings.
*
* @return array
* @deprecated
*/
public function getFieldMappings()
{
return $this->_fieldMappings;
return $this->_fieldMetadata;
}
/**
......@@ -953,7 +918,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
*/
public function getTableName()
{
return $this->getTableOption('tableName');
return $this->_tableOptions['tableName'];
}
public function getInheritedFields()
......@@ -1085,13 +1050,13 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
*/
private function _checkRequiredDiscriminatorOptions(array $options)
{
if ( ! isset($options['discriminatorColumn'])) {
throw new Doctrine_ClassMetadata_Exception("Missing option 'discriminatorColumn'."
/*if ( ! isset($options['discriminatorColumn'])) {
throw new Doctrine_Exception("Missing option 'discriminatorColumn'."
. " Inheritance types JOINED and SINGLE_TABLE require this option.");
} else if ( ! isset($options['discriminatorMap'])) {
throw new Doctrine_ClassMetadata_Exception("Missing option 'discriminatorMap'."
. " Inheritance types JOINED and SINGLE_TABLE require this option.");
}
}*/
}
/**
......@@ -1296,7 +1261,7 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
*/
public function setTableName($tableName)
{
$this->setTableOption('tableName', $tableName);
$this->_tableOptions['tableName'] = $tableName;
}
/**
......@@ -1380,6 +1345,20 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
$mapping['sourceEntity'] = $this->_entityName;
return $mapping;
}
/**
* Adds a field mapping.
*
* @param array $mapping
*/
public function mapField(array $mapping)
{
$this->_validateAndCompleteFieldMapping($mapping);
if (isset($this->_fieldMappings[$mapping['fieldName']])) {
throw Doctrine_MappingException::duplicateFieldMapping();
}
$this->_fieldMappings[$mapping['fieldName']] = $mapping;
}
/**
* Adds a one-to-one mapping.
......@@ -1464,10 +1443,6 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
*/
public function setCustomRepositoryClass($repositoryClassName)
{
if ( ! is_subclass_of($repositoryClassName, 'Doctrine\ORM\EntityRepository')) {
throw new Doctrine_ClassMetadata_Exception("The custom repository must be a subclass"
. " of Doctrine_EntityRepository.");
}
$this->_customRepositoryClassName = $repositoryClassName;
}
......@@ -1499,10 +1474,10 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
* Binding an Entity to a specific EntityManager in 2.0 is the same as binding
* it to a Connection in 1.0.
*/
public function bindToEntityManager($emName)
/*public function bindToEntityManager($emName)
{
}
}*/
/**
* Dispatches the lifecycle event of the given Entity to the registered
......@@ -1594,6 +1569,16 @@ class Doctrine_ORM_Mapping_ClassMetadata extends Doctrine_Common_ClassMetadata i
return false;
}
public function setDiscriminatorColumn($columnDef)
{
$this->_inheritanceOptions['discriminatorColumn'] = $columnDef;
}
public function setDiscriminatorMap(array $map)
{
$this->_inheritanceOptions['discriminatorMap'] = $map;
}
public function isDiscriminatorColumn($columnName)
{
return $columnName === $this->_inheritanceOptions['discriminatorColumn'];
......
......@@ -32,14 +32,14 @@
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version $Revision$
* @link www.phpdoctrine.org
* @link www.doctrine-project.org
* @since 2.0
* @todo Rename to ClassDescriptorFactory.
*/
class Doctrine_ORM_Mapping_ClassMetadataFactory extends Doctrine_Common_ClassMetadataFactory
class Doctrine_ORM_Mapping_ClassMetadataFactory
{
/** The targeted database platform. */
private $_targetPlatform;
private $_driver;
/**
* Constructor.
......@@ -49,9 +49,23 @@ class Doctrine_ORM_Mapping_ClassMetadataFactory extends Doctrine_Common_ClassMet
*/
public function __construct($driver, Doctrine_DBAL_Platforms_AbstractPlatform $targetPlatform)
{
parent::__construct($driver);
$this->_driver = $driver;
$this->_targetPlatform = $targetPlatform;
}
/**
* Returns the metadata object for a class.
*
* @param string $className The name of the class.
* @return Doctrine_Metadata
*/
public function getMetadataFor($className)
{
if ( ! isset($this->_loadedMetadata[$className])) {
$this->_loadMetadata($className);
}
return $this->_loadedMetadata[$className];
}
/**
* Loads the metadata of the class in question and all it's ancestors whose metadata
......@@ -59,11 +73,9 @@ class Doctrine_ORM_Mapping_ClassMetadataFactory extends Doctrine_Common_ClassMet
*
* @param string $name The name of the class for which the metadata should get loaded.
* @param array $tables The metadata collection to which the loaded metadata is added.
* @override
*/
protected function _loadMetadata($name)
{
$parentClass = $name;
$parentClasses = array();
$loadedParentClass = false;
......@@ -114,7 +126,6 @@ class Doctrine_ORM_Mapping_ClassMetadataFactory extends Doctrine_Common_ClassMet
*
* @param Doctrine::ORM::Mapping::ClassMetadata $subClass
* @param Doctrine::ORM::Mapping::ClassMetadata $parentClass
* @return void
*/
private function _addInheritedFields($subClass, $parentClass)
{
......@@ -162,10 +173,6 @@ class Doctrine_ORM_Mapping_ClassMetadataFactory extends Doctrine_Common_ClassMet
$names[] = $className;
} while ($className = get_parent_class($className));
/*if ($className === false) {
throw new Doctrine_Exception("Unknown component '$className'.");
}*/
// save parents
$class->setParentClasses($names);
......
<?php
/*
* $Id$
*
* 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.phpdoctrine.org>.
*/
#namespace Doctrine\ORM\Mapping\Driver;
/**
* The code metadata driver loads the metadata of the classes through invoking
* a static callback method that needs to be implemented when using this driver.
*
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version $Revision$
* @link www.phpdoctrine.org
* @since 2.0
*/
class Doctrine_ORM_Mapping_Driver_CodeDriver
{
/**
* Name of the callback method.
*
* @todo We could make the name of the callback methods customizable for users.
*/
private $_callback = 'initMetadata';
public function setCallback($callback)
{
$this->_callback = $callback;
}
public function getCallback()
{
return $this->_callback;
}
/**
* Loads the metadata for the specified class into the provided container.
*/
public function loadMetadataForClass($className, Doctrine_ORM_Mapping_ClassMetadata $metadata)
{
if ( ! method_exists($className, $this->_callback)) {
throw new Doctrine_Exception("Unable to load metadata for class"
. " '$className'. Callback method 'initMetadata' not found.");
}
call_user_func_array(array($className, $this->_callback), array($metadata));
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
<?php
/**
* Addendum PHP Reflection Annotations
* http://code.google.com/p/addendum/
*
* Copyright (C) 2006 Jan "johno Suchal <johno@jsmf.net>
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**/
class CompositeMatcher {
protected $matchers = array();
private $wasConstructed = false;
public function add($matcher) {
$this->matchers[] = $matcher;
}
public function matches($string, &$value) {
if(!$this->wasConstructed) {
$this->build();
$this->wasConstructed = true;
}
return $this->match($string, $value);
}
protected function build() {}
}
class ParallelMatcher extends CompositeMatcher {
protected function match($string, &$value) {
$maxLength = false;
$result = null;
foreach($this->matchers as $matcher) {
$length = $matcher->matches($string, $subvalue);
if($maxLength === false || $length > $maxLength) {
$maxLength = $length;
$result = $subvalue;
}
}
$value = $this->process($result);
return $maxLength;
}
protected function process($value) {
return $value;
}
}
class SerialMatcher extends CompositeMatcher {
protected function match($string, &$value) {
$results = array();
$total_length = 0;
foreach($this->matchers as $matcher) {
if(($length = $matcher->matches($string, $result)) === false) return false;
$total_length += $length;
$results[] = $result;
$string = substr($string, $length);
}
$value = $this->process($results);
return $total_length;
}
protected function process($results) {
return implode('', $results);
}
}
class SimpleSerialMatcher extends SerialMatcher {
private $return_part_index;
public function __construct($return_part_index = 0) {
$this->return_part_index = $return_part_index;
}
public function process($parts) {
return $parts[$this->return_part_index];
}
}
class RegexMatcher {
private $regex;
public function __construct($regex) {
$this->regex = $regex;
}
public function matches($string, &$value) {
if(preg_match("/^{$this->regex}/", $string, $matches)) {
$value = $this->process($matches);
return strlen($matches[0]);
}
$value = false;
return false;
}
protected function process($matches) {
return $matches[0];
}
}
class AnnotationsMatcher {
public function matches($string, &$annotations) {
$annotations = array();
$annotation_matcher = new AnnotationMatcher;
while(true) {
if(preg_match('/\s(?=@)/', $string, $matches, PREG_OFFSET_CAPTURE)) {
$offset = $matches[0][1] + 1;
$string = substr($string, $offset);
} else {
return; // no more annotations
}
if(($length = $annotation_matcher->matches($string, $data)) !== false) {
$string = substr($string, $length);
list($name, $params) = $data;
$annotations[$name][] = $params;
}
}
}
}
class AnnotationMatcher extends SerialMatcher {
protected function build() {
$this->add(new RegexMatcher('@'));
$this->add(new RegexMatcher('[A-Z][a-zA-Z0-9_]+'));
$this->add(new AnnotationParametersMatcher);
}
protected function process($results) {
return array($results[1], $results[2]);
}
}
class ConstantMatcher extends RegexMatcher {
private $constant;
public function __construct($regex, $constant) {
parent::__construct($regex);
$this->constant = $constant;
}
protected function process($matches) {
return $this->constant;
}
}
class AnnotationParametersMatcher extends ParallelMatcher {
protected function build() {
$this->add(new ConstantMatcher('', array()));
$this->add(new ConstantMatcher('\(\)', array()));
$params_matcher = new SimpleSerialMatcher(1);
$params_matcher->add(new RegexMatcher('\(\s*'));
$params_matcher->add(new AnnotationValuesMatcher);
$params_matcher->add(new RegexMatcher('\s*\)'));
$this->add($params_matcher);
}
}
class AnnotationValuesMatcher extends ParallelMatcher {
protected function build() {
$this->add(new AnnotationTopValueMatcher);
$this->add(new AnnotationHashMatcher);
}
}
class AnnotationTopValueMatcher extends AnnotationValueMatcher {
protected function process($value) {
return array('value' => $value);
}
}
class AnnotationValueMatcher extends ParallelMatcher {
protected function build() {
$this->add(new ConstantMatcher('true', true));
$this->add(new ConstantMatcher('false', false));
$this->add(new ConstantMatcher('TRUE', true));
$this->add(new ConstantMatcher('FALSE', false));
$this->add(new AnnotationStringMatcher);
$this->add(new AnnotationNumberMatcher);
$this->add(new AnnotationArrayMatcher);
}
}
class AnnotationKeyMatcher extends ParallelMatcher {
protected function build() {
$this->add(new RegexMatcher('[a-zA-Z][a-zA-Z0-9_]*'));
$this->add(new AnnotationStringMatcher);
$this->add(new AnnotationIntegerMatcher);
}
}
class AnnotationPairMatcher extends SerialMatcher {
protected function build() {
$this->add(new AnnotationKeyMatcher);
$this->add(new RegexMatcher('\s*=\s*'));
$this->add(new AnnotationValueMatcher);
}
protected function process($parts) {
return array($parts[0] => $parts[2]);
}
}
class AnnotationHashMatcher extends ParallelMatcher {
protected function build() {
$this->add(new AnnotationPairMatcher);
$this->add(new AnnotationMorePairsMatcher);
}
}
class AnnotationMorePairsMatcher extends SerialMatcher {
protected function build() {
$this->add(new AnnotationPairMatcher);
$this->add(new RegexMatcher('\s*,\s*'));
$this->add(new AnnotationHashMatcher);
}
protected function match($string, &$value) {
$result = parent::match($string, $value);
return $result;
}
public function process($parts) {
return array_merge($parts[0], $parts[2]);
}
}
class AnnotationArrayMatcher extends ParallelMatcher {
protected function build() {
$this->add(new ConstantMatcher('{}', array()));
$values_matcher = new SimpleSerialMatcher(1);
$values_matcher->add(new RegexMatcher('\s*{\s*'));
$values_matcher->add(new AnnotationArrayValuesMatcher);
$values_matcher->add(new RegexMatcher('\s*}\s*'));
$this->add($values_matcher);
}
}
class AnnotationArrayValuesMatcher extends ParallelMatcher {
protected function build() {
$this->add(new AnnotationArrayValueMatcher);
$this->add(new AnnotationMoreValuesMatcher);
}
}
class AnnotationMoreValuesMatcher extends SimpleSerialMatcher {
protected function build() {
$this->add(new AnnotationArrayValueMatcher);
$this->add(new RegexMatcher('\s*,\s*'));
$this->add(new AnnotationArrayValuesMatcher);
}
protected function match($string, &$value) {
$result = parent::match($string, $value);
return $result;
}
public function process($parts) {
return array_merge($parts[0], $parts[2]);
}
}
class AnnotationArrayValueMatcher extends ParallelMatcher {
protected function build() {
$this->add(new AnnotationValueInArrayMatcher);
$this->add(new AnnotationPairMatcher);
}
}
class AnnotationValueInArrayMatcher extends AnnotationValueMatcher {
public function process($value) {
return array($value);
}
}
class AnnotationStringMatcher extends ParallelMatcher {
protected function build() {
$this->add(new AnnotationSingleQuotedStringMatcher);
$this->add(new AnnotationDoubleQuotedStringMatcher);
}
}
class AnnotationNumberMatcher extends RegexMatcher {
public function __construct() {
parent::__construct("-?[0-9]*\.?[0-9]*");
}
protected function process($matches) {
$isFloat = strpos($matches[0], '.') !== false;
return $isFloat ? (float) $matches[0] : (int) $matches[0];
}
}
class AnnotationIntegerMatcher extends RegexMatcher {
public function __construct() {
parent::__construct("-?[0-9]*");
}
protected function process($matches) {
return (int) $matches[0];
}
}
class AnnotationSingleQuotedStringMatcher extends RegexMatcher {
public function __construct() {
parent::__construct("'([^']*)'");
}
protected function process($matches) {
return $matches[1];
}
}
class AnnotationDoubleQuotedStringMatcher extends RegexMatcher {
public function __construct() {
parent::__construct('"([^"]*)"');
}
protected function process($matches) {
return $matches[1];
}
}
?>
<?php
class DocComment {
private static $classes = array();
private static $methods = array();
private static $fields = array();
private static $parsedFiles = array();
public static function clearCache() {
self::$classes = array();
self::$methods = array();
self::$fields = array();
self::$parsedFiles = array();
}
public function get($reflection) {
if($reflection instanceof ReflectionClass) {
return $this->forClass($reflection);
} elseif($reflection instanceof ReflectionMethod) {
return $this->forMethod($reflection);
} elseif($reflection instanceof ReflectionProperty) {
return $this->forProperty($reflection);
}
}
public function forClass($reflection) {
$this->process($reflection->getFileName());
$name = $reflection->getName();
return isset(self::$classes[$name]) ? self::$classes[$name] : false;
}
public function forMethod($reflection) {
$this->process($reflection->getDeclaringClass()->getFileName());
$class = $reflection->getDeclaringClass()->getName();
$method = $reflection->getName();
return isset(self::$methods[$class][$method]) ? self::$methods[$class][$method] : false;
}
public function forProperty($reflection) {
$this->process($reflection->getDeclaringClass()->getFileName());
$class = $reflection->getDeclaringClass()->getName();
$field = $reflection->getName();
return isset(self::$fields[$class][$field]) ? self::$fields[$class][$field] : false;
}
private function process($file) {
if(!isset(self::$parsedFiles[$file])) {
$this->parse($file);
self::$parsedFiles[$file] = true;
}
}
protected function parse($file) {
$tokens = $this->getTokens($file);
$currentClass = false;
$currentBlock = false;
$max = count($tokens);
$i = 0;
while($i < $max) {
$token = $tokens[$i];
if(is_array($token)) {
list($code, $value) = $token;
switch($code) {
case T_DOC_COMMENT:
$comment = $value;
break;
case T_CLASS:
$class = $this->getString($tokens, $i, $max);
if($comment !== false) {
self::$classes[$class] = $comment;
$comment = false;
}
break;
case T_VARIABLE:
if($comment !== false) {
$field = substr($token[1], 1);
self::$fields[$class][$field] = $comment;
$comment = false;
}
break;
case T_FUNCTION:
if($comment !== false) {
$function = $this->getString($tokens, $i, $max);
self::$methods[$class][$function] = $comment;
$comment = false;
}
break;
// ignore
case T_WHITESPACE:
case T_PUBLIC:
case T_PROTECTED:
case T_PRIVATE:
case T_ABSTRACT:
case T_FINAL:
case T_VAR:
break;
default:
$comment = false;
break;
}
} else {
$comment = false;
}
$i++;
}
}
private function getString($tokens, &$i, $max) {
do {
$token = $tokens[$i];
$i++;
if(is_array($token)) {
if($token[0] == T_STRING) {
return $token[1];
}
}
} while($i <= $max);
return false;
}
private function getTokens($file) {
return token_get_all(file_get_contents($file));
}
}
?>
\ No newline at end of file
......@@ -82,7 +82,6 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
$this->_entityName = $classMetadata->getClassName();
$this->_conn = $em->getConnection();
$this->_classMetadata = $classMetadata;
//$this->_nullObject = Doctrine_ORM_Internal_Null::$INSTANCE;
}
/**
......@@ -251,7 +250,6 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
//echo "NOT TO-ONE OR INVERSE!";
continue;
}
foreach ($assocMapping->getSourceToTargetKeyColumns() as $sourceColumn => $targetColumn) {
//TODO: What if both join columns (local/foreign) are just db-only
// columns (no fields in models) ? Currently we assume the foreign column
......@@ -281,7 +279,7 @@ abstract class Doctrine_ORM_Persisters_AbstractEntityPersister
$newVal, $this->_em->getConnection()->getDatabasePlatform());*/
}
// populates the discriminator column on insert in Single & Class Table Inheritance
// Populate the discriminator column on insert in Single & Class Table Inheritance
if ($isInsert && ($this->_classMetadata->isInheritanceTypeJoined() ||
$this->_classMetadata->isInheritanceTypeSingleTable())) {
$discColumn = $this->_classMetadata->getInheritanceOption('discriminatorColumn');
......
......@@ -904,6 +904,7 @@ class Doctrine_ORM_UnitOfWork
$class = $this->_em->getClassMetadata(get_class($entity));
foreach ($class->getAssociationMappings() as $assocMapping) {
if ( ! $assocMapping->isCascadeSave()) {
echo "NOT cascade " . $assocMapping->getSourceFieldName();
continue;
}
$relatedEntities = $class->getReflectionProperty($assocMapping->getSourceFieldName())
......
<?php
#namespace Doctrine::Tests::ORM::Models::CMS;
#use Doctrine::ORM::Entity;
#namespace Doctrine\Tests\Models\CMS;
/**
* @DoctrineEntity
*/
class CmsArticle
{
/**
* @DoctrineId
* @DoctrineColumn(type="integer")
* @DoctrineIdGenerator("auto")
*/
public $id;
/**
* @DoctrineColumn(type="string", length=255)
*/
public $topic;
/**
* @DoctrineColumn(type="string")
*/
public $text;
/**
* @DoctrineManyToOne(targetEntity="CmsUser", joinColumns={"user_id" = "id"})
*/
public $user;
/**
* @DoctrineOneToMany(targetEntity="CmsComment", mappedBy="article")
*/
public $comments;
/*static function construct() {
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'id', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'topic', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'text', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'user_id', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'user', 'CmsUser');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'comments', 'collection');
}*/
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true,
'idGenerator' => 'auto'
));
$mapping->mapField(array(
'fieldName' => 'topic',
'type' => 'string',
'length' => 255
));
$mapping->mapField(array(
'fieldName' => 'text',
'type' => 'string'
));
$mapping->mapField(array(
'fieldName' => 'user_id',
'type' => 'integer'
));
$mapping->mapOneToMany(array(
'fieldName' => 'comments',
'targetEntity' => 'CmsComment',
'mappedBy' => 'article'
));
$mapping->mapManyToOne(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'joinColumns' => array('user_id' => 'id')
));
}
}
<?php
#namespace Doctrine::Tests::ORM::Models::CMS;
#use Doctrine::ORM::Entity;
#namespace Doctrine\Tests\Models\CMS;
/**
* @DoctrineEntity
*/
class CmsComment
{
/**
* @DoctrineColumn(type="integer")
* @DoctrineId
* @DoctrineIdGenerator("auto")
*/
public $id;
/**
* @DoctrineColumn(type="string", length=255)
*/
public $topic;
/**
* @DoctrineColumn(type="string")
*/
public $text;
/**
* @DoctrineManyToOne(targetEntity="CmsArticle", joinColumns={"article_id" = "id"})
*/
public $article;
/*static function construct() {
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'id', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'topic', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'text', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'article_id', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'article', 'CmsArticle');
}*/
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true,
'generatorType' => 'auto'
));
$mapping->mapField(array(
'fieldName' => 'topic',
'type' => 'string',
'length' => 255
));
$mapping->mapField(array(
'fieldName' => 'text',
'type' => 'string'
));
$mapping->mapField(array(
'fieldName' => 'article_id',
'type' => 'integer'
));
$mapping->mapManyToOne(array(
'fieldName' => 'article',
'targetEntity' => 'CmsArticle',
'joinColumns' => array('article_id' => 'id')
));
}
}
<?php
class CmsPhonenumber
/**
* @DoctrineEntity
*/
class CmsPhonenumber implements Doctrine_ORM_Entity
{
/**
* @DoctrineColumn(type="string", length=50)
* @DoctrineId
*/
public $phonenumber;
/**
* @DoctrineManyToOne(targetEntity="CmsUser", joinColumns={"user_id" = "id"})
*/
public $user;
/*static function construct() {
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'user_id', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'phonenumber', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'user', 'CmsUser');
}*/
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'user_id',
'type' => 'integer'
));
$mapping->mapField(array(
'fieldName' => 'phonenumber',
'type' => 'string',
'length' => 50,
'id' => true
));
$mapping->mapManyToOne(array(
'fieldName' => 'user',
'targetEntity' => 'CmsUser',
'joinColumns' => array('user_id' => 'id')
));
}
}
......@@ -2,77 +2,35 @@
#namespace Doctrine\Tests\ORM\Models\Cms;
#use Doctrine\ORM\Entity;
#use Doctrine\Common\VirtualPropertySystem;
/**
* @DoctrineEntity
*/
class CmsUser
{
/**
* @DoctrineId
* @DoctrineColumn(type="integer")
* @DoctrineIdGenerator("auto")
*/
public $id;
/**
* @DoctrineColumn(type="string", length=50)
*/
public $status;
/**
* @DoctrineColumn(type="string", length=255)
*/
public $username;
/**
* @DoctrineColumn(type="string", length=255)
*/
public $name;
/**
* @DoctrineOneToMany(targetEntity="CmsPhonenumber", mappedBy="user")
*/
public $phonenumbers;
/**
* @DoctrineOneToMany(targetEntity="CmsArticle", mappedBy="user")
*/
public $articles;
/*static function construct() {
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'id', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'status', 'int');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'username', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'name', 'string');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'phonenumbers', 'CmsPhonenumber');
Doctrine_Common_VirtualPropertySystem::register(__CLASS__, 'articles', 'CmsArticle');
}*/
public static function initMetadata($mapping)
{
/* NEW
$mapping->addFieldMetadata('id', array(
'doctrine.id' => true, 'doctrine.idGenerator' => 'auto'
));
$mapping->addFieldMetadata('status', array(
'doctrine.length' => 50
));
$mapping->addFieldMetadata('phonenumbers', array(
'doctrine.oneToMany' => array('mappedBy' => 'user')
));
$mapping->addFieldMetadata('articles', array(
'doctrine.oneToMany' => array('mappedBy' => 'user')
));
*/
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true,
'idGenerator' => 'auto'
));
$mapping->mapField(array(
'fieldName' => 'status',
'type' => 'string',
'length' => 50
));
$mapping->mapField(array(
'fieldName' => 'username',
'type' => 'string',
'length' => 255
));
$mapping->mapField(array(
'fieldName' => 'name',
'type' => 'string',
'length' => 255
));
$mapping->mapOneToMany(array(
'fieldName' => 'phonenumbers',
'targetEntity' => 'CmsPhonenumber',
'mappedBy' => 'user'
));
$mapping->mapOneToMany(array(
'fieldName' => 'articles',
'targetEntity' => 'CmsArticle',
'mappedBy' => 'user'
));
}
}
......@@ -2,16 +2,13 @@
#namespace Doctrine\Tests\Models\Forum;
/**
* @DoctrineEntity
*/
class ForumAdministrator extends ForumUser
{
/**
* @DoctrineColumn(type="integer", name="access_level")
*/
public $accessLevel;
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'accessLevel',
'columnName' => 'access_level',
'type' => 'integer'
));
}
}
\ No newline at end of file
......@@ -2,22 +2,15 @@
#namespace Doctrine\Tests\Models\Forum;
#use Doctrine\ORM\Entity;
/**
* @DoctrineEntity
*/
class ForumAvatar
{
/**
* @DoctrineId
* @DoctrineColumn(type="integer")
* @DoctrineIdGenerator("auto")
*/
public $id;
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true,
'idGenerator' => 'auto'
));
}
}
?>
\ No newline at end of file
......@@ -2,32 +2,25 @@
#namespace Doctrine\Tests\Models\Forum;
/**
* Represents a board in a forum.
*
* @author robo
* @DoctrineEntity
*/
class ForumBoard
{
/**
* @DoctrineId
* @DoctrineColumn(type="integer")
*/
public $id;
/**
* @DoctrineColumn(type="integer")
*/
public $position;
/**
* @DoctrineManyToOne(targetEntity="ForumCategory", joinColumns={"category_id" = "id"})
*/
public $category;
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true
));
$mapping->mapField(array(
'fieldName' => 'position',
'type' => 'integer'
));
$mapping->mapField(array(
'fieldName' => 'category_id',
'type' => 'integer'
));
$mapping->mapManyToOne(array(
'fieldName' => 'category',
'targetEntity' => 'ForumCategory',
'joinColumns' => array('category_id' => 'id')
));
}
}
......@@ -2,38 +2,30 @@
#namespace Doctrine\Tests\Models\Forum;
/**
* @DoctrineEntity
*/
class ForumCategory
{
/**
* @DoctrineColumn(type="integer")
* @DoctrineId
*/
private $id;
/**
* @DoctrineColumn(type="integer")
*/
public $position;
/**
* @DoctrineColumn(type="string", length=255)
*/
public $name;
/**
* @DoctrineOneToMany(targetEntity="ForumBoard", mappedBy="category")
*/
public $boards;
public function getId() {
return $this->id;
}
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true
));
$mapping->mapField(array(
'fieldName' => 'position',
'type' => 'integer'
));
$mapping->mapField(array(
'fieldName' => 'name',
'type' => 'string',
'length' => 255
));
$mapping->mapOneToMany(array(
'fieldName' => 'boards',
'targetEntity' => 'ForumBoard',
'mappedBy' => 'category'
));
}
}
......@@ -2,29 +2,20 @@
#namespace Doctrine\Tests\Models\Forum;
#use Doctrine\ORM\Entity;
class ForumEntry implements Doctrine_ORM_Entity
/**
* @DoctrineEntity
*/
class ForumEntry
{
/**
* @DoctrineId
* @DoctrineColumn(type="integer")
* @DoctrineIdGenerator("auto")
*/
public $id;
/**
* @DoctrineColumn(type="string", length=50)
*/
public $topic;
public static function initMetadata($mapping)
{
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true,
'idGenerator' => 'auto'
));
$mapping->mapField(array(
'fieldName' => 'topic',
'type' => 'string',
'length' => 50
));
}
}
......@@ -4,54 +4,30 @@
#use Doctrine\ORM\Entity;
/**
* @DoctrineEntity
* @DoctrineInheritanceType("joined")
* @DoctrineDiscriminatorColumn(name="dtype", type="string", length=20)
* @DoctrineDiscriminatorMap({"user" = "ForumUser", "admin" = "ForumAdministrator"})
* @DoctrineSubclasses({"ForumAdministrator"})
*/
class ForumUser
{
/**
* @DoctrineColumn(type="integer")
* @DoctrineId
* @DoctrineIdGenerator("auto")
*/
public $id;
/**
* @DoctrineColumn(type="string", length=50)
*/
public $username;
/**
* @DoctrineOneToOne(
targetEntity="ForumAvatar",
joinColumns={"avatar_id" = "id"},
cascade={"save"})
*/
public $avatar;
public static function initMetadata($mapping)
{
/*$mapping->setClassMetadata(array(
'doctrine.inheritanceType' => 'joined',
'doctrine.discriminatorColumn' => 'dtype',
'doctrine.discriminatorMap' => array('user' => 'ForumUser', 'admin' => 'ForumAdministrator'),
'doctrine.subclasses' => array('ForumAdministrator')
));
$mapping->setFieldMetadata('id', array(
'doctrine.type' => 'integer',
'doctrine.id' => true,
'doctrine.idGenerator' => 'auto'
));*/
// inheritance mapping
$mapping->setInheritanceType('joined', array(
'discriminatorColumn' => 'dtype',
'discriminatorMap' => array(
'user' => 'ForumUser',
'admin' => 'ForumAdministrator')
));
// register subclasses
$mapping->setSubclasses(array('ForumAdministrator'));
// column-to-field mapping
$mapping->mapField(array(
'fieldName' => 'id',
'type' => 'integer',
'id' => true,
'idGenerator' => 'auto'
));
$mapping->mapField(array(
'fieldName' => 'username',
'type' => 'string',
'length' => 50
));
$mapping->mapOneToOne(array(
'fieldName' => 'avatar',
'targetEntity' => 'ForumAvatar',
'joinColumns' => array('avatar_id' => 'id'),
'cascade' => array('save')
));
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment