mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
Merge branch '2.x' into 2.next
This commit is contained in:
commit
135a24e0f1
25 changed files with 444 additions and 87 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -14,6 +14,9 @@
|
|||
#################################
|
||||
/nbproject
|
||||
.idea
|
||||
/.project
|
||||
/.buildpath
|
||||
/.settings/
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
|
|
|
@ -1,15 +1 @@
|
|||
/**
|
||||
* 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
|
||||
* @package app.View.Emails.html
|
||||
* @since CakePHP(tm) v 0.10.0.1076
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
<div id="<?php echo $key; ?>Message" class="<?php echo !empty($params['class']) ? $params['class'] : 'message'; ?>"><?php echo $message; ?></div>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.*",
|
||||
"cakephp/cakephp": "~2.8"
|
||||
"cakephp/cakephp": "~2.9"
|
||||
},
|
||||
"suggest": {
|
||||
"cakephp/cakephp-codesniffer": "Easily check code formatting against the CakePHP coding standards."
|
||||
|
|
|
@ -134,7 +134,7 @@ class ShellDispatcher {
|
|||
if (!defined('TMP') && !is_dir(APP . 'tmp')) {
|
||||
define('TMP', CAKE_CORE_INCLUDE_PATH . DS . 'Cake' . DS . 'Console' . DS . 'Templates' . DS . 'skel' . DS . 'tmp' . DS);
|
||||
}
|
||||
$boot = file_exists(ROOT . DS . APP_DIR . DS . 'Config' . DS . 'bootstrap.php');
|
||||
|
||||
require CORE_PATH . 'Cake' . DS . 'bootstrap.php';
|
||||
|
||||
if (!file_exists(APP . 'Config' . DS . 'core.php')) {
|
||||
|
|
|
@ -403,8 +403,14 @@ class CakeSchema extends CakeObject {
|
|||
* @param string $table Table name you want returned.
|
||||
* @param array $fields Array of field information to generate the table with.
|
||||
* @return string Variable declaration for a schema class.
|
||||
* @throws Exception
|
||||
*/
|
||||
public function generateTable($table, $fields) {
|
||||
// Valid var name regex (http://www.php.net/manual/en/language.variables.basics.php)
|
||||
if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $table)) {
|
||||
throw new Exception("Invalid table name '{$table}'");
|
||||
}
|
||||
|
||||
$out = "\tpublic \${$table} = array(\n";
|
||||
if (is_array($fields)) {
|
||||
$cols = array();
|
||||
|
|
|
@ -230,9 +230,12 @@ class CakeSession {
|
|||
* @return bool True if variable is there
|
||||
*/
|
||||
public static function check($name) {
|
||||
if (empty($name) || !static::_hasSession() || !static::start()) {
|
||||
if (!static::_hasSession() || !static::start()) {
|
||||
return false;
|
||||
}
|
||||
if (isset($_SESSION[$name])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Hash::get($_SESSION, $name) !== null;
|
||||
}
|
||||
|
@ -380,9 +383,6 @@ class CakeSession {
|
|||
* session not started, or provided name not found in the session, false on failure.
|
||||
*/
|
||||
public static function read($name = null) {
|
||||
if (empty($name) && $name !== null) {
|
||||
return null;
|
||||
}
|
||||
if (!static::_hasSession() || !static::start()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -418,7 +418,7 @@ class CakeSession {
|
|||
* @return bool True if the write was successful, false if the write failed
|
||||
*/
|
||||
public static function write($name, $value = null) {
|
||||
if (empty($name) || !static::start()) {
|
||||
if (!static::start()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -849,4 +849,57 @@ class Mysql extends DboSource {
|
|||
return strpos(strtolower($real), 'unsigned') !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts multiple values into a table. Uses a single query in order to insert
|
||||
* multiple rows.
|
||||
*
|
||||
* @param string $table The table being inserted into.
|
||||
* @param array $fields The array of field/column names being inserted.
|
||||
* @param array $values The array of values to insert. The values should
|
||||
* be an array of rows. Each row should have values keyed by the column name.
|
||||
* Each row must have the values in the same order as $fields.
|
||||
* @return bool
|
||||
*/
|
||||
public function insertMulti($table, $fields, $values) {
|
||||
$table = $this->fullTableName($table);
|
||||
$holder = implode(', ', array_fill(0, count($fields), '?'));
|
||||
$fields = implode(', ', array_map(array($this, 'name'), $fields));
|
||||
$pdoMap = array(
|
||||
'integer' => PDO::PARAM_INT,
|
||||
'float' => PDO::PARAM_STR,
|
||||
'boolean' => PDO::PARAM_BOOL,
|
||||
'string' => PDO::PARAM_STR,
|
||||
'text' => PDO::PARAM_STR
|
||||
);
|
||||
$columnMap = array();
|
||||
$rowHolder = "({$holder})";
|
||||
$sql = "INSERT INTO {$table} ({$fields}) VALUES ";
|
||||
$countRows = count($values);
|
||||
for ($i = 0; $i < $countRows; $i++) {
|
||||
if ($i !== 0) {
|
||||
$sql .= ',';
|
||||
}
|
||||
$sql .= " $rowHolder";
|
||||
}
|
||||
$statement = $this->_connection->prepare($sql);
|
||||
foreach ($values[key($values)] as $key => $val) {
|
||||
$type = $this->introspectType($val);
|
||||
$columnMap[$key] = $pdoMap[$type];
|
||||
}
|
||||
$valuesList = array();
|
||||
$i = 1;
|
||||
foreach ($values as $value) {
|
||||
foreach ($value as $col => $val) {
|
||||
$valuesList[] = $val;
|
||||
$statement->bindValue($i, $val, $columnMap[$col]);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
$result = $statement->execute();
|
||||
$statement->closeCursor();
|
||||
if ($this->fullDebug) {
|
||||
$this->logQuery($sql, $valuesList);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -727,19 +727,14 @@ class Postgres extends DboSource {
|
|||
* @return int An integer representing the length of the column
|
||||
*/
|
||||
public function length($real) {
|
||||
$col = str_replace(array(')', 'unsigned'), '', $real);
|
||||
$limit = null;
|
||||
|
||||
if (strpos($col, '(') !== false) {
|
||||
list($col, $limit) = explode('(', $col);
|
||||
$col = $real;
|
||||
if (strpos($real, '(') !== false) {
|
||||
list($col, $limit) = explode('(', $real);
|
||||
}
|
||||
if ($col === 'uuid') {
|
||||
return 36;
|
||||
}
|
||||
if ($limit) {
|
||||
return (int)$limit;
|
||||
}
|
||||
return null;
|
||||
return parent::length($real);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3097,54 +3097,45 @@ class DboSource extends DataSource {
|
|||
* @return mixed An integer or string representing the length of the column, or null for unknown length.
|
||||
*/
|
||||
public function length($real) {
|
||||
if (!preg_match_all('/([\w\s]+)(?:\((\d+)(?:,(\d+))?\))?(\sunsigned)?(\szerofill)?/', $real, $result)) {
|
||||
$col = str_replace(array(')', 'unsigned'), '', $real);
|
||||
$limit = null;
|
||||
|
||||
if (strpos($col, '(') !== false) {
|
||||
list($col, $limit) = explode('(', $col);
|
||||
}
|
||||
if ($limit !== null) {
|
||||
return (int)$limit;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
preg_match('/([\w\s]+)(?:\((.+?)\))?(\sunsigned)?/i', $real, $result);
|
||||
$types = array(
|
||||
'int' => 1, 'tinyint' => 1, 'smallint' => 1, 'mediumint' => 1, 'integer' => 1, 'bigint' => 1
|
||||
);
|
||||
|
||||
list($real, $type, $length, $offset, $sign) = $result;
|
||||
$typeArr = $type;
|
||||
$type = $type[0];
|
||||
$length = $length[0];
|
||||
$offset = $offset[0];
|
||||
$type = $length = null;
|
||||
if (isset($result[1])) {
|
||||
$type = $result[1];
|
||||
}
|
||||
if (isset($result[2])) {
|
||||
$length = $result[2];
|
||||
}
|
||||
$sign = isset($result[3]);
|
||||
|
||||
$isFloat = in_array($type, array('dec', 'decimal', 'float', 'numeric', 'double'));
|
||||
if ($isFloat && $offset) {
|
||||
return $length . ',' . $offset;
|
||||
if ($isFloat && strpos($length, ',') !== false) {
|
||||
return $length;
|
||||
}
|
||||
|
||||
if (($real[0] == $type) && (count($real) === 1)) {
|
||||
if ($length === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset($types[$type])) {
|
||||
$length += $types[$type];
|
||||
if (!empty($sign)) {
|
||||
$length--;
|
||||
}
|
||||
} elseif (in_array($type, array('enum', 'set'))) {
|
||||
$length = 0;
|
||||
foreach ($typeArr as $key => $enumValue) {
|
||||
if ($key === 0) {
|
||||
continue;
|
||||
}
|
||||
return (int)$length;
|
||||
}
|
||||
if (in_array($type, array('enum', 'set'))) {
|
||||
$values = array_map(function ($value) {
|
||||
return trim(trim($value), '\'"');
|
||||
}, explode(',', $length));
|
||||
|
||||
$maxLength = 0;
|
||||
foreach ($values as $key => $enumValue) {
|
||||
$tmpLength = strlen($enumValue);
|
||||
if ($tmpLength > $length) {
|
||||
$length = $tmpLength;
|
||||
if ($tmpLength > $maxLength) {
|
||||
$maxLength = $tmpLength;
|
||||
}
|
||||
}
|
||||
return $maxLength;
|
||||
}
|
||||
return (int)$length;
|
||||
}
|
||||
|
|
|
@ -473,9 +473,16 @@ class Model extends CakeObject implements CakeEventListener {
|
|||
|
||||
/**
|
||||
* List of behaviors to load when the model object is initialized. Settings can be
|
||||
* passed to behaviors by using the behavior name as index. Eg:
|
||||
* passed to behaviors by using the behavior name as index.
|
||||
*
|
||||
* public $actsAs = array('Translate', 'MyBehavior' => array('setting1' => 'value1'))
|
||||
* For example:
|
||||
*
|
||||
* ```
|
||||
* public $actsAs = array(
|
||||
* 'Translate',
|
||||
* 'MyBehavior' => array('setting1' => 'value1')
|
||||
* );
|
||||
* ```
|
||||
*
|
||||
* @var array
|
||||
* @link http://book.cakephp.org/2.0/en/models/behaviors.html#using-behaviors
|
||||
|
@ -3446,12 +3453,19 @@ class Model extends CakeObject implements CakeEventListener {
|
|||
* - 3rd param: If 2nd argument is provided, a boolean flag for enabling/disabled
|
||||
* query caching.
|
||||
*
|
||||
* If the query cache param as 2nd or 3rd argument is not given then the model's
|
||||
* default `$cacheQueries` value is used.
|
||||
*
|
||||
* @param string $sql SQL statement
|
||||
* @return mixed Resultset array or boolean indicating success / failure depending on the query executed
|
||||
* @link http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-query
|
||||
*/
|
||||
public function query($sql) {
|
||||
$params = func_get_args();
|
||||
// use $this->cacheQueries as default when argument not explicitly given already
|
||||
if (count($params) === 1 || count($params) === 2 && !is_bool($params[1])) {
|
||||
$params[] = $this->cacheQueries;
|
||||
}
|
||||
$db = $this->getDataSource();
|
||||
return call_user_func_array(array(&$db, 'query'), $params);
|
||||
}
|
||||
|
|
|
@ -523,6 +523,7 @@ class Router {
|
|||
* - 'id' - The regular expression fragment to use when matching IDs. By default, matches
|
||||
* integer values and UUIDs.
|
||||
* - 'prefix' - URL prefix to use for the generated routes. Defaults to '/'.
|
||||
* - 'connectOptions' – Custom options for connecting the routes.
|
||||
*
|
||||
* @param string|array $controller A controller name or array of controller names (i.e. "Posts" or "ListItems")
|
||||
* @param array $options Options to use when generating REST routes
|
||||
|
|
|
@ -686,6 +686,22 @@ class CakeSchemaTest extends CakeTestCase {
|
|||
$this->assertRegExp('/\'type\' \=\> \'fulltext\'/', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test that tables with unsupported name are not getting through
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGenerateInvalidTable() {
|
||||
$invalidTableName = 'invalid name !@#$%^&*()';
|
||||
$expectedException = "Invalid table name '{$invalidTableName}'";
|
||||
try{
|
||||
$this->Schema->generateTable($invalidTableName, array());
|
||||
$this->fail("Expected exception \"{$expectedException}\" not thrown");
|
||||
} catch (Exception $e) {
|
||||
$this->assertEquals($expectedException, $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* testSchemaWrite method
|
||||
*
|
||||
|
|
|
@ -307,9 +307,9 @@ class CakeSessionTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testWriteEmptyKey() {
|
||||
$this->assertFalse(TestCakeSession::write('', 'graham'));
|
||||
$this->assertFalse(TestCakeSession::write('', ''));
|
||||
$this->assertFalse(TestCakeSession::write(''));
|
||||
$this->assertTrue(TestCakeSession::write('', 'graham'));
|
||||
$this->assertTrue(TestCakeSession::write('', ''));
|
||||
$this->assertTrue(TestCakeSession::write(''));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,6 +403,17 @@ class CakeSessionTest extends CakeTestCase {
|
|||
$this->assertFalse(TestCakeSession::check('Clearing'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDeleteEmptyString() {
|
||||
TestCakeSession::write('', 'empty string');
|
||||
$this->assertTrue(TestCakeSession::delete(''));
|
||||
$this->assertFalse(TestCakeSession::check(''));
|
||||
}
|
||||
|
||||
/**
|
||||
* testClear method
|
||||
*
|
||||
|
@ -500,6 +511,10 @@ class CakeSessionTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testReadingSavedEmpty() {
|
||||
TestCakeSession::write('', 'empty string');
|
||||
$this->assertTrue(TestCakeSession::check(''));
|
||||
$this->assertEquals('empty string', TestCakeSession::read(''));
|
||||
|
||||
TestCakeSession::write('SessionTestCase', 0);
|
||||
$this->assertEquals(0, TestCakeSession::read('SessionTestCase'));
|
||||
|
||||
|
@ -511,7 +526,7 @@ class CakeSessionTest extends CakeTestCase {
|
|||
$this->assertFalse(TestCakeSession::read('SessionTestCase'));
|
||||
|
||||
TestCakeSession::write('SessionTestCase', null);
|
||||
$this->assertEquals(null, TestCakeSession::read('SessionTestCase'));
|
||||
$this->assertNull(TestCakeSession::read('SessionTestCase'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4174,4 +4174,60 @@ SQL;
|
|||
$this->assertTrue($this->Dbo->isConnected(), 'Should be connected.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test insertMulti with id position.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testInsertMultiId() {
|
||||
$this->loadFixtures('Article');
|
||||
$Article = ClassRegistry::init('Article');
|
||||
$db = $Article->getDatasource();
|
||||
$datetime = date('Y-m-d H:i:s');
|
||||
$data = array(
|
||||
array(
|
||||
'user_id' => 1,
|
||||
'title' => 'test',
|
||||
'body' => 'test',
|
||||
'published' => 'N',
|
||||
'created' => $datetime,
|
||||
'updated' => $datetime,
|
||||
'id' => 100,
|
||||
),
|
||||
array(
|
||||
'user_id' => 1,
|
||||
'title' => 'test 101',
|
||||
'body' => 'test 101',
|
||||
'published' => 'N',
|
||||
'created' => $datetime,
|
||||
'updated' => $datetime,
|
||||
'id' => 101,
|
||||
)
|
||||
);
|
||||
$result = $db->insertMulti('articles', array_keys($data[0]), $data);
|
||||
$this->assertTrue($result, 'Data was saved');
|
||||
|
||||
$data = array(
|
||||
array(
|
||||
'id' => 102,
|
||||
'user_id' => 1,
|
||||
'title' => 'test',
|
||||
'body' => 'test',
|
||||
'published' => 'N',
|
||||
'created' => $datetime,
|
||||
'updated' => $datetime,
|
||||
),
|
||||
array(
|
||||
'id' => 103,
|
||||
'user_id' => 1,
|
||||
'title' => 'test 101',
|
||||
'body' => 'test 101',
|
||||
'published' => 'N',
|
||||
'created' => $datetime,
|
||||
'updated' => $datetime,
|
||||
)
|
||||
);
|
||||
$result = $db->insertMulti('articles', array_keys($data[0]), $data);
|
||||
$this->assertTrue($result, 'Data was saved');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1826,4 +1826,35 @@ class DboSourceTest extends CakeTestCase {
|
|||
$this->db->flushQueryCache();
|
||||
$this->assertAttributeCount(0, '_queryCache', $this->db);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test length parsing.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLength() {
|
||||
$result = $this->db->length('varchar(255)');
|
||||
$this->assertEquals(255, $result);
|
||||
|
||||
$result = $this->db->length('integer(11)');
|
||||
$this->assertEquals(11, $result);
|
||||
|
||||
$result = $this->db->length('integer unsigned');
|
||||
$this->assertNull($result);
|
||||
|
||||
$result = $this->db->length('integer(11) unsigned');
|
||||
$this->assertEquals(11, $result);
|
||||
|
||||
$result = $this->db->length('integer(11) zerofill');
|
||||
$this->assertEquals(11, $result);
|
||||
|
||||
$result = $this->db->length('decimal(20,3)');
|
||||
$this->assertEquals('20,3', $result);
|
||||
|
||||
$result = $this->db->length('enum("one", "longer")');
|
||||
$this->assertEquals(6, $result);
|
||||
|
||||
$result = $this->db->length("enum('One Value','ANOTHER ... VALUE ...')");
|
||||
$this->assertEquals(21, $result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -403,7 +403,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
$query .= '.id = ? AND ' . $this->db->fullTableName('articles') . '.published = ?';
|
||||
|
||||
$params = array(1, 'Y');
|
||||
$result = $Article->query($query, $params);
|
||||
$result = $Article->query($query, $params, true);
|
||||
$expected = array(
|
||||
'0' => array(
|
||||
$this->db->fullTableName('articles', false, false) => array(
|
||||
|
@ -438,7 +438,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
$query .= ' WHERE ' . $this->db->fullTableName('articles') . '.title LIKE ?';
|
||||
|
||||
$params = array('%First%');
|
||||
$result = $Article->query($query, $params);
|
||||
$result = $Article->query($query, $params, true);
|
||||
$this->assertTrue(is_array($result));
|
||||
$this->assertTrue(
|
||||
isset($result[0][$this->db->fullTableName('articles', false, false)]['title']) ||
|
||||
|
@ -449,7 +449,7 @@ class ModelReadTest extends BaseModelTest {
|
|||
$query = 'SELECT title FROM ';
|
||||
$query .= $this->db->fullTableName('articles') . ' WHERE title = ? AND published = ?';
|
||||
$params = array('First? Article', 'Y');
|
||||
$Article->query($query, $params);
|
||||
$Article->query($query, $params, true);
|
||||
|
||||
$result = $this->db->getQueryCache($query, $params);
|
||||
$this->assertFalse($result === false);
|
||||
|
@ -8531,4 +8531,118 @@ class ModelReadTest extends BaseModelTest {
|
|||
);
|
||||
$this->assertEquals($expected, $results, 'Model related with belongsTo afterFind callback fails');
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull out the username from a result set.
|
||||
*
|
||||
* @param array $result The results.
|
||||
* @return string The username.
|
||||
*/
|
||||
public static function extractUserNameFromQueryResult(array $result) {
|
||||
return isset($result[0][0]) ? $result[0][0]['user'] : $result[0]['u']['user'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that query() doesn't override the 2nd argument with a default.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQueryRespectsCacheQueriesAsSecondArgument() {
|
||||
$model = new User();
|
||||
$model->save(array('user' => 'Chuck'));
|
||||
$userTableName = $this->db->fullTableName('users');
|
||||
|
||||
$getUserNameFromDb = function ($cacheArgument) use ($model, $userTableName) {
|
||||
$query = sprintf('SELECT u.user FROM %s u WHERE id=%d', $userTableName, $model->id);
|
||||
$users = $model->query($query, $cacheArgument);
|
||||
return ModelReadTest::extractUserNameFromQueryResult($users);
|
||||
};
|
||||
|
||||
$model->cacheQueries = true;
|
||||
$this->assertSame('Chuck', $getUserNameFromDb(true));
|
||||
$this->assertSame('Chuck', $getUserNameFromDb(false));
|
||||
|
||||
$model->updateAll(array('User.user' => "'Sylvester'"), array('User.id' => $model->id));
|
||||
$model->cacheQueries = false;
|
||||
$this->assertSame('Chuck', $getUserNameFromDb(true));
|
||||
$this->assertSame('Sylvester', $getUserNameFromDb(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that query() doesn't override the cache param in the 3nd argument
|
||||
* with a default.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQueryRespectsCacheQueriesAsThirdArgument() {
|
||||
$model = new User();
|
||||
$model->save(array('user' => 'Chuck'));
|
||||
$userTableName = $this->db->fullTableName('users');
|
||||
|
||||
$getUserNameFromDb = function ($cacheArgument) use ($model, $userTableName) {
|
||||
$query = sprintf('SELECT u.user FROM %s u WHERE id=?', $userTableName);
|
||||
$users = $model->query($query, array($model->id), $cacheArgument);
|
||||
return ModelReadTest::extractUserNameFromQueryResult($users);
|
||||
};
|
||||
|
||||
$model->cacheQueries = true;
|
||||
$this->assertSame('Chuck', $getUserNameFromDb(true));
|
||||
$this->assertSame('Chuck', $getUserNameFromDb(false));
|
||||
|
||||
$model->updateAll(array('User.user' => "'Sylvester'"), array('User.id' => $model->id));
|
||||
$model->cacheQueries = false;
|
||||
$this->assertSame('Chuck', $getUserNameFromDb(true));
|
||||
$this->assertSame('Sylvester', $getUserNameFromDb(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that query() uses the cacheQueries property when there is one argument.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQueryTakesModelCacheQueriesValueAsDefaultForOneArgument() {
|
||||
$model = new User();
|
||||
$model->save(array('user' => 'Chuck'));
|
||||
$userTableName = $this->db->fullTableName('users');
|
||||
|
||||
$getUserNameFromDb = function () use ($model, $userTableName) {
|
||||
$query = sprintf('SELECT u.user FROM %s u WHERE id=%d', $userTableName, $model->id);
|
||||
$users = $model->query($query);
|
||||
return ModelReadTest::extractUserNameFromQueryResult($users);
|
||||
};
|
||||
|
||||
$model->cacheQueries = true;
|
||||
$this->assertSame('Chuck', $getUserNameFromDb());
|
||||
$model->updateAll(array('User.user' => "'Sylvester'"), array('User.id' => $model->id));
|
||||
|
||||
$this->assertSame('Chuck', $getUserNameFromDb());
|
||||
$model->cacheQueries = false;
|
||||
$this->assertSame('Sylvester', $getUserNameFromDb());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that query() uses the cacheQueries property when there are two arguments.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testQueryTakesModelCacheQueriesValueAsDefaultForTwoArguments() {
|
||||
$model = new User();
|
||||
$model->save(array('user' => 'Chuck'));
|
||||
$userTableName = $this->db->fullTableName('users');
|
||||
|
||||
$getUserNameFromDb = function () use ($model, $userTableName) {
|
||||
$query = sprintf('SELECT u.user FROM %s u WHERE id=?', $userTableName);
|
||||
$users = $model->query($query, array($model->id));
|
||||
return ModelReadTest::extractUserNameFromQueryResult($users);
|
||||
};
|
||||
|
||||
$model->cacheQueries = true;
|
||||
$this->assertSame('Chuck', $getUserNameFromDb());
|
||||
|
||||
$model->updateAll(array('User.user' => "'Sylvester'"), array('User.id' => $model->id));
|
||||
$this->assertSame('Chuck', $getUserNameFromDb());
|
||||
|
||||
$model->cacheQueries = false;
|
||||
$this->assertSame('Sylvester', $getUserNameFromDb());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,23 @@ class SecondaryPost extends Model {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* ConstructorPost test stub.
|
||||
*/
|
||||
class ConstructorPost extends Model {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $useTable = 'posts';
|
||||
|
||||
public function __construct($id = false, $table = null, $ds = null) {
|
||||
parent::__construct($id, $table, $ds);
|
||||
$this->getDataSource()->cacheMethods = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* CakeTestCaseTest
|
||||
*
|
||||
|
@ -435,6 +452,16 @@ class CakeTestCaseTest extends CakeTestCase {
|
|||
ConnectionManager::drop('test_secondary');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getMockForModel when the model accesses the datasource in the constructor.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMockForModelConstructorDatasource() {
|
||||
$post = $this->getMockForModel('ConstructorPost', array('save'), array('ds' => 'test'));
|
||||
$this->assertEquals('test', $post->useDbConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* test getMockForModel() with plugin models
|
||||
*
|
||||
|
|
|
@ -229,6 +229,19 @@ class HashTest extends CakeTestCase {
|
|||
$this->assertEquals($data[1]['Article'], $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that get() can extract '' key data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetEmptyKey() {
|
||||
$data = array(
|
||||
'' => 'some value'
|
||||
);
|
||||
$result = Hash::get($data, '');
|
||||
$this->assertSame($data[''], $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get() with an invalid path
|
||||
*
|
||||
|
|
|
@ -541,6 +541,7 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->Form->request['action'] = 'add';
|
||||
$this->Form->request->webroot = '';
|
||||
$this->Form->request->base = '';
|
||||
Router::setRequestInfo($this->Form->request);
|
||||
|
||||
ClassRegistry::addObject('Contact', new Contact());
|
||||
ClassRegistry::addObject('ContactNonStandardPk', new ContactNonStandardPk());
|
||||
|
@ -8569,12 +8570,14 @@ class FormHelperTest extends CakeTestCase {
|
|||
*/
|
||||
public function testPostLinkSecurityHashInline() {
|
||||
$hash = Security::hash(
|
||||
'/posts/delete/1' .
|
||||
'/basedir/posts/delete/1' .
|
||||
serialize(array()) .
|
||||
'' .
|
||||
Configure::read('Security.salt')
|
||||
);
|
||||
$hash .= '%3A';
|
||||
$this->Form->request->base = '/basedir';
|
||||
$this->Form->request->webroot = '/basedir/';
|
||||
$this->Form->request->params['_Token']['key'] = 'test';
|
||||
|
||||
$this->Form->create('Post', array('url' => array('action' => 'add')));
|
||||
|
@ -8584,7 +8587,11 @@ class FormHelperTest extends CakeTestCase {
|
|||
|
||||
$this->assertEquals(array('Post.title'), $this->Form->fields);
|
||||
$this->assertContains($hash, $result, 'Should contain the correct hash.');
|
||||
$this->assertAttributeEquals('/posts/add', '_lastAction', $this->Form, 'lastAction was should be restored.');
|
||||
$this->assertAttributeEquals(
|
||||
'/basedir/posts/add',
|
||||
'_lastAction',
|
||||
$this->Form,
|
||||
'lastAction was should be restored.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10990,4 +10997,36 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests `_lastAction`.
|
||||
*
|
||||
* With named, numeric value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLastActionWithNamedNumeric() {
|
||||
$here = '/users/index/page:1';
|
||||
|
||||
$this->Form->request->here = $here;
|
||||
$this->Form->create('User');
|
||||
|
||||
$this->assertAttributeEquals($here, '_lastAction', $this->Form, "_lastAction shouldn't be empty.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests `_lastAction`.
|
||||
*
|
||||
* With named, string value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testLastActionWithNamedString() {
|
||||
$here = '/users/index/foo:bar';
|
||||
|
||||
$this->Form->request->here = $here;
|
||||
$this->Form->create('User');
|
||||
|
||||
$this->assertAttributeEquals($here, '_lastAction', $this->Form, "_lastAction shouldn't be empty.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -718,13 +718,13 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
|||
* @return Model
|
||||
*/
|
||||
public function getMockForModel($model, $methods = array(), $config = array()) {
|
||||
$config += ClassRegistry::config('Model');
|
||||
$defaults = ClassRegistry::config('Model');
|
||||
unset($defaults['ds']);
|
||||
|
||||
list($plugin, $name) = pluginSplit($model, true);
|
||||
App::uses($name, $plugin . 'Model');
|
||||
|
||||
$config = array_merge((array)$config, array('name' => $name));
|
||||
unset($config['ds']);
|
||||
$config = array_merge($defaults, (array)$config, array('name' => $name));
|
||||
|
||||
if (!class_exists($name)) {
|
||||
throw new MissingModelException(array($model));
|
||||
|
|
|
@ -218,7 +218,7 @@ class CakeFixtureManager {
|
|||
if (empty($test->fixtures)) {
|
||||
return;
|
||||
}
|
||||
$fixtures = array_unique($test->fixtures);
|
||||
$fixtures = $test->fixtures;
|
||||
if (empty($fixtures) || !$test->autoFixtures) {
|
||||
return;
|
||||
}
|
||||
|
@ -229,9 +229,7 @@ class CakeFixtureManager {
|
|||
$db = ConnectionManager::getDataSource($fixture->useDbConfig);
|
||||
$db->begin();
|
||||
$this->_setupTable($fixture, $db, $test->dropTables);
|
||||
if (!$test->dropTables) {
|
||||
$fixture->truncate($db);
|
||||
}
|
||||
$fixture->truncate($db);
|
||||
$fixture->insert($db);
|
||||
$db->commit();
|
||||
}
|
||||
|
@ -276,9 +274,7 @@ class CakeFixtureManager {
|
|||
$db = ConnectionManager::getDataSource($fixture->useDbConfig);
|
||||
}
|
||||
$this->_setupTable($fixture, $db, $dropTables);
|
||||
if (!$dropTables) {
|
||||
$fixture->truncate($db);
|
||||
}
|
||||
$fixture->truncate($db);
|
||||
$fixture->insert($db);
|
||||
} else {
|
||||
throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
|
||||
|
|
|
@ -43,7 +43,7 @@ class Hash {
|
|||
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::get
|
||||
*/
|
||||
public static function get(array $data, $path, $default = null) {
|
||||
if (empty($data) || $path === '' || $path === null) {
|
||||
if (empty($data) || $path === null) {
|
||||
return $default;
|
||||
}
|
||||
if (is_string($path) || is_numeric($path)) {
|
||||
|
|
|
@ -3128,7 +3128,7 @@ class FormHelper extends AppHelper {
|
|||
* @return void
|
||||
*/
|
||||
protected function _lastAction($url) {
|
||||
$action = Router::url($url, true);
|
||||
$action = html_entity_decode($this->url($url, true), ENT_QUOTES);
|
||||
$query = parse_url($action, PHP_URL_QUERY);
|
||||
$query = $query ? '?' . $query : '';
|
||||
$this->_lastAction = parse_url($action, PHP_URL_PATH) . $query;
|
||||
|
|
|
@ -946,7 +946,7 @@ class PaginatorHelper extends AppHelper {
|
|||
unset($options['tag'], $options['before'], $options['model'], $options['separator'], $options['ellipsis'], $options['class']);
|
||||
|
||||
$out = '';
|
||||
$lower = $params['pageCount'] - $last + 1;
|
||||
$lower = $params['pageCount'] - (int)$last + 1;
|
||||
|
||||
if ((is_int($last) || ctype_digit($last)) && $params['page'] <= $lower) {
|
||||
if ($before === null) {
|
||||
|
|
|
@ -146,6 +146,7 @@ App::uses('Configure', 'Core');
|
|||
App::uses('CakePlugin', 'Core');
|
||||
App::uses('Cache', 'Cache');
|
||||
App::uses('CakeObject', 'Core');
|
||||
App::uses('Object', 'Core');
|
||||
App::uses('Multibyte', 'I18n');
|
||||
|
||||
App::$bootstrapping = true;
|
||||
|
|
Loading…
Reference in a new issue