1: <?php
2: /**
3: * A mock history driver.
4: *
5: * PHP version 5
6: *
7: * @category Horde
8: * @package History
9: * @author Gunnar Wrobel <wrobel@pardus.de>
10: * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
11: * @link http://pear.horde.org/index.php?package=History
12: */
13:
14: /**
15: * The Horde_History_Mock:: class provides a method of tracking changes in
16: * Horde objects, stored in memory.
17: *
18: * Copyright 2009-2012 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 Gunnar Wrobel <wrobel@pardus.de>
26: * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
27: * @link http://pear.horde.org/index.php?package=History
28: */
29: class Horde_History_Mock extends Horde_History
30: {
31: /**
32: * Our storage location.
33: *
34: * @var array
35: */
36: private $_data = array();
37:
38: /**
39: * The next id.
40: *
41: * @var int
42: */
43: private $_id = 1;
44:
45: /**
46: * Logs an event to an item's history log. Any other details about the
47: * event are passed in $attributes.
48: *
49: * @param Horde_History_Log $history The history item to add to.
50: * @param array $attributes The hash of name => value
51: * entries that describe this
52: * event.
53: * @param boolean $replaceAction If $attributes['action'] is
54: * already present in the item's
55: * history log, update that entry
56: * instead of creating a new one.
57: *
58: * @throws Horde_History_Exception
59: */
60: protected function _log(Horde_History_Log $history, array $attributes,
61: $replaceAction = false)
62: {
63: $values = array(
64: 'history_uid' => $history->uid,
65: 'history_ts' => $attributes['ts'],
66: 'history_who' => $attributes['who'],
67: 'history_desc' => isset($attributes['desc']) ? $attributes['desc'] : null,
68: 'history_action' => isset($attributes['action']) ? $attributes['action'] : null
69: );
70:
71: unset($attributes['ts'], $attributes['who'], $attributes['desc'], $attributes['action']);
72:
73: $values['history_extra'] = $attributes
74: ? serialize($attributes)
75: : null;
76:
77: /* If we want to replace an entry with the same action, try and find
78: * one. Track whether or not we succeed in $done, so we know whether
79: * or not to add the entry later. */
80: $done = false;
81: if ($replaceAction && !empty($values['history_action'])) {
82: foreach ($history as $entry) {
83: if (!empty($entry['action']) &&
84: $entry['action'] == $values['history_action']) {
85: $this->_data[$entry['id']] = $values;
86: $done = true;
87: break;
88: }
89: }
90: }
91:
92: /* If we're not replacing by action, or if we didn't find an entry to
93: * replace, insert a new row. */
94: if (!$done) {
95:
96: $this->_data[$this->_id] = $values;
97: $this->_id++;
98: }
99: }
100:
101: /**
102: * Returns a Horde_History_Log corresponding to the named history entry,
103: * with the data retrieved appropriately.
104: *
105: * @param string $guid The name of the history entry to retrieve.
106: *
107: * @return Horde_History_Log A Horde_History_Log object.
108: */
109: public function _getHistory($guid)
110: {
111: $result= array();
112: foreach ($this->_data as $id => $element) {
113: if ($element['history_uid'] == $guid) {
114: $element['history_id'] = $id;
115: $result[] = $element;
116: }
117: }
118: return new Horde_History_Log($guid, $result);
119: }
120:
121: /**
122: * Finds history objects by timestamp, and optionally filter on other
123: * fields as well.
124: *
125: * @param string $cmp The comparison operator (<, >, <=, >=, or =) to
126: * check the timestamps with.
127: * @param integer $ts The timestamp to compare against.
128: * @param array $filters An array of additional (ANDed) criteria.
129: * Each array value should be an array with 3
130: * entries:
131: * - field: the history field being compared (i.e.
132: * 'action').
133: * - op: the operator to compare this field with.
134: * - value: the value to check for (i.e. 'add').
135: * @param string $parent The parent history to start searching at. If
136: * non-empty, will be searched for with a LIKE
137: * '$parent:%' clause.
138: *
139: * @return array An array of history object ids, or an empty array if
140: * none matched the criteria.
141: *
142: * @throws Horde_History_Exception
143: */
144: public function _getByTimestamp($cmp, $ts, array $filters = array(),
145: $parent = null)
146: {
147: $result = array();
148:
149: foreach ($this->_data as $id => $element) {
150:
151: $ignore = false;
152:
153: switch ($cmp) {
154: case '<=':
155: case '=<':
156: if ($element['history_ts'] > $ts) {
157: $ignore = true;
158: };
159: break;
160: case '<':
161: if ($element['history_ts'] >= $ts) {
162: $ignore = true;
163: };
164: break;
165: case '=':
166: if ($element['history_ts'] != $ts) {
167: $ignore = true;
168: };
169: break;
170: case '>':
171: if ($element['history_ts'] <= $ts) {
172: $ignore = true;
173: };
174: break;
175: case '>=':
176: case '=>':
177: if ($element['history_ts'] < $ts) {
178: $ignore = true;
179: };
180: break;
181: default:
182: throw new Horde_History_Exception(sprintf("Comparison %s not implemented!", $cmp));
183: }
184:
185: if ($ignore) {
186: continue;
187: }
188:
189: /* Add additional filters, if there are any. */
190: if ($filters) {
191: foreach ($filters as $filter) {
192: if ($filter['op'] != '=') {
193: throw new Horde_History_Exception(sprintf("Comparison %s not implemented!", $filter['op']));
194: }
195: if ($element['history_' . $filter['field']] != $filter['value']) {
196: $ignore = true;
197: }
198: }
199: }
200:
201: if ($ignore) {
202: continue;
203: }
204:
205: if ($parent) {
206: if (substr($element['history_uid'], 0, strlen($parent) + 1) != $parent . ':') {
207: continue;
208: }
209: }
210:
211: $result[$element['history_uid']] = $id;
212: }
213: return $result;
214: }
215:
216: /**
217: * Removes one or more history entries by name.
218: *
219: * @param array $names The history entries to remove.
220: *
221: * @throws Horde_History_Exception
222: */
223: public function removeByNames(array $names)
224: {
225: if (!count($names)) {
226: return;
227: }
228:
229: $ids = array();
230: foreach ($this->_data as $id => $element) {
231: if (in_array($element['history_uid'], $names)) {
232: $ids[] = $id;
233: }
234: }
235:
236: foreach ($ids as $id) {
237: unset($this->_data[$id]);
238: }
239: }
240: }
241: