Skip to content

Commit

Permalink
Add cache function
Browse files Browse the repository at this point in the history
  • Loading branch information
xepozz committed Jul 29, 2023
1 parent 7596cdc commit 9fe44bd
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 10 deletions.
21 changes: 20 additions & 1 deletion README.md
Expand Up @@ -146,7 +146,7 @@ validate(

See more about validator rules in [yiisoft/validator](https://github.com/yiisoft/validator)

### `log_message(string $level, string|stringable $message, array $context = []): void
### `log_message(string $level, string|stringable $message, array $context = []): void`

- `$level` is a log level. Available levels: `emergency`, `alert`, `critical`, `error`, `warning`, `notice`, `info`, `debug`.
- You can use `\Psr\Log\LogLevel` constants:
Expand Down Expand Up @@ -185,6 +185,25 @@ log_alert('Alert message');
log_emergency('Emergency message');
```

### `cache(string|int|Stringable|array $key, mixed $value = null, int|DateInterval|null $ttl = null): mixed`

- `$key` is a cache key
- `$value` is a cache value
- `$ttl` is a cache TTL

```php
cache('key', 'value'); // returns "value" and sets cache with key "key" if it does not exist

cache('key', 'value', 3600); // sets cache with key "key" and value "value" for 1 hour
cache('key', 'value', new DateInterval('PT1H')); // also TTL can be an instance of DateInterval

cache('key', fn () => 'value'); // $value can be a closure. It will be executed only if cache with key "key" does not exist

cache(new StringableClass('key'), fn () => 'value'); // $key can be an instance of Stringable
cache(12345, fn () => 'value'); // $key can be an integer
cache(['key' => 'value', '!@#$%^&*()_+`' => '_)(*&^%$#@!~`'], fn () => 'value'); // $key can be an array. It will be serialized to a JSON and the following characters will be replaced to "_": {}()/\@:
```

## Looking for more modules?

- [Unique ID](https://github.com/xepozz/unique-id) - Allows you to track the unique user in the application.
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Expand Up @@ -40,7 +40,9 @@
"yiisoft/translator": "^3.0",
"yiisoft/user": "^2.0",
"yiisoft/access": "^1.1",
"yiisoft/validator": "^1.1"
"yiisoft/validator": "^1.1",
"yiisoft/cache": "^3.0",
"psr/simple-cache": "^3.0"
},
"provide": {
"psr/event-dispatcher-implementation": "1.0.0",
Expand Down
31 changes: 31 additions & 0 deletions src/cache.php
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

use Psr\SimpleCache\CacheInterface;
use Psr\SimpleCache\InvalidArgumentException;

/**
* @throws InvalidArgumentException
*/
function cache(
string|int|Stringable|array $key,
mixed $value = null,
int|DateInterval|null $ttl = null,
): mixed {
/**
* @var CacheInterface $cache

Check failure on line 17 in src/cache.php

View workflow job for this annotation

GitHub Actions / PHP 8.1-ubuntu-latest

UnnecessaryVarAnnotation

src/cache.php:17:13: UnnecessaryVarAnnotation: The @var Psr\SimpleCache\CacheInterface annotation for $cache is unnecessary (see https://psalm.dev/212)

Check failure on line 17 in src/cache.php

View workflow job for this annotation

GitHub Actions / PHP 8.2-ubuntu-latest

UnnecessaryVarAnnotation

src/cache.php:17:13: UnnecessaryVarAnnotation: The @var Psr\SimpleCache\CacheInterface annotation for $cache is unnecessary (see https://psalm.dev/212)
*/
$cache = container(CacheInterface::class);

$key = is_array($key) ? strtr(json_encode($key), '{}()/\@:', '________') : (string) $key;

if ($cache->has($key)) {
return $cache->get($key);
}

$value = is_callable($value) ? $value() : $value;
$cache->set($key, $value, $ttl);

return $value;
}
60 changes: 60 additions & 0 deletions tests/CacheTest.php
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace Xepozz\Shortcut\Tests;

use DateInterval;
use Psr\SimpleCache\CacheInterface;
use Xepozz\Shortcut\State;
use Xepozz\Shortcut\Tests\Support\StringableClass;
use Yiisoft\Cache\NullCache;
use Yiisoft\Test\Support\Container\SimpleContainer;

final class CacheTest extends FunctionsTestCase
{
public function testFunctionExist()
{
$this->assertTrue(function_exists('cache'));
}

public function testCache(): void
{
$this->initEnvironment();

$result = cache('key', 'value');
$this->assertEquals('value', $result);


$result = cache('key', 'value', 3600);
$this->assertEquals('value', $result);

$result = cache('key', 'value', new DateInterval('PT1H'));
$this->assertEquals('value', $result);

$result = cache('key', fn () => 'value');
$this->assertEquals('value', $result);

$result = cache(new StringableClass('key'), fn () => 'value');
$this->assertEquals('value', $result);

$result = cache(12345, fn () => 'value');
$this->assertEquals('value', $result);

$result = cache(['key' => 'value', '!@#$%^&*()_+`' => '_)(*&^%$#@!~`'], fn () => 'value');
$this->assertEquals('value', $result);
}

public function bootstrapFiles(): iterable
{
yield __DIR__ . '/../src/container.php';
yield __DIR__ . '/../src/cache.php';
}

protected function initEnvironment(): void
{
State::$container = new SimpleContainer([
CacheInterface::class => new NullCache(),
]);
}
}
16 changes: 8 additions & 8 deletions tests/LoggerTest.php
Expand Up @@ -47,28 +47,28 @@ public function testLogFunctions(string $function, string|Stringable $message, a
public static function dataLogFunctions(): iterable
{
yield 'log_error' => ['log_error', 'message', []];
yield 'log_error' => ['log_error', new StringableClass('message'), ['key' => 'value']];
yield 'log_error stringable' => ['log_error', new StringableClass('message'), ['key' => 'value']];

yield 'log_info' => ['log_info', 'message', []];
yield 'log_info' => ['log_info', new StringableClass('message'), ['key' => 'value']];
yield 'log_info stringable' => ['log_info', new StringableClass('message'), ['key' => 'value']];

yield 'log_warning' => ['log_warning', 'message', []];
yield 'log_warning' => ['log_warning', new StringableClass('message'), ['key' => 'value']];
yield 'log_warning stringable' => ['log_warning', new StringableClass('message'), ['key' => 'value']];

yield 'log_debug' => ['log_debug', 'message', []];
yield 'log_debug' => ['log_debug', new StringableClass('message'), ['key' => 'value']];
yield 'log_debug stringable' => ['log_debug', new StringableClass('message'), ['key' => 'value']];

yield 'log_notice' => ['log_notice', 'message', []];
yield 'log_notice' => ['log_notice', new StringableClass('message'), ['key' => 'value']];
yield 'log_notice stringable' => ['log_notice', new StringableClass('message'), ['key' => 'value']];

yield 'log_alert' => ['log_alert', 'message', []];
yield 'log_alert' => ['log_alert', new StringableClass('message'), ['key' => 'value']];
yield 'log_alert stringable' => ['log_alert', new StringableClass('message'), ['key' => 'value']];

yield 'log_critical' => ['log_critical', 'message', []];
yield 'log_critical' => ['log_critical', new StringableClass('message'), ['key' => 'value']];
yield 'log_critical stringable' => ['log_critical', new StringableClass('message'), ['key' => 'value']];

yield 'log_emergency' => ['log_emergency', 'message', []];
yield 'log_emergency' => ['log_emergency', new StringableClass('message'), ['key' => 'value']];
yield 'log_emergency stringable' => ['log_emergency', new StringableClass('message'), ['key' => 'value']];
}

public function bootstrapFiles(): iterable
Expand Down

0 comments on commit 9fe44bd

Please sign in to comment.