Browse Source

Merge branch 'master' into 4.next

ADmad 4 years ago
parent
commit
48dcd2ccc9

+ 4 - 0
src/ORM/Association/Loader/SelectLoader.php

@@ -244,6 +244,10 @@ class SelectLoader
      */
     protected function _assertFieldsPresent(Query $fetchQuery, array $key): void
     {
+        if ($fetchQuery->isAutoFieldsEnabled()) {
+            return;
+        }
+
         $select = $fetchQuery->aliasFields($fetchQuery->clause('select'));
         if (empty($select)) {
             return;

+ 2 - 0
src/TestSuite/Fixture/TestFixture.php

@@ -252,6 +252,8 @@ class TestFixture implements ConstraintsInterface, FixtureInterface, TableSchema
             /** @var \Cake\Database\Schema\TableSchema $schema */
             $schema = $ormTable->getSchema();
             $this->_schema = $schema;
+
+            $this->getTableLocator()->clear();
         } catch (CakeException $e) {
             $message = sprintf(
                 'Cannot describe schema for table `%s` for fixture `%s`. The table does not exist.',

+ 18 - 11
src/View/Helper/PaginatorHelper.php

@@ -1234,10 +1234,17 @@ class PaginatorHelper extends Helper
      */
     public function limitControl(array $limits = [], ?int $default = null, array $options = []): string
     {
-        $out = $this->Form->create(null, ['type' => 'get']);
+        $model = $options['model'] ?? $this->defaultModel();
+        unset($options['model']);
+
+        $params = $this->params($model);
+        $scope = '';
+        if (!empty($params['scope'])) {
+            $scope = $params['scope'] . '.';
+        }
 
         if (empty($default)) {
-            $default = $this->param('perPage');
+            $default = $params['perPage'] ?? 0;
         }
 
         if (empty($limits)) {
@@ -1247,15 +1254,15 @@ class PaginatorHelper extends Helper
                 '100' => '100',
             ];
         }
-
-        $out .= $this->Form->control('limit', $options + [
-                'type' => 'select',
-                'label' => __('View'),
-                'default' => $default,
-                'value' => $this->_View->getRequest()->getQuery('limit'),
-                'options' => $limits,
-                'onChange' => 'this.form.submit()',
-            ]);
+        $out = $this->Form->create(null, ['type' => 'get']);
+        $out .= $this->Form->control($scope . 'limit', $options + [
+            'type' => 'select',
+            'label' => __('View'),
+            'default' => $default,
+            'value' => $this->_View->getRequest()->getQuery('limit'),
+            'options' => $limits,
+            'onChange' => 'this.form.submit()',
+        ]);
         $out .= $this->Form->end();
 
         return $out;

+ 16 - 1
tests/TestCase/ORM/QueryTest.php

@@ -2032,7 +2032,7 @@ class QueryTest extends TestCase
      * Integration test that uses the contain signature that is the same as the
      * matching signature
      */
-    public function testContainSecondSignature(): void
+    public function testContainClosureSignature(): void
     {
         $table = $this->getTableLocator()->get('authors');
         $table->hasMany('articles');
@@ -2052,6 +2052,21 @@ class QueryTest extends TestCase
         $this->assertEquals([1], array_unique($ids));
     }
 
+    public function testContainAutoFields(): void
+    {
+        $table = $this->getTableLocator()->get('authors');
+        $table->hasMany('articles');
+        $query = new Query($this->connection, $table);
+        $query
+            ->select()
+            ->contain('articles', function ($q) {
+                return $q->select(['test' => '(SELECT 20)'])
+                    ->enableAutoFields(true);
+            });
+        $results = $query->toArray();
+        $this->assertNotEmpty($results);
+    }
+
     /**
      * Integration test to ensure that filtering associations with the queryBuilder
      * option works.

+ 22 - 3
tests/TestCase/TestSuite/TestFixtureTest.php

@@ -21,9 +21,11 @@ use Cake\Database\Schema\TableSchema;
 use Cake\Database\StatementInterface;
 use Cake\Datasource\ConnectionManager;
 use Cake\Log\Log;
+use Cake\Test\Fixture\PostsFixture;
 use Cake\TestSuite\TestCase;
 use Exception;
 use TestApp\Test\Fixture\ArticlesFixture;
+use TestApp\Test\Fixture\FeaturedTagsFixture;
 use TestApp\Test\Fixture\ImportsFixture;
 use TestApp\Test\Fixture\LettersFixture;
 use TestApp\Test\Fixture\StringsTestsFixture;
@@ -141,7 +143,6 @@ class TestFixtureTest extends TestCase
         $this->expectException(CakeException::class);
         $this->expectExceptionMessage('Cannot describe schema for table `letters` for fixture `' . LettersFixture::class . '`. The table does not exist.');
         $fixture = new LettersFixture();
-        $fixture->init();
     }
 
     /**
@@ -162,7 +163,6 @@ class TestFixtureTest extends TestCase
         }
 
         $fixture = new LettersFixture();
-        $fixture->init();
         $this->assertSame(['id', 'letter'], $fixture->getTableSchema()->columns());
     }
 
@@ -188,13 +188,32 @@ class TestFixtureTest extends TestCase
         $table->getSchema()->setColumnType('complex_field', 'json');
 
         $fixture = new LettersFixture();
-        $fixture->init();
         $fixtureSchema = $fixture->getTableSchema();
         $this->assertSame(['id', 'letter', 'complex_field'], $fixtureSchema->columns());
         $this->assertSame('json', $fixtureSchema->getColumnType('complex_field'));
     }
 
     /**
+     * test init with other tables used in initialize()
+     *
+     * The FeaturedTagsTable uses PostsTable, then when PostsFixture
+     * reflects schema it should not raise an error.
+     */
+    public function testInitInitializeUsesRegistry(): void
+    {
+        $this->setAppNamespace();
+
+        $fixture = new FeaturedTagsFixture();
+
+        $posts = new PostsFixture();
+        $posts->fields = [];
+        $posts->init();
+
+        $expected = ['tag_id', 'priority'];
+        $this->assertSame($expected, $fixture->getTableSchema()->columns());
+    }
+
+    /**
      * test create method
      */
     public function testCreate(): void

+ 54 - 0
tests/TestCase/View/Helper/PaginatorHelperTest.php

@@ -3265,6 +3265,7 @@ class PaginatorHelperTest extends TestCase
             'params' => [
                 'plugin' => null, 'controller' => 'Batches', 'action' => 'index', 'pass' => [],
             ],
+            'query' => ['owner' => 'billy', 'expected' => 1],
             'base' => '',
             'webroot' => '/',
         ]);
@@ -3343,6 +3344,59 @@ class PaginatorHelperTest extends TestCase
     }
 
     /**
+     * test the limitControl() method with model option
+     */
+    public function testLimitControlModelOption(): void
+    {
+        $request = new ServerRequest([
+            'url' => '/accounts/',
+            'params' => [
+                'plugin' => null, 'controller' => 'Accounts', 'action' => 'index', 'pass' => [],
+            ],
+            'base' => '',
+            'webroot' => '/',
+        ]);
+        Router::setRequest($request);
+
+        $this->View->setRequest($this->View->getRequest()->withAttribute('paging', [
+            'Articles' => [
+                'current' => 9,
+                'count' => 62,
+                'prevPage' => false,
+                'nextPage' => true,
+                'pageCount' => 7,
+                'sort' => 'date',
+                'direction' => 'asc',
+                'page' => 1,
+                'scope' => 'article',
+            ],
+        ]));
+        $out = $this->Paginator->limitControl([25 => 25, 50 => 50], null, ['model' => 'Articles']);
+        $expected = [
+            ['form' => ['method' => 'get', 'accept-charset' => 'utf-8', 'action' => '/']],
+            ['div' => ['class' => 'input select']],
+            ['label' => ['for' => 'article-limit']],
+            'View',
+            '/label',
+            ['select' => ['name' => 'article[limit]', 'id' => 'article-limit', 'onChange' => 'this.form.submit()']],
+            ['option' => ['value' => '25']],
+            '25',
+            '/option',
+            ['option' => ['value' => '50']],
+            '50',
+            '/option',
+            '/select',
+            '/div',
+            '/form',
+        ];
+        $this->assertHtml($expected, $out);
+
+        $this->Paginator->options(['model' => 'Articles']);
+        $out = $this->Paginator->limitControl([25 => 25, 50 => 50]);
+        $this->assertHtml($expected, $out);
+    }
+
+    /**
      * Test using paging params set by SimplePaginator which doesn't do count query.
      */
     public function testMethodsWhenThereIsNoPageCount(): void

+ 30 - 0
tests/test_app/TestApp/Model/Table/FeaturedTagsTable.php

@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+/**
+ * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
+ * @since         4.3.7
+ * @license       https://opensource.org/licenses/mit-license.php MIT License
+ */
+namespace TestApp\Model\Table;
+
+use Cake\ORM\Table;
+use Cake\ORM\TableRegistry;
+
+/**
+ * FeaturedTags table class
+ */
+class FeaturedTagsTable extends Table
+{
+    public function initialize(array $config): void
+    {
+        // Used to reproduce https://github.com/cakephp/cakephp/issues/16373
+        $this->Posts = TableRegistry::getTableLocator()->get('Posts');
+    }
+}

+ 26 - 0
tests/test_app/TestApp/tests/Fixture/FeaturedTagsFixture.php

@@ -0,0 +1,26 @@
+<?php
+declare(strict_types=1);
+
+namespace TestApp\Test\Fixture;
+
+use Cake\TestSuite\Fixture\TestFixture;
+
+class FeaturedTagsFixture extends TestFixture
+{
+    /**
+     * Table property
+     *
+     * @var string
+     */
+    public $table = 'featured_tags';
+
+    /**
+     * Records property
+     *
+     * @var array
+     */
+    public $records = [
+        ['tag_id' => 1, 'priority' => 1.0],
+        ['tag_id' => 2, 'priority' => 0.7],
+    ];
+}