mirror of
https://github.com/Karaka-Management/Developer-Guide.git
synced 2026-01-11 12:28:41 +00:00
Expand and fix developer documentation
This commit is contained in:
parent
12a707ea3d
commit
5c3c0224ff
|
|
@ -30,6 +30,7 @@
|
|||
* [LocalStorage]({%}?page=datastorage/localstorage)
|
||||
|
||||
### Database
|
||||
* [Connection]({%}?page=datastorage/database/connection)
|
||||
* [DataMapper]({%}?page=datastorage/database/datamapper)
|
||||
* [Queries]({%}?page=datastorage/database/queries)
|
||||
|
||||
|
|
|
|||
290
application/sample.md
Normal file
290
application/sample.md
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
# 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.
|
||||
|
||||
```txt
|
||||
# .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
|
||||
// index.php
|
||||
// initialize application and output response (entry point for the app)
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
\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
|
||||
// app/Application.php
|
||||
// Application where the framework components are initialized
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace app;
|
||||
|
||||
use phpOMS\ApplicationAbstract; /* provides many member variables which are often shared with controllers */
|
||||
use phpOMS\Dispatcher\Dispatcher;
|
||||
use phpOMS\Message\Http\Request;
|
||||
use phpOMS\Message\Http\Response;
|
||||
use phpOMS\Router\Router;
|
||||
use phpOMS\Uri\UriFactory;
|
||||
use phpOMS\Views\View;
|
||||
|
||||
class Application extends ApplicationAbstract
|
||||
{
|
||||
/* initialize most framework components */
|
||||
public function __construct(array $config)
|
||||
{
|
||||
$this->router = new Router();
|
||||
|
||||
// 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->getUri()->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->getHeader()->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->getUri()->setRootPath('/');
|
||||
|
||||
// this will allow you to create urls based on request data
|
||||
UriFactory::setupUriBuilder($request->getUri());
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/* initialize response object */
|
||||
private function initResponse(Request $request) : Response
|
||||
{
|
||||
$response = new Response();
|
||||
|
||||
// you could use the request content-type in order to define the response content-type
|
||||
$response->getHeader()->set('content-type', 'text/html; charset=utf-8');
|
||||
|
||||
$response->getHeader()->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(Request $request, Response $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
|
||||
// app/Routes.php
|
||||
// Routes for the application
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
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,
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
```php
|
||||
<!-- 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
|
||||
// app/controller/TestController.php
|
||||
// Sample controller which is referenced in the routes
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use phpOMS\ApplicationAbstract;
|
||||
use phpOMS\Message\RequestAbstract;
|
||||
use phpOMS\Message\ResponseAbstract;
|
||||
use phpOMS\Views\View;
|
||||
|
||||
use app\view\TestView;
|
||||
|
||||
class TestController
|
||||
{
|
||||
private $app = null;
|
||||
|
||||
/* 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
|
||||
// app/view/TestView.php
|
||||
// Sample view which can hold additional view logic which can be used by the template
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
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>';
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- app/tpl/welcome.tpl.php This is shown in the index.tpl.php -->
|
||||
<div><?= 'Hello ' . $this->renderBold('beautiful') . ' World!' ?></div>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- app/tpl/welcome.tpl.php This is shown in the index.tpl.php -->
|
||||
<div><?= 'Goodbye World!' ?></div>
|
||||
```
|
||||
|
||||
```html
|
||||
<!-- app/tpl/overwritten.tpl.php This becomes the new main template -->
|
||||
<div>The main template got overwritten!</div>
|
||||
```
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
The dispatching is the follow up on the routing. In the dispatcher the route destination get resolved and executed. Dispatching can be performed on module instance methods, static functions and anonymous functions.
|
||||
|
||||
The result of the `dispatch()` call is an array of renderable views which will be rendered at the end when the response object is finalized.
|
||||
The return of the `dispatch()` call is an array of all end point returns.
|
||||
|
||||
## Basic
|
||||
|
||||
|
|
|
|||
|
|
@ -1,68 +1,62 @@
|
|||
# Routing
|
||||
|
||||
Routing allows to bind a string representation to a function. This is required in order to execute request specific code segments.
|
||||
Routes are defined in a uniform manner for all different application types such as http, socket or console.
|
||||
One very common scenario for routing is to take the url of a http(s) request and assign it to a function located in a controller.
|
||||
|
||||
## Routes
|
||||
|
||||
Routes are defined as RegEx. It is recommended to match the desired route as closely as possible and provide both `^` at the beginning and `$` at the end of the route.
|
||||
|
||||
Resolving a route can be done by providing a request to the router
|
||||
Resolving a route can be done by providing the route path e.g.
|
||||
|
||||
```php
|
||||
$router->route(new Request());
|
||||
```
|
||||
|
||||
or a route
|
||||
|
||||
```php
|
||||
$router->route('foo/bar', RouteVerb::GET);
|
||||
$router->route('foo/bar', null, RouteVerb::GET); // returns an array of endpoints
|
||||
```
|
||||
|
||||
The result is an array of either string references or closures.
|
||||
|
||||
## Closure
|
||||
## Adding Routes to the Router
|
||||
|
||||
Routes can be added individually in the code ore defined in an array which is stored in a file.
|
||||
|
||||
### Closure
|
||||
|
||||
For routes it's possible to define a `\Closure` which will get returned upon using the specified route.
|
||||
|
||||
```php
|
||||
$router->add('foo/bar', function() {
|
||||
return 'Hellow World';
|
||||
$router->add('foo/bar', function() {
|
||||
return 'Hello World';
|
||||
});
|
||||
```
|
||||
|
||||
Routes can have different verbs which are derived from the HTTP verbs. Routes that get assigned a verb will only be matched if the route and the routing verb match.
|
||||
|
||||
```php
|
||||
$this->router->add('foo/bar', function() {
|
||||
return 'Hellow World';
|
||||
$router->add('foo/bar', function() {
|
||||
return 'Hello World';
|
||||
}, RouteVerb::GET | RouteVerb::SET);
|
||||
```
|
||||
|
||||
## Route Parameters
|
||||
|
||||
<coming soon>
|
||||
|
||||
## Reference
|
||||
### Reference
|
||||
|
||||
Instead of defining closures it's possible to define a string representation of the destination that should be called.
|
||||
|
||||
```php
|
||||
$this->router->add('foo/bar', '\foo\controller:barFunction');
|
||||
$router->add('foo/bar', '\foo\controller:barFunction');
|
||||
```
|
||||
|
||||
Static functions can be defined in the following fashion:
|
||||
|
||||
```php
|
||||
$this->router->add('foo/bar', '\foo\controller::barFunction');
|
||||
$router->add('foo/bar', '\foo\controller::barFunction');
|
||||
```
|
||||
|
||||
## Import
|
||||
### Import from File
|
||||
|
||||
While routes can be added manually to the router it's also possible to import a list of routes through the file import function.
|
||||
|
||||
```php
|
||||
$this->router->importFromFile($path);
|
||||
$router->importFromFile($path);
|
||||
```
|
||||
|
||||
The routing file must have the following structure:
|
||||
|
|
@ -85,12 +79,32 @@ The routing file must have the following structure:
|
|||
|
||||
In this schematic the first route has different destinations depending on the verb.
|
||||
|
||||
## Verbs
|
||||
|
||||
With request verbs it's possible to use the same request path and assign different endpoints to them. This is helpful when you want to have the same path for retrieving data and changing data. This is a normal situation in web development e.g.
|
||||
|
||||
Let's assume we have the url `https://yoururl.com/user/1/name` if we make a `GET` request we could return the name for the user `1` and if we make a `POST` request we could update the name for the user `1` and use the same url.
|
||||
|
||||
Allowed request verbs are:
|
||||
|
||||
* ::GET (e.g. for http get requests)
|
||||
* ::SET (e.g. for http post requests which update existing data)
|
||||
* ::PUT (e.g. for http put requests which create data)
|
||||
* ::DELETE (e.g. for http delete requests which delete data)
|
||||
* ::ANY (for every request if the verb doesn't matter)
|
||||
|
||||
In the routing definition it's possible to allow multiple verbs for the same endpoint by using `|` in the definition:
|
||||
|
||||
```php
|
||||
'verb' => RouteVerb::GET | RouteVerb::POST
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
It's also possible to define permissions for a specific application, organization and account in the routes which are then checked if they are set. If they are not set no permissions are checked.
|
||||
|
||||
```php
|
||||
$router->route('foo/bar', RouteVerb::GET, 'APP_NAME', ORG_ID, ACCOUNT);
|
||||
$router->route('foo/bar', null, RouteVerb::GET, 'APP_NAME', ORG_ID, ACCOUNT);
|
||||
```
|
||||
|
||||
```php
|
||||
|
|
@ -127,3 +141,25 @@ The different permission types can be found in the `PermissionType` class/enum.
|
|||
This value is module specific and needs to be defined by every module individually.
|
||||
|
||||
The state allows a module to have different permissions. E.g. a news module has permissions for managing news articles (CRUDP), at the same time it also has permissions for managing tags/badges (CRUDP). Just because a user has permissions for managing news articles this user may not need to have the same permissions for managing tags/badges.
|
||||
|
||||
## CSRF Protection
|
||||
|
||||
Often you would like to enable `CSRF` protection for certain urls or routing paths. The router can check if a CSRF protection is needed for a certain path and if it is needed it will check if a CSRF token is provided. If no CSRF protection is required it will ignore the CSRF token, but if it is necessary the router will check if it is available.
|
||||
|
||||
```php
|
||||
$router->add('foo/bar', function() {
|
||||
return 'Hello World';
|
||||
}, RouteVerb::GET | RouteVerb::SET,
|
||||
true, // CSRF token is required
|
||||
);
|
||||
```
|
||||
|
||||
```php
|
||||
$router->route(
|
||||
'foo/bar',
|
||||
$request->getData('CSRF'),
|
||||
RouteVerb::GET,
|
||||
'APP_NAME',
|
||||
ORG_ID, ACCOUNT
|
||||
);
|
||||
```
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Modules
|
||||
|
||||
The following directory structure should roughly visualize how modules are strucured. The purpose of the different sub-directories and their files will be covered in the following sections.
|
||||
The following directory structure should roughly visualize how modules are structured. The purpose of the different sub-directories and their files will be covered in the following sections.
|
||||
|
||||
* {UniqueModuleName}
|
||||
* Admin
|
||||
|
|
@ -40,20 +40,20 @@ The following directory structure should roughly visualize how modules are struc
|
|||
* Controller.js
|
||||
* info.json
|
||||
|
||||
All modules are located inside the `/Modules` directory and their directory name has to be the module name itself without whitespaces.
|
||||
All modules are located inside the `/Modules` directory and their directory name has to be the module name itself without whitespace.
|
||||
|
||||
## Admin
|
||||
|
||||
The admin directory contains the install directory as well as the install, delete, update, activate and deactivate script assoziated with this module. The install directory contains installation files required for other modules. The above example contains the two required files for providing navigation information to the navigation module so that the navigation module can display this module in the navigation bar. The navigation installation file as well as all other module installation files must have the same name as the navigation module and will be automatically called on installation if defined in the info.json file.
|
||||
The admin directory contains the install directory as well as the install, delete, update, activate and deactivate script associated with this module. The install directory contains installation files required for other modules. The above example contains the two required files for providing navigation information to the navigation module so that the navigation module can display this module in the navigation bar. The navigation installation file as well as all other module installation files must have the same name as the navigation module and will be automatically called on installation if defined in the info.json file.
|
||||
|
||||
The content of the navigation install file highly depends on the module and should be documented in the according module. The additional json file is also required by the navigation module for the installation process. How many additional files and how they have to be structured/named should all be documented in the module documentation. If your module doesn't provide any navigation links or in general doesn't use any other modules, your install directory will be empty.
|
||||
|
||||
Some modules can be used without requiring any additional installations it all depends on how the other modules got implemented. Thats also why many modules don't offer any integration at all and
|
||||
Some modules can be used without requiring any additional installations it all depends on how the other modules got implemented. Thats also why many modules don't offer any integration at all and
|
||||
are almost stand-alone without the possibility to get extended.
|
||||
|
||||
### Installer.php
|
||||
|
||||
In contrast to the install file for other moduels this file has to follow more strict standards. The following example shows you the bare minimum requirements of a installation file:
|
||||
In contrast to the install file for other modules this file has to follow more strict standards. The following example shows you the bare minimum requirements of a installation file:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
|
@ -100,7 +100,7 @@ public static function install(string $path, Pool $dbPool)
|
|||
}
|
||||
```
|
||||
|
||||
How the receiving module (e.g. Navigation) is accepting information depends on the module itself. The module documentation will also state how the content of the `install(...)` method has to look like. At the same time if you write a module and are accepting information from other modules during their installation you have to document very well how they have to provide these information. Very often however it will not be necessary to let other modules pass these information during installation and only do this during runtime.
|
||||
How the receiving module (e.g. Navigation) is accepting information depends on the module itself. The module documentation will also state how the content of the `install(...)` method has to look like. At the same time if you write a module and are accepting information from other modules during their installation you have to document very well how they have to provide these information. Very often however it will not be necessary to let other modules pass these information during installation and only do this during runtime.
|
||||
|
||||
The navigation module is a good example of passing navigation links during installation. The navigation module could request the link information during runtime this would mean that all modules would have to be initialized for every request since the navigation module doesn't know if these modules are providing links or not. By providing these information during the installation, the navigation module can store these information in a database table and query these information for every page request without initializing all modules or performing some file readings.
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ use phpOMS\Router\RouteVerb;
|
|||
return [
|
||||
'^.*/backend/admin/settings/general.*$' => [
|
||||
[
|
||||
'dest' => '\Modules\Admin\Controller:viewSettingsGeneral',
|
||||
'dest' => '\Modules\Admin\Controller:viewSettingsGeneral',
|
||||
'verb' => RouteVerb::GET,
|
||||
],
|
||||
],
|
||||
|
|
@ -147,11 +147,11 @@ The routes are defined via regex. One uri can have multiple destinations dependi
|
|||
|
||||
## Img
|
||||
|
||||
All module specific images (not theme specific images). E.g. Module preview images showing when searching for modules.
|
||||
All module specific images (not theme specific images). E.g. Module preview images showing when searching for modules.
|
||||
|
||||
## Models
|
||||
|
||||
All models and data mapper classes should be stored in here (PHP & JS). How to create a data mapper for a model is described in the data mapper chapter. All JavaScript files need to be provided unoptimized (not minified or concatenated).
|
||||
All models and data mapper classes should be stored in here (PHP & JS). How to create a data mapper for a model is described in the data mapper chapter. All JavaScript files need to be provided un-optimized (not minified or concatenated).
|
||||
|
||||
## Theme
|
||||
|
||||
|
|
@ -172,12 +172,12 @@ The Lang directory contains all language files for this application. Usually the
|
|||
A language file should have the following naming convention:
|
||||
|
||||
{ISO 639-1}.lang.php
|
||||
{UniqueModuleName}.{ISO 639-1}.lang.php
|
||||
{UniqueModuleName}.{ISO 639-1}.lang.php
|
||||
|
||||
The content of the language file is straight forward:
|
||||
|
||||
```php
|
||||
<?php return [
|
||||
<?php return [
|
||||
'{UniqueModuleName}' => [
|
||||
'StringID' => 'Your localized string',
|
||||
...
|
||||
|
|
@ -195,7 +195,7 @@ All other language files are optional and usually are only required by other mod
|
|||
|
||||
## info.json
|
||||
|
||||
The `info.json` file contains general module information used during installation as well for identification and display in the module database.
|
||||
The `info.json` file contains general module information used during installation as well for identification and display in the module database.
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -254,7 +254,7 @@ The `info.json` file contains general module information used during installatio
|
|||
|
||||
### Name
|
||||
|
||||
The name category contains the names used for internel as well as external identification. Both `id` and `internal` are globally unique between all modules and is assigned generated by Orange Management. The `id` can also be used by other modules which need integer identification of modules. The `id` has the form `xxxxx00000` which means, that modules don't only occupy a singl id but a range of ids. This can be usefull for other modules where additional module specifc information need to be assigned (e.g. `Navigation` module). The `external` name is the name the creator of the module can give the module. This is the name that will be used during searches for modules and shown to customers.
|
||||
The name category contains the names used for internal as well as external identification. Both `id` and `internal` are globally unique between all modules and is assigned generated by Orange Management. The `id` can also be used by other modules which need integer identification of modules. The `id` has the form `xxxxx00000` which means, that modules don't only occupy a single id but a range of ids. This can be useful for other modules where additional module specific information need to be assigned (e.g. `Navigation` module). The `external` name is the name the creator of the module can give the module. This is the name that will be used during searches for modules and shown to customers.
|
||||
|
||||
### Version
|
||||
|
||||
|
|
@ -266,7 +266,7 @@ major.minor.build = 2.512.19857
|
|||
|
||||
### Requirements
|
||||
|
||||
The `requirements` are used in order to specify core specific requirements such as the database requirements, framework requirements, third party library regirements as well as potential local software requirements.
|
||||
The `requirements` are used in order to specify core specific requirements such as the database requirements, framework requirements, third party library requirements as well as potential local software requirements.
|
||||
|
||||
### Creator
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ In the `creator` category it's possible to specify the `name` of the creator and
|
|||
|
||||
### Description
|
||||
|
||||
In the `description` a markdown description can be specified which will be shown in the module overview. This can be used in order to describe the users what the purpose of this module is and how it workds.
|
||||
In the `description` a markdown description can be specified which will be shown in the module overview. This can be used in order to describe the users what the purpose of this module is and how it works.
|
||||
|
||||
### Directory
|
||||
|
||||
|
|
@ -304,14 +304,14 @@ The result of the example would result in loading all specified resources for re
|
|||
|
||||
#### Type
|
||||
|
||||
The `type` contains the type of the file that needs to be loaded.
|
||||
The `type` contains the type of the file that needs to be loaded.
|
||||
|
||||
* 5 = Navigation language file
|
||||
* 4 = Module controller
|
||||
|
||||
#### For
|
||||
|
||||
The `for` contains the unique module string representation the file is loaded for. This could be the own module or a thrid party module.
|
||||
The `for` contains the unique module string representation the file is loaded for. This could be the own module or a third party module.
|
||||
|
||||
#### From
|
||||
|
||||
|
|
@ -319,4 +319,4 @@ The `from`contains the unique module string representation the file is loaded fr
|
|||
|
||||
#### File
|
||||
|
||||
The `file` contains the name of the file to be loaded. No path or extension is required nor allowed.
|
||||
The `file` contains the name of the file to be loaded. No path or extension is required nor allowed.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Updates
|
||||
|
||||
The following directory structure shows how a update/patch package has to be structured.The purpose of the different files will be
|
||||
The following directory structure shows how a update/patch package has to be structured.The purpose of the different files will be
|
||||
covered afterwards.
|
||||
|
||||
* {UniquePackageName.tar.gz}
|
||||
|
|
@ -8,7 +8,7 @@ covered afterwards.
|
|||
* Files
|
||||
* package.json
|
||||
* {other_files_or_subdirectories}
|
||||
|
||||
|
||||
## Package Name
|
||||
|
||||
The unique package name is generated by the update server. Usually they are called:
|
||||
|
|
@ -22,7 +22,7 @@ By providing unique package names it's possible to define other updates as depen
|
|||
|
||||
## signature.cert
|
||||
|
||||
The `signature.cert` contains the signature for the package which will be used to certify the origin of the package.
|
||||
The `signature.cert` contains the signature for the package which will be used to certify the origin of the package.
|
||||
The public key provided with the application is used to decrypt the certificate and compare it to the actual package data.
|
||||
|
||||
## Files
|
||||
|
|
@ -34,9 +34,10 @@ In the files directory all files are stored.
|
|||
The `package.json` file contains information of the package.
|
||||
|
||||
```json
|
||||
|
||||
```
|
||||
|
||||
### Other
|
||||
|
||||
All other files are related to updates, patches, extensions and installation. These files can be simple assets that will be used or
|
||||
replaced in modules, classes in the framework that need to be updated and sql methods for updateing the database schema.
|
||||
All other files are related to updates, patches, extensions and installation. These files can be simple assets that will be used or
|
||||
replaced in modules, classes in the framework that need to be updated and sql methods for updating the database schema.
|
||||
|
|
|
|||
68
datastorage/database/connection.md
Normal file
68
datastorage/database/connection.md
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Database Connection
|
||||
|
||||
A database connection can be created manually with the respective database connection model, with the database connection factory or with the database pool which also manages multiple database connections.
|
||||
|
||||
## Database Connection
|
||||
|
||||
A connection takes an array which contains the database connection information and create the connection:
|
||||
|
||||
```php
|
||||
$con = new MysqlConnection([
|
||||
'db' => 'mysql', /* db type */
|
||||
'host' => '127.0.0.1', /* db host address */
|
||||
'port' => '3306', /* db host port */
|
||||
'login' => 'root', /* db login name */
|
||||
'password' => '', /* db login password */
|
||||
'database' => 'oms', /* db name */
|
||||
'prefix' => 'oms_', /* db table prefix */
|
||||
]);
|
||||
```
|
||||
|
||||
With `getStatus()` you can check the status of the connection.
|
||||
|
||||
## Database Factory
|
||||
|
||||
The connection factory automatically creates the correct connection based on the database definition:
|
||||
|
||||
```php
|
||||
$con = ConnectionFactory::create([
|
||||
'db' => 'mysql', /* this is used by the connection factory to pick the correct connection */
|
||||
'host' => '127.0.0.1',
|
||||
'port' => '3306',
|
||||
'login' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'oms',
|
||||
'prefix' => 'oms_',
|
||||
]);
|
||||
```
|
||||
|
||||
## Database Pool
|
||||
|
||||
Existing database connections can be added to the database pool:
|
||||
|
||||
```php
|
||||
$dbPool = new DatabasePool();
|
||||
$dbPool->add('read', $con1);
|
||||
$dbPool->add('write', $con2);
|
||||
|
||||
$dbPool->get('read'); // returns $con1
|
||||
```
|
||||
|
||||
This allows to create different database connections with different permissions or handling database connections with different databases.
|
||||
|
||||
A new database connection can also be directly created by the database pool:
|
||||
|
||||
```php
|
||||
$dbPool = new DatabasePool();
|
||||
$dbPool->create('read',
|
||||
[
|
||||
'db' => 'mysql',
|
||||
'host' => '127.0.0.1',
|
||||
'port' => '3306',
|
||||
'login' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'oms',
|
||||
'prefix' => 'oms_',
|
||||
]
|
||||
);
|
||||
```
|
||||
|
|
@ -12,7 +12,7 @@ The database query builder provides a uniform way to write default database quer
|
|||
|
||||
### Query Builder
|
||||
|
||||
The query builder is used for regular CRUD opperations on the database.
|
||||
The query builder is used for regular CRUD operations on the database.
|
||||
|
||||
#### Prefix
|
||||
|
||||
|
|
@ -69,8 +69,8 @@ $query->prefix(...)->select(...)->from(...)->where('columnA', '=', 123)->where('
|
|||
|
||||
For easier use additional `where` clauses are defined such as:
|
||||
|
||||
* `orWhere()` - same as `where` with `or` as default boolean concatenater
|
||||
* `andWhere()` - same as `where` with `and` as default boolean concatenater
|
||||
* `orWhere()` - same as `where` with `or` as default boolean connector
|
||||
* `andWhere()` - same as `where` with `and` as default boolean connector
|
||||
* `whereIn()` - uses the sql `in(...)`
|
||||
* `whereNull()` - used for null condition
|
||||
* `whereNotNull()` - used for not null condition
|
||||
|
|
@ -99,7 +99,7 @@ The ordering is performed by `orderBy`.
|
|||
$query->prefix(...)->select(...)->from(...)->where(...)->orderBy('columnA', 'DESC');
|
||||
```
|
||||
|
||||
The `newest` and `oldest` operation are a small wrapper which automatically order by `DESC` and `ASC` respectively.
|
||||
The `newest` and `oldest` operation are a small wrapper which automatically order by `DESC` and `ASC` respectively.
|
||||
|
||||
#### Group By
|
||||
|
||||
|
|
|
|||
|
|
@ -15,12 +15,12 @@ Desktop notifications make use of the `Notification` Api. These notifications al
|
|||
|
||||
```js
|
||||
notifyManager.send(
|
||||
new jsOMS.Message.Notification.NotificationMessage(
|
||||
jsOMS.Message.Notification.NotificationStatus.SUCCESS,
|
||||
new NotificationMessage(
|
||||
NotificationStatus.SUCCESS,
|
||||
'Title',
|
||||
'My Message'
|
||||
),
|
||||
jsOMS.Message.Notification.NotificationType.BROWSER_NOTIFICATION
|
||||
NotificationType.BROWSER_NOTIFICATION
|
||||
);
|
||||
```
|
||||
|
||||
|
|
@ -30,11 +30,11 @@ App notifications are a custom notification implementation which can be themed a
|
|||
|
||||
```js
|
||||
notifyManager.send(
|
||||
new jsOMS.Message.Notification.NotificationMessage(
|
||||
jsOMS.Message.Notification.NotificationStatus.SUCCESS,
|
||||
new NotificationMessage(
|
||||
NotificationStatus.SUCCESS,
|
||||
'Title',
|
||||
'My Message'
|
||||
),
|
||||
jsOMS.Message.Notification.NotificationType.APP_NOTIFICATION
|
||||
NotificationType.APP_NOTIFICATION
|
||||
);
|
||||
```
|
||||
|
|
@ -34,10 +34,6 @@ This project uses font-awesome for its icons, the following example allows for s
|
|||
</i>
|
||||
```
|
||||
|
||||
## Colors
|
||||
|
||||
Coloring can be added to many elements such as icons, sections etc. Available colors are `lightgreen`, `green`, `darkgreen`, `lightblue`, `blue`, `darkblue`, `lightred`, `red`, `darkred`, `lightyellow`, `yellow`, `lightorange`, `orange`, `white`, `lightgrey`, `grey`, `black`, `lightpurple`, `purple`, `darkpurple`, `lightteal`, `teal`, `darkteal`, `lightpink`, `pink`.
|
||||
|
||||
## Form Elements
|
||||
|
||||
### Input with button
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ As external tool scrutinizer is used to automate code inspection and provide ins
|
|||
|
||||
## Git Hooks (Linux only)
|
||||
|
||||
The git hooks perform various checks and validations during the `commit` and warn the developer about invalid code or code style/guideline violations.
|
||||
|
||||
For developers it is recommended to copy the contents of the `default.sh` file in the `Build` repository under `Hooks` to your `pre-commit` file in the `.git/hooks` directory. If the `pre-commit` file doesn't exist just create it.
|
||||
|
||||
The same should be done with every module. Simply go to `.git/modules/**/hooks` and also add the content of the `default.sh` file to all `pre-commit` files.
|
||||
|
|
|
|||
|
|
@ -89,16 +89,16 @@ The x-frame-options is providing the same protection for frames as the content-s
|
|||
$response->getHeader()->set('x-frame-options', 'SAMEORIGIN');
|
||||
```
|
||||
|
||||
## Super globals
|
||||
## Superglobals
|
||||
|
||||
Super globals are not available throughout the application and the values can only be accessed through middleware classes like:
|
||||
Superglobals are not available throughout the application and the values can only be accessed through middleware classes like:
|
||||
|
||||
* SessionManager
|
||||
* CookieJar
|
||||
* Request
|
||||
* Response
|
||||
|
||||
In some cases super globals will even be overwritten by values from these classes before generating a response. Do not directly access super globals!
|
||||
In some cases superglobals will even be overwritten by values from these classes before generating a response. Do not directly access superglobals!
|
||||
|
||||
## Input validation
|
||||
|
||||
|
|
|
|||
|
|
@ -12,13 +12,13 @@ $eventManager->attach('eventId', function() { echo 'Hello World'; });
|
|||
|
||||
### Repeating events
|
||||
|
||||
If a event should only be able to be triggered once another boolean parameter has to be edded to the `attach()` function call.
|
||||
If a event should only be able to be triggered once another boolean parameter has to be edded to the `attach()` function call.
|
||||
|
||||
```php
|
||||
$eventManager->attach('eventId', function() { echo 'Hello World'; }, true);
|
||||
```
|
||||
|
||||
Now the event will be removed from the event manager once executed.
|
||||
Now the event will be removed from the event manager once executed.
|
||||
|
||||
### Resetting events
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ The following tools are important to test the application and to ensure the code
|
|||
|
||||
## Git Hooks (Linux only)
|
||||
|
||||
The git hooks perform various checks and validations during the `commit` and warn the developer about invalid code or code style/guideline violations.
|
||||
|
||||
For developers it is recommended to copy the contents of the `default.sh` file in the `Build` repository under `Hooks` to your `pre-commit` file in the `.git/hooks` directory. If the `pre-commit` file doesn't exist just create it.
|
||||
|
||||
The same should be done with every module. Simply go to `.git/modules/**/hooks` and also add the content of the `default.sh` file to all `pre-commit` files.
|
||||
|
|
|
|||
|
|
@ -58,8 +58,10 @@ During this process the database automatically gets dropped (if existing) and re
|
|||
|
||||
## Git Hooks (Linux only)
|
||||
|
||||
The git hooks perform various checks and validations during the `commit` and warn the developer about invalid code or code style/guideline violations.
|
||||
|
||||
For developers it is recommended to copy the contents of the `default.sh` file in the `Build` repository under `Hooks` to your `pre-commit` file in the `.git/hooks` directory. If the `pre-commit` file doesn't exist just create it.
|
||||
|
||||
The same should be done with every module. Simply go to `.git/modules/**/hooks` and also add the content of the `default.sh` file to all `pre-commit` files.
|
||||
The same should be done with every module. Simply go to `.git/modules/**/hooks` and also add the content of the `default.sh` file to all `pre-commit` files.
|
||||
|
||||
By doing this every commit will be inspected and either pass without warnings, pass with warnings or stop with errors. This will allow you to fix code before committing it. Be aware only changed files will be inspected. Also make sure all `pre-commit` have `+x` permissions.
|
||||
|
|
@ -14,7 +14,6 @@ A file documentation MUST be implemented in the following form:
|
|||
*
|
||||
* PHP Version 7.0
|
||||
*
|
||||
* @category Category name
|
||||
* @package Package name
|
||||
* @copyright Orange Management
|
||||
* @license OMS License 1.0
|
||||
|
|
@ -31,7 +30,6 @@ A class documentation MUST be implemented in the following form:
|
|||
/**
|
||||
* Class description.
|
||||
*
|
||||
* @category Category name
|
||||
* @package Package name
|
||||
* @license OMS License 1.0
|
||||
* @link http://your.url.com
|
||||
|
|
@ -91,7 +89,6 @@ The javascript documentation is based on JsDoc, therefore only valid JsDoc comme
|
|||
/**
|
||||
* File description
|
||||
*
|
||||
* @category Category name
|
||||
* @package Package name
|
||||
* @copyright Orange Management
|
||||
* @license OMS License 1.0
|
||||
|
|
@ -108,7 +105,6 @@ A class documentation MUST be implemented in the following form:
|
|||
/**
|
||||
* Class description.
|
||||
*
|
||||
* @category Category name
|
||||
* @package Package name
|
||||
* @license OMS License 1.0
|
||||
* @link http://your.url.com
|
||||
|
|
|
|||
|
|
@ -26,6 +26,17 @@ This means each class is in a file by itself, and is in a namespace of at least
|
|||
|
||||
Class names MUST be declared in StudlyCaps.
|
||||
|
||||
### Default Functions
|
||||
|
||||
Function calls to php internal function calls must use the root namespace `\`:
|
||||
|
||||
```php
|
||||
\substr(...);
|
||||
\is_bool(...);
|
||||
\file_get_contents(...);
|
||||
....
|
||||
```
|
||||
|
||||
## Php in html
|
||||
|
||||
Php code embedded into template files SHOULD use the alternative syntax for control structures in order to improve the readability:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user