PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/history/driver.php

https://github.com/axelitus/fuel-pkg-history
PHP | 349 lines | 176 code | 41 blank | 132 comment | 13 complexity | 255a1003900ae34abeba2638c1ed2836 MD5 | raw file
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP5 framework.
  4. *
  5. * @package Fuel
  6. * @version 1.1
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2011 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace History;
  13. /**
  14. * History_Driver
  15. *
  16. * @package Fuel
  17. * @subpackage History
  18. * @author Axel Pardemann (http://github.com/axelitus)
  19. * @link http://github.com/axelitus/fuel-pkg-history
  20. */
  21. abstract class History_Driver
  22. {
  23. /**
  24. * @var string Contains the History's class history_id (the key in Session)
  25. */
  26. protected $_history_id = 'history';
  27. /**
  28. * @var array Contains the driver configuration
  29. */
  30. protected $_config = array();
  31. /**
  32. * @var History_Driver_GC Garbage Collector specific for driver if needed
  33. */
  34. protected $_gc = null;
  35. // @formatter:off
  36. /**
  37. * @var array of global config defaults
  38. * Can be overloaded in derived class but PAY ATTENTION, otherwise something will
  39. * break awfully. If this happens take look here first. These are the default
  40. * values that should be present, unless your driver doesn't need them.
  41. */
  42. protected static $_config_defaults = array(
  43. 'name' => 'file',
  44. 'compression' => array(
  45. 'active' => true,
  46. 'format' => 'zlib',
  47. 'level' => 5
  48. ),
  49. 'secure' => true,
  50. 'hash_length' => 8,
  51. 'file' => array(
  52. 'path' => '',
  53. 'prefix' => 'his_',
  54. 'extension' => 'tmp'
  55. ),
  56. 'database' => array(
  57. 'table' => 'history',
  58. 'auto_create' => true
  59. ),
  60. 'session' => array(
  61. ),
  62. 'gc' => array(
  63. 'active' => true,
  64. 'threshold' => 900,
  65. 'probability' => 5
  66. )
  67. );
  68. // @formatter:on
  69. /**
  70. * Prevent direct instantiation. If this function is overloaded don't forget to
  71. * call parent::_construct() as needed!
  72. */
  73. protected function __construct($history_id, array $config = array())
  74. {
  75. $this->_history_id = $history_id;
  76. $this->_config = \Arr::merge(static::$_config_defaults, $config);
  77. // The hash length must be between 1 and 40
  78. $this->_config['hash_length'] = (($this->_config['hash_length'] > 0 && $this->_config['hash_length'] < 41) ? $this->_config['hash_length'] : 8);
  79. }
  80. /**
  81. * Loads the GC if it exists
  82. */
  83. protected function _load_gc(array $config = array())
  84. {
  85. // Is Garbage Collector active?
  86. if ($config['active'])
  87. {
  88. // If exists then load the Garbage Collector for the driver and start it
  89. $gc = 'History_Driver_GC_' . ucwords($this->_config['name']);
  90. if (class_exists($gc))
  91. {
  92. $this->_gc = $gc::forge($this, $config);
  93. // Log Info
  94. \Log::info(get_called_class() . "::_load_gc() - The GC collector for the specified driver was loaded.");
  95. $this->_gc->start();
  96. }
  97. }
  98. }
  99. /**
  100. * Forges a new History_Driver instance
  101. *
  102. * @return History_Driver
  103. */
  104. public static function forge($history_id, array $config = array())
  105. {
  106. return new static($history_id, $config);
  107. }
  108. /**
  109. * Generates a random hash
  110. */
  111. protected function _gen_hash()
  112. {
  113. // Some random magic!
  114. $rand = mt_rand();
  115. // Generate the hash using the hash_lnegth config value
  116. $hash = substr(md5($rand), 0, $this->_config['hash_length']);
  117. return $hash;
  118. }
  119. /**
  120. * Compresses the payload to be stored if configured to do so using the specified
  121. * format and level
  122. *
  123. * @return string the compressed payload using the configured options or the
  124. * unmodified payload string
  125. */
  126. protected function _compress($payload)
  127. {
  128. $return = $payload;
  129. if ($this->_config['compression']['active'] === true)
  130. {
  131. try
  132. {
  133. switch(strtoupper($this->_config['compression']['format']))
  134. {
  135. case 'DEFLATE':
  136. $return = @gzdeflate($return, $this->_config['compression']['level']);
  137. break;
  138. /*
  139. * Not yet supported as there is no gzdecode() PHP method as of yet
  140. case 'GZIP':
  141. $return = gzencode($return, $this->_config['compression']['level']);
  142. break;
  143. * */
  144. default:
  145. // This includes the ZLIB option
  146. $return = @gzcompress($return, $this->_config['compression']['level']);
  147. break;
  148. }
  149. }
  150. catch(Exception $e)
  151. {
  152. \Log::error($e->getMessage());
  153. }
  154. }
  155. return $return;
  156. }
  157. /**
  158. * Unompresses the given payload if configured to do so using the specified
  159. * format and level
  160. *
  161. * @return string the uncompressed payload using the configured options or the
  162. * unmodified payload string
  163. */
  164. protected function _uncompress($payload)
  165. {
  166. $return = $payload;
  167. if ($this->_config['compression']['active'] === true)
  168. {
  169. try
  170. {
  171. switch(strtoupper($this->_config['compression']['format']))
  172. {
  173. case 'DEFLATE':
  174. $return = @gzinflate($return);
  175. break;
  176. /*
  177. * Not yet supported as there is no gzdecode() PHP method as of yet
  178. case 'GZIP':
  179. $return = gzdecode($return);
  180. break;
  181. * */
  182. default:
  183. // This includes the ZLIB option
  184. $return = @gzuncompress($return);
  185. break;
  186. }
  187. }
  188. catch(Exception $e)
  189. {
  190. \Log::error($e->getMessage());
  191. }
  192. }
  193. return $return;
  194. }
  195. /**
  196. * Encodes the given payload if configured to so
  197. *
  198. * @return string The encoded payload using the \Crypt class or the unmodified
  199. * payload string
  200. */
  201. protected function _encode($payload)
  202. {
  203. $return = $payload;
  204. if ($this->_config['secure'])
  205. {
  206. try
  207. {
  208. $return = \Crypt::encode($return);
  209. }
  210. catch(Exception $e)
  211. {
  212. \Log::error($e->getMessage());
  213. }
  214. }
  215. return $return;
  216. }
  217. /**
  218. * Decodes the given payload if configured to so
  219. *
  220. * @return string The decoded payload using the \Crypt class or the unmodified
  221. * payload string
  222. */
  223. protected function _decode($payload)
  224. {
  225. $return = $payload;
  226. if ($this->_config['secure'])
  227. {
  228. try
  229. {
  230. $return = \Crypt::decode($return);
  231. }
  232. catch(Exception $e)
  233. {
  234. \Log::error($e->getMessage());
  235. }
  236. }
  237. return $return;
  238. }
  239. /**
  240. * Processes the entries array to output a payload string.
  241. * It does compression and encoding if needed.
  242. *
  243. * @return array of History_Entry objects
  244. */
  245. protected function _process_entries_to_payload(array $entries, $use_base64_encoding = false)
  246. {
  247. $return = '';
  248. if (!empty($entries))
  249. {
  250. // Serialize the entries array
  251. $return = @serialize($entries);
  252. // Encode the payload if needed
  253. $return = $this->_encode($return);
  254. // Compress the payload if needed
  255. $return = $this->_compress($return);
  256. // Encode data usign base64
  257. if ($use_base64_encoding)
  258. {
  259. $return = base64_encode($return);
  260. }
  261. }
  262. return $return;
  263. }
  264. /**
  265. * Processes the payload string to extract the entries array.
  266. * It does uncompression and unencoding if needed.
  267. *
  268. * @return array of History_Entry objects
  269. */
  270. protected function _process_payload_to_entries($payload, $use_base64_encoding = false)
  271. {
  272. $return = array();
  273. if ($payload != '')
  274. {
  275. // Decode data using base64
  276. if ($use_base64_encoding)
  277. {
  278. $payload = base64_decode($payload);
  279. }
  280. // Uncompress the payload if needed
  281. $payload = $this->_uncompress($payload);
  282. // Decode the payload if needed
  283. $payload = $this->_decode($payload);
  284. // Unserialize payload and verify if the entries array is indeed an array else
  285. // default to empty array
  286. is_array(($return = @unserialize($payload))) or $return = array();
  287. }
  288. return $return;
  289. }
  290. /**
  291. * Gets the driver name (type)
  292. *
  293. * @return string
  294. */
  295. abstract public function get_name();
  296. /**
  297. * Loads the entries using the driver's options
  298. *
  299. * @return array
  300. */
  301. abstract public function load();
  302. /**
  303. * Saves the entries using the driver's options
  304. *
  305. * @return bool
  306. */
  307. abstract public function save(array $entries);
  308. }