Skip to content

Commit

Permalink
Adding some basic caching functionality, requires to include `doctrin…
Browse files Browse the repository at this point in the history
…e-cache` in your composer.json.
  • Loading branch information
wtfzdotnet committed Mar 1, 2014
2 parents 2c19c97 + d6d7221 commit 5f03c04
Show file tree
Hide file tree
Showing 6 changed files with 254 additions and 12 deletions.
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
"guzzle/guzzle": ">=0.7"
},
"require-dev": {
"phpunit/phpunit": ">=3.7"
"phpunit/phpunit": ">=3.7",
"doctrine/cache": ">=1.3.0"
},
"suggest": {
"doctrine/cache": "This library is required if you want to make use of caching features."
},
"autoload": {
"psr-0": { "Tmdb\\": "lib/" }
Expand Down
24 changes: 24 additions & 0 deletions examples/movies/model/cache/basic_doctrine_cache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* This file is part of the Tmdb PHP API created by Michael Roterman.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Tmdb
* @author Michael Roterman <[email protected]>
* @copyright (c) 2013, Michael Roterman
* @version 0.0.1
*/
require_once '../../../../vendor/autoload.php';
require_once '../../../../apikey.php';

$token = new \Tmdb\ApiToken(TMDB_API_KEY);
$client = new \Tmdb\Client($token);

$client->setCaching(true);

$repository = new \Tmdb\Repository\MovieRepository($client);
$movie = $repository->load(87421);

var_dump($movie);
24 changes: 24 additions & 0 deletions examples/movies/model/cache/built-in.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
/**
* This file is part of the Tmdb PHP API created by Michael Roterman.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @package Tmdb
* @author Michael Roterman <[email protected]>
* @copyright (c) 2013, Michael Roterman
* @version 0.0.1
*/
require_once '../../../../vendor/autoload.php';
require_once '../../../../apikey.php';

$token = new \Tmdb\ApiToken(TMDB_API_KEY);
$client = new \Tmdb\Client($token);

$client->setCaching(true, '/tmp/php-tmdb-api');

$repository = new \Tmdb\Repository\MovieRepository($client);
$movie = $repository->load(87421);

echo $movie->getTitle();
126 changes: 115 additions & 11 deletions lib/Tmdb/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
*/
namespace Tmdb;

use Guzzle\Cache\DoctrineCacheAdapter;
use Guzzle\Common\Exception\RuntimeException;
use Guzzle\Common\HasDispatcherInterface;
use Guzzle\Http\Client as GuzzleClient;
use Guzzle\Http\ClientInterface;
use Guzzle\Plugin\Cache\CachePlugin;
use Guzzle\Plugin\Cache\DefaultCacheStorage;
use Tmdb\HttpClient\HttpClient;
use Tmdb\HttpClient\HttpClientInterface;
use Tmdb\ApiToken as Token;
Expand Down Expand Up @@ -70,31 +75,94 @@ class Client
*/
private $httpClient;

/**
* Stores the cache path
*
* @var string
*/
private $cachePath;

/**
* Stores wether the cache is enabled or not
*
* @var boolean
*/
private $cacheEnabled = false;

/**
* Construct our client
*
* @param ClientInterface|null $httpClient
* @param ApiToken $token
* @param boolean $secure
*/
public function __construct(Token $token, ClientInterface $httpClient = null, $secure = false)
public function __construct(ApiToken $token, ClientInterface $httpClient = null, $secure = false)
{
$this->setToken($token);
$this->setSecure($secure);
$this->constructHttpClient($httpClient);
}

/**
* Construct the http client
*
* @param ClientInterface $httpClient
* @throws RuntimeException
* @return void
*/
private function constructHttpClient(ClientInterface $httpClient = null)
{
$httpClient = $httpClient ?: new GuzzleClient($this->getBaseUrl());

if ($httpClient instanceof \Guzzle\Common\HasDispatcherInterface) {
$apiTokenPlugin = new ApiTokenPlugin($token);
$httpClient->addSubscriber($apiTokenPlugin);

if ($httpClient instanceof HasDispatcherInterface) {
$acceptJsonHeaderPlugin = new AcceptJsonHeaderPlugin();
$httpClient->addSubscriber($acceptJsonHeaderPlugin);

if ($this->getToken() instanceof ApiToken) {
$apiTokenPlugin = new ApiTokenPlugin($this->getToken());
$httpClient->addSubscriber($apiTokenPlugin);
}

if ($this->cacheEnabled && !empty($this->cachePath)) {
if (!class_exists('Doctrine\Common\Cache\FilesystemCache')) {
/** @codeCoverageIgnoreStart */
throw new RuntimeException(
'Could not find the doctrine cache library, have you added doctrone-cache to your composer.json?'
);
/** @codeCoverageIgnoreEnd */
}

$cachePlugin = new CachePlugin(array(
'storage' => new DefaultCacheStorage(
new DoctrineCacheAdapter(
new \Doctrine\Common\Cache\FilesystemCache($this->cachePath)
)
)
)
);

$httpClient->addSubscriber($cachePlugin);
}

if ($this->getSessionToken() instanceof SessionToken) {
$sessionTokenPlugin = new SessionTokenPlugin($this->getSessionToken());
$httpClient->addSubscriber($sessionTokenPlugin);
}
}

$this->httpClient = new HttpClient($this->getBaseUrl(), array(), $httpClient);
}

/**
* Add the token subscriber
*
* @return Token
*/
public function getToken()
{
return $this->token !== null ? $this->token : null;
}

/**
* Add the token subscriber
*
Expand Down Expand Up @@ -285,7 +353,7 @@ public function getCertificationsApi()
}

/**
* @return HttpClientInterface
* @return HttpClient|HttpClientInterface
*/
public function getHttpClient()
{
Expand Down Expand Up @@ -339,13 +407,10 @@ public function getSecure()
*/
public function setSessionToken($sessionToken)
{
if ($this->httpClient->getClient() instanceof \Guzzle\Common\HasDispatcherInterface) {
$sessionTokenPlugin = new SessionTokenPlugin($sessionToken);
$this->httpClient->getClient()->addSubscriber($sessionTokenPlugin);
}

$this->sessionToken = $sessionToken;

$this->constructHttpClient();

return $this;
}

Expand All @@ -356,4 +421,43 @@ public function getSessionToken()
{
return $this->sessionToken;
}

/**
* @return boolean
*/
public function getCacheEnabled()
{
return $this->cacheEnabled;
}

/**
* Set cache path
*
* You could simply pass an empty string to let the sys_get_temp_dir be used
*
* @param boolean $enabled
* @param string $path
* @return $this
*/
public function setCaching($enabled = true, $path = null)
{
$this->cacheEnabled = $enabled;
$this->cachePath = (null === $path) ?
sys_get_temp_dir() . '/php-tmdb-api' :
$path
;

// @todo doesn't cover a custom client, would require un-registering all known plugins
$this->constructHttpClient();

return $this;
}

/**
* @return string
*/
public function getCachePath()
{
return $this->cachePath;
}
}
38 changes: 38 additions & 0 deletions lib/Tmdb/HttpClient/HttpClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,42 @@ public function getClient()
{
return $this->client;
}

/**
* @param \Guzzle\Http\Message\Request $lastRequest
* @return $this
*/
public function setLastRequest($lastRequest)
{
$this->lastRequest = $lastRequest;

return $this;
}

/**
* @return \Guzzle\Http\Message\Request
*/
public function getLastRequest()
{
return $this->lastRequest;
}

/**
* @param \Guzzle\Http\Message\Response $lastResponse
* @return $this
*/
public function setLastResponse($lastResponse)
{
$this->lastResponse = $lastResponse;

return $this;
}

/**
* @return \Guzzle\Http\Message\Response
*/
public function getLastResponse()
{
return $this->lastResponse;
}
}
48 changes: 48 additions & 0 deletions test/Tmdb/Tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,52 @@ public function assertInstances()
)
);
}

/**
* @test
*/
public function shouldAddCachePluginWhenEnabled()
{
$token = new \Tmdb\ApiToken(self::API_TOKEN);
$client = new \Tmdb\Client($token);
$client->setCaching(true, '/tmp/php-tmdb-api');

$listeners = $client->getHttpClient()
->getClient()
->getEventDispatcher()
->getListeners();

$this->assertEquals(true, $this->isListenerRegistered(
$listeners,
'Guzzle\Plugin\Cache\CachePlugin'
));
}

/**
* Find an plugin in an listeners array
*
* @param $listeners
* @param $class
* @return bool
*/
private function isListenerRegistered($listeners, $class)
{
if (is_object($class)) {
$class = get_class($class);
}

if (is_array($listeners)) {
foreach ($listeners as $subject) {
if (is_object($subject) && get_class($subject) === $class) {
return true;
}

if (is_array($subject)) {
return $this->isListenerRegistered($subject, $class);
}
}
}

return false;
}
}

0 comments on commit 5f03c04

Please sign in to comment.