Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
odan committed Aug 6, 2020
2 parents 6d8f433 + 1aac6ba commit 9503547
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 218 deletions.
167 changes: 0 additions & 167 deletions docs/v5/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ description: "Version 5"
* [PHP Session](#php-session)
* [Memory Session](#memory-session)
* [Slim 4 integration](#slim-4-integration)
* [Slim Flash integration](#slim-flash-integration)

## Requirements

Expand Down Expand Up @@ -252,8 +251,6 @@ return [
'session' => [
'name' => 'webapp',
'cache_expire' => 0,
'cookie_httponly' => true,
'cookie_secure' => true,
],
];
```
Expand Down Expand Up @@ -318,170 +315,6 @@ $app->post('/example', \App\Action\ExampleAction::class)
->add(SessionMiddleware::class);
```

## Slim Flash integration

Although this component already comes with its own Flash message implementation,
you can still integrate other flash components.

The [slim/flash](https://github.com/slimphp/Slim-Flash) may be useful integration package to
add flash massages to your application.

```
composer require slim/flash
```

Add the container definition:

```php

use Slim\Flash\Messages;

return [
// ...
Messages::class => function () {
// Don't use $_SESSION here, because the session is not started at this moment.
// The middleware changes the storage.
$storage = [];

return new Messages($storage);
},
];
```

Add a custom Middleware to pass the session storage, e.g. in `src/Middleware/SlimFlashMiddleware.php`:

```php
<?php

namespace App\Middleware;

use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Flash\Messages;

final class SlimFlashMiddleware implements MiddlewareInterface
{
/**
* @var SessionInterface
*/
private $session;

/**
* @var Messages
*/
private $flash;

public function __construct(SessionInterface $session, Messages $flash)
{
$this->session = $session;
$this->flash = $flash;
}

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$storage = $this->session->getStorage();

// Set flash message storage
$this->flash->__construct($storage);

return $handler->handle($request);
}
}
```

The session must be started first. To prevent an error like
`Fatal error: Uncaught RuntimeException: Flash messages middleware failed. Session not found.`
add the `SessionFlashMiddleware` **before** the `SessionMiddleware`.

```php
<?php

use App\Middleware\SessionFlashMiddleware;
use Odan\Session\Middleware\SessionMiddleware;

// ...

$app->add(SessionFlashMiddleware::class); // <--- here
$app->add(SessionMiddleware::class);
```

Action usage:

```php
<?php

namespace App\Action\Auth;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Flash\Messages;

final class FooAction
{
/**
* @var Messages
*/
private $flash;

public function __construct(Messages $flash)
{
$this->flash = $flash;
}

public function __invoke(
ServerRequestInterface $request,
ResponseInterface $response
): ResponseInterface {
// Add flash message for the next request
$this->flash->addMessage('Test', 'This is a message');


// or add flash message for current request
$this->flash->addMessageNow('Test', 'This is a message');

// Render response
// ...

return $response;
}
}

```

### Using Slim Flash with Twig-View

If you use [Twig-View](https://github.com/slimphp/Twig-View),
then [slim-twig-flash](https://github.com/kanellov/slim-twig-flash) may be a useful integration package.

You could also just add the Slim flash instance as global twig variable:

```php
use Slim\Flash\Messages;
// ...

$twig = Twig::create($settings, $options);
// ...

$flash = $container->get(Messages::class);
$twig->getEnvironment()->addGlobal('flash', $flash);
```

In your Twig templates you can use `flash.getMessages()` or `flash.getMessage('some_key')`
to fetch messages from the Flash service.

{% raw %}
```twig
{% for message in flash.getMessage('error') %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% endfor %}
```
{% endraw %}

## Similar packages

* <https://github.com/laminas/laminas-session>
Expand Down
2 changes: 2 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
<rule ref="Squiz.Commenting.FunctionComment.Missing">
<type>warning</type>
</rule>
<!--
<rule ref="Squiz.Commenting.FunctionComment.MissingParamTag">
<type>warning</type>
</rule>
-->
<rule ref="Squiz.Commenting.FunctionComment.MissingParamComment">
<type>warning</type>
</rule>
Expand Down
8 changes: 4 additions & 4 deletions src/Flash.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Odan\Session;

use ArrayAccess;
use ArrayObject;

/**
* Flash messages.
Expand All @@ -12,7 +12,7 @@ final class Flash implements FlashInterface
/**
* Message storage.
*
* @var ArrayAccess
* @var ArrayObject
*/
private $storage;

Expand All @@ -26,10 +26,10 @@ final class Flash implements FlashInterface
/**
* The constructor.
*
* @param ArrayAccess $storage The storage
* @param ArrayObject $storage The storage
* @param string $storageKey The flash storage key
*/
public function __construct(ArrayAccess $storage, string $storageKey = '_flash')
public function __construct(ArrayObject $storage, string $storageKey = '_flash')
{
$this->storage = $storage;
$this->storageKey = $storageKey;
Expand Down
10 changes: 0 additions & 10 deletions src/PhpSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,6 @@ public function __construct(ArrayObject $storage = null, FlashInterface $flash =
$this->flash = $flash ?? new Flash($this->storage);
}

/**
* Get storage.
*
* @return ArrayObject The storage
*/
public function getStorage(): ArrayObject
{
return $this->storage;
}

/**
* Get flash instance.
*
Expand Down
18 changes: 5 additions & 13 deletions src/SessionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Odan\Session;

use ArrayObject;
use Odan\Session\Exception\SessionException;

/**
Expand All @@ -15,13 +14,6 @@ interface SessionInterface
*/
public function start(): void;

/**
* Get storage.
*
* @return ArrayObject The storage
*/
public function getStorage(): ArrayObject;

/**
* Get flash handler.
*
Expand Down Expand Up @@ -184,11 +176,11 @@ public function getOptions(): array;
*
* @see http://php.net/manual/en/function.session-set-cookie-params.php
*
* @param int $lifetime the lifetime of the cookie in seconds
* @param string|null $path the path where information is stored
* @param string|null $domain the domain of the cookie
* @param bool $secure the cookie should only be sent over secure connections
* @param bool $httpOnly the cookie can only be accessed through the HTTP protocol
* @param int $lifetime The lifetime of the cookie in seconds
* @param string|null $path The path where information is stored
* @param string|null $domain The domain of the cookie
* @param bool $secure The cookie should only be sent over secure connections
* @param bool $httpOnly The cookie can only be accessed through the HTTP protocol
*/
public function setCookieParams(
int $lifetime,
Expand Down
44 changes: 20 additions & 24 deletions tests/PhpSessionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@ protected function setUp(): void

$this->session = new PhpSession();

$this->session->setOptions([
'name' => 'app',
// turn off automatic sending of cache headers entirely
'cache_limiter' => '',
// garbage collection
'gc_probability' => 1,
'gc_divisor' => 1,
'gc_maxlifetime' => 30 * 24 * 60 * 60,
'save_path' => getenv('GITHUB_ACTIONS') ? '/tmp' : '',
]);
$this->session->setOptions(
[
'name' => 'app',
// turn off automatic sending of cache headers entirely
'cache_limiter' => '',
// garbage collection
'gc_probability' => 1,
'gc_divisor' => 1,
'gc_maxlifetime' => 30 * 24 * 60 * 60,
'save_path' => getenv('GITHUB_ACTIONS') ? '/tmp' : '',
]
);

$lifetime = strtotime('20 minutes') - time();
$this->session->setCookieParams($lifetime, '/', '', false, false);
Expand Down Expand Up @@ -68,21 +70,13 @@ public function testStart(): void
$this->session->destroy();
}

/**
* Test.
*/
public function testGetStorage(): void
{
$this->session->set('key', 'value');
$storage = $this->session->getStorage();
$this->assertSame(['key' => 'value'], (array)$storage);
}

/**
* Test.
*/
public function testGetFlash(): void
{
$this->session->set('key', 'value1');

$flash = $this->session->getFlash();
$flash->add('key', 'value');
$this->assertSame([0 => 'value'], $flash->get('key'));
Expand Down Expand Up @@ -253,10 +247,12 @@ public function testRemoveAndClear(): void
$this->session->set('key2', 'value');
$this->assertSame(2, $this->session->count());

$this->session->replace([
'key' => 'value-new',
'key2' => 'value2-new',
]);
$this->session->replace(
[
'key' => 'value-new',
'key2' => 'value2-new',
]
);
$this->assertSame('value-new', $this->session->get('key'));
$this->assertSame('value2-new', $this->session->get('key2'));

Expand Down

0 comments on commit 9503547

Please sign in to comment.