Browse Source

Merge branch '3.next' into 4.x

ADmad 7 years ago
parent
commit
88e3691aac

+ 1 - 1
src/Controller/Component/FlashComponent.php

@@ -86,7 +86,7 @@ class FlashComponent extends Component
      */
     public function set($message, array $options = []): void
     {
-        $options += $this->getConfig();
+        $options += (array)$this->getConfig();
 
         if ($message instanceof Exception) {
             if (!isset($options['params']['code'])) {

+ 1 - 67
src/Controller/Component/RequestHandlerComponent.php

@@ -46,7 +46,7 @@ class RequestHandlerComponent extends Component
      * @var string|null
      * @see \Cake\Routing\Router::extensions()
      */
-    public $ext;
+    protected $ext;
 
     /**
      * The template to use when rendering the given content type.
@@ -275,59 +275,6 @@ class RequestHandlerComponent extends Component
     }
 
     /**
-     * Returns true if the current call accepts an XML response, false otherwise
-     *
-     * @return bool True if client accepts an XML response
-     */
-    public function isXml(): bool
-    {
-        return $this->prefers('xml');
-    }
-
-    /**
-     * Returns true if the current call accepts an RSS response, false otherwise
-     *
-     * @return bool True if client accepts an RSS response
-     */
-    public function isRss(): bool
-    {
-        return $this->prefers('rss');
-    }
-
-    /**
-     * Returns true if the current call accepts an Atom response, false otherwise
-     *
-     * @return bool True if client accepts an RSS response
-     */
-    public function isAtom(): bool
-    {
-        return $this->prefers('atom');
-    }
-
-    /**
-     * Returns true if user agent string matches a mobile web browser, or if the
-     * client accepts WAP content.
-     *
-     * @return bool True if user agent is a mobile web browser
-     */
-    public function isMobile(): bool
-    {
-        $request = $this->getController()->getRequest();
-
-        return $request->is('mobile') || $this->accepts('wap');
-    }
-
-    /**
-     * Returns true if the client accepts WAP content
-     *
-     * @return bool
-     */
-    public function isWap(): bool
-    {
-        return $this->prefers('wap');
-    }
-
-    /**
      * Determines which content types the client accepts. Acceptance is based on
      * the file extension parsed by the Router (if present), and by the HTTP_ACCEPT
      * header. Unlike Cake\Http\ServerRequest::accepts() this method deals entirely with mapped content types.
@@ -597,19 +544,6 @@ class RequestHandlerComponent extends Component
     }
 
     /**
-     * Returns the current response type (Content-type header), or null if not alias exists
-     *
-     * @return mixed A string content type alias, or raw content type if no alias map exists,
-     *  otherwise null
-     */
-    public function responseType()
-    {
-        $response = $this->getController()->getResponse();
-
-        return $response->mapType($response->getType());
-    }
-
-    /**
      * Maps a content type alias back to its mime-type(s)
      *
      * @param string|array $alias String alias to convert back into a content type. Or an array of aliases to map.

+ 1 - 1
src/Database/Log/LoggingStatement.php

@@ -78,7 +78,7 @@ class LoggingStatement extends StatementDecorator
      */
     protected function _log(LoggedQuery $query, ?array $params, float $startTime): void
     {
-        $query->took = round((microtime(true) - $startTime) * 1000, 0);
+        $query->took = (int)round((microtime(true) - $startTime) * 1000, 0);
         $query->params = $params ?: $this->_compiledParams;
         $query->query = $this->queryString;
         $this->getLogger()->log($query);

+ 1 - 0
src/Database/SchemaCache.php

@@ -91,6 +91,7 @@ class SchemaCache
      *
      * @param \Cake\Database\Connection $connection Connection object
      * @return \Cake\Database\Schema\Collection|\Cake\Database\Schema\CachedCollection
+     * @throws \RuntimeException If given connection object is not compatible with schema caching
      */
     public function getSchema(Connection $connection)
     {

+ 3 - 0
src/Datasource/RepositoryInterface.php

@@ -18,6 +18,9 @@ namespace Cake\Datasource;
 /**
  * Describes the methods that any class representing a data storage should
  * comply with.
+ *
+ * @method $this setRegistryAlias(string $alias)
+ * @method string getRegistryAlias()
  */
 interface RepositoryInterface
 {

+ 2 - 2
src/Form/Form.php

@@ -185,7 +185,7 @@ class Form implements EventListenerInterface, EventDispatcherInterface, Validato
      *
      * @return array Last set validation errors.
      */
-    public function errors(): array
+    public function getErrors()
     {
         return $this->_errors;
     }
@@ -283,7 +283,7 @@ class Form implements EventListenerInterface, EventDispatcherInterface, Validato
     {
         $special = [
             '_schema' => $this->schema()->__debugInfo(),
-            '_errors' => $this->errors(),
+            '_errors' => $this->getErrors(),
             '_validator' => $this->getValidator()->__debugInfo(),
         ];
 

+ 1 - 1
src/Form/README.md

@@ -55,7 +55,7 @@ You can always define additional public methods as you need as well.
 ```php
 $contact = new ContactForm();
 $success = $contact->execute($data);
-$errors = $contact->errors();
+$errors = $contact->getErrors();
 ```
 
 ## Documentation

+ 4 - 1
src/Http/ControllerFactory.php

@@ -44,7 +44,10 @@ class ControllerFactory
             $this->missingController($request);
         }
 
-        return $reflection->newInstance($request, $response);
+        /** @var \Cake\Controller\Controller $controller */
+        $controller = $reflection->newInstance($request, $response);
+
+        return $controller;
     }
 
     /**

+ 1 - 1
src/Http/Server.php

@@ -161,7 +161,7 @@ class Server implements EventDispatcherInterface
     /**
      * Get the application's event manager or the global one.
      *
-     * @return \Cake\Event\EventManagerInterface
+     * @return \Cake\Event\EventManager
      */
     public function getEventManager(): EventManagerInterface
     {

+ 3 - 3
src/Mailer/Email.php

@@ -943,10 +943,10 @@ class Email implements JsonSerializable, Serializable
         }
         if ($this->_messageId !== false) {
             if ($this->_messageId === true) {
-                $headers['Message-ID'] = '<' . str_replace('-', '', Text::uuid()) . '@' . $this->_domain . '>';
-            } else {
-                $headers['Message-ID'] = $this->_messageId;
+                $this->_messageId = '<' . str_replace('-', '', Text::uuid()) . '@' . $this->_domain . '>';
             }
+
+            $headers['Message-ID'] = $this->_messageId;
         }
 
         if ($this->_priority) {

+ 1 - 1
src/ORM/ResultSet.php

@@ -57,7 +57,7 @@ class ResultSet implements ResultSetInterface
     /**
      * Default table instance
      *
-     * @var \Cake\ORM\Table
+     * @var \Cake\ORM\Table|\Cake\Datasource\RepositoryInterface
      */
     protected $_defaultTable;
 

+ 1 - 1
src/ORM/Table.php

@@ -438,7 +438,7 @@ class Table implements RepositoryInterface, EventListenerInterface, EventDispatc
     /**
      * Sets the connection instance.
      *
-     * @param \Cake\Database\Connection|\Cake\Datasource\ConnectionInterface $connection The connection instance
+     * @param \Cake\Database\Connection $connection The connection instance
      * @return $this
      */
     public function setConnection(ConnectionInterface $connection)

+ 4 - 1
src/TestSuite/MiddlewareDispatcher.php

@@ -71,6 +71,7 @@ class MiddlewareDispatcher
      * @param string|null $class The application class name. Defaults to App\Application.
      * @param array|null $constructorArgs The constructor arguments for your application class.
      *   Defaults to `['./config']`
+     * @throws \LogicException If it cannot load class for use in integration testing.
      */
     public function __construct(TestCase $test, ?string $class = null, ?array $constructorArgs = null)
     {
@@ -80,7 +81,9 @@ class MiddlewareDispatcher
 
         try {
             $reflect = new ReflectionClass($this->_class);
-            $this->app = $reflect->newInstanceArgs($this->_constructorArgs);
+            /** @var \Cake\Core\HttpApplicationInterface $app */
+            $app = $reflect->newInstanceArgs($this->_constructorArgs);
+            $this->app = $app;
         } catch (ReflectionException $e) {
             throw new LogicException(sprintf('Cannot load "%s" for use in integration testing.', $this->_class));
         }

+ 1 - 1
src/View/Form/FormContext.php

@@ -209,6 +209,6 @@ class FormContext implements ContextInterface
      */
     public function error(string $field): array
     {
-        return array_values((array)Hash::get($this->_form->errors(), $field, []));
+        return array_values((array)Hash::get($this->_form->getErrors(), $field, []));
     }
 }

+ 31 - 55
tests/TestCase/Controller/Component/RequestHandlerComponentTest.php

@@ -28,6 +28,19 @@ use Cake\View\XmlView;
 use TestApp\Controller\RequestHandlerTestController;
 use Zend\Diactoros\Stream;
 
+class RequestHandlerComponentExt extends RequestHandlerComponent
+{
+    public function getExt()
+    {
+        return $this->ext;
+    }
+
+    public function setExt($ext)
+    {
+        $this->ext = $ext;
+    }
+}
+
 /**
  * RequestHandlerComponentTest class
  */
@@ -84,7 +97,7 @@ class RequestHandlerComponentTest extends TestCase
             ->setMethods(['_sendHeader', 'stop'])
             ->getMock();
         $this->Controller = new RequestHandlerTestController($request, $response);
-        $this->RequestHandler = $this->Controller->components()->load('RequestHandler');
+        $this->RequestHandler = $this->Controller->components()->load(RequestHandlerComponentExt::class);
         $this->request = $request;
 
         Router::scope('/', function ($routes): void {
@@ -147,9 +160,9 @@ class RequestHandlerComponentTest extends TestCase
         Router::reload();
         $this->Controller->setRequest($this->request->withHeader('Accept', 'application/json'));
 
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
-        $this->assertEquals('json', $this->RequestHandler->ext);
+        $this->assertEquals('json', $this->RequestHandler->getExt());
     }
 
     /**
@@ -163,7 +176,7 @@ class RequestHandlerComponentTest extends TestCase
         $this->Controller->setRequest($this->request
             ->withHeader('Accept', 'application/json, application/javascript, */*; q=0.01')
             ->withHeader('X-Requested-With', 'XMLHttpRequest'));
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
         Router::extensions('json', false);
 
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
@@ -194,7 +207,7 @@ class RequestHandlerComponentTest extends TestCase
     {
         Router::reload();
         $this->Controller->setRequest($this->request->withHeader('Accept', 'application/json, application/javascript, */*; q=0.01'));
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
         Router::extensions(['rss', 'json'], false);
 
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
@@ -230,13 +243,13 @@ class RequestHandlerComponentTest extends TestCase
             'Accept',
             'application/json, application/javascript, application/xml, */*; q=0.01'
         ));
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
         Router::extensions(['xml', 'json'], false);
 
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
         $this->assertEquals('xml', $this->RequestHandler->ext);
 
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
         Router::extensions(['json', 'xml'], false);
 
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
@@ -255,7 +268,7 @@ class RequestHandlerComponentTest extends TestCase
             'Accept',
             'text/csv;q=1.0, application/json;q=0.8, application/xml;q=0.7'
         ));
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
 
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
         $this->assertEquals('json', $this->RequestHandler->ext);
@@ -273,7 +286,7 @@ class RequestHandlerComponentTest extends TestCase
             'HTTP_ACCEPT',
             'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
         );
-        $this->RequestHandler->ext = null;
+        $this->RequestHandler->setExt(null);
 
         $this->RequestHandler->startup(new Event('Controller.startup', $this->Controller));
         $this->assertNull($this->RequestHandler->ext);
@@ -821,60 +834,23 @@ XML;
             'Accept',
             'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*'
         ));
-        $this->assertTrue($this->RequestHandler->isXml());
-        $this->assertFalse($this->RequestHandler->isAtom());
-        $this->assertFalse($this->RequestHandler->isRSS());
+        $this->assertTrue($this->RequestHandler->prefers('xml'));
+        $this->assertFalse($this->RequestHandler->prefers('atom'));
+        $this->assertFalse($this->RequestHandler->prefers('rss'));
 
         $this->Controller->setRequest($this->request->withHeader(
             'Accept',
             'application/atom+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*'
         ));
-        $this->assertTrue($this->RequestHandler->isAtom());
-        $this->assertFalse($this->RequestHandler->isRSS());
+        $this->assertTrue($this->RequestHandler->prefers('atom'));
+        $this->assertFalse($this->RequestHandler->prefers('rss'));
 
         $this->Controller->setRequest($this->request->withHeader(
             'Accept',
             'application/rss+xml,text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,*/*'
         ));
-        $this->assertFalse($this->RequestHandler->isAtom());
-        $this->assertTrue($this->RequestHandler->isRSS());
-
-        $this->assertFalse($this->RequestHandler->isWap());
-        $this->Controller->setRequest($this->request->withHeader(
-            'Accept',
-            'text/vnd.wap.wml,text/html,text/plain,image/png,*/*'
-        ));
-        $this->assertTrue($this->RequestHandler->isWap());
-    }
-
-    /**
-     * testResponseContentType method
-     *
-     * @return void
-     */
-    public function testResponseContentType(): void
-    {
-        $this->assertEquals('html', $this->RequestHandler->responseType());
-        $this->assertTrue($this->RequestHandler->respondAs('atom'));
-        $this->assertEquals('atom', $this->RequestHandler->responseType());
-    }
-
-    /**
-     * testMobileDeviceDetection method
-     *
-     * @return void
-     */
-    public function testMobileDeviceDetection(): void
-    {
-        $request = $this->getMockBuilder('Cake\Http\ServerRequest')
-            ->setMethods(['is'])
-            ->getMock();
-        $request->expects($this->once())->method('is')
-            ->with('mobile')
-            ->will($this->returnValue(true));
-
-        $this->Controller->setRequest($request);
-        $this->assertTrue($this->RequestHandler->isMobile());
+        $this->assertFalse($this->RequestHandler->prefers('atom'));
+        $this->assertTrue($this->RequestHandler->prefers('rss'));
     }
 
     /**
@@ -929,7 +905,7 @@ XML;
         ));
         $this->assertNotEquals('rss', $this->RequestHandler->prefers());
 
-        $this->RequestHandler->ext = 'rss';
+        $this->RequestHandler->setExt('rss');
         $this->assertEquals('rss', $this->RequestHandler->prefers());
         $this->assertFalse($this->RequestHandler->prefers('xml'));
         $this->assertEquals('xml', $this->RequestHandler->prefers(['js', 'xml', 'xhtml']));
@@ -950,7 +926,7 @@ XML;
         $this->assertFalse($this->RequestHandler->prefers('rss'));
 
         $this->Controller->setRequest($this->request->withEnv('HTTP_ACCEPT', ''));
-        $this->RequestHandler->ext = 'json';
+        $this->RequestHandler->setExt('json');
         $this->assertFalse($this->RequestHandler->prefers('xml'));
     }
 

+ 1 - 5
tests/TestCase/Controller/ControllerTest.php

@@ -270,11 +270,7 @@ class ControllerTest extends TestCase
         $controller->Bar = true;
         $this->assertTrue($controller->Bar);
 
-        if (class_exists(Notice::class)) {
-            $this->expectException(Notice::class);
-        } else {
-            $this->expectException(\PHPUnit_Framework_Error_Notice::class);
-        }
+        $this->expectException(Notice::class);
         $this->expectExceptionMessage(sprintf(
             'Undefined property: Controller::$Foo in %s on line %s',
             __FILE__,

+ 6 - 6
tests/TestCase/Form/FormTest.php

@@ -95,22 +95,22 @@ class FormTest extends TestCase
             'body' => 'too short',
         ];
         $this->assertFalse($form->validate($data));
-        $this->assertCount(2, $form->errors());
+        $this->assertCount(2, $form->getErrors());
 
         $data = [
             'email' => 'test@example.com',
             'body' => 'Some content goes here',
         ];
         $this->assertTrue($form->validate($data));
-        $this->assertCount(0, $form->errors());
+        $this->assertCount(0, $form->getErrors());
     }
 
     /**
-     * Test the errors methods.
+     * Test the get errors methods.
      *
      * @return void
      */
-    public function testErrors()
+    public function testGetErrors()
     {
         $form = new Form();
         $form->getValidator()
@@ -128,7 +128,7 @@ class FormTest extends TestCase
             'body' => 'too short',
         ];
         $form->validate($data);
-        $errors = $form->errors();
+        $errors = $form->getErrors();
         $this->assertCount(2, $errors);
         $this->assertEquals('Must be a valid email', $errors['email']['format']);
         $this->assertEquals('Must be so long', $errors['body']['length']);
@@ -147,7 +147,7 @@ class FormTest extends TestCase
         ];
 
         $form->setErrors($expected);
-        $this->assertSame($expected, $form->errors());
+        $this->assertSame($expected, $form->getErrors());
     }
 
     /**

+ 9 - 0
tests/TestCase/Mailer/EmailTest.php

@@ -617,6 +617,15 @@ class EmailTest extends TestCase
         $this->assertSame('<my-email@localhost>', $result);
     }
 
+    public function testAutoMessageIdIsIdempotent()
+    {
+        $headers = $this->Email->getHeaders();
+        $this->assertArrayHasKey('Message-ID', $headers);
+
+        $regeneratedHeaders = $this->Email->getHeaders();
+        $this->assertSame($headers['Message-ID'], $regeneratedHeaders['Message-ID']);
+    }
+
     /**
      * @return void
      */