mirror of
https://github.com/Karaka-Management/Developer-Guide.git
synced 2026-01-11 20:38:42 +00:00
8.9 KiB
8.9 KiB
Application Sample
The following application is a minimal sample in order to show how it's possible to set it up. Please note that for simplicity purposes many framework features and architectural aspects are omitted.
# .htaccess
# enable url rewriting
<ifmodule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME} \.(js|css)$
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /?{QUERY_STRING} [QSA]
</ifmodule>
<?php declare(strict_types=1);
// index.php
// initialize application and output response (entry point for the app)
\ob_start();
require_once __DIR__ . '/phpOMS/Autoloader.php';
$config = require_once __DIR__ . '/config.php';
$App = new \app\Application($config);
echo $App->run(); // outputs the application response
\ob_end_flush();
<?php declare(strict_types=1);
// app/Application.php
// Application where the framework components are initialized
namespace app;
use phpOMS\Application\ApplicationAbstract; /* provides many member variables which are often shared with controllers */
use phpOMS\Dispatcher\Dispatcher;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\Router\WebRouter;
use phpOMS\Uri\UriFactory;
use phpOMS\Views\View;
class Application extends ApplicationAbstract
{
/* initialize most framework components */
public function __construct(array $config)
{
$this->router = new WebRouter();
// sample routes for different endpoints are defined in a routes file
$this->router->importFromFile(__DIR__ . '/Routes.php');
$this->dispatcher = new Dispatcher($this);
// usually much more stuff happens here for real world apps (e.g. DB initialization, session, ...)
}
/* setup response and return it */
public function run() : string
{
$request = $this->initRequest();
$response = $this->initResponse($request);
$pageView = $this->initMainPageTemplate($request, $response);
// bind the page view to the response object. This is rendered later on.
$response->set('Content', $pageView);
/* get data from url endpoints defined by the routes */
$dispatch = $this->dispatcher->dispatch(
$this->router->route(
$request->uri->getRoute(),
$request->getData('CSRF'), // optional: only required if csrf tokens are used otherwise use null
$request->getRouteVerb() // e.g. get, post, put ...
),
$request, // this is passed to the endpoint
$response // this is passed to the endpoint
// define more data you want to pass to the endpoints if necessary
);
// bind data (in this case the dispatcher response) to the view
$pageView->addData('dispatch', $dispatch);
// push the headers (no changes to the header are possible afterwards)
$response->header->push();
// renders the content of the response object (depends on the content type, text/html, json, ...)
return $response->getBody();
}
/* initialize request of the user */
private function initRequest() : Request
{
// initialize request from the superglobals which are automatically populated
$request = Request::createFromSuperglobals();
// optional: will transform the url path and sub-paths to hashs
$request->createRequestHashs(0);
// if your application is located in a web-subfolder for easier handling
$request->uri->setRootPath('/');
// this will allow you to create urls based on request data
UriFactory::setupUriBuilder($request->uri);
return $request;
}
/* initialize response object */
private function initResponse(HttpRequest $request) : HttpResponse
{
$response = new HttpResponse();
// you could use the request content-type in order to define the response content-type
$response->header->set('content-type', 'text/html; charset=utf-8');
$response->header->set('x-xss-protection', '1; mode=block');
// more CSP can be defined here
return $response;
}
/* initialize main page template. if many pages have a different page template you could put this into the corresponding controllers. */
private function initMainPageTemplate(HttpRequest $request, HttpResponse $response) : View
{
$pageView = new View(null, $request, $response);
$pageView->setTemplate('/app/tpl/index'); // templates need file ending .tpl.php
$pageView->setData('title', 'Default Title!'); // can be changed later on
return $pageView;
}
}
<?php declare(strict_types=1);
// app/Routes.php
// Routes for the application
use phpOMS\Router\RouteVerb;
return [
'^/*$' => [ // root path has two endpoints defined for get requests
[
'dest' => '\app\controller\TestController:home', // method
'verb' => RouteVerb::GET,
],
[
'dest' => '\app\controller\TestController::exit', // static function
'verb' => RouteVerb::GET,
],
],
'^/otherUri$' => [ // has one endpoint defined for a get request and one for a set request
[
'dest' => '\app\controller\TestController::exit',
'verb' => RouteVerb::GET,
],
[
'dest' => '\app\controller\TestController::thisisset', // actually not implemented
'verb' => RouteVerb::SET,
],
],
'^/overwritten.*$' => [ // has one endpoint defined for a get request
[
'dest' => '\app\controller\TestController:newMainTemplate',
'verb' => RouteVerb::GET,
],
],
];
<!-- app/tpl/index.tpl.php Main template -->
<html>
<head>
<title><?= $this->getData('title'); ?></title>
</head>
<body>
<div>This is the main template....</div>
<div>What follows next comes from the dispatcher results:</div>
<main>
<?php
$dispatch = $this->getData('dispatch'); // get data bound to the view with the key "dispatch"
foreach($dispatch as $view) echo $view->render(); // in this case it has a 'render()' method which is called
?>
</main>
</body>
</html>
<?php declare(strict_types=1);
// app/controller/TestController.php
// Sample controller which is referenced in the routes
namespace app\controller;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Views\View;
use app\view\TestView;
class TestController
{
private ApplicationAbstract $app;
/* the dispatcher passes the ApplicationAbstract reference to the controller */
public function __construct(ApplicationAbstract $app)
{
$this->app = $app;
}
/* Sample route endpoint (see routes) */
public function home(RequestAbstract $request, ResponseAbstract $response, $data = null)
{
// special view which extends the normal `View` where we can define additional view logic
$view = new TestView();
$view->setTemplate('/app/tpl/welcome');
return $view;
}
/* Sample route endpoint (see routes) */
public static function exit(RequestAbstract $request, ResponseAbstract $response, $data = null)
{
// overwrite/set the page title used in the main template `index.tpl.php`
$response->get('Content')->setData('title', 'New Title!!!');
$view = new View();
$view->setTemplate('/app/tpl/goodbye');
return $view;
}
/* Sample route endpoint (see routes) */
public function newMainTemplate(RequestAbstract $request, ResponseAbstract $response, $data = null)
{
$view = new View();
$view->setTemplate('/app/tpl/overwritten');
// overwrite the main template with a different template
// this is one example how to define a different main template for a different a page
$response->set('Content', $view);
}
}
<?php declare(strict_types=1);
// app/view/TestView.php
// Sample view which can hold additional view logic which can be used by the template
namespace app\view;
use phpOMS\Views\View;
class TestView extends View
{
/* simple example of some view logic */
public function renderBold(string $bold) : string
{
return '<strong>' . $bold . '</strong>';
}
}
<!-- app/tpl/welcome.tpl.php This is shown in the index.tpl.php -->
<div><?= 'Hello ' . $this->renderBold('beautiful') . ' World!' ?></div>
<!-- app/tpl/welcome.tpl.php This is shown in the index.tpl.php -->
<div><?= 'Goodbye World!' ?></div>
<!-- app/tpl/overwritten.tpl.php This becomes the new main template -->
<div>The main template got overwritten!</div>