Browse Source

Merge branch 'faster-entities' into 3.2

Jose Lorenzo Rodriguez 10 years ago
parent
commit
ad386871f2

+ 2 - 2
src/Core/Plugin.php

@@ -185,9 +185,9 @@ class Plugin
         if (Configure::check('plugins')) {
             return;
         }
-        $vendorFile = dirname(dirname(dirname(dirname(__DIR__)))) . DS . 'cakephp-plugins.php';
+        $vendorFile = dirname(dirname(__DIR__)) . DS . 'cakephp-plugins.php';
         if (!file_exists($vendorFile)) {
-            $vendorFile = dirname(dirname(__DIR__)) . DS . 'cakephp-plugins.php';
+            $vendorFile = dirname(dirname(dirname(dirname(__DIR__)))) . DS . 'cakephp-plugins.php';
             if (!file_exists($vendorFile)) {
                 Configure::write(['plugins' => []]);
                 return;

+ 7 - 3
src/Database/Type.php

@@ -102,7 +102,11 @@ class Type
         if (!isset(static::$_types[$name])) {
             throw new InvalidArgumentException(sprintf('Unknown type "%s"', $name));
         }
-        return static::$_builtTypes[$name] = new static::$_types[$name]($name);
+        if (is_string(static::$_types[$name])) {
+            return static::$_builtTypes[$name] = new static::$_types[$name]($name);
+        }
+        
+        return static::$_builtTypes[$name] = static::$_types[$name];
     }
 
     /**
@@ -136,7 +140,7 @@ class Type
      * If called with no arguments it will return current types map array
      * If $className is omitted it will return mapped class for $type
      *
-     * @param string|array|null $type if string name of type to map, if array list of arrays to be mapped
+     * @param string|array|\Cake\Database\Type|null $type if string name of type to map, if array list of arrays to be mapped
      * @param string|null $className The classname to register.
      * @return array|string|null if $type is null then array with current map, if $className is null string
      * configured class name for give $type, null otherwise
@@ -146,7 +150,7 @@ class Type
         if ($type === null) {
             return self::$_types;
         }
-        if (!is_string($type)) {
+        if (is_array($type)) {
             self::$_types = $type;
             return null;
         }

+ 37 - 19
src/Datasource/EntityTrait.php

@@ -58,13 +58,6 @@ trait EntityTrait
     protected $_virtual = [];
 
     /**
-     * Holds the name of the class for the instance object
-     *
-     * @var string
-     */
-    protected $_className;
-
-    /**
      * Holds a list of the properties that were modified or added after this object
      * was originally created.
      *
@@ -73,7 +66,7 @@ trait EntityTrait
     protected $_dirty = [];
 
     /**
-     * Holds a cached list of methods that exist in the instanced class
+     * Holds a cached list of getters/setters per class
      *
      * @var array
      */
@@ -258,8 +251,8 @@ trait EntityTrait
                 continue;
             }
 
-            $setter = '_set' . Inflector::camelize($p);
-            if ($this->_methodExists($setter)) {
+            $setter = $this->_accessor($p, 'set');
+            if ($setter) {
                 $value = $this->{$setter}($value);
             }
             $this->_properties[$p] = $value;
@@ -282,13 +275,13 @@ trait EntityTrait
         }
 
         $value = null;
-        $method = '_get' . Inflector::camelize($property);
+        $method = $this->_accessor($property, 'get');
 
         if (isset($this->_properties[$property])) {
             $value =& $this->_properties[$property];
         }
 
-        if ($this->_methodExists($method)) {
+        if ($method) {
             $result = $this->{$method}($value);
             return $result;
         }
@@ -506,17 +499,42 @@ trait EntityTrait
     }
 
     /**
-     * Determines whether a method exists in this class
+     * Fetch accessor method name
+     * Accessor methods (available or not) are cached in $_accessors
      *
-     * @param string $method the method to check for existence
-     * @return bool true if method exists
+     * @param string $property the field name to derive getter name from
+     * @param string $type the accessor type ('get' or 'set')
+     * @return string method name or empty string (no method available)
      */
-    protected function _methodExists($method)
+    protected static function _accessor($property, $type)
     {
-        if (empty(static::$_accessors[$this->_className])) {
-            static::$_accessors[$this->_className] = array_flip(get_class_methods($this));
+        $class = static::class;
+        if (isset(static::$_accessors[$class][$type][$property])) {
+            return static::$_accessors[$class][$type][$property];
+        }
+
+        if (!empty(static::$_accessors[$class])) {
+            return static::$_accessors[$class][$type][$property] = '';
+        }
+
+        if ($class === 'Cake\ORM\Entity') {
+            return '';
+        }
+
+        foreach (get_class_methods($class) as $method) {
+            $prefix = substr($method, 1, 3);
+            if ($method[0] !== '_' || ($prefix !== 'get' && $prefix !== 'set')) {
+                continue;
+            }
+            $field = Inflector::underscore(substr($method, 4));
+            static::$_accessors[$class][$prefix][$field] = $method;
+        }
+
+        if (!isset(static::$_accessors[$class][$type][$property])) {
+            static::$_accessors[$class][$type][$property] = '';
         }
-        return isset(static::$_accessors[$this->_className][$method]);
+
+        return static::$_accessors[$class][$type][$property];
     }
 
     /**

+ 4 - 4
src/ORM/Behavior/TranslateBehavior.php

@@ -234,10 +234,10 @@ class TranslateBehavior extends Behavior
             $name = $alias . '_' . $field . '_translation';
 
             $contain[$name]['queryBuilder'] = $conditions(
-            $field,
-            $locale,
-            $query,
-            $select
+                $field,
+                $locale,
+                $query,
+                $select
             );
 
             if ($changeFilter) {

+ 0 - 1
src/ORM/Entity.php

@@ -54,7 +54,6 @@ class Entity implements EntityInterface, InvalidPropertyInterface
             'guard' => false,
             'source' => null
         ];
-        $this->_className = get_class($this);
 
         if (!empty($options['source'])) {
             $this->source($options['source']);

+ 6 - 0
tests/TestCase/Database/TypeTest.php

@@ -138,6 +138,12 @@ class TypeTest extends TestCase
         $this->assertInstanceOf($fooType, $type);
         $this->assertEquals('foo', $type->getName());
         $this->assertEquals('text', $type->getBaseType());
+
+        $fooType = new FooType();
+        Type::map('foo2', $fooType);
+        $map = Type::map();
+        $this->assertSame($fooType, $map['foo2']);
+        $this->assertSame($fooType, Type::map('foo2'));
     }
 
     /**

+ 0 - 1
tests/test_app/TestApp/Model/Entity/NonExtending.php

@@ -23,7 +23,6 @@ class NonExtending implements EntityInterface
             'guard' => false,
             'source' => null
         ];
-        $this->_className = get_class($this);
 
         if (!empty($properties)) {
             $this->set($properties, [