mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2024-11-15 03:18:26 +00:00
commit
87677d7004
21 changed files with 248 additions and 64 deletions
|
@ -40,7 +40,7 @@ CREATE TABLE aros (
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* this indexes will improve acl perfomance */
|
/* this indexes will improve acl performance */
|
||||||
CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rght`);
|
CREATE INDEX idx_acos_lft_rght ON `acos` (`lft`, `rght`);
|
||||||
|
|
||||||
CREATE INDEX idx_acos_alias ON `acos` (`alias`);
|
CREATE INDEX idx_acos_alias ON `acos` (`alias`);
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
"source": "https://github.com/cakephp/cakephp"
|
"source": "https://github.com/cakephp/cakephp"
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.0",
|
"php": ">=5.3.0"
|
||||||
"ext-mcrypt": "*"
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-openssl": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption",
|
||||||
|
"ext-mcrypt": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^3.7",
|
"phpunit/phpunit": "^3.7",
|
||||||
|
|
|
@ -45,9 +45,9 @@ class SessionComponent extends Component {
|
||||||
*
|
*
|
||||||
* In your controller: $this->Session->write('Controller.sessKey', 'session value');
|
* In your controller: $this->Session->write('Controller.sessKey', 'session value');
|
||||||
*
|
*
|
||||||
* @param string $name The name of the key your are setting in the session.
|
* @param string|array $name The name of the key your are setting in the session.
|
||||||
* This should be in a Controller.key format for better organizing
|
* This should be in a Controller.key format for better organizing
|
||||||
* @param string $value The value you want to store in a session.
|
* @param string|array $value The value you want to store in a session.
|
||||||
* @return bool Success
|
* @return bool Success
|
||||||
* @link https://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::write
|
* @link https://book.cakephp.org/2.0/en/core-libraries/components/sessions.html#SessionComponent::write
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -591,7 +591,7 @@ class App {
|
||||||
*
|
*
|
||||||
* @param string|array $type The type of Class if passed as a string, or all params can be passed as
|
* @param string|array $type The type of Class if passed as a string, or all params can be passed as
|
||||||
* a single array to $type.
|
* a single array to $type.
|
||||||
* @param string $name Name of the Class or a unique name for the file
|
* @param string|array $name Name of the Class or a unique name for the file
|
||||||
* @param bool|array $parent boolean true if Class Parent should be searched, accepts key => value
|
* @param bool|array $parent boolean true if Class Parent should be searched, accepts key => value
|
||||||
* array('parent' => $parent, 'file' => $file, 'search' => $search, 'ext' => '$ext');
|
* array('parent' => $parent, 'file' => $file, 'search' => $search, 'ext' => '$ext');
|
||||||
* $ext allows setting the extension of the file name
|
* $ext allows setting the extension of the file name
|
||||||
|
|
|
@ -137,6 +137,7 @@ class L10n {
|
||||||
/* Latvian */ 'lav' => 'lv',
|
/* Latvian */ 'lav' => 'lv',
|
||||||
/* Limburgish */ 'lim' => 'li',
|
/* Limburgish */ 'lim' => 'li',
|
||||||
/* Lithuanian */ 'lit' => 'lt',
|
/* Lithuanian */ 'lit' => 'lt',
|
||||||
|
/* Luxembourgish */ 'ltz' => 'lb',
|
||||||
/* Macedonian */ 'mkd' => 'mk',
|
/* Macedonian */ 'mkd' => 'mk',
|
||||||
/* Macedonian - bibliographic */ 'mac' => 'mk',
|
/* Macedonian - bibliographic */ 'mac' => 'mk',
|
||||||
/* Malaysian */ 'msa' => 'ms',
|
/* Malaysian */ 'msa' => 'ms',
|
||||||
|
@ -284,6 +285,7 @@ class L10n {
|
||||||
'ko-kp' => array('language' => 'Korea (North)', 'locale' => 'ko_kp', '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'),
|
'ko-kr' => array('language' => 'Korea (South)', 'locale' => 'ko_kr', 'localeFallback' => 'kor', 'charset' => 'kr', 'direction' => 'ltr'),
|
||||||
'koi8-r' => array('language' => 'Russian', 'locale' => 'koi8_r', 'localeFallback' => 'rus', 'charset' => 'koi8-r', 'direction' => 'ltr'),
|
'koi8-r' => array('language' => 'Russian', 'locale' => 'koi8_r', 'localeFallback' => 'rus', 'charset' => 'koi8-r', 'direction' => 'ltr'),
|
||||||
|
'lb' => array('language' => 'Luxembourgish', 'locale' => 'ltz', 'localeFallback' => 'ltz', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'li' => array('language' => 'Limburgish', 'locale' => 'lim', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'li' => array('language' => 'Limburgish', 'locale' => 'lim', 'localeFallback' => 'nld', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'lt' => array('language' => 'Lithuanian', 'locale' => 'lit', 'localeFallback' => 'lit', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
'lv' => array('language' => 'Latvian', 'locale' => 'lav', 'localeFallback' => 'lav', 'charset' => 'utf-8', 'direction' => 'ltr'),
|
||||||
|
|
|
@ -344,7 +344,7 @@ class TranslateBehavior extends ModelBehavior {
|
||||||
public function afterFind(Model $Model, $results, $primary = false) {
|
public function afterFind(Model $Model, $results, $primary = false) {
|
||||||
$Model->virtualFields = $this->runtime[$Model->alias]['virtualFields'];
|
$Model->virtualFields = $this->runtime[$Model->alias]['virtualFields'];
|
||||||
|
|
||||||
$this->runtime[$Model->alias]['virtualFields'] = $this->runtime[$Model->alias]['fields'] = array();
|
$this->runtime[$Model->alias]['virtualFields'] = array();
|
||||||
if (!empty($this->runtime[$Model->alias]['restoreFields'])) {
|
if (!empty($this->runtime[$Model->alias]['restoreFields'])) {
|
||||||
$this->runtime[$Model->alias]['fields'] = $this->runtime[$Model->alias]['restoreFields'];
|
$this->runtime[$Model->alias]['fields'] = $this->runtime[$Model->alias]['restoreFields'];
|
||||||
unset($this->runtime[$Model->alias]['restoreFields']);
|
unset($this->runtime[$Model->alias]['restoreFields']);
|
||||||
|
|
|
@ -432,7 +432,7 @@ class CakeSession {
|
||||||
* Writes value to given session variable name.
|
* Writes value to given session variable name.
|
||||||
*
|
*
|
||||||
* @param string|array $name Name of variable
|
* @param string|array $name Name of variable
|
||||||
* @param string $value Value to write
|
* @param string|array $value Value to write
|
||||||
* @return bool True if the write was successful, false if the write failed
|
* @return bool True if the write was successful, false if the write failed
|
||||||
*/
|
*/
|
||||||
public static function write($name, $value = null) {
|
public static function write($name, $value = null) {
|
||||||
|
|
|
@ -109,7 +109,7 @@ class DboSource extends DataSource {
|
||||||
/**
|
/**
|
||||||
* Result
|
* Result
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array|PDOStatement
|
||||||
*/
|
*/
|
||||||
protected $_result = null;
|
protected $_result = null;
|
||||||
|
|
||||||
|
@ -1076,7 +1076,7 @@ class DboSource extends DataSource {
|
||||||
|
|
||||||
for ($i = 0; $i < $count; $i++) {
|
for ($i = 0; $i < $count; $i++) {
|
||||||
$schema = $Model->schema();
|
$schema = $Model->schema();
|
||||||
$valueInsert[] = $this->value($values[$i], $Model->getColumnType($fields[$i]), isset($schema[$fields[$i]]) ? $schema[$fields[$i]]['null'] : true);
|
$valueInsert[] = $this->value($values[$i], $Model->getColumnType($fields[$i]), isset($schema[$fields[$i]]['null']) ? $schema[$fields[$i]]['null'] : true);
|
||||||
$fieldInsert[] = $this->name($fields[$i]);
|
$fieldInsert[] = $this->name($fields[$i]);
|
||||||
if ($fields[$i] === $Model->primaryKey) {
|
if ($fields[$i] === $Model->primaryKey) {
|
||||||
$id = $values[$i];
|
$id = $values[$i];
|
||||||
|
@ -1566,23 +1566,25 @@ class DboSource extends DataSource {
|
||||||
// Make one pass through children and collect by parent key
|
// Make one pass through children and collect by parent key
|
||||||
// Make second pass through parents and associate children
|
// Make second pass through parents and associate children
|
||||||
$mergedByFK = array();
|
$mergedByFK = array();
|
||||||
foreach ($assocResultSet as $data) {
|
if (is_array($assocResultSet)) {
|
||||||
$fk = $data[$association][$foreignKey];
|
foreach ($assocResultSet as $data) {
|
||||||
if (! array_key_exists($fk, $mergedByFK)) {
|
$fk = $data[$association][$foreignKey];
|
||||||
$mergedByFK[$fk] = array();
|
if (! array_key_exists($fk, $mergedByFK)) {
|
||||||
}
|
$mergedByFK[$fk] = array();
|
||||||
if (count($data) > 1) {
|
}
|
||||||
$data = array_merge($data[$association], $data);
|
if (count($data) > 1) {
|
||||||
unset($data[$association]);
|
$data = array_merge($data[$association], $data);
|
||||||
foreach ($data as $key => $name) {
|
unset($data[$association]);
|
||||||
if (is_numeric($key)) {
|
foreach ($data as $key => $name) {
|
||||||
$data[$association][] = $name;
|
if (is_numeric($key)) {
|
||||||
unset($data[$key]);
|
$data[$association][] = $name;
|
||||||
}
|
unset($data[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$mergedByFK[$fk][] = $data;
|
||||||
|
} else {
|
||||||
|
$mergedByFK[$fk][] = $data[$association];
|
||||||
}
|
}
|
||||||
$mergedByFK[$fk][] = $data;
|
|
||||||
} else {
|
|
||||||
$mergedByFK[$fk][] = $data[$association];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2175,7 +2177,7 @@ class DboSource extends DataSource {
|
||||||
$update = $quoted . ' = ';
|
$update = $quoted . ' = ';
|
||||||
|
|
||||||
if ($quoteValues) {
|
if ($quoteValues) {
|
||||||
$update .= $this->value($value, $Model->getColumnType($field), isset($schema[$field]) ? $schema[$field]['null'] : true);
|
$update .= $this->value($value, $Model->getColumnType($field), isset($schema[$field]['null']) ? $schema[$field]['null'] : true);
|
||||||
} elseif ($Model->getColumnType($field) === 'boolean' && (is_int($value) || is_bool($value))) {
|
} elseif ($Model->getColumnType($field) === 'boolean' && (is_int($value) || is_bool($value))) {
|
||||||
$update .= $this->boolean($value, true);
|
$update .= $this->boolean($value, true);
|
||||||
} elseif (!$alias) {
|
} elseif (!$alias) {
|
||||||
|
@ -2576,7 +2578,12 @@ class DboSource extends DataSource {
|
||||||
$virtual = array();
|
$virtual = array();
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $field) {
|
||||||
$virtualField = $this->name($alias . $this->virtualFieldSeparator . $field);
|
$virtualField = $this->name($alias . $this->virtualFieldSeparator . $field);
|
||||||
$expression = $this->_quoteFields($Model->getVirtualField($field));
|
$virtualFieldExpression = $Model->getVirtualField($field);
|
||||||
|
if (is_object($virtualFieldExpression) && $virtualFieldExpression->type == 'expression') {
|
||||||
|
$expression = $virtualFieldExpression->value;
|
||||||
|
} else {
|
||||||
|
$expression = $this->_quoteFields($virtualFieldExpression);
|
||||||
|
}
|
||||||
$virtual[] = '(' . $expression . ") {$this->alias} {$virtualField}";
|
$virtual[] = '(' . $expression . ") {$this->alias} {$virtualField}";
|
||||||
}
|
}
|
||||||
return $virtual;
|
return $virtual;
|
||||||
|
@ -2885,7 +2892,12 @@ class DboSource extends DataSource {
|
||||||
|
|
||||||
if ($Model !== null) {
|
if ($Model !== null) {
|
||||||
if ($Model->isVirtualField($key)) {
|
if ($Model->isVirtualField($key)) {
|
||||||
$key = $this->_quoteFields($Model->getVirtualField($key));
|
$virtualField = $Model->getVirtualField($key);
|
||||||
|
if (is_object($virtualField) && $virtualField->type == 'expression') {
|
||||||
|
$key = $virtualField->value;
|
||||||
|
} else {
|
||||||
|
$key = $this->_quoteFields($virtualField);
|
||||||
|
}
|
||||||
$virtual = true;
|
$virtual = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3034,12 +3046,12 @@ class DboSource extends DataSource {
|
||||||
if (!is_array($keys)) {
|
if (!is_array($keys)) {
|
||||||
$keys = array($keys);
|
$keys = array($keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
$keys = array_filter($keys);
|
$keys = array_filter($keys);
|
||||||
|
|
||||||
$result = array();
|
$result = array();
|
||||||
while (!empty($keys)) {
|
while (!empty($keys)) {
|
||||||
list($key, $dir) = each($keys);
|
$key = key($keys);
|
||||||
|
$dir = current($keys);
|
||||||
array_shift($keys);
|
array_shift($keys);
|
||||||
|
|
||||||
if (is_numeric($key)) {
|
if (is_numeric($key)) {
|
||||||
|
|
|
@ -1648,7 +1648,7 @@ class Model extends CakeObject implements CakeEventListener {
|
||||||
*
|
*
|
||||||
* @param string $name The name of the field to get.
|
* @param string $name The name of the field to get.
|
||||||
* @param array $conditions SQL conditions (defaults to NULL).
|
* @param array $conditions SQL conditions (defaults to NULL).
|
||||||
* @param string $order SQL ORDER BY fragment.
|
* @param string|array $order SQL ORDER BY fragment.
|
||||||
* @return string|false Field content, or false if not found.
|
* @return string|false Field content, or false if not found.
|
||||||
* @link https://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-field
|
* @link https://book.cakephp.org/2.0/en/models/retrieving-your-data.html#model-field
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -594,7 +594,7 @@ class ModelValidator implements ArrayAccess, IteratorAggregate, Countable {
|
||||||
$this->_parseRules();
|
$this->_parseRules();
|
||||||
if ($rule === null) {
|
if ($rule === null) {
|
||||||
unset($this->_fields[$field]);
|
unset($this->_fields[$field]);
|
||||||
} else {
|
} elseif (array_key_exists($field, $this->_fields)) {
|
||||||
$this->_fields[$field]->removeRule($rule);
|
$this->_fields[$field]->removeRule($rule);
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
|
|
|
@ -589,7 +589,7 @@ class CakeEmail {
|
||||||
*/
|
*/
|
||||||
protected function _setEmail($varName, $email, $name) {
|
protected function _setEmail($varName, $email, $name) {
|
||||||
if (!is_array($email)) {
|
if (!is_array($email)) {
|
||||||
$this->_validateEmail($email);
|
$this->_validateEmail($email, $varName);
|
||||||
if ($name === null) {
|
if ($name === null) {
|
||||||
$name = $email;
|
$name = $email;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +601,7 @@ class CakeEmail {
|
||||||
if (is_int($key)) {
|
if (is_int($key)) {
|
||||||
$key = $value;
|
$key = $value;
|
||||||
}
|
}
|
||||||
$this->_validateEmail($key);
|
$this->_validateEmail($key, $varName);
|
||||||
$list[$key] = $value;
|
$list[$key] = $value;
|
||||||
}
|
}
|
||||||
$this->{$varName} = $list;
|
$this->{$varName} = $list;
|
||||||
|
@ -611,11 +611,12 @@ class CakeEmail {
|
||||||
/**
|
/**
|
||||||
* Validate email address
|
* Validate email address
|
||||||
*
|
*
|
||||||
* @param string $email Email
|
* @param string $email Email address to validate
|
||||||
|
* @param string $context Which property was set
|
||||||
* @return void
|
* @return void
|
||||||
* @throws SocketException If email address does not validate
|
* @throws SocketException If email address does not validate
|
||||||
*/
|
*/
|
||||||
protected function _validateEmail($email) {
|
protected function _validateEmail($email, $context) {
|
||||||
if ($this->_emailPattern === null) {
|
if ($this->_emailPattern === null) {
|
||||||
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||||
return;
|
return;
|
||||||
|
@ -623,7 +624,10 @@ class CakeEmail {
|
||||||
} elseif (preg_match($this->_emailPattern, $email)) {
|
} elseif (preg_match($this->_emailPattern, $email)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new SocketException(__d('cake_dev', 'Invalid email: "%s"', $email));
|
if ($email == '') {
|
||||||
|
throw new SocketException(__d('cake_dev', 'The email set for "%s" is empty.', $context));
|
||||||
|
}
|
||||||
|
throw new SocketException(__d('cake_dev', 'Invalid email set for "%s". You passed "%s".', $context, $email));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -659,7 +663,7 @@ class CakeEmail {
|
||||||
*/
|
*/
|
||||||
protected function _addEmail($varName, $email, $name) {
|
protected function _addEmail($varName, $email, $name) {
|
||||||
if (!is_array($email)) {
|
if (!is_array($email)) {
|
||||||
$this->_validateEmail($email);
|
$this->_validateEmail($email, $varName);
|
||||||
if ($name === null) {
|
if ($name === null) {
|
||||||
$name = $email;
|
$name = $email;
|
||||||
}
|
}
|
||||||
|
@ -671,7 +675,7 @@ class CakeEmail {
|
||||||
if (is_int($key)) {
|
if (is_int($key)) {
|
||||||
$key = $value;
|
$key = $value;
|
||||||
}
|
}
|
||||||
$this->_validateEmail($key);
|
$this->_validateEmail($key, $varName);
|
||||||
$list[$key] = $value;
|
$list[$key] = $value;
|
||||||
}
|
}
|
||||||
$this->{$varName} = array_merge($this->{$varName}, $list);
|
$this->{$varName} = array_merge($this->{$varName}, $list);
|
||||||
|
@ -788,7 +792,7 @@ class CakeEmail {
|
||||||
}
|
}
|
||||||
if ($this->_messageId !== false) {
|
if ($this->_messageId !== false) {
|
||||||
if ($this->_messageId === true) {
|
if ($this->_messageId === true) {
|
||||||
$headers['Message-ID'] = '<' . str_replace('-', '', CakeText::UUID()) . '@' . $this->_domain . '>';
|
$headers['Message-ID'] = '<' . str_replace('-', '', CakeText::uuid()) . '@' . $this->_domain . '>';
|
||||||
} else {
|
} else {
|
||||||
$headers['Message-ID'] = $this->_messageId;
|
$headers['Message-ID'] = $this->_messageId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1144,6 +1144,16 @@ class TranslateBehaviorTest extends CakeTestCase {
|
||||||
$TestModel->bindTranslation($translations);
|
$TestModel->bindTranslation($translations);
|
||||||
|
|
||||||
$result = $TestModel->find('first');
|
$result = $TestModel->find('first');
|
||||||
|
$TestModel->find('first', array(
|
||||||
|
'fields' => array(
|
||||||
|
'TranslatedItem.title',
|
||||||
|
),
|
||||||
|
));
|
||||||
|
$TestModel->find('first', array(
|
||||||
|
'fields' => array(
|
||||||
|
'TranslatedItem.title',
|
||||||
|
),
|
||||||
|
));
|
||||||
$this->assertArrayHasKey('Title', $result);
|
$this->assertArrayHasKey('Title', $result);
|
||||||
$this->assertArrayHasKey('content', $result['Title'][0]);
|
$this->assertArrayHasKey('content', $result['Title'][0]);
|
||||||
$this->assertArrayNotHasKey('title', $result);
|
$this->assertArrayNotHasKey('title', $result);
|
||||||
|
|
|
@ -1650,6 +1650,42 @@ class DboSourceTest extends CakeTestCase {
|
||||||
$this->assertEquals($expected, $result[0]);
|
$this->assertEquals($expected, $result[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test conditionKeysToString() with virtual field
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testConditionKeysToStringVirtualFieldExpression() {
|
||||||
|
$Article = ClassRegistry::init('Article');
|
||||||
|
$Article->virtualFields = array(
|
||||||
|
'extra' => $Article->getDataSource()->expression('something virtual')
|
||||||
|
);
|
||||||
|
$conn = $this->getMock('MockPDO', array('quote'));
|
||||||
|
$db = new DboTestSource();
|
||||||
|
$db->setConnection($conn);
|
||||||
|
|
||||||
|
$conn->expects($this->at(0))
|
||||||
|
->method('quote')
|
||||||
|
->will($this->returnValue('just text'));
|
||||||
|
|
||||||
|
$conditions = array('Article.extra' => 'just text');
|
||||||
|
$result = $db->conditionKeysToString($conditions, true, $Article);
|
||||||
|
$expected = "(" . $Article->virtualFields['extra']->value . ") = just text";
|
||||||
|
$this->assertEquals($expected, $result[0]);
|
||||||
|
|
||||||
|
$conn->expects($this->at(0))
|
||||||
|
->method('quote')
|
||||||
|
->will($this->returnValue('just text'));
|
||||||
|
$conn->expects($this->at(1))
|
||||||
|
->method('quote')
|
||||||
|
->will($this->returnValue('other text'));
|
||||||
|
|
||||||
|
$conditions = array('Article.extra' => array('just text', 'other text'));
|
||||||
|
$result = $db->conditionKeysToString($conditions, true, $Article);
|
||||||
|
$expected = "(" . $Article->virtualFields['extra']->value . ") IN (just text, other text)";
|
||||||
|
$this->assertEquals($expected, $result[0]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test conditionKeysToString() with virtual field
|
* Test conditionKeysToString() with virtual field
|
||||||
*
|
*
|
||||||
|
|
|
@ -2007,6 +2007,9 @@ class ModelValidationTest extends BaseModelTest {
|
||||||
$this->assertTrue(isset($Validator['other']));
|
$this->assertTrue(isset($Validator['other']));
|
||||||
$this->assertFalse(isset($Validator['other']['numeric']));
|
$this->assertFalse(isset($Validator['other']['numeric']));
|
||||||
$this->assertTrue(isset($Validator['other']['between']));
|
$this->assertTrue(isset($Validator['other']['between']));
|
||||||
|
|
||||||
|
$Validator->remove('other');
|
||||||
|
$Validator->remove('other', 'between');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -334,23 +334,34 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
/**
|
/**
|
||||||
* testBuildInvalidData
|
* testBuildInvalidData
|
||||||
*
|
*
|
||||||
* @dataProvider invalidEmails
|
|
||||||
* @expectedException SocketException
|
* @expectedException SocketException
|
||||||
|
* @expectedExceptionMessage The email set for "_to" is empty.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testInvalidEmail($value) {
|
public function testInvalidEmail() {
|
||||||
$this->CakeEmail->to($value);
|
$this->CakeEmail->to('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testBuildInvalidData
|
* testBuildInvalidData
|
||||||
*
|
*
|
||||||
* @dataProvider invalidEmails
|
|
||||||
* @expectedException SocketException
|
* @expectedException SocketException
|
||||||
|
* @expectedExceptionMessage Invalid email set for "_from". You passed "cake.@"
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testInvalidEmailAdd($value) {
|
public function testInvalidFrom() {
|
||||||
$this->CakeEmail->addTo($value);
|
$this->CakeEmail->from('cake.@');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* testBuildInvalidData
|
||||||
|
*
|
||||||
|
* @expectedException SocketException
|
||||||
|
* @expectedExceptionMessage Invalid email set for "_to". You passed "1"
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testInvalidEmailAdd() {
|
||||||
|
$this->CakeEmail->addTo('1');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,7 +434,7 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @expectedException SocketException
|
* @expectedException SocketException
|
||||||
* @expectedExceptionMessage Invalid email: "fail.@example.com"
|
* @expectedExceptionMessage Invalid email set for "_to". You passed "fail.@example.com"
|
||||||
*/
|
*/
|
||||||
public function testUnsetEmailPattern() {
|
public function testUnsetEmailPattern() {
|
||||||
$email = new CakeEmail();
|
$email = new CakeEmail();
|
||||||
|
|
|
@ -445,7 +445,8 @@ class CakeTestCaseTest extends CakeTestCase {
|
||||||
), App::RESET);
|
), App::RESET);
|
||||||
CakePlugin::load('TestPlugin');
|
CakePlugin::load('TestPlugin');
|
||||||
ConnectionManager::create('test_secondary', array(
|
ConnectionManager::create('test_secondary', array(
|
||||||
'datasource' => 'Database/TestLocalDriver'
|
'datasource' => 'Database/TestLocalDriver',
|
||||||
|
'prefix' => ''
|
||||||
));
|
));
|
||||||
$post = $this->getMockForModel('SecondaryPost', array('save'));
|
$post = $this->getMockForModel('SecondaryPost', array('save'));
|
||||||
$this->assertEquals('test_secondary', $post->useDbConfig);
|
$this->assertEquals('test_secondary', $post->useDbConfig);
|
||||||
|
|
|
@ -29,6 +29,26 @@ class SecurityTest extends CakeTestCase {
|
||||||
*/
|
*/
|
||||||
public $sut = null;
|
public $sut = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setUp method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUp() {
|
||||||
|
parent::setUp();
|
||||||
|
Configure::delete('Security.useOpenSsl');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tearDown method
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function tearDown() {
|
||||||
|
parent::tearDown();
|
||||||
|
Configure::delete('Security.useOpenSsl');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testInactiveMins method
|
* testInactiveMins method
|
||||||
*
|
*
|
||||||
|
@ -337,6 +357,54 @@ class SecurityTest extends CakeTestCase {
|
||||||
$this->assertEquals($txt, Security::decrypt($result, $key));
|
$this->assertEquals($txt, Security::decrypt($result, $key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that encrypted strings are compatible between the mcrypt and openssl engine.
|
||||||
|
*
|
||||||
|
* @dataProvider plainTextProvider
|
||||||
|
* @param string $txt Plain text to be encrypted.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testEncryptDecryptCompatibility($txt) {
|
||||||
|
$this->skipIf(!extension_loaded('mcrypt'), 'This test requires mcrypt to be installed');
|
||||||
|
$this->skipIf(!extension_loaded('openssl'), 'This test requires openssl to be installed');
|
||||||
|
$this->skipIf(version_compare(PHP_VERSION, '5.3.3', '<'), 'This test requires PHP 5.3.3 or greater');
|
||||||
|
|
||||||
|
$key = '12345678901234567890123456789012';
|
||||||
|
|
||||||
|
Configure::write('Security.useOpenSsl', false);
|
||||||
|
$mcrypt = Security::encrypt($txt, $key);
|
||||||
|
|
||||||
|
Configure::write('Security.useOpenSsl', true);
|
||||||
|
$openssl = Security::encrypt($txt, $key);
|
||||||
|
|
||||||
|
$this->assertEquals(strlen($mcrypt), strlen($openssl));
|
||||||
|
|
||||||
|
Configure::write('Security.useOpenSsl', false);
|
||||||
|
$this->assertEquals($txt, Security::decrypt($mcrypt, $key));
|
||||||
|
$this->assertEquals($txt, Security::decrypt($openssl, $key));
|
||||||
|
|
||||||
|
Configure::write('Security.useOpenSsl', true);
|
||||||
|
$this->assertEquals($txt, Security::decrypt($mcrypt, $key));
|
||||||
|
$this->assertEquals($txt, Security::decrypt($openssl, $key));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for testEncryptDecryptCompatibility
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function plainTextProvider() {
|
||||||
|
return array(
|
||||||
|
array(''),
|
||||||
|
array('abcdefg'),
|
||||||
|
array('1234567890123456'),
|
||||||
|
array('The quick brown fox'),
|
||||||
|
array('12345678901234567890123456789012'),
|
||||||
|
array('The quick brown fox jumped over the lazy dog.'),
|
||||||
|
array('何らかのマルチバイト文字列'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that changing the key causes decryption to fail.
|
* Test that changing the key causes decryption to fail.
|
||||||
*
|
*
|
||||||
|
|
|
@ -866,7 +866,8 @@ abstract class CakeTestCase extends PHPUnit_Framework_TestCase {
|
||||||
$availableDs = array_keys(ConnectionManager::enumConnectionObjects());
|
$availableDs = array_keys(ConnectionManager::enumConnectionObjects());
|
||||||
|
|
||||||
if ($mock->useDbConfig !== 'test' && in_array('test_' . $mock->useDbConfig, $availableDs)) {
|
if ($mock->useDbConfig !== 'test' && in_array('test_' . $mock->useDbConfig, $availableDs)) {
|
||||||
$mock->setDataSource('test_' . $mock->useDbConfig);
|
$mock->useDbConfig = 'test_' . $mock->useDbConfig;
|
||||||
|
$mock->setDataSource($mock->useDbConfig);
|
||||||
} else {
|
} else {
|
||||||
$mock->useDbConfig = 'test';
|
$mock->useDbConfig = 'test';
|
||||||
$mock->setDataSource('test');
|
$mock->setDataSource('test');
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
if (!class_exists('PHPUnit_TextUI_TestRunner')) {
|
if (!class_exists('PHPUnit_TextUI_TestRunner')) {
|
||||||
require_once 'PHPUnit/TextUI/TestRunner.php';
|
require_once 'PHPUnit/TextUI/TestRunner.php';
|
||||||
}
|
}
|
||||||
|
if (class_exists('SebastianBergmann\CodeCoverage\CodeCoverage')) {
|
||||||
|
class_alias('SebastianBergmann\CodeCoverage\CodeCoverage', 'PHP_CodeCoverage');
|
||||||
|
class_alias('SebastianBergmann\CodeCoverage\Report\Text', 'PHP_CodeCoverage_Report_Text');
|
||||||
|
class_alias('SebastianBergmann\CodeCoverage\Report\PHP', 'PHP_CodeCoverage_Report_PHP');
|
||||||
|
class_alias('SebastianBergmann\CodeCoverage\Report\Clover', 'PHP_CodeCoverage_Report_Clover');
|
||||||
|
class_alias('SebastianBergmann\CodeCoverage\Report\Html\Facade', 'PHP_CodeCoverage_Report_HTML');
|
||||||
|
class_alias('SebastianBergmann\CodeCoverage\Exception', 'PHP_CodeCoverage_Exception');
|
||||||
|
}
|
||||||
|
|
||||||
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
|
App::uses('CakeFixtureManager', 'TestSuite/Fixture');
|
||||||
|
|
||||||
|
|
|
@ -184,9 +184,12 @@ class Security {
|
||||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||||
return openssl_random_pseudo_bytes($length);
|
return openssl_random_pseudo_bytes($length);
|
||||||
}
|
}
|
||||||
|
if (function_exists('mcrypt_create_iv')) {
|
||||||
|
return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||||
|
}
|
||||||
trigger_error(
|
trigger_error(
|
||||||
'You do not have a safe source of random data available. ' .
|
'You do not have a safe source of random data available. ' .
|
||||||
'Install either the openssl extension, or paragonie/random_compat. ' .
|
'Install either the openssl extension, the mcrypt extension, or paragonie/random_compat. ' .
|
||||||
'Falling back to an insecure random source.',
|
'Falling back to an insecure random source.',
|
||||||
E_USER_WARNING
|
E_USER_WARNING
|
||||||
);
|
);
|
||||||
|
@ -206,7 +209,7 @@ class Security {
|
||||||
* for sensitive data. Additionally this method does *not* work in environments
|
* for sensitive data. Additionally this method does *not* work in environments
|
||||||
* where suhosin is enabled.
|
* where suhosin is enabled.
|
||||||
*
|
*
|
||||||
* Instead you should use Security::rijndael() when you need strong
|
* Instead you should use Security::encrypt() when you need strong
|
||||||
* encryption.
|
* encryption.
|
||||||
*
|
*
|
||||||
* @param string $text Encrypted string to decrypt, normal string to encrypt
|
* @param string $text Encrypted string to decrypt, normal string to encrypt
|
||||||
|
@ -349,12 +352,24 @@ class Security {
|
||||||
// Generate the encryption and hmac key.
|
// Generate the encryption and hmac key.
|
||||||
$key = substr(hash('sha256', $key . $hmacSalt), 0, 32);
|
$key = substr(hash('sha256', $key . $hmacSalt), 0, 32);
|
||||||
|
|
||||||
$algorithm = MCRYPT_RIJNDAEL_128;
|
if (Configure::read('Security.useOpenSsl')) {
|
||||||
$mode = MCRYPT_MODE_CBC;
|
$method = 'AES-256-CBC';
|
||||||
|
$ivSize = openssl_cipher_iv_length($method);
|
||||||
|
$iv = openssl_random_pseudo_bytes($ivSize);
|
||||||
|
$padLength = (int)ceil((strlen($plain) ?: 1) / $ivSize) * $ivSize;
|
||||||
|
$ciphertext = openssl_encrypt(str_pad($plain, $padLength, "\0"), $method, $key, true, $iv);
|
||||||
|
// Remove the PKCS#7 padding block for compatibility with mcrypt.
|
||||||
|
// Since we have padded the provided data with \0, the final block contains only padded bytes.
|
||||||
|
// So it can be removed safely.
|
||||||
|
$ciphertext = $iv . substr($ciphertext, 0, -$ivSize);
|
||||||
|
} else {
|
||||||
|
$algorithm = MCRYPT_RIJNDAEL_128;
|
||||||
|
$mode = MCRYPT_MODE_CBC;
|
||||||
|
$ivSize = mcrypt_get_iv_size($algorithm, $mode);
|
||||||
|
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
|
||||||
|
$ciphertext = $iv . mcrypt_encrypt($algorithm, $key, $plain, $mode, $iv);
|
||||||
|
}
|
||||||
|
|
||||||
$ivSize = mcrypt_get_iv_size($algorithm, $mode);
|
|
||||||
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM);
|
|
||||||
$ciphertext = $iv . mcrypt_encrypt($algorithm, $key, $plain, $mode, $iv);
|
|
||||||
$hmac = hash_hmac('sha256', $ciphertext, $key);
|
$hmac = hash_hmac('sha256', $ciphertext, $key);
|
||||||
return $hmac . $ciphertext;
|
return $hmac . $ciphertext;
|
||||||
}
|
}
|
||||||
|
@ -404,13 +419,23 @@ class Security {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$algorithm = MCRYPT_RIJNDAEL_128;
|
if (Configure::read('Security.useOpenSsl')) {
|
||||||
$mode = MCRYPT_MODE_CBC;
|
$method = 'AES-256-CBC';
|
||||||
$ivSize = mcrypt_get_iv_size($algorithm, $mode);
|
$ivSize = openssl_cipher_iv_length($method);
|
||||||
|
$iv = substr($cipher, 0, $ivSize);
|
||||||
|
$cipher = substr($cipher, $ivSize);
|
||||||
|
// Regenerate PKCS#7 padding block
|
||||||
|
$padding = openssl_encrypt('', $method, $key, true, substr($cipher, -$ivSize));
|
||||||
|
$plain = openssl_decrypt($cipher . $padding, $method, $key, true, $iv);
|
||||||
|
} else {
|
||||||
|
$algorithm = MCRYPT_RIJNDAEL_128;
|
||||||
|
$mode = MCRYPT_MODE_CBC;
|
||||||
|
$ivSize = mcrypt_get_iv_size($algorithm, $mode);
|
||||||
|
$iv = substr($cipher, 0, $ivSize);
|
||||||
|
$cipher = substr($cipher, $ivSize);
|
||||||
|
$plain = mcrypt_decrypt($algorithm, $key, $cipher, $mode, $iv);
|
||||||
|
}
|
||||||
|
|
||||||
$iv = substr($cipher, 0, $ivSize);
|
|
||||||
$cipher = substr($cipher, $ivSize);
|
|
||||||
$plain = mcrypt_decrypt($algorithm, $key, $cipher, $mode, $iv);
|
|
||||||
return rtrim($plain, "\0");
|
return rtrim($plain, "\0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
// @license https://opensource.org/licenses/mit-license.php MIT License
|
// @license https://opensource.org/licenses/mit-license.php MIT License
|
||||||
// +--------------------------------------------------------------------------------------------+ //
|
// +--------------------------------------------------------------------------------------------+ //
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
2.10.7
|
2.10.11
|
||||||
|
|
Loading…
Reference in a new issue