Skip to content

Commit

Permalink
Add an easy way to set callback priorities for behaviors
Browse files Browse the repository at this point in the history
Behaviors often use priorities, make it easy to define the priority
of callbacks a behavior provides when binding it to a table.
  • Loading branch information
markstory committed Oct 28, 2013
1 parent 8282c66 commit e37a70a
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 2 deletions.
42 changes: 40 additions & 2 deletions Cake/ORM/Behavior.php
Expand Up @@ -67,6 +67,10 @@
* event fired from your Table classes including custom application
* specific ones.
*
* You can set the priority of a behaviors callbacks by using the
* `priority` setting when attaching a behavior. This will set the
* priority for all the callbacks a behavior provides.
*
* ## Finder methods
*
* Behaviors can provide finder methods that hook into a Table's
Expand All @@ -83,6 +87,7 @@
*
*
* @see Cake\ORM\Table::addBehavior()
* @see Cake\Event\EventManager
*/
class Behavior implements EventListener {

Expand All @@ -91,7 +96,29 @@ class Behavior implements EventListener {
*
* @var array
*/
public $settings = [];
protected $_settings = [];

/**
* Constructor
*
* Does not retain a reference to the Table object. If you need this
* you should override the constructor.
*
* @param Table $table The table this behavior is attached to.
* @param array $settings The settings for this behavior.
*/
public function __construct(Table $table, array $settings = []) {
$this->_settings = $settings;
}

/**
* Read the settings being used.
*
* @return array
*/
public function settings() {
return $this->_settings;
}

/**
* Get the Model callbacks this behavior is interested in.
Expand All @@ -112,10 +139,21 @@ public function implementedEvents() {
'Model.beforeDelete' => 'beforeDelete',
'Model.afterDelete' => 'afterDelete',
];
$settings = $this->settings();
$priority = isset($settings['priority']) ? $settings['priority'] : null;
$events = [];

foreach ($eventMap as $event => $method) {
if (method_exists($this, $method)) {
if (!method_exists($this, $method)) {
continue;
}
if ($priority === null) {
$events[$event] = $method;
} else {
$events[$event] = [
'callable' => $method,
'priority' => $priority
];
}
}
return $events;
Expand Down
90 changes: 90 additions & 0 deletions Cake/Test/TestCase/ORM/BehaviorTest.php
@@ -0,0 +1,90 @@
<?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 CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\ORM;

use Cake\ORM\Behavior;
use Cake\TestSuite\TestCase;

/**
* Test Stub.
*/
class TestBehavior extends Behavior {

/**
* Test for event bindings.
*/
public function beforeFind() {
}

}

/**
* Behavior test case
*/
class BehaviorTest extends TestCase {

/**
* setup
*
* @return void
*/
public function setUp() {
parent::setUp();
}

/**
* Test the side effects of the constructor.
*
* @return void
*/
public function testConstructor() {
$table = $this->getMock('Cake\ORM\Table');
$settings = ['key' => 'value'];
$behavior = new TestBehavior($table, $settings);
$this->assertEquals($settings, $behavior->settings());
}

/**
* Test the default behavior of implementedEvents
*
* @return void
*/
public function testImplementedEvents() {
$table = $this->getMock('Cake\ORM\Table');
$behavior = new TestBehavior($table);
$expected = [
'Model.beforeFind' => 'beforeFind'
];
$this->assertEquals($expected, $behavior->implementedEvents());
}

/**
* Test that implementedEvents uses the priority setting.
*
* @return void
*/
public function testImplementedEventsWithPriority() {
$table = $this->getMock('Cake\ORM\Table');
$behavior = new TestBehavior($table, ['priority' => 10]);
$expected = [
'Model.beforeFind' => [
'priority' => 10,
'callable' => 'beforeFind'
]
];
$this->assertEquals($expected, $behavior->implementedEvents());
}

}

0 comments on commit e37a70a

Please sign in to comment.