Jelajahi Sumber

Improved action handling for form POST support

Lukas Angerer 4 tahun lalu
induk
melakukan
18292f3a30

+ 22 - 3
src/lib/Action.php

@@ -4,9 +4,10 @@ abstract class Action
 {
 {
     public $path;
     public $path;
     public $method;
     public $method;
-    protected $statusCode = 200;
+    public $statusCode = 200;
+    private $hooks = array();
 
 
-    public function __construct($path, $method)
+    public function __construct(string $path, string $method)
     {
     {
         $this->path = $path;
         $this->path = $path;
         $this->method = $method;
         $this->method = $method;
@@ -18,5 +19,23 @@ abstract class Action
         return $this;
         return $this;
     }
     }
 
 
-    public abstract function execute(): void;
+    public function withHook(callable $hook): self
+    {
+        array_push($this->hooks, $hook);
+        return $this;
+    }
+
+    public function execute(): void
+    {
+        http_response_code($this->statusCode);
+
+        foreach ($this->hooks as $hook)
+        {
+            $hook($this);
+        }
+
+        $this->render();
+    }
+
+    public abstract function render(): void;
 }
 }

+ 17 - 0
src/lib/HandlerAction.php

@@ -0,0 +1,17 @@
+<?php
+
+class HandlerAction extends Action
+{
+    protected $handler;
+
+    public function __construct($path, $method, IHandler $handler)
+    {
+        parent::__construct($path, $method);
+        $this->handler = $handler;
+    }
+
+    public function execute(): void
+    {
+        $this->handler->execute();
+    }
+}

+ 0 - 0
src/lib/IHandler.php


+ 1 - 2
src/lib/LogicAction.php

@@ -10,9 +10,8 @@ class LogicAction extends Action
         $this->actionFunction = $actionFunction;
         $this->actionFunction = $actionFunction;
     }
     }
 
 
-    public function execute(): void
+    public function render(): void
     {
     {
-        http_response_code($this->statusCode);
         ($this->actionFunction)();
         ($this->actionFunction)();
     }
     }
 }
 }

+ 10 - 3
src/lib/Page.php

@@ -8,18 +8,25 @@ class Page
     // This holds the "main content" of the page that will be wrapped in a simple HTML wrapper
     // This holds the "main content" of the page that will be wrapped in a simple HTML wrapper
     public $content;
     public $content;
     public $user;
     public $user;
+    public $pageData;
 
 
-    public function __construct($pageName, $context = array())
+    public function __construct($pageName, $metadata = array())
     {
     {
-
         $this->targetPage = __DIR__ . "/../templates/pages/" . $pageName . ".php";
         $this->targetPage = __DIR__ . "/../templates/pages/" . $pageName . ".php";
         $this->requestUri = $_SERVER["REQUEST_URI"];
         $this->requestUri = $_SERVER["REQUEST_URI"];
 
 
         $this->user = User::loadFromContext();
         $this->user = User::loadFromContext();
+        $this->pageData = array();
+
+        if (array_key_exists("title", $metadata))
+        {
+            $this->title = $metadata["title"];
+        }
     }
     }
 
 
-    public function render()
+    public function render($pageData = array())
     {
     {
+        $this->pageData = array_merge($this->pageData, $pageData);
         $context = $this;
         $context = $this;
 
 
         // Start output buffering - everything that is "printed" while we are buffering
         // Start output buffering - everything that is "printed" while we are buffering

+ 0 - 79
src/lib/PageContext.php

@@ -1,79 +0,0 @@
-<?php
-
-class PageContext
-{
-    // Initial request path
-    public $requestPath;
-    // Path to the actual target page PHP file
-    public $targetPage;
-    // Title of the page - this is usually set in the page PHP file
-    public $title;
-    // This holds the "main content" of the page that will be wrapped in a simple HTML wrapper
-    public $content;
-    // The currently logged in user - if the user is actually logged in
-    public $user;
-    public $pageData;
-
-    public function __construct($requestPath)
-    {
-        $this->requestPath = $requestPath;
-
-        $targetPage = $this->requestPath;
-        if ($targetPage == "/")
-        {
-            $targetPage = "/home";
-        }
-
-        $targetPage = __DIR__ . "/../pages" . $targetPage . ".php";
-
-        $this->targetPage = $targetPage;
-        $context = array(
-            "requestUri" => $_SERVER["REQUEST_URI"],
-            "targetPage" => $targetPage,
-            "template" => function ($path) {
-                echo "TEMPLATE: " . $path;
-            },
-        );
-
-        $this->user = User::loadFromContext();
-    }
-
-    public function render()
-    {
-        $context = $this;
-        $postHandler = substr($this->targetPage, 0, -4) . "-post.php";
-
-        if ($_SERVER['REQUEST_METHOD'] === 'POST' && is_file($postHandler))
-        {
-            $this->pageData = include $postHandler;
-        }
-
-        // Start output buffering - everything that is "printed" while we are buffering
-        // is captured for later use which allows us to insert the content into a larger
-        // construct like the overall page template.
-        ob_start();
-
-        if (is_file($this->targetPage))
-        {
-            include $this->targetPage;
-        }
-        else
-        {
-            include __DIR__ . "/../pages/404.php";
-        }
-
-        // End buffering and return its contents
-        $this->content = ob_get_clean();
-
-        // Now we take that "content" and wrap it inside of a page template so that the result
-        // will be a fully functional HTML page.
-        $this->template("html");
-    }
-
-    public function template($path, $variables = array())
-    {
-        $context = $this;
-        extract($variables);
-        include __DIR__ . "/../templates/" . $path . ".php";
-    }
-}

+ 17 - 0
src/lib/RedirectAction.php

@@ -0,0 +1,17 @@
+<?php
+
+class RedirectAction extends Action
+{
+    public $targetUrl;
+    public function __construct(string $path, string $method, string $targetUrl)
+    {
+        parent::__construct($path, $method);
+        $this->targetUrl = $targetUrl;
+        $this->statusCode = 302;
+    }
+
+    public function render(): void
+    {
+        header("Location: " . $this->targetUrl);
+    }
+}

+ 8 - 6
src/lib/TemplateAction.php

@@ -3,18 +3,20 @@
 class TemplateAction extends Action
 class TemplateAction extends Action
 {
 {
     protected $templatePath;
     protected $templatePath;
+    protected $metadata;
+    public $pageData;
 
 
-    public function __construct($path, $method, $templatePath)
+    public function __construct($path, $method, $templatePath, $metadata = array())
     {
     {
         parent::__construct($path, $method);
         parent::__construct($path, $method);
         $this->templatePath = $templatePath;
         $this->templatePath = $templatePath;
+        $this->metadata = $metadata;
+        $this->pageData = array();
     }
     }
 
 
-    public function execute(): void
+    public function render(): void
     {
     {
-        http_response_code($this->statusCode);
-
-        $page = new Page($this->templatePath);
-        $page->render();
+        $page = new Page($this->templatePath, $this->metadata);
+        $page->render($this->pageData);
     }
     }
 }
 }

+ 2 - 3
src/routes/404.php

@@ -5,12 +5,11 @@ class NotFoundAction extends TemplateAction
     public function __construct()
     public function __construct()
     {
     {
         parent::__construct("/404", "GET", "404");
         parent::__construct("/404", "GET", "404");
+        $this->statusCode = 404;
     }
     }
 
 
-    public function execute(): void
+    public function render(): void
     {
     {
-        http_response_code(404);
-
         $page = new Page($this->templatePath);
         $page = new Page($this->templatePath);
         $page->title = "Not Found";
         $page->title = "Not Found";
         $page->render();
         $page->render();

+ 1 - 0
src/routes/api-get-data.php

@@ -45,5 +45,6 @@ Router::register(new LogicAction("/api/getdata", "GET", function () {
         ));
         ));
     }
     }
 
 
+    header('Content-type: application/json');
     print(json_encode($data, JSON_PRETTY_PRINT));
     print(json_encode($data, JSON_PRETTY_PRINT));
 }));
 }));

+ 11 - 0
src/routes/form.php

@@ -0,0 +1,11 @@
+<?php
+
+Router::register(new TemplateAction("/form", "GET", "form", array(
+    "title" => "Page With Form",
+)));
+
+Router::register((new TemplateAction("/form", "POST", "form", array(
+    "title" => "POSTed Form",
+)))->withHook(function (TemplateAction $action) {
+    $action->pageData["name"] = "Sir " . $_POST["fname"] . " " . $_POST["lname"];
+}));

+ 3 - 1
src/routes/home.php

@@ -1,3 +1,5 @@
 <?php
 <?php
 
 
-Router::register(new TemplateAction("/", "GET", "home"));
+Router::register(new TemplateAction("/", "GET", "home", array(
+    "title" => "Home!!!"
+)));

+ 3 - 0
src/routes/redirect.php

@@ -0,0 +1,3 @@
+<?php
+
+Router::register(new RedirectAction("/redirect", "GET", "/welcome/details"));

+ 3 - 1
src/routes/welcome-details.php

@@ -1,3 +1,5 @@
 <?php
 <?php
 
 
-Router::register(new TemplateAction("/welcome/details", "GET", "welcome/details"));
+Router::register(new TemplateAction("/welcome/details", "GET", "welcome/details", array(
+    "title" => "Welcome / Details",
+)));

+ 3 - 1
src/routes/welcome.php

@@ -1,3 +1,5 @@
 <?php
 <?php
 
 
-Router::register(new TemplateAction("/welcome", "GET", "welcome"));
+Router::register(new TemplateAction("/welcome", "GET", "welcome", array(
+    "title" => "Welcome",
+)));

+ 2 - 0
src/templates/navigation.php

@@ -3,4 +3,6 @@
     <li><a href="/welcome">Welcome</a></li>
     <li><a href="/welcome">Welcome</a></li>
     <li><a href="/welcome/details">Details (Welcome)</a></li>
     <li><a href="/welcome/details">Details (Welcome)</a></li>
     <li><a href="/form">Form</a></li>
     <li><a href="/form">Form</a></li>
+    <li><a href="/redirect">Redirect</a></li>
+    <li><a href="/api/getdata">There is even an API here</a></li>
 </ul>
 </ul>

+ 0 - 5
src/templates/pages/form-post.php

@@ -1,5 +0,0 @@
-<?php
-
-return array(
-    "title" => "POSTed FORM",
-);

+ 1 - 7
src/templates/pages/form.php

@@ -1,11 +1,5 @@
-<?php
-    // Here we can set the <title> of the page. Since we actually render the "main content" (i.e. this file here)
-    // before we execute the wrapper HTML template (src/templates/html.php), we can define the value here and it
-    // can be used in the wrapper code.
-    $context->title = "Page With Form";
-?>
 <!-- Wome actual HTML content -->
 <!-- Wome actual HTML content -->
-<h1><?= empty($context->pageData["title"]) ? "Please enter some stuff" : $context->pageData["title"] ?></h1>
+<h1><?= empty($context->pageData["name"]) ? "Please enter some stuff" : "You have POSTed the following information: " . $context->pageData["name"] ?></h1>
 <!--
 <!--
     We can also use other, smaller "templates" to build up our page. Here, we just load the navigation snippet
     We can also use other, smaller "templates" to build up our page. Here, we just load the navigation snippet
     that we can see in src/templates/navigation.
     that we can see in src/templates/navigation.

+ 0 - 6
src/templates/pages/home.php

@@ -1,9 +1,3 @@
-<?php
-    // Here we can set the <title> of the page. Since we actually render the "main content" (i.e. this file here)
-    // before we execute the wrapper HTML template (src/templates/html.php), we can define the value here and it
-    // can be used in the wrapper code.
-    $context->title = "Home!!!";
-?>
 <!-- Wome actual HTML content -->
 <!-- Wome actual HTML content -->
 <h1>🏠 Home</h1>
 <h1>🏠 Home</h1>
 <!--
 <!--

+ 0 - 3
src/templates/pages/welcome.php

@@ -1,6 +1,3 @@
-<?php
-    $context->title = "Welcome";
-?>
 <h1>Welcome</h1>
 <h1>Welcome</h1>
 <?= $context->template("navigation") ?>
 <?= $context->template("navigation") ?>
 <p>
 <p>

+ 0 - 3
src/templates/pages/welcome/details.php

@@ -1,6 +1,3 @@
-<?php
-    $context->title = "Welcome / Details";
-?>
 <h1>Details</h1>
 <h1>Details</h1>
 <?= $context->template("navigation") ?>
 <?= $context->template("navigation") ?>
 <p>
 <p>