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
12c6fd4e22
21 changed files with 1580 additions and 1266 deletions
|
@ -1,5 +1,8 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
# Uncomment if you have a .well-known directory in the root folder, e.g. for the Let's Encrypt challenge
|
||||
# https://tools.ietf.org/html/rfc5785
|
||||
#RewriteRule ^(\.well-known/.*)$ $1 [L]
|
||||
RewriteRule ^$ app/webroot/ [L]
|
||||
RewriteRule (.*) app/webroot/$1 [L]
|
||||
</IfModule>
|
|
@ -1,5 +1,8 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
# Uncomment if you have a .well-known directory in the app folder, e.g. for the Let's Encrypt challenge
|
||||
# https://tools.ietf.org/html/rfc5785
|
||||
#RewriteRule ^(\.well-known/.*)$ $1 [L]
|
||||
RewriteRule ^$ webroot/ [L]
|
||||
RewriteRule (.*) webroot/$1 [L]
|
||||
</IfModule>
|
|
@ -132,7 +132,7 @@ class FileEngine extends CacheEngine {
|
|||
}
|
||||
|
||||
$expires = time() + $duration;
|
||||
$contents = $expires . $lineBreak . $data . $lineBreak;
|
||||
$contents = implode(array($expires, $lineBreak, $data, $lineBreak));
|
||||
|
||||
if ($this->settings['lock']) {
|
||||
$this->_File->flock(LOCK_EX);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -125,7 +125,8 @@ class FixtureTask extends BakeTask {
|
|||
return $this->all();
|
||||
}
|
||||
$model = $this->_modelName($this->args[0]);
|
||||
$this->bake($model);
|
||||
$importOptions = $this->importOptions($model);
|
||||
$this->bake($model, false, $importOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,24 +178,29 @@ class FixtureTask extends BakeTask {
|
|||
*/
|
||||
public function importOptions($modelName) {
|
||||
$options = array();
|
||||
$plugin = '';
|
||||
if (isset($this->params['plugin'])) {
|
||||
$plugin = $this->params['plugin'] . '.';
|
||||
}
|
||||
|
||||
if (!empty($this->params['schema'])) {
|
||||
$options['schema'] = $modelName;
|
||||
} else {
|
||||
$options['schema'] = $plugin . $modelName;
|
||||
} elseif ($this->interactive) {
|
||||
$doSchema = $this->in(__d('cake_console', 'Would you like to import schema for this fixture?'), array('y', 'n'), 'n');
|
||||
if ($doSchema === 'y') {
|
||||
$options['schema'] = $modelName;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->params['records'])) {
|
||||
$doRecords = 'y';
|
||||
} else {
|
||||
$options['fromTable'] = true;
|
||||
} elseif ($this->interactive) {
|
||||
$doRecords = $this->in(__d('cake_console', 'Would you like to use record importing for this fixture?'), array('y', 'n'), 'n');
|
||||
if ($doRecords === 'y') {
|
||||
$options['records'] = true;
|
||||
}
|
||||
}
|
||||
if ($doRecords === 'y') {
|
||||
$options['records'] = true;
|
||||
}
|
||||
if ($doRecords === 'n') {
|
||||
if (!isset($options['records']) && $this->interactive) {
|
||||
$prompt = __d('cake_console', "Would you like to build this fixture with data from %s's table?", $modelName);
|
||||
$fromTable = $this->in($prompt, array('y', 'n'), 'n');
|
||||
if (strtolower($fromTable) === 'y') {
|
||||
|
|
|
@ -53,14 +53,15 @@ class CakeBaseException extends RuntimeException {
|
|||
|
||||
}
|
||||
|
||||
if (!class_exists('HttpException', false)) {
|
||||
/**
|
||||
* Parent class for all of the HTTP related exceptions in CakePHP.
|
||||
*
|
||||
* All HTTP status/error related exceptions should extend this class so
|
||||
* catch blocks can be specifically typed.
|
||||
*
|
||||
* @package Cake.Error
|
||||
*/
|
||||
if (!class_exists('HttpException', false)) {
|
||||
class HttpException extends CakeBaseException {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,6 +209,7 @@ class L10n {
|
|||
'ca' => array('language' => 'Catalan', 'locale' => 'cat', 'localeFallback' => 'cat', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'cs' => array('language' => 'Czech', 'locale' => 'ces', 'localeFallback' => 'ces', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'da' => array('language' => 'Danish', 'locale' => 'dan', 'localeFallback' => 'dan', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'da-dk' => array('language' => 'Danish (Denmark)', 'locale' => 'da_dk', 'localeFallback' => 'dan', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'de' => array('language' => 'German (Standard)', 'locale' => 'deu', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'de-at' => array('language' => 'German (Austria)', 'locale' => 'de_at', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'de-ch' => array('language' => 'German (Swiss)', 'locale' => 'de_ch', 'localeFallback' => 'deu', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -248,9 +249,11 @@ class L10n {
|
|||
'es-uy' => array('language' => 'Spanish (Uruguay)', 'locale' => 'es_uy', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'es-ve' => array('language' => 'Spanish (Venezuela)', 'locale' => 'es_ve', 'localeFallback' => 'spa', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'et' => array('language' => 'Estonian', 'locale' => 'est', 'localeFallback' => 'est', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'et-ee' => array('language' => 'Estonian (Estonia)', 'locale' => 'et_ee', 'localeFallback' => 'est', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'eu' => array('language' => 'Basque', 'locale' => 'eus', 'localeFallback' => 'eus', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fa' => array('language' => 'Farsi', 'locale' => 'fas', 'localeFallback' => 'fas', 'charset' => 'utf-8', 'direction' => 'rtl'),
|
||||
'fi' => array('language' => 'Finnish', 'locale' => 'fin', 'localeFallback' => 'fin', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fi-fi' => array('language' => 'Finnish (Finland)', 'locale' => 'fi_fi', 'localeFallback' => 'fin', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fo' => array('language' => 'Faeroese', 'locale' => 'fao', 'localeFallback' => 'fao', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fr' => array('language' => 'French (Standard)', 'locale' => 'fra', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'fr-be' => array('language' => 'French (Belgium)', 'locale' => 'fr_be', 'localeFallback' => 'fra', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -274,6 +277,7 @@ class L10n {
|
|||
'ja' => array('language' => 'Japanese', 'locale' => 'jpn', 'localeFallback' => 'jpn', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'kk' => array('language' => 'Kazakh', 'locale' => 'kaz', 'localeFallback' => 'kaz', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'kl' => array('language' => 'Kalaallisut (Greenlandic)', 'locale' => 'kal', 'localeFallback' => 'kal', 'charset' => 'kl', 'direction' => 'ltr'),
|
||||
'kl-gl' => array('language' => 'Kalaallisut (Greenland)', 'locale' => 'kl_gl', 'localeFallback' => 'kal', 'charset' => 'kl', 'direction' => 'ltr'),
|
||||
'ko' => array('language' => 'Korean', 'locale' => 'kor', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||
'ko-kp' => array('language' => 'Korea (North)', 'locale' => 'ko_kp', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||
'ko-kr' => array('language' => 'Korea (South)', 'locale' => 'ko_kr', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||
|
@ -286,9 +290,12 @@ class L10n {
|
|||
'ms' => array('language' => 'Malaysian', 'locale' => 'msa', 'localeFallback' => 'msa', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'mt' => array('language' => 'Maltese', 'locale' => 'mlt', 'localeFallback' => 'mlt', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nb' => array('language' => 'Norwegian Bokmal', 'locale' => 'nob', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nb-no' => array('language' => 'Norwegian Bokmål (Norway)', 'locale' => 'nb_no', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nl' => array('language' => 'Dutch (Standard)', 'locale' => 'nld', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nl-be' => array('language' => 'Dutch (Belgium)', 'locale' => 'nl_be', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nl-nl' => array('language' => 'Dutch (Netherlands)', 'locale' => 'nl_nl', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nn' => array('language' => 'Norwegian Nynorsk', 'locale' => 'nno', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'nn-no' => array('language' => 'Norwegian Nynorsk (Norway)', 'locale' => 'nn_no', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'no' => array('language' => 'Norwegian', 'locale' => 'nor', 'localeFallback' => 'nor', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'pl' => array('language' => 'Polish', 'locale' => 'pol', 'localeFallback' => 'pol', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'pt' => array('language' => 'Portuguese (Portugal)', 'locale' => 'por', 'localeFallback' => 'por', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -296,6 +303,7 @@ class L10n {
|
|||
'rm' => array('language' => 'Rhaeto-Romanic', 'locale' => 'roh', 'localeFallback' => 'roh', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ro' => array('language' => 'Romanian', 'locale' => 'ron', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ro-mo' => array('language' => 'Romanian (Moldavia)', 'locale' => 'ro_mo', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ro-ro' => array('language' => 'Romanian (Romania)', 'locale' => 'ro_ro', 'localeFallback' => 'ron', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ru' => array('language' => 'Russian', 'locale' => 'rus', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'ru-mo' => array('language' => 'Russian (Moldavia)', 'locale' => 'ru_mo', 'localeFallback' => 'rus', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sb' => array('language' => 'Sorbian', 'locale' => 'wen', 'localeFallback' => 'wen', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
@ -304,6 +312,7 @@ class L10n {
|
|||
'sq' => array('language' => 'Albanian', 'locale' => 'sqi', 'localeFallback' => 'sqi', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sr' => array('language' => 'Serbian', 'locale' => 'srp', 'localeFallback' => 'srp', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sv' => array('language' => 'Swedish', 'locale' => 'swe', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sv-se' => array('language' => 'Swedish (Sweden)', 'locale' => 'sv_se', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'sv-fi' => array('language' => 'Swedish (Finland)', 'locale' => 'sv_fi', 'localeFallback' => 'swe', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'se' => array('language' => 'Sami', 'locale' => 'sme', 'localeFallback' => 'sme', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
'th' => array('language' => 'Thai', 'locale' => 'tha', 'localeFallback' => 'tha', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
App::uses('LogEngineCollection', 'Log');
|
||||
|
||||
/**
|
||||
* Logs messages to configured Log adapters. One or more adapters
|
||||
* can be configured using CakeLogs's methods. If you don't
|
||||
* configure any adapters, and write to the logs a default
|
||||
* FileLog will be autoconfigured for you.
|
||||
* Logs messages to configured Log adapters.
|
||||
*
|
||||
* One or more adapters
|
||||
* can be configured using CakeLogs's methods.
|
||||
*
|
||||
* ### Configuring Log adapters
|
||||
*
|
||||
|
@ -84,6 +84,9 @@ class CakeLog {
|
|||
/**
|
||||
* Default log levels as detailed in RFC 5424
|
||||
* http://tools.ietf.org/html/rfc5424
|
||||
*
|
||||
* Windows has fewer levels, thus notice, info and debug are the same.
|
||||
* https://bugs.php.net/bug.php?id=18090
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
|
|
@ -1490,34 +1490,38 @@ class DboSource extends DataSource {
|
|||
$primaryKey = $Model->primaryKey;
|
||||
$foreignKey = $Model->hasMany[$association]['foreignKey'];
|
||||
|
||||
// Make one pass through children and collect by parent key
|
||||
// Make second pass through parents and associate children
|
||||
$mergedByFK = array();
|
||||
foreach ($assocResultSet as $data) {
|
||||
$fk = $data[$association][$foreignKey];
|
||||
if (! array_key_exists($fk, $mergedByFK)) {
|
||||
$mergedByFK[$fk] = array();
|
||||
}
|
||||
if (count($data) > 1) {
|
||||
$data = array_merge($data[$association], $data);
|
||||
unset($data[$association]);
|
||||
foreach ($data as $key => $name) {
|
||||
if (is_numeric($key)) {
|
||||
$data[$association][] = $name;
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
$mergedByFK[$fk][] = $data;
|
||||
} else {
|
||||
$mergedByFK[$fk][] = $data[$association];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($resultSet as &$result) {
|
||||
if (!isset($result[$modelAlias])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resultPrimaryKey = $result[$modelAlias][$primaryKey];
|
||||
|
||||
$merged = array();
|
||||
foreach ($assocResultSet as $data) {
|
||||
if ($resultPrimaryKey !== $data[$association][$foreignKey]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count($data) > 1) {
|
||||
$data = array_merge($data[$association], $data);
|
||||
unset($data[$association]);
|
||||
foreach ($data as $key => $name) {
|
||||
if (is_numeric($key)) {
|
||||
$data[$association][] = $name;
|
||||
unset($data[$key]);
|
||||
}
|
||||
}
|
||||
$merged[] = $data;
|
||||
} else {
|
||||
$merged[] = $data[$association];
|
||||
}
|
||||
$pk = $result[$modelAlias][$primaryKey];
|
||||
if (isset($mergedByFK[$pk])) {
|
||||
$merged = $mergedByFK[$pk];
|
||||
}
|
||||
|
||||
$result = Hash::mergeDiff($result, array($association => $merged));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1201,9 +1201,6 @@ class CakeResponse {
|
|||
* If the method is called with an array as argument, it will set the cookie
|
||||
* configuration to the cookie container.
|
||||
*
|
||||
* @param array $options Either null to get all cookies, string for a specific cookie
|
||||
* or array to set cookie.
|
||||
*
|
||||
* ### Options (when setting a configuration)
|
||||
* - name: The Cookie name
|
||||
* - value: Value of the cookie
|
||||
|
@ -1227,6 +1224,8 @@ class CakeResponse {
|
|||
*
|
||||
* `$this->cookie((array) $options)`
|
||||
*
|
||||
* @param array $options Either null to get all cookies, string for a specific cookie
|
||||
* or array to set cookie.
|
||||
* @return mixed
|
||||
*/
|
||||
public function cookie($options = null) {
|
||||
|
@ -1417,11 +1416,16 @@ class CakeResponse {
|
|||
* @return void
|
||||
*/
|
||||
protected function _fileRange($file, $httpRange) {
|
||||
list(, $range) = explode('=', $httpRange);
|
||||
list($start, $end) = explode('-', $range);
|
||||
|
||||
$fileSize = $file->size();
|
||||
$lastByte = $fileSize - 1;
|
||||
$start = 0;
|
||||
$end = $lastByte;
|
||||
|
||||
preg_match('/^bytes\s*=\s*(\d+)?\s*-\s*(\d+)?$/', $httpRange, $matches);
|
||||
if ($matches) {
|
||||
$start = $matches[1];
|
||||
$end = isset($matches[2]) ? $matches[2] : '';
|
||||
}
|
||||
|
||||
if ($start === '') {
|
||||
$start = $fileSize - $end;
|
||||
|
|
|
@ -98,6 +98,7 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testImportOptionsSchemaRecords() {
|
||||
$this->Task->interactive = true;
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('y'));
|
||||
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue('y'));
|
||||
|
||||
|
@ -112,6 +113,7 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testImportOptionsNothing() {
|
||||
$this->Task->interactive = true;
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
|
||||
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue('n'));
|
||||
$this->Task->expects($this->at(2))->method('in')->will($this->returnValue('n'));
|
||||
|
@ -130,7 +132,20 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
$this->Task->params = array('schema' => true, 'records' => true);
|
||||
|
||||
$result = $this->Task->importOptions('Article');
|
||||
$expected = array('schema' => 'Article', 'records' => true);
|
||||
$expected = array('schema' => 'Article', 'fromTable' => true);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test importOptions with overwriting CLI options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testImportOptionsWithCommandLineOptionsPlugin() {
|
||||
$this->Task->params = array('schema' => true, 'records' => true, 'plugin' => 'TestPlugin');
|
||||
|
||||
$result = $this->Task->importOptions('Article');
|
||||
$expected = array('schema' => 'TestPlugin.Article', 'fromTable' => true);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
|
@ -140,6 +155,7 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testImportOptionsWithSchema() {
|
||||
$this->Task->interactive = true;
|
||||
$this->Task->params = array('schema' => true);
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
|
||||
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue('n'));
|
||||
|
@ -155,11 +171,12 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testImportOptionsWithRecords() {
|
||||
$this->Task->interactive = true;
|
||||
$this->Task->params = array('records' => true);
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
|
||||
|
||||
$result = $this->Task->importOptions('Article');
|
||||
$expected = array('records' => true);
|
||||
$expected = array('fromTable' => true);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
|
@ -169,6 +186,7 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testImportOptionsTable() {
|
||||
$this->Task->interactive = true;
|
||||
$this->Task->expects($this->at(0))->method('in')->will($this->returnValue('n'));
|
||||
$this->Task->expects($this->at(1))->method('in')->will($this->returnValue('n'));
|
||||
$this->Task->expects($this->at(2))->method('in')->will($this->returnValue('y'));
|
||||
|
@ -244,6 +262,62 @@ class FixtureTaskTest extends CakeTestCase {
|
|||
$this->assertContains("'body' => 'Body \"value\"'", $result, 'Data has bad escaping');
|
||||
}
|
||||
|
||||
/**
|
||||
* test that execute includes import options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExecuteWithImportSchema() {
|
||||
$this->Task->connection = 'test';
|
||||
$this->Task->path = '/my/path/';
|
||||
$this->Task->args = array('article');
|
||||
$this->Task->params = array(
|
||||
'schema' => true,
|
||||
'records' => false,
|
||||
);
|
||||
$filename = '/my/path/ArticleFixture.php';
|
||||
|
||||
$this->Task->expects($this->never())
|
||||
->method('in');
|
||||
|
||||
$this->Task->expects($this->at(0))
|
||||
->method('createFile')
|
||||
->with($filename, $this->logicalAnd(
|
||||
$this->stringContains('class ArticleFixture'),
|
||||
$this->stringContains("\$import = array('model' => 'Article'")
|
||||
));
|
||||
|
||||
$this->Task->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* test that execute includes import options
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testExecuteWithImportRecords() {
|
||||
$this->Task->connection = 'test';
|
||||
$this->Task->path = '/my/path/';
|
||||
$this->Task->args = array('article');
|
||||
$this->Task->params = array(
|
||||
'schema' => true,
|
||||
'records' => true,
|
||||
);
|
||||
$filename = '/my/path/ArticleFixture.php';
|
||||
|
||||
$this->Task->expects($this->never())
|
||||
->method('in');
|
||||
|
||||
$this->Task->expects($this->at(0))
|
||||
->method('createFile')
|
||||
->with($filename, $this->logicalAnd(
|
||||
$this->stringContains('class ArticleFixture'),
|
||||
$this->stringContains("\$import = array('model' => 'Article', 'connection' => 'test')")
|
||||
));
|
||||
|
||||
$this->Task->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* test that execute passes runs bake depending with named model.
|
||||
*
|
||||
|
|
|
@ -1705,48 +1705,81 @@ class CakeResponseTest extends CakeTestCase {
|
|||
$this->assertNotSame(false, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for invalid range header values.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function invalidFileRangeProvider() {
|
||||
return array(
|
||||
// malformed range
|
||||
array(
|
||||
'bytes=0,38'
|
||||
),
|
||||
|
||||
// malformed punctuation
|
||||
array(
|
||||
'bytes: 0 - 32'
|
||||
),
|
||||
array(
|
||||
'garbage: poo - poo'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test invalid file ranges.
|
||||
*
|
||||
* @dataProvider invalidFileRangeProvider
|
||||
* @return void
|
||||
*/
|
||||
public function testFileRangeInvalid() {
|
||||
$_SERVER['HTTP_RANGE'] = 'bytes=30-2';
|
||||
public function testFileRangeInvalid($range) {
|
||||
$_SERVER['HTTP_RANGE'] = $range;
|
||||
$response = $this->getMock('CakeResponse', array(
|
||||
'header',
|
||||
'type',
|
||||
'_sendHeader',
|
||||
'_setContentType',
|
||||
'_isActive',
|
||||
'_clearBuffer',
|
||||
'_flushBuffer'
|
||||
));
|
||||
|
||||
$response->expects($this->at(1))
|
||||
->method('header')
|
||||
->with('Content-Disposition', 'attachment; filename="test_asset.css"');
|
||||
|
||||
$response->expects($this->at(2))
|
||||
->method('header')
|
||||
->with('Content-Transfer-Encoding', 'binary');
|
||||
|
||||
$response->expects($this->at(3))
|
||||
->method('header')
|
||||
->with('Accept-Ranges', 'bytes');
|
||||
|
||||
$response->expects($this->at(4))
|
||||
->method('header')
|
||||
->with(array(
|
||||
'Content-Range' => 'bytes 0-37/38',
|
||||
));
|
||||
|
||||
$response->file(
|
||||
CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css',
|
||||
array('download' => true)
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'Content-Disposition' => 'attachment; filename="test_asset.css"',
|
||||
'Content-Transfer-Encoding' => 'binary',
|
||||
'Accept-Ranges' => 'bytes',
|
||||
'Content-Range' => 'bytes 0-37/38',
|
||||
'Content-Length' => 38,
|
||||
);
|
||||
$this->assertEquals($expected, $response->header());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test backwards file range
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testFileRangeReversed() {
|
||||
$_SERVER['HTTP_RANGE'] = 'bytes=30-5';
|
||||
$response = $this->getMock('CakeResponse', array(
|
||||
'_sendHeader',
|
||||
'_isActive',
|
||||
));
|
||||
|
||||
$response->file(
|
||||
CAKE . 'Test' . DS . 'test_app' . DS . 'Vendor' . DS . 'css' . DS . 'test_asset.css',
|
||||
array('download' => true)
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'Content-Disposition' => 'attachment; filename="test_asset.css"',
|
||||
'Content-Transfer-Encoding' => 'binary',
|
||||
'Accept-Ranges' => 'bytes',
|
||||
'Content-Range' => 'bytes 0-37/38',
|
||||
);
|
||||
$this->assertEquals($expected, $response->header());
|
||||
$this->assertEquals(416, $response->statusCode());
|
||||
$response->send();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1843,7 +1843,6 @@ class HttpSocketTest extends CakeTestCase {
|
|||
} catch (SocketException $e) {
|
||||
$message = $e->getMessage();
|
||||
$this->skipIf(strpos($message, 'Invalid HTTP') !== false, 'Invalid HTTP Response received, skipping.');
|
||||
$this->assertContains('Peer certificate CN', $message);
|
||||
$this->assertContains('Failed to enable crypto', $message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,16 +151,36 @@ class SecurityTest extends CakeTestCase {
|
|||
Security::setHash($_hashType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that blowfish doesn't return '' when the salt is ''
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHashBlowfishEmptySalt() {
|
||||
$test = Security::hash('password', 'blowfish');
|
||||
$this->skipIf(strpos($test, '$2a$') === false, 'Blowfish hashes are incorrect.');
|
||||
|
||||
$stored = '';
|
||||
$hash = Security::hash('anything', 'blowfish', $stored);
|
||||
$this->assertNotEquals($stored, $hash);
|
||||
|
||||
$hash = Security::hash('anything', 'blowfish', false);
|
||||
$this->assertNotEquals($stored, $hash);
|
||||
|
||||
$hash = Security::hash('anything', 'blowfish', null);
|
||||
$this->assertNotEquals($stored, $hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that hash() works with blowfish.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testHashBlowfish() {
|
||||
Security::setCost(10);
|
||||
$test = Security::hash('password', 'blowfish');
|
||||
$this->skipIf(strpos($test, '$2a$') === false, 'Blowfish hashes are incorrect.');
|
||||
|
||||
Security::setCost(10);
|
||||
$_hashType = Security::$hashType;
|
||||
|
||||
$key = 'someKey';
|
||||
|
|
|
@ -88,6 +88,25 @@ class TestDeValidation {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* ValidationStub
|
||||
*
|
||||
* @package Cake.Test.Case.Utility
|
||||
*/
|
||||
class ValidationStub extends Validation {
|
||||
|
||||
/**
|
||||
* Stub out is_uploaded_file check
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
protected static function _isUploadedFile($path) {
|
||||
return file_exists($path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Case for Validation Class
|
||||
*
|
||||
|
@ -384,6 +403,12 @@ class ValidationTest extends CakeTestCase {
|
|||
$this->assertTrue(Validation::cc('5467639122779531', array('mc')));
|
||||
$this->assertTrue(Validation::cc('5297350261550024', array('mc')));
|
||||
$this->assertTrue(Validation::cc('5162739131368058', array('mc')));
|
||||
//Mastercard (additional 2016 BIN)
|
||||
$this->assertTrue(Validation::cc('2221000000000009', array('mc')));
|
||||
$this->assertTrue(Validation::cc('2720999999999996', array('mc')));
|
||||
$this->assertTrue(Validation::cc('2223000010005798', array('mc')));
|
||||
$this->assertTrue(Validation::cc('2623430710235708', array('mc')));
|
||||
$this->assertTrue(Validation::cc('2420452519835723', array('mc')));
|
||||
//Solo 16
|
||||
$this->assertTrue(Validation::cc('6767432107064987', array('solo')));
|
||||
$this->assertTrue(Validation::cc('6334667758225411', array('solo')));
|
||||
|
@ -2142,9 +2167,6 @@ class ValidationTest extends CakeTestCase {
|
|||
$this->assertFalse(Validation::phone('1-(511)-999-9999'));
|
||||
$this->assertFalse(Validation::phone('1-(555)-999-9999'));
|
||||
|
||||
// invalid exhange
|
||||
$this->assertFalse(Validation::phone('1-(222)-511-9999'));
|
||||
|
||||
// invalid phone number
|
||||
$this->assertFalse(Validation::phone('1-(222)-555-0199'));
|
||||
$this->assertFalse(Validation::phone('1-(222)-555-0122'));
|
||||
|
@ -2167,6 +2189,7 @@ class ValidationTest extends CakeTestCase {
|
|||
$this->assertTrue(Validation::phone('1.(333).333-4444'));
|
||||
$this->assertTrue(Validation::phone('1.(333).333.4444'));
|
||||
$this->assertTrue(Validation::phone('1-333-333-4444'));
|
||||
$this->assertTrue(Validation::phone('1-800-211-4511'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2405,11 +2428,11 @@ class ValidationTest extends CakeTestCase {
|
|||
* @return void
|
||||
*/
|
||||
public function testUploadedFileErrorCode() {
|
||||
$this->assertFalse(Validation::uploadedFile('derp'));
|
||||
$this->assertFalse(ValidationStub::uploadedFile('derp'));
|
||||
$invalid = array(
|
||||
'name' => 'testing'
|
||||
);
|
||||
$this->assertFalse(Validation::uploadedFile($invalid));
|
||||
$this->assertFalse(ValidationStub::uploadedFile($invalid));
|
||||
$file = array(
|
||||
'name' => 'cake.power.gif',
|
||||
'tmp_name' => CORE_PATH . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'webroot/img/cake.power.gif',
|
||||
|
@ -2417,9 +2440,9 @@ class ValidationTest extends CakeTestCase {
|
|||
'type' => 'image/gif',
|
||||
'size' => 201
|
||||
);
|
||||
$this->assertTrue(Validation::uploadedFile($file));
|
||||
$this->assertTrue(ValidationStub::uploadedFile($file));
|
||||
$file['error'] = UPLOAD_ERR_NO_FILE;
|
||||
$this->assertFalse(Validation::uploadedFile($file), 'Error upload should fail.');
|
||||
$this->assertFalse(ValidationStub::uploadedFile($file), 'Error upload should fail.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2438,11 +2461,11 @@ class ValidationTest extends CakeTestCase {
|
|||
$options = array(
|
||||
'types' => array('text/plain')
|
||||
);
|
||||
$this->assertFalse(Validation::uploadedFile($file, $options), 'Incorrect mimetype.');
|
||||
$this->assertFalse(ValidationStub::uploadedFile($file, $options), 'Incorrect mimetype.');
|
||||
$options = array(
|
||||
'types' => array('image/gif', 'image/png')
|
||||
);
|
||||
$this->assertTrue(Validation::uploadedFile($file, $options));
|
||||
$this->assertTrue(ValidationStub::uploadedFile($file, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2461,24 +2484,24 @@ class ValidationTest extends CakeTestCase {
|
|||
$options = array(
|
||||
'minSize' => 500
|
||||
);
|
||||
$this->assertFalse(Validation::uploadedFile($file, $options), 'Too small');
|
||||
$this->assertFalse(ValidationStub::uploadedFile($file, $options), 'Too small');
|
||||
$options = array(
|
||||
'maxSize' => 100
|
||||
);
|
||||
$this->assertFalse(Validation::uploadedFile($file, $options), 'Too big');
|
||||
$this->assertFalse(ValidationStub::uploadedFile($file, $options), 'Too big');
|
||||
$options = array(
|
||||
'minSize' => 100,
|
||||
);
|
||||
$this->assertTrue(Validation::uploadedFile($file, $options));
|
||||
$this->assertTrue(ValidationStub::uploadedFile($file, $options));
|
||||
$options = array(
|
||||
'maxSize' => 500,
|
||||
);
|
||||
$this->assertTrue(Validation::uploadedFile($file, $options));
|
||||
$this->assertTrue(ValidationStub::uploadedFile($file, $options));
|
||||
$options = array(
|
||||
'minSize' => 100,
|
||||
'maxSize' => 500
|
||||
);
|
||||
$this->assertTrue(Validation::uploadedFile($file, $options));
|
||||
$this->assertTrue(ValidationStub::uploadedFile($file, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2519,6 +2542,6 @@ class ValidationTest extends CakeTestCase {
|
|||
'size' => 201
|
||||
);
|
||||
$options = array();
|
||||
$this->assertTrue(Validation::uploadedFile($file, $options), 'Wrong order');
|
||||
$this->assertTrue(ValidationStub::uploadedFile($file, $options), 'Wrong order');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4870,6 +4870,50 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* testSelect boolean method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSelectBoolean() {
|
||||
$result = $this->Form->select(
|
||||
'Model.field',
|
||||
array(0 => 'No', 1 => 'Yes'),
|
||||
array('value' => false, 'empty' => false)
|
||||
);
|
||||
$expected = array(
|
||||
'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
|
||||
array('option' => array('value' => '0', 'selected' => 'selected')),
|
||||
'No',
|
||||
'/option',
|
||||
array('option' => array('value' => '1')),
|
||||
'Yes',
|
||||
'/option',
|
||||
'/select'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
|
||||
$result = $this->Form->select(
|
||||
'Model.field',
|
||||
array(0 => 'No', 1 => 'Yes', 2 => 'Yes again'),
|
||||
array('value' => array(false, 2), 'empty' => false)
|
||||
);
|
||||
$expected = array(
|
||||
'select' => array('name' => 'data[Model][field]', 'id' => 'ModelField'),
|
||||
array('option' => array('value' => '0', 'selected' => 'selected')),
|
||||
'No',
|
||||
'/option',
|
||||
array('option' => array('value' => '1')),
|
||||
'Yes',
|
||||
'/option',
|
||||
array('option' => array('value' => '2', 'selected' => 'selected')),
|
||||
'Yes again',
|
||||
'/option',
|
||||
'/select'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* test that select() with optiongroups listens to the escape param.
|
||||
*
|
||||
|
@ -8120,6 +8164,34 @@ class FormHelperTest extends CakeTestCase {
|
|||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that postLink doesn't modify the fields in the containing form.
|
||||
*
|
||||
* postLink() calls inside open forms should not modify the field list
|
||||
* for the form.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testPostLinkSecurityHashInline() {
|
||||
$hash = Security::hash(
|
||||
'/posts/delete/1' .
|
||||
serialize(array()) .
|
||||
'' .
|
||||
Configure::read('Security.salt')
|
||||
);
|
||||
$hash .= '%3A';
|
||||
$this->Form->request->params['_Token']['key'] = 'test';
|
||||
|
||||
$this->Form->create('Post', array('url' => array('action' => 'add')));
|
||||
$this->Form->input('title');
|
||||
$this->Form->postLink('Delete', '/posts/delete/1', array('inline' => false));
|
||||
$result = $this->View->fetch('postLink');
|
||||
|
||||
$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.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test using postLink with N dimensional data.
|
||||
*
|
||||
|
@ -8674,6 +8746,36 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the action key still uses the model as the implicit controller
|
||||
* when the url option is undefined. While the action parameter is deprecated
|
||||
* we need it to continue working for the duration of 2.x
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testCreateUrlImpliedController() {
|
||||
$restore = error_reporting(E_ALL ^ E_USER_DEPRECATED);
|
||||
$this->Form->request['controller'] = 'posts';
|
||||
$result = $this->Form->create('Comment', array(
|
||||
'action' => 'addComment',
|
||||
'id' => 'addCommentForm',
|
||||
'type' => 'POST'
|
||||
));
|
||||
$expected = array(
|
||||
'form' => array(
|
||||
'action' => '/comments/addComment',
|
||||
'id' => 'addCommentForm',
|
||||
'method' => 'post',
|
||||
'accept-charset' => strtolower(Configure::read('App.encoding'))
|
||||
),
|
||||
'div' => array('style' => 'display:none;'),
|
||||
'input' => array('type' => 'hidden', 'name' => '_method', 'value' => 'POST'),
|
||||
'/div'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
error_reporting($restore);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the onsubmit option for create()
|
||||
*
|
||||
|
|
|
@ -178,6 +178,13 @@ abstract class ControllerTestCase extends CakeTestCase {
|
|||
*/
|
||||
protected $_dirtyController = false;
|
||||
|
||||
/**
|
||||
* The class name to use for mocking the response object.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_responseClass = 'CakeResponse';
|
||||
|
||||
/**
|
||||
* Used to enable calling ControllerTestCase::testAction() without the testing
|
||||
* framework thinking that it's a test case
|
||||
|
@ -276,8 +283,14 @@ abstract class ControllerTestCase extends CakeTestCase {
|
|||
$params['requested'] = 1;
|
||||
}
|
||||
$Dispatch->testController = $this->controller;
|
||||
$Dispatch->response = $this->getMock('CakeResponse', array('send', '_clearBuffer'));
|
||||
$Dispatch->response = $this->getMock($this->_responseClass, array('send', '_clearBuffer'));
|
||||
$this->result = $Dispatch->dispatch($request, $Dispatch->response, $params);
|
||||
|
||||
// Clear out any stored requests.
|
||||
while (Router::getRequest()) {
|
||||
Router::popRequest();
|
||||
}
|
||||
|
||||
$this->controller = $Dispatch->testController;
|
||||
$this->vars = $this->controller->viewVars;
|
||||
$this->contents = $this->controller->response->body();
|
||||
|
@ -339,7 +352,7 @@ abstract class ControllerTestCase extends CakeTestCase {
|
|||
$controllerObj = $this->getMock($name . 'Controller', $mocks['methods'], array(), '', false);
|
||||
$controllerObj->name = $name;
|
||||
$request = $this->getMock('CakeRequest');
|
||||
$response = $this->getMock('CakeResponse', array('_sendHeader'));
|
||||
$response = $this->getMock($this->_responseClass, array('_sendHeader'));
|
||||
$controllerObj->__construct($request, $response);
|
||||
$controllerObj->Components->setController($controllerObj);
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ class Security {
|
|||
* @return string The hashed string or an empty string on error.
|
||||
*/
|
||||
protected static function _crypt($password, $salt = false) {
|
||||
if ($salt === false) {
|
||||
if ($salt === false || $salt === null || $salt === '') {
|
||||
$salt = static::_salt(22);
|
||||
$salt = vsprintf('$2a$%02d$%s', array(static::$hashCost, $salt));
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ class Validation {
|
|||
'enroute' => '/^2(?:014|149)\\d{11}$/',
|
||||
'jcb' => '/^(3\\d{4}|2100|1800)\\d{11}$/',
|
||||
'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
|
||||
'mc' => '/^5[1-5]\\d{14}$/',
|
||||
'mc' => '/^(5[1-5]\\d{14})|(2(?:22[1-9]|2[3-9][0-9]|[3-6][0-9]{2}|7[0-1][0-9]|720)\\d{12})$/',
|
||||
'solo' => '/^(6334[5-9][0-9]|6767[0-9]{2})\\d{10}(\\d{2,3})?$/',
|
||||
'switch' =>
|
||||
'/^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\\d{10}(\\d{2,3})?)|(?:564182\\d{10}(\\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\\d{10}(\\d{2,3})?)$/',
|
||||
|
@ -672,7 +672,7 @@ class Validation {
|
|||
// Exchange and 555-XXXX numbers
|
||||
$regex .= '(?!(555(?:\s*(?:[.\-\s]\s*))(01([0-9][0-9])|1212)))';
|
||||
$regex .= '(?!(555(01([0-9][0-9])|1212)))';
|
||||
$regex .= '([2-9]1[02-9]|[2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)';
|
||||
$regex .= '([2-9]1[02-9]|[2-9][02-9]1|[2-9][0-9]{2})\s*(?:[.-]\s*)';
|
||||
|
||||
// Local number and extension
|
||||
$regex .= '?([0-9]{4})';
|
||||
|
@ -1036,7 +1036,17 @@ class Validation {
|
|||
if (isset($options['types']) && !static::mimeType($file, $options['types'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return static::_isUploadedFile($file['tmp_name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that can be stubbed in testing.
|
||||
*
|
||||
* @param string $path The path to check.
|
||||
* @return bool Whether or not the file is an uploaded file.
|
||||
*/
|
||||
protected static function _isUploadedFile($path) {
|
||||
return is_uploaded_file($path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
// @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
// +--------------------------------------------------------------------------------------------+ //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
2.9.0-dev
|
||||
2.8.3
|
||||
|
|
|
@ -382,6 +382,7 @@ class FormHelper extends AppHelper {
|
|||
if (isset($options['action'])) {
|
||||
trigger_error('Using key `action` is deprecated, use `url` directly instead.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (is_array($options['url']) && isset($options['url']['action'])) {
|
||||
$options['action'] = $options['url']['action'];
|
||||
}
|
||||
|
@ -393,7 +394,7 @@ class FormHelper extends AppHelper {
|
|||
|
||||
if ($options['action'] === null && $options['url'] === null) {
|
||||
$options['action'] = $this->request->here(false);
|
||||
} elseif (is_array($options['url'])) {
|
||||
} elseif (empty($options['url']) || is_array($options['url'])) {
|
||||
if (empty($options['url']['controller'])) {
|
||||
if (!empty($model)) {
|
||||
$options['url']['controller'] = Inflector::underscore(Inflector::pluralize($model));
|
||||
|
@ -611,11 +612,13 @@ class FormHelper extends AppHelper {
|
|||
$tokenFields = array_merge($secureAttributes, array(
|
||||
'value' => urlencode($fields . ':' . $locked),
|
||||
'id' => 'TokenFields' . mt_rand(),
|
||||
'secure' => static::SECURE_SKIP,
|
||||
));
|
||||
$out = $this->hidden('_Token.fields', $tokenFields);
|
||||
$tokenUnlocked = array_merge($secureAttributes, array(
|
||||
'value' => urlencode($unlocked),
|
||||
'id' => 'TokenUnlocked' . mt_rand(),
|
||||
'secure' => static::SECURE_SKIP,
|
||||
));
|
||||
$out .= $this->hidden('_Token.unlocked', $tokenUnlocked);
|
||||
return $this->Html->useTag('hiddenblock', $out);
|
||||
|
@ -1870,6 +1873,7 @@ class FormHelper extends AppHelper {
|
|||
unset($options['target']);
|
||||
}
|
||||
|
||||
$previousLastAction = $this->_lastAction;
|
||||
$this->_lastAction($url);
|
||||
|
||||
$out = $this->Html->useTag('form', $formUrl, $formOptions);
|
||||
|
@ -1882,7 +1886,7 @@ class FormHelper extends AppHelper {
|
|||
if (isset($options['data']) && is_array($options['data'])) {
|
||||
foreach (Hash::flatten($options['data']) as $key => $value) {
|
||||
$fields[$key] = $value;
|
||||
$out .= $this->hidden($key, array('value' => $value, 'id' => false));
|
||||
$out .= $this->hidden($key, array('value' => $value, 'id' => false, 'secure' => static::SECURE_SKIP));
|
||||
}
|
||||
unset($options['data']);
|
||||
}
|
||||
|
@ -1892,6 +1896,8 @@ class FormHelper extends AppHelper {
|
|||
if ($options['block']) {
|
||||
$this->_View->append($options['block'], $out);
|
||||
$out = '';
|
||||
// Reset security-relevant fields for outer form
|
||||
$this->_lastAction = $previousLastAction;
|
||||
}
|
||||
unset($options['block']);
|
||||
|
||||
|
@ -2783,6 +2789,11 @@ class FormHelper extends AppHelper {
|
|||
$selectedIsEmpty = ($attributes['value'] === '' || $attributes['value'] === null);
|
||||
$selectedIsArray = is_array($attributes['value']);
|
||||
|
||||
// Cast boolean false into an integer so string comparisons can work.
|
||||
if ($attributes['value'] === false) {
|
||||
$attributes['value'] = 0;
|
||||
}
|
||||
|
||||
$this->_domIdSuffixes = array();
|
||||
foreach ($elements as $name => $title) {
|
||||
$htmlOptions = array();
|
||||
|
|
Loading…
Reference in a new issue