Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

00f100/fcphp-cache

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

00f100/fcphp-cache - npm Package Compare versions

Comparing version
0.3.0
to
0.3.1
+5
00F100-fcphp-cache-962f614/.gitignore
vendor
tests/coverage
composer.lock
docker-compose.yml
tests/var
language: php
php:
- 7.2
before_install:
- sudo apt-get update -qq
- sudo apt-get install build-essential git -y
- git clone -b stable https://github.com/jedisct1/libsodium.git
- cd libsodium && sudo ./configure && sudo make check && sudo make install && cd ..
install:
# Manually install libsodium, because the TravicCi image doesn't provide PHP7.2 with libsodium
- pecl install libsodium
- echo "extension=sodium.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
before_script:
- echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source --dev
script:
- vendor/bin/phpunit --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
services:
- redis-server
{
"name": "00f100/fcphp-cache",
"type": "package",
"version": "0.3.1",
"description": "Cache Index for FcPhp",
"keywords": ["cache", "fcphp", "php7", "php72", "crypto", "redis"],
"homepage": "https://github.com/00f100/fcphp-cache",
"authors": [
{
"name": "João Moraes",
"email": "joaomoraesbr@gmail.com",
"homepage": "https://github.com/00f100"
}
],
"require": {
"php": ">=7.2",
"00f100/fcphp-redis": "0.4.1",
"00f100/fcphp-crypto": "0.2.0",
"ext-redis": "*"
},
"require-dev": {
"00f100/phpdbug": "*",
"phpunit/phpunit": "6.*"
},
"autoload": {
"psr-4": {
"FcPhp\\Cache\\": "src/",
"FcPhp\\Cache\\Test\\": "tests/"
}
}
}
MIT License
Copyright (c) 2018 João Moraes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="testSuite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src/</directory>
</whitelist>
<blacklist>
<directory suffix=".php">./vendor/</directory>
<exclude>
<directory suffix=".php">./vendor/</directory>
</exclude>
</blacklist>
</filter>
<logging>
<log type="coverage-html" target="tests/coverage" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70" />
</logging>
</phpunit>
# FcPhp Cache
Package to manage Cache Index and crypto content using [Sodium PHP](http://php.net/manual/en/book.sodium.php) _(optional)_
[![Build Status](https://travis-ci.org/00F100/fcphp-cache.svg?branch=master)](https://travis-ci.org/00F100/fcphp-cache) [![codecov](https://codecov.io/gh/00F100/fcphp-cache/branch/master/graph/badge.svg)](https://codecov.io/gh/00F100/fcphp-cache) [![Total Downloads](https://poser.pugx.org/00F100/fcphp-cache/downloads)](https://packagist.org/packages/00F100/fcphp-cache)
## How to install
Composer:
```sh
$ composer require 00f100/fcphp-cache
```
or add in composer.json
```json
{
"require": {
"00f100/fcphp-cache": "*"
}
}
```
## How to use
```php
<?php
use FcPhp\Cache\Facades\CacheFacade;
use FcPhp\Crypto\Crypto;
/**
* Method to create new instance of Cache
*
* @param string|array $cacheRepository Configuration of redis or path to save files cache
* @param string $nonce Nonce to use crypto into content of cache. To generate: \FcPhp\Crypto\Crypto::getNonce()
* @param string $pathKeys Path to save keys crypto
* @return FcPhp\Cache\Interfaces\ICache
*/
$cache = CacheFacade::getInstance(string|array $cacheRepository, string $nonce = null, string $pathKeys = null);
/*
To use with Redis
=========================
*/
$redis = [
'host' => '127.0.0.1',
'port' => '6379',
'password' => null,
'timeout' => 100,
];
$cache = CacheFacade::getInstance($redis);
/*
To use with Redis and crypto
=========================
*/
$redis = [
'host' => '127.0.0.1',
'port' => '6379',
'password' => null,
'timeout' => 100,
];
$cache = CacheFacade::getInstance($redis, Crypto::getNonce());
/*
To use with file
=========================
*/
$cache = CacheFacade::getInstance('path/to/dir');
/*
To use with file and crypto
=========================
*/
$cache = CacheFacade::getInstance('path/to/dir', Crypto::getNonce());
/**
* Method to create new cache
*
* @param string $key Key to name cache
* @param mixed $content Content to cache
* @param int $ttl time to live cache
* @return FcPhp\Cache\Interfaces\ICache
*/
$cache->set(string $key, $content, int $ttl) :ICache
/**
* Method to verify if cache exists
*
* @param string $key Key to name cache
* @return bool
*/
$cache->has(string $key) :bool
/**
* Method to verify/read cache
*
* @param string $key Key to name cache
* @return mixed
*/
$cache->get(string $key)
/**
* Method to delete cache
*
* @param string $key Key to name cache
* @return void
*/
$cache->delete(string $key) :void
/**
* Method to clean old caches
*
* @return FcPhp\Cache\Interfaces\ICache
*/
$cache->clean() :ICache
```
<?php
namespace FcPhp\Cache
{
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Redis\Interfaces\IRedis;
use FcPhp\Cache\Traits\CacheTrait;
use FcPhp\Cache\Traits\CacheFileTrait;
use FcPhp\Cache\Traits\CacheRedisTrait;
use FcPhp\Crypto\Interfaces\ICrypto;
use FcPhp\Cache\Exceptions\PathKeyNotFoundException;
class Cache implements ICache
{
/**
* Const to alias cache in Redis
*/
const CACHE_REDIS_ALIAS = 'cache::';
const CACHE_KEY_ALIAS = 'key::';
use CacheTrait;
use CacheFileTrait;
use CacheRedisTrait;
/**
* @var string
*/
private $strategy = 'redis';
/**
* @var FcPhp\Redis\Interfaces\IRedis
*/
private $redis = null;
/**
* @var string
*/
private $path = null;
/**
* @var FcPhp\Crypto\Interfaces\ICrypto
*/
private $crypto = null;
/**
* @var string
*/
private $pathKeys = null;
/**
* Method to construct new instance of Cache
*
* @param FcPhp\Redis\Interfaces\IRedis $redis Redis instance
* @param string $path Path to cache in file
* @return void
*/
public function __construct(?IRedis $redis = null, string $path = null, ?ICrypto $crypto = null, string $pathKeys = null)
{
if($redis instanceof IRedis) {
$this->redis = $redis;
}else{
$this->path = $path;
$this->strategy = 'path';
}
if($crypto instanceof ICrypto) {
$this->crypto = $crypto;
if(empty($pathKeys)) {
throw new PathKeyNotFoundException();
}
$this->pathKeys = $pathKeys;
}
}
/**
* Method to create new cache
*
* @param string $key Key to name cache
* @param mixed $content Content to cache
* @param int $ttl time to live cache
* @return FcPhp\Cache\Interfaces\ICache
*/
public function set(string $key, $content, int $ttl) :ICache
{
$content = serialize($content);
$this->write($key, $content, $ttl);
return $this;
}
/**
* Method to verify if cache exists
*
* @param string $key Key to name cache
* @return bool
*/
public function has(string $key) :bool
{
if($this->isRedis()) {
return $this->redis->get(self::CACHE_REDIS_ALIAS . $key) ? true : false;
}else{
return file_exists($this->path . '/' . $key . '.cache');
}
}
/**
* Method to delete cache
*
* @param string $key Key to name cache
* @return void
*/
public function delete(string $key) :void
{
if($this->isRedis()) {
$this->redis->delete(self::CACHE_REDIS_ALIAS . $key);
}else{
$this->fdelete($key);
}
}
/**
* Method to verify/read cache
*
* @param string $key Key to name cache
* @return mixed
*/
public function get(string $key)
{
$content = $this->read($key);
if(!empty($content)) {
$content = explode('|', $content);
$time = $content[0];
$content = $content[1];
$content = $this->unprocessContent($key, $content);
if($time < time()) {
$this->delete($key);
return null;
}
return unserialize($content);
}
return null;
}
/**
* Method to clean old caches
*
* @return FcPhp\Cache\Interfaces\ICache
*/
public function clean() :ICache
{
if($this->isRedis()) {
$this->redisClean();
}else{
$this->fclean();
}
return $this;
}
}
}
<?php
namespace FcPhp\Cache\Exceptions
{
use Exception;
class PathKeyNotFoundException extends Exception
{
}
}
<?php
namespace FcPhp\Cache\Exceptions
{
use Exception;
class PathNotPermissionFoundException extends Exception
{
}
}
<?php
namespace FcPhp\Cache\Facades
{
use FcPhp\Cache\Cache;
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Redis\Facades\RedisFacade;
use FcPhp\Crypto\Crypto;
class CacheFacade
{
/**
* @var FcPhp\Cache\Interfaces\ICache
*/
public static $instance;
/**
* Method to create new instance of Cache
*
* @param string|array $cacheRepository Configuration of redis or path of dir to cache files
* @return FcPhp\Cache\Interfaces\ICache
*/
public static function getInstance($cacheRepository, string $nonce = null, string $pathKeys = null) :ICache
{
if(!self::$instance instanceof ICache) {
$crypto = (!empty($nonce) ? new Crypto($nonce) : null);
if(is_array($cacheRepository) && isset($cacheRepository['host']) && $redis = self::sanitizeRedis($cacheRepository)) {
self::$instance = new Cache(RedisFacade::getInstance($redis['host'], $redis['port'], $redis['password'], $redis['timeout']), null, $crypto, $pathKeys);
}else{
self::$instance = new Cache(null, $cacheRepository, $crypto, $pathKeys);
}
}
return self::$instance;
}
/**
* Method to reset instance
*
* @return void
*/
public static function reset() :void
{
self::$instance = null;
}
/**
* Method to sanitize array of redis configuration
*
* @param array $redis Configuration of redis
* @return array
*/
private static function sanitizeRedis(array &$redis) :array
{
$default = [
'host' => '',
'port' => '6379',
'password' => null,
'timeout' => 100,
];
return array_merge($default, $redis);
}
}
}
<?php
namespace FcPhp\Cache\Interfaces
{
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Redis\Interfaces\IRedis;
use FcPhp\Crypto\Interfaces\ICrypto;
interface ICache
{
public function __construct(?IRedis $redis = null, string $path = null, ?ICrypto $crypto = null, string $pathKeys = null);
public function set(string $key, $content, int $ttl) :ICache;
public function has(string $key) :bool;
public function delete(string $key) :void;
public function get(string $key);
}
}
<?php
namespace FcPhp\Cache\Traits
{
use Exception;
use FcPhp\Cache\Exceptions\PathNotPermissionFoundException;
trait CacheFileTrait
{
/**
* Method to write cache in file
*
* @param string $key Key to name cache
* @param string $content Content to cache
* @return void
*/
private function fmake(string $key, string $content) :void
{
if(!is_dir($this->path)) {
try {
mkdir($this->path, 0755, true);
} catch (Exception $e) {
throw new PathNotPermissionFoundException($this->path, 500, $e);
}
}
$fopen = fopen($this->path . '/' . $key . '.cache', 'w');
fwrite($fopen, $content);
fclose($fopen);
}
/**
* Method to read cache in file
*
* @param string $key Key to name cache
* @return mixed
*/
private function fread(string $key)
{
$file = $this->path . '/' . $key . '.cache';
return $this->has($key) ? file_get_contents($file) : null;
}
/**
* Method to delete cache in file
*
* @param string $key Key to name cache
* @return void
*/
private function fdelete(string $key) :void
{
if($this->has($key)) {
$file = $this->path . '/' . $key . '.cache';
unlink($file);
}
}
/**
* Method to clean old caches
*
* @return void
*/
private function fclean() :void
{
if(is_dir($this->path)) {
$list = array_diff(scandir($this->path), ['.','..']);
if(count($list) > 0) {
foreach($list as $file) {
$fileData = explode('.', $file);
$key = current($fileData);
if(end($fileData) == 'cache') {
$content = file_get_contents($this->path . '/' . $file);
$content = explode('|', $content);
$time = current($content);
if($time < time()) {
$this->delete($key);
}
}
}
}
}
}
}
}
<?php
namespace FcPhp\Cache\Traits
{
trait CacheRedisTrait
{
/**
* Method to verify if Cache use Redis
*
* @return bool
*/
private function isRedis()
{
return $this->strategy == 'redis';
}
/**
* Method to clean Redis old caches
*
* @return void
*/
private function redisClean() :void
{
$list = $this->redis->keys('*');
if(is_array($list)) {
foreach($list as $key) {
if(substr($key, 0, strlen(self::CACHE_REDIS_ALIAS)) == self::CACHE_REDIS_ALIAS) {
$content = $this->redis->get($key);
$content = explode('|', $content);
$time = current($content);
if($time < time()) {
$this->delete($key);
}
}
}
}
}
}
}
<?php
namespace FcPhp\Cache\Traits
{
use Exception;
use FcPhp\Crypto\Interfaces\ICrypto;
use FcPhp\Cache\Exceptions\PathNotPermissionFoundException;
use FcPhp\Crypto\Crypto;
trait CacheTrait
{
/**
* Method to write cache
*
* @param string $key Key to name cache
* @param mixed $content Content to cache
* @param int $ttl time to live cache
* @return void
*/
private function write(string $key, string $content, int $ttl) :void
{
$content = time() + $ttl . '|' . $this->processContent($key, $content);
if($this->isRedis()) {
$this->redis->set(self::CACHE_REDIS_ALIAS . $key, $content);
}else{
$this->fmake($key, $content);
}
}
private function processContent(string $key, string $content)
{
if($this->crypto instanceof ICrypto) {
$key = $this->getKey(md5($key));
return $this->crypto->encode($key, $content);
}
return base64_encode($content);
}
private function unprocessContent(string $key, string $content)
{
if($this->crypto instanceof ICrypto) {
$key = $this->getKey(md5($key));
return $this->crypto->decode($key, $content);
}
return base64_decode($content);
}
private function getKey(string $hash)
{
if(!is_dir($this->pathKeys)) {
try {
mkdir($this->pathKeys, 0755, true);
} catch (Exception $e) {
throw new PathNotPermissionFoundException($this->pathKeys, 500, $e);
}
}
$filePath = $this->pathKeys . '/' . $hash . '.key';
if(file_exists($filePath)) {
return file_get_contents($filePath);
}
$key = Crypto::getKey();
$fopen = fopen($filePath, 'w');
fwrite($fopen, $key);
fclose($fopen);
return $key;
}
/**
* Method to read cache
*
* @param string $key Key to name cache
* @return mixed
*/
private function read(string $key)
{
if($this->isRedis()) {
return $this->redis->get(self::CACHE_REDIS_ALIAS . $key);
}else{
return $this->fread($key);
}
}
}
}
<?php
use FcPhp\Cache\Cache;
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Cache\Facades\CacheFacade;
use FcPhp\Crypto\Crypto;
use PHPUnit\Framework\TestCase;
class CacheIntegrationTest extends TestCase
{
private $instance;
public function setUp()
{
$redis = [
'host' => '127.0.0.1',
'port' => '6379',
'password' => null,
'timeout' => 100
];
$this->instance = CacheFacade::getInstance($redis, Crypto::getNonce(), 'tests/var/keys');
}
public function testInstance()
{
$this->assertTrue($this->instance instanceof ICache);
}
public function testSetGet()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 10;
$this->instance->set($key, $content, $ttl);
$this->assertEquals($this->instance->get($key), $content);
}
public function testHas()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 10;
$this->instance->set($key, $content, $ttl);
$this->assertTrue($this->instance->has($key));
}
public function testCleanRedis()
{
$this->assertTrue($this->instance->clean() instanceof ICache);
}
public function testSetGetOld()
{
$redisInstance = $this->createMock('FcPhp\Redis\Interfaces\IRedis');
$redisInstance
->expects($this->any())
->method('get')
->will($this->returnValue(123 . '|' . base64_encode(serialize(['data' => 'value']))));
$instance = new Cache($redisInstance);
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 10;
$this->assertTrue($instance->get($key) == null);
$instance->delete($key);
}
public function testSetGetFile()
{
CacheFacade::reset();
$instance = CacheFacade::getInstance('tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$this->assertTrue($instance->has($key));
$instance->clean();
}
public function testSetGetFileDelete()
{
CacheFacade::reset();
$instance = CacheFacade::getInstance('tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$this->assertTrue($instance->has($key));
$instance->delete($key);
}
public function testGetKeyNonExists()
{
$this->assertTrue(is_null($this->instance->get('abc')));
}
public function testClean()
{
$this->assertTrue($this->instance->clean() instanceof ICache);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathKeyNotFoundException
*/
public function testWithCryptoNonPath()
{
$instance = new Cache(null, 'tests/var/cache', new Crypto(Crypto::getNonce()));
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testWithCryptoNonPermissionPath()
{
$instance = new Cache(null, 'tests/var/cache', new Crypto(Crypto::getNonce()), '/root/dir');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
public function testWithCryptoNonNewDir()
{
$instance = new Cache(null, 'tests/var/cache', new Crypto(Crypto::getNonce()), 'tests/var/newdir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$instance->delete($key);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testDirCacheNonPermission()
{
$instance = new Cache(null, '/root/dir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
}
}
<?php
use FcPhp\Cache\Cache;
use FcPhp\Cache\Interfaces\ICache;
use PHPUnit\Framework\TestCase;
use FcPhp\Crypto\Interfaces\ICrypto;
class CacheTest extends TestCase
{
private $instance;
public function setUp()
{
$redisInstance = $this->createMock('FcPhp\Redis\Interfaces\IRedis');
$redisInstance
->expects($this->any())
->method('get')
->will($this->returnValue(time() . '|' . base64_encode(serialize(['data' => 'value']))));
$redisInstance
->expects($this->any())
->method('keys')
->will($this->returnValue([Cache::CACHE_REDIS_ALIAS . '1', Cache::CACHE_REDIS_ALIAS . '2', Cache::CACHE_REDIS_ALIAS . '3']));
$this->instance = new Cache($redisInstance);
}
public function testInstance()
{
$this->assertTrue($this->instance instanceof ICache);
}
public function testSetGet()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 84000;
$this->instance->set($key, $content, $ttl);
$this->assertEquals($this->instance->get($key), $content);
}
public function testHas()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 84000;
$this->instance->set($key, $content, $ttl);
$this->assertTrue($this->instance->has($key));
}
public function testSetGetOld()
{
$redisInstance = $this->createMock('FcPhp\Redis\Interfaces\IRedis');
$redisInstance
->expects($this->any())
->method('get')
->will($this->returnValue(123 . '|' . base64_encode(serialize(['data' => 'value']))));
$instance = new Cache($redisInstance);
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 84000;
$instance->set($key, $content, $ttl);
$this->assertTrue($instance->get($key) == null);
}
public function testSetGetFile()
{
$instance = new Cache(null, 'tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$this->assertTrue($instance->has($key));
$instance->delete($key);
}
public function testGetKeyNonExists()
{
$instance = new Cache(null, 'tests/var/cache');
$this->assertTrue(is_null($instance->get('abc')));
}
public function testClean()
{
$this->assertTrue($this->instance->clean() instanceof ICache);
}
public function testCleanFile()
{
$instance = new Cache(null, 'tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertTrue($instance->clean() instanceof ICache);
}
public function testWithCrypto()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance, 'tests/var/keys');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathKeyNotFoundException
*/
public function testWithCryptoNonPath()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance);
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testWithCryptoNonPermissionPath()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance, '/root/dir');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
public function testWithCryptoNonNewDir()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance, 'tests/var/newdir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$instance->delete($key);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testDirCacheNonPermission()
{
$instance = new Cache(null, '/root/dir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
}
}
-5
vendor
tests/coverage
composer.lock
docker-compose.yml
tests/var
language: php
php:
- 7.2
before_script:
- echo "extension = redis.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- travis_retry composer self-update
- travis_retry composer install --no-interaction --prefer-source --dev
script:
- vendor/bin/phpunit --coverage-clover=coverage.xml
after_success:
- bash <(curl -s https://codecov.io/bash)
services:
- redis-server
{
"name": "00f100/fcphp-cache",
"type": "package",
"version": "0.3.0",
"description": "Cache Index for FcPhp",
"keywords": ["cache", "fcphp", "php7", "php72", "crypto", "redis"],
"homepage": "https://github.com/00f100/fcphp-cache",
"authors": [
{
"name": "João Moraes",
"email": "joaomoraesbr@gmail.com",
"homepage": "https://github.com/00f100"
}
],
"require": {
"php": ">=7.2",
"00f100/fcphp-redis": "0.4.1",
"00f100/fcphp-crypto": "0.2.0",
"ext-redis": "*"
},
"require-dev": {
"00f100/phpdbug": "*",
"phpunit/phpunit": "6.*"
},
"autoload": {
"psr-4": {
"FcPhp\\Cache\\": "src/",
"FcPhp\\Cache\\Test\\": "tests/"
}
}
}
MIT License
Copyright (c) 2018 João Moraes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="testSuite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">./src/</directory>
</whitelist>
<blacklist>
<directory suffix=".php">./vendor/</directory>
<exclude>
<directory suffix=".php">./vendor/</directory>
</exclude>
</blacklist>
</filter>
<logging>
<log type="coverage-html" target="tests/coverage" charset="UTF-8" yui="true" highlight="true" lowUpperBound="35" highLowerBound="70" />
</logging>
</phpunit>
# FcPhp Cache
Package to manage Cache Index and crypto content using [Sodium PHP](http://php.net/manual/en/book.sodium.php) _(optional)_
[![Build Status](https://travis-ci.org/00F100/fcphp-cache.svg?branch=master)](https://travis-ci.org/00F100/fcphp-cache) [![codecov](https://codecov.io/gh/00F100/fcphp-cache/branch/master/graph/badge.svg)](https://codecov.io/gh/00F100/fcphp-cache) [![Total Downloads](https://poser.pugx.org/00F100/fcphp-cache/downloads)](https://packagist.org/packages/00F100/fcphp-cache)
## How to install
Composer:
```sh
$ composer require 00f100/fcphp-cache
```
or add in composer.json
```json
{
"require": {
"00f100/fcphp-cache": "*"
}
}
```
## How to use
```php
<?php
use FcPhp\Cache\Facades\CacheFacade;
use FcPhp\Crypto\Crypto;
/**
* Method to create new instance of Cache
*
* @param string|array $cacheRepository Configuration of redis or path to save files cache
* @param string $nonce Nonce to use crypto into content of cache. To generate: \FcPhp\Crypto\Crypto::getNonce()
* @param string $pathKeys Path to save keys crypto
* @return FcPhp\Cache\Interfaces\ICache
*/
$cache = CacheFacade::getInstance(string|array $cacheRepository, string $nonce = null, string $pathKeys = null);
/*
To use with Redis
=========================
*/
$redis = [
'host' => '127.0.0.1',
'port' => '6379',
'password' => null,
'timeout' => 100,
];
$cache = CacheFacade::getInstance($redis);
/*
To use with Redis and crypto
=========================
*/
$redis = [
'host' => '127.0.0.1',
'port' => '6379',
'password' => null,
'timeout' => 100,
];
$cache = CacheFacade::getInstance($redis, Crypto::getNonce());
/*
To use with file
=========================
*/
$cache = CacheFacade::getInstance('path/to/dir');
/*
To use with file and crypto
=========================
*/
$cache = CacheFacade::getInstance('path/to/dir', Crypto::getNonce());
/**
* Method to create new cache
*
* @param string $key Key to name cache
* @param mixed $content Content to cache
* @param int $ttl time to live cache
* @return FcPhp\Cache\Interfaces\ICache
*/
$cache->set(string $key, $content, int $ttl) :ICache
/**
* Method to verify if cache exists
*
* @param string $key Key to name cache
* @return bool
*/
$cache->has(string $key) :bool
/**
* Method to verify/read cache
*
* @param string $key Key to name cache
* @return mixed
*/
$cache->get(string $key)
/**
* Method to delete cache
*
* @param string $key Key to name cache
* @return void
*/
$cache->delete(string $key) :void
/**
* Method to clean old caches
*
* @return FcPhp\Cache\Interfaces\ICache
*/
$cache->clean() :ICache
```
<?php
namespace FcPhp\Cache
{
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Redis\Interfaces\IRedis;
use FcPhp\Cache\Traits\CacheTrait;
use FcPhp\Cache\Traits\CacheFileTrait;
use FcPhp\Cache\Traits\CacheRedisTrait;
use FcPhp\Crypto\Interfaces\ICrypto;
use FcPhp\Cache\Exceptions\PathKeyNotFoundException;
class Cache implements ICache
{
/**
* Const to alias cache in Redis
*/
const CACHE_REDIS_ALIAS = 'cache::';
const CACHE_KEY_ALIAS = 'key::';
use CacheTrait;
use CacheFileTrait;
use CacheRedisTrait;
/**
* @var string
*/
private $strategy = 'redis';
/**
* @var FcPhp\Redis\Interfaces\IRedis
*/
private $redis = null;
/**
* @var string
*/
private $path = null;
/**
* @var FcPhp\Crypto\Interfaces\ICrypto
*/
private $crypto = null;
/**
* @var string
*/
private $pathKeys = null;
/**
* Method to construct new instance of Cache
*
* @param FcPhp\Redis\Interfaces\IRedis $redis Redis instance
* @param string $path Path to cache in file
* @return void
*/
public function __construct(?IRedis $redis = null, string $path = null, ?ICrypto $crypto = null, string $pathKeys = null)
{
if($redis instanceof IRedis) {
$this->redis = $redis;
}else{
$this->path = $path;
$this->strategy = 'path';
}
if($crypto instanceof ICrypto) {
$this->crypto = $crypto;
if(empty($pathKeys)) {
throw new PathKeyNotFoundException();
}
$this->pathKeys = $pathKeys;
}
}
/**
* Method to create new cache
*
* @param string $key Key to name cache
* @param mixed $content Content to cache
* @param int $ttl time to live cache
* @return FcPhp\Cache\Interfaces\ICache
*/
public function set(string $key, $content, int $ttl) :ICache
{
$content = serialize($content);
$this->write($key, $content, $ttl);
return $this;
}
/**
* Method to verify if cache exists
*
* @param string $key Key to name cache
* @return bool
*/
public function has(string $key) :bool
{
if($this->isRedis()) {
return $this->redis->get(self::CACHE_REDIS_ALIAS . $key) ? true : false;
}else{
return file_exists($this->path . '/' . $key . '.cache');
}
}
/**
* Method to delete cache
*
* @param string $key Key to name cache
* @return void
*/
public function delete(string $key) :void
{
if($this->isRedis()) {
$this->redis->delete(self::CACHE_REDIS_ALIAS . $key);
}else{
$this->fdelete($key);
}
}
/**
* Method to verify/read cache
*
* @param string $key Key to name cache
* @return mixed
*/
public function get(string $key)
{
$content = $this->read($key);
if(!empty($content)) {
$content = explode('|', $content);
$time = $content[0];
$content = $content[1];
$content = $this->unprocessContent($key, $content);
if($time < time()) {
$this->delete($key);
return null;
}
return unserialize($content);
}
return null;
}
/**
* Method to clean old caches
*
* @return FcPhp\Cache\Interfaces\ICache
*/
public function clean() :ICache
{
if($this->isRedis()) {
$this->redisClean();
}else{
$this->fclean();
}
return $this;
}
}
}
<?php
namespace FcPhp\Cache\Exceptions
{
use Exception;
class PathKeyNotFoundException extends Exception
{
}
}
<?php
namespace FcPhp\Cache\Exceptions
{
use Exception;
class PathNotPermissionFoundException extends Exception
{
}
}
<?php
namespace FcPhp\Cache\Facades
{
use FcPhp\Cache\Cache;
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Redis\Facades\RedisFacade;
use FcPhp\Crypto\Crypto;
class CacheFacade
{
/**
* @var FcPhp\Cache\Interfaces\ICache
*/
public static $instance;
/**
* Method to create new instance of Cache
*
* @param string|array $cacheRepository Configuration of redis or path of dir to cache files
* @return FcPhp\Cache\Interfaces\ICache
*/
public static function getInstance($cacheRepository, string $nonce = null, string $pathKeys = null) :ICache
{
if(!self::$instance instanceof ICache) {
$crypto = (!empty($nonce) ? new Crypto($nonce) : null);
if(is_array($cacheRepository) && isset($cacheRepository['host']) && $redis = self::sanitizeRedis($cacheRepository)) {
self::$instance = new Cache(RedisFacade::getInstance($redis['host'], $redis['port'], $redis['password'], $redis['timeout']), null, $crypto, $pathKeys);
}else{
self::$instance = new Cache(null, $cacheRepository, $crypto, $pathKeys);
}
}
return self::$instance;
}
/**
* Method to reset instance
*
* @return void
*/
public static function reset() :void
{
self::$instance = null;
}
/**
* Method to sanitize array of redis configuration
*
* @param array $redis Configuration of redis
* @return array
*/
private static function sanitizeRedis(array &$redis) :array
{
$default = [
'host' => '',
'port' => '6379',
'password' => null,
'timeout' => 100,
];
return array_merge($default, $redis);
}
}
}
<?php
namespace FcPhp\Cache\Interfaces
{
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Redis\Interfaces\IRedis;
use FcPhp\Crypto\Interfaces\ICrypto;
interface ICache
{
public function __construct(?IRedis $redis = null, string $path = null, ?ICrypto $crypto = null, string $pathKeys = null);
public function set(string $key, $content, int $ttl) :ICache;
public function has(string $key) :bool;
public function delete(string $key) :void;
public function get(string $key);
}
}
<?php
namespace FcPhp\Cache\Traits
{
use Exception;
use FcPhp\Cache\Exceptions\PathNotPermissionFoundException;
trait CacheFileTrait
{
/**
* Method to write cache in file
*
* @param string $key Key to name cache
* @param string $content Content to cache
* @return void
*/
private function fmake(string $key, string $content) :void
{
if(!is_dir($this->path)) {
try {
mkdir($this->path, 0755, true);
} catch (Exception $e) {
throw new PathNotPermissionFoundException($this->path, 500, $e);
}
}
$fopen = fopen($this->path . '/' . $key . '.cache', 'w');
fwrite($fopen, $content);
fclose($fopen);
}
/**
* Method to read cache in file
*
* @param string $key Key to name cache
* @return mixed
*/
private function fread(string $key)
{
$file = $this->path . '/' . $key . '.cache';
return $this->has($key) ? file_get_contents($file) : null;
}
/**
* Method to delete cache in file
*
* @param string $key Key to name cache
* @return void
*/
private function fdelete(string $key) :void
{
if($this->has($key)) {
$file = $this->path . '/' . $key . '.cache';
unlink($file);
}
}
/**
* Method to clean old caches
*
* @return void
*/
private function fclean() :void
{
if(is_dir($this->path)) {
$list = array_diff(scandir($this->path), ['.','..']);
if(count($list) > 0) {
foreach($list as $file) {
$fileData = explode('.', $file);
$key = current($fileData);
if(end($fileData) == 'cache') {
$content = file_get_contents($this->path . '/' . $file);
$content = explode('|', $content);
$time = current($content);
if($time < time()) {
$this->delete($key);
}
}
}
}
}
}
}
}
<?php
namespace FcPhp\Cache\Traits
{
trait CacheRedisTrait
{
/**
* Method to verify if Cache use Redis
*
* @return bool
*/
private function isRedis()
{
return $this->strategy == 'redis';
}
/**
* Method to clean Redis old caches
*
* @return void
*/
private function redisClean() :void
{
$list = $this->redis->keys('*');
if(is_array($list)) {
foreach($list as $key) {
if(substr($key, 0, strlen(self::CACHE_REDIS_ALIAS)) == self::CACHE_REDIS_ALIAS) {
$content = $this->redis->get($key);
$content = explode('|', $content);
$time = current($content);
if($time < time()) {
$this->delete($key);
}
}
}
}
}
}
}
<?php
namespace FcPhp\Cache\Traits
{
use Exception;
use FcPhp\Crypto\Interfaces\ICrypto;
use FcPhp\Cache\Exceptions\PathNotPermissionFoundException;
use FcPhp\Crypto\Crypto;
trait CacheTrait
{
/**
* Method to write cache
*
* @param string $key Key to name cache
* @param mixed $content Content to cache
* @param int $ttl time to live cache
* @return void
*/
private function write(string $key, string $content, int $ttl) :void
{
$content = time() + $ttl . '|' . $this->processContent($key, $content);
if($this->isRedis()) {
$this->redis->set(self::CACHE_REDIS_ALIAS . $key, $content);
}else{
$this->fmake($key, $content);
}
}
private function processContent(string $key, string $content)
{
if($this->crypto instanceof ICrypto) {
$key = $this->getKey(md5($key));
return $this->crypto->encode($key, $content);
}
return base64_encode($content);
}
private function unprocessContent(string $key, string $content)
{
if($this->crypto instanceof ICrypto) {
$key = $this->getKey(md5($key));
return $this->crypto->decode($key, $content);
}
return base64_decode($content);
}
private function getKey(string $hash)
{
if(!is_dir($this->pathKeys)) {
try {
mkdir($this->pathKeys, 0755, true);
} catch (Exception $e) {
throw new PathNotPermissionFoundException($this->pathKeys, 500, $e);
}
}
$filePath = $this->pathKeys . '/' . $hash . '.key';
if(file_exists($filePath)) {
return file_get_contents($filePath);
}
$key = Crypto::getKey();
$fopen = fopen($filePath, 'w');
fwrite($fopen, $key);
fclose($fopen);
return $key;
}
/**
* Method to read cache
*
* @param string $key Key to name cache
* @return mixed
*/
private function read(string $key)
{
if($this->isRedis()) {
return $this->redis->get(self::CACHE_REDIS_ALIAS . $key);
}else{
return $this->fread($key);
}
}
}
}
<?php
use FcPhp\Cache\Cache;
use FcPhp\Cache\Interfaces\ICache;
use FcPhp\Cache\Facades\CacheFacade;
use FcPhp\Crypto\Crypto;
use PHPUnit\Framework\TestCase;
class CacheIntegrationTest extends TestCase
{
private $instance;
public function setUp()
{
$redis = [
'host' => '127.0.0.1',
'port' => '6379',
'password' => null,
'timeout' => 100
];
$this->instance = CacheFacade::getInstance($redis, Crypto::getNonce(), 'tests/var/keys');
}
public function testInstance()
{
$this->assertTrue($this->instance instanceof ICache);
}
public function testSetGet()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 10;
$this->instance->set($key, $content, $ttl);
$this->assertEquals($this->instance->get($key), $content);
}
public function testHas()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 10;
$this->instance->set($key, $content, $ttl);
$this->assertTrue($this->instance->has($key));
}
public function testCleanRedis()
{
$this->assertTrue($this->instance->clean() instanceof ICache);
}
public function testSetGetOld()
{
$redisInstance = $this->createMock('FcPhp\Redis\Interfaces\IRedis');
$redisInstance
->expects($this->any())
->method('get')
->will($this->returnValue(123 . '|' . base64_encode(serialize(['data' => 'value']))));
$instance = new Cache($redisInstance);
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 10;
$this->assertTrue($instance->get($key) == null);
$instance->delete($key);
}
public function testSetGetFile()
{
CacheFacade::reset();
$instance = CacheFacade::getInstance('tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$this->assertTrue($instance->has($key));
$instance->clean();
}
public function testSetGetFileDelete()
{
CacheFacade::reset();
$instance = CacheFacade::getInstance('tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$this->assertTrue($instance->has($key));
$instance->delete($key);
}
public function testGetKeyNonExists()
{
$this->assertTrue(is_null($this->instance->get('abc')));
}
public function testClean()
{
$this->assertTrue($this->instance->clean() instanceof ICache);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathKeyNotFoundException
*/
public function testWithCryptoNonPath()
{
$instance = new Cache(null, 'tests/var/cache', new Crypto(Crypto::getNonce()));
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testWithCryptoNonPermissionPath()
{
$instance = new Cache(null, 'tests/var/cache', new Crypto(Crypto::getNonce()), '/root/dir');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
public function testWithCryptoNonNewDir()
{
$instance = new Cache(null, 'tests/var/cache', new Crypto(Crypto::getNonce()), 'tests/var/newdir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$instance->delete($key);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testDirCacheNonPermission()
{
$instance = new Cache(null, '/root/dir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
}
}
<?php
use FcPhp\Cache\Cache;
use FcPhp\Cache\Interfaces\ICache;
use PHPUnit\Framework\TestCase;
use FcPhp\Crypto\Interfaces\ICrypto;
class CacheTest extends TestCase
{
private $instance;
public function setUp()
{
$redisInstance = $this->createMock('FcPhp\Redis\Interfaces\IRedis');
$redisInstance
->expects($this->any())
->method('get')
->will($this->returnValue(time() . '|' . base64_encode(serialize(['data' => 'value']))));
$redisInstance
->expects($this->any())
->method('keys')
->will($this->returnValue([Cache::CACHE_REDIS_ALIAS . '1', Cache::CACHE_REDIS_ALIAS . '2', Cache::CACHE_REDIS_ALIAS . '3']));
$this->instance = new Cache($redisInstance);
}
public function testInstance()
{
$this->assertTrue($this->instance instanceof ICache);
}
public function testSetGet()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 84000;
$this->instance->set($key, $content, $ttl);
$this->assertEquals($this->instance->get($key), $content);
}
public function testHas()
{
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 84000;
$this->instance->set($key, $content, $ttl);
$this->assertTrue($this->instance->has($key));
}
public function testSetGetOld()
{
$redisInstance = $this->createMock('FcPhp\Redis\Interfaces\IRedis');
$redisInstance
->expects($this->any())
->method('get')
->will($this->returnValue(123 . '|' . base64_encode(serialize(['data' => 'value']))));
$instance = new Cache($redisInstance);
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 84000;
$instance->set($key, $content, $ttl);
$this->assertTrue($instance->get($key) == null);
}
public function testSetGetFile()
{
$instance = new Cache(null, 'tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$this->assertTrue($instance->has($key));
$instance->delete($key);
}
public function testGetKeyNonExists()
{
$instance = new Cache(null, 'tests/var/cache');
$this->assertTrue(is_null($instance->get('abc')));
}
public function testClean()
{
$this->assertTrue($this->instance->clean() instanceof ICache);
}
public function testCleanFile()
{
$instance = new Cache(null, 'tests/var/cache');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertTrue($instance->clean() instanceof ICache);
}
public function testWithCrypto()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance, 'tests/var/keys');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathKeyNotFoundException
*/
public function testWithCryptoNonPath()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance);
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testWithCryptoNonPermissionPath()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance, '/root/dir');
$key = 'cb6e0e439eff1d257641502d8fa65698';
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
}
public function testWithCryptoNonNewDir()
{
$cryptoInstance = $this->createMock('FcPhp\Crypto\Interfaces\ICrypto');
$cryptoInstance
->expects($this->any())
->method('decode')
->will($this->returnValue(serialize(['data' => 'value'])));
$instance = new Cache(null, 'tests/var/cache', $cryptoInstance, 'tests/var/newdir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
$this->assertEquals($instance->get($key), $content);
$instance->delete($key);
}
/**
* @expectedException FcPhp\Cache\Exceptions\PathNotPermissionFoundException
*/
public function testDirCacheNonPermission()
{
$instance = new Cache(null, '/root/dir');
$key = md5(time() . rand());
$content = ['data' => 'value'];
$ttl = 0;
$instance->set($key, $content, $ttl);
}
}