/decorators/ProductAPICaching.php
PHP | 320 lines | 190 code | 20 blank | 110 comment | 21 complexity | cf205e63ef8c03da027d966078a450d2 MD5 | raw file
- <?php
- /**
- * @author Samigullin Kamil <feedback@kamilsk.com>
- * @link http://www.kamilsk.com/
- */
- namespace Ecwid\decorators;
- use Ecwid\interfaces\iProductAPI,
- \Exception;
- /**
- * @package Ecwid.decorators
- * @since 1.0
- */
- class ProductAPICaching extends ProductAPIDecorator
- {
- /**
- * @var array
- */
- protected static $_defaultConfig = array(
- 'cache_path' => __DIR__,
- 'lifetime' => 7200,
- 'enabled' => true,
- );
- /**
- * Constructor.
- *
- * @param iProductAPI $product_api
- * @param array $config
- * <code>
- * array(
- * 'cache_path' => %s:path,
- * 'lifetime' => %i:seconds,
- * 'enabled' => %bool,
- * )
- * </code>
- * @throws Exception
- */
- public function __construct(iProductAPI $product_api, array $config = array())
- {
- if ($this->_initConfig(array_merge(self::$_defaultConfig, $config))) {
- parent::__construct($product_api);
- } else {
- throw new Exception('_init');
- }
- }
- /**
- * @return string
- */
- public function getCachePath()
- {
- return $this->_config['cache_path'];
- }
- /**
- * @param string $path
- * @return self
- * @throws Exception
- */
- public function setCachePath($path)
- {
- if ( ! is_string($path)) {
- throw new Exception('_invalid_type');
- }
- if (false === ($path = realpath($path)) or ! is_writable($path)) {
- throw new Exception('_invalid_path');
- }
- $this->_config['cache_path'] = $path;
- return $this;
- }
- /**
- * @return int
- */
- public function getLifetime()
- {
- return $this->_config['lifetime'];
- }
- /**
- * @param int $time
- * @return self
- * @throws Exception
- */
- public function setLifetime($time)
- {
- if ( ! is_int($time) or $time < 0) {
- throw new Exception('_invalid_type');
- }
- $this->_config['lifetime'] = $time;
- return $this;
- }
- /**
- * @return bool
- */
- public function isEnabled()
- {
- return $this->_config['enabled'];
- }
- /**
- * @param bool $condition
- * @return void
- * @throws Exception
- */
- protected function _setCondition($condition)
- {
- if ( ! is_bool($condition)) {
- throw new Exception('_invalid_type');
- }
- $this->_config['enabled'] = $condition;
- }
- /**
- * @param array $config
- * @return bool
- * @throws Exception
- */
- protected function _initConfig(array $config)
- {
- $map = array(
- 'cache_path' => 'setCachePath',
- 'lifetime' => 'setLifetime',
- 'enabled' => '_setCondition',
- );
- $this->_silent = true;
- foreach ($config as $key => $value) {
- if (array_key_exists($key, $map)) {
- $set = $map[$key];
- $this->$set($value);
- }
- }
- $this->_silent = false;
- return true;
- }
- /* iProductAPI */
- /**
- * @param int|null $parent
- * @return mixed
- * @throws Exception
- */
- public function getCategories($parent = null)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getCategories($parent);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param int $id
- * @return mixed
- * $throws Exception
- */
- public function getCategory($id)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getCategory($id);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param int|null $category
- * @return mixed
- * @throws Exception
- */
- public function getProducts($category = null)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getProducts($category);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param int $id
- * @return mixed
- * @throws Exception
- */
- public function getProduct($id)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getProduct($id);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param int $count
- * @return mixed
- * @throws Exception
- */
- public function getRandomProducts($count)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getRandomProducts($count);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @return mixed
- * @throws Exception
- */
- public function getClasses()
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getClasses();
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param int $id
- * @return mixed
- * @throws Exception
- */
- public function getClass($id)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getClass($id);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @return mixed
- * @throws Exception
- */
- public function getProfile()
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->getProfile();
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param array $data
- * @return mixed
- * @throws Exception
- */
- public function runBatch(array $data)
- {
- $response = $this->_fetch(__FUNCTION__, func_get_args());
- if ($response === false) {
- $response = $this->_product_api->runBatch($data);
- return $this->_cache(__FUNCTION__, func_get_args(), $response);
- }
- return $response;
- }
- /**
- * @param string $method
- * @param array $params
- * @return bool|mixed
- */
- protected function _fetch($method, array $params)
- {
- $folder = "{$this->getCachePath()}/{$method}";
- $filename = md5(serialize($params));
- $file = "{$folder}/{$filename}";
- $timestamp = time();
- if (false !== ($cache = @file_get_contents($file))) {
- $cache = unserialize($cache);
- if ($cache['created'] !== $cache['expired'] && $cache['expired'] < $timestamp) {
- return false;
- }
- return $cache['data'];
- }
- return false;
- }
- /**
- * @param string $method
- * @param array $params
- * @param mixed $data
- * @return mixed
- * @throws Exception
- */
- protected function _cache($method, array $params, $data)
- {
- $folder = "{$this->getCachePath()}/{$method}";
- $filename = md5(serialize($params));
- $file = "{$folder}/{$filename}";
- $timestamp = time();
- if ( ! file_exists($folder)) {
- mkdir($folder);
- }
- $cache = array(
- 'created' => $timestamp,
- 'expired' => $timestamp + $this->getLifetime(),
- 'data' => $data,
- );
- if (false !== @file_put_contents($file, serialize($cache))) {
- return $data;
- }
- throw new Exception('_cache');
- }
- }