Browse Source

Merge branch '3.next' into 4.x

ADmad 7 years ago
parent
commit
694428b71b

+ 2 - 2
src/Console/CommandScanner.php

@@ -63,13 +63,13 @@ class CommandScanner
             App::path('Shell')[0],
             $appNamespace . '\Shell\\',
             '',
-            ['app']
+            []
         );
         $appCommands = $this->scanDir(
             App::path('Command')[0],
             $appNamespace . '\Command\\',
             '',
-            ['app']
+            []
         );
 
         return array_merge($appShells, $appCommands);

+ 40 - 0
src/Form/Form.php

@@ -19,6 +19,7 @@ use Cake\Event\EventDispatcherTrait;
 use Cake\Event\EventListenerInterface;
 use Cake\Event\EventManager;
 use Cake\Form\Schema;
+use Cake\Utility\Hash;
 use Cake\Validation\ValidatorAwareInterface;
 use Cake\Validation\ValidatorAwareTrait;
 
@@ -84,6 +85,14 @@ class Form implements EventListenerInterface, EventDispatcherInterface, Validato
     protected $_validator;
 
     /**
+     * Form's data.
+     *
+     * @var array
+     * @since 3.7.0
+     */
+    protected $_data = [];
+
+    /**
      * Constructor
      *
      * @param \Cake\Event\EventManager|null $eventManager The event manager.
@@ -239,6 +248,37 @@ class Form implements EventListenerInterface, EventDispatcherInterface, Validato
     }
 
     /**
+     * Get field data.
+     *
+     * @param string|null $field The field name or null to get data array with
+     *   all fields.
+     * @return mixed
+     * @since 3.7.0
+     */
+    public function getData($field = null)
+    {
+        if ($field === null) {
+            return $this->_data;
+        }
+
+        return Hash::get($this->_data, $field);
+    }
+
+    /**
+     * Set form data.
+     *
+     * @param array $data Data array.
+     * @return $this
+     * @since 3.7.0
+     */
+    public function setData(array $data)
+    {
+        $this->_data = $data;
+
+        return $this;
+    }
+
+    /**
      * Get the printable version of a Form instance.
      *
      * @return array

+ 5 - 2
src/Http/Client/Adapter/Stream.php

@@ -306,8 +306,11 @@ class Stream
         set_error_handler(function ($code, $message) {
             $this->_connectionErrors[] = $message;
         });
-        $this->_stream = fopen($url, 'rb', false, $this->_context);
-        restore_error_handler();
+        try {
+            $this->_stream = fopen($url, 'rb', false, $this->_context);
+        } finally {
+            restore_error_handler();
+        }
 
         if (!$this->_stream || !empty($this->_connectionErrors)) {
             throw new Exception(implode("\n", $this->_connectionErrors));

+ 5 - 0
src/View/Form/FormContext.php

@@ -94,6 +94,11 @@ class FormContext implements ContextInterface
             return $val;
         }
 
+        $val = $this->_form->getData($field);
+        if ($val !== null) {
+            return $val;
+        }
+
         if ($options['default'] !== null || !$options['schemaDefault']) {
             return $options['default'];
         }

+ 1 - 1
src/View/Helper.php

@@ -116,7 +116,7 @@ class Helper implements EventListenerInterface
     public function __construct(View $View, array $config = [])
     {
         $this->_View = $View;
-        $this->request = $View->request;
+        $this->request = $View->getRequest();
 
         $this->setConfig($config);
 

+ 1 - 1
src/View/Helper/HtmlHelper.php

@@ -135,7 +135,7 @@ class HtmlHelper extends Helper
     public function __construct(View $View, array $config = [])
     {
         parent::__construct($View, $config);
-        $this->response = $this->_View->response ?: new Response();
+        $this->response = $this->_View->getResponse() ?: new Response();
     }
 
     /**

+ 1 - 1
src/View/HelperRegistry.php

@@ -144,7 +144,7 @@ class HelperRegistry extends ObjectRegistry implements EventDispatcherInterface
     protected function _create($class, $alias, $settings)
     {
         $instance = new $class($this->_View, $settings);
-        $vars = ['request', 'theme', 'plugin'];
+        $vars = ['theme', 'plugin'];
         foreach ($vars as $var) {
             $instance->{$var} = $this->_View->{$var};
         }

+ 2 - 0
tests/TestCase/Console/CommandCollectionTest.php

@@ -202,11 +202,13 @@ class CommandCollectionTest extends TestCase
         $collection = new CommandCollection();
         $collection->addMany($collection->autoDiscover());
 
+        $this->assertTrue($collection->has('app'));
         $this->assertTrue($collection->has('demo'));
         $this->assertTrue($collection->has('i18m'));
         $this->assertTrue($collection->has('sample'));
         $this->assertTrue($collection->has('testing_dispatch'));
 
+        $this->assertSame('TestApp\Shell\AppShell', $collection->get('app'));
         $this->assertSame('TestApp\Command\DemoCommand', $collection->get('demo'));
         $this->assertSame('TestApp\Shell\I18mShell', $collection->get('i18m'));
         $this->assertSame('TestApp\Shell\SampleShell', $collection->get('sample'));

+ 17 - 0
tests/TestCase/Form/FormTest.php

@@ -195,6 +195,22 @@ class FormTest extends TestCase
     }
 
     /**
+     * Test setting and getting form data.
+     *
+     * @return void
+     */
+    public function testDataSetGet()
+    {
+        $form = new Form();
+        $expected = ['title' => 'title', 'is_published' => true];
+        $form->setData(['title' => 'title', 'is_published' => true]);
+
+        $this->assertSame($expected, $form->getData());
+        $this->assertEquals('title', $form->getData('title'));
+        $this->assertNull($form->getData('non-existent'));
+    }
+
+    /**
      * test __debugInfo
      *
      * @return void
@@ -206,5 +222,6 @@ class FormTest extends TestCase
         $this->assertArrayHasKey('_schema', $result);
         $this->assertArrayHasKey('_errors', $result);
         $this->assertArrayHasKey('_validator', $result);
+        $this->assertArrayHasKey('_data', $result);
     }
 }

+ 30 - 0
tests/TestCase/Http/Client/Adapter/StreamTest.php

@@ -35,6 +35,10 @@ class CakeStreamWrapper implements \ArrayAccess
 
     public function stream_open($path, $mode, $options, &$openedPath)
     {
+        if ($path == 'http://throw_exception/') {
+            throw new \Exception;
+        }
+
         $query = parse_url($path, PHP_URL_QUERY);
         if ($query) {
             parse_str($query, $this->_query);
@@ -152,6 +156,32 @@ class StreamTest extends TestCase
     }
 
     /**
+     * Test stream error_handler cleanup when wrapper throws exception
+     *
+     * @return void
+     */
+    public function testSendWrapperException()
+    {
+        $stream = new Stream();
+        $request = new Request('http://throw_exception/');
+
+        $currentHandler = set_error_handler(function () {
+        });
+        restore_error_handler();
+
+        try {
+            $stream->send($request, []);
+        } catch (\Exception $e) {
+        }
+
+        $newHandler = set_error_handler(function () {
+        });
+        restore_error_handler();
+
+        $this->assertEquals($currentHandler, $newHandler);
+    }
+
+    /**
      * Test building the context headers
      *
      * @return void

+ 21 - 0
tests/TestCase/View/Form/FormContextTest.php

@@ -94,6 +94,27 @@ class FormContextTest extends TestCase
     }
 
     /**
+     * Test reading values from form data.
+     */
+    public function testValPresentInForm()
+    {
+        $form = new Form();
+        $form->setData(['title' => 'set title']);
+
+        $context = new FormContext($this->request, ['entity' => $form]);
+
+        $this->assertEquals('set title', $context->val('title'));
+        $this->assertNull($context->val('Articles.body'));
+
+        $this->request = $this->request->withParsedBody([
+            'title' => 'New title',
+        ]);
+        $context = new FormContext($this->request, ['entity' => $form]);
+
+        $this->assertEquals('New title', $context->val('title'));
+    }
+
+    /**
      * Test getting values when the request and defaults are missing.
      *
      * @return void

+ 4 - 5
tests/TestCase/View/Helper/FlashHelperTest.php

@@ -37,9 +37,8 @@ class FlashHelperTest extends TestCase
     public function setUp()
     {
         parent::setUp();
-        $this->View = new View();
         $session = new Session();
-        $this->View->request = new ServerRequest(['session' => $session]);
+        $this->View = new View(new ServerRequest(['session' => $session]));
         $this->Flash = new FlashHelper($this->View);
 
         $session->write([
@@ -143,7 +142,7 @@ class FlashHelperTest extends TestCase
     public function testFlashThrowsException()
     {
         $this->expectException(\UnexpectedValueException::class);
-        $this->View->request->getSession()->write('Flash.foo', 'bar');
+        $this->View->getRequest()->getSession()->write('Flash.foo', 'bar');
         $this->Flash->render('foo');
     }
 
@@ -217,7 +216,7 @@ class FlashHelperTest extends TestCase
             ['div' => ['id' => 'classy-message']], 'Recorded', '/div'
         ];
         $this->assertHtml($expected, $result);
-        $this->assertNull($this->View->request->getSession()->read('Flash.stack'));
+        $this->assertNull($this->View->getRequest()->getSession()->read('Flash.stack'));
     }
 
     /**
@@ -228,7 +227,7 @@ class FlashHelperTest extends TestCase
      */
     public function testFlashWithPrefix()
     {
-        $this->View->request = $this->View->request->withParam('prefix', 'Admin');
+        $this->View->setRequest($this->View->getRequest()->withParam('prefix', 'Admin'));
         $result = $this->Flash->render('flash');
         $expected = 'flash element from Admin prefix folder';
         $this->assertContains($expected, $result);

+ 5 - 5
tests/TestCase/View/JsonViewTest.php

@@ -292,15 +292,15 @@ class JsonViewTest extends TestCase
         $output = $View->render(false);
 
         $this->assertSame(json_encode($data), $output);
-        $this->assertSame('application/json', $View->response->getType());
+        $this->assertSame('application/json', $View->getResponse()->getType());
 
-        $View->request = $View->request->withQueryParams(['callback' => 'jfunc']);
+        $View->request = $View->getRequest()->withQueryParams(['callback' => 'jfunc']);
         $output = $View->render(false);
         $expected = 'jfunc(' . json_encode($data) . ')';
         $this->assertSame($expected, $output);
-        $this->assertSame('application/javascript', $View->response->getType());
+        $this->assertSame('application/javascript', $View->getResponse()->getType());
 
-        $View->request = $View->request->withQueryParams(['jsonCallback' => 'jfunc']);
+        $View->request = $View->getRequest()->withQueryParams(['jsonCallback' => 'jfunc']);
         $View->viewVars['_jsonp'] = 'jsonCallback';
         $output = $View->render(false);
         $expected = 'jfunc(' . json_encode($data) . ')';
@@ -336,6 +336,6 @@ class JsonViewTest extends TestCase
 
         $expected = json_encode(['user' => 'fake', 'list' => ['item1', 'item2'], 'paging' => null]);
         $this->assertSame($expected, $output);
-        $this->assertSame('application/json', $View->response->getType());
+        $this->assertSame('application/json', $View->getResponse()->getType());
     }
 }

+ 2 - 2
tests/TestCase/View/ViewBuilderTest.php

@@ -176,8 +176,8 @@ class ViewBuilderTest extends TestCase
         $this->assertEquals('Admin/', $view->getLayoutPath());
         $this->assertEquals('TestPlugin', $view->plugin);
         $this->assertEquals('TestTheme', $view->theme);
-        $this->assertSame($request, $view->request);
-        $this->assertInstanceOf(Response::class, $view->response);
+        $this->assertSame($request, $view->getRequest());
+        $this->assertInstanceOf(Response::class, $view->getResponse());
         $this->assertSame($events, $view->getEventManager());
         $this->assertSame(['one' => 'value'], $view->viewVars);
         $this->assertInstanceOf('Cake\View\Helper\HtmlHelper', $view->Html);

+ 5 - 5
tests/TestCase/View/XmlViewTest.php

@@ -52,7 +52,7 @@ class XmlViewTest extends TestCase
         $output = $View->render(false);
 
         $this->assertSame(Xml::build($data)->asXML(), $output);
-        $this->assertSame('application/xml', $View->response->getType());
+        $this->assertSame('application/xml', $View->getResponse()->getType());
 
         $data = [
             [
@@ -190,7 +190,7 @@ class XmlViewTest extends TestCase
         $Controller->set('_serialize', ['no', 'user']);
         $Controller->viewBuilder()->setClassName('Xml');
         $View = $Controller->createView();
-        $this->assertSame('application/xml', $View->response->getType());
+        $this->assertSame('application/xml', $View->getResponse()->getType());
         $output = $View->render(false);
         $expected = [
             'response' => ['no' => $data['no'], 'user' => $data['user']]
@@ -222,7 +222,7 @@ class XmlViewTest extends TestCase
         $Controller->set('_serialize', ['new_name' => 'original_name', 'user']);
         $Controller->viewBuilder()->setClassName('Xml');
         $View = $Controller->createView();
-        $this->assertSame('application/xml', $View->response->getType());
+        $this->assertSame('application/xml', $View->getResponse()->getType());
         $output = $View->render(false);
         $expected = [
             'response' => ['new_name' => $data['original_name'], 'user' => $data['user']]
@@ -256,7 +256,7 @@ class XmlViewTest extends TestCase
         $output = $View->render();
 
         $this->assertSame(Xml::build($data)->asXML(), $output);
-        $this->assertSame('application/xml', $View->response->getType());
+        $this->assertSame('application/xml', $View->getResponse()->getType());
 
         $data = ['no' => 'nope', 'user' => 'fake', 'list' => ['item1', 'item2']];
         $Controller->viewVars = [];
@@ -305,7 +305,7 @@ class XmlViewTest extends TestCase
         ];
         $expected = Xml::build($expected)->asXML();
         $this->assertSame($expected, $output);
-        $this->assertSame('application/xml', $View->response->getType());
+        $this->assertSame('application/xml', $View->getResponse()->getType());
         $this->assertInstanceOf('Cake\View\HelperRegistry', $View->helpers());
     }
 }

+ 24 - 0
tests/test_app/TestApp/Shell/AppShell.php

@@ -0,0 +1,24 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
+ * @link          https://cakephp.org CakePHP(tm) Project
+ * @since         3.6.5
+ * @license       https://opensource.org/licenses/mit-license.php MIT License
+ */
+namespace TestApp\Shell;
+
+use Cake\Console\Shell;
+
+/**
+ * Stub class to ensure inclusion in command list.
+ */
+class AppShell extends Shell
+{
+}