Skip to content

Commit e1a0b56

Browse files
committed
Added v4 docs.
Made v4 the default version in the docs. Signed-off-by: alexmerlin <[email protected]>
1 parent ced9967 commit e1a0b56

File tree

8 files changed

+366
-8
lines changed

8 files changed

+366
-8
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# dot-controller
22

3-
This is DotKernel's controller package that can be use like middleware inside DotKernel or Mezzio application.
3+
This is Dotkernel's controller package that can be use like middleware inside Dotkernel or Mezzio application.
44
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
55

66
![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-controller)
@@ -30,14 +30,14 @@ Middleware controllers act as a handler for multiple routes. Some conventions we
3030
- 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`.
3131
- 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.
3232

33-
In order to create your action based controllers, you must extend the abstract class `DotKernel\DotController\AbstractActionController`
33+
In order to create your action based controllers, you must extend the abstract class `Dot\Controller\AbstractActionController`.
3434

3535
### Example
3636

37-
Creating a UserController with default action and a register action. Will handle routes `/user` and `/user/register`
37+
Creating a UserController with default action and a register action. Will handle routes `/user` and `/user/register`.
3838

3939
```php
40-
use DotKernel\DotController\AbstractActionController;
40+
use Dot\Controller\AbstractActionController;
4141

4242
class UserController extends AbstractActionController
4343
{
@@ -56,7 +56,7 @@ class UserController extends AbstractActionController
5656
Then register this controller as a routed middleware in file `RoutesDelegator.php` just like a regular middleware.
5757

5858
```php
59-
//Example from a DotKernel RoutesDelegator
59+
//Example from a RoutesDelegator
6060
$app->route(
6161
'/user[/{action}]',
6262
UserController::class,
@@ -72,5 +72,5 @@ Use case: You have defined a controller inside some package, with default action
7272
- create your own controller, independent of the package's controller which adds more actions
7373
- Mezzio lets you define an array of middleware for a route, so you can register this controller before the package's controller
7474

75-
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.
75+
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.
7676
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)

docs/book/v4/configuration.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Configuration
2+
3+
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`):
4+
5+
\Dot\Controller\ConfigProvider::class

docs/book/v4/events.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Events
2+
3+
DotKernel's controller package supports events and those events can be of 2 types: global events (middleware-like) or manually dispatch events.
4+
5+
## Getting started
6+
7+
- Every event listener that is triggered from a controller
8+
needs to implement `Dot\Controller\Event\ControllerEventListenerInterface` which actually extends `Laminas\EventManager\ListenerAggregateInterface`.
9+
- You can add the trait `Dot\Controller\Event\ControllerEventListenerTrait` to override the method of the interface.
10+
- 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
11+
12+
## Usage
13+
14+
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
15+
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.
16+
17+
For our example we have a UserController with some methods in it
18+
19+
```php
20+
use DotKernel\DotController\AbstractActionController;
21+
22+
class UserController extends AbstractActionController
23+
{
24+
public function indexAction()
25+
{
26+
//...
27+
}
28+
29+
public function registerAction()
30+
{
31+
//...
32+
}
33+
34+
// post method for updating the user
35+
public function updateAction()
36+
{
37+
38+
}
39+
}
40+
```
41+
42+
### Example 1 - Global way
43+
44+
First we will create the event listener
45+
46+
```php
47+
use Dot\Controller\Event\ControllerEvent;
48+
use Dot\Controller\Event\ControllerEventListenerInterface;
49+
use Dot\Controller\Event\ControllerEventListenerTrait;
50+
51+
// for the logger we assume you will use your own logger and inject it
52+
53+
class UserUpdatedListener implements ControllerEventListenerInterface
54+
{
55+
use ControllerEventListenerTrait;
56+
57+
public function onBeforeDispatch(ControllerEvent $event): void
58+
{
59+
$this->logger->info('on before dispatch');
60+
}
61+
62+
public function onAfterDispatch(ControllerEvent $event): void
63+
{
64+
$this->logger->info('on after dispatch');
65+
}
66+
67+
}
68+
```
69+
70+
We register the event listener in the configuration key
71+
72+
```php
73+
'dot_controller' => [
74+
'event_listeners' => [
75+
AccountController::class => [
76+
UserUpdatedListener::class,
77+
]
78+
]
79+
]
80+
```
81+
82+
As you can assume, `onBeforeDispatch` is triggered right before the controller is dispatched, and `onAfterDispatch` right
83+
after the controller is dispatched.
84+
85+
With this it doesn't matter what action is accessed, the event it will run before and after the action.
86+
87+
In addition, you can make use of the `event` variable to access information about the event.
88+
89+
For example:
90+
91+
```php
92+
// UserUpdatedListener
93+
public function onAfterDispatch(ControllerEvent $e): void
94+
{
95+
$method = $e->getTarget()->getRequest()->getMethod();
96+
$action = $e->getParams()['method'];
97+
if ($method == 'POST' && $action == 'updateAction') {
98+
$this->logger->info('this will trigger ');
99+
100+
}
101+
}
102+
```
103+
104+
So every time the `updateAction` is accessed and the method is post,
105+
right after the action is dispatched, we can log that the user was updated.
106+
107+
We can use the `onBeforeDispatch` in the same way, to log right before the user is updated.
108+
109+
### Example 2 - Manually triggered way
110+
111+
```php
112+
use Dot\Controller\Event\ControllerEvent;
113+
use Dot\Controller\Event\ControllerEventListenerInterface;
114+
use Dot\Controller\Event\ControllerEventListenerTrait;
115+
116+
// for the logger we assume you will use your own logger and inject it
117+
118+
class UserUpdatedListener implements ControllerEventListenerInterface
119+
{
120+
use ControllerEventListenerTrait;
121+
122+
public function attach(EventManagerInterface $events, $priority = 1): void
123+
{
124+
$this->listeners[] = $events->attach(
125+
'user.profile.update',
126+
[$this, 'userProfileUpdated'],
127+
$priority
128+
);
129+
}
130+
131+
public function userProfileUpdated(ControllerEvent $event): void
132+
{
133+
$this->logger->info('User profile updated');
134+
}
135+
136+
}
137+
```
138+
139+
The `attach` method is from the `ListenerAggregateInterface` which `ControllerEventListenerTrait`
140+
already is overriding it so can be used in a global way with `onBeforeDispatch` and `onAfterDispatch`
141+
methods, but we can make our custom event and bind it to our method.
142+
143+
In this case we create attach an event called `user.profile.update` and bind it to the `userProfileUpdated` method.
144+
145+
Next we need to register the event
146+
147+
```php
148+
'dot_controller' => [
149+
'event_listeners' => [
150+
AccountController::class => [
151+
'user.profile.update' => UserUpdatedListener::class
152+
]
153+
]
154+
]
155+
```
156+
157+
Now you can manually trigger the event from the controller using build in `dispatchEvent` method.
158+
159+
```php
160+
// UserController
161+
// post method for updating the user
162+
public function updateAction()
163+
{
164+
// logic
165+
$this->dispatchEvent('user.profile.update', ['user' => $user]);
166+
167+
}
168+
```
169+
170+
As you can see we attach the `user` key to the parameters, so we can actually access it.
171+
172+
```php
173+
public function userProfileUpdated(ControllerEvent $event): void
174+
{
175+
$user = $event->getParams()['user'];
176+
$this->logger->info('User profile updated', $user->toArray());
177+
}
178+
```

docs/book/v4/installation.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Installation
2+
3+
Install `dot-controller` by executing the following Composer command:
4+
5+
composer require dotkernel/dot-controller

docs/book/v4/overview.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Overview
2+
3+
`dot-controller` is DotKernel's controller package that can be use like middleware inside DotKernel or Mezzio application.
4+
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

docs/book/v4/plugins.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Plugins
2+
3+
DotKernel's controller support plugins, much like controllers in a Laminas Applications.
4+
The package comes packed with a few built in plugins, but you can extend controller functionality with your own plugins.
5+
6+
## Usage
7+
8+
Any controller plugins must implement `Dot\Controller\Plugin\PluginInterface`.
9+
You need to create a factory in addition to the plugin and register it
10+
under the `['dot_controller']['plugin_manager']['factories']` with the plugin name.
11+
12+
Once registered, a plugin can be directly accessed in any controller,
13+
by calling a method with the plugin's name (the service name or the key at which the plugin is registered inside the manager)
14+
15+
Controller plugins offer the advantage of globally accessible functionality
16+
in any controller without to manually inject dependencies.
17+
Plugins should be used for functions that are common to any controller.
18+
Do not clutter controller's code with unnecessary plugins.
19+
20+
### Example
21+
22+
First we create our desired plugin, for our example a string helper
23+
24+
```php
25+
class StringPlugin implements PluginInterface
26+
{
27+
28+
// any method inside the plugin needs to be public if you want to access it from a controller
29+
public function toUpper(string $string): string
30+
{
31+
return strtoupper($string);
32+
}
33+
}
34+
```
35+
36+
We create a factory for the plugin
37+
38+
```php
39+
use Psr\Container\ContainerInterface;
40+
41+
class StringPluginFactory
42+
{
43+
44+
public function __invoke(ContainerInterface $container): StringPlugin
45+
{
46+
return new StringPlugin();
47+
}
48+
49+
}
50+
```
51+
52+
Register the factory under the `['dot_controller']['plugin_manager']['factories']` key.
53+
54+
```php
55+
'dot_controller' => [
56+
'plugin_manager' => [
57+
'factories' => [
58+
'string' => StringPluginFactory::class
59+
]
60+
]
61+
]
62+
```
63+
64+
You don't need to register the plugin factory to a regular dependencies in a configuration
65+
because `AbstractPluginManager` actually extends `ServiceManager`
66+
67+
Access it in a controller.
68+
69+
```php
70+
//inside a controller
71+
$this->string(); // will return the StringPlugin class, so you can call any public method from it
72+
$this->string()->toUpper("test") // will return TEST
73+
```
74+
75+
## Build-in plugins
76+
77+
The package comes in with 2 default plugins ``template`` and `url`. You can use
78+
them in the same way as our example above.
79+
80+
- `url` - the plugin is an instance of `Mezzio\Helper\UrlHelper`
81+
82+
```php
83+
//in a controller action
84+
/** @var UrlHelper $url */
85+
$url = $this->url();
86+
echo $url->generate('account', ['action' => 'foo', 'hash' => 'bar'])
87+
```
88+
89+
- `template` - the plugin is an instance of `Mezzio\Template\TemplateRendererInterface`
90+
91+
```php
92+
// in a controller action
93+
return new HtmlResponse(
94+
$this->template->render('page::home', [
95+
'foo' => 'bar'
96+
])
97+
);
98+
```

docs/book/v4/usage.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Usage
2+
3+
Middleware controllers act as a handler for multiple routes. Some conventions were made:
4+
5+
- 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}]`)
6+
- 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`.
7+
- 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.
8+
9+
In order to create your action based controllers, you must extend the abstract class `DotKernel\DotController\AbstractActionController`
10+
11+
## Example
12+
13+
Creating a UserController with default action and a register action. Will handle routes `/user` and `/user/register`
14+
15+
```php
16+
use DotKernel\DotController\AbstractActionController;
17+
18+
class UserController extends AbstractActionController
19+
{
20+
public function indexAction()
21+
{
22+
//...
23+
}
24+
25+
public function registerAction()
26+
{
27+
//...
28+
}
29+
}
30+
```
31+
32+
Then register this controller as a routed middleware in file `RoutesDelegator.php` just like a regular middleware.
33+
34+
```php
35+
//Example from a DotKernel RoutesDelegator
36+
$app->route(
37+
'/user[/{action}]',
38+
UserController::class,
39+
[RequestMethodInterface::METHOD_GET, RequestMethodInterface::METHOD_POST],
40+
'user'
41+
);
42+
```
43+
44+
### Multiple controllers for the same route
45+
46+
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
47+
48+
- create your own controller, independent of the package's controller which adds more actions
49+
- Mezzio lets you define an array of middleware for a route, so you can register this controller before the package's controller
50+
51+
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.
52+
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)
53+
54+
## Plugins
55+
56+
- [Plugins](plugins.md)
57+
58+
## Events
59+
60+
- [Events](events.md)

0 commit comments

Comments
 (0)