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
2 changes: 2 additions & 0 deletions docs/book/v5/core-features/content-validation.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Content Negotiation

> Introduced in Dotkernel API 5.0.0

**Content Negotiation** is performed by an application in order :

- To match the requested representation as specified by the client via the Accept header with a representation the
Expand Down
34 changes: 15 additions & 19 deletions docs/book/v5/core-features/dependency-injection.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
# 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.
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.
In PHP, dependency injection can be implemented in various ways, including through constructor injection, setter injection and property injection.

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

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

## Usage

**Dotkernel API** comes out of the box with the
[dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, which provides all we need for
injecting dependencies into any object you want.
**Dotkernel API** comes out of the box with the [dot-dependency-injection](https://github.com/dotkernel/dot-dependency-injection) package, which provides all we need 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. Dependencies are specified as separate parameters of the `#[Inject]` attribute.
`dot-dependency-injection` determines the dependencies by looking at the `#[Inject]` attribute, added to the constructor of a class.
Dependencies are specified as separate parameters of the `#[Inject]` attribute.

For our example we will inject `UserService` and `config` dependencies into a `UseHandler`.

Expand All @@ -37,11 +35,9 @@ class UserHandler implements RequestHandlerInterface
}
```

> If your class needs the value of a specific configuration key, you can specify the path using dot notation:
> `config.example`
> 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`
The next step is to register the class in the `ConfigProvider` under `factories` using `Dot\DependencyInjection\Factory\AttributedServiceFactory::class`

```php
public function getDependencies(): array
Expand All @@ -54,8 +50,8 @@ public function getDependencies(): array
}
```

That's it. When your object is instantiated from the container, it will automatically have its
dependencies resolved.
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 API. For example, you can inject dependencies in a
> service, a handler and so on, simply by registering it in the `ConfigProvider`.
> Dependencies injection is available to any object within Dotkernel API.
> For example, you can inject dependencies in a service, a handler and so on, simply by registering it in the `ConfigProvider`.
62 changes: 26 additions & 36 deletions docs/book/v5/core-features/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,50 @@

## What are exceptions?

Exceptions are a powerful mechanism for handling errors and other exceptional conditions that may occur during the
execution of a script.
They provide a way to manage errors in a structured and controlled manner, separating error-handling code from regular
code.
Exceptions are a powerful mechanism for handling errors and other exceptional conditions that may occur during the execution of a script.
They provide a way to manage errors in a structured and controlled manner, separating error-handling code from regular code.

## How we use exceptions?
## How we use exceptions

When it comes to handling exceptions, **Dotkernel API** relies on the usage of easy-to-understand, problem-specific
exceptions.

Out-of-the-box we provide the following custom exceptions:
When it comes to handling exceptions, **Dotkernel API** relies on the usage of easy-to-understand, problem-specific exceptions.
Below we will list the available custom exceptions.

### `BadRequestException` thrown when

* client tries to create/update resource, but the data from the request is invalid/incomplete (example: client tries to
create an account, but does not send the required `identity` field)
* The Client tries to **create/update resource**, but the **request data is invalid/incomplete** (example: client tries to create an account, but does not send the required `identity` field)

### `ConflictException` thrown when

* resource cannot be created because a different resource with the same identifier already exists (example: cannot
change existing user's identity because another user with the same identity already exists)
* resource cannot change its state because it is already in the specified state (example: user cannot be activated
because it is already active)
* The **resource cannot be created** because a different resource with the same identifier **already exists** (example: cannot change existing user's identity because another user with the same identity already exists)
* The **resource cannot change its state** because it is **already in the specified state** (example: user cannot be activated because it is already active)

### `ExpiredException` thrown when

* resource cannot be accessed because it expired (example: account activation link)
* resource cannot be accessed because it has been consumed (example: one-time password)
* The **resource cannot be accessed**
* because it has **expired** (example: account activation link)
* because it has been **consumed** (example: one-time password)

### `ForbiddenException` thrown when

* resource cannot be accessed by the authenticated client (example: client authenticated as regular user sends
a `GET /admin` request)
* The **resource cannot be accessed** by the authenticated client's **role** (example: client authenticated as regular user sends a `GET /admin` request)

### `MethodNotAllowedException` thrown when

* client tries to interact with a resource via an invalid HTTP request method (example: client sends a `PATCH /avatar`
request)
* The client tries to interact with a resource via an **invalid HTTP request method** (example: client sends a `PATCH /avatar` request)

### `NotFoundException` thrown when

* client tries to interact with a resource that does not exist on the server (example: client sends
a `GET /resource-does-not-exist` request)
* The client tries to interact with a **resource that does not exist** on the server (example: client sends a `GET /resource-does-not-exist` request)

### `UnauthorizedException` thrown when

* resource cannot be accessed because the client is not authenticated (example: unauthenticated client sends
a `GET /admin` request)
* The **resource cannot be accessed** because the **client is not authenticated** (example: unauthenticated client sends a `GET /admin` request)

## How it works?
## How it works

During a request, if there is no uncaught exception **Dotkernel API** will return a JSON response with the data provided
by the handler that handled the request.
During a request, if there is no uncaught exception, **Dotkernel API** will return a JSON response with the data provided by the handler that processed the request.

Else, it will build and send a response based on the exception thrown:
Otherwise, it will build and send a response based on the exception thrown:

* `BadRequestException` will return a `400 Bad Request` response
* `UnauthorizedException` will return a `401 Unauthorized` response
Expand All @@ -67,11 +56,13 @@ Else, it will build and send a response based on the exception thrown:
* `ExpiredException` will return a `410 Gone` response
* `MailException`, `RuntimeException` and the generic `Exception` will return a `500 Internal Server Error` response

## How to extend?
## How to extend

In this example we will

In this example we will create a custom exception called `CustomException`, place it next to the already existing custom
exceptions (you can use your preferred location) and finally return a custom HTTP status code when `CustomException` is
encountered.
* Create a custom exception called `CustomException`
* Place it next to the already existing custom exceptions (you can use your preferred location)
* Return a custom HTTP status code when `CustomException` is encountered.

### Step 1: Create exception file

Expand Down Expand Up @@ -106,8 +97,7 @@ Save and close the file.

### Step 3: Test for failure

Access your API's home page URL and make sure it returns `500 Internal Server Error` HTTP status code and the following
content:
Access your API's home page URL and make sure it returns `500 Internal Server Error` HTTP status code and the following content:

```json
{
Expand All @@ -133,5 +123,5 @@ Save and close the file.

### Step 5: Test for success

Again, access your API's home page URL, which should return the same content.
Access your API's home page URL, which should return the same content.
Notice that this time it returns `418 I'm a teapot` HTTP status code.
91 changes: 74 additions & 17 deletions docs/book/v5/introduction/file-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,38 +24,95 @@ When using Dotkernel API the following structure is installed by default:
* `.github` - containes workflow files
* `.laminas-ci` - contains laminas-ci workflow files

### `bin` directory

This directory contents are

* `clear-config-cache.php` which removes the config cache file (`data/cache/config-cache.php` - available only when development mode is enabled).
* `cli.php` used to build console applications based on [laminas-cli](https://github.com/laminas/laminas-cli)
* `doctrine` used by the doctrine fixtures to populate the database tables

### `config` directory

This directory contains all application-related config files:

* `cli-config.php`: command line interface configuration used by migrations, fixtures, crons
* `config.php`: registers ConfigProviders for installing packages
* `container.php`: main service container that provides access to all registered services
* `development.config.php.dist`: activates debug mode; gets symlinked as `development.config.php` when enabling development mode
* `migrations.php`: configuration for database migration, like migration file location and table to save the migration log
* `pipeline.php`: contains a list of middlewares, in the order of their execution
* `twig-cs-fixer.php`: configuration file for Twig code style checker/fixer

#### `config/autoload` directory

This directory contains all service-related local and global config files:

* `authorization.global.php`: configures access per route for user roles
* `cli.global.php`: configures cli
* `content-negotiation.global.php`: configures request and response formats
* `cors.local.php.dist`: configures Cross-Origin Resource Sharing, like call origin, headers, cookies
* `dependencies.global.php`: config file to set global dependencies that should be accessible by all modules
* `development.local.php.dist`: gets symlinked as `development.local.php` when enabling development mode - activates error handlers
* `doctrine.global.php`: configuration used by Object–relational mapping
* `error-handling.global.php`: configures and activates error logs
* `local.php.dist`: local config file where you can overwrite application name and URL
* `local.test.php.dist`: local configuration for functional tests
* `mail.local.php.dist`: mail configuration; e.g. sendmail vs smtp, message configuration, mail logging
* `mezzio.global.php`: Mezzio core config file
* `mezzio-tooling-factories.global.php`: add or remove factory definitions
* `response-header.global.php`: defines headers per route
* `templates.global.php`: dotkernel/dot-twigrenderer config file

### `data` directory

This directory is a storage for project data files and service caches.
It contains these folders:

* `cache`: cache for e.g. Twig files
* `doctrine`: database migrations and fixtures
* `oauth`: encryption, private and public keys needed for authentication
* `data/lock` - lock files generated by [`dotkernel/dot-cli`](https://docs.dotkernel.org/dot-cli/v3/lock-files/)

> AVOID storing sensitive data on VCS.

### `log` directory

This directory stores daily log files.
When you access the application from the browser, (if not already created) a new log file gets created in the format specified in the `config/autoload/error-handling.global.php` config file under the `stream` array key.

### `public` directory

This directory contains all publicly available assets and serves as the entry point of the application:

* `uploads`: a folder that normally contains files uploaded via the application
* `.htaccess`: server configuration file used by Apache web server; it enables the URL rewrite functionality
* `index.php`: the application's main entry point
* `robots.txt.dist`: a sample robots.txt file that allows/denies bot access to certain areas of your application; activate it by duplicating the file as `robots.txt` and comment out the lines that don't match your environment

## `src` directory

This directory contains all source code related to the Module. It should contain following directories, if they’re not empty:
This folder contains a separate folder for each Module.
Each Module folder, in turn, should contain following directories, unless they are empty:

* Handler - Action classes (similar to Controllers but can only perform one action)
* Entity - For database entities
* Entity - Used by database entities
* Service - Service classes
* Collection - Database entities collections
* Repository - Entity repository folder

> The above example is just some of the directories a project may include, but these should give you an idea of how the structure should look like.
> The above example is just some of the directories a project may include, but they should give you an idea about the recommended structure.

Other classes in the `src` directory may include `InputFilter`, `EventListener`, `Helper`, `Command`, `Factory` etc.

The `src` directory should also contain 2 files:
The `src` directory normally also contains these files:

* `ConfigProvider.php` - Provides configuration data
* `RoutesDelegator.php` - Module main routes entry file
* `ConfigProvider.php` - Configuration data for the module
* `OpenAPI.php` - Detailed descriptions for each endpoint in the OpenAPI format
* `RoutesDelegator.php` - Module specific route registrations Module main routes entry file

## `templates` directory

This directory contains the template files, used for example to help render e-mail templates.

> Dotkernel API uses twig as Templating Engine. All template files have the extension .html.twig

## `data` directory

This directory contains project-related data (such as cache, file uploads)

We recommend using the following directory structure:

* `data/cache` - location where caches are stored
* `data/oauth` - encryption, private and public keys needed for authentication.
* `data/doctrine` - fixtures and migrations
* `data/lock` - lock files generated by `dotkernel/dot-cli` [See more](https://docs.dotkernel.org/dot-cli/v3/lock-files/)
38 changes: 38 additions & 0 deletions docs/book/v5/introduction/psr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# PSRs

Some of the PSRs on this list are at the core of Dotkernel API, but several others are installed with the 3rd party packages used in the application.
Below is the full list of PSRs present in Dotkernel API and their purpose.

* PSR-3: [Logger Interface](https://www.php-fig.org/psr/psr-3/)
* Interface for logging libraries
* Interfaces implemented in [php-fig/log](https://github.com/php-fig/log)
* PSR-4: [Autoloader](https://www.php-fig.org/psr/psr-4/)
* Autoloading classes from file paths
* Interfaces implemented in [laminas/laminas-loader](https://github.com/laminas/laminas-loader)
* PSR-6: [Caching Interface](https://www.php-fig.org/psr/psr-6/)
* Interface for caching systems to improve the performance of any project
* Interfaces implemented in [php-fig/cache](https://github.com/php-fig/cache)
* PSR-7: [HTTP message interfaces](https://www.php-fig.org/psr/psr-7/)
* Interfaces for representing HTTP messages and URIs for use with HTTP messages
* Interfaces implemented in [php-fig/http-message](https://github.com/php-fig/http-message)
* PSR-11: [Container interface](https://www.php-fig.org/psr/psr-11/)
* Interface for dependency injection containers
* Interfaces implemented in [php-fig/container](https://github.com/php-fig/container)
* PSR-13: [Link definition interfaces](https://www.php-fig.org/psr/psr-13/)
* Way of representing a hypermedia link independently of the serialization format
* Interfaces implemented in [php-fig/link](https://github.com/php-fig/link)
* PSR-14: [Event Dispatcher](https://www.php-fig.org/psr/psr-14/)
* Mechanism for event-based extension and collaboration
* Interfaces implemented in [php-fig/event-dispatcher](https://github.com/php-fig/event-dispatcher)
* PSR-15: [HTTP Server Request Handlers](https://www.php-fig.org/psr/psr-15/)
* Interfaces for HTTP server request handlers and HTTP server middleware components that use HTTP messages
* Interfaces implemented in [php-fig/http-server-handler](https://github.com/php-fig/http-server-handler) and [php-fig/http-server-middleware](https://github.com/php-fig/http-server-middleware)
* PSR-17: [HTTP Factories](https://www.php-fig.org/psr/psr-17/)
* Standard for factories that create PSR-7 compliant HTTP objects
* Interfaces implemented in [php-fig/http-factory](https://github.com/php-fig/http-factory)
* PSR-18: [HTTP Client](https://www.php-fig.org/psr/psr-18/)
* Interface for sending HTTP requests and receiving HTTP responses
* Interfaces implemented in [php-fig/http-client](https://github.com/php-fig/http-client)
* PSR-20: [Clock](https://www.php-fig.org/psr/psr-20/)
* Interface for reading the system clock
* Interfaces implemented in [php-fig/clock](https://github.com/php-fig/clock)
Loading