mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-18 18:46:17 +00:00
Adding Model::attach() and Model::detach() for dynamic loading/unloading of behaviors + tests, fixes #4010
git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6415 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
parent
f00834f81a
commit
423a56c958
2 changed files with 93 additions and 39 deletions
|
@ -397,49 +397,85 @@ class Model extends Overloadable {
|
|||
}
|
||||
|
||||
if ($this->actsAs !== null && empty($this->behaviors)) {
|
||||
$callbacks = array('setup', 'beforeFind', 'afterFind', 'beforeSave', 'afterSave', 'beforeDelete', 'afterDelete', 'afterError');
|
||||
$this->actsAs = Set::normalize($this->actsAs);
|
||||
|
||||
foreach ($this->actsAs as $behavior => $config) {
|
||||
$className = $behavior . 'Behavior';
|
||||
$this->attach($behavior, $config);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Attaches a behavior to a model
|
||||
*
|
||||
* @param string $behavior CamelCased name of the behavior to load
|
||||
* @param array $config Behavior configuration parameters
|
||||
* @return boolean True on success, false on failure
|
||||
* @access public
|
||||
*/
|
||||
function attach($behavior, $config = array()) {
|
||||
$name = $behavior;
|
||||
if (strpos($behavior, '.')) {
|
||||
list($plugin, $name) = explode('.', $behavior, 2);
|
||||
}
|
||||
$class = $name . 'Behavior';
|
||||
|
||||
if (!App::import('Behavior', $behavior)) {
|
||||
// Raise an error
|
||||
if (!App::import('Behavior', $behavior)) {
|
||||
// Raise an error
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isset($this->behaviors[$name])) {
|
||||
if (ClassRegistry::isKeySet($class)) {
|
||||
if (PHP5) {
|
||||
$this->behaviors[$name] = ClassRegistry::getObject($class);
|
||||
} else {
|
||||
if (ClassRegistry::isKeySet($className)) {
|
||||
if (PHP5) {
|
||||
$this->behaviors[$behavior] = ClassRegistry::getObject($className);
|
||||
} else {
|
||||
$this->behaviors[$behavior] =& ClassRegistry::getObject($className);
|
||||
}
|
||||
} else {
|
||||
if (PHP5) {
|
||||
$this->behaviors[$behavior] = new $className;
|
||||
} else {
|
||||
$this->behaviors[$behavior] =& new $className;
|
||||
}
|
||||
ClassRegistry::addObject($className, $this->behaviors[$behavior]);
|
||||
}
|
||||
$this->behaviors[$behavior]->setup($this, $config);
|
||||
|
||||
$methods = $this->behaviors[$behavior]->mapMethods;
|
||||
foreach ($methods as $method => $alias) {
|
||||
if (!array_key_exists($method, $this->__behaviorMethods)) {
|
||||
$this->__behaviorMethods[$method] = array($alias, $behavior);
|
||||
}
|
||||
}
|
||||
|
||||
$methods = get_class_methods($this->behaviors[$behavior]);
|
||||
$parentMethods = get_class_methods('ModelBehavior');
|
||||
|
||||
foreach ($methods as $m) {
|
||||
if (!in_array($m, $parentMethods)) {
|
||||
if (strpos($m, '_') !== 0 && !array_key_exists($m, $this->__behaviorMethods) && !in_array($m, $callbacks)) {
|
||||
$this->__behaviorMethods[$m] = array($m, $behavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->behaviors[$name] =& ClassRegistry::getObject($class);
|
||||
}
|
||||
} else {
|
||||
if (PHP5) {
|
||||
$this->behaviors[$name] = new $class;
|
||||
} else {
|
||||
$this->behaviors[$name] =& new $class;
|
||||
}
|
||||
ClassRegistry::addObject($class, $this->behaviors[$name]);
|
||||
}
|
||||
} elseif (isset($this->behaviors[$name]->settings) && isset($this->behaviors[$name]->settings[$this->alias])) {
|
||||
$config = array_merge($this->behaviors[$name]->settings[$this->alias], $config);
|
||||
}
|
||||
$this->behaviors[$name]->setup($this, $config);
|
||||
$methods = $this->behaviors[$name]->mapMethods;
|
||||
|
||||
foreach ($methods as $method => $alias) {
|
||||
if (!array_key_exists($method, $this->__behaviorMethods)) {
|
||||
$this->__behaviorMethods[$method] = array($alias, $name);
|
||||
}
|
||||
}
|
||||
|
||||
$methods = get_class_methods($this->behaviors[$name]);
|
||||
$parentMethods = get_class_methods('ModelBehavior');
|
||||
$callbacks = array('setup', 'beforeFind', 'afterFind', 'beforeSave', 'afterSave', 'beforeDelete', 'afterDelete', 'afterError');
|
||||
|
||||
foreach ($methods as $m) {
|
||||
if (!in_array($m, $parentMethods)) {
|
||||
if (strpos($m, '_') !== 0 && !array_key_exists($m, $this->__behaviorMethods) && !in_array($m, $callbacks)) {
|
||||
$this->__behaviorMethods[$m] = array($m, $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Detaches a behavior from a model
|
||||
*
|
||||
* @param string $behavior CamelCased name of the behavior to unload
|
||||
* @access public
|
||||
*/
|
||||
function detach($behavior) {
|
||||
if (isset($this->behaviors[$behavior])) {
|
||||
unset($this->behaviors[$behavior]);
|
||||
}
|
||||
foreach ($this->__behaviorMethods as $m => $callback) {
|
||||
if (is_array($callback) && $callback[1] == $behavior) {
|
||||
unset($this->__behaviorMethods[$m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2158,7 +2194,6 @@ class Model extends Overloadable {
|
|||
}
|
||||
|
||||
$valid = true;
|
||||
$msg = null;
|
||||
|
||||
if (method_exists($this, $rule) || isset($this->__behaviorMethods[$rule]) || isset($this->__behaviorMethods[strtolower($rule)])) {
|
||||
$ruleParams[] = array_diff_key($validator, $default);
|
||||
|
|
|
@ -3332,6 +3332,25 @@ class ModelTest extends CakeTestCase {
|
|||
$this->assertEqual($this->model->data, $expected);
|
||||
}
|
||||
|
||||
function testDynamicBehaviorAttachment() {
|
||||
$this->loadFixtures('Apple');
|
||||
$this->model =& new Apple();
|
||||
$this->assertEqual($this->model->behaviors, array());
|
||||
|
||||
$this->model->attach('Tree', array('left' => 'left_field', 'right' => 'right_field'));
|
||||
$this->assertTrue(is_object($this->model->behaviors['Tree']));
|
||||
|
||||
$expected = array('parent' => 'parent_id', 'left' => 'left_field', 'right' => 'right_field', 'scope' => '1 = 1', 'enabled' => true, 'type' => 'nested', '__parentChange' => false);
|
||||
$this->assertEqual($this->model->behaviors['Tree']->settings['Apple'], $expected);
|
||||
|
||||
$expected['enabled'] = false;
|
||||
$this->model->attach('Tree', array('enabled' => false));
|
||||
$this->assertEqual($this->model->behaviors['Tree']->settings['Apple'], $expected);
|
||||
|
||||
$this->model->detach('Tree');
|
||||
$this->assertEqual($this->model->behaviors, array());
|
||||
}
|
||||
|
||||
function endTest() {
|
||||
ClassRegistry::flush();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue