Skip to content

Commit

Permalink
Support modifying objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
wrobel committed Mar 14, 2011
1 parent abe4ac4 commit 6c6db9e
Show file tree
Hide file tree
Showing 15 changed files with 439 additions and 8 deletions.
5 changes: 5 additions & 0 deletions framework/Kolab_Cli/lib/Horde/Kolab/Cli/Module/Data.php
Expand Up @@ -141,6 +141,11 @@ public function run($cli, $options, $arguments, &$world)
(string) $world['storage']->getData($folder_name)->getStamp()
);
break;
case 'complete':
$data = $world['storage']->getData($folder_name);
$complete = $data->fetchComplete($arguments[3]);
$cli->writeln($complete[1]->toString(array('headers' => $complete[0])));
break;
case 'part':
$data = $world['storage']->getData($folder_name);
$part = $data->fetchPart($arguments[3], $arguments[4]);
Expand Down
68 changes: 67 additions & 1 deletion framework/Kolab_Storage/lib/Horde/Kolab/Storage/Data/Base.php
Expand Up @@ -190,13 +190,79 @@ public function create($object, $raw = false)
);
}

/**
* Modify an existing object.
*
* @param array $object The array that holds the updated object data.
* @param boolean $raw True if the data to be stored has been provided in
* raw format.
*
* @return NULL
*
* @throws Horde_Kolab_Storage_Exception In case an error occured while
* saving the data.
*/
public function modify($object, $raw = false)
{
if (!isset($object['uid'])) {
throw new Horde_Kolab_Storage_Exception(
'The provided object data contains no ID value!'
);
}
try {
$obid = $this->getBackendId($object['uid']);
} catch (Horde_Kolab_Storage_Exception $e) {
throw new Horde_Kolab_Storage_Exception(
sprintf(
Horde_Kolab_Storage_Translation::t(
'The message with ID %s does not exist. This probably means that the Kolab object has been modified by somebody else since you retrieved the object from the backend. Original error: %s'
),
$object['uid'],
0,
$e
)
);
}
$this->_driver->getParser()
->modify(
$this->_folder->getPath(),
$object,
$obid,
array(
'type' => $this->getType(),
'version' => $this->_version,
'raw' => $raw
)
);
}

/**
* Retrieves the complete message for the given UID.
*
* @param string $uid The message UID.
*
* @return array The message encapsuled as an array that contains a
* Horde_Mime_Headers and a Horde_Mime_Part object.
*/
public function fetchComplete($uid)
{
if (!method_exists($this->_driver, 'fetchComplete')) {
throw new Horde_Kolab_Storage_Exception(
'The backend does not support the "fetchComplete" method!'
);
}
return $this->_driver->fetchComplete(
$this->_folder->getPath(), $uid
);
}

/**
* Retrieves the body part for the given UID and mime part ID.
*
* @param string $uid The message UID.
* @param string $id The mime part ID.
*
* @return @TODO
* @return resource The message part as stream resource.
*/
public function fetchPart($uid, $id)
{
Expand Down
Expand Up @@ -238,4 +238,26 @@ public function createKolabPart($object, array $options)
return $kolab;
}

/**
* Modify a Kolab groupware object.
*
* @param Horde_Kolab_Storage_Driver_Modifiable $modifiable The modifiable object.
* @param array $object The updated object.
* @param array $options Additional options.
*
* @return NULL
*/
public function modify(
Horde_Kolab_Storage_Data_Modifiable $modifiable,
$object,
array $options
) {
$mime_id = $this->matchMimeId(
$options['type'], $modifiable->getStructure()->contentTypeMap()
);
$modifiable->setPart(
$mime_id, $this->createKolabPart($object, $options)
);
$modifiable->store();
}
}
@@ -0,0 +1,69 @@
<?php
/**
* A modifiable message object.
*
* PHP version 5
*
* @category Kolab
* @package Kolab_Storage
* @author Gunnar Wrobel <wrobel@pardus.de>
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
* @link http://pear.horde.org/index.php?package=Kolab_Storage
*/

/**
* A modifiable message object.
*
* Copyright 2011 The Horde Project (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
* @category Kolab
* @package Kolab_Storage
* @author Gunnar Wrobel <wrobel@pardus.de>
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
* @link http://pear.horde.org/index.php?package=Kolab_Storage
*/
class Horde_Kolab_Storage_Data_Modifiable
{
/**
* Constructor.
*
* @param Horde_Kolab_Storage_Driver $driver The backend driver.
* @param string $folder The folder this object belongs to.
* @param array $object The MIME parsed message elements.
*/
public function __construct($driver, $folder, $object)
{
$this->_driver = $driver;
$this->_folder = $folder;
$this->_object = $object;
}

public function getStructure()
{
return $this->_object[1];
}

public function setPart($mime_id, $new_part)
{
$this->_object[1]->getPart(0)->setContents('');
$this->_object[1]->alterPart($mime_id, $new_part);
$this->_object[1]->buildMimeIds();
}

public function store()
{
return $this->_driver->appendMessage(
$this->_folder,
$this->_object[1]->toString(
array(
'canonical' => true,
'stream' => true,
'headers' => $this->_object[0]
)
)
);
}
}
Expand Up @@ -111,6 +111,9 @@ public function fetch($folder, $obids, $options = array())
}
//@todo: deal with exceptions
$objects[$obid] = $this->getFormat()->parse($folder, $obid, $structure['structure'], $options);
if ($this->_driver->hasCatenateSupport()) {
$objects[$obid]['__structure'] = $structure['structure'];
}
$this->_fetchAttachments($objects[$obid], $folder, $obid, $options);
}
return $objects;
Expand Down Expand Up @@ -182,16 +185,42 @@ private function _completeOptions(&$options)
* format.
* </pre>
*
* @return NULL
* @return string The ID of the new object or true in case the backend does
* not support this return value.
*/
public function create($folder, $object, $options = array())
{
$this->_driver->appendMessage(
return $this->_driver->appendMessage(
$folder,
$this->createObject($object, $options)
);
}

/**
* Modify an existing object in the specified folder.
*
* @param string $folder The folder to use.
* @param array $object The object.
* @param string $obid The object ID in the backend.
* @param array $options Additional options for storing.
* <pre>
* 'type' - Required argument specifying the object type that should be
* stored.
* 'version' - Optional argument specifying the version of the object
* format.
* </pre>
*
* @return string The ID of the modified object or true in case the backend
* does not support this return value.
*/
public function modify($folder, $object, $obid, $options = array())
{
$modifiable = $this->_driver->getModifiable($folder, $obid, $object);
$new_uid = $this->_format->modify($modifiable, $object, $options);
$this->_driver->deleteMessages($folder, array($obid));
return $new_uid;
}

/**
* Create a new MIME representation for the object.
*
Expand Down
7 changes: 7 additions & 0 deletions framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver.php
Expand Up @@ -92,6 +92,13 @@ public function getId();
*/
public function getParameters();

/**
* Checks if the backend supports CATENATE.
*
* @return boolean True if the backend supports CATENATE.
*/
public function hasCatenateSupport();


/** List functionality */

Expand Down
26 changes: 26 additions & 0 deletions framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Base.php
Expand Up @@ -278,6 +278,32 @@ protected function decodeListKeys(array $list)
return $result;
}

/**
* Checks if the backend supports CATENATE.
*
* @return boolean True if the backend supports CATENATE.
*/
public function hasCatenateSupport()
{
return false;
}

/**
* Return a modifiable message object.
*
* @param string $folder The folder to access.
* @param string $obid The backend ID of the object to retrieve from the folder.
* @param array $object The object data.
*
* @return Horde_Kolab_Storage_Driver_Modifiable The modifiable message object.
*/
public function getModifiable($folder, $obid, $object)
{
return new Horde_Kolab_Storage_Data_Modifiable(
$this, $folder, $this->fetchComplete($folder, $obid)
);
}

/**
* Retrieve the namespace information for this connection.
*
Expand Down
35 changes: 35 additions & 0 deletions framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Cclient.php
Expand Up @@ -563,6 +563,41 @@ public function getUids($folder)
return $uids;
}

/**
* Retrieves a complete message.
*
* @param string $folder The folder to fetch the messages from.
* @param array $uid The message UID.
*
* @return array The message encapsuled as an array that contains a
* Horde_Mime_Headers and a Horde_Mime_Part object.
*/
public function fetchComplete($folder, $uid)
{
$this->select($folder);

$headers = @imap_fetchheader($this->getBackend(), $uid, FT_UID | FT_PREFETCHTEXT);
$body = @imap_body($this->getBackend(), $uid, FT_UID);
if ($headers && $body) {
return array(
Horde_Mime_Headers::parseHeaders($headers),
Horde_Mime_Part::parseMessage($body)
);
} else {
throw new Horde_Kolab_Storage_Exception(
sprintf(
Horde_Kolab_Storage_Translation::t(
"Failed fetching message %s in folder %s%s. Error: %s"
),
$this->_getBaseMbox(),
$uid,
$folder,
imap_last_error()
)
);
}
}

/**
* Retrieves the messages for the given message ids.
*
Expand Down
27 changes: 27 additions & 0 deletions framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Imap.php
Expand Up @@ -308,6 +308,33 @@ public function getUids($folder)
return $uids->ids;
}

/**
* Retrieves a complete message.
*
* @param string $folder The folder to fetch the messages from.
* @param array $uid The message UID.
*
* @return array The message encapsuled as an array that contains a
* Horde_Mime_Headers and a Horde_Mime_Part object.
*/
public function fetchComplete($folder, $uid)
{
$query = new Horde_Imap_Client_Fetch_Query();
$query->headerText();
$query->bodyText();

$ret = $this->getBackend()->fetch(
$folder,
$query,
array('ids' => new Horde_Imap_Client_Ids($uid))
);

return array(
$ret[$uid]->getHeaderText(0, Horde_Imap_Client_Data_Fetch::HEADER_PARSE),
Horde_Mime_Part::parseMessage($ret[$uid]->getBodyText())
);
}

/**
* Retrieves the messages for the given message ids.
*
Expand Down
17 changes: 17 additions & 0 deletions framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Mock.php
Expand Up @@ -621,6 +621,23 @@ public function fetchStructure($folder, $uids)
);
}

/**
* Retrieves a complete message.
*
* @param string $folder The folder to fetch the messages from.
* @param array $uid The message UID.
*
* @return array The message encapsuled as an array that contains a
* Horde_Mime_Headers and a Horde_Mime_Part object.
*/
public function fetchComplete($folder, $uid)
{
return $this->_data->fetchComplete(
$this->_convertToInternal($folder),
$uid
);
}

/**
* Retrieves a bodypart for the given message ID and mime part ID.
*
Expand Down

0 comments on commit 6c6db9e

Please sign in to comment.