ソースを参照

NamedScopeBehavior testing

euromark 12 年 前
コミット
b78b6f19e4

+ 87 - 0
Model/Behavior/NamedScopeBehavior.php

@@ -0,0 +1,87 @@
+<?php
+App::uses('ModelBehavior', 'Model');
+
+// basic code taken and modified/fixed from https://github.com/netguru/namedscopebehavior
+
+/**
+ * Edited - Mark Scherer
+ * - its now "scope" instead of "scopes" (singular and now analogous to "contain" etc)
+ * - corrected syntax, indentation
+ * - now probably cake2.x ready (awaiting tests)
+ */
+class NamedScopeBehavior extends ModelBehavior {
+
+	protected $_defaults = array(
+		'scope' => array()
+	);
+
+	public function setup(Model $Model, $settings = array()) {
+		$this->settings[$Model->alias] = $settings + $this->_defaults;
+	}
+
+	public function beforeFind(Model $Model, $queryData) {
+		$scopes = array();
+		// passed as scopes
+		if (!empty($queryData['scope'])) {
+			$scope = !is_array($queryData['scope']) ? array($queryData['scope']) : $queryData['scope'];
+			$scopes = array_merge($scopes, $scope);
+		}
+		// passed as conditions['scope']
+		if (is_array($queryData['conditions']) && !empty($queryData['conditions']['scope'])) {
+			$scope = !is_array($queryData['conditions']['scope']) ? array($queryData['conditions']['scope']) : $queryData['conditions']['scope'];
+			unset($queryData['conditions']['scope']);
+			$scopes = array_merge($scopes, $scope);
+		}
+
+		// if there are scopes defined, we need to get rid of possible condition set earlier by find() method if model->id was set
+		if (!empty($scopes) && !empty($Model->id) && !empty($queryData['conditions']["`{$Model->alias}`.`{$Model->primaryKey}`"]) && $queryData['conditions']["`{$Model->alias}`.`{$Model->primaryKey}`"] ==
+			$Model->id) {
+			unset($queryData['conditions']["`{$Model->alias}`.`{$Model->primaryKey}`"]);
+		}
+
+		$queryData['conditions'][] = $this->_conditions($scopes, $Model->alias);
+		return $queryData;
+	}
+
+	/**
+	 * NamedScopeBehavior::scope()
+	 *
+	 * @param Model $Model
+	 * @param string $name
+	 * @param mixed $value
+	 * @return mixed
+	 */
+	public function scope(Model $Model, $name = null, $value = null) {
+		if ($name === null) {
+			return $this->settings[$Model->alias]['scope'];
+		}
+		if (in_array($name, $this->settings[$Model->alias]['scope'])) {
+			continue;
+		}
+		$this->settings[$Model->alias]['scope'][$name] = $value;
+	}
+
+	/**
+	 * NamedScopeBehavior::_conditions()
+	 *
+	 * @param array $scopes
+	 * @param string $modelName
+	 * @return array
+	 */
+	protected function _conditions(array $scopes, $modelName) {
+		$conditions = array();
+		foreach ($scopes as $scope) {
+			if (strpos($scope, '.')) {
+				list($scopeModel, $scope) = explode('.', $scope);
+			} else {
+				$scopeModel = $modelName;
+			}
+			if (!empty($this->settings[$scopeModel]['scope'][$scope])) {
+				$conditions[] = array($this->settings[$scopeModel]['scope'][$scope]);
+			}
+		}
+
+		return $conditions;
+	}
+
+}

+ 68 - 0
Test/Case/Model/Behavior/NamedScopeBehaviorTest.php

@@ -0,0 +1,68 @@
+<?php
+
+App::uses('NamedScopeBehavior', 'Tools.Model/Behavior');
+App::uses('MyCakeTestCase', 'Tools.TestSuite');
+
+class NamedScopeBehaviorTest extends MyCakeTestCase {
+
+	public $NamedScopeBehavior;
+
+	public $Comment;
+
+	public $fixtures = array('core.comment', 'core.user');
+
+	public function setUp() {
+		parent::setUp();
+
+		$this->NamedScopeBehavior = new NamedScopeBehavior();
+
+		$this->Comment = ClassRegistry::init('Comment');
+		$this->Comment->bindModel(array('belongsTo' => array('User')), false);
+		$this->Comment->displayField = 'comment';
+		$this->Comment->Behaviors->load('Tools.NamedScope');
+		$this->Comment->User->Behaviors->load('Tools.NamedScope');
+	}
+
+	public function testObject() {
+		$this->assertTrue(is_object($this->NamedScopeBehavior));
+		$this->assertInstanceOf('NamedScopeBehavior', $this->NamedScopeBehavior);
+	}
+
+	/**
+	 * NamedScopeBehaviorTest::testBasic()
+	 *
+	 * @return void
+	 */
+	public function testBasic() {
+		$before = $this->Comment->find('count');
+
+		$this->Comment->scope('active', array('published' => 'Y'));
+		$options = array(
+			'scope' => array('active')
+		);
+		$after = $this->Comment->find('count', $options);
+		$this->assertTrue($before > $after);
+		$this->assertSame(5, $after);
+	}
+
+	/**
+	 * NamedScopeBehaviorTest::testCrossModel()
+	 *
+	 * @return void
+	 */
+	public function testCrossModel() {
+		$before = $this->Comment->find('count');
+
+		$this->Comment->scope('active', array('Comment.published' => 'Y'));
+		$this->Comment->User->scope('senior', array('User.id <' => '3'));
+
+		$options = array(
+			'contain' => array('User'),
+			'scope' => array('Comment.active', 'User.senior')
+		);
+		$after = $this->Comment->find('count', $options);
+		$this->assertTrue($before > $after);
+		$this->assertSame(4, $after);
+	}
+
+}