Merge pull request #2 from Orange-Management/develop

This commit is contained in:
Dennis Eichhorn 2016-08-09 16:33:11 +02:00 committed by GitHub
commit c92f204ad0
34 changed files with 590 additions and 20 deletions

View File

@ -26,3 +26,4 @@
## Components
* [Caching, Sessions, Local Storage & Cookies](components/caching,_sessions,_local_storage_&_cookies.md)
* [Modules](components/modules.md)
* [Modules](components/datamapper.md)

17
basics/dispatching.md Normal file
View File

@ -0,0 +1,17 @@
# Dispatching
The dispatching is the follow up on the routing. In the dispatcher the route destination get resolved and executed.
The dispatching is fairly simple as it only requires a single function call.
```
$this->dispatcher->dispatch($this->router->route($request))
```
Based on the function definition returned by the router it's possible to pass more parameters to the function such e.g. request and response objects.
```
$this->dispatcher->dispatch($this->router->route($request), $request, $response)
```
The result of the `dispatch` call is an array of results.

0
basics/requests.md Normal file
View File

0
basics/responses.md Normal file
View File

86
basics/routing.md Normal file
View File

@ -0,0 +1,86 @@
# 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.
## 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
```
$this->router->route(new Request());
```
or a route
```
$this->router->route('foo/bar', RouteVerb::GET);
```
The result is an array of either string references or closures.
## Closure
For routes it's possible to define a `\Closure` which will get returned upon using the specified route.
```
$this->router->add('foo/bar', function() {
return 'Hellow 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.
```
$this->router->add('foo/bar', function() {
return 'Hellow World';
}, RouteVerb::GET | RouteVerb::SET);
```
## Route Parameters
<coming soon>
## Reference
Instead of defining closures it's possible to define a string representation of the destination that should be called.
```
$this->router->add('foo/bar', '\foo\controller:barFunction');
```
Static functions can be defined in the following fashion:
```
$this->router->add('foo/bar', '\foo\controller::barFunction');
```
## Import
While routes can be added manually to the router it's also possible to import a list of routes through the file import function.
```
$this->router->importFromFile($path);
```
The routing file must have the folloing structure:
```
<?php return [
'{ROUTE_STRING}' => [
[
'dest' => {CLOSURE/REFERENCE_STRING},
'verb' => {VERB_1 | VERB_2},
],
[
'dest' => {CLOSURE/REFERENCE_STRING},
'verb' => {VERB_3},
],
],
'{ANOTHER_ROUTE_STRING}' => [ ... ],
];
```
In this schematic the first route has different destinations depending on the verb.

0
basics/views.md Normal file
View File

View File

@ -1,4 +0,0 @@
# DataMapper & Query Builder

View File

@ -7,6 +7,9 @@ The following directory structure should roughly visualize how modules are struc
* Install
* Navigation.install.json
* Navigation.php
* Routes
* Web
* Backend.php
* Update
* yourUpdateFiles.???
* Activate.php
@ -109,6 +112,39 @@ The navigation module is a good example of passing navigation links during insta
### Deactivate.php
### Routes
In the routes directory all application routes are stored. These routing files get used during the installation process of every module and are stored in an application specific routing file. The first directory level contains the directories of the application type `Web`, `Socket` and `Console`. Inside these directories the routing files for the applications are stored by the name of the application e.g. `Backend.php`. The routing files themselves look like this:
```
<?php
use phpOMS\Router\RouteVerb;
return [
'^.*/backend/admin/settings/general.*$' => [
[
'dest' => '\Modules\Admin\Controller:viewSettingsGeneral',
'verb' => RouteVerb::GET,
],
],
'^.*/api/admin/module/status.*$' => [
[
'dest' => '\Modules\Admin\Controller:apiModuleStatusGet',
'verb' => RouteVerb::GET,
],
[
'dest' => '\Modules\Admin\Controller:apiModuleStatusUpdate',
'verb' => RouteVerb::SET,
],
],
];
```
The routes are defined via regex. One uri can have multiple destinations depending on the request type/verb. It's also possible to have multiple destinations for the same verb in case other views need to be loaded for the same uri (e.g. view injection in order to extend modules).
## Img
All module specific images (not theme specific images). E.g. Module preview images showing when searching for modules.
@ -141,10 +177,12 @@ A language file should have the following naming convention:
The content of the language file is straight forward:
```
<?php
$return [ '{UniqueModuleName}' => [
'StringID' => 'Your localized string',
]];
<?php return [
'{UniqueModuleName}' => [
'StringID' => 'Your localized string',
...
]
];
```
All other language files are optional and usually are only required by other modules. The navigation module for example requires an extra language file for the navigation elements. This however should be specified in the modules you want to make use of.
@ -155,4 +193,130 @@ All other language files are optional and usually are only required by other mod
## Controller.js
## info.json
## info.json
The `info.json` file contains general module information used during installation as well for identification and display in the module database.
```
{
"name": {
"id": {UniqueModuleId_INT},
"internal": "{UniqueModuleId_STR}",
"external": "{Readable module name}"
},
"version": "{Version}",
"requirements": {
"phpOMS": "{Version}",
"phpOMS-db": "{Version}"
},
"creator": {
"name": "{Creator name/organization}",
"website": "{Creator website}"
},
"description": "{Module description}",
"directory": "{UniqueModuleId_STR}",
"dependencies": {},
"providing": {
"Navigation": "{Version}"
},
"load": [
{
"pid": [
"{SHA1_Uri_hash}"
],
"type": 4,
"for": "Content",
"file": "{UniqueModuleId_STR}",
"from": "{UniqueModuleId_STR}"
},
{
"pid": [
"{SHA1_Uri_hash}"
],
"type": 5,
"from": "{UniqueModuleId_STR}",
"for": "{UniqueModuleId_For_STR}",
"file": "{UniqueModuleId_For_STR}"
},
{
"pid": [
"{SHA1_Uri_hash}"
],
"type": 5,
"for": "Content",
"file": "{UniqueModuleId_STR}",
"from": "{UniqueModuleId_STR}"
}
]
}
```
### 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.
### Version
The version is automatically incremented by Orange Management. The version might be used by other modules in order to require a specific version of a module. Versions must follow the following format:
```
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.
### Creator
In the `creator` category it's possible to specify the `name` of the creator and the `website` of the creator. Multiple creators are not possible.
### 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.
### Directory
The `directory` is the directory name of the module which is usually the unique string representation of the module. This is the directory in the modules folder where the module files will be located.
### Dependencies
Often modules depend on other modules, these dependencies can be defined in the `dependencies`. The keys contain the unique string representation of the required modules and the value contains the version that is required.
### Providing
In the `providing` category modules can specify other modules they intend to extend if they are installed. The keys contain the unique string representation of the module which is getting extended and the value contains the version of the module that is supposed to get extended.
### Load
The `load` category contains all the files (controllers, language files) that need to be loaded during the application setup for a specific request uri.
#### PID
The `pid` (page identifier) is a sha1 hash of the uri where the `file` is supposed to be loaded. The pid needs to be defined in the following matter (e.g. http://127.0.0.1/en/app/path/sub&some=thing):
```
sha1('apppath');
```
The result of the example hash would result in loading all specified files for requests containing '/app/path'. This also includes requests to any subdirectories.
#### Type
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.
#### From
The `from`contains the unique module string representation the file is loaded from. This is the `internal` module name from the top of the `info.json` file.
#### File
The `file` contains the name of the file to be loaded. No path or extension is required nor allowed.

0
datastorage/cache.md Normal file
View File

115
datastorage/datamapper.md Normal file
View File

@ -0,0 +1,115 @@
# DataMapper
## Models
Models can be constructed in what ever way you like, all of the mapping logic is defined in the data mapper itself. It is however recommended to provide the following member variables if applicable (names can be different):
```
private $id = 0;
private $createdAt = null;
private $createdBy = null;
```
The `$id` can be used as primary key. For this member variable no setter method should be present. For the `$createdAt` as well as the `$createdBy` member variables both getter and setter methods are possible. It's also possible to make these variables immutable since both should be known during the initialization point of a new model.
## DataMapper
The data mapper itself is where all the magic happens, from inserts, updates, to selects etc.
### Primary key
The primary key can be indicated with the variable `$primaryField`. This variable should contain the string representation of the database field name. This variable is compulsory.
### Created at
While it is possible to log user, module and database activities thorugh the logging module it is often necessary to know when a certain entry got created. For that purpose the `$createdAt` can be used to define the string representation of the database field name which contains the date of the insert.
### Created by
In a similar fashion as the `$createdAt` variable often it is also necessary to have a field containing the id of the account creating the entry. The varibale `$createdBy` has to contain the string representation of that database field name.
### Table
One model can only be stored in one table. With the `$table` variable it's possible to specify the table name. This variable is compulsory. It's important to note that by extending a model you also need to implement a data mapper that can access multiple tables. In that case it's also necessary to extend the data mapper of the extended module.
### Columns
In the `$columns` array all columns, respective model variables and data types need to be specified.
```
protected static $columns = [
'db_field_name_1' => ['name' => 'db_field_name_1', 'type' => 'int', 'internal' => 'model_var_name_1'],
'db_field_name_2' => ['name' => 'db_field_name_2', 'type' => 'string', 'internal' => 'model_var_name_2'],
]
```
The `name` contains the field name in the database, the `type` represents the data type and `internal` is the string representation of the model variable name.
#### Types
Possible types are:
* int
* string
* bool
* float
* serializable (will call `serialize()`)
* json (will call `jsonSerialize()`)
### Has many
With the `$hasMany` variable it's possible to specify other models that belong to this model.
```
protected static $hasMany = [
'model_var_name_3' => [
'mapper' => HasManyMapper::class,
'table' => 'relation_table_name',
'dst' => 'relation_destinaiton_name',
'src' => 'relation_source_name',
],
];
```
The `mapper` contains the class name of the mapper responsible for the many models that belong to this model. The `table` contains the name of the table where the relations are defined (this can be the same table as the source model or a relation table). If a model is only in relation with one other model this relation can be defined in the same table as the model and this `table` field can be `null`. The `dst` field contains the name of field where the primary key of the destination is defined. The `src` field is only required for models which have a relation table. This field contains the name of the field where the primary key of the source model is defined.
A one to many relation would look like the following:
```
protected static $hasMany = [
'model_var_name_3' => [
'mapper' => HasManyMapper::class,
'table' => null,
'dst' => 'relation_destinaiton_name',
'src' => null,
],
];
```
A many to many relation which can only be defined in a relation table looks like the following:
```
protected static $hasMany = [
'model_var_name_3' => [
'mapper' => HasManyMapper::class,
'table' => 'relation_table_name',
'dst' => 'relation_destinaiton_name',
'src' => 'relation_source_name',
],
];
```
### Has one
It's possible to also define a relation in the destination module itself. This can be acomplished by using the `$hasOne` variable. In this case the model itself has to specify a field where the primary key of the source model is defined.
```
protected static $hasOne = [
'model_var_name_4' => [
'mapper' => HasOneMapper::class,
'src' => 'relation_source_name',
],
];
```
The `mapper` field contains the class name of the mapper of the source model. The `src` field contains the database field name where the primary key is stored that is used for the realation.

39
datastorage/queries.md Normal file
View File

@ -0,0 +1,39 @@
# Queries
## Database
The database query builder provides a uniform way to write default database queries for the following databases:
* MySQL
* PostgreSQL
* SQLite
* MicrosoftSQL
* OracleSQL
### Query Builder
The query builder is used for regular CRUD opperations on the database.
#### Prefix
#### Select, Insert, Update, Delete
##### Random
#### From
#### Into
#### Where
#### Limit
#### Offset
#### Order
#### Join
### Schema Builder
The schema builder is used for schema related operations such as `DROP`, `CREATE` etc.

0
datastorage/session.md Normal file
View File

0
math/forecasting.md Normal file
View File

0
math/matrix.md Normal file
View File

View File

0
services/charting.md Normal file
View File

0
services/codes.md Normal file
View File

0
services/collection.md Normal file
View File

0
services/encoding.md Normal file
View File

0
services/encryption.md Normal file
View File

0
services/events.md Normal file
View File

0
services/filesystem.md Normal file
View File

75
services/localization.md Normal file
View File

@ -0,0 +1,75 @@
# Localization
Most of the localization is stored inside the localization object which is part of every request and response as well as the account model.
## Language
Language specific text can be used through the `LocalizationManager`, either by directly calling the `getText()` function of the localization manager
```
$this->l11nManager->getText({LANGUAGE}, {MODULE}, {THEME}, {TEXT})
```
or indirectly by calling the `getText()` in the view context.
```
$this->getText({TEXT})
```
The language that should be used for a response should always be depending on the requested language and therefore never be hard coded.
The language code of the localization object is the 2 character ISO639 code. The corresponding enums are located in the localization directory and labeled with `ISO639`.
* ISO639Enum Language name
* ISO639x1Enum 2 character language code
* ISO639x2Enum 3 character language code
## Country
The country code of the localization object is the 2 character ISO3166 code. The corresponding enums are located in the localization directory and labeled with `ISO3166`.
* ISO3166TwoEnum 2 character country code
* ISO3166CharEnum 3 character country code
* ISO3166NameEnum country name
* ISO3166NumEnum country code
## Units
### Currency
The currency code of the localization object is the 3 character ISO4217 code. The corresponding enums are located in the localization directory and labeled with `ISO4217`.
* ISO4217CharEnum 3 character currency code
* ISO4217DecimalEnum currency decimal places
* ISO4217Enum currency name
* ISO4217NumEnum currency code
* ISO4217SubUnitEnum currency sub unit
* ISO4217SymbolEnum currency symbol
## Formatting
### Currency
The currency symbol can be placed either in front or at the end of a value. The `Money` class provides a function called `getCurrency()` which returns a localized representation by specifying the thousands and decimal separator as well as the currency symbol and its position.
```
$money->getcurrency(2, ',', '.', '$', 0);
```
### DateTime
The date/time is versatile and can have multiple formats. By default the localization object stores 5 different date/time formats depending on the degree of accuracy required.
* very_short
* short
* medium
* long
* very_long
Other formats are beyond the scope of the localization and must be hard coded. Please be cautios when to hard code the formatting and pay attention to potential confusion for different localizations.
In the database only the ISO 8601 format will be used.
### Numeric
The numeric formatting is defined by a `thousands` and `decimal` separator and available as separate member variables of the localization object.

0
services/logging.md Normal file
View File

0
services/mail.md Normal file
View File

25
services/money.md Normal file
View File

@ -0,0 +1,25 @@
# Money
Money is a delicate element and must be handled precisely. With the `Money` class a precise representation of float up to the precision of 4 decimal places is supported.
## Initialization
The initialization can be done by providing an integer, float or string representation. The following list describes how different scalar types get converted.
* (int) 12300 = 1.23
* (float) 1.23 = 1.23
* (string) 1.23 = 1.23
The max and min money values that can be represented on a 32bit system are `214,748.3647` and `-214,748.3647` which is most of the time not sufficient. On 64bit systems however the max and min values that can be represented ar `922,337,203,685,477.5807` and `-922,337,203,685,477.5807`.
## Operations
The `Money` class follows the builder pattern. The provided operations are addition, subtraction, multiplication, division, absolute and power.
## Example
```
$money = new Money(1234567, ',', '.', '$', 0);
$money->add(1.0)->sub(10000)->mult('-1.0')->div(new Money(-1.0));
echo $money->getCurrency(); // $123.46
```

0
services/persers.md Normal file
View File

0
services/queues.md Normal file
View File

0
services/rng.md Normal file
View File

0
services/tasks.md Normal file
View File

58
services/uri.md Normal file
View File

@ -0,0 +1,58 @@
# Uri
The `UriFactory` is used in order to build URIs. The factory generates the URIs based on a raw uri as well as defined parameters and placeholders. The uri factory is available for the backend as well as the frontend and operate mostly the same and provide similar functionlity.
## Parameters
The raw uri string supports parameters that will be replaced with manual or default values. Parameters are always enclosed by `{}` and have a special prefix such as `#./?@$%`
```
$rawUri = 'http://www.yoururl.com/en/some/{/path}?foo=bar&id={@data}'
```
These placeholders will be filled by values that are defined by the `setQuery()` function.
```
UriFactory::setQuery('/path', 'thing');
UriFactory::setQuery('@data', 1);
UriFactory::build($rawUri) // http://www.yoururl.com/en/some/thing?foo=bar&id=1
```
It is possible to simply use the current uri and simply append parameters if you only want to change or set additional query parameters.
```
{%}&another={@value}
```
### Default Parameters
Some default parameters can be used for easier use.
* /scheme = current scheme (e.g. http)
* /host = current host (e.g. www.yoururl.com)
* /lang = current language (e.g. en)
* ?foo = value of the specified parameter
* ? = current query
* % = current uri
* # = fragment
* / = root
* :port = port
* :user = user
* :pass = password
### Frontend Parameters
While it's also possible to define parameters at the frontend and make use of the default values certain prefixes have a special meaning.
* #somid = value of the element with the specified id
* .somclass = values of the elements with the specified class
### Dynamic Parameters
Sometimes a parameter shouldn't be globally defined but is necessary to parse for a specific uri, in that case it's possible to pass an array or object of parameter definitions to the build function where the key is the parameter key and the value is the parameter value it should replace.
```
jsOMS.Uri.UriFactory.build('yoururl.com/en/some/{/path}?id={@data}', {'@data': 1});
```
The match array/object takes priority over the default parameters which means you can overwrite them for a specific uri.

0
services/validation.md Normal file
View File

0
setup/configuration.md Normal file
View File

View File

@ -1,23 +1,17 @@
# Installation
Installing the application as a developer can be achived by following one of the following instructions
Installing the application as a developer can be achived by following one of the following instructions.
## General
## Server Requirements
After installation following one of the instructions make sure you set the appropriate permissions for files and directories:
* 0700 Log
* PHP >= 7.1
* PDO PHP Extension
* Mbstring PHP Extension
## Linux Shell Script
This is the prefered way to install the application since this also installs all required dev tools and sets up the direcetory structure by itself. Using this method also tears down previous installs for a fresh install perfect for re-installing from the current development version. Furthermore the use of phpUnit also makes sure that the application is working as intended. The phpUnit install also provides lots of dummy data for better integration and functionality testing of your own code/modules.
### Requirements
1. PHP 7.0
2. npm
3. xdebug or phpdbg
### Steps
1. Go somewhere where you want to install the build script