Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for v4.0.0 including migration guide #274

Merged
merged 19 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
20e925c
docs: move v3 documentation to v4 directory
boesing Aug 26, 2023
57d3c9c
docs: add `v4` to `mkdocs` config
boesing Aug 26, 2023
6d9c5d2
docs: initial migration guide
boesing Aug 26, 2023
292b805
docs: apply metadata modifications to documentation
boesing Aug 26, 2023
d1024b5
docs: remove increment/decrement functionality
boesing May 8, 2024
6ad5691
docs: adapt native type-hints
boesing May 8, 2024
835bc24
qa: add missing type-hints and/or remove superfluous docblocks
boesing May 8, 2024
371ceb6
qa: enhance docblocks and add missing native type-hints
boesing May 8, 2024
a45b464
docs: normalize table structures
boesing May 8, 2024
fd9d28e
docs: add BC break regarding serializer plugin option to migration guide
boesing May 8, 2024
8a357dd
docs: add native types to BC breaking changes
boesing May 8, 2024
66e6951
docs: add increment/decrement feature removal to BC breaking changes …
boesing May 8, 2024
a7c8ea0
docs: rephrase the benchmarks text as benchmarks are only available i…
boesing May 8, 2024
3ae3cd0
docs: add checklist and removed classes to migration guide
boesing May 8, 2024
a02564e
docs: add migration intro
boesing May 8, 2024
e8489c1
docs: mention rector for automatic type declarations
boesing May 8, 2024
8203f1a
docs: add `psr/cache` and `psr/simple-cache` v2 & v3 in migration gui…
boesing May 8, 2024
1fbe772
docs: add `ObjectCache` inheritance change to the migration guide (bo…
boesing May 8, 2024
f173c27
qa: remove `decorate` phrase as the `ObjectCache` does not really dec…
boesing May 8, 2024
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: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ $storage->setItem('foo', 'bar');

We provide scripts for benchmarking laminas-cache using the
[PHPBench](https://github.com/phpbench/phpbench) framework; these can be
found in the `benchmark/` directory.
found in the `benchmark/` directory of each storage adapter.

To execute the benchmarks you can run the following command:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Usage in a laminas-mvc Application

The following example shows _one_ potential use case of laminas-cache within a laminas-mvc based application.
The example uses a module, a controller and shows the resolving of dependencies of the controller by configuration.

## Preparation

Before starting, make sure laminas-cache is [installed and configured](../installation.md).

> MISSING: **Installation Requirements**
> laminas-cache is shipped without a specific cache adapter to allow free choice of storage backends and their dependencies.
> So make sure that the required adapters are installed.
>
> The following example used the [filesystem adapter of laminas-cache](../storage/adapter.md#filesystem-adapter):
>
> ```bash
> $ composer require laminas/laminas-cache-storage-adapter-filesystem
> ```

## Configure Cache

To configure the cache in a laminas-mvc based application, use either application or module configuration (such as `config/autoload/*.global.php` or `module/Application/config/module.config.php`, respectively), and define the configuration key `caches`.

In this example, the global configuration is used and a separate file is created for the cache configuration.
Create a configuration file with name like `config/autoload/cache.global.php` and it will [automatically be included](https://docs.laminas.dev/tutorials/advanced-config/#environment-specific-application-configuration):

```php
return [
'caches' => [
'default-cache' => [
'adapter' => Laminas\Cache\Storage\Adapter\Filesystem::class,
'options' => [
'cache_dir' => __DIR__ . '/../../data/cache',
],
],
],
];
```

The factory `Laminas\Cache\Service\StorageCacheAbstractServiceFactory` uses the configuration, searches for the configuration key `caches` and creates the storage adapters using the discovered configuration.

## Create Controller

[Create a controller class](https://docs.laminas.dev/laminas-mvc/quick-start/#create-a-controller) and inject the cache with the interface for all cache storage adapters via the constructor, e.g. `module/Application/Controller/IndexController.php`:

```php
namespace Application\Controller;

use Laminas\Cache\Storage\StorageInterface;
use Laminas\Mvc\Controller\AbstractActionController;

final class IndexController extends AbstractActionController
{
public function __construct(
private readonly StorageInterface $cache
) {}

public function indexAction(): array
{
if (! $this->cache->hasItem('example')) {
$this->cache->addItem('example', 'value');
}

echo $this->cache->getItem('example') // value;

// …

return [];
}
}
```

## Register Controller

To [register the controller](https://docs.laminas.dev/laminas-mvc/quick-start/#create-a-route) for the application, extend the configuration of the module.
Add the following lines to the module configuration file, e.g. `module/Application/config/module.config.php`:

<pre class="language-php" data-line="3,8"><code>
namespace Application;

use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;

return [
'controllers' => [
'factories' => [
Controller\IndexController::class => ConfigAbstractFactory::class,
],
],
// …
];
</code></pre>

The example uses the [config factory from laminas-servicemanager](https://docs.laminas.dev/laminas-servicemanager/config-abstract-factory/) which allows any string to be used to fetch a service from the application service container, like the name of the configured cache: `default-cache`.

This means that the factory [searches for an appropriate configuration](https://docs.laminas.dev/laminas-servicemanager/config-abstract-factory/#configuration) to create the controller and to resolve the constructor dependencies for the controller class.

### Add Factory Configuration For Controller

Extend the module configuration file to add the configuration for the controller.
Use the name of the cache (`default-cache`), which was previously defined in the configuration of the caches, to retrieve the related cache storage instance:

<pre class="language-php" data-line="11-15"><code>
namespace Application;

use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;

return [
'controllers' => [
'factories' => [
Controller\IndexController::class => ConfigAbstractFactory::class,
],
],
ConfigAbstractFactory::class => [
Controller\IndexController::class => [
'default-cache',
],
],
// …
];
</code></pre>

## Using Multiple Caches

The use more than one cache backend, the factory `Laminas\Cache\Service\StorageCacheAbstractServiceFactory` allows to define multiple cache storages.

Extend the cache configuration in `config/autoload/cache.global.php` and add more cache adapters:

<pre class="language-php" data-line="9-14"><code>
return [
'caches' => [
'default-cache' => [
'adapter' => Laminas\Cache\Storage\Adapter\Filesystem::class,
'options' => [
'cache_dir' => __DIR__ . '/../../data/cache',
],
],
'secondary-cache' => [
'adapter' => Laminas\Cache\Storage\Adapter\Memory::class,
],
'dummy-cache' => [
'adapter' => Laminas\Cache\Storage\Adapter\BlackHole::class,
],
],
];
</code></pre>

MISSING: **Installation Requirements**
Make sure that the [used storage adapters are installed](#preparation):
```bash
$ composer require laminas/laminas-cache-storage-adapter-memory laminas/laminas-cache-storage-adapter-blackhole
```

### Change Used Adapter for Controller

To use a different cache adapter for the controller, change the related module configuration and use one of the previously defined names:

<pre class="language-php" data-line="13"><code>
namespace Application;

use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;

return [
'controllers' => [
'factories' => [
Controller\IndexController::class => ConfigAbstractFactory::class,
],
],
ConfigAbstractFactory::class => [
Controller\IndexController::class => [
'dummy-cache',
],
],
// …
];
</code></pre>

## Learn More

- [Storage Adapters](../storage/adapter.md)
- [Environment-Specific Application Configuration](https://docs.laminas.dev/tutorials/advanced-config/#environment-specific-application-configuration)
- [Configuration-based Abstract Factory](https://docs.laminas.dev/laminas-servicemanager/config-abstract-factory/)
5 changes: 5 additions & 0 deletions docs/book/v4/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This Is Only a Placeholder

The content of this page can be found under:

https://github.com/laminas/documentation-theme/blob/master/theme/pages/installation.html
45 changes: 45 additions & 0 deletions docs/book/v4/migration/to-version-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Migration to Version 4.0

Finally, native types **everywhere**. With v4.0, `laminas-cache` depends on `laminas-servicemanager` v4 which already introduced full native types and thus, cache now has native types as well.
Along with these changes, we also decided to remove and/or enhance some features to make the usage of this component more user-friendly.
So instead of working with metadata arrays, a new `MetadataCapableInterface` was introduced which provides a generic interface for storage adapters to tell both IDEs and static analysers to understand what metadata instances are returned for which storage adapter.
This allows per-storage Metadata which can differ depending on the storage being used.

## Checklist

1. Ensure you are on latest `laminas/laminas-cache` v3
2. Ensure you are on latest `laminas/laminas-cache-storage-adapter-*` version (might differ)
3. Verify that you are **not** using one of the following methods
1. `StorageInterface#incrementItem` (no replacement available, should be implemented in userland code)
2. `StorageInterface#incrementItems` (no replacement available, should be implemented in userland code)
3. `StorageInterface#decrementItem` (no replacement available, should be implemented in userland code)
4. `StorageInterface#decrementItems` (no replacement available, should be implemented in userland code)
4. Verify that you are **not** using `supportedMetadata` capability (use `MetadataCapableInterface#getMetadata` instead)
5. Verify that you are **not** using `KeyListIterator` with mode `CURRENT_AS_METADATA` (use the returned `key` instead and pass it to the `MetadataCapable` storage adapter (**NOTE: not all adapters do implement `MetadataCapableInterface`**)
6. If you use the `Serializer` plugin
1. Verify that if you pass a `string` as `serializer` option, you do not directly depend on the return value of `PluginOptions#getSerializer` (method will return `string` instead of instantiating a new `SerializerInterface` instance). The plugin itself can still handle `string` and an instance of `SerializerInterface` as in previous versions
7. If you provide own plugins, storage adapters, pattern, you have to upgrade to v4 and update all method/argument/property (return-) types according to the updated versions. Check out [rector](https://github.com/rectorphp/rector) which can help with this kind of migration
8. If you are handling `Laminas\Cache\Exception\MissingKeyException`, you can remove that code as the exception does not exist anymore
9. Check if you use `ObjectCache` pattern, that your code does not expect an instance of `CallbackCache` to be passed

## New Features

- Every adapter which supports `metadata` now implements `MetadataCapableInterface` and provides a dedicated object containing all the metadata values it supports
- Adds support for `psr/cache` and `psr/simple-cache` v2 & v3

## Removed Classes

- `Laminas\Cache\Exception\MissingKeyException`

## Breaking Changes

- `AbstractAdapter` and `StorageInterface` are not aware of the methods `getMetadata` anymore. These were moved to the new `MetadataCapableInterface`
- `Capabilities` do not provide `supportedMetadata` anymore. The supported metadata is tied to the used storage adapter and thus, was already requiring projects to explicitly know the exact implementation of the cache backend in case of using these metadatas anyway
- `KeyListIterator` and the corresponding `IteratorInterface` does not provide the `mode` `CURRENT_AS_METADATA` anymore
- `PluginOptions#getSerializer` does not create a serializer anymore if a `string` option was passed, instead, the `string` is returned
- Increment and decrement feature was removed from `StorageInterface`, so there is no more `StorageInterface#incrementItem`, `StorageInterface#decrementItem`, `StorageInterface#decrementItems` and `StorageInterface#incrementItems`
- this also removes `incrementItem`, `incrementItems`, `decrementItem`, `derementItems` events (`pre`, `post` and `exception`)
- Every method now has native return types
- Every property now has native types
- Every method argument now has native types
- `ObjectCache` does not inherit the `CallbackCache` pattern anymore
87 changes: 87 additions & 0 deletions docs/book/v4/pattern/callback-cache.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# CallbackCache

The callback cache pattern caches the results of arbitrary PHP callables.

## Quick Start

```php
use Laminas\Cache\Pattern\CallbackCache;
use Laminas\Cache\Pattern\PatternOptions;

// Or the equivalent manual instantiation:
$callbackCache = new CallbackCache(
$storage,
new PatternOptions([
'cache_output' => true,
])
);
```

> ### Storage Adapter
>
> The `$storage` adapter can be any adapter which implements the `StorageInterface`. Check out the [Pattern Quick Start](./intro.md#quick-start)-Section for a standard adapter which can be used here.

## Configuration Options

| Option | Data Type | Default Value | Description |
|----------------|---------------------------------------------------------|---------------|------------------------------------------------------------------|
| `storage` | `string\|array\|Laminas\Cache\Storage\StorageInterface` | none | **deprecated** Adapter used for reading and writing cached data. |
| `cache_output` | `bool` | `true` | Whether or not to cache callback output. |

## Examples

### Instantiating the Callback Cache Pattern

```php
use Laminas\Cache\Pattern\CallbackCache;

$callbackCache = new CallbackCache($storage);
```

## Available Methods

In addition to the methods defined in the `PatternInterface` and the `StorageCapableInterface`, this
implementation provides the following methods.

```php
namespace Laminas\Cache\Pattern;

use Laminas\Cache\Exception;

class CallbackCache extends AbstractStorageCapablePattern
{
/**
* Call the specified callback or get the result from cache
*
* @param callable $callback A valid callback
* @param array $args Callback arguments
* @return mixed Result
* @throws Exception\RuntimeException if invalid cached data
* @throws \Exception
*/
public function call(callable $callback, array $args = []): mixed;

/**
* Intercept method overloading; proxies to call()
*
* @param callable-string $function Function name to call
* @param array $args Function arguments
* @return mixed
* @throws Exception\RuntimeException
* @throws \Exception
*/
public function __call(string $function, array $args): mixed;

/**
* Generate a unique key in base of a key representing the callback part
* and a key representing the arguments part.
*
* @param callable $callback A valid callback
* @param array $args Callback arguments
* @return non-empty-string
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
*/
public function generateKey(callable $callback, array $args = []): string;
}
```
Loading