]> git.andy128k.dev Git - ipf.git/commitdiff
replace HTTP related code with PSR-7 compatible libraries
authorAndrey Kutejko <andy128k@gmail.com>
Fri, 12 Apr 2019 22:23:00 +0000 (00:23 +0200)
committerAndrey Kutejko <andy128k@gmail.com>
Sat, 4 May 2019 09:19:30 +0000 (11:19 +0200)
34 files changed:
composer.json
composer.lock
ipf.php
ipf/admin/app.php
ipf/admin/component.php
ipf/admin/controllers/base.php
ipf/admin/controllers/components.php
ipf/admin/controllers/dashboard.php
ipf/admin/controllers/file_browser.php
ipf/admin/controllers/user.php
ipf/admin/log.php
ipf/admin/templates/admin/items.html.twig
ipf/admin/templates/admin/log.html.twig
ipf/auth/app.php
ipf/auth/middleware.php
ipf/controller/base.php
ipf/error/500_debug.html
ipf/form/field/file.php
ipf/form/field/image.php
ipf/form/widget/fileinput.php
ipf/http/request.php [deleted file]
ipf/http/response.php
ipf/http/response/file.php [deleted file]
ipf/http/response/json.php [deleted file]
ipf/http/response/notfound.php [deleted file]
ipf/http/response/redirect.php [deleted file]
ipf/middleware/base.php
ipf/middleware/common.php
ipf/middleware/dispatch.php
ipf/middleware/error.php
ipf/middleware/serve_static.php
ipf/router.php
ipf/session/middleware.php
ipf/template.php

index 32330a90321827d29e10fafbe663cc81b2a0ef54..d0277c9048268e3f5a07fa74756648ecb6011e92 100644 (file)
     "classmap" : ["."]
   },
   "require": {
+    "psr/http-message": "~1.0",
+    "guzzlehttp/psr7": "^1",
     "pear/archive_tar": "1.3.*",
     "doctrine/dbal": "^2.5",
     "d11wtq/boris": "~1",
     "andy128k/missing-tools": "~0.3",
     "andy128k/pegp": "~0.2",
     "pimple/pimple": "~3.0",
-    "twig/twig": "~1"
+    "twig/twig": "~1",
+    "http-interop/response-sender": "^1.0",
+    "dflydev/fig-cookies": "^1.0"
   },
   "require-dev": {
     "phpunit/phpunit": "~5"
index 18902b1104fd3f49358ed0f255c808f3e46bc4b8..509f1bbb6a1cf2dd5f7b2c8027357fcacf2b4cd8 100644 (file)
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "644aeae9afe6d53dd080f9d189b994f5",
+    "content-hash": "033acffc1357df5be748520f701b68c8",
     "packages": [
         {
             "name": "andy128k/missing-tools",
             "description": "A tiny, but robust REPL (Read-Evaluate-Print-Loop) for PHP.",
             "time": "2015-03-01T08:05:19+00:00"
         },
+        {
+            "name": "dflydev/fig-cookies",
+            "version": "v1.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/dflydev/dflydev-fig-cookies.git",
+                "reference": "883233c159d00d39e940bd12cfe42c0d23420c1c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/dflydev/dflydev-fig-cookies/zipball/883233c159d00d39e940bd12cfe42c0d23420c1c",
+                "reference": "883233c159d00d39e940bd12cfe42c0d23420c1c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4",
+                "psr/http-message": "~1.0"
+            },
+            "require-dev": {
+                "codeclimate/php-test-reporter": "~0.1@dev",
+                "phpunit/phpunit": "~4.5",
+                "squizlabs/php_codesniffer": "~2.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Dflydev\\FigCookies\\": "src/Dflydev/FigCookies"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Beau Simensen",
+                    "email": "beau@dflydev.com"
+                }
+            ],
+            "description": "Cookies for PSR-7 HTTP Message Interface.",
+            "keywords": [
+                "cookies",
+                "psr-7",
+                "psr7"
+            ],
+            "time": "2016-03-28T09:10:18+00:00"
+        },
         {
             "name": "doctrine/annotations",
             "version": "v1.4.0",
             ],
             "time": "2014-09-09T13:34:57+00:00"
         },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "1.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "9f83dded91781a01c63574e387eaa769be769115"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
+                "reference": "9f83dded91781a01c63574e387eaa769be769115",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.4.0",
+                "psr/http-message": "~1.0",
+                "ralouphie/getallheaders": "^2.0.5"
+            },
+            "provide": {
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.5-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "homepage": "https://github.com/Tobion"
+                }
+            ],
+            "description": "PSR-7 message implementation that also provides common utility methods",
+            "keywords": [
+                "http",
+                "message",
+                "psr-7",
+                "request",
+                "response",
+                "stream",
+                "uri",
+                "url"
+            ],
+            "time": "2018-12-04T20:46:45+00:00"
+        },
+        {
+            "name": "http-interop/response-sender",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/http-interop/response-sender.git",
+                "reference": "fd63be06cd6c9216ef3c725af1a3f6b155eebc84"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/http-interop/response-sender/zipball/fd63be06cd6c9216ef3c725af1a3f6b155eebc84",
+                "reference": "fd63be06cd6c9216ef3c725af1a3f6b155eebc84",
+                "shasum": ""
+            },
+            "require": {
+                "psr/http-message": "^1.0"
+            },
+            "require-dev": {
+                "guzzlehttp/psr7": "^1.4",
+                "php-mock/php-mock-phpunit": "^1.1",
+                "phpunit/phpunit": "^5.6"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/functions.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Woody Gilk",
+                    "email": "woody.gilk@gmail.com"
+                }
+            ],
+            "description": "A function to convert PSR-7 Response to HTTP output",
+            "time": "2017-03-17T15:46:19+00:00"
+        },
         {
             "name": "pear/archive_tar",
             "version": "1.3.16",
             ],
             "time": "2017-02-14T16:28:37+00:00"
         },
+        {
+            "name": "psr/http-message",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-message.git",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP messages",
+            "homepage": "https://github.com/php-fig/http-message",
+            "keywords": [
+                "http",
+                "http-message",
+                "psr",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "time": "2016-08-06T14:39:51+00:00"
+        },
+        {
+            "name": "ralouphie/getallheaders",
+            "version": "2.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ralouphie/getallheaders.git",
+                "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
+                "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~3.7.0",
+                "satooshi/php-coveralls": ">=1.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/getallheaders.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ralph Khattar",
+                    "email": "ralph.khattar@gmail.com"
+                }
+            ],
+            "description": "A polyfill for getallheaders.",
+            "time": "2016-02-11T07:05:27+00:00"
+        },
         {
             "name": "symfony/polyfill-ctype",
-            "version": "v1.10.0",
+            "version": "v1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "e3d826245268269cd66f8326bd8bc066687b4a19"
+                "reference": "82ebae02209c21113908c229e9883c419720738a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19",
-                "reference": "e3d826245268269cd66f8326bd8bc066687b4a19",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
+                "reference": "82ebae02209c21113908c229e9883c419720738a",
                 "shasum": ""
             },
             "require": {
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.9-dev"
+                    "dev-master": "1.11-dev"
                 }
             },
             "autoload": {
                 "polyfill",
                 "portable"
             ],
-            "time": "2018-08-06T14:22:27+00:00"
+            "time": "2019-02-06T07:57:58+00:00"
         },
         {
             "name": "twig/twig",
-            "version": "v1.38.2",
+            "version": "v1.38.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "874adbd9222f928f6998732b25b01b41dff15b0c"
+                "reference": "7732e9e7017d751313811bd118de61302e9c8b35"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/874adbd9222f928f6998732b25b01b41dff15b0c",
-                "reference": "874adbd9222f928f6998732b25b01b41dff15b0c",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/7732e9e7017d751313811bd118de61302e9c8b35",
+                "reference": "7732e9e7017d751313811bd118de61302e9c8b35",
                 "shasum": ""
             },
             "require": {
             "keywords": [
                 "templating"
             ],
-            "time": "2019-03-12T18:45:24+00:00"
+            "time": "2019-03-23T14:27:19+00:00"
         }
     ],
     "packages-dev": [
         },
         {
             "name": "symfony/yaml",
-            "version": "v3.4.23",
+            "version": "v3.4.24",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "57f1ce82c997f5a8701b89ef970e36bb657fd09c"
+                "reference": "212a27b731e5bfb735679d1ffaac82bd6a1dc996"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/57f1ce82c997f5a8701b89ef970e36bb657fd09c",
-                "reference": "57f1ce82c997f5a8701b89ef970e36bb657fd09c",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/212a27b731e5bfb735679d1ffaac82bd6a1dc996",
+                "reference": "212a27b731e5bfb735679d1ffaac82bd6a1dc996",
                 "shasum": ""
             },
             "require": {
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2019-02-23T15:06:07+00:00"
+            "time": "2019-03-25T07:48:46+00:00"
         },
         {
             "name": "webmozart/assert",
diff --git a/ipf.php b/ipf.php
index 8f4b15b57d654c4396f6b599d13978da5c719e1a..d110ae2942424a8ffa16500366252d80fb92f873 100644 (file)
--- a/ipf.php
+++ b/ipf.php
@@ -1,5 +1,6 @@
 <?php
 
+use GuzzleHttp\Psr7\ServerRequest;
 use IPF\BootstrapProvider;
 use Pimple\Container;
 
@@ -34,11 +35,11 @@ final class IPF
         if (php_sapi_name() === 'cli') {
             $container['cli']->run();
         } else {
-            $request = new IPF_HTTP_Request;
+            $request = ServerRequest::fromGlobals();
 
             $pipeline = $container['pipeline'];
             $response = $pipeline->call($request);
-            $response->render($request->method !== 'HEAD');
+            \Http\Response\send($response);
         }
     }
 
index 457717ecb3b9e0c6700b72993f3777022b5ecdc6..2e57a2bd08f4fd329bb187de63dfbd6b0f2659a7 100644 (file)
@@ -162,7 +162,7 @@ class IPF_Admin_LoginRequired extends IPF_Router_Shortcut
         /** @var IPF_Router $router */
         $router = $container['router'];
         $loginPage = $router->reverse(['IPF_Admin_User_Controller', 'login']);
-        return new IPF_HTTP_Response_Redirect($loginPage);
+        return IPF_HTTP_Response::redirect($loginPage);
     }
 }
 
@@ -170,6 +170,6 @@ class IPF_Admin_AccessDenied extends IPF_Router_Shortcut
 {
     public function response($container, $request)
     {
-        return new IPF_HTTP_Response_NotFound($container, $request);
+        return IPF_HTTP_Response::notFound($container, $request);
     }
 }
index 2785abc860f81ac7b01c538d8203665d5f8ff063..78d7fc645f395dadc1d526c0442935bb3cbe26b9 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use PFF\HtmlBuilder\Tag as Tag;
+use Psr\Http\Message\ServerRequestInterface;
 
 interface IPF_Admin_ListFilter
 {
@@ -13,7 +14,9 @@ interface IPF_Admin_ListFilter
 abstract class IPF_Admin_Component
 {
     public $perPage = 50;
-    public $app = null, $request = null;
+    public $app = null;
+    /** @var ServerRequestInterface */
+    public $request = null;
     /** @var IPF_Admin_ILog|null */
     public $admin_log;
     /** @var IPF_Auth_App */
@@ -46,7 +49,7 @@ abstract class IPF_Admin_Component
         return array('view', 'add', 'change', 'delete');
     }
 
-    public function isAccessible($what, $request)
+    public function isAccessible($what, ServerRequestInterface $request)
     {
         if (!$request)
             throw new IPF_Exception('No request.');
@@ -59,7 +62,7 @@ abstract class IPF_Admin_Component
             return $prefix . $action;
         }, $what);
 
-        return $this->auth_app->userCan($request->user, $authPermissions);
+        return $this->auth_app->userCan($request->getAttribute('user'), $authPermissions);
     }
 
     protected function context($request)
@@ -165,17 +168,17 @@ abstract class IPF_Admin_Component
     protected function referrerOfChangeAction()
     {
         return
-            \PFF\Arr::get($this->request->REQUEST, 'ipf_referrer',
-            \PFF\Arr::get($this->request->SERVER, 'HTTP_REFERER',
+            \PFF\Arr::get(array_merge((array)$this->request->getQueryParams(), (array)$this->request->getParsedBody()), 'ipf_referrer',
+            \PFF\Arr::get($this->request->getServerParams(), 'HTTP_REFERER',
             ''));
     }
 
     protected function changeSucceed()
     {
-        $url = @$this->request->POST['ipf_referrer'];
+        $url = @$this->request->getParsedBody()['ipf_referrer'];
         if (!$url)
             $url = $this->router->reverse(array('IPF_Admin_Components_Controller', 'listItems'), array($this->app->slug(), $this->slug()));
-        return new IPF_HTTP_Response_Redirect($url);
+        return IPF_HTTP_Response::redirect($url);
     }
 
     public function addItem()
@@ -187,8 +190,8 @@ abstract class IPF_Admin_Component
         );
 
         $errors = false;
-        if ($this->request->method == 'POST') {
-            $form = $this->_getAddForm(null, $this->request->getFormData(), $extra);
+        if ($this->request->getMethod() == 'POST') {
+            $form = $this->_getAddForm(null, array_merge_recursive($this->request->getParsedBody(), $this->request->getUploadedFiles()), $extra);
             $this->_setupAddForm($form);
 
             if ($form->isValid()) {
@@ -227,7 +230,7 @@ abstract class IPF_Admin_Component
         if (!$object)
             throw new IPF_HTTP_Error404;
 
-        if ($this->request->method == 'POST') {
+        if ($this->request->getMethod() == 'POST') {
             $this->admin_log->logObject($this, 'delete', $object);
             $this->deleteObject($object);
             return $this->changeSucceed();
@@ -255,8 +258,8 @@ abstract class IPF_Admin_Component
         );
 
         $errors = false;
-        if ($this->request->method == 'POST') {
-            $form = $this->_getEditForm($object, $this->request->getFormData(), $extra);
+        if ($this->request->getMethod() == 'POST') {
+            $form = $this->_getEditForm($object, array_merge_recursive($this->request->getParsedBody(), $this->request->getUploadedFiles()), $extra);
             $this->_setupEditForm($form);
 
             if ($form->isValid()) {
@@ -306,13 +309,15 @@ abstract class IPF_Admin_Component
 
     public function listItems()
     {
-        $searchValue = @$this->request->GET['q'];
+        $params = $this->request->getQueryParams();
+
+        $searchValue = @$params['q'];
 
         $filters = $this->listFilters();
         foreach ($filters as $f)
-            $f->setParams($this->request->GET);
+            $f->setParams($params);
 
-        $currentPage = (int)@$this->request->GET['page'];
+        $currentPage = (int)@$params['page'];
         if (!$currentPage)
             $currentPage = 1;
 
@@ -398,7 +403,7 @@ abstract class IPF_Admin_Component
 
     function renderFilter($filter)
     {
-        $params = $this->request->GET;
+        $params = $this->request->getQueryParams();
         $paramName = $filter->paramName();
 
         $ul = Tag::ul();
index 3eede9e8a1577dbece42cc3de4c287b5fa391efc..c3a8163dab3a909bd34b1c2274de0462a6054446 100644 (file)
@@ -1,20 +1,23 @@
 <?php
 
+use GuzzleHttp\Psr7\Response;
+
 abstract class IPF_Admin_Base_Controller extends IPF_Controller
 {
     protected function ensureUserIsStaff()
     {
-        if ($this->request->user->isAnonymous())
+        $user = $this->request->getAttribute('user');
+        if (!$user || $user->isAnonymous())
             throw new IPF_Admin_LoginRequired;
 
-        if (!$this->request->user->is_staff && !$this->request->user->is_superuser)
+        if (!$user->is_staff && !$user->is_superuser)
             throw new IPF_Admin_LoginRequired;
     }
 
     protected function render($template, $params)
     {
         $body = $this->container['template']->render($template, $params, $this->request);
-        return new IPF_HTTP_Response($body);
+        return new Response(200, [], $body);
     }
 
     /**
index b2c4dddf00d8073cdd5b6cc106f41920b2550ddf..c0c027880ad4245063a41b021b71b40c9138ed7e 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use Psr\Http\Message\ResponseInterface;
+
 class IPF_Admin_Components_Controller extends IPF_Admin_Base_Controller
 {
     function listItems()
@@ -42,13 +44,14 @@ class IPF_Admin_Components_Controller extends IPF_Admin_Base_Controller
     {
         $this->checkPermissions('view', 'change');
 
-        if (!isset($this->request->POST['ids']) || !is_array($this->request->POST['ids']))
-            return new IPF_HTTP_Response_NotFound($this->container, $this->request);
+        $post = $this->request->getParsedBody();
+        if (!isset($post['ids']) || !is_array($post['ids']))
+            return IPF_HTTP_Response::notFound($this->container, $this->request);
 
-        if ($this->component->reorder($this->request->POST['ids']))
-            return new IPF_HTTP_Response_Json("Ok");
+        if ($this->component->reorder($post['ids']))
+            return IPF_HTTP_Response::json("Ok");
         else
-            return new IPF_HTTP_Response_Json('Cannot find model');
+            return IPF_HTTP_Response::json('Cannot find model');
     }
 
     // protected
@@ -60,7 +63,8 @@ class IPF_Admin_Components_Controller extends IPF_Admin_Base_Controller
     {
         $this->ensureUserIsStaff();
 
-        $this->component = $this->adminApplication()->getComponentBySlugs($this->request->params[1], $this->request->params[2]);
+        $params = $this->request->getAttribute('params');
+        $this->component = $this->adminApplication()->getComponentBySlugs($params[1], $params[2]);
         if (!$this->component)
             throw new IPF_HTTP_Error404;
 
@@ -78,7 +82,7 @@ class IPF_Admin_Components_Controller extends IPF_Admin_Base_Controller
     protected function after__listItems__addItem__editItem__deleteItem($action, $response)
     {
         list($template, $context) = $response;
-        if ($context instanceof IPF_HTTP_Response)
+        if ($context instanceof ResponseInterface)
             return $context;
         else
             return $this->render($template, $context);
index 89462f27a4ca21c92724e5c1cdb15bbecd1ea697..30eeb8e42356418ec3f81e5c9a3fdc7fec05b691 100644 (file)
@@ -23,7 +23,7 @@ class IPF_Admin_Dashboard_Controller extends IPF_Admin_Base_Controller
 
     function log()
     {
-        $currentPage = (int)@$this->request->GET['page'];
+        $currentPage = (int)@$this->request->getQueryParams()['page'];
         if (!$currentPage)
             $currentPage = 1;
 
index c7b80a45ecdaa2d7bad9964e5e76842b7b238ba4..9ee70e224d84290027c3dfac5b2af82c8695874b 100644 (file)
@@ -24,10 +24,10 @@ class IPF_Admin_FileBrowser_Controller extends IPF_Admin_Base_Controller
 
     function listDirectory()
     {
-        $dir = $this->validateDirectory($this->request->GET['dir']);
+        $dir = $this->validateDirectory($this->request->getQueryParams()['dir']);
 
         list($dirs, $files) = self::listDir($dir);
-        return new IPF_HTTP_Response_Json([
+        return IPF_HTTP_Response::json([
             'dirs' => $dirs,
             'files' => $files,
         ]);
@@ -35,47 +35,52 @@ class IPF_Admin_FileBrowser_Controller extends IPF_Admin_Base_Controller
 
     function rename()
     {
-        $dir = $this->validateDirectory($this->request->POST['dir']);
-        $old_name = $this->validateName($this->request->POST['old_name']);
-        $new_name = $this->validateName($this->request->POST['new_name']);
+        $post = $this->request->getParsedBody();
+        $dir = $this->validateDirectory($post['dir']);
+        $old_name = $this->validateName($post['old_name']);
+        $new_name = $this->validateName($post['new_name']);
         rename($dir . $old_name, $dir . $new_name);
-        return $this->noContent();
+        return IPF_HTTP_Response::noContent();
     }
 
     function move()
     {
-        $dir = $this->validateDirectory($this->request->POST['dir']);
-        $destination = $this->validateDirectory($this->request->POST['destination']);
-        $name = $this->validateName($this->request->POST['name']);
+        $post = $this->request->getParsedBody();
+        $dir = $this->validateDirectory($post['dir']);
+        $destination = $this->validateDirectory($post['destination']);
+        $name = $this->validateName($post['name']);
 
         rename($dir . $name, $destination . $name);
-        return $this->noContent();
+        return IPF_HTTP_Response::noContent();
     }
 
     function mkdir()
     {
-        $dir = $this->validateDirectory($this->request->POST['dir']);
-        $name = $this->validateName($this->request->POST['name']);
+        $post = $this->request->getParsedBody();
+        $dir = $this->validateDirectory($post['dir']);
+        $name = $this->validateName($post['name']);
         mkdir($dir . $name);
-        return $this->noContent();
+        return IPF_HTTP_Response::noContent();
     }
 
     function delete()
     {
-        $dir = $this->validateDirectory($this->request->POST['dir']);
-        $name = $this->validateName($this->request->POST['name']);
+        $post = $this->request->getParsedBody();
+        $dir = $this->validateDirectory($post['dir']);
+        $name = $this->validateName($post['name']);
         IPF_Utils::removeDirectories($dir . $name);
-        return $this->noContent();
+        return IPF_HTTP_Response::noContent();
     }
 
     function upload()
     {
-        $dir = $this->validateDirectory($this->request->POST['dir']);
-        foreach ($this->request->FILES['files'] as $file) {
+        $post = $this->request->getParsedBody();
+        $dir = $this->validateDirectory($post['dir']);
+        foreach ($this->request->getUploadedFiles()['files'] as $file) {
             $uploadfile = $dir . basename($file['name']);
             move_uploaded_file($file['tmp_name'], $uploadfile);
         }
-        return $this->noContent();
+        return IPF_HTTP_Response::noContent();
     }
 
     private function validateDirectory($path)
@@ -155,14 +160,4 @@ class IPF_Admin_FileBrowser_Controller extends IPF_Admin_Base_Controller
             return 0;
         return ($a['name'] < $b['name']) ? -1 : 1;
     }
-
-    /**
-     * @return IPF_HTTP_Response
-     */
-    private function noContent()
-    {
-        $response = new IPF_HTTP_Response();
-        $response->status_code = 204;
-        return $response;
-    }
 }
index 81eff8dc2f17ec338e2268bfe4debb3194a04db2..912e73a2e6b2f0017f3d06dd0408c6e0a2742215 100644 (file)
@@ -16,21 +16,19 @@ class IPF_Admin_User_Controller extends IPF_Admin_Base_Controller
 
     function login()
     {
-        $success_url = trim(\PFF\Arr::get($this->request->REQUEST, 'next', ''));
-        if (!$success_url)
-            $success_url = $this->container['router']->reverse(array('IPF_Admin_Dashboard_Controller', 'index'));
+        $success_url = $this->getNextUrl();
 
         $auth_app = $this->authApp();
         $auth_serice = $this->container['auth_service'];
 
-        if ($this->request->method == 'POST') {
-            $form = new IPF_Admin_Forms_Login($this->request->POST, array('auth_app' => $auth_app, 'auth_service' => $auth_serice));
+        if ($this->request->getMethod() == 'POST') {
+            $form = new IPF_Admin_Forms_Login($this->request->getParsedBody(), array('auth_app' => $auth_app, 'auth_service' => $auth_serice));
             if ($form->isValid()) {
                 $auth_app->login($this->request, $form->user);
-                return new IPF_HTTP_Response_Redirect($success_url);
+                return IPF_HTTP_Response::redirect($success_url);
             }
         } else {
-            $form = new IPF_Admin_Forms_Login(array('next'=>$success_url), array('auth_app' => $auth_app, 'auth_service' => $auth_serice));
+            $form = new IPF_Admin_Forms_Login(array('next' => $success_url), array('auth_app' => $auth_app, 'auth_service' => $auth_serice));
         }
 
         $context = array(
@@ -51,17 +49,31 @@ class IPF_Admin_User_Controller extends IPF_Admin_Base_Controller
 
     function impersonate()
     {
-        $success_url = trim(\PFF\Arr::get($this->request->REQUEST, 'next', ''));
-        if (!$success_url)
-            $success_url = $this->container['router']->reverse(array('IPF_Admin_Dashboard_Controller', 'index'));
+        $success_url = $this->getNextUrl();
 
-        if (!$this->request->user->isAnonymous() && $this->request->user->is_superuser) {
+        $user1 = $this->request->getAttribute('user');
+        if (!$user1->isAnonymous() && $user1->is_superuser) {
             $user = $this->authApp()->findUser($this->params[1]);
             if (!$user)
-                return new IPF_HTTP_Response_NotFound($this->container, $this->request);
+                return IPF_HTTP_Response::notFound($this->container, $this->request);
             $this->authApp()->login($this->request, $user);
         }
 
-        return new IPF_HTTP_Response_Redirect($success_url);
+        return IPF_HTTP_Response::redirect($success_url);
+    }
+
+    /**
+     * @return string
+     */
+    private function getNextUrl()
+    {
+        return \PFF\Arr::get(
+            array_merge(
+                (array)$this->request->getQueryParams(),
+                (array)$this->request->getParsedBody()
+            ),
+            'next',
+            $this->container['router']->reverse(array('IPF_Admin_Dashboard_Controller', 'index'))
+        );
     }
 }
index 3750655213daadeac910eebdd0c2717fad4b8b48..4a27d12de5613fdab2623b2182adca69c32b1177 100644 (file)
@@ -30,7 +30,7 @@ interface IPF_Admin_ILog {
      * @param mixed $object
      * @param int|null $object_id
      */
-    public function logObject($component, $action, $object, $object_id=null);
+    public function logObject(IPF_Admin_Component $component, $action, $object, $object_id=null);
 }
 
 class IPF_Admin_Log implements IPF_Admin_ILog
@@ -79,11 +79,11 @@ class IPF_Admin_Log implements IPF_Admin_ILog
         $stmt->execute();
     }
 
-    public function logObject($component, $action, $object, $object_id=null)
+    public function logObject(IPF_Admin_Component $component, $action, $object, $object_id=null)
     {
         $url = $object_id
             ? $this->router->reverse(['IPF_Admin_Components_Controller', 'editItem'], [$component->app->slug(), $component->slug(), $object_id])
             : '';
-        $this->log($component->request->user, $action, (string)$object, $component->verbose_name(), $url);
+        $this->log($component->request->getAttribute('user'), $action, (string)$object, $component->verbose_name(), $url);
     }
 }
index 233cccf0f9be62e76b2fd84da666bd35bd1a1eae..f748df6bd0cb052008a95f58baf24b9ed5b93eba 100644 (file)
@@ -17,7 +17,7 @@
       <div id="toolbar">
         <form id="changelist-search" method="get" action="">
           <div>
-            {% for k, v in request.GET %}
+            {% for k, v in request.getQueryParams %}
               {% if k != 'q' %}
                 <input type="hidden" name="{{ k }}" value="{{ v }}">
               {% endif %}
@@ -28,7 +28,7 @@
             <input id="searchbar" type="text" value="{{ search_value }}" name="q" size="40"/>
             <input type="submit" value="Go"/>
             {% if search_value %}
-            <span class="small quiet">{{ count }} results (<a href="?{{ params(request.GET, 'q', null) }}">reset</a>)</span>
+            <span class="small quiet">{{ count }} results (<a href="?{{ params(request.getQueryParams, 'q', null) }}">reset</a>)</span>
             {% endif %}
           </div>
         </form>
@@ -72,7 +72,7 @@
               {% if p == current_page %}
                 <span class="this-page">{{ p }}</span>
               {% else %}
-                <a href="?{{ params(request.GET, 'page', p) }}">{{ p }}</a>
+                <a href="?{{ params(request.getQueryParams, 'page', p) }}">{{ p }}</a>
               {% endif %}
             {% else %}
               &hellip;
index 59e05fd975963663dfe897224d12490e9108462c..4cd7d1d876427285611c98a49b8888633566220d 100644 (file)
@@ -42,7 +42,7 @@
               {% if p == current_page %}
                 <span class="this-page">{{ p }}</span>
               {% else %}
-                <a href="?{{ params(request.GET, 'page', p) }}">{{ p }}</a>
+                <a href="?{{ params(request.getQueryParams, 'page', p) }}">{{ p }}</a>
               {% endif %}
             {% else %}
               &hellip;
index df14637be21538b4529798ec2bad0bdc85f6d4c2..eeb28b9220c74f12390bf15295c392568b1cba54 100644 (file)
@@ -4,6 +4,7 @@ use Doctrine\DBAL\Connection;
 use IPF\Auth\AuthServiceDefault;
 use IPF\Auth\User;
 use Pimple\Container;
+use Psr\Http\Message\ServerRequestInterface;
 
 class IPF_Auth_App extends IPF_Application
 {
@@ -51,20 +52,18 @@ class IPF_Auth_App extends IPF_Application
         return new $className;
     }
 
-    function login($request, $user)
+    function login(ServerRequestInterface $request, $user)
     {
-        $request->user = $user;
-        $request->session->data = array(
-            'login_time' => gmdate('Y-m-d H:i:s')
-        );
+        $session = $request->getAttribute('session');
+        $session->data[\IPF\Auth\Middleware::SessionKey] = $user->id;
+        $session->data['login_time'] = gmdate('Y-m-d H:i:s');
     }
 
-    function logout($request)
+    function logout(ServerRequestInterface $request)
     {
-        $request->user = new \IPF\Auth\AnonymousUser;
-        $request->session->data = array(
-            'login_time' => gmdate('Y-m-d H:i:s')
-        );
+        $session = $request->getAttribute('session');
+        unset($session->data[\IPF\Auth\Middleware::SessionKey]);
+        $session->data['login_time'] = gmdate('Y-m-d H:i:s');
     }
 
     private $permissionsEnabled = null;
index c924d0912503992fd9d268910d1283418e6c3208..73c7c3dfa9cc1c7698bd72789d53811fea4f2255 100644 (file)
@@ -3,34 +3,34 @@
 namespace IPF\Auth;
 
 use Doctrine\DBAL\Connection;
+use Psr\Http\Message\ServerRequestInterface;
 
 class Middleware extends \IPF_Middleware
 {
     const SessionKey = 'IPF_User_auth';
 
-    function processRequest($request)
+    function call(ServerRequestInterface $request)
     {
-        $request->user = null;
+        $session = $request->getAttribute('session');
+        $user = null;
 
-        $user_id = \PFF\Arr::get($request->session->data, self::SessionKey, 0);
+        $user_id = \PFF\Arr::get($session->data, self::SessionKey, 0);
         if ($user_id > 0) {
             $connection = $this->getConnection();
-            $request->user = $this->getAuthApp()->findUser($user_id);
-            if ($request->user && 43200 < time() - strtotime($request->user->last_login.' GMT')) {
-                $request->user->last_login = gmdate('Y-m-d H:i:s');
-                $request->user->save($connection);
+            $user = $this->getAuthApp()->findUser($user_id);
+            if ($user && 43200 < time() - strtotime($user->last_login.' GMT')) {
+                $user->last_login = gmdate('Y-m-d H:i:s');
+                $user->save($connection);
             }
         }
 
-        if (!$request->user)
-            $request->user = new \IPF\Auth\AnonymousUser;
+        if (!$user)
+            $user = new \IPF\Auth\AnonymousUser;
 
-        return false;
-    }
+        $response = $this->next->call(
+            $request->withAttribute('user', $user)
+        );
 
-    function processResponse($request, $response)
-    {
-        $request->session->data[self::SessionKey] = $request->user->id;
         return $response;
     }
 
index c1b7fcfc2fe462245da5ec776509065e6e7bc9db..b813b82a3cbeba4684f3f7a5d7f62e3345deddd7 100644 (file)
@@ -1,10 +1,12 @@
 <?php
 
 use Pimple\Container;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
 
 class IPF_Controller
 {
-    /** @var IPF_HTTP_Request */
+    /** @var ServerRequestInterface */
     protected $request;
     protected $params;
     /** @var Container */
@@ -21,7 +23,7 @@ class IPF_Controller
         $this->params = $matches;
 
         $response = $this->before($action);
-        if ($response instanceof IPF_HTTP_Response)
+        if ($response instanceof ResponseInterface)
             return $response;
 
         $response = $this->$action();
index 2780ae72575705e15b9aae0f85a7da90e8a1d1b4..60c09426908a24e7b05f9d3ea68aed0aaa873e61 100644 (file)
@@ -1,6 +1,9 @@
 <?php
 
-$desc = get_class($this->exception) . ' making ' . $this->request->method . ' request to ' . $this->request->SERVER['REQUEST_URI'];
+/** @var \Psr\Http\Message\ServerRequestInterface $request */
+$request = $this->request;
+
+$desc = get_class($this->exception) . ' making ' . $request->getMethod() . ' request to ' . $request->getRequestTarget();
 
 $msg = $this->exception->getMessage();
 if ($this->exception->getCode())
@@ -52,7 +55,7 @@ $frames = $this->frames($this->exception);
   <div id="summary">
     <h1><?php $this->e($desc) ?></h1>
     <h2><?php $this->e($msg) ?></h2>
-    <p><?php echo $this->request->method ?> <?php $this->e($this->request->SERVER['REQUEST_URI']) ?></p>
+    <p><?php echo $request->getMethod() ?> <?php $this->e($request->getRequestTarget()) ?></p>
   </div>
   <!-- /Summary -->
 
@@ -90,11 +93,11 @@ $frames = $this->frames($this->exception);
 
       <?php $this->values('$_ENV', $_ENV) ?>
 
-      <?php $this->values('Raw Headers', $this->request->getHeaders()) ?>
+      <?php $this->values('Raw Headers', $request->getHeaders()) ?>
 
-      <?php if ($this->request->getBody()): ?>
+      <?php if ($request->getBody()): ?>
         <h3>Raw Body</h3>
-        <div class="dump"><?php $this->e($this->request->getBody()) ?></div>
+        <div class="dump"><?php $this->e((string)$request->getBody()) ?></div>
       <?php endif; ?>
     </div>
 
index 93b01b58cbdb8141df5127c5e0a2104d8b98179b..3cb12e45e3d23a0fda4778e7dac5b6e00c6f769a 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+use GuzzleHttp\Psr7\UploadedFile;
+
 class IPF_Form_Field_File extends IPF_Form_Field
 {
     public $widget = 'IPF_Form_Widget_FileInput';
@@ -61,7 +63,9 @@ class IPF_Form_Field_File extends IPF_Form_Field
             return IPF_Utils::cleanFileName($value['name'], $this->getAbsolutePath('')); // initial
         }
 
-        switch (\PFF\Arr::get($value['file'], 'error')) {
+        /** @var UploadedFile $data */
+        $data = $value['file'];
+        switch ($data->getError()) {
         case UPLOAD_ERR_OK:
             break;
         default:
@@ -70,8 +74,7 @@ class IPF_Form_Field_File extends IPF_Form_Field
             return $oldname;
         }
 
-        $data = $value['file'];
-        switch ($data['error']) {
+        switch ($data->getError()) {
             case UPLOAD_ERR_OK:
                 break;
             case UPLOAD_ERR_INI_SIZE:
@@ -89,16 +92,15 @@ class IPF_Form_Field_File extends IPF_Form_Field
             default:
                 throw new IPF_Exception_Form(__('An error occured when upload the file. Please try to send the file again.'));
         }
-        if ($data['size'] > $this->max_size) {
+        if ($data->getSize() > $this->max_size) {
             throw new IPF_Exception_Form(sprintf(__('The uploaded file is to big (%1$s). Reduce the size to less than %2$s and try again.'),
-                                        IPF_Utils::prettySize($data['size']),
+                                        IPF_Utils::prettySize($data->getSize()),
                                         IPF_Utils::prettySize($this->max_size)));
         }
 
-        $name = IPF_Utils::cleanFileName($data['name'], $this->getAbsolutePath(''));
+        $name = IPF_Utils::cleanFileName($data->getClientFilename(), $this->getAbsolutePath(''));
         $dest = $this->getAbsolutePath($name);
-        if (!move_uploaded_file($data['tmp_name'], $dest))
-            throw new IPF_Exception_Form(__('An error occured when upload the file. Please try to send the file again.'));
+        $data->moveTo($dest);
         @chmod($dest, $this->file_permission);
         return $this->getRelativePath($name);
     }
index 907b6407d9312c4527880df7cf1f96db5f41c2c6..6ed84408c4696d0a39b499b3ebd92bd3df75aec9 100644 (file)
@@ -15,4 +15,3 @@ class IPF_Form_Field_Image extends IPF_Form_Field_File
         return $name;
     }
 }
-
index b78679166202f85053f41d303789de1ff12d2379..dd532baef3d280e2c738d6c8a3cce238059e435a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 
-use \PFF\HtmlBuilder\Tag as Tag;
+use PFF\HtmlBuilder\Tag as Tag;
 
 class IPF_Form_Widget_FileInput extends IPF_Form_Widget_Input
 {
@@ -62,7 +62,7 @@ class IPF_Form_Widget_FileInput extends IPF_Form_Widget_Input
 
         $value = $data[$name];
 
-        if (isset($value['file']) && isset($value['file']['error']) && $value['file']['error'] === UPLOAD_ERR_NO_FILE)
+        if (isset($value['file']) && $value['file']->getError() === UPLOAD_ERR_NO_FILE)
             unset($value['file']);
 
         if (!isset($value['file']) && !isset($value['name']))
diff --git a/ipf/http/request.php b/ipf/http/request.php
deleted file mode 100644 (file)
index d946710..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-class IPF_HTTP_Request
-{
-    public $POST = array();
-    public $GET = array();
-    public $REQUEST = array();
-    public $COOKIE = array();
-    public $FILES = array();
-    public $query = '';
-    public $method = '';
-    public $uri = '';
-    public $view = '';
-    public $remote_addr = '';
-    public $http_host = '';
-    public $SERVER = array();
-    public $is_secure = false;
-    public $path_info;
-
-    public function __construct()
-    {
-        $this->POST = $_POST;
-        $this->GET = $_GET;
-        $this->REQUEST = $_REQUEST;
-        $this->COOKIE = $_COOKIE;
-        $this->FILES = self::saneFiles($_FILES);
-        $this->method = $_SERVER['REQUEST_METHOD'];
-        $this->uri = $_SERVER['REQUEST_URI'];
-        $this->remote_addr = $_SERVER['REMOTE_ADDR'];
-        $this->http_host = $_SERVER['HTTP_HOST'];
-
-        if (isset($_SERVER['REQUEST_URI'])) {
-            $uri = $_SERVER['REQUEST_URI'];
-            $pq = strpos($uri,'?');
-            if ($pq !== false)
-                $uri = substr($uri, 0, $pq);
-            $this->query = preg_replace('#^(//+)#', '/', '/'.$uri);
-        } else {
-            $this->query = '/';
-        }
-
-        if (isset($_SERVER['PATH_INFO']))
-            $this->path_info = $_SERVER['PATH_INFO'];
-        else
-            $this->path_info = '/';
-
-        $this->SERVER = $_SERVER;
-        $this->is_secure = !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
-    }
-
-    public function absoluteUrl()
-    {
-        return ($this->is_secure ? 'https://' : 'http://') . $this->http_host . $this->query;
-    }
-
-    public function getHeaders()
-    {
-        if (function_exists('getallheaders'))
-            return getallheaders();
-        else
-            return false;
-    }
-
-    public function getBody()
-    {
-        return file_get_contents('php://input');
-    }
-
-    public function getFormData()
-    {
-        return array_merge_recursive($this->POST, $this->FILES);
-    }
-
-    public static function saneFiles($files)
-    {
-        $result = array();
-        foreach ($files as $prefix => $v) {
-            foreach ($v as $key => $array) {
-                array_walk_recursive($array, function(&$v, $i) use($key) {
-                    $v = array($key => $v);
-                });
-                $result = self::deepMerge($result, array($prefix => $array));
-            }
-        }
-        return $result;
-    }
-
-    private static function deepMerge($into, $arr)
-    {
-        foreach ($arr as $key => $value) {
-            if (array_key_exists($key, $into) && is_array($into[$key]) && is_array($value)) {
-                $into[$key] = self::deepMerge($into[$key], $value);
-            } else {
-                $into[$key] = $value;
-            }
-        }
-        return $into;
-    }
-}
-
index 9c51a4cdc25dd7b0607b640da91b50f1b48cd3e2..c7e81a0d544210e5ffe7b3a720b6cd574f5df05b 100644 (file)
@@ -1,94 +1,56 @@
 <?php
 
+use GuzzleHttp\Psr7\Response;
+use GuzzleHttp\Psr7\Stream;
+use Pimple\Container;
+use Psr\Http\Message\ServerRequestInterface;
+
 class IPF_HTTP_Response
 {
-    public $short_session = false;
-    public $content = '';
-    public $headers = array();
-    public $status_code = 200;
-    public $cookies = array();
-    public $status_code_list = array(
-        '100' => 'CONTINUE',
-        '101' => 'SWITCHING PROTOCOLS',
-        '200' => 'OK',
-        '201' => 'CREATED',
-        '202' => 'ACCEPTED',
-        '203' => 'NON-AUTHORITATIVE INFORMATION',
-        '204' => 'NO CONTENT',
-        '205' => 'RESET CONTENT',
-        '206' => 'PARTIAL CONTENT',
-        '300' => 'MULTIPLE CHOICES',
-        '301' => 'MOVED PERMANENTLY',
-        '302' => 'FOUND',
-        '303' => 'SEE OTHER',
-        '304' => 'NOT MODIFIED',
-        '305' => 'USE PROXY',
-        '306' => 'RESERVED',
-        '307' => 'TEMPORARY REDIRECT',
-        '400' => 'BAD REQUEST',
-        '401' => 'UNAUTHORIZED',
-        '402' => 'PAYMENT REQUIRED',
-        '403' => 'FORBIDDEN',
-        '404' => 'NOT FOUND',
-        '405' => 'METHOD NOT ALLOWED',
-        '406' => 'NOT ACCEPTABLE',
-        '407' => 'PROXY AUTHENTICATION REQUIRED',
-        '408' => 'REQUEST TIMEOUT',
-        '409' => 'CONFLICT',
-        '410' => 'GONE',
-        '411' => 'LENGTH REQUIRED',
-        '412' => 'PRECONDITION FAILED',
-        '413' => 'REQUEST ENTITY TOO LARGE',
-        '414' => 'REQUEST-URI TOO LONG',
-        '415' => 'UNSUPPORTED MEDIA TYPE',
-        '416' => 'REQUESTED RANGE NOT SATISFIABLE',
-        '417' => 'EXPECTATION FAILED',
-        '500' => 'INTERNAL SERVER ERROR',
-        '501' => 'NOT IMPLEMENTED',
-        '502' => 'BAD GATEWAY',
-        '503' => 'SERVICE UNAVAILABLE',
-        '504' => 'GATEWAY TIMEOUT',
-        '505' => 'HTTP VERSION NOT SUPPORTED',
-    );
+    public static function ok($content, $contentType = 'text/html; charset=utf-8')
+    {
+        return new Response(200, ['Content-Type' => $contentType], $content);
+    }
 
-    function __construct($content='', $mimetype='text/html; charset=utf-8')
+    public static function notFound(Container $container, ServerRequestInterface $request)
     {
-        $this->content = $content;
-        $this->headers['Content-Type'] = $mimetype;
-        $this->status_code = 200;
-        $this->cookies = array();
+        $render404 = $container['render404'];
+        $content = call_user_func($render404, $request);
+        return new Response(404, [], $content);
     }
 
-    function render($output_body=true)
+    public static function redirect($url)
     {
-        if ($this->status_code >= 200
-            && $this->status_code != 204
-            && $this->status_code != 304
-            && !\PFF\Arr::get($this->headers, 'Content-Length')) {
+        return new Response(
+            302,
+            ['Location' => $url],
+            sprintf('<a href="%s">%s</a>', $url, __('Please, click here to be redirected.'))
+        );
+    }
 
-            $this->headers['Content-Length'] = strlen($this->content);
-        }
+    public static function json($data)
+    {
+        return new Response(200, ['Content-Type' => 'application/json'], json_encode($data));
+    }
 
-        $this->outputHeaders();
-        if ($output_body)
-            $this->outputBody();
+    public static function noContent()
+    {
+        return new Response(204);
     }
 
-    function outputHeaders()
+    public static function file($filename, $mimetype = 'application/octet-stream')
     {
-        header('HTTP/1.1 '.$this->status_code.' '
-               .$this->status_code_list[$this->status_code],
-               true, $this->status_code);
-        foreach ($this->headers as $header => $ch) {
-            header($header.': '.$ch);
-        }
-        foreach ($this->cookies as $cookie => $data) {
-            setcookie($cookie, $data, time() + 31536000, '/', null, false, true);
-        }
+        return (new Response())
+            ->withHeader('Content-Type', $mimetype)
+            ->withHeader('Content-Transfer-Encoding', 'binary')
+            ->withHeader('Content-Length', filesize($filename))
+            ->withBody(new Stream($filename));
     }
 
-    function outputBody()
+    public static function download($filename, $downloadName, $mimetype = 'application/octet-stream')
     {
-        echo $this->content;
+        return self::file($filename, $mimetype)
+            ->withHeader('Content-Description', 'File Transfer')
+            ->withHeader('Content-Disposition', 'attachment; filename=' . basename($downloadName));
     }
 }
diff --git a/ipf/http/response/file.php b/ipf/http/response/file.php
deleted file mode 100644 (file)
index 1c9895a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-class IPF_HTTP_Response_File extends IPF_HTTP_Response
-{
-    private $filename;
-
-    function __construct($filename, $downloadName=null, $mimetype='application/octet-stream')
-    {
-        parent::__construct('', $mimetype);
-        $this->filename = $filename;
-        if ($downloadName) {
-            $this->headers['Content-Description'] = 'File Transfer';
-            $this->headers['Content-Disposition'] = 'attachment; filename='.basename($downloadName);
-        }
-        $this->headers['Content-Transfer-Encoding'] = 'binary';
-        $this->headers['Content-Length'] = filesize($filename);
-    }
-
-    function outputBody()
-    {
-        if (ob_get_level())
-            ob_end_clean();
-        readfile($this->filename);
-    }
-}
-
diff --git a/ipf/http/response/json.php b/ipf/http/response/json.php
deleted file mode 100644 (file)
index 97fddf9..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<?php
-
-class IPF_HTTP_Response_Json extends IPF_HTTP_Response
-{
-    function __construct($content)
-    {
-        parent::__construct(json_encode($content),'application/json');
-    }
-}
diff --git a/ipf/http/response/notfound.php b/ipf/http/response/notfound.php
deleted file mode 100644 (file)
index 4dfa439..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-use Pimple\Container;
-
-class IPF_HTTP_Response_NotFound extends IPF_HTTP_Response
-{
-    function __construct(Container $container, IPF_HTTP_Request $request)
-    {
-        $render404 = $container['render404'];
-        $content = call_user_func($render404, $request);
-
-        parent::__construct($content);
-        $this->status_code = 404;
-    }
-}
diff --git a/ipf/http/response/redirect.php b/ipf/http/response/redirect.php
deleted file mode 100644 (file)
index 4c68c17..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-class IPF_HTTP_Response_Redirect extends IPF_HTTP_Response
-{
-    function __construct($url)
-    {
-        $content = sprintf('<a href="%s">%s</a>', $url, __('Please, click here to be redirected.'));
-        parent::__construct($content);
-        $this->headers['Location'] = $url;
-        $this->status_code = 302;
-    }
-}
index 47f80c7a42fca6ce7d89b01d35aa830b30dfbfe7..12e66301d3a410e02be1a3cbcc3a9e8bfeaa6b44 100644 (file)
@@ -1,10 +1,12 @@
 <?php
 
 use Pimple\Container;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
 
-class IPF_Middleware
+abstract class IPF_Middleware
 {
-    /** @var IPF_Middleware */
+    /** @var IPF_Middleware|null */
     protected $next;
 
     /** @var Container */
@@ -20,27 +22,9 @@ class IPF_Middleware
         $this->container = $container;
     }
 
-    function processRequest($request)
-    {
-        return false;
-    }
-
-    function processResponse($request, $response)
-    {
-        return $response;
-    }
-
-    function call($request)
-    {
-        $response = $this->processRequest($request);
-        if ($response !== false) {
-            return $response;
-        }
-
-        if ($this->next) {
-            $response = $this->next->call($request);
-        }
-
-        return $this->processResponse($request, $response);
-    }
+    /**
+     * @param ServerRequestInterface $request
+     * @return ResponseInterface
+     */
+    public abstract function call(ServerRequestInterface $request);
 }
index 33196aea0ee9840359db912c4681159299cc99e5..feed289d4369af81dbaf960cec07f1e825f92795 100644 (file)
@@ -1,15 +1,28 @@
 <?php
 
+use Psr\Http\Message\ServerRequestInterface;
+
 class IPF_Middleware_Common extends IPF_Middleware
 {
-    function processRequest($request)
+    function call(ServerRequestInterface $request)
     {
         if ($this->container['settings']->get('append_slash', true)) {
-            $url = $request->absoluteUrl();
-            if (substr($url, -1) !== '/') {
-                return new IPF_HTTP_Response_Redirect($url.'/');
+            $uri = $request->getUri();
+            $path = $uri->getPath();
+            $query = $uri->getQuery();
+            if (substr($path, -1) !== '/') {
+                if ($path == '') {
+                    $target = '/';
+                } else {
+                    $target = $path . '/';
+                }
+                if ($query != '') {
+                    $target .= '?' . $query;
+                }
+                return IPF_HTTP_Response::redirect($target);
             }
         }
-        return false;
+
+        return $this->next->call($request);
     }
 }
index 007617bbc491d15b1ab9ea2d6caf9cabe9690ed2..8d2fff9cd0bf1334753652f8f490fb1c4d2b3e5c 100644 (file)
@@ -1,16 +1,18 @@
 <?php
 
+use Psr\Http\Message\ServerRequestInterface;
+
 class IPF_Dispatch_Middleware extends IPF_Middleware
 {
-    function processRequest($request)
+    function call(ServerRequestInterface $request)
     {
         $m = $this->getRouter()->match($request);
         if (!$m) {
-            return new IPF_HTTP_Response_NotFound($this->container, $request);
+            return IPF_HTTP_Response::notFound($this->container, $request);
         }
 
         list($route, $match) = $m;
-        $request->params = $match;
+        $request = $request->withAttribute('params', $match);
 
         try {
             $controllerClass = $route->controller();
index d2e595e6ddc6eb4ef4ea0b9f81e22b4bb89f4040..84e1ee910c9b5371e2882a053c366edea93fe6e9 100644 (file)
@@ -1,10 +1,14 @@
 <?php
 
+use GuzzleHttp\Psr7\Response;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
 class IPF_Error_Middleware extends IPF_Middleware
 {
     private $previous_error_handler;
 
-    function call($request)
+    function call(ServerRequestInterface $request)
     {
         $this->previous_error_handler = set_error_handler(array($this, 'error_handler'));
         register_shutdown_function(array($this, 'shutdown_handler'), $request);
@@ -14,8 +18,8 @@ class IPF_Error_Middleware extends IPF_Middleware
 
             $response = $this->next->call($request);
 
-            if (!($response instanceof IPF_HTTP_Response))
-                throw new \Exception('Response is not a IPF_HTTP_Response');
+            if (!($response instanceof ResponseInterface))
+                throw new \Exception('Response is not a ResponseInterface');
         } catch (\Exception $exception) {
             error_log($exception);
             $response = $this->getServerErrorResponse($request, $exception);
@@ -44,23 +48,20 @@ class IPF_Error_Middleware extends IPF_Middleware
             error_log($exception);
             if (!headers_sent()) {
                 $response = $this->getServerErrorResponse($request, $exception);
-                $response->render();
+                \Http\Response\send($response);
             }
         }
     }
 
     /**
-     * @param IPF_HTTP_Request $request
+     * @param ServerRequestInterface $request
      * @param Exception $exception
-     * @return IPF_HTTP_Response
+     * @return ResponseInterface
      */
-    private function getServerErrorResponse(IPF_HTTP_Request $request, Exception $exception)
+    private function getServerErrorResponse(ServerRequestInterface $request, Exception $exception)
     {
         $render500 = $this->container['render500'];
         $content = call_user_func($render500, $request, $exception);
-
-        $response = new IPF_HTTP_Response($content, null);
-        $response->status_code = 500;
-        return $response;
+        return new Response(500, [], $content);
     }
 }
index 234e4e5698c0b0dcd2a49b82cae38c60fd43cb34..7fd4aad319a52a94dde09334bf917399098071c1 100644 (file)
@@ -1,23 +1,24 @@
 <?php
 
+use Psr\Http\Message\ServerRequestInterface;
+
 class IPF_Serve_Static_Middleware extends IPF_Middleware
 {
-    function processRequest($request)
+    function call(ServerRequestInterface $request)
     {
         $staticUrl = $this->getStaticUrl();
 
-        if (!preg_match('#^'.preg_quote($staticUrl).'(.*)$#', $request->query, $matches))
-            return false;
-
-        $query = $matches[1];
+        if (preg_match('#^' . preg_quote($staticUrl) . '(.*)$#', $request->getRequestTarget(), $matches)) {
+            $query = $matches[1];
 
-        foreach ($this->getApps() as $app) {
-            $static = $app->getPath() . $staticUrl . $query;
-            if (is_file($static))
-                return new IPF_HTTP_Response_File($static, null, $this->mimetype($query));
+            foreach ($this->getApps() as $app) {
+                $static = $app->getPath() . $staticUrl . $query;
+                if (is_file($static))
+                    return IPF_HTTP_Response::file($static, $this->mimetype($query));
+            }
         }
 
-        return false;
+        return $this->next->call($request);
     }
 
     private function mimetype($filename)
index cd413ad59f1e8fffba4f9031e3482241a3336fce..16a31f355ad980126a66d1a0dde05340545255e2 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use IPF\Router\Expression;
+use Psr\Http\Message\ServerRequestInterface;
 
 class IPF_Router
 {
@@ -34,15 +35,15 @@ class IPF_Router
         }
     }
 
-    public function match($req)
+    public function match(ServerRequestInterface $req)
     {
         foreach ($this->routes as $route) {
             $match = array();
-            if (!$route->matcher()->match($req->query, $match))
+            if (!$route->matcher()->match($req->getUri()->getPath(), $match))
                 continue;
 
             $methods = $route->methods();
-            if ($methods && !in_array($req->method, $methods)) {
+            if ($methods && !in_array($req->getMethod(), $methods)) {
                 continue;
             }
 
@@ -199,6 +200,6 @@ class IPF_HTTP_Error404 extends IPF_Router_Shortcut
 {
     public function response($container, $request)
     {
-        return new IPF_HTTP_Response_NotFound($container, $request);
+        return IPF_HTTP_Response::notFound($container, $request);
     }
 }
index a4fd3602bd87869d716f38615c711d20a70ac521..76a5d6bd09fab54f0557f106e1a354e7968e3122 100644 (file)
@@ -1,19 +1,28 @@
 <?php
 
+use Dflydev\FigCookies\SetCookie;
+use Dflydev\FigCookies\SetCookies;
+use Psr\Http\Message\ServerRequestInterface;
+
 class IPF_Session_Middleware extends IPF_Middleware
 {
-    function processRequest($request)
+    function call(ServerRequestInterface $request)
     {
-        $session_cookie = \PFF\Arr::get($request->COOKIE, $this->getSessionCookieName());
-        $request->session = $this->getSessionApp()->getSession($session_cookie);
-        return false;
-    }
+        $session_cookie = \PFF\Arr::get($request->getCookieParams(), $this->getSessionCookieName());
+        $session = $this->getSessionApp()->getSession($session_cookie);
 
-    function processResponse($request, $response)
-    {
-        $session_cookie = $request->session->cookie();
-        $response->cookies[$this->getSessionCookieName()] = $session_cookie;
-        return $response;
+        $response = $this->next->call(
+            $request->withAttribute('session', $session)
+        );
+
+        $setCookie = SetCookie::create($this->getSessionCookieName(), $session->cookie())
+            ->withPath('/')
+            ->withHttpOnly(true)
+            ->withExpires(time() + 31536000);
+
+        return SetCookies::fromResponse($response)
+            ->with($setCookie)
+            ->renderIntoSetCookieHeader($response);
     }
 
     /**
index 72bd514a46d7a4ce3ab1aa8740a9df051e253abd..bc439736811b5fe42d0a99539ea670368e2963de 100644 (file)
@@ -8,6 +8,7 @@ use IPF_Router;
 use IPF_Settings;
 use Pimple\Container;
 use Pimple\ServiceProviderInterface;
+use Psr\Http\Message\ServerRequestInterface;
 use Twig\Environment;
 use Twig\Loader\FilesystemLoader;
 use Twig\Loader\LoaderInterface;
@@ -81,14 +82,14 @@ class TemplateEnvironmentTwig implements TemplateEnvironment
         $twig->addGlobal('UPLOAD_URL', $this->settings->get('upload_url'));
     }
 
-    private function addRequestGlobals(Environment $twig, $request)
+    private function addRequestGlobals(Environment $twig, ServerRequestInterface $request)
     {
         if (!$request)
             return;
 
         $twig->addGlobal('request', $request);
-        $twig->addGlobal('user', $request->user);
-        $twig->addGlobal('CURRENT_URL', $request->query);
+        $twig->addGlobal('user', $request->getAttribute('user'));
+        $twig->addGlobal('CURRENT_URL', $request->getUri()->getPath());
 
         foreach ($this->processors as $proc) {
             $context = call_user_func_array($proc, array($request));