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
aa6770fa45
8 changed files with 684 additions and 104 deletions
|
@ -26,9 +26,18 @@
|
|||
"cakephp/cakephp-codesniffer": "^1.0.0"
|
||||
},
|
||||
"config": {
|
||||
"vendor-dir": "vendors/"
|
||||
"vendor-dir": "vendors/",
|
||||
"process-timeout": 0
|
||||
},
|
||||
"bin": [
|
||||
"lib/Cake/Console/cake"
|
||||
]
|
||||
],
|
||||
"scripts": {
|
||||
"check": [
|
||||
"@cs-check",
|
||||
"@test"
|
||||
],
|
||||
"cs-check": "./vendors/bin/phpcs -p --extensions=php --standard=CakePHP ./lib/Cake",
|
||||
"test": "./lib/Cake/Console/cake test core AllTests --stderr"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,28 +147,45 @@ class TranslateBehavior extends ModelBehavior {
|
|||
$this->_joinTable = $joinTable;
|
||||
$this->_runtimeModel = $RuntimeModel;
|
||||
|
||||
if (is_string($query['fields']) && $query['fields'] === "COUNT(*) AS {$db->name('count')}") {
|
||||
$query['fields'] = "COUNT(DISTINCT({$db->name($Model->escapeField())})) {$db->alias}count";
|
||||
$query['joins'][] = array(
|
||||
'type' => $this->runtime[$Model->alias]['joinType'],
|
||||
'alias' => $RuntimeModel->alias,
|
||||
'table' => $joinTable,
|
||||
'conditions' => array(
|
||||
$Model->escapeField() => $db->identifier($RuntimeModel->escapeField('foreign_key')),
|
||||
$RuntimeModel->escapeField('model') => $Model->name,
|
||||
$RuntimeModel->escapeField('locale') => $locale
|
||||
)
|
||||
);
|
||||
$conditionFields = $this->_checkConditions($Model, $query);
|
||||
foreach ($conditionFields as $field) {
|
||||
$query = $this->_addJoin($Model, $query, $field, $field, $locale);
|
||||
if (is_string($query['fields'])) {
|
||||
if ($query['fields'] === "COUNT(*) AS {$db->name('count')}") {
|
||||
$query['fields'] = "COUNT(DISTINCT({$db->name($Model->escapeField())})) {$db->alias}count";
|
||||
$query['joins'][] = array(
|
||||
'type' => $this->runtime[$Model->alias]['joinType'],
|
||||
'alias' => $RuntimeModel->alias,
|
||||
'table' => $joinTable,
|
||||
'conditions' => array(
|
||||
$Model->escapeField() => $db->identifier($RuntimeModel->escapeField('foreign_key')),
|
||||
$RuntimeModel->escapeField('model') => $Model->name,
|
||||
$RuntimeModel->escapeField('locale') => $locale
|
||||
)
|
||||
);
|
||||
$conditionFields = $this->_checkConditions($Model, $query);
|
||||
foreach ($conditionFields as $field) {
|
||||
$query = $this->_addJoin($Model, $query, $field, $field, $locale);
|
||||
}
|
||||
unset($this->_joinTable, $this->_runtimeModel);
|
||||
return $query;
|
||||
} else {
|
||||
$query['fields'] = CakeText::tokenize($query['fields']);
|
||||
}
|
||||
unset($this->_joinTable, $this->_runtimeModel);
|
||||
return $query;
|
||||
} elseif (is_string($query['fields'])) {
|
||||
$query['fields'] = CakeText::tokenize($query['fields']);
|
||||
}
|
||||
$addFields = $this->_getFields($Model, $query);
|
||||
$this->runtime[$Model->alias]['virtualFields'] = $Model->virtualFields;
|
||||
$query = $this->_addAllJoins($Model, $query, $addFields);
|
||||
$this->runtime[$Model->alias]['beforeFind'] = $addFields;
|
||||
unset($this->_joinTable, $this->_runtimeModel);
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets fields to be retrieved.
|
||||
*
|
||||
* @param Model $Model The model being worked on.
|
||||
* @param array $query The query array to take fields from.
|
||||
* @return array The fields.
|
||||
*/
|
||||
protected function _getFields(Model $Model, $query) {
|
||||
$fields = array_merge(
|
||||
$this->settings[$Model->alias],
|
||||
$this->runtime[$Model->alias]['fields']
|
||||
|
@ -191,15 +208,24 @@ class TranslateBehavior extends ModelBehavior {
|
|||
}
|
||||
}
|
||||
}
|
||||
return $addFields;
|
||||
}
|
||||
|
||||
$this->runtime[$Model->alias]['virtualFields'] = $Model->virtualFields;
|
||||
/**
|
||||
* Appends all necessary joins for translated fields.
|
||||
*
|
||||
* @param Model $Model The model being worked on.
|
||||
* @param array $query The query array to append joins to.
|
||||
* @param array $addFields The fields being joined.
|
||||
* @return array The modified query
|
||||
*/
|
||||
protected function _addAllJoins(Model $Model, $query, $addFields) {
|
||||
$locale = $this->_getLocale($Model);
|
||||
if ($addFields) {
|
||||
foreach ($addFields as $_f => $field) {
|
||||
$aliasField = is_numeric($_f) ? $field : $_f;
|
||||
|
||||
foreach (array($aliasField, $Model->alias . '.' . $aliasField) as $_field) {
|
||||
$key = array_search($_field, (array)$query['fields']);
|
||||
|
||||
if ($key !== false) {
|
||||
unset($query['fields'][$key]);
|
||||
}
|
||||
|
@ -207,8 +233,6 @@ class TranslateBehavior extends ModelBehavior {
|
|||
$query = $this->_addJoin($Model, $query, $field, $aliasField, $locale);
|
||||
}
|
||||
}
|
||||
$this->runtime[$Model->alias]['beforeFind'] = $addFields;
|
||||
unset($this->_joinTable, $this->_runtimeModel);
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
@ -221,11 +245,26 @@ class TranslateBehavior extends ModelBehavior {
|
|||
* @return array The list of translated fields that are in the conditions.
|
||||
*/
|
||||
protected function _checkConditions(Model $Model, $query) {
|
||||
$conditionFields = array();
|
||||
if (empty($query['conditions']) || (!empty($query['conditions']) && !is_array($query['conditions']))) {
|
||||
return $conditionFields;
|
||||
return array();
|
||||
}
|
||||
foreach ($query['conditions'] as $col => $val) {
|
||||
return $this->_getConditionFields($Model, $query['conditions']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts condition field names recursively.
|
||||
*
|
||||
* @param Model $Model The model being read.
|
||||
* @param array $conditions The conditions array.
|
||||
* @return array The list of condition fields.
|
||||
*/
|
||||
protected function _getConditionFields(Model $Model, $conditions) {
|
||||
$conditionFields = array();
|
||||
foreach ($conditions as $col => $val) {
|
||||
if (is_array($val)) {
|
||||
$subConditionFields = $this->_getConditionFields($Model, $val);
|
||||
$conditionFields = array_merge($conditionFields, $subConditionFields);
|
||||
}
|
||||
foreach ($this->settings[$Model->alias] as $field => $assoc) {
|
||||
if (is_numeric($field)) {
|
||||
$field = $assoc;
|
||||
|
|
|
@ -359,7 +359,9 @@ class Mysql extends DboSource {
|
|||
if (in_array($fields[$column->Field]['type'], $this->fieldParameters['unsigned']['types'], true)) {
|
||||
$fields[$column->Field]['unsigned'] = $this->_unsigned($column->Type);
|
||||
}
|
||||
if (in_array($fields[$column->Field]['type'], array('timestamp', 'datetime')) && strtoupper($column->Default) === 'CURRENT_TIMESTAMP') {
|
||||
if (in_array($fields[$column->Field]['type'], array('timestamp', 'datetime')) &&
|
||||
in_array(strtoupper($column->Default), array('CURRENT_TIMESTAMP', 'CURRENT_TIMESTAMP()'))
|
||||
) {
|
||||
$fields[$column->Field]['default'] = null;
|
||||
}
|
||||
if (!empty($column->Key) && isset($this->index[$column->Key])) {
|
||||
|
|
|
@ -23,6 +23,8 @@ App::uses('PaginatorComponent', 'Controller/Component');
|
|||
App::uses('CakeRequest', 'Network');
|
||||
App::uses('CakeResponse', 'Network');
|
||||
|
||||
require_once dirname(dirname(dirname(__FILE__))) . DS . 'Model' . DS . 'models.php';
|
||||
|
||||
/**
|
||||
* PaginatorTestController class
|
||||
*
|
||||
|
@ -288,7 +290,8 @@ class PaginatorComponentTest extends CakeTestCase {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fixtures = array('core.post', 'core.comment', 'core.author');
|
||||
public $fixtures = array('core.post', 'core.comment', 'core.author',
|
||||
'core.translated_article', 'core.translate_article', 'core.user');
|
||||
|
||||
/**
|
||||
* setup
|
||||
|
@ -408,6 +411,116 @@ class PaginatorComponentTest extends CakeTestCase {
|
|||
$this->assertSame(2, $Controller->params['paging']['PaginatorControllerPost']['count']);
|
||||
}
|
||||
|
||||
public function testPaginateNotCondition() {
|
||||
$Controller = new PaginatorTestController($this->request);
|
||||
$Controller->uses = array('PaginatorControllerPost', 'PaginatorControllerComment');
|
||||
$Controller->request->params['pass'] = array('1');
|
||||
$Controller->request->query = array();
|
||||
$Controller->constructClasses();
|
||||
$Controller->Paginator->settings = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array('PaginatorAuthor.user' => 'mariano'),
|
||||
),
|
||||
);
|
||||
$result = $Controller->Paginator->paginate('PaginatorControllerPost');
|
||||
$this->assertEquals('larry', $result[0]['PaginatorAuthor']['user']);
|
||||
$this->assertCount(1, $result);
|
||||
}
|
||||
|
||||
public function testPaginateI18nConditionUser() {
|
||||
$Request = new CakeRequest('articles/index');
|
||||
$Controller = new PaginatorTestController($Request);
|
||||
$Controller->uses = array('TranslatedArticle');
|
||||
$Controller->constructClasses();
|
||||
$Controller->TranslatedArticle->locale = 'eng';
|
||||
$Controller->Paginator->settings = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'User.user' => 'mariano',
|
||||
),
|
||||
);
|
||||
$result = $Controller->Paginator->paginate('TranslatedArticle');
|
||||
$this->assertEquals('Title (eng) #1', $result[0]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('mariano', $result[0]['User']['user']);
|
||||
$this->assertEquals('Title (eng) #3', $result[1]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('mariano', $result[1]['User']['user']);
|
||||
$this->assertCount(2, $result);
|
||||
}
|
||||
|
||||
public function testPaginateI18nConditionTitle() {
|
||||
$Request = new CakeRequest('articles/index');
|
||||
$Controller = new PaginatorTestController($Request);
|
||||
$Controller->uses = array('TranslatedArticle');
|
||||
$Controller->constructClasses();
|
||||
$Controller->TranslatedArticle->locale = 'eng';
|
||||
$Controller->Paginator->settings = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'I18n__title.content' => 'Title (eng) #3',
|
||||
),
|
||||
);
|
||||
$result = $Controller->Paginator->paginate('TranslatedArticle');
|
||||
$this->assertEquals('Title (eng) #3', $result[0]['TranslatedArticle']['title']);
|
||||
$this->assertCount(1, $result);
|
||||
}
|
||||
|
||||
public function testPaginateI18nConditionNotTitle() {
|
||||
$Request = new CakeRequest('articles/index');
|
||||
$Controller = new PaginatorTestController($Request);
|
||||
$Controller->uses = array('TranslatedArticle');
|
||||
$Controller->constructClasses();
|
||||
$Controller->TranslatedArticle->locale = 'eng';
|
||||
$Controller->Paginator->settings = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'I18n__title.content !=' => '',
|
||||
),
|
||||
);
|
||||
$result = $Controller->Paginator->paginate('TranslatedArticle');
|
||||
$this->assertEquals('Title (eng) #1', $result[0]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('Title (eng) #2', $result[1]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('Title (eng) #3', $result[2]['TranslatedArticle']['title']);
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
|
||||
public function testPaginateI18nConditionNotTitleArraySyntax() {
|
||||
$Request = new CakeRequest('articles/index');
|
||||
$Controller = new PaginatorTestController($Request);
|
||||
$Controller->uses = array('TranslatedArticle');
|
||||
$Controller->constructClasses();
|
||||
$Controller->TranslatedArticle->locale = 'eng';
|
||||
$Controller->Paginator->settings = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
);
|
||||
$result = $Controller->Paginator->paginate('TranslatedArticle');
|
||||
$this->assertEquals('Title (eng) #1', $result[0]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('Title (eng) #2', $result[1]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('Title (eng) #3', $result[2]['TranslatedArticle']['title']);
|
||||
$this->assertCount(3, $result);
|
||||
}
|
||||
|
||||
public function testPaginateI18nConditionNotTitleWithLimit() {
|
||||
$Request = new CakeRequest('articles/index');
|
||||
$Controller = new PaginatorTestController($Request);
|
||||
$Controller->uses = array('TranslatedArticle');
|
||||
$Controller->constructClasses();
|
||||
$Controller->TranslatedArticle->locale = 'eng';
|
||||
$Controller->Paginator->settings = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'limit' => 2,
|
||||
);
|
||||
$result = $Controller->Paginator->paginate('TranslatedArticle');
|
||||
$this->assertEquals('Title (eng) #1', $result[0]['TranslatedArticle']['title']);
|
||||
$this->assertEquals('Title (eng) #2', $result[1]['TranslatedArticle']['title']);
|
||||
$this->assertCount(2, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that non-numeric values are rejected for page, and limit
|
||||
*
|
||||
|
|
|
@ -1443,4 +1443,166 @@ class TranslateBehaviorTest extends CakeTestCase {
|
|||
$this->assertEquals('name', $results[0]['TranslateTestModel']['field']);
|
||||
}
|
||||
|
||||
public function testBeforeFindAllI18nConditions() {
|
||||
$this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
|
||||
$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User');
|
||||
$TestModel = new TranslatedArticle();
|
||||
$TestModel->cacheQueries = false;
|
||||
$TestModel->locale = 'eng';
|
||||
$expected = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'fields' => null,
|
||||
'joins' => array(
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__title',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'TranslatedArticle.id' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => 'I18n__title.foreign_key',
|
||||
),
|
||||
'I18n__title.model' => 'TranslatedArticle',
|
||||
'I18n__title.field' => 'title',
|
||||
'I18n__title.locale' => 'eng',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__body',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'TranslatedArticle.id' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => 'I18n__body.foreign_key',
|
||||
),
|
||||
'I18n__body.model' => 'TranslatedArticle',
|
||||
'I18n__body.field' => 'body',
|
||||
'I18n__body.locale' => 'eng',
|
||||
),
|
||||
),
|
||||
),
|
||||
'limit' => 2,
|
||||
'offset' => null,
|
||||
'order' => array(
|
||||
'TranslatedArticle.id' => 'ASC',
|
||||
),
|
||||
'page' => 1,
|
||||
'group' => null,
|
||||
'callbacks' => true,
|
||||
'recursive' => 0,
|
||||
);
|
||||
$query = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array(
|
||||
'I18n__title.content' => '',
|
||||
),
|
||||
),
|
||||
'fields' => null,
|
||||
'joins' => array(),
|
||||
'limit' => 2,
|
||||
'offset' => null,
|
||||
'order' => array(
|
||||
'TranslatedArticle.id' => 'ASC',
|
||||
),
|
||||
'page' => 1,
|
||||
'group' => null,
|
||||
'callbacks' => true,
|
||||
'recursive' => 0,
|
||||
);
|
||||
$TranslateBehavior = ClassRegistry::getObject('TranslateBehavior');
|
||||
$result = $TranslateBehavior->beforeFind($TestModel, $query);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testBeforeFindCountI18nConditions() {
|
||||
$this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
|
||||
$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User');
|
||||
$TestModel = new TranslatedArticle();
|
||||
$TestModel->cacheQueries = false;
|
||||
$TestModel->locale = 'eng';
|
||||
$expected = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'fields' => 'COUNT(DISTINCT(`TranslatedArticle`.`id`)) AS count',
|
||||
'joins' => array(
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'TranslateArticleModel',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'`TranslatedArticle`.`id`' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => '`TranslateArticleModel`.`foreign_key`',
|
||||
),
|
||||
'`TranslateArticleModel`.`model`' => 'TranslatedArticle',
|
||||
'`TranslateArticleModel`.`locale`' => 'eng',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__title',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'TranslatedArticle.id' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => 'I18n__title.foreign_key',
|
||||
),
|
||||
'I18n__title.model' => 'TranslatedArticle',
|
||||
'I18n__title.field' => 'title',
|
||||
'I18n__title.locale' => 'eng',
|
||||
),
|
||||
),
|
||||
),
|
||||
'limit' => 2,
|
||||
'offset' => null,
|
||||
'order' => array(
|
||||
0 => false,
|
||||
),
|
||||
'page' => 1,
|
||||
'group' => null,
|
||||
'callbacks' => true,
|
||||
'recursive' => 0,
|
||||
);
|
||||
$query = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array(
|
||||
'I18n__title.content' => '',
|
||||
)
|
||||
),
|
||||
'fields' => 'COUNT(*) AS `count`',
|
||||
'joins' => array(),
|
||||
'limit' => 2,
|
||||
'offset' => null,
|
||||
'order' => array(
|
||||
0 => false
|
||||
),
|
||||
'page' => 1,
|
||||
'group' => null,
|
||||
'callbacks' => true,
|
||||
'recursive' => 0,
|
||||
);
|
||||
$TranslateBehavior = ClassRegistry::getObject('TranslateBehavior');
|
||||
$result = $TranslateBehavior->beforeFind($TestModel, $query);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,6 +192,81 @@ class ModelReadTest extends BaseModelTest {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function skipIfIsStrictGroupBy() {
|
||||
$isOnlyFullGroupBy = false;
|
||||
if ($this->db instanceof Mysql) {
|
||||
$sqlMode = $this->db->query('SELECT @@sql_mode AS sql_mode;');
|
||||
if (strpos($sqlMode[0][0]['sql_mode'], 'ONLY_FULL_GROUP_BY') > -1) {
|
||||
$isOnlyFullGroupBy = true;
|
||||
}
|
||||
}
|
||||
$isStrictGroupBy = $isOnlyFullGroupBy ||
|
||||
$this->db instanceof Postgres ||
|
||||
$this->db instanceof Sqlite ||
|
||||
$this->db instanceof Oracle ||
|
||||
$this->db instanceof Sqlserver;
|
||||
$message = 'Postgres, Oracle, SQLite, SQL Server and MySQL in ONLY_FULL_GROUP_BY ' .
|
||||
'mode have strict GROUP BY and are incompatible with this test.';
|
||||
$this->skipIf($isStrictGroupBy, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* testGroupByAndOrder method
|
||||
*
|
||||
* This test will never pass with Postgres or Oracle as all fields in a select must be
|
||||
* part of an aggregate function or in the GROUP BY statement.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGroupByAndOrder() {
|
||||
$this->skipIfIsStrictGroupBy();
|
||||
$this->loadFixtures('Project', 'Thread', 'Message');
|
||||
$Thread = new Thread();
|
||||
$result = $Thread->find('all', array(
|
||||
'group' => 'Thread.project_id',
|
||||
'order' => 'Thread.id ASC',
|
||||
));
|
||||
$expected = array(
|
||||
array(
|
||||
'Thread' => array(
|
||||
'id' => 1,
|
||||
'project_id' => 1,
|
||||
'name' => 'Project 1, Thread 1',
|
||||
),
|
||||
'Project' => array(
|
||||
'id' => 1,
|
||||
'name' => 'Project 1',
|
||||
),
|
||||
'Message' => array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'thread_id' => 1,
|
||||
'name' => 'Thread 1, Message 1',
|
||||
),
|
||||
),
|
||||
),
|
||||
array (
|
||||
'Thread' => array(
|
||||
'id' => 3,
|
||||
'project_id' => 2,
|
||||
'name' => 'Project 2, Thread 1',
|
||||
),
|
||||
'Project' => array(
|
||||
'id' => 2,
|
||||
'name' => 'Project 2',
|
||||
),
|
||||
'Message' => array(
|
||||
array(
|
||||
'id' => 3,
|
||||
'thread_id' => 3,
|
||||
'name' => 'Thread 3, Message 1',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testGroupBy method
|
||||
*
|
||||
|
@ -201,55 +276,12 @@ class ModelReadTest extends BaseModelTest {
|
|||
* @return void
|
||||
*/
|
||||
public function testGroupBy() {
|
||||
$isStrictGroupBy = $this->db instanceof Postgres || $this->db instanceof Sqlite || $this->db instanceof Oracle || $this->db instanceof Sqlserver;
|
||||
$message = 'Postgres, Oracle, SQLite and SQL Server have strict GROUP BY and are incompatible with this test.';
|
||||
|
||||
$this->skipIf($isStrictGroupBy, $message);
|
||||
$this->skipIfIsStrictGroupBy();
|
||||
|
||||
$this->loadFixtures('Project', 'Product', 'Thread', 'Message', 'Bid');
|
||||
$Thread = new Thread();
|
||||
$Product = new Product();
|
||||
|
||||
$result = $Thread->find('all', array(
|
||||
'group' => 'Thread.project_id',
|
||||
'order' => 'Thread.id ASC'
|
||||
));
|
||||
|
||||
$expected = array(
|
||||
array(
|
||||
'Thread' => array(
|
||||
'id' => 1,
|
||||
'project_id' => 1,
|
||||
'name' => 'Project 1, Thread 1'
|
||||
),
|
||||
'Project' => array(
|
||||
'id' => 1,
|
||||
'name' => 'Project 1'
|
||||
),
|
||||
'Message' => array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'thread_id' => 1,
|
||||
'name' => 'Thread 1, Message 1'
|
||||
))),
|
||||
array(
|
||||
'Thread' => array(
|
||||
'id' => 3,
|
||||
'project_id' => 2,
|
||||
'name' => 'Project 2, Thread 1'
|
||||
),
|
||||
'Project' => array(
|
||||
'id' => 2,
|
||||
'name' => 'Project 2'
|
||||
),
|
||||
'Message' => array(
|
||||
array(
|
||||
'id' => 3,
|
||||
'thread_id' => 3,
|
||||
'name' => 'Thread 3, Message 1'
|
||||
))));
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$rows = $Thread->find('all', array(
|
||||
'group' => 'Thread.project_id',
|
||||
'fields' => array('Thread.project_id', 'COUNT(*) AS total')
|
||||
|
@ -6452,6 +6484,145 @@ class ModelReadTest extends BaseModelTest {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testBuildQueryAllI18nConditions() {
|
||||
$this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
|
||||
$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User');
|
||||
$TestModel = new TranslatedArticle();
|
||||
$TestModel->cacheQueries = false;
|
||||
$TestModel->locale = 'eng';
|
||||
$expected = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'fields' => null,
|
||||
'joins' => array(
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__title',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'TranslatedArticle.id' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => 'I18n__title.foreign_key',
|
||||
),
|
||||
'I18n__title.model' => 'TranslatedArticle',
|
||||
'I18n__title.field' => 'title',
|
||||
'I18n__title.locale' => 'eng',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__body',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'TranslatedArticle.id' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => 'I18n__body.foreign_key',
|
||||
),
|
||||
'I18n__body.model' => 'TranslatedArticle',
|
||||
'I18n__body.field' => 'body',
|
||||
'I18n__body.locale' => 'eng',
|
||||
),
|
||||
),
|
||||
),
|
||||
'limit' => 2,
|
||||
'offset' => null,
|
||||
'order' => array(
|
||||
'TranslatedArticle.id' => 'ASC',
|
||||
),
|
||||
'page' => 1,
|
||||
'group' => null,
|
||||
'callbacks' => true,
|
||||
'recursive' => 0,
|
||||
);
|
||||
$query = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'limit' => 2,
|
||||
);
|
||||
$result = $TestModel->buildQuery('all', $query);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testBuildQueryCountI18nConditions() {
|
||||
$this->skipIf(!$this->db instanceof Mysql, 'This test is only compatible with Mysql.');
|
||||
$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User');
|
||||
$TestModel = new TranslatedArticle();
|
||||
$TestModel->cacheQueries = false;
|
||||
$TestModel->locale = 'eng';
|
||||
$expected = array(
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'fields' => 'COUNT(DISTINCT(`TranslatedArticle`.`id`)) AS count',
|
||||
'joins' => array(
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'TranslateArticleModel',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'`TranslatedArticle`.`id`' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => '`TranslateArticleModel`.`foreign_key`',
|
||||
),
|
||||
'`TranslateArticleModel`.`model`' => 'TranslatedArticle',
|
||||
'`TranslateArticleModel`.`locale`' => 'eng',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'INNER',
|
||||
'alias' => 'I18n__title',
|
||||
'table' => (object)array(
|
||||
'tablePrefix' => '',
|
||||
'table' => 'article_i18n',
|
||||
'schemaName' => 'cakephp_test',
|
||||
),
|
||||
'conditions' => array(
|
||||
'TranslatedArticle.id' => (object)array(
|
||||
'type' => 'identifier',
|
||||
'value' => 'I18n__title.foreign_key',
|
||||
),
|
||||
'I18n__title.model' => 'TranslatedArticle',
|
||||
'I18n__title.field' => 'title',
|
||||
'I18n__title.locale' => 'eng',
|
||||
),
|
||||
),
|
||||
),
|
||||
'limit' => 2,
|
||||
'offset' => null,
|
||||
'order' => array(
|
||||
0 => false,
|
||||
),
|
||||
'page' => 1,
|
||||
'group' => null,
|
||||
'callbacks' => true,
|
||||
'recursive' => 0,
|
||||
);
|
||||
$query = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'limit' => 2,
|
||||
);
|
||||
$result = $TestModel->buildQuery('count', $query);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test find('all') method
|
||||
*
|
||||
|
@ -6712,6 +6883,62 @@ class ModelReadTest extends BaseModelTest {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFindAllI18nConditions() {
|
||||
$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User');
|
||||
$TestModel = new TranslatedArticle();
|
||||
$TestModel->cacheQueries = false;
|
||||
$TestModel->locale = 'eng';
|
||||
$options = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'limit' => 2,
|
||||
);
|
||||
$result = $TestModel->find('all', $options);
|
||||
$expected = array(
|
||||
array(
|
||||
'TranslatedArticle' => array(
|
||||
'id' => '1',
|
||||
'user_id' => '1',
|
||||
'published' => 'Y',
|
||||
'created' => '2007-03-18 10:39:23',
|
||||
'updated' => '2007-03-18 10:41:31',
|
||||
'locale' => 'eng',
|
||||
'title' => 'Title (eng) #1',
|
||||
'body' => 'Body (eng) #1',
|
||||
),
|
||||
'User' => array(
|
||||
'id' => '1',
|
||||
'user' => 'mariano',
|
||||
'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
|
||||
'created' => '2007-03-17 01:16:23',
|
||||
'updated' => '2007-03-17 01:18:31',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'TranslatedArticle' => array(
|
||||
'id' => '2',
|
||||
'user_id' => '3',
|
||||
'published' => 'Y',
|
||||
'created' => '2007-03-18 10:41:23',
|
||||
'updated' => '2007-03-18 10:43:31',
|
||||
'locale' => 'eng',
|
||||
'title' => 'Title (eng) #2',
|
||||
'body' => 'Body (eng) #2',
|
||||
),
|
||||
'User' => array(
|
||||
'id' => '3',
|
||||
'user' => 'larry',
|
||||
'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
|
||||
'created' => '2007-03-17 01:20:23',
|
||||
'updated' => '2007-03-17 01:22:31',
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* test find('list') method
|
||||
*
|
||||
|
@ -7145,6 +7372,22 @@ class ModelReadTest extends BaseModelTest {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testFindCountI18nConditions() {
|
||||
$this->loadFixtures('TranslateArticle', 'TranslatedArticle', 'User');
|
||||
$TestModel = new TranslatedArticle();
|
||||
$TestModel->cacheQueries = false;
|
||||
$TestModel->locale = 'eng';
|
||||
$options = array(
|
||||
'recursive' => 0,
|
||||
'conditions' => array(
|
||||
'NOT' => array('I18n__title.content' => ''),
|
||||
),
|
||||
'limit' => 2,
|
||||
);
|
||||
$result = $TestModel->find('count', $options);
|
||||
$this->assertEquals(3, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that find('first') does not use the id set to the object.
|
||||
*
|
||||
|
@ -8186,6 +8429,29 @@ class ModelReadTest extends BaseModelTest {
|
|||
$this->assertEquals($expected, $result);
|
||||
}
|
||||
|
||||
public function testVirtualFieldsMysqlGroup() {
|
||||
$this->skipIf(!($this->db instanceof Mysql), 'The rest of virtualFields test only compatible with Mysql.');
|
||||
$this->skipIfIsStrictGroupBy();
|
||||
$this->loadFixtures('Post');
|
||||
$Post = ClassRegistry::init('Post');
|
||||
$Post->create();
|
||||
$Post->virtualFields = array(
|
||||
'low_title' => 'lower(Post.title)',
|
||||
'unique_test_field' => 'COUNT(Post.id)',
|
||||
);
|
||||
$expectation = array(
|
||||
'Post' => array(
|
||||
'low_title' => 'first post',
|
||||
'unique_test_field' => 1,
|
||||
),
|
||||
);
|
||||
$result = $Post->find('first', array(
|
||||
'fields' => array_keys($Post->virtualFields),
|
||||
'group' => array('low_title'),
|
||||
));
|
||||
$this->assertEquals($expectation, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* testVirtualFieldsMysql()
|
||||
*
|
||||
|
@ -8196,42 +8462,17 @@ class ModelReadTest extends BaseModelTest {
|
|||
*/
|
||||
public function testVirtualFieldsMysql() {
|
||||
$this->skipIf(!($this->db instanceof Mysql), 'The rest of virtualFields test only compatible with Mysql.');
|
||||
|
||||
$this->loadFixtures('Post', 'Author');
|
||||
$Post = ClassRegistry::init('Post');
|
||||
|
||||
$Post->create();
|
||||
$Post->virtualFields = array(
|
||||
'low_title' => 'lower(Post.title)',
|
||||
'unique_test_field' => 'COUNT(Post.id)'
|
||||
);
|
||||
|
||||
$expectation = array(
|
||||
'Post' => array(
|
||||
'low_title' => 'first post',
|
||||
'unique_test_field' => 1
|
||||
)
|
||||
);
|
||||
|
||||
$result = $Post->find('first', array(
|
||||
'fields' => array_keys($Post->virtualFields),
|
||||
'group' => array('low_title')
|
||||
));
|
||||
|
||||
$this->assertEquals($expectation, $result);
|
||||
|
||||
$this->loadFixtures('Author');
|
||||
$Author = ClassRegistry::init('Author');
|
||||
$Author->virtualFields = array(
|
||||
'full_name' => 'CONCAT(Author.user, " ", Author.id)'
|
||||
);
|
||||
|
||||
$result = $Author->find('first', array(
|
||||
'conditions' => array('Author.user' => 'mariano'),
|
||||
'fields' => array('Author.password', 'Author.full_name'),
|
||||
'recursive' => -1
|
||||
));
|
||||
$this->assertTrue(isset($result['Author']['full_name']));
|
||||
|
||||
$result = $Author->find('first', array(
|
||||
'conditions' => array('Author.user' => 'mariano'),
|
||||
'fields' => array('Author.full_name', 'Author.password'),
|
||||
|
|
|
@ -73,6 +73,7 @@ abstract class BaseModelTest extends CakeTestCase {
|
|||
'core.bidding', 'core.bidding_message', 'core.site', 'core.domain', 'core.domains_site',
|
||||
'core.uuidnativeitem', 'core.uuidnativeportfolio', 'core.uuidnativeitems_uuidnativeportfolio',
|
||||
'core.uuidnativeitems_uuidnativeportfolio_numericid',
|
||||
'core.translated_article', 'core.translate_article',
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1673,8 +1673,19 @@ class ModelWriteTest extends BaseModelTest {
|
|||
$this->assertFalse(empty($result));
|
||||
$this->assertEquals($data['Tag'], $result['Tag']);
|
||||
|
||||
$TestModel->unbindModel(array('belongsTo' => array('User'), 'hasMany' => array('Comment')));
|
||||
$result = $TestModel->find('first', array('fields' => array('id', 'user_id', 'title', 'body'), 'conditions' => array('Article.id' => 2)));
|
||||
$TestModel->unbindModel(array(
|
||||
'belongsTo' => array('User'),
|
||||
'hasMany' => array('Comment'),
|
||||
));
|
||||
$TestModel->bindModel(array(
|
||||
'hasAndBelongsToMany' => array(
|
||||
'Tag' => array('order' => 'Tag.id'),
|
||||
),
|
||||
), false);
|
||||
$result = $TestModel->find('first', array(
|
||||
'fields' => array('id', 'user_id', 'title', 'body'),
|
||||
'conditions' => array('Article.id' => 2),
|
||||
));
|
||||
$expected = array(
|
||||
'Article' => array(
|
||||
'id' => '2',
|
||||
|
@ -1694,7 +1705,9 @@ class ModelWriteTest extends BaseModelTest {
|
|||
'tag' => 'tag2',
|
||||
'created' => '2007-03-18 12:24:23',
|
||||
'updated' => '2007-03-18 12:26:31'
|
||||
)));
|
||||
),
|
||||
),
|
||||
);
|
||||
$this->assertEquals($expected, $result);
|
||||
|
||||
$data = array('Article' => array('id' => '2'), 'Tag' => array('Tag' => array(2, 3)));
|
||||
|
|
Loading…
Reference in a new issue