diff --git a/basics/dispatching.md b/basics/dispatching.md index b84d249..f86464e 100644 --- a/basics/dispatching.md +++ b/basics/dispatching.md @@ -20,6 +20,19 @@ The module function can be called by providing the namespace followed by the fun $dispatcher->dispatch('\My\Namespace:methodToCall', $methodToCallPara1, $methodToCallPara2, ...); ``` +In order to allow the dispatcher to automatically create a a controller instance. The class constructore for the controller `\my\Namespace` needs to extend `ModuleAbstract` and have the format: + +```php +public function __construct(ApplicationAbstract $app) {} +``` + +Alternatively you can also add a controller manually to the disptacher. In this case you may construct the controller as you see fit. However, the controller must extend `ModuleAbstract`. + +```php +$testController = new MyController(); +$dispatcher->set($testController, MyController::class) +``` + #### Static A static function can be called by providing the namespace followed by the function name concatonated with two colons `::` between the function name and the namespace. diff --git a/basics/routing.md b/basics/routing.md index 74d5fb7..95eb08b 100644 --- a/basics/routing.md +++ b/basics/routing.md @@ -64,12 +64,12 @@ The routing file must have the following structure: [ [ - 'dest' => {CLOSURE/REFERENCE_STRING}, - 'verb' => {VERB_1 | VERB_2}, + 'dest' => CLOSURE/REFERENCE_STRING, + 'verb' => VERB_1 | VERB_2, ], [ - 'dest' => {CLOSURE/REFERENCE_STRING}, - 'verb' => {VERB_3}, + 'dest' => CLOSURE/REFERENCE_STRING, + 'verb' => VERB_3, ], ], '{ANOTHER_ROUTE_STRING}' => [ ... ], @@ -110,17 +110,17 @@ $router->route('foo/bar', null, RouteVerb::GET, 'APP_NAME', ORG_ID, ACCOUNT); [ [ - 'dest' => {CLOSURE/REFERENCE_STRING}, - 'verb' => {VERB_1 | VERB_2}, + 'dest' => CLOSURE/REFERENCE_STRING, + 'verb' => VERB_1 | VERB_2, 'permission' => [ - 'module' => {MODULE_NAME}, - 'type' => {CREATE | READ | UPDATE | DELETE | PERMISSION}, - 'state' => {MODULE_SPECIFIC_IDENTIFIER_FOR_THE_PERMISSION}, + 'module' => MODULE_NAME, + 'type' => CREATE | READ | UPDATE | DELETE | PERMISSION, + 'state' => MODULE_SPECIFIC_IDENTIFIER_FOR_THE_PERMISSION, ], ], [ - 'dest' => {CLOSURE/REFERENCE_STRING}, - 'verb' => {VERB_3}, + 'dest' => CLOSURE/REFERENCE_STRING, + 'verb' => VERB_3, ], ], '{ANOTHER_ROUTE_STRING}' => [ ... ], diff --git a/datastorage/cache.md b/datastorage/cache.md index ab01c3e..11f9a3f 100644 --- a/datastorage/cache.md +++ b/datastorage/cache.md @@ -1,8 +1,8 @@ -## Cache +# Cache For caching the `CacheManager` provides access to the caching systems in place. Out of the box the CacheManager supports and automatically initializes either Redis or Memcached depending on the client configuration. The caching is not mandatory and therefor shouldn't be misused as in-memory database. It is not necessary to check if Redis or Memcached are available the CacheManager automatically handles the caching based on their existence. -### HTTP Cache +## HTTP Cache By default only stylesheets, javascript and layout images as well as module images are cached. Everything else is considered volatile and not cached. If a response specific response should be cached feel free to use the response header: @@ -18,4 +18,31 @@ Example usage: ```php $head->addAsset(AssetType::JS, $request->uri->getBase() . 'Modules/Media/Controller.js?v=' . self::MODULE_VERSION); -``` \ No newline at end of file +``` + +## System Cache + +All cache systems implement very similar functionality. It is only due to different features of the underlying technologie that some minor details are different between the different cache solutions. + +The available cache solutions are: + +* File Cache +* Redis Cache +* MemCached + +The available features are as follows: + +* set - Sets a cache value or overwrites it (in some cache implementations with expiration date) +* add - Adds a cache value if the key doesn't exists (in some cache implementations with expiration date) +* replace - Replaces a cache value if the key exists +* get - Gets the cache value by key +* delete - Deletes a cache key/value +* exists - Checks if a key/value exists +* increment - Increments a numeric value by a given amount +* decrement - Decrements a numeric value by a given amount +* rename - Renames a key +* getLike - Finds keys/values based on a regex pattern +* deleteLike - Deletes keys/values based on a regex pattern +* updateExpire - Updates the expire date (only in some cache implementations possible) +* flush - Empties the cache by expiration +* flushAll - Empties the complete cache \ No newline at end of file diff --git a/example_module/packages.md b/example_module/packages.md index 131131a..5d5bdf6 100644 --- a/example_module/packages.md +++ b/example_module/packages.md @@ -16,7 +16,7 @@ The unique package name is generated by the update server. Usually they are call * Modules: {Module Name}_{New Version}.tar.gz * Framework: {Framework Name}_{New Version}.tar.gz * Resources: {Resource Name}_{New Version}.tar.gz -* Other Components: {Component Name}_{New Version}.tar.gz +* Other Components: {Component Name}\_{New Version}.tar.gz By providing unique package names it's possible to define other updates as dependencies and prevent overwriting update packages. diff --git a/services/events.md b/services/events.md index 58a2840..df4c3c3 100644 --- a/services/events.md +++ b/services/events.md @@ -10,6 +10,8 @@ Every event requires a unique trigger key as well as a `\Closure` which should b $eventManager->attach('eventId', function() { echo 'Hello World'; }); ``` +The eventId can also be a regex in order to let it trigger on multiple occasions (e.g. `$eventManager->attach('/Test[a-z]+/', ...)`) + ### 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. @@ -38,6 +40,10 @@ An event can be triggered by calling the `trigger()` function. $eventManager->trigger('eventId'); ``` +### Triggering Similar Events + +In some situations you might want to trigger multiple events. In this case you can provide a regex as eventId and/or conditionName (e.g. `$eventManager->grigger('/[a-z]+/')`) + ## Multi Condition Events In some cases it is required that multiple conditions are met before an event is supposed to be triggered. This can be achieved by registering these conditions through the `addGroup()` function. @@ -62,4 +68,4 @@ The order in which these conditions are triggered doesn't mapper. A multi condit ## Frontend vs. Backend -The only key difference between the frontend and backend implementation is that the frontend prevents running the same event in quick succession (less than 500 ms) in order to prevent undesired effects which can happen due to quick UI interaction. +The only key difference between the frontend and backend implementation is that the frontend prevents running the same event in quick succession (less than 300 ms) in order to prevent undesired effects which can happen due to quick UI interaction. diff --git a/services/validation.md b/services/validation.md index e69de29..749bd24 100644 --- a/services/validation.md +++ b/services/validation.md @@ -0,0 +1,189 @@ +# Validation + +The built in validation allows to quickly validate some basic data formats. + +## Validator + +The `Validator` provides basic validations with: + +### isValid + +With the `isValid` function you can provide a variable which should be validated and one or multiple constraints which should be checked. The return is a boolean. + +```php +public static function isValid(mixed $var, array $constraints = null) : bool; +``` + +Example: + +```php +function functionName(mixed $var, $mySetting1, $mySetting2) : bool +{ + // Do some validation here + return true; +} + +Validator::isValid($testVariable, ['functionName' => $settings]); +``` + +The second parameter (settings paramenter) contains an associative array where the key is the function name which should get invoked and the value are the settings/options/parameters passed to the function name. The function must be implemented by the user. + +If multiple constraints are provided the validation only returns true if all validations are successful. + +In order to negate the validation simply add a `Not` to the function name. + +> The negated function name with *Not* must not be separately implemented as it will be negated internally. + +### hasLength + +With `hasLength` you can check if a string has defined length. + +```php +public static function hasLength(string $var, int $min = 0, int $max = \PHP_INT_MAX) : bool; +``` + +### hasLimit + +With `hasLimit` you can check if a numeric value is in a defined range. + +```php +public static function hasLimit(int | float $var, int | float $min = 0, int | float $max = \PHP_INT_MAX) : bool; +``` + +## Base + +### DateTime + +The `DateTime` validator checks if a specified value is a valid datetime. + +```php +DateTime::isValid('2099-01-01'); +``` + +### Json + +The `Json` validator checks if a specified value is a valid json string. + +```php +Json::isValid('[1, 2, 3]'); +``` + +#### Templates + +You can specify a json template which uses regex for validation. The template then is used to validate against a json array. + +The validator checks for completeness, match against the template and possible additional specifications which are not part of the template. + +Example for our `info.json` valdiation + +```json +{ + "name": { + "id": "^[1-9]\\d*", + "internal": "[a-zA-Z0-9]+", + "external": "[a-zA-Z0-9]+" + }, + "category": "[a-zA-Z0-9]+", + "version": "([0-9]+\\.){2}[0-9]+", + "requirements": { + ".*": ".*" + }, + "creator": { + "name": ".+", + "website": ".*" + }, + "description": ".+", + "directory": "[a-zA-Z0-9]+", + "dependencies": { + ".*": ".*" + }, + "providing": { + ".*": ".*" + }, + "load": [ + { + "pid": [ + ".*" + ], + "type": "^[1-9]\\d*", + "for": "^([1-9]\\d*)|([a-zA-Z0-9]+)", + "from": "[a-zA-Z0-9]+", + "file": "[a-zA-Z0-9]*" + } + ] +} + +``` + +The example above shows how to specifiy optional elements (e.g. "dependencies") which can have as many children in any form possible or optional values with a specific key (e.g. website) which can be omitted. + +## Finance + +### BIC + +A simple BIC validator which only validates the structure not if it actually exists. + +```php +BIC::isValid('DSBACNBXSHA'); +``` + +### Iban + +A simple IBAN validator which only validates the structure not if it actually exists. + +```php +Iban::isValid('DE22 6008 0000 0960 0280 00'); +``` + +### CreditCard + +A simple credit card validator which only validates the structure not if it actually exists. + +```php +CreditCard::isValid('4242424242424242'); +``` + +## Network + +### Email + +A simple email validator which only validates the structure not if it actually exists. + +```php +Email::isValid('test.string@email.com'); +``` + +### Hostname + +A simple hostname validator which only validates the structure not if it actually exists. + +```php +Hostname::isValid('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]'); // true +Hostname::isValid('test.com'); // true + +Hostname::isValid('2001:0db8:85a3:0000:0000:8a2e:0370:7334'); // false +Hostname::isValid('http://test.com'); // false +``` + +### Ip + +A simple ip validator which only validates the structure not if it actually exists. + +```php +IP::isValid('192.168.178.1'); +IP::isValid('2001:0db8:85a3:0000:0000:8a2e:0370:7334'); + +IP::testValidIp4('192.168.178.1'); +IP::testValidIp6('2001:0db8:85a3:0000:0000:8a2e:0370:7334'); +``` + +> Please note that the Ip4 and Ip6 validators only validate their corresponding Ips which means that a Ip4 will not correctly validate as Ip6 and vice versa. + +## Enum + +Enums can be validated by name/key and by value. + +```php +MyEnum::isValidName('ENUM_NAME'); +MyEnum::isValidValue(123); +``` \ No newline at end of file