diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml new file mode 100644 index 0000000..d2fb2d4 --- /dev/null +++ b/.github/workflows/image.yml @@ -0,0 +1,24 @@ +name: Compress images +on: + push: + paths: + - '**.jpg' + - '**.png' + - '**.webp' + pull_request: + paths: + - '**.jpg' + - '**.png' + - '**.webp' +jobs: + build: + name: calibreapp/image-actions + runs-on: ubuntu-latest + steps: + - name: Checkout Repo + uses: actions/checkout@master + + - name: Compress Images + uses: calibreapp/image-actions@master + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22d0d82 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vendor diff --git a/SUMMARY.md b/SUMMARY.md index 23a60f4..11f6e85 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,60 +1,58 @@ # General -* [Introduction]({%}?page=README) -* [Setup]({%}?page=general/setup) -* [Application Structure]({%}?page=general/structure) +* [Introduction]({%}&page=README) +* [Setup]({%}&page=general/setup) +* [Application Structure]({%}&page=general/structure) ## Quality & Standards -* [Code Inspection]({%}?page=quality/inspections) -* [Documentation Standards]({%}?page=standards/documentation) -* [General Code Standards]({%}?page=standards/general) -* [Security Standards]({%}?page=security/security_guidelines) -* [Html Coding Standards]({%}?page=standards/html) -* [Php Coding Standards]({%}?page=standards/php) +* [Code Inspections & Tests]({%}&page=quality/inspections) +* [Documentation Standards]({%}&page=standards/documentation) +* [General Code Standards]({%}&page=standards/general) +* [Security Standards]({%}&page=security/security_guidelines) +* [Html Coding Standards]({%}&page=standards/html) +* [Php Coding Standards]({%}&page=standards/php) ## Examples -* [Application Sample]({%}?page=example_app/app) -* [Modules]({%}?page=example_module/module) -* [Packages]({%}?page=example_module/packages) +* [Application Sample]({%}&page=example_app/app) +* [Modules]({%}&page=example_module/module) +* [Packages]({%}&page=example_module/packages) ## API -### Application -* [Routing]({%}?page=basics/routing) -* [Dispatching]({%}?page=basics/dispatching) -* [Localization]({%}?page=services/localization) -* [Views]({%}?page=basics/views) - -### Messaging -* [Requests]({%}?page=basics/requests) -* [Responses]({%}?page=basics/responses) -* [Mail]({%}?page=services/mail) -* [Uri]({%}?page=services/uri) +### Message +* [Uri]({%}&page=services/uri) +* [Requests]({%}&page=basics/requests) +* [Responses]({%}&page=basics/responses) +* [Mail]({%}&page=services/mail) ### DataStorage -* [Cache]({%}?page=datastorage/cache) -* [Session]({%}?page=datastorage/session) -* [Cookie]({%}?page=datastorage/cookie) -* [LocalStorage]({%}?page=datastorage/localstorage) -* [Filesystem]({%}?page=services/filesystem) -* [Database Connection]({%}?page=datastorage/database/connection) -* [DataMapper]({%}?page=datastorage/database/datamapper) -* [Queries]({%}?page=datastorage/database/queries) +* [LocalStorage]({%}&page=datastorage/localstorage) +* [Database Connection]({%}&page=datastorage/database/connection) +* [DataMapper]({%}&page=datastorage/database/datamapper) +* [Queries]({%}&page=datastorage/database/queries) +* [Cache]({%}&page=datastorage/cache) +* [Session]({%}&page=datastorage/session) +* [Cookie]({%}&page=datastorage/cookie) + +### System +* [Filesystem]({%}&page=services/filesystem) +* [Events]({%}&page=services/events) +* [Logging]({%}&page=services/logging) +* [Tasks]({%}&page=services/tasks) + +### StdLib +* [Localization]({%}&page=services/localization) +* [Money]({%}&page=services/money) +* [Queues]({%}&page=services/queues) +* [Collection]({%}&page=services/collection) ### UI -* [Styles and Layout]({%}?page=frontend/styles_and_layout) -* [Charting]({%}?page=services/charting) -* [Codes]({%}?page=services/codes) +* [Styles and Layout]({%}&page=frontend/styles_and_layout) +* [Charting]({%}&page=services/charting) +* [Codes]({%}&page=services/codes) +* [Routing]({%}&page=basics/routing) +* [Dispatching]({%}&page=basics/dispatching) +* [Views]({%}&page=basics/views) +* [Validation]({%}&page=services/validation) ### Security -* [Encoding]({%}?page=services/encoding) -* [Encryption]({%}?page=services/encryption) - -### Datatypes -* [Money]({%}?page=services/money) -* [Queues]({%}?page=services/queues) -* [Collection]({%}?page=services/collection) - -### Misc. -* [Events]({%}?page=services/events) -* [Logging]({%}?page=services/logging) -* [Tasks]({%}?page=services/tasks) -* [Validation]({%}?page=services/validation) \ No newline at end of file +* [Encoding]({%}&page=services/encoding) +* [Encryption]({%}&page=services/encryption) diff --git a/basics/dispatching.md b/basics/dispatching.md index c199186..7990628 100644 --- a/basics/dispatching.md +++ b/basics/dispatching.md @@ -1,12 +1,12 @@ # Dispatching -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 dispatching is the follow up on the routing. In the dispatcher the route destination gets resolved and executed. Dispatching can be performed on module instance methods, static functions and anonymous functions. The return of the `dispatch()` call is an array of all end point returns. ## Basic -The dispatcher accepts a string representation of the method or static function which should be dispatched, a closure which should be executed or an array of the above. +The dispatcher accepts a string representation of the method or static function which should be dispatched, a closure which should be executed or an array of the just mentioned options. The `dispatch()` function accepts additionally a variable amount of parameters which will be passed to the routed method/function. @@ -38,14 +38,14 @@ $dispatcher->dispatch(function($para1, $para2) { ... }, $staticToCallPara1, $sta ## Routing -The dispatcher accepts the resoults from the `route()` method of the router which is an array of routes. +The dispatcher accepts the results from the `route()` method of the router which is an array of routes. ```php -$dispatcher->dispatch($router->route($request->getUri()->getRoute())); +$dispatcher->dispatch($router->route($request->uri->getRoute())); ``` 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. ```php -$dispatcher->dispatch($router->route($request->getUri()->getRoute()), $request, $response); +$dispatcher->dispatch($router->route($request->uri->getRoute()), $request, $response); ``` diff --git a/basics/routing.md b/basics/routing.md index a417c23..2897e25 100644 --- a/basics/routing.md +++ b/basics/routing.md @@ -162,4 +162,8 @@ $router->route( 'APP_NAME', ORG_ID, ACCOUNT ); -``` \ No newline at end of file +``` + +## Notes + +* 2-character routes on the first level are discouraged because they may conflict with ISO 639-1 codes (e.g. /hr/staff/list) \ No newline at end of file diff --git a/datastorage/cache.md b/datastorage/cache.md index 5010e72..ab01c3e 100644 --- a/datastorage/cache.md +++ b/datastorage/cache.md @@ -1,6 +1,6 @@ ## 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 therfor shouldn't be missuesed 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. +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 @@ -9,7 +9,7 @@ By default only stylesheets, javascript and layout images as well as module imag Example usage for 30 days caching: ```php -$resposne->setHeader('Cache-Control', 'Cache-Control: max-age=2592000'); +$response->setHeader('Cache-Control', 'Cache-Control: max-age=2592000'); ``` In order to trigger a re-cache of stylesheets or javascript files make sure to update the version in the `Controller.php` file. This way version updates will result in a new virtual file uri and result in a re-cache. @@ -17,5 +17,5 @@ In order to trigger a re-cache of stylesheets or javascript files make sure to u Example usage: ```php -$head->addAsset(AssetType::JS, $request->getUri()->getBase() . 'Modules/Media/Controller.js?v=' . self::MODULE_VERSION); +$head->addAsset(AssetType::JS, $request->uri->getBase() . 'Modules/Media/Controller.js?v=' . self::MODULE_VERSION); ``` \ No newline at end of file diff --git a/datastorage/cookie.md b/datastorage/cookie.md index 1c60aa0..2ca7691 100644 --- a/datastorage/cookie.md +++ b/datastorage/cookie.md @@ -2,6 +2,6 @@ ## PHP -Only use cookies when absolutely necessary. Most of the time session data or local storage is the prefered choice. The `CookieJar` class provides you with all the necessary functionality similar to the `SessionManager`. The super global `$_COOKIE` is also overwritten and shouldn't be used anywhere. +Only use cookies when absolutely necessary. Most of the time session data or local storage is the preferred choice. The `CookieJar` class provides you with all the necessary functionality similar to the `SessionManager`. The super global `$_COOKIE` is also overwritten and shouldn't be used anywhere. ## JavaScript diff --git a/datastorage/database/connection.md b/datastorage/database/connection.md index d399d56..9f31e0b 100644 --- a/datastorage/database/connection.md +++ b/datastorage/database/connection.md @@ -14,7 +14,6 @@ $con = new MysqlConnection([ 'login' => 'root', /* db login name */ 'password' => 'root', /* db login password */ 'database' => 'oms', /* db name */ - 'prefix' => 'oms_', /* db table prefix */ ]); ``` @@ -32,7 +31,6 @@ $con = ConnectionFactory::create([ 'login' => 'root', 'password' => 'root', 'database' => 'oms', - 'prefix' => 'oms_', ]); ``` @@ -62,7 +60,6 @@ $dbPool->create('read', 'login' => 'root', 'password' => 'root', 'database' => 'oms', - 'prefix' => 'oms_', ] ); ``` \ No newline at end of file diff --git a/datastorage/database/datamapper.md b/datastorage/database/datamapper.md index f18359c..8080acf 100644 --- a/datastorage/database/datamapper.md +++ b/datastorage/database/datamapper.md @@ -2,7 +2,7 @@ ## 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): +Models can be constructed in what ever way you like, all of the mapping logic is defined in the data mapper itself. However, it is recommended to provide the following member variables if applicable (names can be different): ```php private $id = 0; @@ -32,6 +32,21 @@ In a similar fashion as the `$createdAt` variable often it is also necessary to 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. +### Model + +The `$model` variable can be optionally used in order to specify the model this mapper is supposed to populate. By default the mapper will try to find a model in the same directory as the mapper without the `Mapper` suffix in its name. + +Default behavior example: + +* Mapper name: `\test\path\TestMapper` +* Default maodel: `\test\path\Test` + +If the model is defined somewhere else or has a different name, the `$model` variable name should be used to define the correct model. E.g. + +```php +protected static string $model = OtherModel::class; +``` + ### Columns In the `$columns` array all columns, respective model variables and data types need to be specified. @@ -45,6 +60,17 @@ protected static array $columns = [ 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. +#### Searchable columns + +In order to make columns searchable you have to add `'autocomplete' => true` as column information to the respective column. + +```php +protected static array $columns = [ + 'db_field_name_1' => ['name' => 'db_field_name_1', 'type' => 'int', 'internal' => 'model_var_name_1', 'autocomplete' => true], + 'db_field_name_2' => ['name' => 'db_field_name_2', 'type' => 'string', 'internal' => 'model_var_name_2'], +]; +``` + #### Types Possible types are: @@ -53,9 +79,9 @@ Possible types are: * string * bool * float -* \DateTime -* serializable (will call `serialize()`) -* json (will call `jsonSerialize()`) +* DateTime +* Serializable (will call `serialize()`) +* Json (will call `jsonSerialize()`) ### Has many @@ -66,7 +92,7 @@ protected static array $hasMany = [ 'model_var_name_3' => [ 'mapper' => HasManyMapper::class, 'table' => 'relation_table_name', - 'dst' => 'relation_destinaiton_name', + 'dst' => 'relation_destination_name', 'src' => 'relation_source_name', ], ]; @@ -74,6 +100,8 @@ protected static array $hasMany = [ 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. +#### Relation is defined in the model table + A many to one or one to one relation would look like the following: ```php @@ -81,12 +109,14 @@ protected static array $hasMany = [ 'model_var_name_3' => [ 'mapper' => HasManyMapper::class, 'table' => null, - 'dst' => 'relation_destinaiton_name', + 'dst' => 'relation_destination_name', 'src' => null, ], ]; ``` +#### Relation is defined in a relation table + A many to many relation which can only be defined in a relation table looks like the following: ```php @@ -94,15 +124,34 @@ protected static array $hasMany = [ 'model_var_name_3' => [ 'mapper' => HasManyMapper::class, 'table' => 'relation_table_name', - 'dst' => 'relation_destinaiton_name', + 'dst' => 'relation_destination_name', 'src' => 'relation_source_name', ], ]; ``` +#### Single field relations + +By defining a `column` it's also possible to only populate the model with a single column/field value from another table or model. + +```php +protected static array $hasMany = [ + 'my_title' => [ + 'mapper' => L11nTagMapper::class, + 'table' => 'tag_l11n', + 'external' => 'tag_l11n_tag', + 'column' => 'title', + 'conditional' => true, + 'self' => null, + ], +]; +``` + +In the example above the model member variable `my_title` will be populated with the value `title` from the `L11nTagMapper`. Here the `L11nTagMapper` will to a reverse lookup of the column name for the variable `title` and return the content. + ### Owns one -It's possible to also define a relation in the source module itself. This can be acomplished by using the `$ownsOne` variable. In this case the model itself has to specify a field where the primary key of the source model is defined. +It's possible to also define a relation in the source module itself. This can be accomplished by using the `$ownsOne` variable. In this case the model itself has to specify a field where the primary key of the source model is defined. ```php protected static array $ownsOne = [ @@ -113,11 +162,11 @@ protected static array $ownsOne = [ ]; ``` -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. +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 relation. ### Belongs to -The reverse of a has one is a belongs to. This allows to also load models that a specific model belongs to. This can be acomplished by using the `$belongsTo` variable. In this case the model itself has to specify a field where the primary key of the source model is defined. +The reverse of a has one is a belongs to. This allows to also load models that a specific model belongs to. This can be accomplished by using the `$belongsTo` variable. In this case the model itself has to specify a field where the primary key of the source model is defined. ```php protected static array $belongsTo = [ @@ -129,3 +178,19 @@ protected static array $belongsTo = [ ``` The `mapper` field contains the class name of the mapper of the destination model. The `dest` field contains the database field name where the primary key is stored that this model belongs to. + +## Conditionals + +Conditionals provide a general way to filter the desired result of models. You can think about conditionals as SQL `WHERE` clauses. A conditional uses the model member variable name instead of the database table name. + +```php +WithConditionalMapper::withConditional('language', 'en')::getAll(); +``` + +This query returns all models of the `WithConditionalMapper` which have a member variable with the value `en`. In the background the mapper does a reverse lookup, checks the column name which is associated with the `language` member variable and filters the database result accordingly. + +By default conditionals are recursive and get applied to all models which are somehow referenced in the request (e.g. has many models which have also a `language` member variable). In some cases this is undesired and the user wants to specify the models where the conditionals should be applied to. This can be achieved in the following way: + +```php +WithConditionalMapper::withConditional('language', 'en', [FirstModelToApplyTo::class, SecondModelToApplyTo::class, ...])::getAll(); +``` \ No newline at end of file diff --git a/datastorage/database/queries.md b/datastorage/database/queries.md index be37841..5bf007e 100644 --- a/datastorage/database/queries.md +++ b/datastorage/database/queries.md @@ -14,34 +14,25 @@ The database query builder provides a uniform way to write default database quer The query builder is used for regular CRUD operations on the database. -#### Prefix - -Projects often use a prefix for all of the tables. For this project the default prefix is `oms_`. - -```php -$query = new Builder(); -$query->prefix('oms_'); -``` - #### Select, Insert, Update, Delete Both `select` and `insert` expect the column names as parameter. The `where`, `from` and `into` clause can be necessary depending on the type of operation like a normal sql query. ```php -$query->prefix(...)->select('columnA', 'columnB')->from('table')->where(...); -$query->prefix(...)->insert('columnA', 'columnB')->values('a', 'b')->into('table'); +$query->select('columnA', 'columnB')->from('table')->where(...); +$query->insert('columnA', 'columnB')->values('a', 'b')->into('table'); ``` The `update` expects the table name which should be updated and then the `set` function to define the columns and new values. ```php -$query->prefix(...)->update('table')->set(['columnA' => 'a'])->set(['columnB' => 'b'])->where(...); +$query->update('table')->set(['columnA' => 'a'])->set(['columnB' => 'b'])->where(...); ``` The `delete` function only expects the `from` and `where` clause to identify the to delete columns in a table. ```php -$query->prefix(...)->delete()->from('table')->where(...); +$query->delete()->from('table')->where(...); ``` ##### Random @@ -51,8 +42,8 @@ $query->prefix(...)->delete()->from('table')->where(...); The `from` part of a query accepts `string`, `array`, `\Closure`, `From`, `Builder` as parameter. ```php -$query->prefix(...)->select(...)->from('table'); -$query->prefix(...)->select(...)->from('tableA', 'tableB'); +$query->select(...)->from('table'); +$query->select(...)->from('tableA', 'tableB'); ``` #### Into @@ -64,7 +55,7 @@ The `into` part of a query accepts `string`, `array`, `\Closure`, `Into`, `Build The basic `where` clause expects a column, operator, value and boolean concatenater which is used to concatenate multiple where clauses. ```php -$query->prefix(...)->select(...)->from(...)->where('columnA', '=', 123)->where('columnB', '=', 'abc', 'or'); +$query->select(...)->from(...)->where('columnA', '=', 123)->where('columnB', '=', 'abc', 'or'); ``` For easier use additional `where` clauses are defined such as: @@ -80,7 +71,7 @@ For easier use additional `where` clauses are defined such as: The `limit` expects an integer. ```php -$query->prefix(...)->select(...)->from(...)->where(...)->limit(3); +$query->select(...)->from(...)->where(...)->limit(3); ``` #### Offset @@ -88,7 +79,7 @@ $query->prefix(...)->select(...)->from(...)->where(...)->limit(3); The `offset` expects an integer. ```php -$query->prefix(...)->select(...)->from(...)->where(...)->offset(3); +$query->select(...)->from(...)->where(...)->offset(3); ``` #### Order @@ -96,7 +87,7 @@ $query->prefix(...)->select(...)->from(...)->where(...)->offset(3); The ordering is performed by `orderBy`. ```php -$query->prefix(...)->select(...)->from(...)->where(...)->orderBy('columnA', 'DESC'); +$query->select(...)->from(...)->where(...)->orderBy('columnA', 'DESC'); ``` The `newest` and `oldest` operation are a small wrapper which automatically order by `DESC` and `ASC` respectively. @@ -106,7 +97,7 @@ The `newest` and `oldest` operation are a small wrapper which automatically orde Grouping of columns can be achieved through `groupBy`. ```php -$query->prefix(...)->select(...)->from(...)->where(...)->groupBy('columnA', 'columnB'); +$query->select(...)->from(...)->where(...)->groupBy('columnA', 'columnB'); ``` #### Join diff --git a/datastorage/session.md b/datastorage/session.md index 307e97d..abe24b6 100644 --- a/datastorage/session.md +++ b/datastorage/session.md @@ -1,6 +1,6 @@ # Sessions -Sessions are handled via the `SessionManager`. Sessions can be set and manipulated from the web application as well as the socket or console application. +Sessions are handled via the `SessionManager`. Sessions can be set and manipulated from the web application as well as the socket or console application. ## HTTP @@ -8,4 +8,4 @@ The Http session will be saved automatically, there is no need to access the sup ## Socket & Console -The session will be stored and assoziated with the logged in user in memory. A disconnect or quit is considered as a logout and therefor results in the destruction of the session object of this user and will be empty for the next login. +The session will be stored and associated with the logged in user in memory. A disconnect or quit is considered as a logout and therefor results in the destruction of the session object of this user and will be empty for the next login. diff --git a/example_app/app.md b/example_app/app.md index ae29b40..6bea8f1 100644 --- a/example_app/app.md +++ b/example_app/app.md @@ -41,7 +41,7 @@ echo $App->run(); // outputs the application response namespace app; -use phpOMS\ApplicationAbstract; /* provides many member variables which are often shared with controllers */ +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; @@ -78,7 +78,7 @@ class Application extends ApplicationAbstract /* get data from url endpoints defined by the routes */ $dispatch = $this->dispatcher->dispatch( $this->router->route( - $request->getUri()->getRoute(), + $request->uri->getRoute(), $request->getData('CSRF'), // optional: only required if csrf tokens are used otherwise use null $request->getRouteVerb() // e.g. get, post, put ... ), @@ -91,7 +91,7 @@ class Application extends ApplicationAbstract $pageView->addData('dispatch', $dispatch); // push the headers (no changes to the header are possible afterwards) - $response->getHeader()->push(); + $response->header->push(); // renders the content of the response object (depends on the content type, text/html, json, ...) return $response->getBody(); @@ -107,10 +107,10 @@ class Application extends ApplicationAbstract $request->createRequestHashs(0); // if your application is located in a web-subfolder for easier handling - $request->getUri()->setRootPath('/'); + $request->uri->setRootPath('/'); // this will allow you to create urls based on request data - UriFactory::setupUriBuilder($request->getUri()); + UriFactory::setupUriBuilder($request->uri); return $request; } @@ -121,9 +121,9 @@ class Application extends ApplicationAbstract $response = new HttpResponse(); // 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->header->set('content-type', 'text/html; charset=utf-8'); - $response->getHeader()->set('x-xss-protection', '1; mode=block'); + $response->header->set('x-xss-protection', '1; mode=block'); // more CSP can be defined here return $response; @@ -203,7 +203,7 @@ return [ namespace app\controller; -use phpOMS\ApplicationAbstract; +use phpOMS\Application\ApplicationAbstract; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Views\View; diff --git a/example_module/module.md b/example_module/module.md index 555f38a..c99d2c8 100644 --- a/example_module/module.md +++ b/example_module/module.md @@ -139,12 +139,12 @@ namespace Modules\Navigation\Admin; use phpOMS\DataStorage\Database\DatabaseType; use phpOMS\DataStorage\Database\DatabasePool; -use phpOMS\Module\InfoManager; +use phpOMS\Module\ModuleInfo; use phpOMS\Module\InstallerAbstract; -class Installer extends InstallerAbstract +final class Installer extends InstallerAbstract { - public static function install(string $path, Pool $dbPool, InfoManager $info) + public static function install(string $path, Pool $dbPool, ModuleInfo $info) { parent::install($path, $dbPool, $info); @@ -157,7 +157,7 @@ class Installer extends InstallerAbstract } ``` -If your application doesn't need to implement any database tables for itself the switch statement can be omitted. From the directory structur at the beginning we can however see that some modules accept information form other modules. The following example shows how the navigation module is accepting information during the installation of other modules: +If your application doesn't need to implement any database tables for itself the switch statement can be omitted. From the directory structure at the beginning we can however see that some modules accept information form other modules. The following example shows how the navigation module is accepting information during the installation of other modules: ```php public static function installExternal(Pool $dbPool, array $data) diff --git a/frontend/styles_and_layout.md b/frontend/styles_and_layout.md index c543157..0919cad 100644 --- a/frontend/styles_and_layout.md +++ b/frontend/styles_and_layout.md @@ -11,7 +11,7 @@ Flexboxes are preferred for all content containers. ```html