377 lines
11 KiB
PHP
377 lines
11 KiB
PHP
<?php
|
|
/**
|
|
* Horde Mnemo driver for the Kolab_Storage backend.
|
|
*
|
|
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file LICENSE for license information (ASL). If you
|
|
* did not receive this file, see http://www.horde.org/licenses/apache.
|
|
*
|
|
* @author Gunnar Wrobel <wrobel@pardus.de>
|
|
* @author Thomas Jarosch <thomas.jarosch@intra2net.com>
|
|
* @author Stuart Binge <omicron@mighty.co.za>
|
|
* @since Mnemo 2.0
|
|
* @package Mnemo
|
|
*/
|
|
class Mnemo_Driver_Kolab extends Mnemo_Driver
|
|
{
|
|
/**
|
|
* The Kolab_Storage backend.
|
|
*
|
|
* @var Horde_Kolab_Storage
|
|
*/
|
|
private $_kolab;
|
|
|
|
/**
|
|
* The current notepad.
|
|
*
|
|
* @var Horde_Kolab_Storage_Data
|
|
*/
|
|
private $_data;
|
|
|
|
/**
|
|
* Construct a new Kolab storage object.
|
|
*
|
|
* @param string $notepad The name of the notepad to load/save notes from.
|
|
* @param array $params The connection parameters
|
|
*
|
|
* @throws InvalidArguementException
|
|
*/
|
|
public function __construct($notepad, $params = array())
|
|
{
|
|
if (empty($params['storage'])) {
|
|
throw new InvalidArgumentException('Missing required storage handler.');
|
|
}
|
|
$this->_notepad = $notepad;
|
|
$this->_kolab = $params['storage'];
|
|
}
|
|
|
|
/**
|
|
* Retrieves all of the notes of the current notepad from the backend.
|
|
*
|
|
* @throws Mnemo_Exception
|
|
*/
|
|
public function retrieve()
|
|
{
|
|
$this->_memos = array();
|
|
|
|
try {
|
|
$note_list = $this->_getData()->getObjects();
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
if (empty($note_list)) {
|
|
return;
|
|
}
|
|
|
|
foreach ($note_list as $note) {
|
|
$this->_memos[Horde_Url::uriB64Encode($note['uid'])] = $this->_buildNote($note);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves one note from the backend.
|
|
*
|
|
* @param string $noteId The ID of the note to retrieve.
|
|
* @param string $passphrase A passphrase with which this note was
|
|
* supposed to be encrypted.
|
|
*
|
|
* @return array The array of note attributes.
|
|
* @throws Mnemo_Exception
|
|
* @throws Horde_Exception_NotFound
|
|
*/
|
|
public function get($noteId, $passphrase = null)
|
|
{
|
|
try {
|
|
$uid = Horde_Url::uriB64Decode($noteId);
|
|
if ($this->_getData()->objectIdExists($uid)) {
|
|
$note = $this->_getData()->getObject($uid);
|
|
return $this->_buildNote($note, $passphrase);
|
|
} else {
|
|
throw new Horde_Exception_NotFound();
|
|
}
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves one note from the backend by UID.
|
|
*
|
|
* @param string $uid The UID of the note to retrieve.
|
|
* @param string $passphrase A passphrase with which this note was
|
|
* supposed to be encrypted.
|
|
*
|
|
* @return array The array of note attributes.
|
|
* @throws Mnemo_Exception
|
|
* @throws Horde_Exception_NotFound
|
|
*/
|
|
public function getByUID($uid, $passphrase = null)
|
|
{
|
|
//@todo: search across notepads
|
|
// HACK: Use default notepad if no notepad is set.
|
|
// ActiveSync does not work without this
|
|
// as we don't search across all notepads yet.
|
|
if (empty($this->_notepad)) {
|
|
$this->_notepad = Mnemo::getDefaultNotepad();
|
|
}
|
|
|
|
return $this->get(Horde_Url::uriB64Encode($uid), $passphrase);
|
|
}
|
|
|
|
/**
|
|
* Adds a note to the backend storage.
|
|
*
|
|
* @param string $noteId The ID of the new note.
|
|
* @param string $desc The first line of the note.
|
|
* @param string $body The whole note body.
|
|
* @param string $tags The tags of the note.
|
|
*
|
|
* @return string The unique ID of the new note.
|
|
* @throws Mnemo_Exception
|
|
*/
|
|
protected function _add($noteId, $desc, $body, $tags)
|
|
{
|
|
$object = $this->_buildObject($noteId, $desc, $body, $tags);
|
|
|
|
try {
|
|
$this->_getData()->create($object);
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
|
|
return $object['uid'];
|
|
}
|
|
|
|
/**
|
|
* Modifies an existing note.
|
|
*
|
|
* @param string $noteId The note to modify.
|
|
* @param string $desc The first line of the note.
|
|
* @param string $body The whole note body.
|
|
* @param string $tags The tags of the note.
|
|
*
|
|
* @return string The note's UID.
|
|
* @throws Mnemo_Exception
|
|
*/
|
|
protected function _modify($noteId, $desc, $body, $tags)
|
|
{
|
|
|
|
$object = $this->_buildObject($noteId, $desc, $body, $tags);
|
|
|
|
try {
|
|
$this->_getData()->modify($object);
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
|
|
return $object['uid'];
|
|
}
|
|
|
|
/**
|
|
* Converts a note hash to a Kolab hash.
|
|
*
|
|
* @param string $noteId The note to modify.
|
|
* @param string $desc The first line of the note.
|
|
* @param string $body The whole note body.
|
|
* @param string $tags The tags of the note.
|
|
*
|
|
* @return object The Kolab hash.
|
|
*/
|
|
protected function _buildObject($noteId, $desc, $body, $tags)
|
|
{
|
|
$uid = Horde_Url::uriB64Decode($noteId);
|
|
$object = array(
|
|
'uid' => $uid,
|
|
'summary' => $desc,
|
|
'body' => $body,
|
|
);
|
|
$object['categories'] = $GLOBALS['injector']
|
|
->getInstance('Mnemo_Tagger')
|
|
->split($tags);
|
|
usort($object['categories'], 'strcoll');
|
|
|
|
return $object;
|
|
}
|
|
|
|
/**
|
|
* Moves a note to a new notepad.
|
|
*
|
|
* @param string $noteId The note to move.
|
|
* @param string $newNotepad The new notepad.
|
|
*
|
|
* @return string The note's UID.
|
|
* @throws Mnemo_Exception
|
|
*/
|
|
protected function _move($noteId, $newNotepad)
|
|
{
|
|
$uid = Horde_Url::uriB64Decode($noteId);
|
|
try {
|
|
$this->_getData()->move(
|
|
$uid,
|
|
$GLOBALS['mnemo_shares']->getShare($newNotepad)->get('folder')
|
|
);
|
|
$this->_getDataForNotepad($newNotepad)->synchronize();
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
return $uid;
|
|
}
|
|
|
|
/**
|
|
* Deletes a note permanently.
|
|
*
|
|
* @param array $note The note to delete.
|
|
*
|
|
* @return string The note's UID.
|
|
* @throws Mnemo_Exception
|
|
*/
|
|
protected function _delete($noteId)
|
|
{
|
|
$uid = Horde_Url::uriB64Decode($noteId);
|
|
try {
|
|
$this->_getData()->delete($uid);
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
return $uid;
|
|
}
|
|
|
|
/**
|
|
* Deletes all notes from the current notepad.
|
|
*
|
|
* @return array An array of uids that have been removed.
|
|
* @throws Mnemo_Exception
|
|
*/
|
|
protected function _deleteAll()
|
|
{
|
|
try {
|
|
$uids = $this->_getData()->getObjectIds();
|
|
$this->_getData()->deleteAll();
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception($e);
|
|
}
|
|
|
|
return $uids;
|
|
}
|
|
|
|
/**
|
|
* Return the Kolab data handler for the current notepad.
|
|
*
|
|
* @return Horde_Kolab_Storage_Data The data handler.
|
|
*/
|
|
protected function _getData()
|
|
{
|
|
if (empty($this->_notepad)) {
|
|
throw new LogicException(
|
|
'The notepad has been left undefined but is required!'
|
|
);
|
|
}
|
|
if ($this->_data === null) {
|
|
$this->_data = $this->_getDataForNotepad($this->_notepad);
|
|
}
|
|
return $this->_data;
|
|
}
|
|
|
|
/**
|
|
* Return the Kolab data handler for the specified notepad.
|
|
*
|
|
* @param string $notepad The notepad name.
|
|
*
|
|
* @return Horde_Kolab_Storage_Data The data handler.
|
|
*/
|
|
protected function _getDataForNotepad($notepad)
|
|
{
|
|
try {
|
|
return $this->_kolab->getData(
|
|
$GLOBALS['mnemo_shares']->getShare($notepad)->get('folder'),
|
|
'note'
|
|
);
|
|
} catch (Horde_Kolab_Storage_Exception $e) {
|
|
throw new Mnemo_Exception(
|
|
sprintf(
|
|
_("Failed retrieving Kolab data for notepad %s: %s"),
|
|
$notepad,
|
|
$e->getMessage()
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Build a note based on data array
|
|
*
|
|
* @param array $note The data for the note
|
|
* @param string $passphrase A passphrase for decrypting a note
|
|
*
|
|
* @return array The converted data array representing the note
|
|
*/
|
|
protected function _buildNote($note, $passphrase = null)
|
|
{
|
|
$encrypted = false;
|
|
$body = $note['body'];
|
|
$id = Horde_Url::uriB64Encode($note['uid']);
|
|
|
|
if (strpos($body, '-----BEGIN PGP MESSAGE-----') === 0) {
|
|
$encrypted = true;
|
|
if (empty($passphrase)) {
|
|
$passphrase = Mnemo::getPassphrase($id);
|
|
}
|
|
if (empty($passphrase)) {
|
|
$body = new Mnemo_Exception(_("This note has been encrypted."), Mnemo::ERR_NO_PASSPHRASE);
|
|
} else {
|
|
try {
|
|
$body = $this->_decrypt($body, $passphrase)->message;
|
|
} catch (Mnemo_Exception $e) {
|
|
$body = $e;
|
|
}
|
|
Mnemo::storePassphrase($id, $passphrase);
|
|
}
|
|
}
|
|
|
|
$tagger = $GLOBALS['injector']->getInstance('Mnemo_Tagger');
|
|
$tags = $tagger->getTags($note['uid'], 'note');
|
|
if (!empty($note['categories'])) {
|
|
usort($tags, 'strcoll');
|
|
if (array_diff($note['categories'], $tags)) {
|
|
$tagger->replaceTags(
|
|
$note['uid'],
|
|
$note['categories'],
|
|
$GLOBALS['registry']->getAuth(),
|
|
'note'
|
|
);
|
|
}
|
|
$tags = $note['categories'];
|
|
}
|
|
|
|
$result = array(
|
|
'memolist_id' => $this->_notepad,
|
|
'memo_id' => $id,
|
|
'uid' => $note['uid'],
|
|
'tags' => $tags,
|
|
'desc' => $note['summary'],
|
|
'encrypted' => $encrypted,
|
|
'body' => $body,
|
|
);
|
|
|
|
if (!empty($note['creation-date'])) {
|
|
$result['created'] = new Horde_Date($note['creation-date']);
|
|
}
|
|
if (!empty($note['last-modification-date'])) {
|
|
$result['modified'] = new Horde_Date($note['last-modification-date']);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Generates a local note ID.
|
|
*
|
|
* @return string A new note ID.
|
|
*/
|
|
protected function _generateId()
|
|
{
|
|
return Horde_Url::uriB64Encode($this->_getData()->generateUid());
|
|
}
|
|
}
|