Created
August 31, 2010 20:33
-
-
Save bradley-holt/559700 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Default | |
* | |
* @category Default | |
* @package Default_Model | |
* @copyright Copyright (c) 2005-2010 Found Line, Inc. (http://foundline.com/) | |
* @license http://foundline.com/legal/software-license New BSD License | |
*/ | |
/** | |
* Entry Data Mapper | |
* | |
* @category Default | |
* @package Default_Model | |
* @copyright Copyright (c) 2005-2010 Found Line, Inc. (http://foundline.com/) | |
* @license http://foundline.com/legal/software-license New BSD License | |
*/ | |
class Default_Model_EntryDataMapper | |
{ | |
/** | |
* @var string | |
*/ | |
private $_db; | |
/** | |
* @var string | |
*/ | |
private $_host; | |
/** | |
* @var Zend_Http_Client | |
*/ | |
private $_client; | |
/** | |
* @var Zend_Cache_Core | |
*/ | |
private $_cache; | |
/** | |
* Entry to JSON | |
* | |
* @param Default_Model_Entry $entry | |
* @return string | |
*/ | |
private function _entryToJson(Default_Model_Entry $entry) | |
{ | |
return Zend_Json::encode($entry->toArray()); | |
} | |
/** | |
* JSON to Entry | |
* | |
* @param string $json | |
* @return Default_Model_Entry | |
*/ | |
private function _jsonToEntry($json) | |
{ | |
return Default_Model_Entry::fromArray(Zend_Json::decode($json)); | |
} | |
/** | |
* Prepare Index By Category | |
* | |
* @param Default_Model_Category $category | |
* @param string $order | |
*/ | |
private function _prepareIndexByCategory(Default_Model_Category $category, $order) | |
{ | |
switch($order) { | |
case 'published': | |
$this->_client->setUri($this->_host . $this->_db . '/_design/category/_view/published'); | |
$this->_client->setParameterGet('descending', 'true'); | |
$this->_client->setParameterGet( | |
'startkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
'published' => array ( | |
'$t' => '9999-99-99T99:99:99-99:99', | |
), | |
) | |
) | |
); | |
$this->_client->setParameterGet( | |
'endkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
'published' => array ( | |
'$t' => '0000-00-00T00:00:00-00:00', | |
), | |
) | |
) | |
); | |
break; | |
case 'index': | |
$this->_client->setUri($this->_host . $this->_db . '/_design/category/_view/index'); | |
$this->_client->setParameterGet('descending', 'true'); | |
$this->_client->setParameterGet( | |
'startkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
'i$index' => array ( | |
'$t' => '999999', | |
), | |
) | |
) | |
); | |
$this->_client->setParameterGet( | |
'endkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
'i$index' => array ( | |
'$t' => null, | |
), | |
) | |
) | |
); | |
break; | |
case 'rank': | |
$this->_client->setUri($this->_host . $this->_db . '/_design/category/_view/rank'); | |
$this->_client->setParameterGet('descending', 'true'); | |
$this->_client->setParameterGet( | |
'startkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
're$rank' => array ( | |
'scheme' => $category->getScheme(), | |
'domain' => 'http://schemas.example.net/domain/2010#' . $category->getTerm(), | |
'$t' => '999999', | |
), | |
) | |
) | |
); | |
$this->_client->setParameterGet( | |
'endkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
're$rank' => array ( | |
'scheme' => $category->getScheme(), | |
'domain' => 'http://schemas.example.net/domain/2010#' . $category->getTerm(), | |
'$t' => null, | |
), | |
) | |
) | |
); | |
break; | |
case 'single': | |
$this->_client->setUri($this->_host . $this->_db . '/_design/category/_view/single'); | |
$this->_client->setParameterGet('descending', 'true'); | |
$this->_client->setParameterGet( | |
'startkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
) | |
) | |
); | |
$this->_client->setParameterGet( | |
'endkey', | |
Zend_Json::encode( | |
array ( | |
'category' => $category->toArray(), | |
) | |
) | |
); | |
break; | |
default; | |
throw new InvalidArgumentException('Invalid order name'); | |
} | |
} | |
/** | |
* Construct | |
* | |
* @param string $db | |
* @param string $host | |
* @param Zend_Http_Client $client | |
* @return Default_Model_EntryDataMapper | |
*/ | |
public function __construct( | |
$db, | |
$host = 'http://127.0.0.1:5984/', | |
Zend_Http_Client $client = null, | |
Zend_Cache_Core $cache = null | |
) | |
{ | |
$this->_db = $db; | |
$this->_host = $host; | |
if (null === $client) { | |
$client = new Zend_Http_Client(); | |
$client->setConfig( | |
array ( | |
'keepalive' => true, | |
) | |
); | |
} | |
$this->_client = $client; | |
$this->_cache = $cache; | |
} | |
/** | |
* Index By Category Paginator | |
* | |
* @param Default_Model_Category $category | |
* @param string $order | |
* @return Zend_Paginator | |
*/ | |
public function indexByCategoryPaginator(Default_Model_Category $category, $order) | |
{ | |
$entryPaginatorAdapter = new Default_Model_EntryPaginatorAdapter($this, $category, $order); | |
return new Zend_Paginator($entryPaginatorAdapter); | |
} | |
/** | |
* Index By Category Count | |
* | |
* @param Default_Model_Category $category | |
* @param string $order | |
* @return integer | |
*/ | |
public function indexByCategoryCount(Default_Model_Category $category, $order) | |
{ | |
$this->_prepareIndexByCategory($category, $order); | |
$this->_client->setParameterGet('reduce', 'true'); | |
$this->_client->setHeaders('Content-Type', 'application/json'); | |
$response = $this->_client->request(Zend_Http_Client::GET); | |
$this->_client->resetParameters(true); | |
switch ($response->getStatus()) { | |
case 200: | |
// Do nothing | |
break; | |
default: | |
//TODO: throw a more specific exception | |
throw new Exception('Could not GET index of entries by category'); | |
} | |
$responseArray = Zend_Json::decode($response->getBody()); | |
if (0 == count($responseArray['rows'])) { | |
return 0; | |
} | |
return (integer)$responseArray['rows'][0]['value']; | |
} | |
/** | |
* Index By Category | |
* | |
* @param Default_Model_Category $category | |
* @param string $order | |
* @param integer $offset | |
* @param integer $itemCountPerPage | |
* @return array <Default_Model_Entry> | |
*/ | |
public function indexByCategory(Default_Model_Category $category, $order, $offset = 0, $itemCountPerPage = -1) | |
{ | |
$this->_prepareIndexByCategory($category, $order); | |
$this->_client->setParameterGet('reduce', 'false'); | |
if ($offset > 0) { | |
$this->_client->setParameterGet('skip', $offset); | |
} | |
if ($itemCountPerPage >= 0) { | |
$this->_client->setParameterGet('limit', $itemCountPerPage); | |
} | |
$this->_client->setHeaders('Content-Type', 'application/json'); | |
$response = $this->_client->request(Zend_Http_Client::GET); | |
$this->_client->resetParameters(true); | |
$responseArray = Zend_Json::decode($response->getBody()); | |
switch ($response->getStatus()) { | |
case 200: | |
// Do nothing | |
break; | |
default: | |
//TODO: throw a more specific exception | |
throw new Exception('Could not GET index of entries by category'); | |
} | |
$entries = array (); | |
foreach ($responseArray['rows'] as $row) { | |
$entries[] = $this->get($row['id']); | |
} | |
return $entries; | |
} | |
/** | |
* Get | |
* | |
* @param string $id | |
* @return Default_Model_Entry | |
*/ | |
public function get($id) | |
{ | |
$uri = $this->_host . $this->_db . '/' . urlencode($id); | |
$this->_client->setUri($uri); | |
$this->_client->setHeaders('Content-Type', 'application/json'); | |
$cacheId = md5($uri); | |
/* @var $cachedEntry Default_Model_Entry */ | |
$cachedEntry = false; | |
if (null !== $this->_cache) { | |
$cachedEntry = $this->_cache->load($cacheId); | |
if (false !== $cachedEntry && null !== $cachedEntry->getRev()) { | |
$this->_client->setHeaders('If-None-Match', '"' . $cachedEntry->getRev() . '"'); | |
} | |
} | |
$response = $this->_client->request(Zend_Http_Client::GET); | |
$this->_client->resetParameters(true); | |
$entry = $cachedEntry; | |
switch ($response->getStatus()) { | |
case 200: | |
// OK | |
$entry = $this->_jsonToEntry($response->getBody()); | |
if (null !== $this->_cache) { | |
$this->_cache->save($entry, $cacheId); | |
} | |
break; | |
case 304: | |
// Not Modified | |
if (false === $cachedEntry) { | |
throw new Exception('Not modified but no cached entry available'); | |
} | |
$entry = $cachedEntry; | |
break; | |
case 404: | |
// Object Not Found | |
return null; | |
default: | |
//TODO: throw a more specific exception | |
throw new Exception('Could not GET entry'); | |
} | |
return $entry; | |
} | |
/** | |
* Post | |
* | |
* @param Default_Model_Entry $entry | |
* @return Default_Model_Entry | |
*/ | |
public function post(Default_Model_Entry $entry) | |
{ | |
$this->_client->setUri($this->_host . $this->_db); | |
$this->_client->setHeaders('Content-Type', 'application/json'); | |
$this->_client->setRawData($this->_entryToJson($entry)); | |
$response = $this->_client->request(Zend_Http_Client::POST); | |
$this->_client->resetParameters(true); | |
$responseArray = Zend_Json::decode($response->getBody()); | |
if (201 != $response->getStatus()) { | |
//TODO: throw a more specific exception | |
throw new Exception('Could not POST entry'); | |
} | |
$entry->setId($responseArray['id']); | |
$entry->setRev($responseArray['rev']); | |
if (null !== $this->_cache) { | |
$uri = $this->_host . $this->_db . '/' . urlencode($entry->getId()); | |
$cacheId = md5($uri); | |
$this->_cache->save($entry, $cacheId); | |
} | |
return $entry; | |
} | |
/** | |
* Put | |
* | |
* @param Default_Model_Entry $entry | |
* @return Default_Model_Entry | |
*/ | |
public function put(Default_Model_Entry $entry) | |
{ | |
$uri = $this->_host . $this->_db . '/' . urlencode($entry->getId()); | |
$this->_client->setUri($uri); | |
$this->_client->setHeaders('Content-Type', 'application/json'); | |
$this->_client->setRawData($this->_entryToJson($entry)); | |
$response = $this->_client->request(Zend_Http_Client::PUT); | |
$this->_client->resetParameters(true); | |
$responseArray = Zend_Json::decode($response->getBody()); | |
if (201 != $response->getStatus()) { | |
//TODO: throw a more specific exception | |
throw new Exception('Could not PUT entry'); | |
} | |
$entry->setId($responseArray['id']); | |
$entry->setRev($responseArray['rev']); | |
if (null !== $this->_cache) { | |
$cacheId = md5($uri); | |
$this->_cache->save($entry, $cacheId); | |
} | |
return $entry; | |
} | |
/** | |
* Delete | |
* | |
* @param Default_Model_Entry $entry | |
* @return Default_Model_Entry | |
*/ | |
public function delete(Default_Model_Entry $entry) | |
{ | |
$uri = $this->_host . $this->_db . '/' . urlencode($entry->getId()); | |
$this->_client->setUri($uri); | |
$this->_client->setHeaders('Content-Type', 'application/json'); | |
$this->_client->setParameterGet('rev', $entry->getRev()); | |
$response = $this->_client->request(Zend_Http_Client::DELETE); | |
$this->_client->resetParameters(true); | |
$responseArray = Zend_Json::decode($response->getBody()); | |
if (200 != $response->getStatus()) { | |
//TODO: throw a more specific exception | |
throw new Exception('Could not DELETE entry'); | |
} | |
$entry->setId($responseArray['id']); | |
$entry->setRev($responseArray['rev']); | |
if (null !== $this->_cache) { | |
$cacheId = md5($uri); | |
$this->_cache->remove($cacheId); | |
} | |
return $entry; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment