Merge branch '2.x' into 2.next

This commit is contained in:
mark_story 2016-10-28 00:29:46 -04:00
commit 135a24e0f1
25 changed files with 444 additions and 87 deletions

3
.gitignore vendored
View file

@ -14,6 +14,9 @@
#################################
/nbproject
.idea
/.project
/.buildpath
/.settings/
# OS generated files #
######################

View file

@ -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>

View file

@ -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."

View file

@ -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')) {

View file

@ -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();

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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);
}
/**

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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
*

View file

@ -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'));
}
/**

View file

@ -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');
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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
*

View file

@ -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
*

View file

@ -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.");
}
}

View file

@ -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));

View file

@ -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));

View file

@ -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)) {

View file

@ -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;

View file

@ -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) {

View file

@ -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;