Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: byjg
4 changes: 2 additions & 2 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ jobs:
strategy:
matrix:
php-version:
- "8.3"
- "8.2"
- "8.1"
- "8.0"
- "7.4"

# Service containers to run
services:
Expand All @@ -37,6 +36,7 @@ jobs:
- uses: actions/checkout@v4
- run: composer install
- run: ./vendor/bin/phpunit --stderr
- run: ./vendor/bin/psalm

Documentation:
if: github.ref == 'refs/heads/master'
Expand Down
6 changes: 6 additions & 0 deletions .run/PHPUnit.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="PHPUnit" type="PHPUnitRunConfigurationType" factoryName="PHPUnit">
<TestRunner bootstrap_file="$PROJECT_DIR$/phpunit.xml.dist" configuration_file="$PROJECT_DIR$/phpunit.xml.dist" directory="$PROJECT_DIR$" scope="XML" options="--stderr" use_alternative_configuration_file="true" />
<method v="2" />
</configuration>
</component>
5 changes: 5 additions & 0 deletions .run/PSalm.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="PSalm" type="PhpLocalRunConfigurationType" factoryName="PHP Console" path="$PROJECT_DIR$/vendor/bin/psalm">
<method v="2" />
</configuration>
</component>
15 changes: 11 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@
"ByJG\\Cache\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"require": {
"php": ">=7.4",
"psr/cache": "^1.0|^2.0",
"php": ">=8.1 <8.4",
"psr/cache": "^1.0|^2.0|^3.0",
"psr/log": "^1.0|^1.1|^2.0",
"psr/simple-cache": "^1.0|^2.0",
"psr/container": "^1.0|^1.1|^2.0"
},
"require-dev": {
"phpunit/phpunit": "5.7.*|7.4.*|^9.5"
"phpunit/phpunit": "^9.6",
"vimeo/psalm": "^5.9"
},
"suggest": {
"ext-memcached": "*",
"ext-redis": "*"
"ext-redis": "*",
"ext-shmop": "*"
},
"provide": {
"psr/cache-implementation": "1.0",
Expand Down
18 changes: 18 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<psalm
errorLevel="4"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
<directory name="tests" />
<ignoreFiles>
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>
2 changes: 1 addition & 1 deletion src/CacheAvailabilityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ interface CacheAvailabilityInterface
* Return if this CacheEngine is available for use
* @return bool
*/
public function isAvailable();
public function isAvailable(): bool;
}
4 changes: 2 additions & 2 deletions src/CacheLockInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ interface CacheLockInterface
* Lock resource before set it.
* @param string $key
*/
public function lock($key);
public function lock(string $key): void;

/**
* Unlock resource
* @param string $key
*/
public function unlock($key);
public function unlock(string $key): void;
}
17 changes: 9 additions & 8 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,58 @@
use ByJG\Cache\Psr16\SessionCacheEngine;
use ByJG\Cache\Psr16\ShmopCacheEngine;
use ByJG\Cache\Psr6\CachePool;
use Psr\Log\LoggerInterface;

class Factory
{
public static function createNullPool()
public static function createNullPool(): CachePool
{
return new CachePool(
new NoCacheEngine()
);
}

public static function createSessionPool($prefix = null, $bufferSize = null)
public static function createSessionPool(string $prefix = 'cache', int $bufferSize = 10): CachePool
{
return new CachePool(
new SessionCacheEngine($prefix),
$bufferSize
);
}

public static function createFilePool($prefix = null, $path = null, $bufferSize = null, $logger = null)
public static function createFilePool(string $prefix = 'cache', ?string $path = null, int $bufferSize = 10, ?LoggerInterface $logger = null, bool $createPath = false): CachePool
{
return new CachePool(
new FileSystemCacheEngine($prefix, $path, $logger),
new FileSystemCacheEngine($prefix, $path, $logger, $createPath),
$bufferSize
);
}

public static function createShmopPool($config = [], $bufferSize = null, $logger = null)
public static function createShmopPool(array $config = [], int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
{
return new CachePool(
new ShmopCacheEngine($config, $logger),
$bufferSize
);
}

public static function createArrayPool($bufferSize = null, $logger = null)
public static function createArrayPool(int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
{
return new CachePool(
new ArrayCacheEngine($logger),
$bufferSize
);
}

public static function createMemcachedPool($servers = null, $bufferSize = null, $logger = null)
public static function createMemcachedPool(?array $servers = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
{
return new CachePool(
new MemcachedEngine($servers, $logger),
$bufferSize
);
}

public static function createRedisCacheEngine($servers = null, $password = null, $bufferSize = null, $logger = null)
public static function createRedisCacheEngine(?string $servers = null, ?string $password = null, int $bufferSize = 10, ?LoggerInterface $logger = null): CachePool
{
return new CachePool(
new RedisCacheEngine($servers, $password, $logger),
Expand Down
32 changes: 20 additions & 12 deletions src/Psr16/ArrayCacheEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

namespace ByJG\Cache\Psr16;

use ByJG\Cache\Exception\InvalidArgumentException;
use DateInterval;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

class ArrayCacheEngine extends BaseCacheEngine
{

protected $cache = array();
protected array $cache = [];

protected $logger = null;
protected LoggerInterface|null $logger = null;

public function __construct($logger = null)
public function __construct(LoggerInterface|null $logger = null)
{
$this->logger = $logger;
if (is_null($logger)) {
Expand All @@ -29,10 +33,11 @@ public function __construct($logger = null)
*
* @param string $key The cache item key.
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
* MUST be thrown if the $key string is not a legal value.
* @throws InvalidArgumentException
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
*/
public function has($key)
public function has(string $key): bool
{
$key = $this->getKeyFromContainer($key);
if (isset($this->cache[$key])) {
Expand All @@ -51,9 +56,11 @@ public function has($key)
* @param string $key The object KEY
* @param mixed $default IGNORED IN MEMCACHED.
* @return mixed Description
* @throws \Psr\SimpleCache\InvalidArgumentException
* @throws ContainerExceptionInterface
* @throws InvalidArgumentException
* @throws NotFoundExceptionInterface
*/
public function get($key, $default = null)
public function get(string $key, mixed $default = null): mixed
{
if ($this->has($key)) {
$key = $this->getKeyFromContainer($key);
Expand All @@ -78,7 +85,7 @@ public function get($key, $default = null)
*
* MUST be thrown if the $key string is not a legal value.
*/
public function set($key, $value, $ttl = null)
public function set(string $key, mixed $value, DateInterval|int|null $ttl = null): bool
{
$key = $this->getKeyFromContainer($key);

Expand All @@ -92,9 +99,10 @@ public function set($key, $value, $ttl = null)
return true;
}

public function clear()
public function clear(): bool
{
$this->cache = [];
return true;
}

/**
Expand All @@ -103,7 +111,7 @@ public function clear()
* @param string $key
* @return bool
*/
public function delete($key)
public function delete(string $key): bool
{
$key = $this->getKeyFromContainer($key);

Expand All @@ -112,7 +120,7 @@ public function delete($key)
return true;
}

public function isAvailable()
public function isAvailable(): bool
{
return true;
}
Expand Down
49 changes: 29 additions & 20 deletions src/Psr16/BaseCacheEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,27 @@
use ByJG\Cache\Exception\InvalidArgumentException;
use DateInterval;
use DateTime;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\SimpleCache\CacheInterface;

abstract class BaseCacheEngine implements CacheInterface, CacheAvailabilityInterface
{
protected ?ContainerInterface $container;

/**
* @param $keys
* @param null $default
* @return array|iterable
* @param string|iterable $keys
* @param mixed $default
* @return iterable<string, mixed>
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function getMultiple($keys, $default = null)
public function getMultiple(string|iterable $keys, mixed $default = null): iterable
{
if (!is_array($keys)) {
throw new InvalidArgumentException('getMultipleKeys expected an array');
if (is_string($keys)) {
$keys = [$keys];
}

$result = [];
foreach ($keys as $key) {
$result[$key] = $this->get($key, $default);
Expand All @@ -33,32 +36,34 @@ public function getMultiple($keys, $default = null)

/**
* @param iterable $values
* @param null $ttl
* @return bool|void
* @param DateInterval|int|null $ttl
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function setMultiple($values, $ttl = null)
public function setMultiple(iterable $values, DateInterval|int|null $ttl = null): bool
{
foreach ($values as $key => $value) {
$this->set($key, $value, $ttl);
}
return true;
}

/**
* @param iterable $keys
* @return bool|void
* @return bool
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function deleteMultiple($keys)
public function deleteMultiple(iterable $keys): bool
{
foreach ($keys as $key) {
$this->delete($key);
}
return true;
}

abstract public function isAvailable();
abstract public function isAvailable(): bool;

protected function addToNow($ttl)
protected function addToNow(DateInterval|int|null $ttl): int|null
{
if (is_numeric($ttl)) {
return strtotime("+$ttl second");
Expand All @@ -73,21 +78,25 @@ protected function addToNow($ttl)
return null;
}

protected function convertToSeconds($ttl)
/**
* @throws InvalidArgumentException
*/
protected function convertToSeconds(DateInterval|int|null $ttl): DateInterval|int|null
{
if (empty($ttl) || is_numeric($ttl)) {
return $ttl;
}

if ($ttl instanceof DateInterval) {
return $ttl->days*86400 + $ttl->h*3600 + $ttl->i*60 + $ttl->s;
}

throw new InvalidArgumentException('Invalid TTL');
return $ttl->days*86400 + $ttl->h*3600 + $ttl->i*60 + $ttl->s;
}


protected function getKeyFromContainer($key)
/**
* @throws ContainerExceptionInterface
* @throws InvalidArgumentException
* @throws NotFoundExceptionInterface
*/
protected function getKeyFromContainer(string $key): mixed
{
if (empty($this->container)) {
return $key;
Expand Down
Loading