From c2a0d900a8373115da351de8cbb8b929bb946d13 Mon Sep 17 00:00:00 2001 From: alexmerlin Date: Fri, 31 Oct 2025 18:50:59 +0200 Subject: [PATCH] Issue #49: Remove PHP 8.1 and add PHP 8.4 & 8.5 support Signed-off-by: alexmerlin --- .github/workflows/codecov.yml | 2 +- .github/workflows/static-analysis.yml | 2 +- README.md | 31 +++++++++++-------- SECURITY.md | 8 ++--- composer.json | 6 ++-- docs/book/v3/configuration.md | 2 +- docs/book/v3/events.md | 24 ++++++++------ docs/book/v3/overview.md | 18 +++++++++-- docs/book/v3/plugins.md | 16 +++++----- docs/book/v3/usage.md | 26 ++++++++++------ docs/book/v4/configuration.md | 2 +- docs/book/v4/events.md | 24 ++++++++------ docs/book/v4/overview.md | 6 ++-- docs/book/v4/plugins.md | 16 +++++----- docs/book/v4/usage.md | 26 ++++++++++------ ...ontrollerEventListenersInitializerTest.php | 1 + 16 files changed, 124 insertions(+), 86 deletions(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 0e0f02c..89e83df 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -15,10 +15,10 @@ jobs: - ubuntu-latest php: - - "8.1" - "8.2" - "8.3" - "8.4" + - "8.5" steps: - name: Checkout diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 03d62cb..9976515 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -15,10 +15,10 @@ jobs: - ubuntu-latest php: - - "8.1" - "8.2" - "8.3" - "8.4" + - "8.5" steps: - name: Checkout diff --git a/README.md b/README.md index e708948..53dc995 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # dot-controller -This is Dotkernel's controller package that can be use like middleware inside Dotkernel or Mezzio application. -It provides base classes for action based controllers similar to Laminas controller component. -It is more lightweight though, but supports controller plugins and event listeners. +This is Dotkernel's controller package that can be used like middleware inside Dotkernel or Mezzio application. +It provides base classes for action-based controllers similar to a Laminas controller component. +It is more lightweight, though, but supports controller plugins and event listeners. ## Documentation @@ -11,7 +11,7 @@ Documentation is available at: https://docs.dotkernel.org/dot-controller/. ## Badges ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-controller) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.1.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.2.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/network) @@ -32,17 +32,22 @@ composer require dotkernel/dot-controller ## Usage -Middleware controllers act as a handler for multiple routes. Some conventions were made: +Middleware controllers act as a handler for multiple routes. +Some conventions were made: -- register controllers in the routes array just like any mezzio middleware. The requirement is that you should define an `action` route parameter(possibly optional) anywhere inside the route(e.g `/user[/{action}]`) -- action parameter value is converted to a method name inside the controller. Underscore, dot and line characters are removed and the action name is converted to camel-case suffixed by the string `Action`. For example a route and action pair like `/user/forgot-password` will be converted to method `forgotPasswordAction`. +- register controllers in the `routes` array just like any Mezzio middleware. + The requirement is that you should define an `action` route parameter (possibly optional) anywhere inside the route (e.g `/user[/{action}]`). +- action parameter value is converted to a method name inside the controller. + Underscore, dot and line characters are removed and the action name is converted to a camel-case suffixed by the string `Action`. + For example, a route and action pair like `/user/forgot-password` will be converted to method `forgotPasswordAction`. - the default action value, if not present in the URI is `index`, so you should always define an `indexAction` within your controllers for displaying a default page or redirecting. -In order to create your action based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`. +To create your action-based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`. ### Example -Creating a UserController with default action and a register action. Will handle routes `/user` and `/user/register`. +Creating a UserController with a default action and a register action. +Will handle routes `/user` and `/user/register`. ```php use Dot\Controller\AbstractActionController; @@ -61,7 +66,7 @@ class UserController extends AbstractActionController } ``` -Then register this controller as a routed middleware in file `RoutesDelegator.php` just like a regular middleware. +Then register this controller as routed middleware in file `RoutesDelegator.php` just like regular middleware. ```php //Example from a RoutesDelegator @@ -77,13 +82,13 @@ $app->route( **Use case:** You have defined a controller inside some package, with default actions. -You want to add actions that fall into the same controller name(or route name more exactly). +You want to add actions that fall into the same controller name (or route name more exactly). You want to do this without extending the controller provided by the package. In this case you can do the following: -- create your own controller, independent of the package's controller which adds more actions +- create your own controller, independent of the package's controller, which adds more actions - Mezzio lets you define an array of middleware for a route, so you can register this controller before the package's controller Now when a request for this route comes in, your controller will run first. Dotkernel controllers are designed to ignore requests that cannot be matched to one of its methods, so if no action matches, it will call the next middleware, in our case, the second controller. -If this is the last controller, and action does not match here, it will go to the default 404 Not found page(handled by NotFoundDelegate). +If this is the last controller, and the action does not match here, it will go to the default 404 Not found page (handled by NotFoundDelegate). diff --git a/SECURITY.md b/SECURITY.md index 4a0e65f..cced106 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,13 +2,12 @@ ## Supported Versions - | Version | Supported | PHP Version | |---------|--------------------|----------------------------------------------------------------------------------------------------------------| -| 3.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/3.4.3) | +| 4.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.2.0) | +| 3.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/3.6.0) | | <= 2.x | :x: | | - ## Reporting Potential Security Issues If you have encountered a potential security vulnerability in this project, @@ -24,10 +23,9 @@ When reporting issues, please provide the following information: We request that you contact us via the email address above and give the project contributors a chance to resolve the vulnerability and issue a new release prior to any public exposure; this helps protect the project's -users, and provides them with a chance to upgrade and/or update in order to +users and provides them with a chance to upgrade and/or update to protect their applications. - ## Policy If we verify a reported security vulnerability, our policy is: diff --git a/composer.json b/composer.json index 0f3796c..be6ee33 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ } ], "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "dotkernel/dot-event": "^4.0.0", "laminas/laminas-servicemanager": "^4.0", "mezzio/mezzio-helpers": "^5.8.0", @@ -50,8 +50,8 @@ ], "cs-check": "phpcs", "cs-fix": "phpcbf", - "test": "phpunit --colors=always", - "static-analysis": "phpstan analyse --memory-limit 1G" + "static-analysis": "phpstan analyse --memory-limit 1G", + "test": "phpunit --colors=always" }, "config": { "sort-packages": true, diff --git a/docs/book/v3/configuration.md b/docs/book/v3/configuration.md index e7f403a..6f5d89d 100644 --- a/docs/book/v3/configuration.md +++ b/docs/book/v3/configuration.md @@ -1,6 +1,6 @@ # Configuration -After installation, the package can be used immediately but if you want to use all features of the package, like plugins and events you need to register the `ConfigProvider` in your project by adding the below line to your configuration aggregator (usually: `config/config.php`): +After installation, the package can be used immediately but if you want to use all features of the package, like plugins and events, you need to register the `ConfigProvider` in your project by adding the below line to your configuration aggregator (usually: `config/config.php`): ```php \Dot\Controller\ConfigProvider::class, diff --git a/docs/book/v3/events.md b/docs/book/v3/events.md index 002f039..b8ea58e 100644 --- a/docs/book/v3/events.md +++ b/docs/book/v3/events.md @@ -1,17 +1,21 @@ # Events -Dotkernel's controller package supports events and those events can be of 2 types: global events (middleware-like) or manually dispatch events. +Dotkernel's controller package supports events, and those events can be of two types: global events (middleware-like) or manually dispatched events. ## Getting started -- Every event listener that is triggered from a controller needs to implement `Dot\Controller\Event\ControllerEventListenerInterface` which actually extends `Laminas\EventManager\ListenerAggregateInterface`. +- Every event listener triggered from a controller needs to implement `Dot\Controller\Event\ControllerEventListenerInterface` which actually extends `Laminas\EventManager\ListenerAggregateInterface`. - You can add the trait `Dot\Controller\Event\ControllerEventListenerTrait` to override the method of the interface. - Every event listener needs to be registered under the `['dot_controller']['event_listenenrs]` key in the ConfigProvider, and every key must be the class that you want to attach the events. ## Usage -The events in a controller can be done in 2 different ways, a global way where an event is attached automatically to all the controllers action and works in the same way the middlewares works or a manually dispatchable way, where you can define to which controller the events is attached, and you can trigger the event where you want. -For our example we have a UserController with some methods in it: +The events in a controller can be done in two different ways: + +- a global way where an event is attached automatically to all the controller actions and works in the same way the middlewares works +- in a manually dispatchable way, where you can define to which controller the events are attached, and you can trigger the event where you want + +For our example, we have a UserController with some methods in it: ```php use Dotkernel\DotController\AbstractActionController; @@ -36,9 +40,9 @@ class UserController extends AbstractActionController } ``` -### Example 1 - Global way +### Global method -First we will create the event listener: +First, we will create the event listener: ```php use Dot\Controller\Event\ControllerEvent; @@ -98,7 +102,7 @@ public function onAfterDispatch(ControllerEvent $e): void So every time the `updateAction` is accessed and the method is post, right after the action is dispatched, we can log that the user was updated. We can use the `onBeforeDispatch` in the same way, to log right before the user is updated. -### Example 2 - Manually triggered way +### Manual method ```php use Dot\Controller\Event\ControllerEvent; @@ -128,7 +132,7 @@ class UserUpdatedListener implements ControllerEventListenerInterface } ``` -The `attach` method is from the `ListenerAggregateInterface` which `ControllerEventListenerTrait` already is overriding it so can be used in a global way with `onBeforeDispatch` and `onAfterDispatch` methods, but we can make our custom event and bind it to our method. +The `attach` method is from the `ListenerAggregateInterface` which `ControllerEventListenerTrait` already is overriding it so can be used globally with `onBeforeDispatch` and `onAfterDispatch` methods, but we can make our custom event and bind it to our method. In this case we create attach an event called `user.profile.update` and bind it to the `userProfileUpdated` method. Next, we need to register the event: @@ -137,7 +141,7 @@ Next, we need to register the event: 'dot_controller' => [ 'event_listeners' => [ AccountController::class => [ - 'user.profile.update' => UserUpdatedListener::class + 'user.profile.update' => UserUpdatedListener::class, ] ] ] @@ -147,7 +151,7 @@ Now you can manually trigger the event from the controller using build in `dispa ```php // UserController -// post method for updating the user +// POST method for updating the user public function updateAction() { // logic diff --git a/docs/book/v3/overview.md b/docs/book/v3/overview.md index be4e4b6..1d41d13 100644 --- a/docs/book/v3/overview.md +++ b/docs/book/v3/overview.md @@ -1,5 +1,19 @@ # Overview `dot-controller` is Dotkernel's controller package that can be use like middleware inside Dotkernel or Mezzio application. -It provides base classes for action based controllers similar to Laminas controller component. -It is more lightweight though, but supports controller plugins and event listeners. +It provides base classes for action-based controllers similar to a Laminas controller component. +It is more lightweight, though, but supports controller plugins and event listeners. + +## Badges + +![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-controller) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/3.6.0) + +[![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/issues) +[![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/network) +[![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/stargazers) +[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/blob/3.0/LICENSE.md) + +[![Build Static](https://github.com/dotkernel/dot-controller/actions/workflows/continuous-integration.yml/badge.svg?branch=3.0)](https://github.com/dotkernel/dot-controller/actions/workflows/continuous-integration.yml) +[![codecov](https://codecov.io/gh/dotkernel/dot-controller/graph/badge.svg?token=VUBG5LM4CK)](https://codecov.io/gh/dotkernel/dot-controller) +[![PHPStan](https://github.com/dotkernel/dot-controller/actions/workflows/static-analysis.yml/badge.svg?branch=3.0)](https://github.com/dotkernel/dot-controller/actions/workflows/static-analysis.yml) diff --git a/docs/book/v3/plugins.md b/docs/book/v3/plugins.md index cb7d008..e25098a 100644 --- a/docs/book/v3/plugins.md +++ b/docs/book/v3/plugins.md @@ -1,22 +1,22 @@ # Plugins -Dotkernel's controller support plugins, much like controllers in Laminas applications. -The package comes packed with a few built in plugins, but you can extend controller functionality with your own plugins. +Dotkernel's controller supports plugins, much like controllers in Laminas applications. +The package comes packed with a few built-in plugins, but you can extend controller functionality with your own plugins. ## Usage Any controller plugins must implement `Dot\Controller\Plugin\PluginInterface`. You need to create a factory in addition to the plugin and register it under the `['dot_controller']['plugin_manager']['factories']` with the plugin name. -Once registered, a plugin can be directly accessed in any controller, by calling a method with the plugin's name (the service name or the key at which the plugin is registered inside the manager). +Once registered, a plugin can be directly accessed in any controller by calling a method with the plugin's name (the service name or the key at which the plugin is registered inside the manager). -Controller plugins offer the advantage of globally accessible functionality in any controller without to manually inject dependencies. +Controller plugins offer the advantage of globally accessible functionality in any controller without manually injecting dependencies. Plugins should be used for functions that are common to any controller. Do not clutter controller's code with unnecessary plugins. ### Example -First we create our desired plugin, for our example a string helper: +First we create our desired plugin, for our example, a string helper: ```php class StringPlugin implements PluginInterface @@ -58,7 +58,7 @@ Register the factory under the `['dot_controller']['plugin_manager']['factories' ] ``` -You don't need to register the plugin factory to a regular dependencies in a configuration because `AbstractPluginManager` actually extends `ServiceManager`. +You don't need to register the plugin factory to a regular dependency in a configuration because `AbstractPluginManager` actually extends `ServiceManager`. Access it in a controller: ```php @@ -67,9 +67,9 @@ $this->string(); // will return the StringPlugin class, so you can call any publ $this->string()->toUpper("test") // will return TEST ``` -## Build-in plugins +## Built-in plugins -The package comes in with 2 default plugins ``template`` and `url`. +The package comes in with two default plugins `template` and `url`. You can use them in the same way as our example above. - `url` - the plugin is an instance of `Mezzio\Helper\UrlHelper`: diff --git a/docs/book/v3/usage.md b/docs/book/v3/usage.md index 2094740..f4876ec 100644 --- a/docs/book/v3/usage.md +++ b/docs/book/v3/usage.md @@ -1,16 +1,20 @@ # Usage -Middleware controllers act as a handler for multiple routes. Some conventions were made: - -- register controllers in the routes array just like any mezzio middleware. The requirement is that you should define an `action` route parameter(possibly optional) anywhere inside the route(e.g `/user[/{action}]`) -- action parameter value is converted to a method name inside the controller. Underscore, dot and line characters are removed and the action name is converted to camel-case suffixed by the string `Action`. For example a route and action pair like `/user/forgot-password` will be converted to method `forgotPasswordAction`. +Middleware controllers act as a handler for multiple routes. +Some conventions were made: + +- register controllers in the `routes` array just like any Mezzio middleware. + The requirement is that you should define an `action` route parameter (possibly optional) anywhere inside the route(e.g `/user[/{action}]`). +- action parameter value is converted to a method name inside the controller. + Underscore, dot and line characters are removed and the action name is converted to a camel-case suffixed by the string `Action`. + For example, a route and action pair like `/user/forgot-password` will be converted to method `forgotPasswordAction`. - the default action value, if not present in the URI is `index`, so you should always define an `indexAction` within your controllers for displaying a default page or redirecting. -In order to create your action based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`. +To create your action-based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`. ## Example -Creating a UserController with default action and a register action. +Creating a UserController with a default action and a register action. It will handle routes `/user` and `/user/register`: ```php @@ -30,7 +34,7 @@ class UserController extends AbstractActionController } ``` -Then register this controller as a routed middleware in file `RoutesDelegator.php` just like a regular middleware: +Then register this controller as routed middleware in file `RoutesDelegator.php` just like regular middleware: ```php //Example from a Dotkernel RoutesDelegator @@ -45,14 +49,16 @@ $app->route( ### Multiple controllers for the same route **Use case:** -You have defined a controller inside some package, with default actions. You want to add actions that fall into the same controller name(or route name more exactly). You want to do this without extending the controller provided by the package. In this case you can do the following +You have defined a controller inside some package, with default actions. You want to add actions that fall into the same controller name (or route name more exactly). +You want to do this without extending the controller provided by the package. +In this case you can do the following: -- create your own controller, independent of the package's controller which adds more actions +- create your own controller, independent of the package's controller, which adds more actions - Mezzio lets you define an array of middleware for a route, so you can register this controller before the package's controller Now when a request for this route comes in, your controller will run first. Dotkernel controllers are designed to ignore requests that cannot be matched to one of its methods, so if no action matches, it will call the next middleware, in our case, the second controller. -If this is the last controller, and action does not match here, it will go to the default 404 Not found page(handled by NotFoundDelegate). +If this is the last controller, and the action does not match here, it will go to the default 404 Not found page (handled by NotFoundDelegate). ## Plugins diff --git a/docs/book/v4/configuration.md b/docs/book/v4/configuration.md index e7f403a..6f5d89d 100644 --- a/docs/book/v4/configuration.md +++ b/docs/book/v4/configuration.md @@ -1,6 +1,6 @@ # Configuration -After installation, the package can be used immediately but if you want to use all features of the package, like plugins and events you need to register the `ConfigProvider` in your project by adding the below line to your configuration aggregator (usually: `config/config.php`): +After installation, the package can be used immediately but if you want to use all features of the package, like plugins and events, you need to register the `ConfigProvider` in your project by adding the below line to your configuration aggregator (usually: `config/config.php`): ```php \Dot\Controller\ConfigProvider::class, diff --git a/docs/book/v4/events.md b/docs/book/v4/events.md index 0abfe74..4f9c72e 100644 --- a/docs/book/v4/events.md +++ b/docs/book/v4/events.md @@ -1,17 +1,21 @@ # Events -Dotkernel's controller package supports events and those events can be of 2 types: global events (middleware-like) or manually dispatch events. +Dotkernel's controller package supports events, and those events can be of two types: global events (middleware-like) or manually dispatched events. ## Getting started -- Every event listener that is triggered from a controller needs to implement `Dot\Controller\Event\ControllerEventListenerInterface` which actually extends `Laminas\EventManager\ListenerAggregateInterface`. +- Every event listener triggered from a controller needs to implement `Dot\Controller\Event\ControllerEventListenerInterface` which actually extends `Laminas\EventManager\ListenerAggregateInterface`. - You can add the trait `Dot\Controller\Event\ControllerEventListenerTrait` to override the method of the interface. - Every event listener needs to be registered under the `['dot_controller']['event_listenenrs]` key in the ConfigProvider, and every key must be the class that you want to attach the events ## Usage -The events in a controller can be done in 2 different ways, a global way where an event is attached automatically to all the controllers action and works in the same way the middlewares works or a manually dispatchable way, where you can define to which controller the events is attached, and you can trigger the event where you want. -For our example we have a UserController with some methods in it: +The events in a controller can be done in two different ways: + +- a global way where an event is attached automatically to all the controller actions and works in the same way the middlewares works +- in a manually dispatchable way, where you can define to which controller the events are attached, and you can trigger the event where you want + +For our example, we have a UserController with some methods in it: ```php use Dot\Controller\AbstractActionController; @@ -36,9 +40,9 @@ class UserController extends AbstractActionController } ``` -### Example 1 - Global way +### Global method -First we will create the event listener: +First, we will create the event listener: ```php use Dot\Controller\Event\ControllerEvent; @@ -98,7 +102,7 @@ public function onAfterDispatch(ControllerEvent $e): void So every time the `updateAction` is accessed and the method is post, right after the action is dispatched, we can log that the user was updated. We can use the `onBeforeDispatch` in the same way, to log right before the user is updated. -### Example 2 - Manually triggered way +### Manual method ```php use Dot\Controller\Event\ControllerEvent; @@ -128,7 +132,7 @@ class UserUpdatedListener implements ControllerEventListenerInterface } ``` -The `attach` method is from the `ListenerAggregateInterface` which `ControllerEventListenerTrait` already is overriding it so can be used in a global way with `onBeforeDispatch` and `onAfterDispatch` methods, but we can make our custom event and bind it to our method. +The `attach` method is from the `ListenerAggregateInterface` which `ControllerEventListenerTrait` already is overriding it so can be used globally with `onBeforeDispatch` and `onAfterDispatch` methods, but we can make our custom event and bind it to our method. In this case we create attach an event called `user.profile.update` and bind it to the `userProfileUpdated` method. Next we need to register the event: @@ -137,7 +141,7 @@ Next we need to register the event: 'dot_controller' => [ 'event_listeners' => [ AccountController::class => [ - 'user.profile.update' => UserUpdatedListener::class + 'user.profile.update' => UserUpdatedListener::class, ] ] ] @@ -147,7 +151,7 @@ Now you can manually trigger the event from the controller using build in `dispa ```php // UserController -// post method for updating the user +// POST method for updating the user public function updateAction() { // logic diff --git a/docs/book/v4/overview.md b/docs/book/v4/overview.md index f44077b..bb82c52 100644 --- a/docs/book/v4/overview.md +++ b/docs/book/v4/overview.md @@ -1,13 +1,13 @@ # Overview `dot-controller` is Dotkernel's controller package that can be use like middleware inside Dotkernel or Mezzio application. -It provides base classes for action based controllers similar to Laminas controller component. -It is more lightweight though, but supports controller plugins and event listeners. +It provides base classes for action-based controllers similar to a Laminas controller component. +It is more lightweight, though, but supports controller plugins and event listeners. ## Badges ![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-controller) -![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.1.0) +![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-controller/4.2.0) [![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/issues) [![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-controller)](https://github.com/dotkernel/dot-controller/network) diff --git a/docs/book/v4/plugins.md b/docs/book/v4/plugins.md index cb7d008..e25098a 100644 --- a/docs/book/v4/plugins.md +++ b/docs/book/v4/plugins.md @@ -1,22 +1,22 @@ # Plugins -Dotkernel's controller support plugins, much like controllers in Laminas applications. -The package comes packed with a few built in plugins, but you can extend controller functionality with your own plugins. +Dotkernel's controller supports plugins, much like controllers in Laminas applications. +The package comes packed with a few built-in plugins, but you can extend controller functionality with your own plugins. ## Usage Any controller plugins must implement `Dot\Controller\Plugin\PluginInterface`. You need to create a factory in addition to the plugin and register it under the `['dot_controller']['plugin_manager']['factories']` with the plugin name. -Once registered, a plugin can be directly accessed in any controller, by calling a method with the plugin's name (the service name or the key at which the plugin is registered inside the manager). +Once registered, a plugin can be directly accessed in any controller by calling a method with the plugin's name (the service name or the key at which the plugin is registered inside the manager). -Controller plugins offer the advantage of globally accessible functionality in any controller without to manually inject dependencies. +Controller plugins offer the advantage of globally accessible functionality in any controller without manually injecting dependencies. Plugins should be used for functions that are common to any controller. Do not clutter controller's code with unnecessary plugins. ### Example -First we create our desired plugin, for our example a string helper: +First we create our desired plugin, for our example, a string helper: ```php class StringPlugin implements PluginInterface @@ -58,7 +58,7 @@ Register the factory under the `['dot_controller']['plugin_manager']['factories' ] ``` -You don't need to register the plugin factory to a regular dependencies in a configuration because `AbstractPluginManager` actually extends `ServiceManager`. +You don't need to register the plugin factory to a regular dependency in a configuration because `AbstractPluginManager` actually extends `ServiceManager`. Access it in a controller: ```php @@ -67,9 +67,9 @@ $this->string(); // will return the StringPlugin class, so you can call any publ $this->string()->toUpper("test") // will return TEST ``` -## Build-in plugins +## Built-in plugins -The package comes in with 2 default plugins ``template`` and `url`. +The package comes in with two default plugins `template` and `url`. You can use them in the same way as our example above. - `url` - the plugin is an instance of `Mezzio\Helper\UrlHelper`: diff --git a/docs/book/v4/usage.md b/docs/book/v4/usage.md index 2094740..695b546 100644 --- a/docs/book/v4/usage.md +++ b/docs/book/v4/usage.md @@ -1,16 +1,20 @@ # Usage -Middleware controllers act as a handler for multiple routes. Some conventions were made: - -- register controllers in the routes array just like any mezzio middleware. The requirement is that you should define an `action` route parameter(possibly optional) anywhere inside the route(e.g `/user[/{action}]`) -- action parameter value is converted to a method name inside the controller. Underscore, dot and line characters are removed and the action name is converted to camel-case suffixed by the string `Action`. For example a route and action pair like `/user/forgot-password` will be converted to method `forgotPasswordAction`. +Middleware controllers act as a handler for multiple routes. +Some conventions were made: + +- register controllers in the `routes` array just like any mezzio middleware. + The requirement is that you should define an `action` route parameter (possibly optional) anywhere inside the route (e.g `/user[/{action}]`). +- action parameter value is converted to a method name inside the controller. + Underscore, dot and line characters are removed and the action name is converted to a camel-case suffixed by the string `Action`. + For example, a route and action pair like `/user/forgot-password` will be converted to method `forgotPasswordAction`. - the default action value, if not present in the URI is `index`, so you should always define an `indexAction` within your controllers for displaying a default page or redirecting. -In order to create your action based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`. +To create your action-based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`. ## Example -Creating a UserController with default action and a register action. +Creating a UserController with a default action and a register action. It will handle routes `/user` and `/user/register`: ```php @@ -30,7 +34,7 @@ class UserController extends AbstractActionController } ``` -Then register this controller as a routed middleware in file `RoutesDelegator.php` just like a regular middleware: +Then register this controller as routed middleware in file `RoutesDelegator.php` just like regular middleware: ```php //Example from a Dotkernel RoutesDelegator @@ -45,14 +49,16 @@ $app->route( ### Multiple controllers for the same route **Use case:** -You have defined a controller inside some package, with default actions. You want to add actions that fall into the same controller name(or route name more exactly). You want to do this without extending the controller provided by the package. In this case you can do the following +You have defined a controller inside some package, with default actions. You want to add actions that fall into the same controller name (or route name more exactly). +You want to do this without extending the controller provided by the package. +In this case you can do the following: -- create your own controller, independent of the package's controller which adds more actions +- create your own controller, independent of the package's controller, which adds more actions - Mezzio lets you define an array of middleware for a route, so you can register this controller before the package's controller Now when a request for this route comes in, your controller will run first. Dotkernel controllers are designed to ignore requests that cannot be matched to one of its methods, so if no action matches, it will call the next middleware, in our case, the second controller. -If this is the last controller, and action does not match here, it will go to the default 404 Not found page(handled by NotFoundDelegate). +If this is the last controller, and the action does not match here, it will go to the default 404 Not found page (handled by NotFoundDelegate). ## Plugins diff --git a/test/Factory/ControllerEventListenersInitializerTest.php b/test/Factory/ControllerEventListenersInitializerTest.php index 62c5302..358120a 100644 --- a/test/Factory/ControllerEventListenersInitializerTest.php +++ b/test/Factory/ControllerEventListenersInitializerTest.php @@ -72,6 +72,7 @@ public function testAttachControllerListeners(): void $this->eventManager->expects($this->any())->method('attach') ->with($this->isInstanceOf(ControllerEventListenerInterface::class), 1); + $this->expectNotToPerformAssertions(); $this->subject->attachControllerListeners($this->container, $this->controller); } }