Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Dotkernel Admin Documentation
1 change: 0 additions & 1 deletion docs/book/index.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/book/index.md
1 change: 0 additions & 1 deletion docs/book/v5/introduction/file-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ Other classes the `src` folder may include are `InputFilter`, `EventListener`, `
The `src` folder in each Module folder normally also contains these files:

* `ConfigProvider.php` - Configuration data for the module
* `OpenAPI.php` - Detailed descriptions for each endpoint in the OpenAPI format
* `RoutesDelegator.php` - Module specific route registrations

### `templates` folder for modules
Expand Down
1 change: 0 additions & 1 deletion docs/book/v6/introduction/file-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ Other classes the `src` folder may include are `Adapter`, `Factory`, `Form`, `De
The `src` folder in each Module folder normally also contains these files:

* `ConfigProvider.php` - Configuration data for the module
* `OpenAPI.php` - Detailed descriptions for each endpoint in the OpenAPI format
* `RoutesDelegator.php` - Module specific route registrations

### `templates` folder for modules
Expand Down
8 changes: 2 additions & 6 deletions docs/book/v6/tutorials/create-book-module-via-dot-maker.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Implementing a book module in Dotkernel Admin using DotMaker

The `dotkernel/dot-maker` library can be used to programmatically generate project files and directories.
It can be added to your API installation by following the [official documentation](https://docs.dotkernel.org/dot-maker/).
It can be added to your Dotkernel Admin installation by following the [official documentation](https://docs.dotkernel.org/dot-maker/).

## Folder and files structure

Expand Down Expand Up @@ -72,10 +72,6 @@ you can have multiple components such as event listeners, wrappers, etc.
* `src/Core/src/Book/src/Repository/BookRepository.php` – a repository is a class responsible for querying and retrieving entities from the database
* `src/Core/src/Book/src/ConfigProvider.php` – is a class that provides configuration for Doctrine ORM

> Note that while this tutorial covers a standalone case, the `Core` module generated by default has the same structure as the one described in the
> [Dotkernel API "Book" module](https://docs.dotkernel.org/api-documentation/v6/tutorials/create-book-module-via-dot-maker/)
> allowing use as part of the [Dotkernel Headless Platform](https://docs.dotkernel.org/headless-documentation/)

## File creation and contents

After successfully installing `dot-maker`, it can be used to generate the Book module.
Expand All @@ -90,7 +86,7 @@ Type `book` when prompted to enter the module name.

Next you will be prompted to add the relevant components of a module, accepting `y(es)`, `n(o)` and `Enter` (defaults to `yes`):

> Note that `dot-maker` will automatically split the files into the described `Api` and `Core` structure without a further input needed.
> Note that `dot-maker` will automatically split the files into the described `Admin` and `Core` structure without a further input needed.

* `Entity and repository` (Y): will generate the `Book.php` entity and the associated `BookRepository.php`.
* `Service` and `service interface` (Y): will generate the `BookService` and the `BookServiceInterface`.
Expand Down
43 changes: 43 additions & 0 deletions docs/book/v7/how-to/authorization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Authorization Guards

The packages responsible for restricting access to certain parts of the application are [dot-rbac-guard](https://github.com/dotkernel/dot-rbac-guard) and [dot-rbac](https://github.com/dotkernel/dot-rbac).
These packages work together to create an infrastructure that is customizable and diversified to manage user access to the platform by specifying the type of role the user has.

The `authorization.global.php` file provides multiple configurations specifying multiple roles as well as the types of permissions to which these roles have access.

```php
//example of a flat RBAC model that specifies two types of roles as well as their permission
'roles' => [
'admin' => [
'permissions' => [
'authenticated',
'edit',
'delete',
//etc..
]
],
'user' => [
'permissions' => [
'authenticated',
//etc..
]
]
]
```

The `authorization-guards.global.php` file defines which permissions are required to access specific route handlers.
These permissions must first be declared in the `authorization.global.php` (dot-rbac) configuration file.

```php
// Example configuration granting access to route handlers based on permissions.
'rules' => [
'admin::admin-login-form' => [],
'admin::admin-login' => [],
'admin::admin-create-form' => ['authenticated'],
'admin::admin-create' => ['authenticated'],
'admin::admin-delete-form' => ['authenticated'],
'admin::admin-delete' => ['authenticated'],
'admin::admin-edit-form' => ['authenticated'],
'admin::admin-edit' => ['authenticated'],
]
```
32 changes: 32 additions & 0 deletions docs/book/v7/how-to/creating-fixtures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Fixtures

> Fixtures are used to seed the database with initial values and should only be executed ONCE each, after migrating the database.

Seeding the database is done with the help of our custom package `dotkernel/dot-data-fixtures` built on top of `doctrine/data-fixtures`.
See below on how to use our CLI command for listing and executing Doctrine data fixtures.

## Working with fixtures

You can find an example of a fixtures class in `src/Core/src/App/src/Fixture/AdminLoader.php`.

To list all the available fixtures by order of execution, run:

```shell
php ./bin/doctrine fixtures:list
```

To execute all fixtures, run:

```shell
php ./bin/doctrine fixtures:execute
```

To execute a specific fixture, use its class name, like in this example:

```shell
php ./bin/doctrine fixtures:execute --class=AdminLoader
```

Fixtures can and should be ordered to ensure database consistency.
More on ordering fixtures can be found here:
https://www.doctrine-project.org/projects/doctrine-data-fixtures/en/latest/how-to/fixture-ordering.html#fixture-ordering
29 changes: 29 additions & 0 deletions docs/book/v7/how-to/creating-migrations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Creating migrations

Migrations are used to create and/or edit the database structure.
To generate a new migration file, use this command:

```shell
php ./vendor/bin/doctrine-migrations migrations:generate
```

It creates a PHP file like this one `src/Core/src/App/src/Migration/Version20240627134952.php` that can then be edited in the IDE.
You can add new queries in:

- `public function up` - these are executed when the migration is run.
- `public function down` - these are optional queries that undo the above changes.

## Example

This example creates a new column named `test`.
Add this in `public function up`:

```shell
$this->addSql('ALTER TABLE admin ADD test VARCHAR(255) NOT NULL');
```

And its opposite in `public function down`:

```shell
$this->addSql('ALTER TABLE admin DROP test');
```
73 changes: 73 additions & 0 deletions docs/book/v7/how-to/csrf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# CSRF protection in forms

A Cross-Site Request Forgery (CSRF) attack is a type of security vulnerability that tricks a user into performing actions on a web application in which they are authenticated, without their knowledge or consent.

Web applications can protect users against these types of attacks by implementing CSRF tokens in their forms, which are known only to the application that generated them and must be included when submitting forms.
With each visit, a new CSRF token is added to the form, so tokens are not reusable between forms.
Missing to provide a valid CSRF token will result in a form validation error.

## Implement CSRF protection

Implementing CSRF protection requires three steps:

- create a new field using [laminas/laminas-form](https://github.com/laminas/laminas-form)'s [CSRF](https://github.com/laminas/laminas-form/blob/3.21.x/src/Element/Csrf.php) element
- validate new field using [laminas/laminas-session](https://github.com/laminas/laminas-session)'s [CSRF](https://github.com/laminas/laminas-session/blob/2.22.x/src/Validator/Csrf.php) validator
- render field using [laminas/laminas-form](https://github.com/laminas/laminas-form)'s [FormElement](https://github.com/laminas/laminas-form/blob/3.21.x/src/View/Helper/FormElement.php) helper

### Create field

Open the form's PHP class and append the following code to the method that initializes the fields (usually `init`):

```php
$this->add(
(new \Laminas\Form\Element\Csrf('exampleCsrf'))
->setOptions([
'csrf_options' => ['timeout' => 3600, 'session' => new Container()],
])
->setAttribute('required', true)
);
```

where `exampleCsrf` should be a suggestive name that describes the purpose of the field (example: `forgotPasswordCsrf`).

### Validate field

Open the InputFilter that validates the form fields and append the following code to the method that initializes the fields (usually `init`):

```php
$this->add(new \Admin\App\InputFilter\Input\CsrfInput('exampleCsrf'));
```

where `exampleCsrf` must match the CSRF field's name in the form.

> Remember to modify both occurrences in this file.

> Make sure that you validate the form using its `isValid` method in the handler/controller where it is submitted.

### Render field

Open the template that renders your form and add the following code somewhere between the form's opening and closing tags:

```text
{{ formElement(form.get('exampleCsrf')) }}
```

## Test the implementation

Access your form from the browser and view its source. You should see a new hidden field, called `exampleCsrf` (or however you named it).
After filling out the form, submitting it should work as before.

To make sure that the new CSRF field works as expected, you can inspect the form using your browser's `Developer tools` and modify its value in any way.
Submitting a filled-out form should result in a validation error:

> This field is required and cannot be empty.

### Timeout

Note the `timeout` option in your PHP form's `exampleCsrf` field, with its default value set to **3600**.
This represents the value in seconds for how long the token is valid.
Submitting a form that has been rendered for longer than this value will result in a validation error:

> Invalid CSRF.

You can modify the value of `timeout` in each form, but the default value should work in most cases.
55 changes: 55 additions & 0 deletions docs/book/v7/how-to/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Dependency Injection

Dependency injection is a design pattern used in software development to implement inversion of control.
In simpler terms, it's the act of providing dependencies for an object during instantiation.

In PHP, dependency injection can be implemented in various ways, including through constructor injection, setter injection and property injection.

Dotkernel Admin, through its [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, focuses only on constructor injection.

## Usage

Dotkernel Admin comes out of the box with the [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, which provides all the functionality for injecting dependencies into any object you want.

`dot-dependency-injection` determines the dependencies by looking at the `#[Inject]` attribute, added to the constructor of a class.
Each dependency is specified as a separate parameter of the `#[Inject]` attribute.

For our example we will inject `RouterInterface` and `AuthenticationServiceInterface` dependencies into `GetAccountLogoutHandler`.

```php
use Dot\DependencyInjection\Attribute\Inject;

class GetAccountLogoutHandler implements RequestHandlerInterface
{
#[Inject(
RouterInterface::class,
AuthenticationServiceInterface::class,
)]
public function __construct(
protected RouterInterface $router,
protected AuthenticationServiceInterface $authenticationService,
) {
}
}
```

> If your class needs the value of a specific configuration key, you can specify the path using dot notation: `config.example`

The next step is to register the class in the `ConfigProvider` under `factories` using `Dot\DependencyInjection\Factory\AttributedServiceFactory::class`.

```php
public function getDependencies(): array
{
return [
'factories' => [
GetAccountLogoutHandler::class => AttributedServiceFactory::class,
],
];
}
```

That's it.
When your object is instantiated from the container, it will automatically have its dependencies resolved.

> Dependencies injection is available to any object within Dotkernel Admin.
> For example, you can inject dependencies in a service, a handler and so on, simply by registering them in the `ConfigProvider`.
22 changes: 22 additions & 0 deletions docs/book/v7/how-to/npm_commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# NPM Commands

To install dependencies into the `node_modules` directory run this command.

```shell
npm install
```

> If `npm install` fails, this could be caused by user permissions of npm.
> The recommended way to install npm is through `Node Version Manager`.

The watch command compiles the components, then monitors the files for changes and recompiles them.

```shell
npm run watch
```

After all updates are done, this command compiles the assets locally, minifies them and makes them ready for production.

```shell
npm run prod
```
73 changes: 73 additions & 0 deletions docs/book/v7/installation/composer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Composer Installation of Packages

Composer is required to install Dotkernel Admin. You can install Composer from the [official site](https://getcomposer.org/).

> First, make sure that you have navigated your command prompt to the folder where you copied the files in the previous step.

## Install dependencies

Run this command in the command prompt.

> Use the **CLI** to ensure interactivity for proper configuration.

```shell
composer install
```

You should see this text below, along with a long list of packages to be installed instead of the `[...]`.
In this example there are 171 packages, though the number can change in future updates.
You will find the packages in the `vendor` folder.

```shell
No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
Loading composer repositories with package information
Updating dependencies
Lock file operations: 171 installs, 0 updates, 0 removals
[...]
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 171 installs, 0 updates, 0 removals
[...]
```

The setup script prompts for some configuration settings, for example, the lines below:

```text
Please select which config file you wish to inject 'Laminas\Validator\ConfigProvider' into:
[0] Do not inject
[1] config/config.php
Make your selection (default is 1):
```

Type `0` to select `[0] Do not inject`.

> We choose `0` because Dotkernel includes its own ConfigProvider, which already contains the prompted configurations.
> If you choose `[1] config/config.php`, an extra `ConfigProvider` will be injected.

The next question is:

```text
Remember this option for other packages of the same type? (y/N)
```

Type `y` here, and hit `enter` to complete this stage.

## Development mode

If you're installing the project for development, make sure you have development mode enabled by running:

```shell
composer development-enable
```

You can disable the development mode by running:

```shell
composer development-disable
```

You can check if you have development mode enabled by running:

```shell
composer development-status
```
Loading