Completed
Pull Request — master (#233)
by
unknown
12:45
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 <[email protected]>
7
 */
8
9
define ("VERSION", "1.0.0RC4");
10
define ("DB", "db");     // url parameter for the selected database
11
define ("VL", "vl");     // url parameter for the selected virtual library
12
date_default_timezone_set($config['default_timezone']);
13
14
require_once('virtuallib.php');
15
16
17 3
function useServerSideRendering () {
18 3
    global $config;
19
    return preg_match("/" . $config['cops_server_side_render'] . "/", $_SERVER['HTTP_USER_AGENT']);
20
}
21
22
function serverSideRender ($data) {
23 2
    // Get the templates
24 2
    $theme = getCurrentTemplate ();
25 2
    $header = file_get_contents('templates/' . $theme . '/header.html');
26 2
    $footer = file_get_contents('templates/' . $theme . '/footer.html');
27 2
    $main = file_get_contents('templates/' . $theme . '/main.html');
28 2
    $bookdetail = file_get_contents('templates/' . $theme . '/bookdetail.html');
29
    $page = file_get_contents('templates/' . $theme . '/page.html');
30
31 2
    // Generate the function for the template
32 2
    $template = new doT ();
33 2
    $dot = $template->template ($page, array ("bookdetail" => $bookdetail,
34 2
                                              "header" => $header,
35 2
                                              "footer" => $footer,
36
                                              "main" => $main));
37
    // If there is a syntax error in the function created
38 2
    // $dot will be equal to FALSE
39
    if (!$dot) {
40
        return FALSE;
41
    }
42 2
    // Execute the template
43
    if (!empty ($data)) {
44
        return $dot ($data);
45
    }
46 2
47
    return NULL;
48
}
49
50 18
function getQueryString () {
51 16
    if ( isset($_SERVER['QUERY_STRING']) ) {
52
        return $_SERVER['QUERY_STRING'];
53 2
    }
54
    return "";
55
}
56
57
function notFound () {
58
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
59
    header("Status: 404 Not Found");
60
61
    $_SERVER['REDIRECT_STATUS'] = 404;
62
}
63
64 101
function getURLParam ($name, $default = NULL) {
65 24
    if (!empty ($_GET) && isset($_GET[$name]) && $_GET[$name] != "") {
66
        return $_GET[$name];
67 101
    }
68
    return $default;
69
}
70
71 87
function getCurrentOption ($option) {
72 87
    global $config;
73 2
    if (isset($_COOKIE[$option])) {
74
        if (isset($config ["cops_" . $option]) && is_array ($config ["cops_" . $option])) {
75
            return explode (",", $_COOKIE[$option]);
76 2
        } else {
77
            return $_COOKIE[$option];
78
        }
79 85
    }
80 2
    if ($option == "style") {
81
        return "default";
82
    }
83 85
84 85
    if (isset($config ["cops_" . $option])) {
85
        return $config ["cops_" . $option];
86
    }
87
88
    return "";
89
}
90
91 2
function getCurrentCss () {
92
    return "templates/" . getCurrentTemplate () . "/styles/style-" . getCurrentOption ("style") . ".css";
93
}
94
95 4
function getCurrentTemplate () {
96
    return getCurrentOption ("template");
97
}
98
99 50
function getUrlWithVersion ($url) {
100
    return $url . "?v=" . VERSION;
101
}
102
103 35
function xml2xhtml($xml) {
104
    return preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', create_function('$m', '
105
        $xhtml_tags = array("br", "hr", "input", "frame", "img", "area", "link", "col", "base", "basefont", "param");
106 35
        return in_array($m[1], $xhtml_tags) ? "<$m[1]$m[2] />" : "<$m[1]$m[2]></$m[1]>";
107
    '), $xml);
108
}
109
110
function display_xml_error($error)
111
{
112
    $return = "";
113
    $return .= str_repeat('-', $error->column) . "^\n";
114
115
    switch ($error->level) {
116
        case LIBXML_ERR_WARNING:
117
            $return .= "Warning $error->code: ";
118
            break;
119
         case LIBXML_ERR_ERROR:
120
            $return .= "Error $error->code: ";
121
            break;
122
        case LIBXML_ERR_FATAL:
123
            $return .= "Fatal Error $error->code: ";
124
            break;
125
    }
126
127
    $return .= trim($error->message) .
128
               "\n  Line: $error->line" .
129
               "\n  Column: $error->column";
130
131
    if ($error->file) {
132
        $return .= "\n  File: $error->file";
133
    }
134
135
    return "$return\n\n--------------------------------------------\n\n";
136
}
137
138
function are_libxml_errors_ok ()
139 35
{
140
    $errors = libxml_get_errors();
141 35
142
    foreach ($errors as $error) {
143 35
        if ($error->code == 801) return false;
144 35
    }
145
    return true;
146
}
147
148 35
function html2xhtml ($html) {
149 35
    $doc = new DOMDocument();
150
    libxml_use_internal_errors(true);
151 35
152 35
    $doc->loadHTML('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>' .
153 35
                        $html  . '</body></html>'); // Load the HTML
154 35
    $output = $doc->saveXML($doc->documentElement); // Transform to an Ansi xml stream
155 35
    $output = xml2xhtml($output);
156 35
    if (preg_match ('#<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></meta></head><body>(.*)</body></html>#ms', $output, $matches)) {
157 35
        $output = $matches [1]; // Remove <html><body>
158
    }
159
    /*
160
    // In case of error with summary, use it to debug
161
    $errors = libxml_get_errors();
162
163
    foreach ($errors as $error) {
164
        $output .= display_xml_error($error);
165
    }
166
    */
167 35
168
    if (!are_libxml_errors_ok ()) $output = "HTML code not valid.";
169 35
170 35
    libxml_use_internal_errors(false);
171
    return $output;
172
}
173
174
/**
175
 * This method is a direct copy-paste from
176
 * http://tmont.com/blargh/2010/1/string-format-in-php
177
 */
178 94
function str_format($format) {
0 ignored issues
show
The parameter $format is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
179 94
    $args = func_get_args();
180
    $format = array_shift($args);
181 94
182 94
    preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
183 94
    $offset = 0;
184 94
    foreach ($matches[1] as $data) {
185 94
        $i = $data[0];
186 94
        $format = substr_replace($format, @$args[$i], $offset + $data[1] - 1, 2 + strlen($i));
187 94
        $offset += strlen(@$args[$i]) - 2 - strlen($i);
188
    }
189 94
190
    return $format;
191
}
192
193
/**
194
 * Get all accepted languages from the browser and put them in a sorted array
195
 * languages id are normalized : fr-fr -> fr_FR
196
 * @return array of languages
197
 */
198 16
function getAcceptLanguages() {
199
    $langs = array();
200 16
201
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
202 16
        // break up string into pieces (languages and q factors)
203 16
        $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
204
        if (preg_match('/^(\w{2})-\w{2}$/', $accept, $matches)) {
205 3
            // Special fix for IE11 which send fr-FR and nothing else
206 3
            $accept = $accept . "," . $matches[1] . ";q=0.8";
207 16
        }
208
        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $lang_parse);
209 16
210 16
        if (count($lang_parse[1])) {
211 16
            $langs = array();
212
            foreach ($lang_parse[1] as $lang) {
213 16
                // Format the language code (not standard among browsers)
214 11
                if (strlen($lang) == 5) {
215 11
                    $lang = str_replace("-", "_", $lang);
216 11
                    $splitted = preg_split("/_/", $lang);
217 11
                    $lang = $splitted[0] . "_" . strtoupper($splitted[1]);
218 16
                }
219 16
                array_push($langs, $lang);
220
            }
221 16
            // create a list like "en" => 0.8
222
            $langs = array_combine($langs, $lang_parse[4]);
223
224 16
            // set default to 1 for any without q factor
225 16
            foreach ($langs as $lang => $val) {
226 16
                if ($val === '') $langs[$lang] = 1;
227
            }
228
229 16
            // sort list based on value
230 16
            arsort($langs, SORT_NUMERIC);
231 16
        }
232
    }
233 16
234
    return $langs;
235
}
236
237
/**
238
 * Find the best translation file possible based on the accepted languages
239
 * @return array of language and language file
240
 */
241 17
function getLangAndTranslationFile() {
242 17
    global $config;
243 17
    $langs = array();
244 17
    $lang = "en";
245
    if (!empty($config['cops_language'])) {
246
        $lang = $config['cops_language'];
247 17
    }
248 16
    elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
249 16
        $langs = getAcceptLanguages();
250
    }
251 17
    //echo var_dump($langs);
252 17
    $lang_file = NULL;
253 16
    foreach ($langs as $language => $val) {
254 16
        $temp_file = dirname(__FILE__). '/lang/Localization_' . $language . '.json';
255 16
        if (file_exists($temp_file)) {
256 16
            $lang = $language;
257 16
            $lang_file = $temp_file;
258
            break;
259 17
        }
260 17
    }
261 3
    if (empty ($lang_file)) {
262 3
        $lang_file = dirname(__FILE__). '/lang/Localization_' . $lang . '.json';
263 17
    }
264
    return array($lang, $lang_file);
265
}
266
267
/**
268
 * This method is based on this page
269
 * http://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php/
270
 */
271 114
function localize($phrase, $count=-1, $reset=false) {
272 114
    global $config;
273 114
    if ($count == 0)
274 114
        $phrase .= ".none";
275 114
    if ($count == 1)
276 114
        $phrase .= ".one";
277 114
    if ($count > 1)
278
        $phrase .= ".many";
279
280 114
    /* Static keyword is used to ensure the file is loaded only once */
281 114
    static $translations = NULL;
282 16
    if ($reset) {
283 16
        $translations = NULL;
284
    }
285 114
    /* If no instance of $translations has occured load the language file */
286 17
    if (is_null($translations)) {
287 17
        $lang_file_en = NULL;
288 17
        list ($lang, $lang_file) = getLangAndTranslationFile();
289 1
        if ($lang != "en") {
290 1
            $lang_file_en = dirname(__FILE__). '/lang/' . 'Localization_en.json';
291
        }
292 17
293
        $lang_file_content = file_get_contents($lang_file);
294 17
        /* Load the language file as a JSON object and transform it into an associative array */
295
        $translations = json_decode($lang_file_content, true);
296
297 17
        /* Clean the array of all unfinished translations */
298 17
        foreach (array_keys ($translations) as $key) {
299 1
            if (preg_match ("/^##TODO##/", $key)) {
300 1
                unset ($translations [$key]);
301 17
            }
302
        }
303 17
        if ($lang_file_en)
0 ignored issues
show
Bug Best Practice introduced by
The expression $lang_file_en of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
304 1
        {
305 1
            $lang_file_content = file_get_contents($lang_file_en);
306 1
            $translations_en = json_decode($lang_file_content, true);
307 1
            $translations = array_merge ($translations_en, $translations);
308 17
        }
309 114
    }
310 114
    if (array_key_exists ($phrase, $translations)) {
311
        return $translations[$phrase];
312 1
    }
313
    return $phrase;
314
}
315
316 58
function addURLParameter($urlParams, $paramName, $paramValue) {
317 48
    if (empty ($urlParams)) {
318 48
        $urlParams = "";
319 58
    }
320 58
    $start = "";
321 15
    if (preg_match ("#^\?(.*)#", $urlParams, $matches)) {
322 15
        $start = "?";
323 15
        $urlParams = $matches[1];
324 58
    }
325 58
    $params = array();
326 58
    parse_str($urlParams, $params);
327
    if (empty ($paramValue) && $paramValue != 0) {
328
        unset ($params[$paramName]);
329 58
    } else {
330
        $params[$paramName] = $paramValue;
331 58
    }
332
    return $start . http_build_query($params);
333
}
334
335 107
function useNormAndUp () {
336 107
    global $config;
337
    return $config ['cops_normalized_search'] == "1";
338
}
339
340 8
function normalizeUtf8String( $s) {
341 8
    include_once 'transliteration.php';
342
    return _transliteration_process($s);
343
}
344
345 7
function normAndUp ($s) {
346
    return mb_strtoupper (normalizeUtf8String($s), 'UTF-8');
347
}
348
349
class Link
350
{
351
    const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail";
352
    const OPDS_IMAGE_TYPE = "http://opds-spec.org/image";
353
    const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition";
354
    const OPDS_NAVIGATION_TYPE = "application/atom+xml;profile=opds-catalog;kind=navigation";
355
    const OPDS_PAGING_TYPE = "application/atom+xml;profile=opds-catalog;kind=acquisition";
356
357
    public $href;
358
    public $type;
359
    public $rel;
360
    public $title;
361
    public $facetGroup;
362
    public $activeFacet;
363 96
364 96
    public function __construct($phref, $ptype, $prel = NULL, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
365 96
        $this->href = $phref;
366 96
        $this->type = $ptype;
367 96
        $this->rel = $prel;
368 96
        $this->title = $ptitle;
369 96
        $this->facetGroup = $pfacetGroup;
370 96
        $this->activeFacet = $pactiveFacet;
371
    }
372 10
373 10
    public function hrefXhtml () {
374
        return $this->href;
375
    }
376
}
377
378
class LinkNavigation extends Link
379 95
{
380 95
    public function __construct($phref, $prel = NULL, $ptitle = NULL) {
381 95
        parent::__construct ($phref, Link::OPDS_NAVIGATION_TYPE, $prel, $ptitle);
382 95
        if (!is_null (GetUrlParam (DB))) {
383 95
        	$this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
384
        	$this->href = addURLParameter ($this->href, VL, GetUrlParam (VL, 0));
385
        }
386 95
        if (!preg_match ("#^\?(.*)#", $this->href) && !empty ($this->href)) $this->href = "?" . $this->href;
387
        if (preg_match ("/(bookdetail|getJSON).php/", $_SERVER["SCRIPT_NAME"])) {
388 95
            $this->href = "index.php" . $this->href;
389
        } else {
390
            $this->href = $_SERVER["SCRIPT_NAME"] . $this->href;
391
        }
392
    }
393 1
}
394 1
395 1
class LinkFacet extends Link
396 1
{
397 1
    public function __construct($phref, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
398
        parent::__construct ($phref, Link::OPDS_PAGING_TYPE, "http://opds-spec.org/facet", $ptitle, $pfacetGroup, $pactiveFacet);
399
        if (!is_null (GetUrlParam (DB))) {
400
        	$this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
401
        	$this->href = addURLParameter ($this->href, VL, GetUrlParam (VL, 0));
402
        }
403
        $this->href = $_SERVER["SCRIPT_NAME"] . $this->href;
404
    }
405
}
406
407
class Entry
408
{
409
    public $title;
410
    public $id;
411
    public $content;
412
    public $numberOfElement;
413
    public $contentType;
414
    public $linkArray;
415
    public $localUpdated;
416
    public $className;
417
    private static $updated = NULL;
418
419
    public static $icons = array(
420
        Author::ALL_AUTHORS_ID       => 'images/author.png',
421
        Serie::ALL_SERIES_ID         => 'images/serie.png',
422
        Book::ALL_RECENT_BOOKS_ID    => 'images/recent.png',
423
        Tag::ALL_TAGS_ID             => 'images/tag.png',
424
        Language::ALL_LANGUAGES_ID   => 'images/language.png',
425
        CustomColumn::ALL_CUSTOMS_ID => 'images/tag.png',
426
        "cops:books$"             => 'images/allbook.png',
427
        "cops:books:letter"       => 'images/allbook.png',
428
        Publisher::ALL_PUBLISHERS_ID => 'images/publisher.png'
429
    );
430
431
    public function getUpdatedTime () {
432
        if (!is_null ($this->localUpdated)) {
433
            return date (DATE_ATOM, $this->localUpdated);
434 7
        }
435 7
        if (is_null (self::$updated)) {
436 7
            self::$updated = time();
437
        }
438 7
        return date (DATE_ATOM, self::$updated);
439
    }
440
441
    public function getNavLink () {
442
        foreach ($this->linkArray as $link) {
443 89
            if ($link->type != Link::OPDS_NAVIGATION_TYPE) { continue; }
444 89
445 89
            return $link->hrefXhtml ();
446 89
        }
447 89
        return "#";
448 89
    }
449 89
450 89
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pclass = "", $pcount = 0) {
451 89
        global $config;
452
        $this->title = $ptitle;
453 89
        $this->id = $pid;
454 89
        $this->content = $pcontent;
455 89
        $this->contentType = $pcontentType;
456
        $this->linkArray = $plinkArray;
457 89
        $this->className = $pclass;
458 50
        $this->numberOfElement = $pcount;
459 50
460
        if ($config['cops_show_icons'] == 1)
461 89
        {
462 89
            foreach (self::$icons as $reg => $image)
463
            {
464 89
                if (preg_match ("/" . $reg . "/", $pid)) {
465 89
                    array_push ($this->linkArray, new Link (getUrlWithVersion ($image), "image/png", Link::OPDS_THUMBNAIL_TYPE));
466
                    break;
467
                }
468
            }
469
        }
470
471
        if (!is_null (GetUrlParam (DB))) $this->id = str_replace ("cops:", "cops:" . GetUrlParam (DB) . ":" . GetUrlParam (VL,0) . ":", $this->id);
472 39
    }
473 39
}
474 39
475 39
class EntryBook extends Entry
476 39
{
477
    public $book;
478
479
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pbook) {
480
        parent::__construct ($ptitle, $pid, $pcontent, $pcontentType, $plinkArray);
481
        $this->book = $pbook;
482
        $this->localUpdated = $pbook->timestamp;
483
    }
484
485
    public function getCoverThumbnail () {
486
        foreach ($this->linkArray as $link) {
487
            if ($link->rel == Link::OPDS_THUMBNAIL_TYPE)
488
                return $link->hrefXhtml ();
489
        }
490
        return null;
491
    }
492
493
    public function getCover () {
494
        foreach ($this->linkArray as $link) {
495
            if ($link->rel == Link::OPDS_IMAGE_TYPE)
496
                return $link->hrefXhtml ();
497
        }
498
        return null;
499
    }
500
}
501
502
class Page
503
{
504
    public $title;
505
    public $subtitle = "";
506
    public $authorName = "";
507
    public $authorUri = "";
508
    public $authorEmail = "";
509
    public $idPage;
510
    public $idGet;
511 81
    public $query;
512
    public $favicon;
513
    public $n;
514 81
    public $book;
515 3
    public $totalNumber = -1;
516 78
    public $entryArray = array();
517 1
518 77
    public static function getPage ($pageId, $id, $query, $n)
519 7
    {
520 70
        switch ($pageId) {
521 2
            case Base::PAGE_ALL_AUTHORS :
522 68
                return new PageAllAuthors ($id, $query, $n);
523 1
            case Base::PAGE_AUTHORS_FIRST_LETTER :
524 67
                return new PageAllAuthorsLetter ($id, $query, $n);
525 2
            case Base::PAGE_AUTHOR_DETAIL :
526 65
                return new PageAuthorDetail ($id, $query, $n);
527 1
            case Base::PAGE_ALL_TAGS :
528 64
                return new PageAllTags ($id, $query, $n);
529 3
            case Base::PAGE_TAG_DETAIL :
530 61
                return new PageTagDetail ($id, $query, $n);
531 3
            case Base::PAGE_ALL_LANGUAGES :
532 58
                return new PageAllLanguages ($id, $query, $n);
533 1
            case Base::PAGE_LANGUAGE_DETAIL :
534 57
                return new PageLanguageDetail ($id, $query, $n);
535 1
            case Base::PAGE_ALL_CUSTOMS :
536 56
                return new PageAllCustoms ($id, $query, $n);
537 2
            case Base::PAGE_CUSTOM_DETAIL :
538 54
                return new PageCustomDetail ($id, $query, $n);
539 3
            case Base::PAGE_ALL_RATINGS :
540 51
                return new PageAllRating ($id, $query, $n);
541 1
            case Base::PAGE_RATING_DETAIL :
542 50
                return new PageRatingDetail ($id, $query, $n);
543 4
            case Base::PAGE_ALL_SERIES :
544 46
                return new PageAllSeries ($id, $query, $n);
545 1
            case Base::PAGE_ALL_BOOKS :
546 45
                return new PageAllBooks ($id, $query, $n);
547 31
            case Base::PAGE_ALL_BOOKS_LETTER:
548 14
                return new PageAllBooksLetter ($id, $query, $n);
549 1
            case Base::PAGE_ALL_RECENT_BOOKS :
550 13
                return new PageRecentBooks ($id, $query, $n);
551 2
            case Base::PAGE_SERIE_DETAIL :
552 11
                return new PageSerieDetail ($id, $query, $n);
553 1
            case Base::PAGE_OPENSEARCH_QUERY :
554 10
                return new PageQueryResult ($id, $query, $n);
555
            case Base::PAGE_BOOK_DETAIL :
556 10
                return new PageBookDetail ($id, $query, $n);
557
            case Base::PAGE_ALL_PUBLISHERS:
558 10
                return new PageAllPublishers ($id, $query, $n);
559 10
            case Base::PAGE_PUBLISHER_DETAIL :
560 10
                return new PagePublisherDetail ($id, $query, $n);
561 10
            case Base::PAGE_ABOUT :
562 10
                return new PageAbout ($id, $query, $n);
563
            case Base::PAGE_CUSTOMIZE :
564
                return new PageCustomize ($id, $query, $n);
565 81
            default:
566 81
                $page = new Page ($id, $query, $n);
567
                $page->idPage = "cops:catalog";
568 81
                return $page;
569 81
        }
570 81
    }
571 81
572 81
    public function __construct($pid, $pquery, $pn) {
573 81
        global $config;
574 81
575 81
        $this->idGet = $pid;
576
        $this->query = $pquery;
577 10
        $this->n = $pn;
578
        $this->favicon = $config['cops_icon'];
579 10
        $this->authorName = empty($config['cops_author_name']) ? utf8_encode('S�bastien Lucas') : $config['cops_author_name'];
580 10
        $this->authorUri = empty($config['cops_author_uri']) ? 'http://blog.slucas.fr' : $config['cops_author_uri'];
581 10
        $this->authorEmail = empty($config['cops_author_email']) ? '[email protected]' : $config['cops_author_email'];
582 10
    }
583 2
584 2
    public function InitializeContent ()
585 2
    {
586
        global $config;
587
        $this->title = $config['cops_title_default'];
588
        $this->subtitle = $config['cops_subtitle_default'];
589
        if (Base::noDatabaseSelected ()) {
590
            $i = 0;
591
            foreach (Base::getDbNameList () as $key) {
592
            	if (VirtualLib::isVLEnabled()) {
593
            		// Virtual Libraries are enabled show each virtual library as one database
594
            		$nBooks = Book::getBookCount ($i);
595 2
            		$j = 0;
596 2
            		foreach (VirtualLib::getVLNameList($i) as $vlName) {
597 2
            			array_push ($this->entryArray, new Entry (VirtualLib::getDisplayName($key, $vlName),
598 2
            								"cops:{$i}:catalog",
599
            								str_format (localize ("bookword", $nBooks), $nBooks), "text",
600 2
            								array ( new LinkNavigation ("?" . DB . "={$i}&" . VL . "={$j}")), "", $nBooks));
601 2
            			$j++;
602 2
            		}
603 2
            	} else {
604 8
            		// Virtual Libraries are enabled show each virtual library as one database
605 7
            		$nBooks = Book::getBookCount ($i);
606 7
	                array_push ($this->entryArray, new Entry ($key, "cops:{$i}:catalog",
607 8
	                                        str_format (localize ("bookword", $nBooks), $nBooks), "text",
608 7
	                                        array ( new LinkNavigation ("?" . DB . "={$i}")), "", $nBooks));
609 7
            	}
610 7
                $i++;
611 8
                Base::clearDb ();
612 7
            }
613 7
        } else {
614 7
            if (!in_array (PageQueryResult::SCOPE_AUTHOR, getCurrentOption ('ignored_categories'))) {
615 8
                array_push ($this->entryArray, Author::getCount());
616 7
            }
617 7
            if (!in_array (PageQueryResult::SCOPE_SERIES, getCurrentOption ('ignored_categories'))) {
618 7
                $series = Serie::getCount();
619 8
                if (!is_null ($series)) array_push ($this->entryArray, $series);
620 8
            }
621 8
            if (!in_array (PageQueryResult::SCOPE_PUBLISHER, getCurrentOption ('ignored_categories'))) {
622 8
                $publisher = Publisher::getCount();
623 8
                if (!is_null ($publisher)) array_push ($this->entryArray, $publisher);
624 7
            }
625 7
            if (!in_array (PageQueryResult::SCOPE_TAG, getCurrentOption ('ignored_categories'))) {
626 7
                $tags = Tag::getCount();
627 8
                if (!is_null ($tags)) array_push ($this->entryArray, $tags);
628 4
            }
629 4
            if (!in_array (PageQueryResult::SCOPE_RATING, getCurrentOption ('ignored_categories'))) {
630 4
                $rating = Rating::getCount();
631 4
                if (!is_null ($rating)) array_push ($this->entryArray, $rating);
632 8
            }
633 8
            if (!in_array ("language", getCurrentOption ('ignored_categories'))) {
634
                $languages = Language::getCount();
635 8
                if (!is_null ($languages)) array_push ($this->entryArray, $languages);
636
            }
637 10
            foreach ($config['cops_calibre_custom_column'] as $lookup) {
638
                $customId = CustomColumn::getCustomId ($lookup);
639 17
                if (!is_null ($customId)) {
640
                    array_push ($this->entryArray, CustomColumn::getCount($customId));
641 17
                }
642 17
            }
643 17
            $this->entryArray = array_merge ($this->entryArray, Book::getCount());
644
645
            if (Base::isDatabaseArray ()) $this->title =  Base::getDbName ();
646 2
        }
647
    }
648 2
649 2
    public function isPaginated ()
650 1
    {
651
        return (getCurrentOption ("max_item_per_page") != -1 &&
652 1
                $this->totalNumber != -1 &&
653
                $this->totalNumber > getCurrentOption ("max_item_per_page"));
654
    }
655 2
656
    public function getNextLink ()
657 2
    {
658 2
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
659 1
        if (($this->n) * getCurrentOption ("max_item_per_page") < $this->totalNumber) {
660
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n + 1), "next", localize ("paging.next.alternate"));
661 2
        }
662
        return NULL;
663
    }
664 2
665
    public function getPrevLink ()
666 2
    {
667
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
668
        if ($this->n > 1) {
669 70
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n - 1), "previous", localize ("paging.previous.alternate"));
670
        }
671 70
        return NULL;
672 68
    }
673 46
674
    public function getMaxPage ()
675
    {
676
        return ceil ($this->totalNumber / getCurrentOption ("max_item_per_page"));
677
    }
678
679 3
    public function containsBook ()
680
    {
681 3
        if (count ($this->entryArray) == 0) return false;
682 3
        if (get_class ($this->entryArray [0]) == "EntryBook") return true;
683 2
        return false;
684 2
    }
685
}
686 1
687
class PageAllAuthors extends Page
688 3
{
689 3
    public function InitializeContent ()
690
    {
691
        $this->title = localize("authors.title");
692
        if (getCurrentOption ("author_split_first_letter") == 1) {
693
            $this->entryArray = Author::getAllAuthorsByFirstLetter();
694 1
        }
695
        else {
696 1
            $this->entryArray = Author::getAllAuthors();
697 1
        }
698 1
        $this->idPage = Author::ALL_AUTHORS_ID;
699 1
    }
700
}
701
702
class PageAllAuthorsLetter extends Page
703
{
704 7
    public function InitializeContent ()
705
    {
706 7
        $this->idPage = Author::getEntryIdByLetter ($this->idGet);
707 7
        $this->entryArray = Author::getAuthorsByStartingLetter ($this->idGet);
708 7
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("authorword", count ($this->entryArray)), count ($this->entryArray)), $this->idGet);
709 7
    }
710 7
}
711
712
class PageAuthorDetail extends Page
713
{
714
    public function InitializeContent ()
715 2
    {
716
        $author = Author::getAuthorById ($this->idGet);
717 2
        $this->idPage = $author->getEntryId ();
718 2
        $this->title = $author->name;
719 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByAuthor ($this->idGet, $this->n);
720 2
    }
721
}
722
723
class PageAllPublishers extends Page
724
{
725 1
    public function InitializeContent ()
726
    {
727 1
        $this->title = localize("publishers.title");
728 1
        $this->entryArray = Publisher::getAllPublishers();
729 1
        $this->idPage = Publisher::ALL_PUBLISHERS_ID;
730 1
    }
731 1
}
732
733
class PagePublisherDetail extends Page
734
{
735
    public function InitializeContent ()
736 2
    {
737
        $publisher = Publisher::getPublisherById ($this->idGet);
738 2
        $this->title = $publisher->name;
739 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByPublisher ($this->idGet, $this->n);
740 2
        $this->idPage = $publisher->getEntryId ();
741 2
    }
742
}
743
744
class PageAllTags extends Page
745
{
746 2
    public function InitializeContent ()
747
    {
748 2
        $this->title = localize("tags.title");
749 2
        $this->entryArray = Tag::getAllTags();
750 2
        $this->idPage = Tag::ALL_TAGS_ID;
751 2
    }
752
}
753
754
class PageAllLanguages extends Page
755
{
756 3
    public function InitializeContent ()
757
    {
758 3
        $this->title = localize("languages.title");
759 3
        $this->entryArray = Language::getAllLanguages();
760 3
        $this->idPage = Language::ALL_LANGUAGES_ID;
761 3
    }
762 3
}
763 3
764
class PageCustomDetail extends Page
765
{
766
    public function InitializeContent ()
767
    {
768 3
        $customId = getURLParam ("custom", NULL);
769
        $custom = CustomColumn::getCustomById ($customId, $this->idGet);
770 3
        $this->idPage = $custom->getEntryId ();
771 3
        $this->title = $custom->name;
772 3
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByCustom ($customId, $this->idGet, $this->n);
773 3
    }
774 3
}
775
776
class PageAllCustoms extends Page
777
{
778
    public function InitializeContent ()
779 1
    {
780
        $customId = getURLParam ("custom", NULL);
781 1
        $this->title = CustomColumn::getAllTitle ($customId);
782 1
        $this->entryArray = CustomColumn::getAllCustoms($customId);
783 1
        $this->idPage = CustomColumn::getAllCustomsId ($customId);
784 1
    }
785 1
}
786
787
class PageTagDetail extends Page
788
{
789
    public function InitializeContent ()
790 1
    {
791
        $tag = Tag::getTagById ($this->idGet);
792 1
        $this->idPage = $tag->getEntryId ();
793 1
        $this->title = $tag->name;
794 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByTag ($this->idGet, $this->n);
795 1
    }
796 1
}
797
798
class PageLanguageDetail extends Page
799
{
800
    public function InitializeContent ()
801 2
    {
802
        $language = Language::getLanguageById ($this->idGet);
803 2
        $this->idPage = $language->getEntryId ();
804 2
        $this->title = $language->lang_code;
805 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByLanguage ($this->idGet, $this->n);
806 2
    }
807
}
808
809
class PageAllSeries extends Page
810
{
811 1
    public function InitializeContent ()
812
    {
813 1
        $this->title = localize("series.title");
814 1
        $this->entryArray = Serie::getAllSeries();
815 1
        $this->idPage = Serie::ALL_SERIES_ID;
816 1
    }
817 1
}
818
819
class PageSerieDetail extends Page
820
{
821
    public function InitializeContent ()
822 1
    {
823
        $serie = Serie::getSerieById ($this->idGet);
824 1
        $this->title = $serie->name;
825 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksBySeries ($this->idGet, $this->n);
826 1
        $this->idPage = $serie->getEntryId ();
827 1
    }
828
}
829
830
class PageAllRating extends Page
831
{
832 1
    public function InitializeContent ()
833
    {
834 1
        $this->title = localize("ratings.title");
835 1
        $this->entryArray = Rating::getAllRatings();
836 1
        $this->idPage = Rating::ALL_RATING_ID;
837 1
    }
838 1
}
839
840
class PageRatingDetail extends Page
841
{
842
    public function InitializeContent ()
843 3
    {
844
        $rating = Rating::getRatingById ($this->idGet);
845 3
        $this->idPage = $rating->getEntryId ();
846 3
        $this->title =str_format (localize ("ratingword", $rating->name/2), $rating->name/2);
847 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByRating ($this->idGet, $this->n);
848 2
    }
849
}
850 1
851
class PageAllBooks extends Page
852 3
{
853 3
    public function InitializeContent ()
854
    {
855
        $this->title = localize ("allbooks.title");
856
        if (getCurrentOption ("titles_split_first_letter") == 1) {
857
            $this->entryArray = Book::getAllBooks();
858 1
        }
859
        else {
860 1
            list ($this->entryArray, $this->totalNumber) = Book::getBooks ($this->n);
861 1
        }
862
        $this->idPage = Book::ALL_BOOKS_ID;
863 1
    }
864 1
}
865 1
866
class PageAllBooksLetter extends Page
867 1
{
868 1
    public function InitializeContent ()
869
    {
870
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByStartingLetter ($this->idGet, $this->n);
871
        $this->idPage = Book::getEntryIdByLetter ($this->idGet);
872
873 4
        $count = $this->totalNumber;
874
        if ($count == -1)
875 4
            $count = count ($this->entryArray);
876 4
877 4
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("bookword", $count), $count), $this->idGet);
878 4
    }
879
}
880
881
class PageRecentBooks extends Page
882
{
883
    public function InitializeContent ()
884
    {
885
        $this->title = localize ("recent.title");
886
        $this->entryArray = Book::getAllRecentBooks ();
887
        $this->idPage = Book::ALL_RECENT_BOOKS_ID;
888
    }
889
}
890 24
891 24
class PageQueryResult extends Page
892
{
893
    const SCOPE_TAG = "tag";
894 29
    const SCOPE_RATING = "rating";
895 29
    const SCOPE_SERIES = "series";
896 29
    const SCOPE_AUTHOR = "author";
897 29
    const SCOPE_BOOK = "book";
898 29
    const SCOPE_PUBLISHER = "publisher";
899 7
900 7
    private function useTypeahead () {
901 29
        return !is_null (getURLParam ("search"));
902 22
    }
903 22
904 22
    private function searchByScope ($scope, $limit = FALSE) {
905
        $n = $this->n;
906 29
        $numberPerPage = NULL;
907 23
        $queryNormedAndUp = $this->query;
908 23
        if (useNormAndUp ()) {
909 28
            $queryNormedAndUp = normAndUp ($this->query);
910 23
        }
911 23
        if ($limit) {
912 25
            $n = 1;
913 22
            $numberPerPage = 5;
914 22
        }
915 24
        switch ($scope) {
916 23
            case self::SCOPE_BOOK :
917 23
                $array = Book::getBooksByStartingLetter ('%' . $queryNormedAndUp, $n, NULL, $numberPerPage);
918 23
                break;
919 23
            case self::SCOPE_AUTHOR :
920 23
                $array = Author::getAuthorsForSearch ('%' . $queryNormedAndUp);
921
                break;
922
            case self::SCOPE_SERIES :
923
                $array = Serie::getAllSeriesByQuery ($queryNormedAndUp);
924
                break;
925
            case self::SCOPE_TAG :
926 29
                $array = Tag::getAllTagsByQuery ($queryNormedAndUp, $n, NULL, $numberPerPage);
927
                break;
928
            case self::SCOPE_PUBLISHER :
929 22
                $array = Publisher::getAllPublishersByQuery ($queryNormedAndUp);
930 22
                break;
931 22
            default:
932 22
                $array = Book::getBooksByQuery (
933 22
                    array ("all" => "%" . $queryNormedAndUp . "%"), $n);
934 22
        }
935 22
936
        return $array;
937 22
    }
938 1
939 1
    public function doSearchByCategory () {
940 1
        $database = GetUrlParam (DB);
941 22
        $virtualLib = getURLParam(VL, 0);
942 22
        $out = array ();
943 1
        $pagequery = Base::PAGE_OPENSEARCH_QUERY;
944 1
        $dbArray = array ("");
945 1
        $d = $database;
946 1
        $query = $this->query;
947 1
        // Special case when no databases were chosen, we search on all databases
948 22
        if (Base::noDatabaseSelected ()) {
949 22
            $dbArray = Base::getDbNameList ();
950 22
            $d = 0;
951 22
        }
952 22
        $vl = $virtualLib;
953 22
        $vlArray = VirtualLib::getVLNameList($d);
954 3
        $vlArray = array($vlArray[$vl]);
955
        
956 22
        foreach ($dbArray as $dbKey) {
957
        	if (Base::noDatabaseSelected () && VirtualLib::isVLEnabled()) {
958 22
        		// If virtual libraries are enabled, but no Database is selected, 
959 22
        		// then iterate over all virtual libraries
960 22
        		$vlArray = VirtualLib::getVLNameList($d);
961 22
        		$vl = 0;
962 22
        	}
963 22
        	foreach ($vlArray as $vlKey) {	
964
	            if (Base::noDatabaseSelected ()) {
965 22
	                array_push ($this->entryArray, new Entry (VirtualLib::getDisplayName($dbKey, $vlKey), 
966
	                						DB . ":query:{$d}:{$vl}",
967
	                                        " ", "text",
968
	                                        array ( new LinkNavigation ("?" . DB . "={$d}&" . VL . "={$vl}")), "tt-header"));
969
	                Base::getDb ($d);
970
	                // TODO: set current virtual library in Base Or VirtualLib
971
	            }
972 21
	            foreach (array (PageQueryResult::SCOPE_BOOK,
973 21
	                            PageQueryResult::SCOPE_AUTHOR,
974 21
	                            PageQueryResult::SCOPE_SERIES,
975 21
	                            PageQueryResult::SCOPE_TAG,
976 21
	                            PageQueryResult::SCOPE_PUBLISHER) as $key) {
977 22
	                if (in_array($key, getCurrentOption ('ignored_categories'))) {
978 6
	                    continue;
979 6
	                }
980 6
	                $array = $this->searchByScope ($key, TRUE);
981 6
	
982 6
	                $i = 0;
983 6
	                if (count ($array) == 2 && is_array ($array [0])) {
984 22
	                    $total = $array [1];
985 22
	                    $array = $array [0];
986 22
	                } else {
987 1
	                    $total = count($array);
988 1
	                }
989 22
	                if ($total > 0) {
990 22
	                    // Comment to help the perl i18n script
991
	                    // str_format (localize("bookword", count($array))
992
	                    // str_format (localize("authorword", count($array))
993 31
	                    // str_format (localize("seriesword", count($array))
994
	                    // str_format (localize("tagword", count($array))
995 31
	                    // str_format (localize("publisherword", count($array))
996 31
	                    array_push ($this->entryArray, new Entry (str_format (localize ("search.result.{$key}"), $this->query), DB . ":query:{$d}:{$key}:{$vl}",
997 24
	                                        str_format (localize("{$key}word", $total), $total), "text",
998 24
	                                        array ( new LinkNavigation ("?page={$pagequery}&query={$query}&db={$d}&vl={$vl}&scope={$key}")),
999
	                                        Base::noDatabaseSelected () ? "" : "tt-header", $total));
1000
	                }
1001
	                if (!Base::noDatabaseSelected () && $this->useTypeahead ()) {
1002
	                    foreach ($array as $entry) {
1003
	                        array_push ($this->entryArray, $entry);
1004
	                        $i++;
1005 7
	                        if ($i > 4) { break; };
1006
	                    }
1007
	                }
1008 31
	            }
1009
	            $vl++;
1010
        	}
1011 31
            $d++;
1012 2
            if (Base::noDatabaseSelected ()) {
1013 2
                Base::clearDb ();
1014 2
            }
1015 2
        }
1016 2
        return $out;
1017 2
    }
1018 2
1019 2
    public function InitializeContent ()
1020 2
    {
1021 2
        $scope = getURLParam ("scope");
1022
        if (empty ($scope)) {
1023 29
            $this->title = str_format (localize ("search.result"), $this->query);
1024 22
        } else {
1025 22
            // Comment to help the perl i18n script
1026
            // str_format (localize ("search.result.author"), $this->query)
1027
            // str_format (localize ("search.result.tag"), $this->query)
1028 7
            // str_format (localize ("search.result.series"), $this->query)
1029 7
            // str_format (localize ("search.result.book"), $this->query)
1030 2
            // str_format (localize ("search.result.publisher"), $this->query)
1031 2
            $this->title = str_format (localize ("search.result.{$scope}"), $this->query);
1032 5
        }
1033
1034 7
        $crit = "%" . $this->query . "%";
1035
1036
        // Special case when we are doing a search and no database is selected
1037
        if (Base::noDatabaseSelected () && !$this->useTypeahead ()) {
1038
            $i = 0;
1039 1
            foreach (Base::getDbNameList () as $key) {
1040
                Base::clearDb ();
1041 1
                list ($array, $totalNumber) = Book::getBooksByQuery (array ("all" => $crit), 1, $i, 1);
0 ignored issues
show
The assignment to $array is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
1042 1
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$i}",
1043 1
                                        str_format (localize ("bookword", $totalNumber), $totalNumber), "text",
1044
                                        array ( new LinkNavigation ("?" . DB . "={$i}&page=9&query=" . $this->query)), "", $totalNumber));
1045
                $i++;
1046
            }
1047
            return;
1048
        }
1049
        if (empty ($scope)) {
1050
            $this->doSearchByCategory ();
1051
            return;
1052
        }
1053
1054
        $array = $this->searchByScope ($scope);
1055
        if (count ($array) == 2 && is_array ($array [0])) {
1056
            list ($this->entryArray, $this->totalNumber) = $array;
1057
        } else {
1058
            $this->entryArray = $array;
1059
        }
1060
    }
1061
}
1062
1063
class PageBookDetail extends Page
1064
{
1065
    public function InitializeContent ()
1066
    {
1067
        $this->book = Book::getBookById ($this->idGet);
1068
        $this->title = $this->book->title;
1069
    }
1070
}
1071
1072
class PageAbout extends Page
1073
{
1074
    public function InitializeContent ()
1075
    {
1076
        $this->title = localize ("about.title");
1077
    }
1078
}
1079
1080
class PageCustomize extends Page
1081
{
1082
    private function isChecked ($key, $testedValue = 1) {
1083
        $value = getCurrentOption ($key);
1084
        if (is_array ($value)) {
1085
            if (in_array ($testedValue, $value)) {
1086
                return "checked='checked'";
1087
            }
1088
        } else {
1089
            if ($value == $testedValue) {
1090
                return "checked='checked'";
1091
            }
1092
        }
1093
        return "";
1094
    }
1095
1096
    private function isSelected ($key, $value) {
1097
        if (getCurrentOption ($key) == $value) {
1098
            return "selected='selected'";
1099
        }
1100
        return "";
1101
    }
1102
1103
    private function getStyleList () {
1104
        $result = array ();
1105
        foreach (glob ("templates/" . getCurrentTemplate () . "/styles/style-*.css") as $filename) {
1106
            if (preg_match ('/styles\/style-(.*?)\.css/', $filename, $m)) {
1107
                array_push ($result, $m [1]);
1108
            }
1109
        }
1110
        return $result;
1111
    }
1112
1113
    public function InitializeContent ()
1114
    {
1115
        $this->title = localize ("customize.title");
1116
        $this->entryArray = array ();
1117
1118
        $ignoredBaseArray = array (PageQueryResult::SCOPE_AUTHOR,
1119
                                   PageQueryResult::SCOPE_TAG,
1120
                                   PageQueryResult::SCOPE_SERIES,
1121
                                   PageQueryResult::SCOPE_PUBLISHER,
1122
                                   PageQueryResult::SCOPE_RATING,
1123
                                   "language");
1124
1125
        $content = "";
1126
        array_push ($this->entryArray, new Entry ("Template", "",
1127
                                        "<span style='cursor: pointer;' onclick='$.cookie(\"template\", \"bootstrap\", { expires: 365 });window.location=$(\".headleft\").attr(\"href\");'>Click to switch to Bootstrap</span>", "text",
1128
                                        array ()));
1129
        if (!preg_match("/(Kobo|Kindle\/3.0|EBRD1101)/", $_SERVER['HTTP_USER_AGENT'])) {
1130
            $content .= '<select id="style" onchange="updateCookie (this);">';
1131
            foreach ($this-> getStyleList () as $filename) {
1132
                $content .= "<option value='{$filename}' " . $this->isSelected ("style", $filename) . ">{$filename}</option>";
1133
            }
1134
            $content .= '</select>';
1135
        } else {
1136
            foreach ($this-> getStyleList () as $filename) {
1137
                $content .= "<input type='radio' onchange='updateCookieFromCheckbox (this);' id='style-{$filename}' name='style' value='{$filename}' " . $this->isChecked ("style", $filename) . " /><label for='style-{$filename}'> {$filename} </label>";
1138
            }
1139
        }
1140
        array_push ($this->entryArray, new Entry (localize ("customize.style"), "",
1141
                                        $content, "text",
1142
                                        array ()));
1143
        if (!useServerSideRendering ()) {
1144
            $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="use_fancyapps" ' . $this->isChecked ("use_fancyapps") . ' />';
1145
            array_push ($this->entryArray, new Entry (localize ("customize.fancybox"), "",
1146
                                            $content, "text",
1147
                                            array ()));
1148
        }
1149
        $content = '<input type="number" onchange="updateCookie (this);" id="max_item_per_page" value="' . getCurrentOption ("max_item_per_page") . '" min="-1" max="1200" pattern="^[-+]?[0-9]+$" />';
1150
        array_push ($this->entryArray, new Entry (localize ("customize.paging"), "",
1151
                                        $content, "text",
1152
                                        array ()));
1153
        $content = '<input type="text" onchange="updateCookie (this);" id="email" value="' . getCurrentOption ("email") . '" />';
1154
        array_push ($this->entryArray, new Entry (localize ("customize.email"), "",
1155
                                        $content, "text",
1156
                                        array ()));
1157
        $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="html_tag_filter" ' . $this->isChecked ("html_tag_filter") . ' />';
1158
        array_push ($this->entryArray, new Entry (localize ("customize.filter"), "",
1159
                                        $content, "text",
1160
                                        array ()));
1161
        $content = "";
1162
        foreach ($ignoredBaseArray as $key) {
1163
            $keyPlural = preg_replace ('/(ss)$/', 's', $key . "s");
1164
            $content .=  '<input type="checkbox" name="ignored_categories[]" onchange="updateCookieFromCheckboxGroup (this);" id="ignored_categories_' . $key . '" ' . $this->isChecked ("ignored_categories", $key) . ' > ' . localize ("{$keyPlural}.title") . '</input> ';
1165
        }
1166
1167
        array_push ($this->entryArray, new Entry (localize ("customize.ignored"), "",
1168
                                        $content, "text",
1169
                                        array ()));
1170
    }
1171
}
1172
1173
1174
abstract class Base
1175
{
1176
    const PAGE_INDEX = "index";
1177
    const PAGE_ALL_AUTHORS = "1";
1178
    const PAGE_AUTHORS_FIRST_LETTER = "2";
1179
    const PAGE_AUTHOR_DETAIL = "3";
1180
    const PAGE_ALL_BOOKS = "4";
1181 108
    const PAGE_ALL_BOOKS_LETTER = "5";
1182 108
    const PAGE_ALL_SERIES = "6";
1183 108
    const PAGE_SERIE_DETAIL = "7";
1184
    const PAGE_OPENSEARCH = "8";
1185
    const PAGE_OPENSEARCH_QUERY = "9";
1186 46
    const PAGE_ALL_RECENT_BOOKS = "10";
1187 46
    const PAGE_ALL_TAGS = "11";
1188
    const PAGE_TAG_DETAIL = "12";
1189
    const PAGE_BOOK_DETAIL = "13";
1190 46
    const PAGE_ALL_CUSTOMS = "14";
1191 46
    const PAGE_CUSTOM_DETAIL = "15";
1192 46
    const PAGE_ABOUT = "16";
1193 46
    const PAGE_ALL_LANGUAGES = "17";
1194 46
    const PAGE_LANGUAGE_DETAIL = "18";
1195
    const PAGE_CUSTOMIZE = "19";
1196
    const PAGE_ALL_PUBLISHERS = "20";
1197 45
    const PAGE_PUBLISHER_DETAIL = "21";
1198 45
    const PAGE_ALL_RATINGS = "22";
1199
    const PAGE_RATING_DETAIL = "23";
1200
1201 4
    const COMPATIBILITY_XML_ALDIKO = "aldiko";
1202 4
    
1203 4
    const SQL_SETTING = 'SELECT val FROM preferences WHERE key = "{0}"';
1204 4
1205
    private static $db = NULL;
1206 1
1207
    public static function isDatabaseArray () {
1208
        global $config;
1209
        return is_array ($config['calibre_directory']);
1210 5
    }
1211 5
    
1212 5
    public static function isMultipleDatabaseEnabled () {
1213 5
    	return (self::isDatabaseArray () || VirtualLib::isVLEnabled());
1214
    }
1215
1216
    public static function useAbsolutePath () {
1217
        global $config;
1218
        $path = self::getDbDirectory();
1219 1
        return preg_match ('/^\//', $path) || // Linux /
1220 1
               preg_match ('/^\w\:/', $path); // Windows X:
1221 1
    }
1222 1
1223 1
    public static function noDatabaseSelected () {
1224
        return self::isMultipleDatabaseEnabled() && is_null (GetUrlParam (DB));
1225
    }
1226 1
1227 1
    public static function getDbList () {
1228
        global $config;
1229
        if (self::isDatabaseArray ()) {
1230
            return $config['calibre_directory'];
1231
        } else {
1232 90
            return array ("" => $config['calibre_directory']);
1233 90
        }
1234 90
    }
1235 9
1236 9
    public static function getDbNameList () {
1237
        global $config;
1238
        if (self::isDatabaseArray ()) {
1239 9
            return array_keys ($config['calibre_directory']);
1240 9
        } else {
1241
            return array ("");
1242 81
        }
1243
    }
1244
1245
    public static function getDbName ($database = NULL) {
1246 61
        global $config;
1247 61
        if (self::isDatabaseArray ()) {
1248
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1249
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1250 2
                return self::error ($database);
1251 2
            }
1252
            $array = array_keys ($config['calibre_directory']);
1253
            return  $array[$database];
1254 2
        }
1255
        return "";
1256
    }
1257 126
1258 126
    public static function getDbDirectory ($database = NULL) {
1259
        global $config;
1260 61
        if (self::isDatabaseArray ()) {
1261 60
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1262 60
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1263 7
                return self::error ($database);
1264 7
            }
1265 60
            $array = array_values ($config['calibre_directory']);
1266 2
            return  $array[$database];
1267
        }
1268 61
        return $config['calibre_directory'];
1269 2
    }
1270
1271 60
1272 125
    public static function getDbFileName ($database = NULL) {
1273
        return self::getDbDirectory ($database) .'metadata.db';
1274
    }
1275 4
1276 4
    private static function error ($database) {
1277 3
        if (php_sapi_name() != "cli") {
1278 3
            header("location: checkconfig.php?err=1");
1279 2
        }
1280 2
        throw new Exception("Database <{$database}> not found.");
1281 1
    }
1282 1
1283
    public static function getDb ($database = NULL) {
1284 2
        if (is_null (self::$db)) {
1285
            try {
1286
                if (is_readable (self::getDbFileName ($database))) {
1287 58
                    self::$db = new PDO('sqlite:'. self::getDbFileName ($database));
1288 58
                    if (useNormAndUp ()) {
1289 58
                        self::$db->sqliteCreateFunction ('normAndUp', 'normAndUp', 1);
1290
                    }
1291 13
                } else {
1292 13
                    self::error ($database);
1293
                }
1294
            } catch (Exception $e) {
1295 8
                self::error ($database);
1296 8
            }
1297 7
        }
1298 7
        return self::$db;
1299 8
    }
1300 8
1301 8
    public static function checkDatabaseAvailability () {
1302 8
        if (self::noDatabaseSelected ()) {
1303 8
            for ($i = 0; $i < count (self::getDbList ()); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1304 8
                self::getDb ($i);
1305
                self::clearDb ();
1306
            }
1307 35
        } else {
1308 35
            self::getDb ();
1309 35
        }
1310 35
        return true;
1311
    }
1312 25
1313 25
    public static function clearDb () {
1314 17
        self::$db = NULL;
1315 17
    }
1316 8
1317
    public static function executeQuerySingle ($query, $database = NULL) {
1318 25
        return self::getDb ($database)->query($query)->fetchColumn();
1319 25
    }
1320 25
1321 25
    public static function getCountGeneric($table, $id, $pageId, $numberOfString = NULL) {
1322 35
        if (!$numberOfString) {
1323
            $numberOfString = $table . ".alphabetical";
1324
        }
1325 73
        $count = self::executeQuerySingle ('select count(*) from ' . $table);
1326 73
        if ($count == 0) return NULL;
1327
        $entry = new Entry (localize($table . ".title"), $id,
1328 73
            str_format (localize($numberOfString, $count), $count), "text",
1329 7
            array ( new LinkNavigation ("?page=".$pageId)), "", $count);
1330 7
        return $entry;
1331 7
    }
1332
1333 73
    public static function getEntryArrayWithBookNumber ($query, $columns, $params, $category) {
1334 71
        list (, $result) = self::executeQuery ($query, $columns, "", $params, -1);
1335 71
        $entryArray = array();
1336
        while ($post = $result->fetchObject ())
1337 73
        {
1338 73
            $instance = new $category ($post);
1339
            if (property_exists($post, "sort")) {
1340 28
                $title = $post->sort;
1341 28
            } else {
1342 28
                $title = $post->name;
1343
            }
1344
            array_push ($entryArray, new Entry ($title, $instance->getEntryId (),
1345 28
                str_format (localize("bookword", $post->count), $post->count), "text",
1346 28
                array ( new LinkNavigation ($instance->getUri ())), "", $post->count));
1347 28
        }
1348
        return $entryArray;
1349 73
    }
1350 73
1351 73
    public static function executeQuery($query, $columns, $filter, $params, $n, $database = NULL, $numberPerPage = NULL) {
1352
        $totalResult = -1;
1353
1354
        if (useNormAndUp ()) {
1355
            $query = preg_replace("/upper/", "normAndUp", $query);
1356
            $columns = preg_replace("/upper/", "normAndUp", $columns);
1357
        }
1358
1359
        if (is_null ($numberPerPage)) {
1360
            $numberPerPage = getCurrentOption ("max_item_per_page");
1361
        }
1362
1363
        if ($numberPerPage != -1 && $n != -1)
1364
        {
1365
            // First check total number of results
1366
            $result = self::getDb ($database)->prepare (str_format ($query, "count(*)", $filter));
1367
            $result->execute ($params);
1368
            $totalResult = $result->fetchColumn ();
1369
1370
            // Next modify the query and params
1371
            $query .= " limit ?, ?";
1372
            array_push ($params, ($n - 1) * $numberPerPage, $numberPerPage);
1373
        }
1374
1375
        $result = self::getDb ($database)->prepare(str_format ($query, $columns, $filter));
1376
        $result->execute ($params);
1377
        return array ($totalResult, $result);
1378
    }
1379
1380
    /**
1381
     * Gets a calibre setting from the database.
1382
     * 
1383
     * @param string $name Name of the property
1384
     * @param int $database Database to query from
1385
     * @return string Value of the property
1386
     */
1387
    public static function getCalibreSetting($name, $database = NULL) {
1388
    	$query = str_format(self::SQL_SETTING, $name);
1389
    	return self::executeQuerySingle($query, $database);
1390
    }
1391
}
1392