Skip to content

Commit

Permalink
Implemented property inflection and method cache
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Oct 17, 2013
1 parent 0751ba3 commit ad3ff15
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 16 deletions.
54 changes: 49 additions & 5 deletions Cake/ORM/Entity.php
@@ -1,8 +1,23 @@
<?php

/**
* PHP Version 5.4
*
* 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 CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\ORM;

use Cake\ORM\Table;
use Cake\Utility\Inflector;

class Entity implements \ArrayAccess {

Expand All @@ -13,6 +28,20 @@ class Entity implements \ArrayAccess {
*/
protected $_properties = [];

/**
* Holds the name of the class for the instance object
*
* @var string
*/
protected $_className;

/**
* Holds a cached list of methods that exist in the instanced class
*
* @var array
*/
protected static $_accessors = [];

/**
* Initializes the internal properties of this entity out of the
* keys in an array
Expand All @@ -26,6 +55,7 @@ class Entity implements \ArrayAccess {
* @return void
*/
public function __construct(array $properties = [], $useSetters = true) {
$this->_className = get_class($this);
$this->set($properties, $useSetters);
}

Expand Down Expand Up @@ -123,8 +153,9 @@ public function set($property, $value = true, $useSetters = true) {
}

foreach ($property as $p => $value) {
if (method_exists($this, 'set' . ucFirst($p))) {
$value = $this->{'set' . ucFirst($p)}($value);
$setter = 'set' . Inflector::camelize($p);
if ($this->_methodExists($setter)) {
$value = $this->{$setter}($value);
}
$this->_properties[$p] = $value;
}
Expand All @@ -138,14 +169,14 @@ public function set($property, $value = true, $useSetters = true) {
* @return mixed
*/
public function &get($property) {
$method = 'get' . ucFirst($property);
$method = 'get' . Inflector::camelize($property);
$value = null;

if (isset($this->_properties[$property])) {
$value =& $this->_properties[$property];
}

if (method_exists($this, $method)) {
if ($this->_methodExists($method)) {
$value = $this->{$method}($value);
}
return $value;
Expand Down Expand Up @@ -248,4 +279,17 @@ public function offsetUnset($offset) {
$this->unsetProperty($offset);
}

/**
* Determines whether a method exists in this class
*
* @param string $method the method to check for existence
* @return boolean true if method exists
*/
protected function _methodExists($method) {
if (empty(static::$_accessors[$this->_className])) {
static::$_accessors[$this->_className] = array_flip(get_class_methods($this));
}
return isset(static::$_accessors[$this->_className][$method]);
}

}
12 changes: 6 additions & 6 deletions Cake/ORM/Error/MissingEntityException.php
@@ -1,17 +1,17 @@
<?php
/**
* MissingModelException class
*
* PHP 5
* PHP Version 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2013, Cake Software Foundation, Inc. (http://cakefoundation.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 2005-2013, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @since CakePHP(tm) v 3.0
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\ORM\Error;
Expand Down
28 changes: 23 additions & 5 deletions Cake/Test/TestCase/ORM/EntityTest.php
Expand Up @@ -374,11 +374,29 @@ public function testSetArrayAccess() {
* @return void
*/
public function testUnsetArrayAccess() {
$entity = $this->getMock('\Cake\ORM\Entity', ['unsetProperty']);
$entity->expects($this->at(0))
->method('unsetProperty')
->with('foo');
unset($entity['foo']);
$entity = $this->getMock('\Cake\ORM\Entity', ['unsetProperty']);
$entity->expects($this->at(0))
->method('unsetProperty')
->with('foo');
unset($entity['foo']);
}

/**
* Tests that the method cache will only report the methods for the called class,
* this is, calling methods defined in another entity will not cause a fatal error
* when trying to call directly an inexistent method in another class
*
* @return void
*/
public function testMethodCache() {
$entity = $this->getMock('\Cake\ORM\Entity', ['setFoo', 'getBar']);
$entity2 = $this->getMock('\Cake\ORM\Entity', ['setBar']);
$entity->expects($this->once())->method('setFoo');
$entity->expects($this->once())->method('getBar');
$entity2->expects($this->once())->method('setBar');

$entity->setFoo(1);
$entity->getBar();
$entity2->setBar(1);
}
}

0 comments on commit ad3ff15

Please sign in to comment.