Source for file OnpubArticles.php
Documentation is available at OnpubArticles.php
* Manage articles in an Onpub database.
* This class contains the methods to manage the data contained in an
* {@link http://onpub.com/pdfs/onpub_schema.pdf OnpubArticles table}.
* @author {@link mailto:corey@onpub.com Corey H.M. Taylor}
* @copyright Onpub (TM). Copyright 2012, Onpub.com.
* {@link http://onpub.com/}
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
* Controls whether or not the methods in this class use transactions when
* they access the database.
* By default, this is set to TRUE and database transactions will be used
* where necessary. Set this to FALSE if you want to manage transactions
* Connect to an Onpub database.
* All the methods in this class which query the database use the database
* connection provided by the PDO object required by this constructor.
* Currently, Onpub only supports MySQL as a database for storing content.
* Therefore, when constructing the PDO object, only the
* {@link PHP_MANUAL#ref.pdo-mysql PDO_MYSQL} driver is supported
* as a PDO {@link PHP_MANUAL#ref.pdo-mysql.connection data source}.
* All the methods in this class require the
* {@link http://onpub.com/pdfs/onpub_schema.pdf Onpub schema}
* to be installed in the PDO-connected database. The {@link OnpubDatabase}
* class contains methods to manage the Onpub schema. The Onpub
* schema can also be installed by clicking the "Install the schema" link
* once logged in to the Onpub web interface. The schema generally only has
* to be installed once per database.
* @param PDO $pdo A {@link PHP_MANUAL#function.pdo-construct PHP Data Object}.
* @param bool $enableTransactions If TRUE (the default), the methods in
* this class that use database transactions will do so. If FALSE, methods
* that by default use transactions, will not. Only pass FALSE to this
* argument if you are managing transactions yourself.
function __construct(PDO $pdo, $enableTransactions =
TRUE)
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, TRUE);
* Get the total number of articles in the database.
* @param int $sectionID Get the total number of articles in a section
public function count($sectionID =
NULL)
$query =
$this->countQuery($sectionID);
$result =
$this->pdo->query($query);
if (!($row =
$result->fetch(PDO::FETCH_ASSOC))) {
private function countQuery($sectionID =
NULL)
return "SELECT COUNT(articles.ID) AS count FROM OnpubArticles AS articles LEFT JOIN OnpubSAMaps as samaps ON articles.ID = samaps.articleID WHERE sectionID = $sectionID";
return "SELECT COUNT(articles.ID) AS count FROM OnpubArticles AS articles";
* Delete an article from the database.
* @param int $ID ID of the article to delete.
* @return int 1 if the article was deleted, 0 if the article does not exist in the database.
$status =
$this->pdo->beginTransaction();
$oaamaps->delete($ID, NULL);
catch
(PDOException $e) {
$osamaps->delete(NULL, $ID);
catch
(PDOException $e) {
$stmt =
$this->pdo->prepare("DELETE FROM OnpubArticles WHERE ID = :ID");
$stmt->bindParam(':ID', $ID);
$result =
$stmt->execute();
$status =
$this->pdo->commit();
return $stmt->rowCount();
* Search for articles in the database.
* @param string $keywords Keyword(s) to search for.
* @return array All the articles which were found as an array of {@link OnpubArticle} objects.
public function search($keywords, OnpubQueryOptions $queryOptions =
NULL)
if ($queryOptions ===
NULL)
$query =
$this->searchQuery($keywords, $queryOptions);
$result =
$this->pdo->query($query);
$rows =
$result->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$currIID =
$row["imageID"];
$currAIID =
$row["authorImageID"];
if ($lastAID !=
$currAID) {
$author->ID =
$row["authorID"];
$author->imageID =
$currAIID;
$author->givenNames =
$row["givenNames"];
$author->familyName =
$row["familyName"];
$author->displayAs =
$row["displayAs"];
$author->setCreated(new DateTime($row["authorCreated"]));
$author->setModified(new DateTime($row["authorModified"]));
$author =
$authors[($s -
1)];
$image->websiteID =
$row["authorImageWebsiteID"];
$image->fileName =
$row["authorImageFileName"];
$image->description =
$row["authorImageDescription"];
$image->setCreated(new DateTime($row["authorImageCreated"]));
$image->setModified(new DateTime($row["authorImageModified"]));
if ($queryOptions->includeContent) {
$content =
$row["content"];
$currArticle->ID =
$currAID;
$currArticle->imageID =
$currIID;
$currArticle->title =
$row["title"];
$currArticle->content =
$content;
$currArticle->url =
$row["url"];
$currArticle->setCreated(new DateTime($row["created"]));
$currArticle->setModified(new DateTime($row["modified"]));
$image->websiteID =
$row["websiteID"];
$image->fileName =
$row["fileName"];
$image->description =
$row["description"];
$image->url =
$row["articleImageURL"];
$image->setCreated(new DateTime($row["imageCreated"]));
$image->setModified(new DateTime($row["imageModified"]));
$currArticle->image =
$image;
if ($lastArticle !=
NULL) {
if ($lastArticle->ID ==
$currArticle->ID) {
$lastArticle->authors =
$authors;
$articles[] =
$currArticle;
$currArticle->authors =
$authors;
$articles[] =
$currArticle;
$currArticle->authors =
$authors;
if ($lastArticle !=
NULL) {
if ($lastArticle->ID !=
$currArticle->ID) {
$lastArticle =
$currArticle;
$lastArticle =
$currArticle;
private function searchQuery($keywords, OnpubQueryOptions $queryOptions =
NULL)
if ($queryOptions ===
NULL)
if ($queryOptions->fullTextSearch) {
$where =
"WHERE articles.title LIKE '%$keywords%' OR authors.displayAS LIKE '%$keywords%' OR articles.created LIKE '%$keywords%' OR articles.modified LIKE '%$keywords%' OR articles.ID LIKE '%$keywords%' OR articles.content LIKE '%$keywords%' OR articles.url LIKE '%$keywords%'";
$where =
"WHERE articles.title LIKE '%$keywords%' OR authors.displayAS LIKE '%$keywords%' OR articles.created LIKE '%$keywords%' OR articles.modified LIKE '%$keywords%' OR articles.ID LIKE '%$keywords%' OR articles.url LIKE '%$keywords%'";
if ($queryOptions->orderBy) {
$orderBy =
$queryOptions->orderBy;
if ($queryOptions->order) {
$order =
$queryOptions->order;
if ($queryOptions->includeContent) {
$articleColumns =
"articles.ID, articles.imageID, title, content, articles.url, articles.created, articles.modified";
$articleColumns =
"articles.ID, articles.imageID, title, articles.url, articles.created, articles.modified";
if ($queryOptions->dateLimit) {
$dateLimit =
$queryOptions->dateLimit->format('Y-m-d H:i:s');
$where .=
" AND articles.created <= '$dateLimit'";
$where =
"WHERE articles.created <= '$dateLimit'";
"SELECT $articleColumns, articleimages.websiteID, articleimages.fileName, articleimages.description, articleimages.url AS articleImageURL, articleimages.created AS imageCreated, articleimages.modified AS imageModified, authors.ID AS authorID, authors.imageID AS authorImageID, givenNames, familyName, displayAs, authors.created AS authorCreated, authors.modified AS authorModified, authorimages.websiteID AS authorImageWebsiteID, authorimages.fileName AS authorImageFileName, authorimages.description AS authorImageDescription, authorimages.url AS authorImageURL, authorimages.created AS authorImageCreated, authorimages.modified AS authorImageModified FROM OnpubArticles AS articles LEFT JOIN OnpubImages AS articleimages ON articles.imageID = articleimages.ID LEFT JOIN OnpubAAMaps AS aamaps ON articles.ID = aamaps.articleID LEFT JOIN OnpubAuthors AS authors ON aamaps.authorID = authors.ID LEFT JOIN OnpubImages AS authorimages ON authors.imageID = authorimages.ID $where ORDER BY articles.$orderBy $order";
return "SELECT $articleColumns, articleimages.websiteID, articleimages.fileName, articleimages.description, articleimages.url AS articleImageURL, articleimages.created AS imageCreated, articleimages.modified AS imageModified, authors.ID AS authorID, authors.imageID AS authorImageID, givenNames, familyName, displayAs, authors.created AS authorCreated, authors.modified AS authorModified, authorimages.websiteID AS authorImageWebsiteID, authorimages.fileName AS authorImageFileName, authorimages.description AS authorImageDescription, authorimages.url AS authorImageURL, authorimages.created AS authorImageCreated, authorimages.modified AS authorImageModified FROM OnpubArticles AS articles LEFT JOIN OnpubImages AS articleimages ON articles.imageID = articleimages.ID LEFT JOIN OnpubAAMaps AS aamaps ON articles.ID = aamaps.articleID LEFT JOIN OnpubAuthors AS authors ON aamaps.authorID = authors.ID LEFT JOIN OnpubImages AS authorimages ON authors.imageID = authorimages.ID $where ORDER BY articles.$orderBy";
return "SELECT $articleColumns, articleimages.websiteID, articleimages.fileName, articleimages.description, articleimages.url AS articleImageURL, articleimages.created AS imageCreated, articleimages.modified AS imageModified, authors.ID AS authorID, authors.imageID AS authorImageID, givenNames, familyName, displayAs, authors.created AS authorCreated, authors.modified AS authorModified, authorimages.websiteID AS authorImageWebsiteID, authorimages.fileName AS authorImageFileName, authorimages.description AS authorImageDescription, authorimages.url AS authorImageURL, authorimages.created AS authorImageCreated, authorimages.modified AS authorImageModified FROM OnpubArticles AS articles LEFT JOIN OnpubImages AS articleimages ON articles.imageID = articleimages.ID LEFT JOIN OnpubAAMaps AS aamaps ON articles.ID = aamaps.articleID LEFT JOIN OnpubAuthors AS authors ON aamaps.authorID = authors.ID LEFT JOIN OnpubImages AS authorimages ON authors.imageID = authorimages.ID $where";
* Get a single article from the database.
* @param int $ID ID of the article to get.
* @param OnpubQueryOptions $queryOptions Optional database query options.
* @return OnpubArticle An {@link OnpubArticle} object. NULL if the article does not exist in the database.
public function get($ID, OnpubQueryOptions $queryOptions =
NULL)
if ($queryOptions ===
NULL)
$query =
$this->getQuery($ID, $queryOptions);
$result =
$this->pdo->query($query);
$rows =
$result->fetchAll(PDO::FETCH_ASSOC);
if ($queryOptions->includeContent) {
$content =
$row["content"];
$article->ID =
$row["ID"];
$article->imageID =
$row["imageID"];
$article->title =
$row["title"];
$article->content =
$content;
$article->url =
$row["url"];
$article->setCreated(new DateTime($row["created"]));
$article->setModified(new DateTime($row["modified"]));
if (!$queryOptions->includeAuthors) {
$image->ID =
$row["imageID"];
$image->websiteID =
$row["websiteID"];
$image->fileName =
$row["fileName"];
$image->description =
$row["description"];
$image->setCreated(new DateTime($row["imageCreated"]));
$image->setModified(new DateTime($row["imageModified"]));
$article->image =
$image;
foreach ($rows as $row) {
$authorID =
$row["authorID"];
$author->imageID =
$row["authorImageID"];
$author->givenNames =
$row["givenNames"];
$author->familyName =
$row["familyName"];
$author->displayAs =
$row["displayAs"];
$author->setCreated(new DateTime($row["authorCreated"]));
$author->setModified(new DateTime($row["authorModified"]));
if (isset
($authorsassoc["$authorID"])) {
$author =
$authorsassoc["$authorID"];
$authorsassoc["$authorID"] =
$author;
if ($row["authorImageID"]) {
$image->ID =
$row["authorImageID"];
$image->websiteID =
$row["authorImageWebsiteID"];
$image->fileName =
$row["authorImageFileName"];
$image->description =
$row["authorImageDescription"];
$image->setCreated(new DateTime($row["authorImageCreated"]));
$image->setModified(new DateTime($row["authorImageModified"]));
$authors =
$article->authors;
foreach ($authors as $a) {
if ($a->ID ==
$author->ID) {
$article->authors =
$authors;
private function getQuery($ID, OnpubQueryOptions $queryOptions =
NULL)
if ($queryOptions ===
NULL)
if ($queryOptions->orderBy) {
$orderBy =
$queryOptions->orderBy;
$orderBy =
"articles.$orderBy";
if ($queryOptions->order) {
$order =
$queryOptions->order;
$where =
"WHERE articles.ID = $ID";
if ($queryOptions->dateLimit) {
$dateLimit =
$queryOptions->dateLimit->format('Y-m-d H:i:s');
$where .=
" AND articles.created <= '$dateLimit'";
if ($queryOptions->includeContent) {
$articleColumns =
"articles.ID, articles.imageID, title, content, " .
"articles.url, articles.created, articles.modified";
$articleColumns =
"articles.ID, articles.imageID, title, articles.url, " .
"articles.created, articles.modified";
if ($queryOptions->includeAuthors) {
return "SELECT $articleColumns, articleimages.websiteID, " .
"articleimages.fileName, articleimages.description, " .
"articleimages.url AS articleImageURL, articleimages.created AS " .
"imageCreated, articleimages.modified AS imageModified, " .
"authors.ID AS authorID, authors.imageID AS authorImageID, " .
"givenNames, familyName, displayAs, authors.created AS " .
"authorCreated, authors.modified AS authorModified, " .
"authorimages.websiteID AS authorImageWebsiteID, " .
"authorimages.fileName AS authorImageFileName, " .
"authorimages.description AS authorImageDescription, " .
"authorimages.url AS authorImageURL, authorimages.created AS " .
"authorImageCreated, authorimages.modified AS authorImageModified " .
"FROM OnpubArticles AS articles LEFT JOIN OnpubImages AS " .
"articleimages ON articles.imageID = articleimages.ID " .
"LEFT JOIN OnpubAAMaps AS aamaps ON articles.ID = aamaps.articleID " .
"LEFT JOIN OnpubAuthors AS authors ON aamaps.authorID = authors.ID " .
"LEFT JOIN OnpubImages AS authorimages ON " .
"authors.imageID = authorimages.ID $where ORDER BY $orderBy $order";
return "SELECT $articleColumns FROM OnpubArticles as articles WHERE ID = $ID";
* Get the ID of an article in the database.
* Looks for an article in the database with the same title and content.
* If there's a match, the ID of the article is returned.
* @param OnpubArticle $article Article whose ID you want to get.
* @return int The ID of the article. NULL if the article does not exist in the database.
public function getID(OnpubArticle $article)
$stmt =
$this->pdo->prepare("SELECT ID FROM OnpubArticles WHERE title = :title AND content = :content");
$stmt->bindParam(':title', $title);
$stmt->bindParam(':content', $content);
$result =
$stmt->execute();
if (($row =
$stmt->fetch(PDO::FETCH_ASSOC))) {
* Insert new article(s) into the database.
* @param mixed $articles A single {@link OnpubArticle} object or an array of {@link OnpubArticle} objects (to insert multiple articles at a time).
* @return mixed The ID(s) of the new article(s). An int will be returned if a single article was inserted. An array of ints will be returned if multiple articles were inserted.
* @throws PDOException if there's a database error.
public function insert($articles)
$articles =
array ($articles);
$status =
$this->pdo->beginTransaction();
$stmt =
$this->pdo->prepare("INSERT INTO OnpubArticles (ID, imageID, title, content, url, created, modified) VALUES (:ID, :imageID, :title, :content, :url, :created, :modified)");
foreach ($articles as $article) {
$imageID =
$oimages->insert($article->image);
$article->imageID =
$imageID;
catch
(PDOException $e) {
$ID =
$this->getID($article);
catch
(PDOException $e) {
$imageID =
$article->imageID;
$created =
$article->getCreated()->format('Y-m-d H:i:s');
$modified =
$article->getModified()->format('Y-m-d H:i:s');
$stmt->bindParam(':ID', $ID);
$stmt->bindParam(':imageID', $imageID);
$stmt->bindParam(':title', $title);
$stmt->bindParam(':content', $content);
$stmt->bindParam(':url', $url);
$stmt->bindParam(':created', $created);
$stmt->bindParam(':modified', $modified);
$result =
$stmt->execute();
$IDs[] =
$this->pdo->lastInsertId();
$article->ID =
$this->pdo->lastInsertId();
$authors =
$article->authors;
$oauthors->insert($authors);
catch
(PDOException $e) {
foreach ($authors as $author) {
$aamap->articleID =
$article->ID;
$aamap->authorID =
$author->ID;
$aamap->setCreated($article->getCreated());
$aamap->setModified($article->getModified());
$oaamaps->insert($aamaps);
catch
(PDOException $e) {
$sectionIDs =
$article->sectionIDs;
foreach ($sectionIDs as $sectionID) {
$samap->sectionID =
$sectionID;
$samap->articleID =
$article->ID;
$samap->setCreated($article->getCreated());
$samap->setModified($article->getModified());
$osamaps->insert($samaps);
catch
(PDOException $e) {
$status =
$this->pdo->commit();
* Get multiple articles from the database.
* @param OnpubQueryOptions $queryOptions Database query options.
* @return array An array of {@link OnpubArticle} objects.
public function select(OnpubQueryOptions $queryOptions =
NULL, $sectionID =
NULL, $websiteID =
NULL)
if ($queryOptions ===
NULL)
$query =
$this->selectQuery($queryOptions, $sectionID, $websiteID);
$result =
$this->pdo->query($query);
$rows =
$result->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
if ($lastID !=
$row["ID"]) {
if ($queryOptions->includeContent) {
$content =
$row["content"];
$article->ID =
$row["ID"];
$article->imageID =
$row["imageID"];
$article->title =
$row["title"];
$article->content =
$content;
$article->url =
$row["url"];
$article->setCreated(new DateTime($row["created"]));
$article->setModified(new DateTime($row["modified"]));
$image->ID =
$row["imageID"];
$image->websiteID =
$row["imageWebsiteID"];
$image->fileName =
$row["imageFileName"];
$image->description =
$row["imageDescription"];
$image->setCreated(new DateTime($row["imageCreated"]));
$image->setModified(new DateTime($row["imageModified"]));
$article->image =
$image;
if ($sectionID ||
$websiteID) {
$article->sectionIDs[] =
$row["sectionID"];
if ($lastID !=
$row["ID"]) {
private function selectQuery(OnpubQueryOptions $queryOptions =
NULL, $sectionID =
NULL, $websiteID =
NULL)
if ($queryOptions ===
NULL)
$articleColumns =
"articles.ID, articles.imageID, articles.title, " .
"articles.url, articles.created, articles.modified, " .
"articleimages.websiteID AS imageWebsiteID, articleimages.fileName AS imageFileName, " .
"articleimages.description AS imageDescription, articleimages.url AS " .
"articleImageURL, articleimages.created AS imageCreated, " .
"articleimages.modified AS imageModified";
if ($queryOptions->includeContent) {
$articleColumns =
"articles.ID, articles.imageID, articles.title, " .
"articles.content, articles.url, articles.created, " .
"articles.modified, articleimages.websiteID AS " .
"imageWebsiteID, articleimages.fileName AS " .
"imageFileName, articleimages.description AS " .
"imageDescription, articleimages.url AS " .
"articleImageURL, articleimages.created AS " .
"imageCreated, articleimages.modified AS imageModified";
if ($sectionID ||
$websiteID) {
$articleColumns .=
", samaps.sectionID AS sectionID";
if ($queryOptions->dateLimit) {
$where =
"WHERE articles.created <= " .
$this->pdo->quote($queryOptions->dateLimit->format('Y-m-d H:i:s'));
if ($sectionID &&
!$websiteID) {
$where .=
" AND samaps.sectionID = $sectionID";
if ($websiteID &&
!$sectionID) {
$where .=
" AND wsmaps.websiteID = $websiteID";
if ($sectionID &&
!$websiteID) {
$where =
"WHERE samaps.sectionID = $sectionID";
if ($websiteID &&
!$sectionID) {
$where =
"WHERE wsmaps.websiteID = $websiteID";
if ($queryOptions->orderBy) {
$orderBy =
"ORDER BY articles." .
$queryOptions->orderBy;
if ($queryOptions->order) {
$orderBy .=
" " .
$queryOptions->order;
if ($sectionID &&
!$websiteID) {
$orderBy =
"ORDER BY samaps.ID ASC";
if ($queryOptions->getPage() &&
$queryOptions->rowLimit &&
$queryOptions->rowLimit >
0) {
$limit =
"LIMIT " .
(($queryOptions->getPage() -
1) *
$queryOptions->rowLimit) .
"," .
$queryOptions->rowLimit;
elseif ($queryOptions->rowLimit &&
$queryOptions->rowLimit >
0) {
$limit =
"LIMIT 0," .
$queryOptions->rowLimit;
if ($sectionID &&
!$websiteID) {
return "SELECT $articleColumns FROM OnpubArticles AS articles LEFT JOIN " .
"OnpubImages AS articleimages ON articles.imageID = articleimages.ID LEFT JOIN " .
"OnpubSAMaps AS samaps ON articles.ID = samaps.articleID " .
"$where $orderBy $limit";
elseif ($websiteID &&
!$sectionID) {
return "SELECT $articleColumns FROM OnpubArticles AS articles LEFT JOIN " .
"OnpubImages AS articleimages ON articles.imageID = articleimages.ID LEFT JOIN " .
"OnpubSAMaps AS samaps ON articles.ID = samaps.articleID " .
"LEFT JOIN OnpubWSMaps AS wsmaps ON samaps.sectionID = " .
"wsmaps.sectionID $where $orderBy $limit";
return "SELECT $articleColumns FROM OnpubArticles AS articles LEFT JOIN " .
"OnpubImages AS articleimages ON articles.imageID = articleimages.ID " .
"$where $orderBy $limit";
* Update an article already in the database.
* If you set the article's sectionIDs to NULL, it will be unmapped from
* any sections it was previously mapped to.
* @param OnpubArticle $article The article to be updated.
* @param bool $overwriteAAMaps False by default. If set to TRUE, the
* article-author maps for this article will be deleted and recreated, if
* @return int 1 if the article was updated. 0 if the article does not exist in the database.
public function update(OnpubArticle $article, $overwriteAAMaps =
FALSE)
$status =
$this->pdo->beginTransaction();
$stmt =
$this->pdo->prepare("UPDATE OnpubArticles SET imageID = :imageID, title = :title, content = :content, url = :url, created = :created, modified = :modified WHERE ID = :ID");
$imageID =
$oimages->insert($article->image);
$article->imageID =
$imageID;
catch
(PDOException $e) {
$imageID =
$article->imageID;
$created =
$article->getCreated()->format('Y-m-d H:i:s');
$modified =
$now->format('Y-m-d H:i:s');
$stmt->bindParam(':ID', $ID);
$stmt->bindParam(':imageID', $imageID);
$stmt->bindParam(':title', $title);
$stmt->bindParam(':content', $content);
$stmt->bindParam(':url', $url);
$stmt->bindParam(':created', $created);
$stmt->bindParam(':modified', $modified);
$result =
$stmt->execute();
$oaamaps->delete($article->ID, NULL);
catch
(PDOException $e) {
$authors =
$article->authors;
foreach ($authors as $author) {
$oauthors->update($author);
catch
(PDOException $e) {
$oauthors->insert($author);
catch
(PDOException $e) {
$aamap->articleID =
$article->ID;
$aamap->authorID =
$author->ID;
$oaamaps->insert($aamap);
catch
(PDOException $e) {
$sectionIDs =
$article->sectionIDs;
if ($sectionIDs ===
NULL) {
$samaps =
$osamaps->delete(NULL, $article->ID);
catch
(PDOException $e) {
elseif (sizeof($sectionIDs)) {
$queryOptions->orderBy =
"ID";
$queryOptions->order =
"ASC";
$samaps =
$osamaps->select($queryOptions, NULL, $article->ID);
catch
(PDOException $e) {
// Unmap sections not included in $sectionIDs.
foreach ($samaps as $samap) {
if (!in_array($samap->sectionID, $sectionIDs)) {
$osamaps->delete($samap->sectionID, $article->ID);
catch
(PDOException $e) {
foreach ($sectionIDs as $sectionID) {
$samap->sectionID =
$sectionID;
$samap->articleID =
$article->ID;
$samap->setCreated($article->getCreated());
$samap->setModified($article->getModified());
$samapID =
$osamaps->getID($samap);
catch
(PDOException $e) {
$osamaps->update($samap);
catch
(PDOException $e) {
$osamaps->insert($samap);
catch
(PDOException $e) {
$status =
$this->pdo->commit();
return $stmt->rowCount();
Documentation generated on Fri, 08 Feb 2013 04:02:18 -0500 by phpDocumentor 1.4.4