1) Исправления в связи со сменой API MySQL
[openlib.git] / www / OPDS_renderer.php.bak
1 <?php
2 /**
3  * COPS (Calibre OPDS PHP Server) class file
4  *
5  * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6  * @author     Sébastien Lucas <sebastien@slucas.fr>
7  */
8
9 require_once ("base.php");
10  
11 class OPDSRenderer
12 {
13     const PAGE_OPENSEARCH = "8";
14     const PAGE_OPENSEARCH_QUERY = "9";
15
16     private $xmlStream = NULL;
17     private $updated = NULL;
18     
19     private function getUpdatedTime () {
20         if (is_null ($this->updated)) {
21             $this->updated = time();
22         }
23         return date (DATE_ATOM, $this->updated);
24     }
25     
26     private function getXmlStream () {
27         if (is_null ($this->xmlStream)) {
28             $this->xmlStream = new XMLWriter();
29             $this->xmlStream->openMemory();
30             $this->xmlStream->setIndent (true);
31         }
32         return $this->xmlStream;
33     }
34     
35     public function getOpenSearch () {
36         global $config;
37         $xml = new XMLWriter ();
38         $xml->openMemory ();
39         $xml->setIndent (true);
40         $xml->startDocument('1.0','UTF-8');
41             $xml->startElement ("OpenSearchDescription");
42                 $xml->writeAttribute ("xmlns", "http://a9.com/-/spec/opensearch/1.1/");
43                 $xml->startElement ("ShortName");
44                     $xml->text ("My catalog");
45                 $xml->endElement ();
46                 $xml->startElement ("Description");
47                     $xml->text ("Search for ebooks");
48                 $xml->endElement ();
49                 $xml->startElement ("InputEncoding");
50                     $xml->text ("UTF-8");
51                 $xml->endElement ();
52                 $xml->startElement ("OutputEncoding");
53                     $xml->text ("UTF-8");
54                 $xml->endElement ();
55                 $xml->startElement ("Image");
56                     $xml->writeAttribute ("type", "image/x-icon");
57                     $xml->writeAttribute ("width", "16");
58                     $xml->writeAttribute ("height", "16");
59                     $xml->text ($config['cops_icon']);
60                 $xml->endElement ();
61                 $xml->startElement ("Url");
62                     $xml->writeAttribute ("type", 'application/atom+xml');
63                     $urlparam = "?query={searchTerms}";
64                     $urlparam = str_replace ("%7B", "{", $urlparam);
65                     $urlparam = str_replace ("%7D", "}", $urlparam);
66                     $xml->writeAttribute ("template", $config['cops_full_url'] . 'feed.php' . $urlparam);
67                 $xml->endElement ();
68                 $xml->startElement ("Query");
69                     $xml->writeAttribute ("role", "example");
70                     $xml->writeAttribute ("searchTerms", "robot");
71                 $xml->endElement ();
72             $xml->endElement ();
73         $xml->endDocument();
74         return $xml->outputMemory(true);
75     }
76     
77     private function startXmlDocument ($page) {
78         global $config;
79         self::getXmlStream ()->startDocument('1.0','UTF-8');
80         self::getXmlStream ()->startElement ("feed");
81             self::getXmlStream ()->writeAttribute ("xmlns", "http://www.w3.org/2005/Atom");
82             self::getXmlStream ()->writeAttribute ("xmlns:xhtml", "http://www.w3.org/1999/xhtml");
83             self::getXmlStream ()->writeAttribute ("xmlns:opds", "http://opds-spec.org/2010/catalog");
84             self::getXmlStream ()->writeAttribute ("xmlns:opensearch", "http://a9.com/-/spec/opensearch/1.1/");
85             self::getXmlStream ()->writeAttribute ("xmlns:dcterms", "http://purl.org/dc/terms/");
86             self::getXmlStream ()->startElement ("title");
87                 self::getXmlStream ()->text ($page->title);
88             self::getXmlStream ()->endElement ();
89             if ($page->subtitle != "")
90             {
91                 self::getXmlStream ()->startElement ("subtitle");
92                     self::getXmlStream ()->text ($page->subtitle);
93                 self::getXmlStream ()->endElement ();
94             }
95             self::getXmlStream ()->startElement ("id");
96                 if ($page->idPage)
97                 {
98                     $idPage = $page->idPage;
99                     self::getXmlStream ()->text ($idPage);
100                 }
101                 else
102                 {
103                     self::getXmlStream ()->text ($_SERVER['REQUEST_URI']);
104                 }
105             self::getXmlStream ()->endElement ();
106             self::getXmlStream ()->startElement ("updated");
107                 self::getXmlStream ()->text (self::getUpdatedTime ());
108             self::getXmlStream ()->endElement ();
109             self::getXmlStream ()->startElement ("icon");
110                 self::getXmlStream ()->text ($page->favicon);
111             self::getXmlStream ()->endElement ();
112             self::getXmlStream ()->startElement ("author");
113                 self::getXmlStream ()->startElement ("name");
114                     self::getXmlStream ()->text (utf8_encode ("Sébastien Lucas"));
115                 self::getXmlStream ()->endElement ();
116                 self::getXmlStream ()->startElement ("uri");
117                     self::getXmlStream ()->text ("http://blog.slucas.fr");
118                 self::getXmlStream ()->endElement ();
119                 self::getXmlStream ()->startElement ("email");
120                     self::getXmlStream ()->text ("sebastien@slucas.fr");
121                 self::getXmlStream ()->endElement ();
122             self::getXmlStream ()->endElement ();
123             $link = new LinkNavigation ("", "start", "Home");
124             self::renderLink ($link);
125             $link = new LinkNavigation ("?" . $_SERVER['QUERY_STRING'], "self");
126             self::renderLink ($link);
127             $urlparam = "?page=" . self::PAGE_OPENSEARCH;
128             if ($config['cops_generate_invalid_opds_stream'] == 0 || preg_match("/(MantanoReader|FBReader)/", $_SERVER['HTTP_USER_AGENT'])) {
129                 // Good and compliant way of handling search
130                 $link = new Link ("feed.php" . $urlparam, "application/opensearchdescription+xml", "search", "Search here");
131             }
132             else
133             {
134                 // Bad way, will be removed when OPDS client are fixed
135                 $link = new Link ($config['cops_full_url'] . 'feed.php' . $urlparam, "application/atom+xml", "search", "Search here");
136             }
137             self::renderLink ($link);
138             if ($page->containsBook () && !is_null ($config['cops_books_filter']) && count ($config['cops_books_filter']) > 0) {
139                 $Urlfilter = getURLParam ("tag", "");
140                 foreach ($config['cops_books_filter'] as $lib => $filter) {
141                     $link = new LinkFacet ("?" . addURLParameter ($_SERVER['QUERY_STRING'], "tag", $filter), $lib, localize ("tagword.title"), $filter == $Urlfilter);
142                     self::renderLink ($link);
143                 }
144             }
145     }
146         
147     private function endXmlDocument () {
148         self::getXmlStream ()->endElement ();
149         self::getXmlStream ()->endDocument ();
150         return self::getXmlStream ()->outputMemory(true);
151     }
152     
153     private function renderLink ($link) {
154         self::getXmlStream ()->startElement ("link");
155             self::getXmlStream ()->writeAttribute ("href", $link->href);
156             self::getXmlStream ()->writeAttribute ("type", $link->type);
157             if (!is_null ($link->rel)) {
158                 self::getXmlStream ()->writeAttribute ("rel", $link->rel);
159             }
160             if (!is_null ($link->title)) {
161                 self::getXmlStream ()->writeAttribute ("title", $link->title);
162             }
163             if (!is_null ($link->facetGroup)) {
164                 self::getXmlStream ()->writeAttribute ("opds:facetGroup", $link->facetGroup);
165             }
166             if ($link->activeFacet) {
167                 self::getXmlStream ()->writeAttribute ("opds:activeFacet", "true");
168             }
169         self::getXmlStream ()->endElement ();
170     }
171
172     
173     private function renderEntry ($entry) {
174         self::getXmlStream ()->startElement ("title");
175             self::getXmlStream ()->text ($entry->title);
176         self::getXmlStream ()->endElement ();
177         self::getXmlStream ()->startElement ("updated");
178             self::getXmlStream ()->text (self::getUpdatedTime ());
179         self::getXmlStream ()->endElement ();
180         self::getXmlStream ()->startElement ("id");
181             self::getXmlStream ()->text ($entry->id);
182         self::getXmlStream ()->endElement ();
183         self::getXmlStream ()->startElement ("content");
184             self::getXmlStream ()->writeAttribute ("type", $entry->contentType);
185             if ($entry->contentType == "text") {
186                 self::getXmlStream ()->text ($entry->content);
187             } else {
188                 self::getXmlStream ()->writeRaw ($entry->content);
189             }
190         self::getXmlStream ()->endElement ();
191         foreach ($entry->linkArray as $link) {
192             self::renderLink ($link);
193         }
194         
195         if (get_class ($entry) != "EntryBook") {
196             return;
197         }
198         
199         foreach ($entry->book->getAuthors () as $author) {
200             self::getXmlStream ()->startElement ("author");
201                 self::getXmlStream ()->startElement ("name");
202                     self::getXmlStream ()->text ($author->name);
203                 self::getXmlStream ()->endElement ();
204                 self::getXmlStream ()->startElement ("uri");
205                     self::getXmlStream ()->text ("feed.php" . $author->getUri ());
206                 self::getXmlStream ()->endElement ();
207             self::getXmlStream ()->endElement ();
208         }
209         foreach ($entry->book->getTags () as $category) {
210             self::getXmlStream ()->startElement ("category");
211                 self::getXmlStream ()->writeAttribute ("term", $category->name);
212                 self::getXmlStream ()->writeAttribute ("label", $category->name);
213             self::getXmlStream ()->endElement ();
214         }
215         if ($entry->book->getPubDate () != "") {
216             self::getXmlStream ()->startElement ("dcterms:issued");
217                 self::getXmlStream ()->text (date ("Y-m-d", $entry->book->pubdate));
218             self::getXmlStream ()->endElement ();
219             self::getXmlStream ()->startElement ("published");
220                 self::getXmlStream ()->text (date ("Y-m-d", $entry->book->pubdate) . "T08:08:08Z");
221             self::getXmlStream ()->endElement ();
222         }
223         
224         $lang = $entry->book->getLanguages ();
225         if (!empty ($lang)) {
226             self::getXmlStream ()->startElement ("dcterms:language");
227                 self::getXmlStream ()->text ($lang);
228             self::getXmlStream ()->endElement ();
229         }
230
231     }
232     
233     public function render ($page) {
234         global $config;
235         self::startXmlDocument ($page);
236         if ($page->isPaginated ())
237         {
238             self::getXmlStream ()->startElement ("opensearch:totalResults");
239                 self::getXmlStream ()->text ($page->totalNumber);
240             self::getXmlStream ()->endElement ();
241             self::getXmlStream ()->startElement ("opensearch:itemsPerPage");
242                 self::getXmlStream ()->text ($config['cops_max_item_per_page']);
243             self::getXmlStream ()->endElement ();
244             self::getXmlStream ()->startElement ("opensearch:startIndex");
245                 self::getXmlStream ()->text (($page->n - 1) * $config['cops_max_item_per_page'] + 1);
246             self::getXmlStream ()->endElement ();
247             $prevLink = $page->getPrevLink ();
248             $nextLink = $page->getNextLink ();
249             if (!is_null ($prevLink)) {
250                 self::renderLink ($prevLink);
251             }
252             if (!is_null ($nextLink)) {
253                 self::renderLink ($nextLink);
254             }
255         }
256         foreach ($page->entryArray as $entry) {
257             self::getXmlStream ()->startElement ("entry");
258                 self::renderEntry ($entry);
259             self::getXmlStream ()->endElement ();
260         }
261         return self::endXmlDocument ();
262     }
263 }
264