Browse Source

Merge pull request #6430 from robertpustulka/3.1-table-locator

3.1 - Reduce the number of static TableRegistry calls and use table locators instead.
José Lorenzo Rodríguez 11 years ago
parent
commit
0205fe6e41

+ 4 - 1
src/Console/Shell.php

@@ -21,6 +21,7 @@ use Cake\Core\Plugin;
 use Cake\Datasource\ModelAwareTrait;
 use Cake\Filesystem\File;
 use Cake\Log\LogTrait;
+use Cake\ORM\Locator\LocatorAwareTrait;
 use Cake\Utility\Inflector;
 use Cake\Utility\MergeVariablesTrait;
 use Cake\Utility\Text;
@@ -33,6 +34,7 @@ use Cake\Utility\Text;
 class Shell
 {
 
+    use LocatorAwareTrait;
     use LogTrait;
     use MergeVariablesTrait;
     use ModelAwareTrait;
@@ -158,7 +160,8 @@ class Shell
         }
         $this->_io = $io ?: new ConsoleIo();
 
-        $this->modelFactory('Table', ['Cake\ORM\TableRegistry', 'get']);
+        $locator = $this->tableLocator() ? : 'Cake\ORM\TableRegistry';
+        $this->modelFactory('Table', [$locator, 'get']);
         $this->Tasks = new TaskRegistry($this);
 
         $this->_io->setLoggers(true);

+ 3 - 1
src/Controller/Controller.php

@@ -22,6 +22,7 @@ use Cake\Event\EventManagerTrait;
 use Cake\Log\LogTrait;
 use Cake\Network\Request;
 use Cake\Network\Response;
+use Cake\ORM\Locator\LocatorAwareTrait;
 use Cake\Routing\RequestActionTrait;
 use Cake\Routing\Router;
 use Cake\Utility\MergeVariablesTrait;
@@ -84,6 +85,7 @@ class Controller implements EventListenerInterface
 {
 
     use EventManagerTrait;
+    use LocatorAwareTrait;
     use LogTrait;
     use MergeVariablesTrait;
     use ModelAwareTrait;
@@ -270,7 +272,7 @@ class Controller implements EventListenerInterface
             $this->eventManager($eventManager);
         }
 
-        $this->modelFactory('Table', ['Cake\ORM\TableRegistry', 'get']);
+        $this->modelFactory('Table', [$this->tableLocator(), 'get']);
         $modelClass = ($this->plugin ? $this->plugin . '.' : '') . $this->name;
         $this->_setModelClass($modelClass);
 

+ 5 - 3
src/Network/Session/DatabaseSession.php

@@ -51,11 +51,13 @@ class DatabaseSession implements SessionHandlerInterface
      */
     public function __construct(array $config = [])
     {
+        $tableLocator = isset($config['tableLocator']) ? $config['tableLocator'] : TableRegistry::locator();
+
         if (empty($config['model'])) {
-            $config = TableRegistry::exists('Sessions') ? [] : ['table' => 'sessions'];
-            $this->_table = TableRegistry::get('Sessions', $config);
+            $config = $tableLocator->exists('Sessions') ? [] : ['table' => 'sessions'];
+            $this->_table = $tableLocator->get('Sessions', $config);
         } else {
-            $this->_table = TableRegistry::get($config['model']);
+            $this->_table = $tableLocator->get($config['model']);
         }
 
         $this->_timeout = ini_get('session.gc_maxlifetime');

+ 7 - 3
src/ORM/Association.php

@@ -18,9 +18,9 @@ use Cake\Core\ConventionsTrait;
 use Cake\Database\Expression\IdentifierExpression;
 use Cake\Datasource\EntityInterface;
 use Cake\Datasource\ResultSetDecorator;
+use Cake\ORM\Locator\LocatorAwareTrait;
 use Cake\ORM\Query;
 use Cake\ORM\Table;
-use Cake\ORM\TableRegistry;
 use Cake\Utility\Inflector;
 use InvalidArgumentException;
 use RuntimeException;
@@ -34,6 +34,7 @@ abstract class Association
 {
 
     use ConventionsTrait;
+    use LocatorAwareTrait;
 
     /**
      * Strategy name to use joins for fetching associated records
@@ -198,6 +199,7 @@ abstract class Association
             'finder',
             'foreignKey',
             'joinType',
+            'tableLocator',
             'propertyName',
             'sourceTable',
             'targetTable'
@@ -291,11 +293,13 @@ abstract class Association
             $registryAlias = $this->_name;
         }
 
+        $tableLocator = $this->tableLocator();
+
         $config = [];
-        if (!TableRegistry::exists($registryAlias)) {
+        if (!$tableLocator->exists($registryAlias)) {
             $config = ['className' => $this->_className];
         }
-        $this->_targetTable = TableRegistry::get($registryAlias, $config);
+        $this->_targetTable = $tableLocator->get($registryAlias, $config);
 
         return $this->_targetTable;
     }

+ 4 - 4
src/ORM/Association/BelongsToMany.php

@@ -18,7 +18,6 @@ use Cake\Datasource\EntityInterface;
 use Cake\ORM\Association;
 use Cake\ORM\Query;
 use Cake\ORM\Table;
-use Cake\ORM\TableRegistry;
 use Cake\Utility\Inflector;
 use InvalidArgumentException;
 use RuntimeException;
@@ -164,6 +163,7 @@ class BelongsToMany extends Association
         $source = $this->source();
         $sAlias = $source->alias();
         $tAlias = $target->alias();
+        $tableLocator = $this->tableLocator();
 
         if ($table === null) {
             if (!empty($this->_junctionTable)) {
@@ -177,15 +177,15 @@ class BelongsToMany extends Association
                 $tableAlias = Inflector::camelize($tableName);
 
                 $config = [];
-                if (!TableRegistry::exists($tableAlias)) {
+                if (!$tableLocator->exists($tableAlias)) {
                     $config = ['table' => $tableName];
                 }
-                $table = TableRegistry::get($tableAlias, $config);
+                $table = $tableLocator->get($tableAlias, $config);
             }
         }
 
         if (is_string($table)) {
-            $table = TableRegistry::get($table);
+            $table = $tableLocator->get($table);
         }
         $junctionAlias = $table->alias();
 

+ 15 - 6
src/ORM/Behavior/TranslateBehavior.php

@@ -20,9 +20,9 @@ use Cake\Event\Event;
 use Cake\I18n\I18n;
 use Cake\ORM\Behavior;
 use Cake\ORM\Entity;
+use Cake\ORM\Locator\LocatorAwareTrait;
 use Cake\ORM\Query;
 use Cake\ORM\Table;
-use Cake\ORM\TableRegistry;
 use Cake\Utility\Inflector;
 
 /**
@@ -40,6 +40,8 @@ use Cake\Utility\Inflector;
 class TranslateBehavior extends Behavior
 {
 
+    use LocatorAwareTrait;
+
     /**
      * Table instance
      *
@@ -78,7 +80,8 @@ class TranslateBehavior extends Behavior
         'referenceName' => '',
         'allowEmptyTranslations' => true,
         'onlyTranslated' => false,
-        'strategy' => 'subquery'
+        'strategy' => 'subquery',
+        'tableLocator' => null
     ];
 
     /**
@@ -93,6 +96,11 @@ class TranslateBehavior extends Behavior
             'defaultLocale' => I18n::defaultLocale(),
             'referenceName' => $this->_referenceName($table)
         ];
+
+        if (isset($config['tableLocator'])) {
+            $this->_tableLocator = $config['tableLocator'];
+        }
+
         parent::__construct($table, $config);
     }
 
@@ -104,7 +112,7 @@ class TranslateBehavior extends Behavior
      */
     public function initialize(array $config)
     {
-        $this->_translationTable = TableRegistry::get($this->_config['translationTable']);
+        $this->_translationTable = $this->tableLocator()->get($this->_config['translationTable']);
 
         $this->setupFieldAssociations(
             $this->_config['fields'],
@@ -133,18 +141,19 @@ class TranslateBehavior extends Behavior
         $targetAlias = $this->_translationTable->alias();
         $alias = $this->_table->alias();
         $filter = $this->_config['onlyTranslated'];
+        $tableLocator = $this->tableLocator();
 
         foreach ($fields as $field) {
             $name = $alias . '_' . $field . '_translation';
 
-            if (!TableRegistry::exists($name)) {
-                $fieldTable = TableRegistry::get($name, [
+            if (!$tableLocator->exists($name)) {
+                $fieldTable = $tableLocator->get($name, [
                     'className' => $table,
                     'alias' => $name,
                     'table' => $this->_translationTable->table()
                 ]);
             } else {
-                $fieldTable = TableRegistry::get($name);
+                $fieldTable = $tableLocator->get($name);
             }
 
             $conditions = [

+ 49 - 0
src/ORM/Locator/LocatorAwareTrait.php

@@ -0,0 +1,49 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.1.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace Cake\ORM\Locator;
+
+use Cake\ORM\TableRegistry;
+
+/**
+ * Contains method for setting and accessing LocatorInterface instance
+ */
+trait LocatorAwareTrait
+{
+
+    /**
+     * Table locator instance
+     *
+     * @var \Cake\ORM\Locator\LocatorInterface
+     */
+    protected $_tableLocator;
+
+    /**
+     * Sets the table locator.
+     * If no parameters are passed, it will return the currently used locator.
+     *
+     * @param \Cake\ORM\Locator\LocatorInterface|null $tableLocator LocatorInterface instance.
+     * @return \Cake\ORM\Locator\LocatorInterface
+     */
+    public function tableLocator(LocatorInterface $tableLocator = null)
+    {
+        if ($tableLocator !== null) {
+            $this->_tableLocator = $tableLocator;
+        }
+        if (!$this->_tableLocator) {
+            $this->_tableLocator = TableRegistry::locator();
+        }
+        return $this->_tableLocator;
+    }
+}

+ 3 - 1
src/View/Cell.php

@@ -19,6 +19,7 @@ use Cake\Event\EventManager;
 use Cake\Event\EventManagerTrait;
 use Cake\Network\Request;
 use Cake\Network\Response;
+use Cake\ORM\Locator\LocatorAwareTrait;
 use Cake\Utility\Inflector;
 use Cake\View\Exception\MissingCellViewException;
 use Cake\View\Exception\MissingTemplateException;
@@ -32,6 +33,7 @@ abstract class Cell
 {
 
     use EventManagerTrait;
+    use LocatorAwareTrait;
     use ModelAwareTrait;
     use ViewVarsTrait;
 
@@ -140,7 +142,7 @@ abstract class Cell
         $this->eventManager($eventManager);
         $this->request = $request;
         $this->response = $response;
-        $this->modelFactory('Table', ['Cake\ORM\TableRegistry', 'get']);
+        $this->modelFactory('Table', [$this->tableLocator(), 'get']);
 
         foreach ($this->_validCellOptions as $var) {
             if (isset($cellOptions[$var])) {

+ 20 - 0
tests/TestCase/ORM/AssociationTest.php

@@ -326,4 +326,24 @@ class AssociationTest extends TestCase
             $this->association->find()->getOptions()
         );
     }
+
+    /**
+     * Tests that `locator` is a valid option for the association constructor
+     *
+     * @return void
+     */
+    public function testLocatorInConstructor()
+    {
+        $locator = $this->getMock('Cake\ORM\Locator\LocatorInterface');
+        $config = [
+            'className' => '\Cake\Test\TestCase\ORM\TestTable',
+            'tableLocator' => $locator
+        ];
+        $assoc = $this->getMock(
+            '\Cake\ORM\Association',
+            ['type', 'eagerLoader', 'cascadeDelete', 'isOwningSide', 'saveAssociated'],
+            ['Foo', $config]
+        );
+        $this->assertEquals($locator, $assoc->tableLocator());
+    }
 }

+ 53 - 0
tests/TestCase/ORM/Locator/LocatorAwareTraitTest.php

@@ -0,0 +1,53 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.1.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+
+namespace Cake\Test\TestCase\ORM\Locator;
+
+use Cake\ORM\TableRegistry;
+use Cake\TestSuite\TestCase;
+
+/**
+ * LocatorAwareTrait test case
+ *
+ */
+class LocatorAwareTraitTest extends TestCase
+{
+
+    /**
+     * setup
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        parent::setUp();
+
+        $this->subject = $this->getObjectForTrait('Cake\ORM\Locator\LocatorAwareTrait');
+    }
+
+    /**
+     * Tests tableLocator method
+     *
+     * @return void
+     */
+    public function testTableLocator()
+    {
+        $tableLocator = $this->subject->tableLocator();
+        $this->assertSame(TableRegistry::locator(), $tableLocator);
+
+        $newLocator = $this->getMock('Cake\ORM\Locator\LocatorInterface');
+        $subjectLocator = $this->subject->tableLocator($newLocator);
+        $this->assertSame($newLocator, $subjectLocator);
+    }
+}