/framework/History/lib/Horde/History.php

https://github.com/finger2000/horde · PHP · 274 lines · 79 code · 21 blank · 174 comment · 12 complexity · ba88d49a2bbb4efa6b190c82e34dbb4c MD5 · raw file

  1. <?php
  2. /**
  3. * The Horde_History:: system.
  4. *
  5. * PHP version 5
  6. *
  7. * @category Horde
  8. * @package History
  9. * @author Chuck Hagenbuch <chuck@horde.org>
  10. * @author Gunnar Wrobel <wrobel@pardus.de>
  11. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  12. * @link http://pear.horde.org/index.php?package=History
  13. */
  14. /**
  15. * The Horde_History:: class provides a method of tracking changes in Horde
  16. * objects, stored in a SQL table.
  17. *
  18. * Copyright 2003-2011 Horde LLC (http://www.horde.org/)
  19. *
  20. * See the enclosed file COPYING for license information (LGPL). If you
  21. * did not receive this file, see http://www.horde.org/licenses/lgpl21.
  22. *
  23. * @category Horde
  24. * @package History
  25. * @author Chuck Hagenbuch <chuck@horde.org>
  26. * @author Gunnar Wrobel <wrobel@pardus.de>
  27. * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
  28. * @link http://pear.horde.org/index.php?package=History
  29. */
  30. abstract class Horde_History
  31. {
  32. /**
  33. * The current user.
  34. *
  35. * @var string
  36. */
  37. protected $_auth;
  38. /**
  39. * Our log handler.
  40. *
  41. * @var Horde_Log_Logger
  42. */
  43. protected $_logger;
  44. /**
  45. * Constructor.
  46. *
  47. * @param string $auth The current user.
  48. */
  49. public function __construct($auth)
  50. {
  51. $this->_auth = $auth;
  52. }
  53. /**
  54. * Set the log handler.
  55. *
  56. * @param Horde_Log_Logger $logger The log handler.
  57. *
  58. * @return NULL
  59. */
  60. public function setLogger(Horde_Log_Logger $logger)
  61. {
  62. $this->_logger = $logger;
  63. }
  64. /**
  65. * Logs an event to an item's history log.
  66. *
  67. * The item must be uniquely identified by $guid. Any other details about
  68. * the event are passed in $attributes. Standard suggested attributes are:
  69. * - who: The id of the user that performed the action (will be added
  70. * automatically if not present).
  71. * - ts: Timestamp of the action (this will be added automatically if it
  72. * is not present).
  73. *
  74. * @param string $guid The unique identifier of the entry to add
  75. * to.
  76. * @param array $attributes The hash of name => value entries that
  77. * describe this event.
  78. * @param boolean $replaceAction If $attributes['action'] is already
  79. * present in the item's history log, update
  80. * that entry instead of creating a new one.
  81. *
  82. * @throws Horde_History_Exception
  83. */
  84. public function log($guid, array $attributes = array(),
  85. $replaceAction = false)
  86. {
  87. if (!is_string($guid)) {
  88. throw new Horde_History_Exception('The guid needs to be a string!');
  89. }
  90. $history = $this->getHistory($guid);
  91. if (!isset($attributes['who'])) {
  92. $attributes['who'] = $this->_auth;
  93. }
  94. if (!isset($attributes['ts'])) {
  95. $attributes['ts'] = time();
  96. }
  97. $this->_log($history, $attributes, $replaceAction);
  98. }
  99. /**
  100. * Logs an event to an item's history log. Any other details about the
  101. * event are passed in $attributes.
  102. *
  103. * @param Horde_History_Log $history The history item to add to.
  104. * @param array $attributes The hash of name => value
  105. * entries that describe this
  106. * event.
  107. * @param boolean $replaceAction If $attributes['action'] is
  108. * already present in the item's
  109. * history log, update that entry
  110. * instead of creating a new one.
  111. *
  112. * @throws Horde_History_Exception
  113. */
  114. abstract protected function _log(Horde_History_Log $history,
  115. array $attributes, $replaceAction = false);
  116. /**
  117. * Returns a Horde_History_Log corresponding to the named history entry,
  118. * with the data retrieved appropriately.
  119. *
  120. * @param string $guid The name of the history entry to retrieve.
  121. *
  122. * @return Horde_History_Log A Horde_History_Log object.
  123. *
  124. * @throws Horde_History_Exception
  125. */
  126. public function getHistory($guid)
  127. {
  128. if (!is_string($guid)) {
  129. throw new Horde_History_Exception('The guid needs to be a string!');
  130. }
  131. return $this->_getHistory($guid);
  132. }
  133. /**
  134. * Returns a Horde_History_Log corresponding to the named history entry,
  135. * with the data retrieved appropriately.
  136. *
  137. * @param string $guid The name of the history entry to retrieve.
  138. *
  139. * @return Horde_History_Log A Horde_History_Log object.
  140. */
  141. abstract public function _getHistory($guid);
  142. /**
  143. * Finds history objects by timestamp, and optionally filter on other
  144. * fields as well.
  145. *
  146. * @param string $cmp The comparison operator (<, >, <=, >=, or =) to
  147. * check the timestamps with.
  148. * @param integer $ts The timestamp to compare against.
  149. * @param array $filters An array of additional (ANDed) criteria.
  150. * Each array value should be an array with 3
  151. * entries:
  152. * - field: the history field being compared (i.e.
  153. * 'action').
  154. * - op: the operator to compare this field with.
  155. * - value: the value to check for (i.e. 'add').
  156. * @param string $parent The parent history to start searching at. If
  157. * non-empty, will be searched for with a LIKE
  158. * '$parent:%' clause.
  159. *
  160. * @return array An array of history object ids, or an empty array if
  161. * none matched the criteria.
  162. *
  163. * @throws Horde_History_Exception
  164. */
  165. public function getByTimestamp($cmp, $ts, array $filters = array(),
  166. $parent = null)
  167. {
  168. if (!is_string($cmp)) {
  169. throw new Horde_History_Exception('The comparison operator needs to be a string!');
  170. }
  171. if (!is_integer($ts)) {
  172. throw new Horde_History_Exception('The timestamp needs to be an integer!');
  173. }
  174. return $this->_getByTimestamp($cmp, $ts, $filters, $parent);
  175. }
  176. /**
  177. * Finds history objects by timestamp, and optionally filter on other
  178. * fields as well.
  179. *
  180. * @param string $cmp The comparison operator (<, >, <=, >=, or =) to
  181. * check the timestamps with.
  182. * @param integer $ts The timestamp to compare against.
  183. * @param array $filters An array of additional (ANDed) criteria.
  184. * Each array value should be an array with 3
  185. * entries:
  186. * - field: the history field being compared (i.e.
  187. * 'action').
  188. * - op: the operator to compare this field with.
  189. * - value: the value to check for (i.e. 'add').
  190. * @param string $parent The parent history to start searching at. If
  191. * non-empty, will be searched for with a LIKE
  192. * '$parent:%' clause.
  193. *
  194. * @return array An array of history object ids, or an empty array if
  195. * none matched the criteria.
  196. *
  197. * @throws Horde_History_Exception
  198. */
  199. abstract public function _getByTimestamp($cmp, $ts,
  200. array $filters = array(),
  201. $parent = null);
  202. /**
  203. * Gets the timestamp of the most recent change to $guid.
  204. *
  205. * @param string $guid The name of the history entry to retrieve.
  206. * @param string $action An action: 'add', 'modify', 'delete', etc.
  207. *
  208. * @return integer The timestamp, or 0 if no matching entry is found.
  209. *
  210. * @throws Horde_History_Exception If the input parameters are not of type string.
  211. */
  212. public function getActionTimestamp($guid, $action)
  213. {
  214. if (!is_string($guid) || !is_string($action)) {
  215. throw new Horde_History_Exception('$guid and $action need to be strings!');
  216. }
  217. try {
  218. $history = $this->getHistory($guid);
  219. } catch (Horde_History_Exception $e) {
  220. return 0;
  221. }
  222. $last = 0;
  223. foreach ($history as $entry) {
  224. if (($entry['action'] == $action) && ($entry['ts'] > $last)) {
  225. $last = $entry['ts'];
  226. }
  227. }
  228. return (int)$last;
  229. }
  230. /**
  231. * Remove one or more history entries by parent.
  232. *
  233. * @param string $parent The parent name to remove.
  234. *
  235. * @throws Horde_History_Exception
  236. */
  237. public function removeByParent($parent)
  238. {
  239. /* Remove entries 100 at a time. */
  240. $all = array_keys($this->getByTimestamp('>', 0, array(), $parent));
  241. while (count($d = array_splice($all, 0, 100)) > 0) {
  242. $this->removebyNames($d);
  243. }
  244. }
  245. /**
  246. * Removes one or more history entries by name.
  247. *
  248. * @param array $names The history entries to remove.
  249. *
  250. * @throws Horde_History_Exception
  251. */
  252. abstract public function removeByNames(array $names);
  253. }