浏览代码

allow order shim.

euromark 11 年之前
父节点
当前提交
2bb0b58675
共有 3 个文件被更改,包括 106 次插入0 次删除
  1. 65 0
      src/Model/Table/Table.php
  2. 8 0
      tests/TestApp/Model/Table/ToolsUsersTable.php
  3. 33 0
      tests/TestCase/Model/Table/TableTest.php

+ 65 - 0
src/Model/Table/Table.php

@@ -8,9 +8,13 @@ use Cake\Utility\Inflector;
 use Cake\Validation\Validation;
 use Cake\Validation\Validator;
 use Tools\Utility\Utility;
+use Cake\ORM\Query;
+use Cake\Event\Event;
 
 class Table extends CakeTable {
 
+	public $order = null;
+
 	/**
 	 * initialize()
 	 *
@@ -27,6 +31,8 @@ class Table extends CakeTable {
 		}
 		$this->_shimRelations();
 
+		$this->prefixOrderProperty();
+
 		$this->addBehavior('Timestamp');
 	}
 
@@ -294,6 +300,65 @@ class Table extends CakeTable {
 	}
 
 	/**
+	 * Set the default ordering as 2.x shim
+	 *
+	 * If you don't want that, don't call parent when overwriting it in extending classses.
+	 *
+	 * @param Event $event
+	 * @param Query $query
+	 * @param array $options
+	 * @param boolean $primary
+	 * @return Query
+	 */
+	public function beforeFind(Event $event, Query $query, $options, $primary) {
+		if ($query->clause('order') === null && !empty($this->order)) {
+			$query->order($this->order);
+		}
+
+		return $query;
+	}
+
+	/**
+	 * Prefixes the order property with the actual alias if its a string or array.
+	 *
+	 * The core fails on using the proper prefix when building the query with two
+	 * different tables.
+	 *
+	 * @return void
+	 */
+	public function prefixOrderProperty() {
+		if (is_string($this->order)) {
+			$this->order = $this->_prefixAlias($this->order);
+		}
+		if (is_array($this->order)) {
+			foreach ($this->order as $key => $value) {
+				if (is_numeric($key)) {
+					$this->order[$key] = $this->_prefixAlias($value);
+				} else {
+					$newKey = $this->_prefixAlias($key);
+					$this->order[$newKey] = $value;
+					if ($newKey !== $key) {
+						unset($this->order[$key]);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Checks if a string of a field name contains a dot if not it will add it and add the alias prefix.
+	 *
+	 * @param string
+	 * @return string
+	 */
+	protected function _prefixAlias($string) {
+		if (strpos($string, '.') === false) {
+			return $this->alias() . '.' . $string;
+		}
+		return $string;
+	}
+
+	/**
 	 * Return the next auto increment id from the current table
 	 * UUIDs will return false
 	 *

+ 8 - 0
tests/TestApp/Model/Table/ToolsUsersTable.php

@@ -5,4 +5,12 @@ namespace TestApp\Model\Table;
 use Tools\Model\Table\Table;
 
 class ToolsUsersTable extends Table {
+
+	/**
+	 * 2.x way of declaring order - here to test shims
+	 *
+	 * @var array
+	 */
+	public $order = array('name' => 'ASC');
+
 }

+ 33 - 0
tests/TestCase/Model/Table/TableTest.php

@@ -108,6 +108,39 @@ class TableTest extends TestCase {
 	}
 
 	/**
+	 * Test 2.x shimmed order property
+	 *
+	 *   $this->order = array('field_name' => 'ASC') etc
+	 *
+	 * becomes
+	 *
+	 *   $this->order = array('TableName.field_name' => 'ASC') and a beforeFind addition.
+	 *
+	 * @return void
+	 */
+	public function testOrder() {
+		$this->Users->truncate();
+		$rows = array(
+			array('role_id' => 1, 'name' => 'Gandalf'),
+			array('role_id' => 2, 'name' => 'Asterix'),
+			array('role_id' => 1, 'name' => 'Obelix'),
+			array('role_id' => 3, 'name' => 'Harry Potter'));
+		foreach ($rows as $row) {
+			$entity = $this->Users->newEntity($row);
+			$this->Users->save($entity);
+		}
+
+		$result = $this->Users->find('list')->toArray();
+		$expected = array(
+			'Asterix',
+			'Gandalf',
+			'Harry Potter',
+			'Obelix'
+		);
+		$this->assertSame($expected, array_values($result));
+	}
+
+	/**
 	 * TableTest::testGetRelatedInUse()
 	 *
 	 * @return void