mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
commit
9a69363858
37 changed files with 475 additions and 175 deletions
11
.travis.yml
11
.travis.yml
|
@ -10,6 +10,7 @@ php:
|
|||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
|
||||
env:
|
||||
matrix:
|
||||
|
@ -38,6 +39,15 @@ matrix:
|
|||
- php: 7.1
|
||||
env: DB=mysql PHPUNIT=5.7.19
|
||||
|
||||
- php: 7.2
|
||||
env: DB=mysql PHPUNIT=5.7.19
|
||||
allow_failures:
|
||||
- php: 7.2
|
||||
env: DB=mysql
|
||||
|
||||
- php: 7.2
|
||||
env: DB=mysql PHPUNIT=5.7.19
|
||||
|
||||
|
||||
before_script:
|
||||
- composer require "phpunit/phpunit=$PHPUNIT"
|
||||
|
@ -52,6 +62,7 @@ before_script:
|
|||
- sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'CREATE SCHEMA test3;' -U postgres -d cakephp_test; fi"
|
||||
- chmod -R 777 ./app/tmp
|
||||
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "5.3" ]] ; then pecl install timezonedb ; fi
|
||||
- if [[ ${TRAVIS_PHP_VERSION:0:3} == "7.2" ]] ; then pecl install mcrypt ; fi
|
||||
- sh -c "if [ '$PHPCS' = '1' ]; then composer require 'cakephp/cakephp-codesniffer:1.*'; fi"
|
||||
- sh -c "if [ '$PHPCS' = '1' ]; then vendors/bin/phpcs --config-set installed_paths vendors/cakephp/cakephp-codesniffer; fi"
|
||||
- echo "extension = memcached.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
|
||||
|
|
|
@ -415,7 +415,7 @@ class Shell extends CakeObject {
|
|||
* @param string $command The command name to run on this shell. If this argument is empty,
|
||||
* and the shell has a `main()` method, that will be called instead.
|
||||
* @param array $argv Array of arguments to run the shell with. This array should be missing the shell name.
|
||||
* @return void
|
||||
* @return int|bool
|
||||
* @link https://book.cakephp.org/2.0/en/console-and-shells.html#Shell::runCommand
|
||||
*/
|
||||
public function runCommand($command, $argv) {
|
||||
|
@ -469,7 +469,7 @@ class Shell extends CakeObject {
|
|||
* Display the help in the correct format
|
||||
*
|
||||
* @param string $command The command to get help for.
|
||||
* @return void
|
||||
* @return int|bool
|
||||
*/
|
||||
protected function _displayHelp($command) {
|
||||
$format = 'text';
|
||||
|
@ -571,7 +571,7 @@ class Shell extends CakeObject {
|
|||
* @param string $prompt Prompt text.
|
||||
* @param string|array $options Array or string of options.
|
||||
* @param string $default Default input value.
|
||||
* @return Either the default value, or the user-provided input.
|
||||
* @return string|int the default value, or the user-provided input.
|
||||
*/
|
||||
protected function _getInput($prompt, $options, $default) {
|
||||
if (!is_array($options)) {
|
||||
|
@ -726,7 +726,7 @@ class Shell extends CakeObject {
|
|||
*
|
||||
* @param string $title Title of the error
|
||||
* @param string $message An optional error message
|
||||
* @return void
|
||||
* @return int
|
||||
* @link https://book.cakephp.org/2.0/en/console-and-shells.html#Shell::error
|
||||
*/
|
||||
public function error($title, $message = null) {
|
||||
|
|
|
@ -52,7 +52,7 @@ class DbAcl extends CakeObject implements AclInterface {
|
|||
/**
|
||||
* Initializes the containing component and sets the Aro/Aco objects to it.
|
||||
*
|
||||
* @param AclComponent $component The AclComponent instance.
|
||||
* @param Component $component The AclComponent instance.
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Component $component) {
|
||||
|
|
|
@ -44,7 +44,7 @@ App::uses('BasicAuthenticate', 'Controller/Component/Auth');
|
|||
* Due to the Digest authentication specification, digest auth requires a special password value. You
|
||||
* can generate this password using `DigestAuthenticate::password()`
|
||||
*
|
||||
* `$digestPass = DigestAuthenticate::password($username, env('SERVER_NAME'), $password);`
|
||||
* `$digestPass = DigestAuthenticate::password($username, $password, env('SERVER_NAME'));`
|
||||
*
|
||||
* Its recommended that you store this digest auth only password separate from password hashes used for other
|
||||
* login methods. For example `User.digest_pass` could be used for a digest password, while `User.password` would
|
||||
|
@ -136,7 +136,7 @@ class DigestAuthenticate extends BasicAuthenticate {
|
|||
/**
|
||||
* Gets the digest headers from the request/environment.
|
||||
*
|
||||
* @return array Array of digest information.
|
||||
* @return array|bool|null Array of digest information.
|
||||
*/
|
||||
protected function _getDigest() {
|
||||
$digest = env('PHP_AUTH_DIGEST');
|
||||
|
|
|
@ -761,7 +761,7 @@ class AuthComponent extends Component {
|
|||
*
|
||||
* @param CakeRequest $request The request that contains authentication data.
|
||||
* @param CakeResponse $response The response
|
||||
* @return array User record data, or false, if the user could not be identified.
|
||||
* @return array|bool User record data, or false, if the user could not be identified.
|
||||
*/
|
||||
public function identify(CakeRequest $request, CakeResponse $response) {
|
||||
if (empty($this->_authenticateObjects)) {
|
||||
|
|
|
@ -229,27 +229,14 @@ class CookieComponent extends Component {
|
|||
}
|
||||
|
||||
foreach ($key as $name => $value) {
|
||||
$names = array($name);
|
||||
if (strpos($name, '.') !== false) {
|
||||
$names = explode('.', $name, 2);
|
||||
}
|
||||
$firstName = $names[0];
|
||||
$isMultiValue = (is_array($value) || count($names) > 1);
|
||||
|
||||
if (!isset($this->_values[$this->name][$firstName]) && $isMultiValue) {
|
||||
$this->_values[$this->name][$firstName] = array();
|
||||
}
|
||||
|
||||
if (count($names) > 1) {
|
||||
$this->_values[$this->name][$firstName] = Hash::insert(
|
||||
$this->_values[$this->name][$firstName],
|
||||
$names[1],
|
||||
$value
|
||||
);
|
||||
$this->_values[$this->name] = Hash::insert($this->_values[$this->name], $name, $value);
|
||||
list($name) = explode('.', $name, 2);
|
||||
$value = $this->_values[$this->name][$name];
|
||||
} else {
|
||||
$this->_values[$this->name][$firstName] = $value;
|
||||
$this->_values[$this->name][$name] = $value;
|
||||
}
|
||||
$this->_write('[' . $firstName . ']', $this->_values[$this->name][$firstName]);
|
||||
$this->_write('[' . $name . ']', $value);
|
||||
}
|
||||
$this->_encrypted = true;
|
||||
}
|
||||
|
@ -274,22 +261,7 @@ class CookieComponent extends Component {
|
|||
if ($key === null) {
|
||||
return $this->_values[$this->name];
|
||||
}
|
||||
|
||||
if (strpos($key, '.') !== false) {
|
||||
$names = explode('.', $key, 2);
|
||||
$key = $names[0];
|
||||
}
|
||||
if (!isset($this->_values[$this->name][$key])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!empty($names[1])) {
|
||||
if (is_array($this->_values[$this->name][$key])) {
|
||||
return Hash::get($this->_values[$this->name][$key], $names[1]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return $this->_values[$this->name][$key];
|
||||
return Hash::get($this->_values[$this->name], $key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,20 +301,16 @@ class CookieComponent extends Component {
|
|||
$this->read();
|
||||
}
|
||||
if (strpos($key, '.') === false) {
|
||||
if (isset($this->_values[$this->name][$key]) && is_array($this->_values[$this->name][$key])) {
|
||||
foreach ($this->_values[$this->name][$key] as $idx => $val) {
|
||||
$this->_delete("[$key][$idx]");
|
||||
}
|
||||
}
|
||||
$this->_delete("[$key]");
|
||||
unset($this->_values[$this->name][$key]);
|
||||
return;
|
||||
$this->_delete('[' . $key . ']');
|
||||
} else {
|
||||
$this->_values[$this->name] = Hash::remove((array)$this->_values[$this->name], $key);
|
||||
list($key) = explode('.', $key, 2);
|
||||
if (isset($this->_values[$this->name][$key])) {
|
||||
$value = $this->_values[$this->name][$key];
|
||||
$this->_write('[' . $key . ']', $value);
|
||||
}
|
||||
$names = explode('.', $key, 2);
|
||||
if (isset($this->_values[$this->name][$names[0]]) && is_array($this->_values[$this->name][$names[0]])) {
|
||||
$this->_values[$this->name][$names[0]] = Hash::remove($this->_values[$this->name][$names[0]], $names[1]);
|
||||
}
|
||||
$this->_delete('[' . implode('][', $names) . ']');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,14 +328,7 @@ class CookieComponent extends Component {
|
|||
}
|
||||
|
||||
foreach ($this->_values[$this->name] as $name => $value) {
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $key => $val) {
|
||||
unset($this->_values[$this->name][$name][$key]);
|
||||
$this->_delete("[$name][$key]");
|
||||
}
|
||||
}
|
||||
unset($this->_values[$this->name][$name]);
|
||||
$this->_delete("[$name]");
|
||||
$this->delete($name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,7 +455,7 @@ class CookieComponent extends Component {
|
|||
* Decrypts $value using public $type method in Security class
|
||||
*
|
||||
* @param array $values Values to decrypt
|
||||
* @return string decrypted string
|
||||
* @return array decrypted string
|
||||
*/
|
||||
protected function _decrypt($values) {
|
||||
$decrypted = array();
|
||||
|
@ -516,7 +477,7 @@ class CookieComponent extends Component {
|
|||
* Decodes and decrypts a single value.
|
||||
*
|
||||
* @param string $value The value to decode & decrypt.
|
||||
* @return string Decoded value.
|
||||
* @return string|array Decoded value.
|
||||
*/
|
||||
protected function _decode($value) {
|
||||
$prefix = 'Q2FrZQ==.';
|
||||
|
@ -552,7 +513,7 @@ class CookieComponent extends Component {
|
|||
* Maintains reading backwards compatibility with 1.x CookieComponent::_implode().
|
||||
*
|
||||
* @param string $string A string containing JSON encoded data, or a bare string.
|
||||
* @return array Map of key and values
|
||||
* @return string|array Map of key and values
|
||||
*/
|
||||
protected function _explode($string) {
|
||||
$first = substr($string, 0, 1);
|
||||
|
|
|
@ -282,7 +282,7 @@ class EmailComponent extends Component {
|
|||
* If you are rendering a template this variable will be sent to the templates as `$content`
|
||||
* @param string $template Template to use when sending email
|
||||
* @param string $layout Layout to use to enclose email body
|
||||
* @return bool Success
|
||||
* @return array Success
|
||||
*/
|
||||
public function send($content = null, $template = null, $layout = null) {
|
||||
$lib = new CakeEmail();
|
||||
|
|
|
@ -136,7 +136,13 @@ class SessionComponent extends Component {
|
|||
* @deprecated 3.0.0 Since 2.7, use the FlashComponent instead.
|
||||
*/
|
||||
public function setFlash($message, $element = 'default', $params = array(), $key = 'flash') {
|
||||
CakeSession::write('Message.' . $key, compact('message', 'element', 'params'));
|
||||
$messages = (array)CakeSession::read('Message.' . $key);
|
||||
$messages[] = array(
|
||||
'message' => $message,
|
||||
'element' => $element,
|
||||
'params' => $params,
|
||||
);
|
||||
CakeSession::write('Message.' . $key, $messages);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,7 +153,7 @@ class SessionComponent extends Component {
|
|||
* @return void
|
||||
*/
|
||||
public function renew() {
|
||||
return CakeSession::renew();
|
||||
CakeSession::renew();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -170,7 +176,7 @@ class SessionComponent extends Component {
|
|||
* @link https://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::destroy
|
||||
*/
|
||||
public function destroy() {
|
||||
return CakeSession::destroy();
|
||||
CakeSession::destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -111,7 +111,7 @@ class CakeEvent {
|
|||
/**
|
||||
* Stops the event from being used anymore
|
||||
*
|
||||
* @return void
|
||||
* @return bool
|
||||
*/
|
||||
public function stopPropagation() {
|
||||
return $this->_stopped = true;
|
||||
|
|
|
@ -432,7 +432,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
* is disabled.
|
||||
*
|
||||
* @param Model $Model Model using this behavior.
|
||||
* @return void
|
||||
* @return bool true.
|
||||
*/
|
||||
protected function _setRuntimeData(Model $Model) {
|
||||
$locale = $this->_getLocale($Model);
|
||||
|
@ -465,7 +465,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
* This solves issues with saveAssociated and validate = first.
|
||||
*
|
||||
* @param Model $Model Model using this behavior.
|
||||
* @return void
|
||||
* @return bool true.
|
||||
*/
|
||||
public function afterValidate(Model $Model) {
|
||||
$Model->data[$Model->alias] = array_merge(
|
||||
|
@ -481,7 +481,7 @@ class TranslateBehavior extends ModelBehavior {
|
|||
* @param Model $Model Model the callback is called on
|
||||
* @param bool $created Whether or not the save created a record.
|
||||
* @param array $options Options passed from Model::save().
|
||||
* @return void
|
||||
* @return bool true.
|
||||
*/
|
||||
public function afterSave(Model $Model, $created, $options = array()) {
|
||||
if (!isset($this->runtime[$Model->alias]['beforeValidate']) && !isset($this->runtime[$Model->alias]['beforeSave'])) {
|
||||
|
|
|
@ -73,7 +73,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
*
|
||||
* @param string $behavior Behavior name.
|
||||
* @param array $config Configuration options.
|
||||
* @return void
|
||||
* @return bool true.
|
||||
* @deprecated 3.0.0 Will be removed in 3.0. Replaced with load().
|
||||
*/
|
||||
public function attach($behavior, $config = array()) {
|
||||
|
@ -97,7 +97,7 @@ class BehaviorCollection extends ObjectCollection implements CakeEventListener {
|
|||
*
|
||||
* @param string $behavior CamelCased name of the behavior to load
|
||||
* @param array $config Behavior configuration parameters
|
||||
* @return bool True on success, false on failure
|
||||
* @return bool True on success.
|
||||
* @throws MissingBehaviorException when a behavior could not be found.
|
||||
*/
|
||||
public function load($behavior, $config = array()) {
|
||||
|
|
|
@ -134,6 +134,13 @@ class CakeSession {
|
|||
*/
|
||||
protected static $_cookieName = null;
|
||||
|
||||
/**
|
||||
* Whether this session is running under a CLI environment
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected static $_isCLI = false;
|
||||
|
||||
/**
|
||||
* Pseudo constructor.
|
||||
*
|
||||
|
@ -155,6 +162,7 @@ class CakeSession {
|
|||
}
|
||||
|
||||
static::$_initialized = true;
|
||||
static::$_isCLI = (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -596,14 +604,18 @@ class CakeSession {
|
|||
* @return bool
|
||||
*/
|
||||
protected static function _hasSession() {
|
||||
return static::started() || isset($_COOKIE[static::_cookieName()]) || (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg');
|
||||
return static::started()
|
||||
|| !ini_get('session.use_cookies')
|
||||
|| isset($_COOKIE[static::_cookieName()])
|
||||
|| static::$_isCLI
|
||||
|| (ini_get('session.use_trans_sid') && isset($_GET[session_name()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the handler class and make sure it implements the correct interface.
|
||||
*
|
||||
* @param string $handler Handler name.
|
||||
* @return void
|
||||
* @return CakeSessionHandlerInterface
|
||||
* @throws CakeSessionException
|
||||
*/
|
||||
protected static function _getHandler($handler) {
|
||||
|
|
|
@ -212,7 +212,7 @@ class Sqlite extends DboSource {
|
|||
* @param array $fields The fields to update.
|
||||
* @param array $values The values to set columns to.
|
||||
* @param mixed $conditions array of conditions to use.
|
||||
* @return array
|
||||
* @return bool
|
||||
*/
|
||||
public function update(Model $model, $fields = array(), $values = null, $conditions = null) {
|
||||
if (empty($values) && !empty($fields)) {
|
||||
|
|
|
@ -72,7 +72,6 @@ class Sqlserver extends DboSource {
|
|||
* @var array
|
||||
*/
|
||||
protected $_baseConfig = array(
|
||||
'persistent' => true,
|
||||
'host' => 'localhost\SQLEXPRESS',
|
||||
'login' => '',
|
||||
'password' => '',
|
||||
|
@ -118,15 +117,24 @@ class Sqlserver extends DboSource {
|
|||
/**
|
||||
* Connects to the database using options in the given configuration array.
|
||||
*
|
||||
* Please note that the PDO::ATTR_PERSISTENT attribute is not supported by
|
||||
* the SQL Server PHP PDO drivers. As a result you cannot use the
|
||||
* persistent config option when connecting to a SQL Server (for more
|
||||
* information see: https://github.com/Microsoft/msphpsql/issues/65).
|
||||
*
|
||||
* @return bool True if the database could be connected, else false
|
||||
* @throws InvalidArgumentException if an unsupported setting is in the database config
|
||||
* @throws MissingConnectionException
|
||||
*/
|
||||
public function connect() {
|
||||
$config = $this->config;
|
||||
$this->connected = false;
|
||||
|
||||
if (isset($config['persistent']) && $config['persistent']) {
|
||||
throw new InvalidArgumentException('Config setting "persistent" cannot be set to true, as the Sqlserver PDO driver does not support PDO::ATTR_PERSISTENT');
|
||||
}
|
||||
|
||||
$flags = $config['flags'] + array(
|
||||
PDO::ATTR_PERSISTENT => $config['persistent'],
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
);
|
||||
|
||||
|
@ -403,7 +411,7 @@ class Sqlserver extends DboSource {
|
|||
$rt = ' TOP';
|
||||
}
|
||||
$rt .= sprintf(' %u', $limit);
|
||||
if (is_int($offset) && $offset > 0) {
|
||||
if ((is_int($offset) || ctype_digit($offset)) && $offset > 0) {
|
||||
$rt = sprintf(' OFFSET %u ROWS FETCH FIRST %u ROWS ONLY', $offset, $limit);
|
||||
}
|
||||
return $rt;
|
||||
|
|
|
@ -234,7 +234,7 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
|
|||
* actually run validation rules over data, not just return the messages.
|
||||
*
|
||||
* @param string $options An optional array of custom options to be made available in the beforeValidate callback
|
||||
* @return array Array of invalid fields
|
||||
* @return array|bool Array of invalid fields
|
||||
* @triggers Model.afterValidate $model
|
||||
* @see ModelValidator::validates()
|
||||
*/
|
||||
|
|
|
@ -70,7 +70,7 @@ class CakeEmail {
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
const EMAIL_PATTERN = '/^((?:[\p{L}0-9.!#$%&\'*+\/=?^_`{|}~-]+)*@[\p{L}0-9-.]+)$/ui';
|
||||
const EMAIL_PATTERN = '/^((?:[\p{L}0-9.!#$%&\'*+\/=?^_`{|}~-]+)*@[\p{L}0-9-_.]+)$/ui';
|
||||
|
||||
/**
|
||||
* Recipient of the email
|
||||
|
|
|
@ -760,7 +760,7 @@ class HttpSocket extends CakeSocket {
|
|||
*
|
||||
* @param string|array $uri URI to parse
|
||||
* @param bool|array $base If true use default URI config, otherwise indexed array to set 'scheme', 'host', 'port', etc.
|
||||
* @return array Parsed URI
|
||||
* @return array|bool Parsed URI
|
||||
*/
|
||||
protected function _parseUri($uri = null, $base = array()) {
|
||||
$uriBase = array(
|
||||
|
|
|
@ -259,7 +259,7 @@ class HttpSocketResponse implements ArrayAccess {
|
|||
* Parses an array based header.
|
||||
*
|
||||
* @param array $header Header as an indexed array (field => value)
|
||||
* @return array Parsed header
|
||||
* @return array|bool Parsed header
|
||||
*/
|
||||
protected function _parseHeader($header) {
|
||||
if (is_array($header)) {
|
||||
|
|
|
@ -429,6 +429,24 @@ class CookieComponentTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that replacing scalar with array works.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReplaceScalarWithArray() {
|
||||
$this->Cookie->write('foo', 1);
|
||||
$this->Cookie->write('foo.bar', 2);
|
||||
|
||||
$data = $this->Cookie->read();
|
||||
$expected = array(
|
||||
'foo' => array(
|
||||
'bar' => 2
|
||||
)
|
||||
);
|
||||
$this->assertEquals($expected, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* testReadingCookieValue
|
||||
*
|
||||
|
@ -696,6 +714,20 @@ class CookieComponentTest extends CakeTestCase {
|
|||
$this->assertEquals(array(), $this->Cookie->read('Array'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test reading empty key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testReadEmptyKey() {
|
||||
$_COOKIE['CakeTestCookie'] = array(
|
||||
'0' => '{"name":"value"}',
|
||||
'foo' => array('bar'),
|
||||
);
|
||||
$this->assertEquals('value', $this->Cookie->read('0.name'));
|
||||
$this->assertEquals('bar', $this->Cookie->read('foo.0'));
|
||||
}
|
||||
|
||||
/**
|
||||
* test that no error is issued for non array data.
|
||||
*
|
||||
|
@ -789,6 +821,89 @@ class CookieComponentTest extends CakeTestCase {
|
|||
$this->assertNull($this->Cookie->delete('Not.Found'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test deleting deep child elements sends correct cookies.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDeleteDeepChildren() {
|
||||
$_COOKIE = array(
|
||||
'CakeTestCookie' => array(
|
||||
'foo' => $this->_encrypt(array(
|
||||
'bar' => array(
|
||||
'baz' => 'value',
|
||||
),
|
||||
)),
|
||||
),
|
||||
);
|
||||
|
||||
$this->Cookie->delete('foo.bar.baz');
|
||||
|
||||
$cookies = $this->Controller->response->cookie();
|
||||
$expected = array(
|
||||
'CakeTestCookie[foo]' => array(
|
||||
'name' => 'CakeTestCookie[foo]',
|
||||
'value' => '{"bar":[]}',
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httpOnly' => false
|
||||
),
|
||||
);
|
||||
|
||||
$expires = Hash::combine($cookies, '{*}.name', '{*}.expire');
|
||||
$cookies = Hash::remove($cookies, '{*}.expire');
|
||||
$this->assertEquals($expected, $cookies);
|
||||
|
||||
$this->assertWithinMargin($expires['CakeTestCookie[foo]'], time() + 10, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test destroy works.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testDestroy() {
|
||||
$_COOKIE = array(
|
||||
'CakeTestCookie' => array(
|
||||
'foo' => $this->_encrypt(array(
|
||||
'bar' => array(
|
||||
'baz' => 'value',
|
||||
),
|
||||
)),
|
||||
'other' => 'value',
|
||||
),
|
||||
);
|
||||
|
||||
$this->Cookie->destroy();
|
||||
|
||||
$cookies = $this->Controller->response->cookie();
|
||||
$expected = array(
|
||||
'CakeTestCookie[foo]' => array(
|
||||
'name' => 'CakeTestCookie[foo]',
|
||||
'value' => '',
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httpOnly' => false
|
||||
),
|
||||
'CakeTestCookie[other]' => array(
|
||||
'name' => 'CakeTestCookie[other]',
|
||||
'value' => '',
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => false,
|
||||
'httpOnly' => false
|
||||
),
|
||||
);
|
||||
|
||||
$expires = Hash::combine($cookies, '{*}.name', '{*}.expire');
|
||||
$cookies = Hash::remove($cookies, '{*}.expire');
|
||||
$this->assertEquals($expected, $cookies);
|
||||
$this->assertWithinMargin($expires['CakeTestCookie[foo]'], time() - 42000, 2);
|
||||
$this->assertWithinMargin($expires['CakeTestCookie[other]'], time() - 42000, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for generating old style encoded cookie values.
|
||||
*
|
||||
|
|
|
@ -247,16 +247,13 @@ class SessionComponentTest extends CakeTestCase {
|
|||
$this->assertNull($Session->read('Message.flash'));
|
||||
|
||||
$Session->setFlash('This is a test message');
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.flash'));
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.flash.0'));
|
||||
|
||||
$Session->setFlash('This is a test message', 'test', array('name' => 'Joel Moss'));
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'test', 'params' => array('name' => 'Joel Moss')), $Session->read('Message.flash'));
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'test', 'params' => array('name' => 'Joel Moss')), $Session->read('Message.flash.1'));
|
||||
|
||||
$Session->setFlash('This is a test message', 'default', array(), 'myFlash');
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.myFlash'));
|
||||
|
||||
$Session->setFlash('This is a test message', 'non_existing_layout');
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.myFlash'));
|
||||
$this->assertEquals(array('message' => 'This is a test message', 'element' => 'default', 'params' => array()), $Session->read('Message.myFlash.0'));
|
||||
|
||||
$Session->delete('Message');
|
||||
}
|
||||
|
|
|
@ -397,6 +397,13 @@ class SqlserverTest extends CakeTestCase {
|
|||
));
|
||||
$result = $this->db->getLastQuery();
|
||||
$this->assertRegExp('/^SELECT DISTINCT TOP 5/', $result);
|
||||
|
||||
$this->db->read($this->model, array(
|
||||
'fields' => array('DISTINCT SqlserverTestModel.city', 'SqlserverTestModel.country'),
|
||||
'limit' => '5'
|
||||
));
|
||||
$result = $this->db->getLastQuery();
|
||||
$this->assertRegExp('/^SELECT DISTINCT TOP 5/', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -275,6 +275,10 @@ class CakeEmailTest extends CakeTestCase {
|
|||
$expected = array('cake@cakephp.org' => 'CakePHP');
|
||||
$this->assertSame($expected, $this->CakeEmail->to());
|
||||
|
||||
$this->CakeEmail->to('cake@cake_php.org', 'CakePHPUnderscore');
|
||||
$expected = array('cake@cake_php.org' => 'CakePHPUnderscore');
|
||||
$this->assertSame($expected, $this->CakeEmail->to());
|
||||
|
||||
$list = array(
|
||||
'root@localhost' => 'root',
|
||||
'bjørn@hammeröath.com' => 'Bjorn',
|
||||
|
|
|
@ -1356,7 +1356,7 @@ class HashTest extends CakeTestCase {
|
|||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$result = Hash::sort($items, '{n}.Item.image', 'asc', array('type' => 'natural', 'ignoreCase' => true));
|
||||
$result = Hash::sort($items, '{n}.Item.image', 'asc', array('type' => 'NATURAL', 'ignoreCase' => true));
|
||||
$expected = array(
|
||||
array('Item' => array('image' => 'img1.jpg')),
|
||||
array('Item' => array('image' => 'img2.jpg')),
|
||||
|
@ -1529,6 +1529,58 @@ class HashTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $sorted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sorting on a nested key that is sometimes undefined.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testSortSparse() {
|
||||
$data = array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'title' => 'element 1',
|
||||
'extra' => 1,
|
||||
),
|
||||
array(
|
||||
'id' => 2,
|
||||
'title' => 'element 2',
|
||||
'extra' => 2,
|
||||
),
|
||||
array(
|
||||
'id' => 3,
|
||||
'title' => 'element 3',
|
||||
),
|
||||
array(
|
||||
'id' => 4,
|
||||
'title' => 'element 4',
|
||||
'extra' => 4,
|
||||
)
|
||||
);
|
||||
$result = Hash::sort($data, '{n}.extra', 'desc', 'natural');
|
||||
$expected = array(
|
||||
array(
|
||||
'id' => 4,
|
||||
'title' => 'element 4',
|
||||
'extra' => 4,
|
||||
),
|
||||
array(
|
||||
'id' => 2,
|
||||
'title' => 'element 2',
|
||||
'extra' => 2,
|
||||
),
|
||||
array(
|
||||
'id' => 1,
|
||||
'title' => 'element 1',
|
||||
'extra' => 1,
|
||||
),
|
||||
array(
|
||||
'id' => 3,
|
||||
'title' => 'element 3',
|
||||
),
|
||||
);
|
||||
$this->assertSame($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test insert()
|
||||
*
|
||||
|
@ -1594,6 +1646,17 @@ class HashTest extends CakeTestCase {
|
|||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data[3]['testable'] = true;
|
||||
$result = Hash::insert($data, '{n}[testable].Item[id=/\b2|\b4/].test', 2);
|
||||
$expected = array(
|
||||
0 => array('Item' => array('id' => 1, 'title' => 'first')),
|
||||
1 => array('Item' => array('id' => 2, 'title' => 'second')),
|
||||
2 => array('Item' => array('id' => 3, 'title' => 'third')),
|
||||
3 => array('Item' => array('id' => 4, 'title' => 'fourth', 'test' => 2), 'testable' => true),
|
||||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1686,6 +1749,43 @@ class HashTest extends CakeTestCase {
|
|||
$this->assertEquals($expected, $result);
|
||||
$result = Hash::remove($array, '{n}.{n}.part');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$array = array(
|
||||
'foo' => 'string',
|
||||
);
|
||||
$expected = $array;
|
||||
$result = Hash::remove($array, 'foo.bar');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$array = array(
|
||||
'foo' => 'string',
|
||||
'bar' => array(
|
||||
0 => 'a',
|
||||
1 => 'b',
|
||||
),
|
||||
);
|
||||
$expected = array(
|
||||
'foo' => 'string',
|
||||
'bar' => array(
|
||||
1 => 'b',
|
||||
),
|
||||
);
|
||||
$result = Hash::remove($array, '{s}.0');
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$array = array(
|
||||
'foo' => array(
|
||||
0 => 'a',
|
||||
1 => 'b',
|
||||
),
|
||||
);
|
||||
$expected = array(
|
||||
'foo' => array(
|
||||
1 => 'b',
|
||||
),
|
||||
);
|
||||
$result = Hash::remove($array, 'foo[1=b].0');
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1721,6 +1821,17 @@ class HashTest extends CakeTestCase {
|
|||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data[3]['testable'] = true;
|
||||
$result = Hash::remove($data, '{n}[testable].Item[id=/\b2|\b4/].title');
|
||||
$expected = array(
|
||||
0 => array('Item' => array('id' => 1, 'title' => 'first')),
|
||||
1 => array('Item' => array('id' => 2, 'title' => 'second')),
|
||||
2 => array('Item' => array('id' => 3, 'title' => 'third')),
|
||||
3 => array('Item' => array('id' => 4), 'testable' => true),
|
||||
4 => array('Item' => array('id' => 5, 'title' => 'fifth')),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -329,14 +329,14 @@ class ValidationTest extends CakeTestCase {
|
|||
$this->assertTrue(Validation::cc('214981579370225', array('enroute')));
|
||||
$this->assertTrue(Validation::cc('201447595859877', array('enroute')));
|
||||
//JCB 15 digit
|
||||
$this->assertTrue(Validation::cc('210034762247893', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('213134762247898', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('180078671678892', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('180010559353736', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('210095474464258', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('210006675562188', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('210063299662662', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('213195474464253', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('213106675562183', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('213163299662667', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('180032506857825', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('210057919192738', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('213157919192733', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('180031358949367', array('jcb')));
|
||||
$this->assertTrue(Validation::cc('180033802147846', array('jcb')));
|
||||
//JCB 16 digit
|
||||
|
@ -706,7 +706,7 @@ class ValidationTest extends CakeTestCase {
|
|||
//enRoute
|
||||
$this->assertTrue(Validation::luhn('201496944158937', true));
|
||||
//JCB 15 digit
|
||||
$this->assertTrue(Validation::luhn('210034762247893', true));
|
||||
$this->assertTrue(Validation::luhn('213134762247898', true));
|
||||
//JCB 16 digit
|
||||
$this->assertTrue(Validation::luhn('3096806857839939', true));
|
||||
//Maestro (debit card)
|
||||
|
@ -811,7 +811,7 @@ class ValidationTest extends CakeTestCase {
|
|||
//enRoute
|
||||
$this->assertTrue(Validation::cc('201496944158937', 'all'));
|
||||
//JCB 15 digit
|
||||
$this->assertTrue(Validation::cc('210034762247893', 'all'));
|
||||
$this->assertTrue(Validation::cc('213134762247898', 'all'));
|
||||
//JCB 16 digit
|
||||
$this->assertTrue(Validation::cc('3096806857839939', 'all'));
|
||||
//Maestro (debit card)
|
||||
|
@ -861,7 +861,7 @@ class ValidationTest extends CakeTestCase {
|
|||
//enRoute
|
||||
$this->assertTrue(Validation::cc('201496944158937', 'all', true));
|
||||
//JCB 15 digit
|
||||
$this->assertTrue(Validation::cc('210034762247893', 'all', true));
|
||||
$this->assertTrue(Validation::cc('213134762247898', 'all', true));
|
||||
//JCB 16 digit
|
||||
$this->assertTrue(Validation::cc('3096806857839939', 'all', true));
|
||||
//Maestro (debit card)
|
||||
|
|
|
@ -4944,6 +4944,30 @@ class FormHelperTest extends CakeTestCase {
|
|||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* test setting a hiddenField value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testRadioHiddenFieldValue() {
|
||||
$result = $this->Form->input('Model.1.field', array(
|
||||
'type' => 'radio',
|
||||
'options' => array('option A'),
|
||||
'hiddenField' => 'N'
|
||||
)
|
||||
);
|
||||
$expected = array(
|
||||
'div' => array('class' => 'input radio'),
|
||||
array('input' => array('type' => 'hidden', 'name' => 'data[Model][1][field]', 'value' => 'N', 'id' => 'Model1Field_')),
|
||||
array('input' => array('type' => 'radio', 'name' => 'data[Model][1][field]', 'value' => '0', 'id' => 'Model1Field0')),
|
||||
'label' => array('for' => 'Model1Field0'),
|
||||
'option A',
|
||||
'/label',
|
||||
'/div'
|
||||
);
|
||||
$this->assertTags($result, $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* test adding an empty option for radio buttons
|
||||
*
|
||||
|
|
|
@ -47,26 +47,34 @@ class SessionHelperTest extends CakeTestCase {
|
|||
'test' => 'info',
|
||||
'Message' => array(
|
||||
'flash' => array(
|
||||
array(
|
||||
'element' => 'default',
|
||||
'params' => array(),
|
||||
'message' => 'This is a calling'
|
||||
),
|
||||
),
|
||||
'notification' => array(
|
||||
array(
|
||||
'element' => 'session_helper',
|
||||
'params' => array('title' => 'Notice!', 'name' => 'Alert!'),
|
||||
'message' => 'This is a test of the emergency broadcasting system',
|
||||
),
|
||||
),
|
||||
'classy' => array(
|
||||
array(
|
||||
'element' => 'default',
|
||||
'params' => array('class' => 'positive'),
|
||||
'message' => 'Recorded'
|
||||
),
|
||||
),
|
||||
'bare' => array(
|
||||
array(
|
||||
'element' => null,
|
||||
'message' => 'Bare message',
|
||||
'params' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
'Deeply' => array('nested' => array('key' => 'value')),
|
||||
);
|
||||
}
|
||||
|
@ -104,7 +112,7 @@ class SessionHelperTest extends CakeTestCase {
|
|||
public function testCheck() {
|
||||
$this->assertTrue($this->Session->check('test'));
|
||||
|
||||
$this->assertTrue($this->Session->check('Message.flash.element'));
|
||||
$this->assertTrue($this->Session->check('Message.flash.0.element'));
|
||||
|
||||
$this->assertFalse($this->Session->check('Does.not.exist'));
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ class CakeFixtureManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Runs the drop and create commands on the fixtures if necessary.
|
||||
* Runs the drop, create and truncate commands on the fixtures if necessary.
|
||||
*
|
||||
* @param CakeTestFixture $fixture the fixture object to create
|
||||
* @param DataSource $db the datasource instance to use
|
||||
|
@ -191,6 +191,7 @@ class CakeFixtureManager {
|
|||
}
|
||||
}
|
||||
if (!empty($fixture->created) && in_array($db->configKeyName, $fixture->created)) {
|
||||
$fixture->truncate($db);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -205,6 +206,7 @@ class CakeFixtureManager {
|
|||
$fixture->create($db);
|
||||
} else {
|
||||
$fixture->created[] = $db->configKeyName;
|
||||
$fixture->truncate($db);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +231,6 @@ class CakeFixtureManager {
|
|||
$db = ConnectionManager::getDataSource($fixture->useDbConfig);
|
||||
$db->begin();
|
||||
$this->_setupTable($fixture, $db, $test->dropTables);
|
||||
$fixture->truncate($db);
|
||||
$fixture->insert($db);
|
||||
$db->commit();
|
||||
}
|
||||
|
@ -274,7 +275,6 @@ class CakeFixtureManager {
|
|||
$db = ConnectionManager::getDataSource($fixture->useDbConfig);
|
||||
}
|
||||
$this->_setupTable($fixture, $db, $dropTables);
|
||||
$fixture->truncate($db);
|
||||
$fixture->insert($db);
|
||||
} else {
|
||||
throw new UnexpectedValueException(__d('cake_dev', 'Referenced fixture class %s not found', $name));
|
||||
|
|
|
@ -265,7 +265,16 @@ class CakeHtmlReporter extends CakeBaseReporter {
|
|||
echo "<div class='msg'><pre>" . $this->_htmlEntities($message->toString());
|
||||
|
||||
if ((is_string($actualMsg) && is_string($expectedMsg)) || (is_array($actualMsg) && is_array($expectedMsg))) {
|
||||
echo "<br />" . $this->_htmlEntities(PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg));
|
||||
|
||||
$diffs = "";
|
||||
if (class_exists('PHPUnit_Util_Diff')) {
|
||||
$diffs = PHPUnit_Util_Diff::diff($expectedMsg, $actualMsg);
|
||||
} elseif (class_exists('SebastianBergmann\Diff\Differ')) {
|
||||
$differ = new SebastianBergmann\Diff\Differ();
|
||||
$diffs = $differ->diff($expectedMsg, $actualMsg);
|
||||
}
|
||||
|
||||
echo "<br />" . $this->_htmlEntities($diffs);
|
||||
}
|
||||
|
||||
echo "</pre></div>\n";
|
||||
|
|
|
@ -323,7 +323,7 @@ class Folder {
|
|||
* Returns true if given $path is a registered stream wrapper.
|
||||
*
|
||||
* @param string $path Path to check
|
||||
* @return boo true If path is registered stream wrapper.
|
||||
* @return bool true If path is registered stream wrapper.
|
||||
*/
|
||||
public static function isRegisteredStreamWrapper($path) {
|
||||
if (preg_match('/^[A-Z]+(?=:\/\/)/i', $path, $matches) &&
|
||||
|
|
|
@ -91,8 +91,8 @@ class Hash {
|
|||
*
|
||||
* - `1.User.name` Get the name of the user at index 1.
|
||||
* - `{n}.User.name` Get the name of every user in the set of users.
|
||||
* - `{n}.User[id]` Get the name of every user with an id key.
|
||||
* - `{n}.User[id>=2]` Get the name of every user with an id key greater than or equal to 2.
|
||||
* - `{n}.User[id].name` Get the name of every user with an id key.
|
||||
* - `{n}.User[id>=2].name` Get the name of every user with an id key greater than or equal to 2.
|
||||
* - `{n}.User[username=/^paul/]` Get User elements with username matching `^paul`.
|
||||
*
|
||||
* @param array $data The data to extract from.
|
||||
|
@ -149,6 +149,7 @@ class Hash {
|
|||
}
|
||||
return $context[$_key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Split token conditions
|
||||
*
|
||||
|
@ -274,12 +275,10 @@ class Hash {
|
|||
|
||||
foreach ($data as $k => $v) {
|
||||
if (static::_matchToken($k, $token)) {
|
||||
if ($conditions && static::_matches($v, $conditions)) {
|
||||
$data[$k] = array_merge($v, $values);
|
||||
continue;
|
||||
}
|
||||
if (!$conditions) {
|
||||
$data[$k] = static::insert($v, $nextPath, $values);
|
||||
if (!$conditions || static::_matches($v, $conditions)) {
|
||||
$data[$k] = $nextPath
|
||||
? static::insert($v, $nextPath, $values)
|
||||
: array_merge($v, (array)$values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,9 +300,6 @@ class Hash {
|
|||
$count = count($path);
|
||||
$last = $count - 1;
|
||||
foreach ($path as $i => $key) {
|
||||
if ((is_numeric($key) && intval($key) > 0 || $key === '0') && strpos($key, '0') !== 0) {
|
||||
$key = (int)$key;
|
||||
}
|
||||
if ($op === 'insert') {
|
||||
if ($i === $last) {
|
||||
$_list[$key] = $values;
|
||||
|
@ -318,7 +314,9 @@ class Hash {
|
|||
}
|
||||
} elseif ($op === 'remove') {
|
||||
if ($i === $last) {
|
||||
if (is_array($_list)) {
|
||||
unset($_list[$key]);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
if (!isset($_list[$key])) {
|
||||
|
@ -358,15 +356,21 @@ class Hash {
|
|||
foreach ($data as $k => $v) {
|
||||
$match = static::_matchToken($k, $token);
|
||||
if ($match && is_array($v)) {
|
||||
if ($conditions && static::_matches($v, $conditions)) {
|
||||
unset($data[$k]);
|
||||
continue;
|
||||
}
|
||||
if ($conditions) {
|
||||
if (static::_matches($v, $conditions)) {
|
||||
if ($nextPath !== '') {
|
||||
$data[$k] = static::remove($v, $nextPath);
|
||||
} else {
|
||||
unset($data[$k]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data[$k] = static::remove($v, $nextPath);
|
||||
}
|
||||
if (empty($data[$k])) {
|
||||
unset($data[$k]);
|
||||
}
|
||||
} elseif ($match && empty($nextPath)) {
|
||||
} elseif ($match && $nextPath === '') {
|
||||
unset($data[$k]);
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +458,7 @@ class Hash {
|
|||
* The `$format` string can use any format options that `vsprintf()` and `sprintf()` do.
|
||||
*
|
||||
* @param array $data Source array from which to extract the data
|
||||
* @param string $paths An array containing one or more Hash::extract()-style key paths
|
||||
* @param array $paths An array containing one or more Hash::extract()-style key paths
|
||||
* @param string $format Format string into which values will be inserted, see sprintf()
|
||||
* @return array An array of strings extracted from `$path` and formatted with `$format`
|
||||
* @link https://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::format
|
||||
|
@ -729,7 +733,7 @@ class Hash {
|
|||
* Counts the dimensions of an array.
|
||||
* Only considers the dimension of the first element in the array.
|
||||
*
|
||||
* If you have an un-even or heterogenous array, consider using Hash::maxDimensions()
|
||||
* If you have an un-even or heterogeneous array, consider using Hash::maxDimensions()
|
||||
* to get the dimensions of the array.
|
||||
*
|
||||
* @param array $data Array to count dimensions on
|
||||
|
@ -809,11 +813,15 @@ class Hash {
|
|||
* You can easily count the results of an extract using apply().
|
||||
* For example to count the comments on an Article:
|
||||
*
|
||||
* `$count = Hash::apply($data, 'Article.Comment.{n}', 'count');`
|
||||
* ```
|
||||
* $count = Hash::apply($data, 'Article.Comment.{n}', 'count');
|
||||
* ```
|
||||
*
|
||||
* You could also use a function like `array_sum` to sum the results.
|
||||
*
|
||||
* `$total = Hash::apply($data, '{n}.Item.price', 'array_sum');`
|
||||
* ```
|
||||
* $total = Hash::apply($data, '{n}.Item.price', 'array_sum');
|
||||
* ```
|
||||
*
|
||||
* @param array $data The data to reduce.
|
||||
* @param string $path The path to extract from $data.
|
||||
|
@ -833,7 +841,7 @@ class Hash {
|
|||
* - `asc` Sort ascending.
|
||||
* - `desc` Sort descending.
|
||||
*
|
||||
* ## Sort types
|
||||
* ### Sort types
|
||||
*
|
||||
* - `regular` For regular sorting (don't change types)
|
||||
* - `numeric` Compare values numerically
|
||||
|
@ -868,12 +876,18 @@ class Hash {
|
|||
$data = array_values($data);
|
||||
}
|
||||
$sortValues = static::extract($data, $path);
|
||||
$sortCount = count($sortValues);
|
||||
$dataCount = count($data);
|
||||
|
||||
// Make sortValues match the data length, as some keys could be missing
|
||||
// the sorted value path.
|
||||
if ($sortCount < $dataCount) {
|
||||
$missingData = count($sortValues) < $dataCount;
|
||||
if ($missingData && $numeric) {
|
||||
// Get the path without the leading '{n}.'
|
||||
$itemPath = substr($path, 4);
|
||||
foreach ($data as $key => $value) {
|
||||
$sortValues[$key] = static::get($value, $itemPath);
|
||||
}
|
||||
} elseif ($missingData) {
|
||||
$sortValues = array_pad($sortValues, $dataCount, null);
|
||||
}
|
||||
$result = static::_squash($sortValues);
|
||||
|
@ -888,9 +902,8 @@ class Hash {
|
|||
$type += array('ignoreCase' => false, 'type' => 'regular');
|
||||
$ignoreCase = $type['ignoreCase'];
|
||||
$type = $type['type'];
|
||||
} else {
|
||||
$type = strtolower($type);
|
||||
}
|
||||
$type = strtolower($type);
|
||||
|
||||
if ($type === 'natural' && version_compare(PHP_VERSION, '5.4.0', '<')) {
|
||||
$type = 'regular';
|
||||
|
|
|
@ -34,9 +34,9 @@ class Sanitize {
|
|||
/**
|
||||
* Removes any non-alphanumeric characters.
|
||||
*
|
||||
* @param string $string String to sanitize
|
||||
* @param string|array $string String to sanitize
|
||||
* @param array $allowed An array of additional characters that are not to be removed.
|
||||
* @return string Sanitized string
|
||||
* @return string|array Sanitized string
|
||||
*/
|
||||
public static function paranoid($string, $allowed = array()) {
|
||||
$allow = null;
|
||||
|
|
|
@ -175,7 +175,7 @@ class Validation {
|
|||
'disc' => '/^(?:6011|650\\d)\\d{12}$/',
|
||||
'electron' => '/^(?:417500|4917\\d{2}|4913\\d{2})\\d{10}$/',
|
||||
'enroute' => '/^2(?:014|149)\\d{11}$/',
|
||||
'jcb' => '/^(3\\d{4}|2100|1800)\\d{11}$/',
|
||||
'jcb' => '/^(3\\d{4}|2131|1800)\\d{11}$/',
|
||||
'maestro' => '/^(?:5020|6\\d{3})\\d{12}$/',
|
||||
'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})?$/',
|
||||
|
@ -478,7 +478,7 @@ class Validation {
|
|||
if (function_exists('checkdnsrr') && checkdnsrr($regs[1], 'MX')) {
|
||||
return true;
|
||||
}
|
||||
return is_array(gethostbynamel($regs[1]));
|
||||
return is_array(gethostbynamel($regs[1] . '.'));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,4 +17,4 @@
|
|||
// @license https://opensource.org/licenses/mit-license.php MIT License
|
||||
// +--------------------------------------------------------------------------------------------+ //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
2.10.0
|
||||
2.10.5
|
||||
|
|
|
@ -1674,7 +1674,7 @@ class FormHelper extends AppHelper {
|
|||
$hidden = $this->hidden($fieldName, array(
|
||||
'form' => isset($attributes['form']) ? $attributes['form'] : null,
|
||||
'id' => $attributes['id'] . '_',
|
||||
'value' => '',
|
||||
'value' => $hiddenField === true ? '' : $hiddenField,
|
||||
'name' => $attributes['name']
|
||||
));
|
||||
}
|
||||
|
|
|
@ -134,30 +134,14 @@ class SessionHelper extends AppHelper {
|
|||
if (CakeSession::check('Message.' . $key)) {
|
||||
$flash = CakeSession::read('Message.' . $key);
|
||||
CakeSession::delete('Message.' . $key);
|
||||
$message = $flash['message'];
|
||||
unset($flash['message']);
|
||||
|
||||
$out = '';
|
||||
foreach ($flash as $flashArray) {
|
||||
if (!empty($attrs)) {
|
||||
$flash = array_merge($flash, $attrs);
|
||||
$flashArray = array_merge($flashArray, $attrs);
|
||||
}
|
||||
|
||||
if ($flash['element'] === 'default') {
|
||||
$class = 'message';
|
||||
if (!empty($flash['params']['class'])) {
|
||||
$class = $flash['params']['class'];
|
||||
}
|
||||
$out = '<div id="' . $key . 'Message" class="' . $class . '">' . $message . '</div>';
|
||||
} elseif (!$flash['element']) {
|
||||
$out = $message;
|
||||
} else {
|
||||
$options = array();
|
||||
if (isset($flash['params']['plugin'])) {
|
||||
$options['plugin'] = $flash['params']['plugin'];
|
||||
}
|
||||
$tmpVars = $flash['params'];
|
||||
$tmpVars['message'] = $message;
|
||||
$tmpVars['key'] = $key;
|
||||
$out = $this->_View->element($flash['element'], $tmpVars, $options);
|
||||
$flashArray['key'] = $key;
|
||||
$out .= $this->_render($flashArray);
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
|
@ -173,4 +157,34 @@ class SessionHelper extends AppHelper {
|
|||
return CakeSession::valid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a flash message
|
||||
*
|
||||
* @param array $flash Flash message array
|
||||
* @return string
|
||||
*/
|
||||
protected function _render($flash) {
|
||||
$message = $flash['message'];
|
||||
unset($flash['message']);
|
||||
|
||||
if ($flash['element'] === 'default') {
|
||||
$class = 'message';
|
||||
if (!empty($flash['params']['class'])) {
|
||||
$class = $flash['params']['class'];
|
||||
}
|
||||
$out = '<div id="' . $flash['key'] . 'Message" class="' . $class . '">' . $message . '</div>';
|
||||
} elseif (!$flash['element']) {
|
||||
$out = $message;
|
||||
} else {
|
||||
$options = array();
|
||||
if (isset($flash['params']['plugin'])) {
|
||||
$options['plugin'] = $flash['params']['plugin'];
|
||||
}
|
||||
$tmpVars = $flash['params'];
|
||||
$tmpVars['message'] = $message;
|
||||
$tmpVars['key'] = $flash['key'];
|
||||
$out = $this->_View->element($flash['element'], $tmpVars, $options);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ if (!function_exists('h')) {
|
|||
* implement a `__toString` method. Otherwise the class name will be used.
|
||||
* @param bool $double Encode existing html entities
|
||||
* @param string $charset Character set to use when escaping. Defaults to config value in 'App.encoding' or 'UTF-8'
|
||||
* @return string Wrapped text
|
||||
* @return string|array|object Wrapped text, Wrapped Array or Wrapped Object
|
||||
* @link https://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#h
|
||||
*/
|
||||
function h($text, $double = true, $charset = null) {
|
||||
|
|
Loading…
Reference in a new issue