Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote-tracking branch 'cakephp/2.2' into 3.0-namespace

Conflicts:
	lib/Cake/Utility/Validation.php
  • Loading branch information...
commit ebac318c9490488208b242e8701401b01844809e 2 parents cdadaee + 06476a2
@jrbasso authored
View
24 lib/Cake/Model/Datasource/DboSource.php
@@ -1088,6 +1088,7 @@ public function read(Model $model, $queryData = array(), $recursive = null) {
$query = trim($this->generateAssociationQuery($model, null, null, null, null, $queryData, false, $null));
$resultSet = $this->fetchAll($query, $model->cacheQueries);
+
if ($resultSet === false) {
$model->onError();
return false;
@@ -1100,6 +1101,10 @@ public function read(Model $model, $queryData = array(), $recursive = null) {
}
if ($model->recursive > -1) {
+ $joined = array();
+ if (isset($queryData['joins'][0]['alias'])) {
+ $joined[$model->alias] = (array)Hash::extract($queryData['joins'], '{n}.alias');
+ }
foreach ($_associations as $type) {
foreach ($model->{$type} as $assoc => $assocData) {
$linkModel = $model->{$assoc};
@@ -1116,6 +1121,7 @@ public function read(Model $model, $queryData = array(), $recursive = null) {
if (isset($db) && method_exists($db, 'queryAssociation')) {
$stack = array($assoc);
+ $stack['_joined'] = $joined;
$db->queryAssociation($model, $linkModel, $type, $assoc, $assocData, $array, true, $resultSet, $model->recursive - 1, $stack);
unset($db);
@@ -1184,6 +1190,11 @@ protected function _filterResults(&$results, Model $model, $filtered = array())
* @throws CakeException when results cannot be created.
*/
public function queryAssociation(Model $model, &$linkModel, $type, $association, $assocData, &$queryData, $external, &$resultSet, $recursive, $stack) {
+ if (isset($stack['_joined'])) {
+ $joined = $stack['_joined'];
+ unset($stack['_joined']);
+ }
+
if ($query = $this->generateAssociationQuery($model, $linkModel, $type, $association, $assocData, $queryData, $external, $resultSet)) {
if (!is_array($resultSet)) {
throw new Error\Exception(__d('cake_dev', 'Error in Model %s', get_class($model)));
@@ -1259,10 +1270,17 @@ public function queryAssociation(Model $model, &$linkModel, $type, $association,
foreach ($resultSet as &$row) {
if ($type !== 'hasAndBelongsToMany') {
$q = $this->insertQueryData($query, $row, $association, $assocData, $model, $linkModel, $stack);
+ $fetch = null;
if ($q !== false) {
- $fetch = $this->fetchAll($q, $model->cacheQueries);
- } else {
- $fetch = null;
+ $joinedData = array();
+ if (($type === 'belongsTo' || $type === 'hasOne') && isset($row[$linkModel->alias], $joined[$model->alias]) && in_array($linkModel->alias, $joined[$model->alias])) {
+ $joinedData = Hash::filter($row[$linkModel->alias]);
+ if (!empty($joinedData)) {
+ $fetch[0] = array($linkModel->alias => $row[$linkModel->alias]);
+ }
+ } else {
+ $fetch = $this->fetchAll($q, $model->cacheQueries);
+ }
}
}
$selfJoin = $linkModel->name === $model->name;
View
4 lib/Cake/Test/TestCase/Console/Command/Task/ModelTaskTest.php
@@ -315,7 +315,7 @@ public function testInteractiveFieldValidation() {
$this->Task->initValidations();
$this->Task->interactive = true;
$this->Task->expects($this->any())->method('in')
- ->will($this->onConsecutiveCalls('22', 'y', '17', 'n'));
+ ->will($this->onConsecutiveCalls('23', 'y', '17', 'n'));
$result = $this->Task->fieldValidation('text', array('type' => 'string', 'length' => 10, 'null' => false));
$expected = array('notempty' => 'notempty', 'maxlength' => 'maxlength');
@@ -333,7 +333,7 @@ public function testInteractiveFieldValidationWithBogusResponse() {
$this->Task->interactive = true;
$this->Task->expects($this->any())->method('in')
- ->will($this->onConsecutiveCalls('999999', '22', 'n'));
+ ->will($this->onConsecutiveCalls('999999', '23', 'n'));
$this->Task->expects($this->at(7))->method('out')
->with($this->stringContains('make a valid'));
View
56 lib/Cake/Test/TestCase/Model/Datasource/DboSourceTest.php
@@ -768,6 +768,62 @@ public function testReadOnlyCallingQueryAssociationWhenDefined() {
}
/**
+ * test that queryAssociation() reuse already joined data for 'belongsTo' and 'hasOne' associations
+ * instead of running unneeded queries for each record
+ *
+ * @return void
+ */
+ public function testQueryAssociationUnneededQueries() {
+ $this->loadFixtures('Article', 'User', 'Comment', 'Attachment', 'Tag', 'ArticlesTag');
+ $Comment = new Comment;
+
+ $fullDebug = $this->db->fullDebug;
+ $this->db->fullDebug = true;
+
+ $Comment->find('all', array('recursive' => 2)); // ensure Model descriptions are saved
+ $this->db->getLog();
+
+ // case: Comment belongsTo User and Article
+ $Comment->unbindModel(array(
+ 'hasOne' => array('Attachment')
+ ));
+ $Comment->Article->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasMany' => array('Comment'),
+ 'hasAndBelongsToMany' => array('Tag')
+ ));
+ $Comment->find('all', array('recursive' => 2));
+ $log = $this->db->getLog();
+ $this->assertEquals(1, count($log['log']));
+
+ // case: Comment belongsTo Article, Article belongsTo User
+ $Comment->unbindModel(array(
+ 'belongsTo' => array('User'),
+ 'hasOne' => array('Attachment')
+ ));
+ $Comment->Article->unbindModel(array(
+ 'hasMany' => array('Comment'),
+ 'hasAndBelongsToMany' => array('Tag'),
+ ));
+ $Comment->find('all', array('recursive' => 2));
+ $log = $this->db->getLog();
+ $this->assertEquals(7, count($log['log']));
+
+ // case: Comment hasOne Attachment
+ $Comment->unbindModel(array(
+ 'belongsTo' => array('Article', 'User'),
+ ));
+ $Comment->Attachment->unbindModel(array(
+ 'belongsTo' => array('Comment'),
+ ));
+ $Comment->find('all', array('recursive' => 2));
+ $log = $this->db->getLog();
+ $this->assertEquals(1, count($log['log']));
+
+ $this->db->fullDebug = $fullDebug;
+ }
+
+/**
* test that fields() is using methodCache()
*
* @return void
View
26 lib/Cake/Test/TestCase/Utility/ValidationTest.php
@@ -2169,4 +2169,30 @@ public function testDatetime() {
$this->assertFalse(Validation::datetime('31 11 2006 1:00pm', 'dmy'));
}
+/**
+ * testMimeType method
+ *
+ * @return void
+ */
+ public function testMimeType() {
+ $file = CORE_PATH . 'Cake' . DS . 'Test' . DS . 'test_app' . DS . 'webroot' . DS . 'img' . DS . 'cake.power.gif';
+ $this->assertTrue(Validation::mimeType($file, array('image/gif')));
+ $this->assertTrue(Validation::mimeType(array('tmp_name' => $file), array('image/gif')));
+
+ $this->assertFalse(Validation::mimeType($file, array('image/png')));
+ $this->assertFalse(Validation::mimeType(array('tmp_name' => $file), array('image/png')));
+ }
+
+/**
+ * testMimeType method
+ *
+ * @return void
+ */
+ public function testUploadError() {
+ $this->assertTrue(Validation::uploadError(0));
+ $this->assertTrue(Validation::uploadError(array('error' => 0)));
+
+ $this->assertFalse(Validation::uploadError(2));
+ $this->assertFalse(Validation::uploadError(array('error' => 2)));
+ }
}
View
34 lib/Cake/Utility/Validation.php
@@ -18,6 +18,7 @@
*/
namespace Cake\Utility;
use Cake\Core\App;
+use Cake\Utility\File;
// Load multibyte if the extension is missing.
if (!function_exists('mb_strlen')) {
@@ -860,6 +861,39 @@ public static function luhn($check, $deep = false) {
}
/**
+ * Checks the mime type of a file
+ *
+ * @param string|array $check
+ * @param array $mimeTypes to check for
+ * @return boolean Success
+ */
+ public static function mimeType($check, $mimeTypes = array()) {
+ if (is_array($check) && isset($check['tmp_name'])) {
+ $check = $check['tmp_name'];
+ }
+
+ $File = new File($check);
+ $mime = $File->mime();
+
+ return in_array($mime, $mimeTypes);
+ }
+
+/**
+ * Checking for upload errors
+ *
+ * @param string|array $check
+ * @retrun boolean
+ * @see http://www.php.net/manual/en/features.file-upload.errors.php
+ */
+ public static function uploadError($check) {
+ if (is_array($check) && isset($check['error'])) {
+ $check = $check['error'];
+ }
+
+ return $check === UPLOAD_ERR_OK;
+ }
+
+/**
* Lazily populate the IP address patterns used for validations
*
* @return void
Please sign in to comment.
Something went wrong with that request. Please try again.