Skip to content

Commit

Permalink
Merge pull request #41 from bedita/feat/3.x/thumbcache
Browse files Browse the repository at this point in the history
Introduce cache for ThumbHelper
  • Loading branch information
didoda authored May 10, 2021
2 parents 1225c97 + f6e2821 commit 6d5dff2
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/View/Helper/ThumbHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
namespace BEdita\WebTools\View\Helper;

use BEdita\WebTools\ApiClientProvider;
use Cake\Cache\Cache;
use Cake\Log\LogTrait;
use Cake\Utility\Hash;
use Cake\View\Helper;

/**
Expand All @@ -25,6 +27,15 @@ class ThumbHelper extends Helper
{
use LogTrait;

/**
* Default config for this helper.
*
* @var array
*/
protected $_defaultConfig = [
'cache' => '_thumbs_',
];

/**
* @var int Thumb not available
*/
Expand All @@ -50,6 +61,25 @@ class ThumbHelper extends Helper
*/
public const OK = 1;

/**
* Use 'default' as fallback if no cache configuration is found.
*
* @param array $config The configuration settings provided to this helper.
* @return void
*/
public function initialize(array $config): void
{
parent::initialize($config);
if (!empty($config['cache'])) {
$this->setConfig('cache', $config['cache']);
}
$cacheCfg = $this->getConfig('cache');
$cfg = Cache::getConfig($cacheCfg);
if ($cfg === null) {
$this->setConfig('cache', 'default');
}
}

/**
* Verify status of image thumb.
* Return int representing status.
Expand Down Expand Up @@ -162,4 +192,31 @@ private function hasUrl($thumb = []): bool

return false;
}

/**
* Retrieve thumb URL using cache.
* Silently fail with log if no image 'id' is found in array.
*
* @param array $image Image object array containing at least `id`
* @param string $options Thumb options
* @return string
*/
public function getUrl(array $image, array $options = []): string
{
if (empty($image['id'])) {
$this->log(sprintf('Missing image ID - %s', json_encode($image)), 'warning');

return '';
}
$thumbHash = md5((string)Hash::get($image, 'meta.media_url') . json_encode($options));
$key = sprintf('%d_%s', $image['id'], $thumbHash);

return (string)Cache::remember(
$key,
function () use ($image, $options) {
return $this->url($image['id'], $options);
},
$this->getConfig('cache')
);
}
}
102 changes: 102 additions & 0 deletions tests/TestCase/View/Helper/ThumbHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
use BEdita\SDK\BEditaClient;
use BEdita\WebTools\ApiClientProvider;
use BEdita\WebTools\View\Helper\ThumbHelper;
use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\TestSuite\TestCase;
use Cake\Utility\Hash;
use Cake\View\View;

/**
Expand Down Expand Up @@ -100,6 +102,70 @@ private function _image($filename = 'test.png'): int
return (int)$response['data']['id'];
}

/**
* Create image and media stream for test.
* Return id
*
* @param string $filename the File name.
* @return array|null The image Data.
*/
private function _imageData($filename = 'test.png'): ?array
{
$apiClient = ApiClientProvider::getApiClient();

$filepath = sprintf('%s/tests/files/%s', getcwd(), $filename);
$response = $apiClient->upload($filename, $filepath);

$streamId = $response['data']['id'];
$response = $apiClient->get(sprintf('/streams/%s', $streamId));

$type = 'images';
$title = 'The test image';
$attributes = compact('title');
$data = compact('type', 'attributes');
$body = compact('data');
$response = $apiClient->createMediaFromStream($streamId, $type, $body);
$response['id'] = (int)$response['data']['id'];

return $response;
}

/**
* Initialize Thumb Helper test
*
* @return void
* @covers ::initialize()
*/
public function testInitialize(): void
{
$this->Thumb = new ThumbHelper(new View());
$actual = $this->Thumb->getConfig('cache');
$expected = 'default';
static::assertEquals($expected, $actual);
}

/**
* Initialize Thumb Helper test, custom cfg
*
* @return void
* @covers ::initialize()
*/
public function testInitializeCustomConfig(): void
{
$expected = 'dummy';
Cache::setConfig(
$expected,
[
'engine' => 'File',
'prefix' => sprintf('%s_', $expected),
'serialize' => true,
]
);
$this->Thumb = new ThumbHelper(new View(), ['cache' => $expected]);
$actual = $this->Thumb->getConfig('cache');
static::assertEquals($expected, $actual);
}

/**
* Data provider for `testUrl` test case.
*
Expand Down Expand Up @@ -359,4 +425,40 @@ public function testStatusInput(): void
$status = $this->Thumb->status(null);
static::assertEquals($status, ThumbHelper::NOT_ACCEPTABLE);
}

/**
* Test `getUrl()` method for 3 cases:
* 1) image with empty id
* 2) image NOT present in cache
* 3) image already present in cache
*
* @covers ::getUrl()
* @return void
*/
public function testGetUrl(): void
{
//empty id
$this->Thumb = new ThumbHelper(new View());
$id = [];
$actual = $this->Thumb->getUrl($id);
$expected = '';
static::assertEquals($expected, $actual);

//fake data NOT in cache
$image = $this->_imageData();
$options = [];
$expected = $this->Thumb->url($image['id'], $options);
$actual = $this->Thumb->getUrl($image);
static::assertEquals($expected, $actual);

//fake data in cache
$image = $this->_imageData();
$options = [];
$actual = $this->Thumb->getUrl($image);
$thumbHash = md5((string)Hash::get($image, 'meta.media_url') . json_encode($options));
$key = sprintf('%d_%s', $image['id'], $thumbHash);
Cache::write($key, $actual);
$expected = $this->Thumb->url($image['id'], []);
static::assertEquals($expected, $actual);
}
}
5 changes: 5 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@
]);

Cache::setConfig([
'default' => [
'className' => 'File',
'path' => CACHE,
'url' => env('CACHE_DEFAULT_URL', null),
],
'_cake_core_' => [
'engine' => 'File',
'prefix' => 'cake_core_',
Expand Down

0 comments on commit 6d5dff2

Please sign in to comment.