From 5d9c54eee60df084b43662cc27b972086f240b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lucas?= Date: Fri, 11 Jan 2013 15:16:15 +0100 Subject: [PATCH] Add custom filter of tags in the OPDS feed using facets. Need more testing but should be ok. re #21 --- OPDS_renderer.php | 13 +++++++++++++ author.php | 2 +- base.php | 26 ++++++++++++++++++++++---- book.php | 31 +++++++++++++++++++++++++------ config_default.php | 7 ++++++- 5 files changed, 67 insertions(+), 12 deletions(-) diff --git a/OPDS_renderer.php b/OPDS_renderer.php index 407e38b..93f939c 100644 --- a/OPDS_renderer.php +++ b/OPDS_renderer.php @@ -130,6 +130,13 @@ class OPDSRenderer $link = new Link ($config['cops_full_url'] . 'feed.php?query={searchTerms}', "application/atom+xml", "search", "Search here"); } self::renderLink ($link); + if ($page->containsBook () && !is_null ($config['cops_books_filter']) && count ($config['cops_books_filter']) > 0) { + $Urlfilter = getURLParam ("tag", ""); + foreach ($config['cops_books_filter'] as $lib => $filter) { + $link = new LinkFacet ("?" . $_SERVER['QUERY_STRING'] . "&tag=" . $filter, $lib, localize ("tagword.title"), $filter == $Urlfilter); + self::renderLink ($link); + } + } } private function endXmlDocument () { @@ -148,6 +155,12 @@ class OPDSRenderer if (!is_null ($link->title)) { self::getXmlStream ()->writeAttribute ("title", $link->title); } + if (!is_null ($link->facetGroup)) { + self::getXmlStream ()->writeAttribute ("opds:facetGroup", $link->facetGroup); + } + if ($link->activeFacet) { + self::getXmlStream ()->writeAttribute ("opds:activeFacet", "true"); + } self::getXmlStream ()->endElement (); } diff --git a/author.php b/author.php index eb7f666..d41bb84 100644 --- a/author.php +++ b/author.php @@ -68,7 +68,7 @@ order by substr (upper (sort), 1, 1)'); } public static function getEntryArray ($query, $params) { - list ($totalNumber, $result) = parent::executeQuery ($query, self::AUTHOR_COLUMNS, $params, -1); + list ($totalNumber, $result) = parent::executeQuery ($query, self::AUTHOR_COLUMNS, "", $params, -1); $entryArray = array(); while ($post = $result->fetchObject ()) { diff --git a/base.php b/base.php index 9001904..8ff4804 100644 --- a/base.php +++ b/base.php @@ -93,12 +93,16 @@ class Link public $type; public $rel; public $title; + public $facetGroup; + public $activeFacet; - public function __construct($phref, $ptype, $prel = NULL, $ptitle = NULL) { + public function __construct($phref, $ptype, $prel = NULL, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) { $this->href = $phref; $this->type = $ptype; $this->rel = $prel; $this->title = $ptitle; + $this->facetGroup = $pfacetGroup; + $this->activeFacet = $pactiveFacet; } public function hrefXhtml () { @@ -114,6 +118,13 @@ class LinkNavigation extends Link } } +class LinkFacet extends Link +{ + public function __construct($phref, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) { + parent::__construct ($phref, Link::OPDS_PAGING_TYPE, "http://opds-spec.org/facet", $ptitle, $pfacetGroup, $pactiveFacet); + $this->href = $_SERVER["SCRIPT_NAME"] . $this->href; + } +} class Entry { @@ -293,6 +304,13 @@ class Page global $config; return ceil ($this->totalNumber / $config['cops_max_item_per_page']); } + + public function containsBook () + { + if (count ($this->entryArray) == 0) return false; + if (get_class ($this->entryArray [1]) == "EntryBook") return true; + return false; + } } @@ -470,14 +488,14 @@ abstract class Base return self::$db; } - public static function executeQuery($query, $columns, $params, $n) { + public static function executeQuery($query, $columns, $filter, $params, $n) { global $config; $totalResult = -1; if ($config['cops_max_item_per_page'] != -1 && $n != -1) { // First check total number of results - $result = self::getDb ()->prepare (str_format ($query, "count(*)")); + $result = self::getDb ()->prepare (str_format ($query, "count(*)", $filter)); $result->execute ($params); $totalResult = $result->fetchColumn (); @@ -486,7 +504,7 @@ abstract class Base array_push ($params, ($n - 1) * $config['cops_max_item_per_page'], $config['cops_max_item_per_page']); } - $result = self::getDb ()->prepare(str_format ($query, $columns)); + $result = self::getDb ()->prepare(str_format ($query, $columns, $filter)); $result->execute ($params); return array ($totalResult, $result); } diff --git a/book.php b/book.php index 0b41815..7cb2478 100644 --- a/book.php +++ b/book.php @@ -20,15 +20,15 @@ define ('SQL_BOOKS_LEFT_JOIN', "left outer join comments on comments.book = book define ('SQL_BOOKS_BY_FIRST_LETTER', "select {0} from books " . SQL_BOOKS_LEFT_JOIN . " where upper (books.sort) like ?"); define ('SQL_BOOKS_BY_AUTHOR', "select {0} from books_authors_link, books " . SQL_BOOKS_LEFT_JOIN . " - where books_authors_link.book = books.id and author = ? order by pubdate"); + where books_authors_link.book = books.id and author = ? {1} order by pubdate"); define ('SQL_BOOKS_BY_SERIE', "select {0} from books_series_link, books " . SQL_BOOKS_LEFT_JOIN . " - where books_series_link.book = books.id and series = ? order by series_index"); + where books_series_link.book = books.id and series = ? {1} order by series_index"); define ('SQL_BOOKS_BY_TAG', "select {0} from books_tags_link, books " . SQL_BOOKS_LEFT_JOIN . " - where books_tags_link.book = books.id and tag = ? order by sort"); + where books_tags_link.book = books.id and tag = ? {1} order by sort"); define ('SQL_BOOKS_QUERY', "select {0} from books " . SQL_BOOKS_LEFT_JOIN . " - where exists (select null from authors, books_authors_link where book = books.id and author = authors.id and authors.name like ?) or title like ?"); + where (exists (select null from authors, books_authors_link where book = books.id and author = authors.id and authors.name like ?) or title like ?) {1}"); define ('SQL_BOOKS_RECENT', "select {0} from books " . SQL_BOOKS_LEFT_JOIN . " - order by timestamp desc limit "); + where 1=1 {1} order by timestamp desc limit "); class Book extends Base { const ALL_BOOKS_UUID = "urn:uuid"; @@ -113,6 +113,25 @@ class Book extends Base { return $this->authors; } + public function getFilterString () { + $filter = getURLParam ("tag", NULL); + if (is_null ($filter)) return ""; + + $exists = true; + if (preg_match ("/^!(.*)$/", $filter, $matches)) { + $exists = false; + $filter = $matches[1]; + } + + $result = "exists (select null from books_tags_link, tags where books_tags_link.book = books.id and books_tags_link.tag = tags.id and tags.name = '" . $filter . "')"; + + if (!$exists) { + $result = "not " . $result; + } + + return "and " . $result; + } + public function getAuthorsName () { $authorList = null; foreach ($this->getAuthors () as $author) { @@ -432,7 +451,7 @@ order by substr (upper (sort), 1, 1)"); } public static function getEntryArray ($query, $params, $n) { - list ($totalNumber, $result) = parent::executeQuery ($query, self::BOOK_COLUMNS, $params, $n); + list ($totalNumber, $result) = parent::executeQuery ($query, self::BOOK_COLUMNS, self::getFilterString (), $params, $n); $entryArray = array(); while ($post = $result->fetchObject ()) { diff --git a/config_default.php b/config_default.php index 3af12f4..9f6ce9e 100644 --- a/config_default.php +++ b/config_default.php @@ -133,5 +133,10 @@ * 1 : Yes (enable) * 0 : No */ - $config['cops_update_epub-metadata'] = "0"; + $config['cops_update_epub-metadata'] = "0"; + + /* + * Filter on tags to book list + */ + $config['cops_books_filter'] = array ("Non lus" => "!Read", "lus" => "Read"); ?> \ No newline at end of file