diff --git a/Cake/ORM/Association.php b/Cake/ORM/Association.php index c224cf2c177..8185d399305 100644 --- a/Cake/ORM/Association.php +++ b/Cake/ORM/Association.php @@ -127,14 +127,6 @@ abstract class Association { */ protected $_strategy = self::STRATEGY_JOIN; -/** - * The name of the entity class associated to the targetTable, used to load an - * instance of this table in case it is present - * - * @return void - */ - protected $_entityClass; - /** * Constructor. Subclasses can override _options function to get the original * list of passed options if expecting any other special key @@ -152,8 +144,7 @@ public function __construct($name, array $options = []) { 'sourceTable', 'targetTable', 'joinType', - 'property', - 'entityClass' + 'property' ]; foreach ($defaults as $property) { if (isset($options[$property])) { @@ -213,11 +204,6 @@ public function target(Table $table = null) { return $this->_targetTable; } - if ($table === null && $this->_entityClass) { - $entity = $this->_entityClass; - $table = $entity::repository(); - } - if ($table !== null) { return $this->_targetTable = $table; } diff --git a/Cake/ORM/Entity.php b/Cake/ORM/Entity.php index d936f014345..f9341a99de0 100644 --- a/Cake/ORM/Entity.php +++ b/Cake/ORM/Entity.php @@ -2,7 +2,6 @@ namespace Cake\ORM; -use Cake\Core\App; use Cake\ORM\Table; class Entity implements \ArrayAccess { @@ -14,52 +13,6 @@ class Entity implements \ArrayAccess { */ protected $_properties = []; -/** - * Holds a reference to the objects acting as a repository for this type - * of entity - * - * @var Cake\ORM\Table - */ - protected static $_repository; - -/** - * A list of entity classes pointing to the class name of the repository - * object to use - * - * @var array - */ - protected static $_repositoryClass; - -/** - * List of Belongs To associations - * - * ### Basic usage - * - * `public $belongsTo = array('Group', 'Department');` - * - * ### Detailed configuration - * - * {{{ - * public $belongsTo = array( - * 'Group', - * 'Department' => array( - * 'className' => 'Department', - * 'foreignKey' => 'department_id' - * ) - * ); - * }}} - * - * @see \Cake\ORM\Table::belongsTo() for a list of accepted configuration keys - * @var array - */ - protected static $_belongsTo = []; - - protected static $_hasOne = []; - - protected static $_hasMany = []; - - protected static $_belongsToMany = []; - /** * Initializes the internal properties of this entity out of the * keys in an array @@ -295,125 +248,4 @@ public function offsetUnset($offset) { $this->unsetProperty($offset); } -/** - * Returns the instance of the table object associated to this entity. - * If called with a Table object as first argument, it will be set as the default - * repository object to use. - * - * @param \Cake\ORM\Table $table The table object to use as a repository of this - * type of Entity - * @return \Cake\ORM\Table - */ - public static function repository(Table $table = null) { - if ($table === null) { - if (static::$_repository === null) { - $className = static::repositoryClass(); - $self = get_called_class(); - list($namespace, $alias) = namespaceSplit($self); - static::$_repository = $className::build($alias, [ - 'entityClass' => $self - ]); - } - return static::$_repository; - } - $table->entityClass(get_called_class()); - return static::$_repository = $table; - } - -/** - * Returns the fully namespaced class name for the repository object associated to - * this entity. If a string is passed as first argument, it will be used to store - * the name of the repository object to use. - * - * Plugin notation can be used to specify the name of the object to load. By - * convention, classes will be loaded from `[PluginName]\Model\Repository\` - * base namespace if a plugin is specified or from `App\Model\Repository` if - * none is passed. - * - * ### Examples: - * - * - ``User::repositoryClass('\App\Model\Repository\SuperUserTable');`` - * - ``User::repositoryClass('My.User');`` // Looks inside My plugin - * - * @param string $class Fully namespaced class name or name of the object using - * plugin notation. - * @throws \Cake\ORM\Error\MissingTableClassException when the table class cannot be found - * @return string|boolean the full name of the class or false if the class does not exist - */ - public static function repositoryClass($class = null) { - $self = get_called_class(); - if ($class) { - self::$_repositoryClass[$self] = $class; - } - - if (empty(static::$_repositoryClass[$self])) { - if (!empty(self::$_repository)) { - return self::$_repositoryClass[$self] = get_class(static::$_repository); - } - - $default = '\Cake\ORM\Table'; - $self = get_called_class(); - $parts = explode('\\', $self); - - if ($self === __CLASS__ || count($parts) < 3) { - return self::$_repositoryClass[$self] = $default; - } - - $alias = array_pop($parts) . 'Table'; - $class = implode('\\', array_slice($parts, 0, -1)) . '\Repository\\' . $alias; - if (!class_exists($class)) { - return self::$_repositoryClass[$self] = $default; - } - - self::$_repositoryClass[$self] = $class; - } - - $result = App::className(self::$_repositoryClass[$self], 'Model\Repository', 'Table'); - if (!$result) { - throw new Error\MissingTableClassException([static::$_repositoryClass[$self]]); - } - - return $result; - } - -/** - * Returns the BelongsTo associations as statically defined in the $_belongsTo - * property - * - * @return array - */ - public static function belongsTo() { - return static::$_belongsTo; - } - -/** - * Returns the HasOne associations as statically defined in the $_hasOne - * property - * - * @return array - */ - public static function hasOne() { - return static::$_hasOne; - } - -/** - * Returns the HasMany associations as statically defined in the $_hasMany - * property - * - * @return array - */ - public static function hasMany() { - return static::$_hasMany; - } - -/** - * Returns the BelongsToMany associations as statically defined in the - * $_belongsToMany property - * - * @return array - */ - public static function belongsToMany() { - return static::$_belongsToMany; - } - } diff --git a/Cake/ORM/Table.php b/Cake/ORM/Table.php index 8d2d009e35f..a30b4675af9 100644 --- a/Cake/ORM/Table.php +++ b/Cake/ORM/Table.php @@ -127,12 +127,6 @@ class Table { */ protected $_entityClass = '\Cake\ORM\Entity'; -/** - * Whether associations where copied already from the entity class or not - * - * @var boolean - */ - protected $_associationsInit = false; /** * Initializes a new instance @@ -410,10 +404,6 @@ public function entityClass($name = null) { * @return Cake\ORM\Association */ public function association($name) { - if (!$this->_associationsInit && $this->entityClass()) { - $this->_associationsInit = true; - $this->_setupAssociations(); - } if (isset($this->_associations[$name])) { return $this->_associations[$name]; } @@ -769,48 +759,4 @@ public function __call($method, $args) { return $this->callFinder($method, $query, $options); } -/** - * Copies association configuration from the entity class to the associations - * classes stored in this object - * - * @return void - */ - protected function _setupAssociations() { - $entity = $this->entityClass(); - $types = [ - 'belongsTo' => false, - 'hasOne' => false, - 'hasMany' => true, - 'belongsToMany' => true - ]; - - foreach ($types as $assoc => $plural) { - $associations = $entity::$assoc(); - foreach ($associations as $key => $val) { - if (is_integer($key)) { - $entityClass = App::classname($val, 'Model\Entity'); - list(,$className) = pluginSplit($val); - list($key, $val) = [$className, compact('entityClass')]; - } - - if (!empty($val['className'])) { - $val['entityClass'] = App::classname($val['className'], 'Model\Entity'); - unset($val['className']); - } - - if (empty($val['property'])) { - $name = Inflector::variable($key); - $name = $plural ? Inflector::pluralize($name) : $name; - $val['property'] = $name; - } - - $result = $this->{$assoc}($key, $val); - if ($assoc === 'belongsToMany' && !empty($val['with'])) { - $withClass = App::classname($val['with'], 'Model\Entity'); - $result->pivot($withClass::repository()); - } - } - } - } - } diff --git a/Cake/Test/TestApp/Model/Entity/Article.php b/Cake/Test/TestApp/Model/Entity/Article.php deleted file mode 100644 index 47403d97b43..00000000000 --- a/Cake/Test/TestApp/Model/Entity/Article.php +++ /dev/null @@ -1,13 +0,0 @@ -assertEquals('\Cake\ORM\Table', Entity::repositoryClass()); - } - -/** - * Tests that using a simple string for repositoryClass will try to - * load the class from the App namespace - * - * @return void - */ - public function testRepositoryClassInAPP() { - $class = $this->getMockClass('\Cake\ORM\Table'); - class_alias($class, 'App\Model\Repository\TestUserTable'); - $this->assertEquals('App\Model\Repository\TestUserTable', Entity::repositoryClass('TestUser')); - } - -/** - * Tests that using a simple string for repositoryClass will try to - * load the class from the Plugin namespace when using plugin notation - * - * @return void - */ - public function testRepositoryClassInPlugin() { - $class = $this->getMockClass('\Cake\ORM\Table'); - class_alias($class, 'MyPlugin\Model\Repository\SuperUserTable'); - $this->assertEquals( - 'MyPlugin\Model\Repository\SuperUserTable', - Entity::repositoryClass('MyPlugin.SuperUser') - ); - } - -/** - * Tests that using a simple string for repositoryClass will throw an exception - * when the class does not exist in the namespace - * - * @expectedException Cake\ORM\Error\MissingTableClassException - * @expectedExceptionMessage Table class FooUser could not be found. - * @return void - */ - public function testRepositoryClassNonExisting() { - $this->assertFalse(Entity::repositoryClass('FooUser')); - } - -/** - * Tests getting the repositoryClass based on conventions for the entity - * namespace - * - * @return void - */ - public function testRepositoryClassConventionForAPP() { - $class = $this->getMockClass('\Cake\ORM\Table'); - class_alias($class, 'TestApp\Model\Repository\ArticleTable'); - $result = \TestApp\Model\Entity\Article::repositoryClass(); - $this->assertEquals('TestApp\Model\Repository\ArticleTable', $result); - } - -/** - * Tests the repository method - * - * @return void - */ - public function testRepository() { - $entity = $this->getMockClass('\Cake\ORM\Entity', ['repositoryClass']); - $entity::staticExpects($this->once())->method('repositoryClass') - ->will($this->returnValue('\Cake\ORM\Table')); - $repository = $entity::repository(); - $this->assertInstanceOf('\Cake\ORM\Table', $repository); - $this->assertEquals($entity, $repository->entityClass()); - $this->assertSame($repository, $entity::repository()); - } - -/** - * Tests setting a table object using the repository method - * - * @return void - */ - public function testSetRepository() { - $entity = $this->getMockClass('\Cake\ORM\Entity', ['repositoryClass']); - $table = new \Cake\ORM\Table; - $entity::repository($table); - $this->assertEquals($entity, $table->entityClass()); - $this->assertSame($table, $entity::repository()); - } - } diff --git a/Cake/Test/TestCase/ORM/TableTest.php b/Cake/Test/TestCase/ORM/TableTest.php index e87d587dcd8..7a5cbd65ff3 100644 --- a/Cake/Test/TestCase/ORM/TableTest.php +++ b/Cake/Test/TestCase/ORM/TableTest.php @@ -783,215 +783,4 @@ public function testFindListHydrated() { $this->assertSame($expected, $query->toArray()); } -/** - * Tests automatic setup of associations based on entity information - * - * @return void - */ - public function testAutoSetupBelongsToBasic() { - $table = new Table(['table' => 'users', 'connection' => $this->connection]); - $barTarget = new Table(['table' => 'bars', 'connection' => $this->connection]); - - $entity = $this->getMockClass('\Cake\ORM\Entity', ['belongsTo']); - $barEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($barEntity, 'App\Model\Entity\Bar'); - - $entity::staticExpects($this->once())->method('belongsTo') - ->will($this->returnValue(['Bar', 'Foo.Department'])); - - $barEntity::staticExpects($this->at(0))->method('repository') - ->will($this->returnValue($barTarget)); - - $depatmentTarget = new Table([ - 'table' => 'departments', - 'connection' => $this->connection - ]); - $departmentEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($departmentEntity, 'Foo\Model\Entity\Department'); - - $departmentEntity::staticExpects($this->at(1))->method('repository') - ->will($this->returnValue($depatmentTarget)); - - $table->entityClass($entity); - $association = $table->association('Bar'); - $this->assertInstanceOf('\Cake\ORM\Association\BelongsTo', $association); - $this->assertEquals('Bar', $association->name()); - $this->assertEquals('bar', $association->property()); - $this->assertSame($barTarget, $association->target()); - - $association = $table->association('Department'); - $this->assertInstanceOf('\Cake\ORM\Association\BelongsTo', $association); - $this->assertEquals('Department', $association->name()); - $this->assertEquals('department', $association->property()); - $this->assertSame($depatmentTarget, $association->target()); - } - -/** - * Tests automatic setup of associations based on entity information - * - * @return void - */ - public function testAutoSetupBelongsToWithOptions() { - $table = new Table(['table' => 'users', 'connection' => $this->connection]); - $barTarget = new Table(['table' => 'bars', 'connection' => $this->connection]); - - $entity = $this->getMockClass('\Cake\ORM\Entity', ['belongsTo']); - $barEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($barEntity, 'Foo\Model\Entity\Bar'); - - $entity::staticExpects($this->once())->method('belongsTo') - ->will($this->returnValue([ - 'Bar' => ['className' => 'Foo.Bar', 'property' => 'thing'], - 'Baz' => ['className' => 'Foo.Baz', 'foreignKey' => 'crazy_id'] - ])); - - $barEntity::staticExpects($this->at(0))->method('repository') - ->will($this->returnValue($barTarget)); - - $bazTarget = new Table([ - 'table' => 'baz', - 'connection' => $this->connection - ]); - $bazEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($bazEntity, 'Foo\Model\Entity\Baz'); - - $bazEntity::staticExpects($this->at(1))->method('repository') - ->will($this->returnValue($bazTarget)); - - $table->entityClass($entity); - $association = $table->association('Bar'); - $this->assertInstanceOf('\Cake\ORM\Association\BelongsTo', $association); - $this->assertEquals('Bar', $association->name()); - $this->assertEquals('thing', $association->property()); - $this->assertSame($barTarget, $association->target()); - - $association = $table->association('Baz'); - $this->assertInstanceOf('\Cake\ORM\Association\BelongsTo', $association); - $this->assertEquals('Baz', $association->name()); - $this->assertEquals('baz', $association->property()); - $this->assertEquals('crazy_id', $association->foreignKey()); - $this->assertSame($bazTarget, $association->target()); - } - -/** - * Tests automatic setup of associations based on entity information - * - * @return void - */ - public function testAutoSetupHasManyAndHasOne() { - $table = new Table(['table' => 'users', 'connection' => $this->connection]); - $barTarget = new Table(['table' => 'bars', 'connection' => $this->connection]); - - $entity = $this->getMockClass('\Cake\ORM\Entity', ['hasMany', 'hasOne']); - $barEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($barEntity, 'Foo2\Model\Entity\Bar'); - - $entity::staticExpects($this->once())->method('hasMany') - ->will($this->returnValue([ - 'Bar' => ['className' => 'Foo2.Bar'], - ])); - - $entity::staticExpects($this->once())->method('hasOne') - ->will($this->returnValue([ - 'Baz' => ['className' => 'Foo2.Bar'], - ])); - - $barEntity::staticExpects($this->at(0))->method('repository') - ->will($this->returnValue($barTarget)); - - $bazTarget = new Table([ - 'table' => 'baz', - 'connection' => $this->connection - ]); - $bazEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($bazEntity, 'Foo2\Model\Entity\Baz'); - - $bazEntity::staticExpects($this->at(1))->method('repository') - ->will($this->returnValue($bazTarget)); - - $table->entityClass($entity); - $association = $table->association('Bar'); - $this->assertInstanceOf('\Cake\ORM\Association\HasMany', $association); - $this->assertEquals('Bar', $association->name()); - $this->assertEquals('bars', $association->property()); - $this->assertSame($barTarget, $association->target()); - - $association = $table->association('Baz'); - $this->assertInstanceOf('\Cake\ORM\Association\HasOne', $association); - $this->assertEquals('Baz', $association->name()); - $this->assertEquals('baz', $association->property()); - $this->assertSame($bazTarget, $association->target()); - } - -/** - * Tests automatic setup of associations based on entity information - * - * @return void - */ - public function testAutoSetupBelongstoMany() { - $table = new Table(['table' => 'users', 'connection' => $this->connection]); - $barTarget = new Table(['table' => 'bars', 'connection' => $this->connection]); - - $entity = $this->getMockClass('\Cake\ORM\Entity', ['belongsToMany']); - $barEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($barEntity, 'Foo3\Model\Entity\Bar'); - - $entity::staticExpects($this->once())->method('belongsToMany') - ->will($this->returnValue(['Foo3.Bar'])); - - $barEntity::staticExpects($this->at(0))->method('repository') - ->will($this->returnValue($barTarget)); - - $table->entityClass($entity); - $association = $table->association('Bar'); - $this->assertInstanceOf('\Cake\ORM\Association\BelongsToMany', $association); - $this->assertEquals('Bar', $association->name()); - $this->assertEquals('bars', $association->property()); - $this->assertSame($barTarget, $association->target()); - } - -/** - * Tests that it is possible to setup a belongsTo association and specify the pivot - * entity - * - * @return void - */ - public function testAutoSetupBelongstoManyWith() { - $table = new Table(['table' => 'users', 'connection' => $this->connection]); - $barTarget = new Table(['table' => 'bars', 'connection' => $this->connection]); - - $entity = $this->getMockClass('\Cake\ORM\Entity', ['belongsToMany']); - $barEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($barEntity, 'Foo4\Model\Entity\Bar'); - - $entity::staticExpects($this->once())->method('belongsToMany') - ->will($this->returnValue([ - 'Bar' => [ - 'className' => 'Foo4.Bar', - 'with' => 'Foo4.Baz' - ] - ])); - - $barEntity::staticExpects($this->at(1))->method('repository') - ->will($this->returnValue($barTarget)); - - $bazTarget = new Table([ - 'table' => 'baz', - 'connection' => $this->connection - ]); - $bazEntity = $this->getMockClass('\Cake\ORM\Entity', ['repository']); - class_alias($bazEntity, 'Foo4\Model\Entity\Baz'); - - $bazEntity::staticExpects($this->at(0))->method('repository') - ->will($this->returnValue($bazTarget)); - - $table->entityClass($entity); - $association = $table->association('Bar'); - $this->assertInstanceOf('\Cake\ORM\Association\BelongsToMany', $association); - $this->assertEquals('Bar', $association->name()); - $this->assertEquals('bars', $association->property()); - $this->assertSame($barTarget, $association->target()); - $this->assertSame($bazTarget, $association->pivot()); - } - }