1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
28: class Horde_Kolab_Storage_Driver_Mock_Data
29: implements ArrayAccess
30: {
31:
32: const FLAG_DELETED = 1;
33:
34: 35: 36: 37: 38:
39: private $_data;
40:
41: 42: 43: 44: 45:
46: private $_selected;
47:
48: 49: 50: 51: 52: 53: 54: 55:
56: public function __construct($data)
57: {
58: if (isset($data['format'])) {
59: $format = $data['format'];
60: unset($data['format']);
61: switch ($format) {
62: case 'brief':
63: $data = $this->_convertBrief($data);
64: break;
65: default:
66: break;
67: }
68: }
69: $this->_data = $data;
70: }
71:
72: 73: 74: 75: 76: 77: 78: 79:
80: private function _convertBrief(array $data)
81: {
82: $result = array();
83: foreach ($data as $path => $element) {
84: if (!isset($element['p'])) {
85: $folder = array('permissions' => array('anyone' => 'alrid'));
86: } else {
87: $folder = array('permissions' => $element['p']);
88: }
89: if (isset($element['a'])) {
90: $folder['annotations'] = $element['a'];
91: }
92: if (isset($element['t'])) {
93: $folder['annotations'] = array(
94: '/shared/vendor/kolab/folder-type' => $element['t'],
95: );
96: }
97: if (isset($element['m'])) {
98: $folder['mails'] = $element['m'];
99: foreach ($element['m'] as $uid => $mail) {
100: if (isset($mail['structure'])) {
101: $folder['mails'][$uid]['structure'] = unserialize(
102: base64_decode(file_get_contents($mail['structure']))
103: );
104: }
105: if (isset($mail['parts'])) {
106: $folder['mails'][$uid]['structure']['parts'] = $mail['parts'];
107: }
108: if (isset($mail['file'])) {
109: $folder['mails'][$uid]['stream'] = fopen($mail['file'], 'r');
110: }
111: }
112: }
113: if (isset($element['s'])) {
114: $folder['status'] = $element['s'];
115: } else {
116: $folder['status'] = array(
117: 'uidvalidity' => time(),
118: 'uidnext' => !empty($folder['mails']) ? max(array_keys($folder['mails'])) + 1 : 1
119: );
120: }
121: $result[$path] = $folder;
122: }
123: return $result;
124: }
125:
126: 127: 128: 129: 130: 131: 132:
133: public function offsetGet($offset)
134: {
135: return $this->_data[$offset];
136: }
137:
138: 139: 140: 141: 142: 143: 144: 145:
146: public function offsetSet($offset, $value)
147: {
148: $this->_data[$offset] = $value;
149: }
150:
151: 152: 153: 154: 155: 156: 157:
158: public function offsetExists($offset)
159: {
160: return isset($this->_data[$offset]);
161: }
162:
163: 164: 165: 166: 167: 168: 169:
170: public function offsetUnset($offset)
171: {
172: unset($this->_data[$offset]);
173: }
174:
175: 176: 177: 178: 179:
180: public function arrayKeys()
181: {
182: return array_keys($this->_data);
183: }
184:
185: public function hasPermissions($folder)
186: {
187: return isset($this->_data[$folder]['permissions']);
188: }
189:
190: public function getPermissions($folder)
191: {
192: return $this->_data[$folder]['permissions'];
193: }
194:
195: public function hasUserPermissions($folder, $user)
196: {
197: return isset($this->_data[$folder]['permissions'][$user]);
198: }
199:
200: public function getUserPermissions($folder, $user)
201: {
202: return $this->_data[$folder]['permissions'][$user];
203: }
204:
205: public function setUserPermissions($folder, $user, $acl)
206: {
207: $this->_data[$folder]['permissions'][$user] = $acl;
208: }
209:
210: public function deleteUserPermissions($folder, $user)
211: {
212: unset($this->_data[$folder]['permissions'][$user]);
213: }
214:
215: public function hasAnnotation($folder, $annotation)
216: {
217: return isset($this->_data[$folder]['annotations'][$annotation]);
218: }
219:
220: public function getAnnotation($folder, $annotation)
221: {
222: return $this->_data[$folder]['annotations'][$annotation];
223: }
224:
225: public function setAnnotation($folder, $annotation, $value)
226: {
227: $this->_data[$folder]['annotations'][$annotation] = $value;
228: }
229:
230: public function deleteAnnotation($folder, $annotation)
231: {
232: unset($this->_data[$folder]['annotations'][$annotation]);
233: }
234:
235: public function select($folder)
236: {
237: if (!isset($this->_data[$folder])) {
238: throw new Horde_Kolab_Storage_Exception(
239: sprintf('Folder %s does not exist!', $folder)
240: );
241: }
242: if ($this->_selected !== $this->_data[$folder]) {
243: $this->_selected = &$this->_data[$folder];
244: }
245: }
246:
247: public function status($folder)
248: {
249: $this->select($folder);
250: return $this->_selected['status'];
251: }
252:
253: public function getUids($folder)
254: {
255: $this->select($folder);
256: if (empty($this->_selected['mails'])) {
257: return array();
258: } else {
259: return array_keys(
260: array_filter($this->_selected['mails'], array($this, '_notDeleted'))
261: );
262: }
263: }
264:
265: 266: 267: 268: 269: 270: 271:
272: public function _notDeleted($message)
273: {
274: return !isset($message['flags'])
275: || !($message['flags'] & self::FLAG_DELETED);
276: }
277:
278: public function fetchComplete($folder, $uid)
279: {
280: $this->select($folder);
281: if (isset($this->_selected['mails'][$uid]['stream'])) {
282: rewind($this->_selected['mails'][$uid]['stream']);
283: $msg = stream_get_contents($this->_selected['mails'][$uid]['stream']);
284: return array(
285: Horde_Mime_Headers::parseHeaders($msg),
286: Horde_Mime_Part::parseMessage($msg)
287: );
288: } else {
289: throw new Horde_Kolab_Storage_Exception(
290: sprintf(
291: 'No message %s in folder %s!',
292: $uid,
293: $folder
294: )
295: );
296: }
297: }
298:
299: 300: 301: 302: 303: 304: 305: 306: 307:
308: public function fetchStructure($folder, $uids)
309: {
310: $this->select($folder);
311: $result = array();
312: foreach ($uids as $uid) {
313: if (isset($this->_selected['mails'][$uid]['structure'])) {
314: $result[$uid]['structure'] = $this->_selected['mails'][$uid]['structure'];
315: } else if (isset($this->_selected['mails'][$uid]['stream'])) {
316: rewind($this->_selected['mails'][$uid]['stream']);
317: $result[$uid]['structure'] = Horde_Mime_Part::parseMessage(
318: stream_get_contents($this->_selected['mails'][$uid]['stream'])
319: );
320: } else {
321: throw new Horde_Kolab_Storage_Exception(
322: sprintf(
323: 'No message %s in folder %s!',
324: $uid,
325: $folder
326: )
327: );
328: }
329: }
330: return $result;
331: }
332:
333: 334: 335: 336: 337: 338: 339: 340: 341:
342: public function fetchBodypart($folder, $uid, $id)
343: {
344: $this->select($folder);
345: if (isset($this->_selected['mails'][$uid]['parts'][$id])) {
346: if (isset($this->_selected['mails'][$uid]['parts'][$id]['file'])) {
347: return fopen(
348: $this->_selected['mails'][$uid]['parts'][$id]['file'],
349: 'r'
350: );
351: }
352: } else if (isset($this->_selected['mails'][$uid]['stream'])) {
353: rewind($this->_selected['mails'][$uid]['stream']);
354: return Horde_Mime_Part::parseMessage(
355: stream_get_contents($this->_selected['mails'][$uid]['stream'])
356: )->getPart($id)->getContents();
357: } else {
358: throw new Horde_Kolab_Storage_Exception(
359: sprintf(
360: 'No such part %s for message uid %s in folder %s!',
361: $id,
362: $uid,
363: $folder
364: )
365: );
366: }
367: }
368:
369: 370: 371: 372: 373: 374: 375: 376: 377:
378: public function appendMessage($folder, $msg)
379: {
380: rewind($msg);
381: $this->select($folder);
382: $this->_selected['mails'][$this->_selected['status']['uidnext']] = array(
383: 'flags' => 0,
384: 'stream' => $msg,
385: );
386: return $this->_selected['status']['uidnext']++;
387: }
388:
389: public function deleteMessages($folder, $uids)
390: {
391: $this->select($folder);
392: foreach ($uids as $uid) {
393: if (isset($this->_selected['mails'][$uid]['flags'])) {
394: $this->_selected['mails'][$uid]['flags'] |= self::FLAG_DELETED;
395: } else {
396: $this->_selected['mails'][$uid]['flags'] = self::FLAG_DELETED;
397: }
398: }
399: }
400:
401: public function moveMessage($uid, $old_folder, $new_folder)
402: {
403: $this->select($old_folder);
404: if (!isset($this->_selected['mails'][$uid])) {
405: throw new Horde_Kolab_Storage_Exception(sprintf("No IMAP message %s!", $uid));
406: }
407: $mail = $this->_selected['mails'][$uid];
408: $this->deleteMessages($old_folder, array($uid));
409: $this->appendMessage($new_folder, $mail['stream']);
410: $this->expunge($old_folder);
411: }
412:
413: public function expunge($folder)
414: {
415: $this->select($folder);
416: $delete = array();
417: foreach ($this->_selected['mails'] as $uid => $mail) {
418: if (isset($mail['flags']) &&
419: ($mail['flags'] & self::FLAG_DELETED)) {
420: $delete[] = $uid;
421: }
422: }
423: foreach ($delete as $uid) {
424: unset($this->_selected['mails'][$uid]);
425: }
426: }
427: }