1: <?php
2: /**
3: * Horde Mnemo driver for the Kolab_Storage backend.
4: *
5: * Copyright 2004-2012 Horde LLC (http://www.horde.org/)
6: *
7: * See the enclosed file LICENSE for license information (ASL). If you
8: * did not receive this file, see http://www.horde.org/licenses/apache.
9: *
10: * @author Gunnar Wrobel <wrobel@pardus.de>
11: * @author Thomas Jarosch <thomas.jarosch@intra2net.com>
12: * @author Stuart Binge <omicron@mighty.co.za>
13: * @since Mnemo 2.0
14: * @package Mnemo
15: */
16: class Mnemo_Driver_Kolab extends Mnemo_Driver
17: {
18: /**
19: * The Kolab_Storage backend.
20: *
21: * @var Horde_Kolab_Storage
22: */
23: private $_kolab;
24:
25: /**
26: * The current notepad.
27: *
28: * @var Horde_Kolab_Storage_Data
29: */
30: private $_data;
31:
32: /**
33: * Construct a new Kolab storage object.
34: *
35: * @param string $notepad The name of the notepad to load/save notes from.
36: * @param array $params The connection parameters
37: *
38: * @throws InvalidArguementException
39: */
40: public function __construct($notepad, $params = array())
41: {
42: if (empty($params['storage'])) {
43: throw new InvalidArgumentException('Missing required storage handler.');
44: }
45: $this->_notepad = $notepad;
46: $this->_kolab = $params['storage'];
47: }
48:
49: /**
50: * Return the Kolab data handler for the current notepad.
51: *
52: * @return Horde_Kolab_Storage_Date The data handler.
53: */
54: private function _getData()
55: {
56: if (empty($this->_notepad)) {
57: throw new Mnemo_Exception(
58: 'The notepad has been left undefined but is required!'
59: );
60: }
61: if ($this->_data === null) {
62: $this->_data = $this->_getDataForNotepad($this->_notepad);
63: }
64: return $this->_data;
65: }
66:
67: /**
68: * Return the Kolab data handler for the specified notepad.
69: *
70: * @param string $notepad The notepad name.
71: *
72: * @return Horde_Kolab_Storage_Date The data handler.
73: */
74: private function _getDataForNotepad($notepad)
75: {
76: try {
77: return $this->_kolab->getData(
78: $GLOBALS['mnemo_shares']->getShare($notepad)->get('folder'),
79: 'note'
80: );
81: } catch (Horde_Kolab_Storage_Exception $e) {
82: throw new Mnemo_Exception(
83: sprintf(
84: 'Failed retrieving Kolab data for notepad %s: %s',
85: $notepad,
86: $e->getMessage()
87: ),
88: 0,
89: $e
90: );
91: }
92: }
93:
94: /**
95: * Retrieve one note from the store.
96: *
97: * @param string $noteId The ID of the note to retrieve.
98: * @param string $passphrase A passphrase with which this note was
99: * supposed to be encrypted.
100: *
101: * @return array The array of note attributes.
102: */
103: function get($noteId, $passphrase = null)
104: {
105: if ($this->_getData()->objectIdExists($noteId)) {
106: $note = $this->_getData()->getObject($noteId);
107: return $this->_buildNote($note, $passphrase);
108: } else {
109: throw new Horde_Exception_NotFound(_("Not Found"));
110: }
111: }
112:
113: /**
114: * Retrieve one note by UID.
115: *
116: * @param string $uid The UID of the note to retrieve.
117: * @param string $passphrase A passphrase with which this note was
118: * supposed to be encrypted.
119: *
120: * @return array The array of note attributes.
121: */
122: function getByUID($uid, $passphrase = null)
123: {
124: //@todo: search across notepads
125: return $this->get($uid, $passphrase);
126: }
127:
128: /**
129: * Add a note to the backend storage.
130: *
131: * @param string $desc The first line of the note.
132: * @param string $body The whole note body.
133: * @param string $category The category of the note.
134: * @param string $uid A Unique Identifier for the note.
135: * @param string $passphrase The passphrase to encrypt the note with.
136: *
137: * @return string The unique ID of the new note.
138: * @throws Mnemo_Exception
139: */
140: public function add($desc, $body, $category = '', $uid = null, $passphrase = null)
141: {
142: if (is_null($uid)) {
143: $uid = $this->_getData()->generateUid();
144: }
145:
146: if ($passphrase) {
147: $body = $this->_encrypt($body, $passphrase);
148: Mnemo::storePassphrase($uid, $passphrase);
149: }
150:
151: $object = array(
152: 'uid' => $uid,
153: 'summary' => $desc,
154: 'body' => $body,
155: 'categories' => $category,
156: );
157: $this->_getData()->create($object);
158:
159: // Log the creation of this item in the history log.
160: // @TODO: Inject the history driver
161: $history = $GLOBALS['injector']->getInstance('Horde_History');
162: $history->log('mnemo:' . $this->_notepad . ':' . $uid, array('action' => 'add'), true);
163:
164: return $uid;
165: }
166:
167: /**
168: * Modify an existing note.
169: *
170: * @param integer $noteId The note to modify.
171: * @param string $desc The description (long) of the note.
172: * @param string $body The description (long) of the note.
173: * @param string $category The category of the note.
174: * @param string $passphrase The passphrase to encrypt the note with.
175: *
176: * @return booelan
177: */
178: function modify($noteId, $desc, $body, $category = '', $passphrase = null)
179: {
180: if ($passphrase) {
181: $body = $this->_encrypt($body, $passphrase);
182: Mnemo::storePassphrase($uid, $passphrase);
183: }
184:
185: $this->_getData()->modify(
186: array(
187: 'uid' => $noteId,
188: 'summary' => $desc,
189: 'body' => $body,
190: 'categories' => $category,
191: )
192: );
193:
194: // Log the creation of this item in the history log.
195: // @TODO: Inject the history driver
196: $history = $GLOBALS['injector']->getInstance('Horde_History');
197: $history->log('mnemo:' . $this->_notepad . ':' . $uid, array('action' => 'modify'), true);
198:
199: return $uid;
200: }
201:
202: /**
203: * Move a note to a new notepad.
204: *
205: * @param string $noteId The note to move.
206: * @param string $newNotepad The new notepad.
207: *
208: * @return mixed True on success, PEAR_Error on failure.
209: */
210: function move($noteId, $newNotepad)
211: {
212: return $this->_getData()->move(
213: $noteId,
214: $GLOBALS['mnemo_shares']->getShare($newNotepad)->get('folder')
215: );
216: }
217:
218: /**
219: * Delete the specified note from the current notepad
220: *
221: * @param string $noteId The note to delete.
222: *
223: * @return NULL
224: */
225: function delete($noteId)
226: {
227: $note = $this->get($noteId);
228: $this->_getData()->delete($noteId);
229: $history = $GLOBALS['injector']->getInstance('Horde_History');
230: $history->log('mnemo:' . $this->_notepad . ':' . $note['uid'], array('action' => 'delete'), true);
231: }
232:
233: /**
234: * Delete all notes from the current notepad
235: *
236: * @return NULL
237: */
238: function deleteAll()
239: {
240: $this->_getData()->deleteAll();
241: }
242:
243: /**
244: * Retrieves all of the notes from $this->_notepad from the database.
245: *
246: * @return NULL
247: *
248: * @throws Mnemo_Exception
249: */
250: function retrieve()
251: {
252: $this->_memos = array();
253:
254: $note_list = $this->_getData()->getObjects();
255: if (empty($note_list)) {
256: return;
257: }
258:
259: foreach ($note_list as $note) {
260: $this->_memos[$note['uid']] = $this->_buildNote($note);
261: }
262: }
263:
264: /**
265: * Build a note based on data array
266: *
267: * @param array $note The data for the note
268: * @param string $passphrase A passphrase for decrypting a note
269: *
270: * @return array The converted data array representing the note
271: */
272: function _buildNote($note, $passphrase = null)
273: {
274: $note['memolist_id'] = $this->_notepad;
275: $note['memo_id'] = $note['uid'];
276:
277: $note['category'] = $note['categories'];
278: unset($note['categories']);
279:
280: $note['desc'] = $note['summary'];
281: unset($note['summary']);
282:
283: $note['encrypted'] = false;
284: $body = $note['body'];
285:
286: if (strpos($body, '-----BEGIN PGP MESSAGE-----') === 0) {
287: $note['encrypted'] = true;
288: if (empty($passphrase)) {
289: $passphrase = Mnemo::getPassphrase($note['memo_id']);
290: }
291: if (empty($passphrase)) {
292: $body = new Mnemo_Exception(_("This note has been encrypted."), Mnemo::ERR_NO_PASSPHRASE);
293: } else {
294: try {
295: $body = $this->_decrypt($body, $passphrase);
296: $body = $body->message;
297: } catch (Mnemo_Exception $e) {
298: $body = $e;
299: }
300: Mnemo::storePassphrase($row['memo_id'], $passphrase);
301: }
302: }
303: $note['body'] = $body;
304:
305: return $note;
306: }
307: }
308: