Completed
Pull Request — master (#232)
by
unknown
12:44
created

Link   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 33
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 0

Test Coverage

Coverage 100%
Metric Value
wmc 3
lcom 0
cbo 0
dl 0
loc 33
ccs 10
cts 10
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A hrefXhtml() 0 3 1
A __construct() 0 8 1
A getScriptName() 0 4 1
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");
11
date_default_timezone_set($config['default_timezone']);
12
13
14
function useServerSideRendering () {
15
    global $config;
16
    return preg_match("/" . $config['cops_server_side_render'] . "/", $_SERVER['HTTP_USER_AGENT']);
17 3
}
18 3
19
function serverSideRender ($data) {
20
    // Get the templates
21
    $theme = getCurrentTemplate ();
22
    $header = file_get_contents('templates/' . $theme . '/header.html');
23 2
    $footer = file_get_contents('templates/' . $theme . '/footer.html');
24 2
    $main = file_get_contents('templates/' . $theme . '/main.html');
25 2
    $bookdetail = file_get_contents('templates/' . $theme . '/bookdetail.html');
26 2
    $page = file_get_contents('templates/' . $theme . '/page.html');
27 2
28 2
    // Generate the function for the template
29
    $template = new doT ();
30
    $dot = $template->template ($page, array ("bookdetail" => $bookdetail,
31 2
                                              "header" => $header,
32 2
                                              "footer" => $footer,
33 2
                                              "main" => $main));
34 2
    // If there is a syntax error in the function created
35 2
    // $dot will be equal to FALSE
36
    if (!$dot) {
37
        return FALSE;
38 2
    }
39
    // Execute the template
40
    if (!empty ($data)) {
41
        return $dot ($data);
42 2
    }
43
44
    return NULL;
45
}
46 2
47
function getQueryString () {
48
    if ( isset($_SERVER['QUERY_STRING']) ) {
49
        return $_SERVER['QUERY_STRING'];
50 18
    }
51 16
    return "";
52
}
53 2
54
function notFound () {
55
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
56
    header("Status: 404 Not Found");
57
58
    $_SERVER['REDIRECT_STATUS'] = 404;
59
}
60
61
function getURLParam ($name, $default = NULL) {
62
    if (!empty ($_GET) && isset($_GET[$name]) && $_GET[$name] != "") {
63
        return $_GET[$name];
64 101
    }
65 24
    return $default;
66
}
67 101
68
function getCurrentOption ($option) {
69
    global $config;
70
    if (isset($_COOKIE[$option])) {
71 87
        if (isset($config ["cops_" . $option]) && is_array ($config ["cops_" . $option])) {
72 87
            return explode (",", $_COOKIE[$option]);
73 2
        } else {
74
            return $_COOKIE[$option];
75
        }
76 2
    }
77
    if ($option == "style") {
78
        return "default";
79 85
    }
80 2
81
    if (isset($config ["cops_" . $option])) {
82
        return $config ["cops_" . $option];
83 85
    }
84 85
85
    return "";
86
}
87
88
function getCurrentCss () {
89
    return "templates/" . getCurrentTemplate () . "/styles/style-" . getCurrentOption ("style") . ".css";
90
}
91 2
92
function getCurrentTemplate () {
93
    return getCurrentOption ("template");
94
}
95 4
96
function getUrlWithVersion ($url) {
97
    return $url . "?v=" . VERSION;
98
}
99 50
100
function xml2xhtml($xml) {
101
    return preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', create_function('$m', '
102
        $xhtml_tags = array("br", "hr", "input", "frame", "img", "area", "link", "col", "base", "basefont", "param");
103 35
        return in_array($m[1], $xhtml_tags) ? "<$m[1]$m[2] />" : "<$m[1]$m[2]></$m[1]>";
104
    '), $xml);
105
}
106 35
107
function display_xml_error($error)
108
{
109
    $return = "";
110
    $return .= str_repeat('-', $error->column) . "^\n";
111
112
    switch ($error->level) {
113
        case LIBXML_ERR_WARNING:
114
            $return .= "Warning $error->code: ";
115
            break;
116
         case LIBXML_ERR_ERROR:
117
            $return .= "Error $error->code: ";
118
            break;
119
        case LIBXML_ERR_FATAL:
120
            $return .= "Fatal Error $error->code: ";
121
            break;
122
    }
123
124
    $return .= trim($error->message) .
125
               "\n  Line: $error->line" .
126
               "\n  Column: $error->column";
127
128
    if ($error->file) {
129
        $return .= "\n  File: $error->file";
130
    }
131
132
    return "$return\n\n--------------------------------------------\n\n";
133
}
134
135
function are_libxml_errors_ok ()
136
{
137
    $errors = libxml_get_errors();
138
139 35
    foreach ($errors as $error) {
140
        if ($error->code == 801) return false;
141 35
    }
142
    return true;
143 35
}
144 35
145
function html2xhtml ($html) {
146
    $doc = new DOMDocument();
147
    libxml_use_internal_errors(true);
148 35
149 35
    $doc->loadHTML('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>' .
150
                        $html  . '</body></html>'); // Load the HTML
151 35
    $output = $doc->saveXML($doc->documentElement); // Transform to an Ansi xml stream
152 35
    $output = xml2xhtml($output);
153 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)) {
154 35
        $output = $matches [1]; // Remove <html><body>
155 35
    }
156 35
    /*
157 35
    // In case of error with summary, use it to debug
158
    $errors = libxml_get_errors();
159
160
    foreach ($errors as $error) {
161
        $output .= display_xml_error($error);
162
    }
163
    */
164
165
    if (!are_libxml_errors_ok ()) $output = "HTML code not valid.";
166
167 35
    libxml_use_internal_errors(false);
168
    return $output;
169 35
}
170 35
171
/**
172
 * This method is a direct copy-paste from
173
 * http://tmont.com/blargh/2010/1/string-format-in-php
174
 */
175
function str_format($format) {
0 ignored issues
show
Unused Code introduced by
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...
176
    $args = func_get_args();
177
    $format = array_shift($args);
178 94
179 94
    preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
180
    $offset = 0;
181 94
    foreach ($matches[1] as $data) {
182 94
        $i = $data[0];
183 94
        $format = substr_replace($format, @$args[$i], $offset + $data[1] - 1, 2 + strlen($i));
184 94
        $offset += strlen(@$args[$i]) - 2 - strlen($i);
185 94
    }
186 94
187 94
    return $format;
188
}
189 94
190
/**
191
 * Get all accepted languages from the browser and put them in a sorted array
192
 * languages id are normalized : fr-fr -> fr_FR
193
 * @return array of languages
194
 */
195
function getAcceptLanguages() {
196
    $langs = array();
197
198 16
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
199
        // break up string into pieces (languages and q factors)
200 16
        $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
201
        if (preg_match('/^(\w{2})-\w{2}$/', $accept, $matches)) {
202 16
            // Special fix for IE11 which send fr-FR and nothing else
203 16
            $accept = $accept . "," . $matches[1] . ";q=0.8";
204
        }
205 3
        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $lang_parse);
206 3
207 16
        if (count($lang_parse[1])) {
208
            $langs = array();
209 16
            foreach ($lang_parse[1] as $lang) {
210 16
                // Format the language code (not standard among browsers)
211 16
                if (strlen($lang) == 5) {
212
                    $lang = str_replace("-", "_", $lang);
213 16
                    $splitted = preg_split("/_/", $lang);
214 11
                    $lang = $splitted[0] . "_" . strtoupper($splitted[1]);
215 11
                }
216 11
                array_push($langs, $lang);
217 11
            }
218 16
            // create a list like "en" => 0.8
219 16
            $langs = array_combine($langs, $lang_parse[4]);
220
221 16
            // set default to 1 for any without q factor
222
            foreach ($langs as $lang => $val) {
223
                if ($val === '') $langs[$lang] = 1;
224 16
            }
225 16
226 16
            // sort list based on value
227
            arsort($langs, SORT_NUMERIC);
228
        }
229 16
    }
230 16
231 16
    return $langs;
232
}
233 16
234
/**
235
 * Find the best translation file possible based on the accepted languages
236
 * @return array of language and language file
237
 */
238
function getLangAndTranslationFile() {
239
    global $config;
240
    $langs = array();
241 17
    $lang = "en";
242 17
    if (!empty($config['cops_language'])) {
243 17
        $lang = $config['cops_language'];
244 17
    }
245
    elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
246
        $langs = getAcceptLanguages();
247 17
    }
248 16
    //echo var_dump($langs);
249 16
    $lang_file = NULL;
250
    foreach ($langs as $language => $val) {
251 17
        $temp_file = dirname(__FILE__). '/lang/Localization_' . $language . '.json';
252 17
        if (file_exists($temp_file)) {
253 16
            $lang = $language;
254 16
            $lang_file = $temp_file;
255 16
            break;
256 16
        }
257 16
    }
258
    if (empty ($lang_file)) {
259 17
        $lang_file = dirname(__FILE__). '/lang/Localization_' . $lang . '.json';
260 17
    }
261 3
    return array($lang, $lang_file);
262 3
}
263 17
264
/**
265
 * This method is based on this page
266
 * http://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php/
267
 */
268
function localize($phrase, $count=-1, $reset=false) {
269
    global $config;
270
    if ($count == 0)
271 114
        $phrase .= ".none";
272 114
    if ($count == 1)
273 114
        $phrase .= ".one";
274 114
    if ($count > 1)
275 114
        $phrase .= ".many";
276 114
277 114
    /* Static keyword is used to ensure the file is loaded only once */
278
    static $translations = NULL;
279
    if ($reset) {
280 114
        $translations = NULL;
281 114
    }
282 16
    /* If no instance of $translations has occured load the language file */
283 16
    if (is_null($translations)) {
284
        $lang_file_en = NULL;
285 114
        list ($lang, $lang_file) = getLangAndTranslationFile();
286 17
        if ($lang != "en") {
287 17
            $lang_file_en = dirname(__FILE__). '/lang/' . 'Localization_en.json';
288 17
        }
289 1
290 1
        $lang_file_content = file_get_contents($lang_file);
291
        /* Load the language file as a JSON object and transform it into an associative array */
292 17
        $translations = json_decode($lang_file_content, true);
293
294 17
        /* Clean the array of all unfinished translations */
295
        foreach (array_keys ($translations) as $key) {
296
            if (preg_match ("/^##TODO##/", $key)) {
297 17
                unset ($translations [$key]);
298 17
            }
299 1
        }
300 1
        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...
301 17
        {
302
            $lang_file_content = file_get_contents($lang_file_en);
303 17
            $translations_en = json_decode($lang_file_content, true);
304 1
            $translations = array_merge ($translations_en, $translations);
305 1
        }
306 1
    }
307 1
    if (array_key_exists ($phrase, $translations)) {
308 17
        return $translations[$phrase];
309 114
    }
310 114
    return $phrase;
311
}
312 1
313
function addURLParameter($urlParams, $paramName, $paramValue) {
314
    if (empty ($urlParams)) {
315
        $urlParams = "";
316 58
    }
317 48
    $start = "";
318 48
    if (preg_match ("#^\?(.*)#", $urlParams, $matches)) {
319 58
        $start = "?";
320 58
        $urlParams = $matches[1];
321 15
    }
322 15
    $params = array();
323 15
    parse_str($urlParams, $params);
324 58
    if (empty ($paramValue) && $paramValue != 0) {
325 58
        unset ($params[$paramName]);
326 58
    } else {
327
        $params[$paramName] = $paramValue;
328
    }
329 58
    return $start . http_build_query($params);
330
}
331 58
332
function useNormAndUp () {
333
    global $config;
334
    return $config ['cops_normalized_search'] == "1";
335 107
}
336 107
337
function normalizeUtf8String( $s) {
338
    include_once 'transliteration.php';
339
    return _transliteration_process($s);
340 8
}
341 8
342
function normAndUp ($s) {
343
    return mb_strtoupper (normalizeUtf8String($s), 'UTF-8');
344
}
345 7
346
class Link
347
{
348
    const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail";
349
    const OPDS_IMAGE_TYPE = "http://opds-spec.org/image";
350
    const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition";
351
    const OPDS_NAVIGATION_TYPE = "application/atom+xml;profile=opds-catalog;kind=navigation";
352
    const OPDS_PAGING_TYPE = "application/atom+xml;profile=opds-catalog;kind=acquisition";
353
354
    public $href;
355
    public $type;
356
    public $rel;
357
    public $title;
358
    public $facetGroup;
359
    public $activeFacet;
360
361
    public function __construct($phref, $ptype, $prel = NULL, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
362
        $this->href = $phref;
363 96
        $this->type = $ptype;
364 96
        $this->rel = $prel;
365 96
        $this->title = $ptitle;
366 96
        $this->facetGroup = $pfacetGroup;
367 96
        $this->activeFacet = $pactiveFacet;
368 96
    }
369 96
370 96
    public function hrefXhtml () {
371
        return $this->href;
372 10
    }
373 10
374
    public function getScriptName() {
375
        $parts = explode('/', $_SERVER["SCRIPT_NAME"]);
376
        return $parts[count($parts) - 1];
377
    }
378
}
379 95
380 95
class LinkNavigation extends Link
381 95
{
382 95
    public function __construct($phref, $prel = NULL, $ptitle = NULL) {
383 95
        parent::__construct ($phref, Link::OPDS_NAVIGATION_TYPE, $prel, $ptitle);
384
        if (!is_null (GetUrlParam (DB))) $this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
385
        if (!preg_match ("#^\?(.*)#", $this->href) && !empty ($this->href)) $this->href = "?" . $this->href;
386 95
        if (preg_match ("/(bookdetail|getJSON).php/", parent::getScriptName())) {
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getScriptName() instead of __construct()). Are you sure this is correct? If so, you might want to change this to $this->getScriptName().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
387
            $this->href = "index.php" . $this->href;
388 95
        } else {
389
            $this->href = parent::getScriptName() . $this->href;
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getScriptName() instead of __construct()). Are you sure this is correct? If so, you might want to change this to $this->getScriptName().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
390
        }
391
    }
392
}
393 1
394 1
class LinkFacet extends Link
395 1
{
396 1
    public function __construct($phref, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
397 1
        parent::__construct ($phref, Link::OPDS_PAGING_TYPE, "http://opds-spec.org/facet", $ptitle, $pfacetGroup, $pactiveFacet);
398
        if (!is_null (GetUrlParam (DB))) $this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
399
        $this->href = parent::getScriptName() . $this->href;
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getScriptName() instead of __construct()). Are you sure this is correct? If so, you might want to change this to $this->getScriptName().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
400
    }
401
}
402
403
class Entry
404
{
405
    public $title;
406
    public $id;
407
    public $content;
408
    public $numberOfElement;
409
    public $contentType;
410
    public $linkArray;
411
    public $localUpdated;
412
    public $className;
413
    private static $updated = NULL;
414
415
    public static $icons = array(
416
        Author::ALL_AUTHORS_ID       => 'images/author.png',
417
        Serie::ALL_SERIES_ID         => 'images/serie.png',
418
        Book::ALL_RECENT_BOOKS_ID    => 'images/recent.png',
419
        Tag::ALL_TAGS_ID             => 'images/tag.png',
420
        Language::ALL_LANGUAGES_ID   => 'images/language.png',
421
        CustomColumn::ALL_CUSTOMS_ID => 'images/tag.png',
422
        "cops:books$"             => 'images/allbook.png',
423
        "cops:books:letter"       => 'images/allbook.png',
424
        Publisher::ALL_PUBLISHERS_ID => 'images/publisher.png'
425
    );
426
427
    public function getUpdatedTime () {
428
        if (!is_null ($this->localUpdated)) {
429
            return date (DATE_ATOM, $this->localUpdated);
430
        }
431
        if (is_null (self::$updated)) {
432
            self::$updated = time();
433
        }
434 7
        return date (DATE_ATOM, self::$updated);
435 7
    }
436 7
437
    public function getNavLink () {
438 7
        foreach ($this->linkArray as $link) {
439
            if ($link->type != Link::OPDS_NAVIGATION_TYPE) { continue; }
440
441
            return $link->hrefXhtml ();
442
        }
443 89
        return "#";
444 89
    }
445 89
446 89
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pclass = "", $pcount = 0) {
447 89
        global $config;
448 89
        $this->title = $ptitle;
449 89
        $this->id = $pid;
450 89
        $this->content = $pcontent;
451 89
        $this->contentType = $pcontentType;
452
        $this->linkArray = $plinkArray;
453 89
        $this->className = $pclass;
454 89
        $this->numberOfElement = $pcount;
455 89
456
        if ($config['cops_show_icons'] == 1)
457 89
        {
458 50
            foreach (self::$icons as $reg => $image)
459 50
            {
460
                if (preg_match ("/" . $reg . "/", $pid)) {
461 89
                    array_push ($this->linkArray, new Link (getUrlWithVersion ($image), "image/png", Link::OPDS_THUMBNAIL_TYPE));
462 89
                    break;
463
                }
464 89
            }
465 89
        }
466
467
        if (!is_null (GetUrlParam (DB))) $this->id = str_replace ("cops:", "cops:" . GetUrlParam (DB) . ":", $this->id);
468
    }
469
}
470
471
class EntryBook extends Entry
472 39
{
473 39
    public $book;
474 39
475 39
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pbook) {
476 39
        parent::__construct ($ptitle, $pid, $pcontent, $pcontentType, $plinkArray);
477
        $this->book = $pbook;
478
        $this->localUpdated = $pbook->timestamp;
479
    }
480
481
    public function getCoverThumbnail () {
482
        foreach ($this->linkArray as $link) {
483
            if ($link->rel == Link::OPDS_THUMBNAIL_TYPE)
484
                return $link->hrefXhtml ();
485
        }
486
        return null;
487
    }
488
489
    public function getCover () {
490
        foreach ($this->linkArray as $link) {
491
            if ($link->rel == Link::OPDS_IMAGE_TYPE)
492
                return $link->hrefXhtml ();
493
        }
494
        return null;
495
    }
496
}
497
498
class Page
499
{
500
    public $title;
501
    public $subtitle = "";
502
    public $authorName = "";
503
    public $authorUri = "";
504
    public $authorEmail = "";
505
    public $idPage;
506
    public $idGet;
507
    public $query;
508
    public $favicon;
509
    public $n;
510
    public $book;
511 81
    public $totalNumber = -1;
512
    public $entryArray = array();
513
514 81
    public static function getPage ($pageId, $id, $query, $n)
515 3
    {
516 78
        switch ($pageId) {
517 1
            case Base::PAGE_ALL_AUTHORS :
518 77
                return new PageAllAuthors ($id, $query, $n);
519 7
            case Base::PAGE_AUTHORS_FIRST_LETTER :
520 70
                return new PageAllAuthorsLetter ($id, $query, $n);
521 2
            case Base::PAGE_AUTHOR_DETAIL :
522 68
                return new PageAuthorDetail ($id, $query, $n);
523 1
            case Base::PAGE_ALL_TAGS :
524 67
                return new PageAllTags ($id, $query, $n);
525 2
            case Base::PAGE_TAG_DETAIL :
526 65
                return new PageTagDetail ($id, $query, $n);
527 1
            case Base::PAGE_ALL_LANGUAGES :
528 64
                return new PageAllLanguages ($id, $query, $n);
529 3
            case Base::PAGE_LANGUAGE_DETAIL :
530 61
                return new PageLanguageDetail ($id, $query, $n);
531 3
            case Base::PAGE_ALL_CUSTOMS :
532 58
                return new PageAllCustoms ($id, $query, $n);
533 1
            case Base::PAGE_CUSTOM_DETAIL :
534 57
                return new PageCustomDetail ($id, $query, $n);
535 1
            case Base::PAGE_ALL_RATINGS :
536 56
                return new PageAllRating ($id, $query, $n);
537 2
            case Base::PAGE_RATING_DETAIL :
538 54
                return new PageRatingDetail ($id, $query, $n);
539 3
            case Base::PAGE_ALL_SERIES :
540 51
                return new PageAllSeries ($id, $query, $n);
541 1
            case Base::PAGE_ALL_BOOKS :
542 50
                return new PageAllBooks ($id, $query, $n);
543 4
            case Base::PAGE_ALL_BOOKS_LETTER:
544 46
                return new PageAllBooksLetter ($id, $query, $n);
545 1
            case Base::PAGE_ALL_RECENT_BOOKS :
546 45
                return new PageRecentBooks ($id, $query, $n);
547 31
            case Base::PAGE_SERIE_DETAIL :
548 14
                return new PageSerieDetail ($id, $query, $n);
549 1
            case Base::PAGE_OPENSEARCH_QUERY :
550 13
                return new PageQueryResult ($id, $query, $n);
551 2
            case Base::PAGE_BOOK_DETAIL :
552 11
                return new PageBookDetail ($id, $query, $n);
553 1
            case Base::PAGE_ALL_PUBLISHERS:
554 10
                return new PageAllPublishers ($id, $query, $n);
555
            case Base::PAGE_PUBLISHER_DETAIL :
556 10
                return new PagePublisherDetail ($id, $query, $n);
557
            case Base::PAGE_ABOUT :
558 10
                return new PageAbout ($id, $query, $n);
559 10
            case Base::PAGE_CUSTOMIZE :
560 10
                return new PageCustomize ($id, $query, $n);
561 10
            default:
562 10
                $page = new Page ($id, $query, $n);
563
                $page->idPage = "cops:catalog";
564
                return $page;
565 81
        }
566 81
    }
567
568 81
    public function __construct($pid, $pquery, $pn) {
569 81
        global $config;
570 81
571 81
        $this->idGet = $pid;
572 81
        $this->query = $pquery;
573 81
        $this->n = $pn;
574 81
        $this->favicon = $config['cops_icon'];
575 81
        $this->authorName = empty($config['cops_author_name']) ? utf8_encode('S�bastien Lucas') : $config['cops_author_name'];
576
        $this->authorUri = empty($config['cops_author_uri']) ? 'http://blog.slucas.fr' : $config['cops_author_uri'];
577 10
        $this->authorEmail = empty($config['cops_author_email']) ? '[email protected]' : $config['cops_author_email'];
578
    }
579 10
580 10
    public function InitializeContent ()
581 10
    {
582 10
        global $config;
583 2
        $this->title = $config['cops_title_default'];
584 2
        $this->subtitle = $config['cops_subtitle_default'];
585 2
        if (Base::noDatabaseSelected ()) {
586
            $i = 0;
587
            foreach (Base::getDbNameList () as $key) {
588
                $nBooks = Book::getBookCount ($i);
589
                array_push ($this->entryArray, new Entry ($key, "cops:{$i}:catalog",
590
                                        str_format (localize ("bookword", $nBooks), $nBooks), "text",
591
                                        array ( new LinkNavigation ("?" . DB . "={$i}")), "", $nBooks));
592
                $i++;
593
                Base::clearDb ();
594
            }
595 2
        } else {
596 2
            if (!in_array (PageQueryResult::SCOPE_AUTHOR, getCurrentOption ('ignored_categories'))) {
597 2
                array_push ($this->entryArray, Author::getCount());
598 2
            }
599
            if (!in_array (PageQueryResult::SCOPE_SERIES, getCurrentOption ('ignored_categories'))) {
600 2
                $series = Serie::getCount();
601 2
                if (!is_null ($series)) array_push ($this->entryArray, $series);
602 2
            }
603 2
            if (!in_array (PageQueryResult::SCOPE_PUBLISHER, getCurrentOption ('ignored_categories'))) {
604 8
                $publisher = Publisher::getCount();
605 7
                if (!is_null ($publisher)) array_push ($this->entryArray, $publisher);
606 7
            }
607 8
            if (!in_array (PageQueryResult::SCOPE_TAG, getCurrentOption ('ignored_categories'))) {
608 7
                $tags = Tag::getCount();
609 7
                if (!is_null ($tags)) array_push ($this->entryArray, $tags);
610 7
            }
611 8
            if (!in_array (PageQueryResult::SCOPE_RATING, getCurrentOption ('ignored_categories'))) {
612 7
                $rating = Rating::getCount();
613 7
                if (!is_null ($rating)) array_push ($this->entryArray, $rating);
614 7
            }
615 8
            if (!in_array ("language", getCurrentOption ('ignored_categories'))) {
616 7
                $languages = Language::getCount();
617 7
                if (!is_null ($languages)) array_push ($this->entryArray, $languages);
618 7
            }
619 8
            foreach ($config['cops_calibre_custom_column'] as $lookup) {
620 8
                $customId = CustomColumn::getCustomId ($lookup);
621 8
                if (!is_null ($customId)) {
622 8
                    array_push ($this->entryArray, CustomColumn::getCount($customId));
623 8
                }
624 7
            }
625 7
            $this->entryArray = array_merge ($this->entryArray, Book::getCount());
626 7
627 8
            if (Base::isMultipleDatabaseEnabled ()) $this->title =  Base::getDbName ();
628 4
        }
629 4
    }
630 4
631 4
    public function isPaginated ()
632 8
    {
633 8
        return (getCurrentOption ("max_item_per_page") != -1 &&
634
                $this->totalNumber != -1 &&
635 8
                $this->totalNumber > getCurrentOption ("max_item_per_page"));
636
    }
637 10
638
    public function getNextLink ()
639 17
    {
640
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
641 17
        if (($this->n) * getCurrentOption ("max_item_per_page") < $this->totalNumber) {
642 17
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n + 1), "next", localize ("paging.next.alternate"));
643 17
        }
644
        return NULL;
645
    }
646 2
647
    public function getPrevLink ()
648 2
    {
649 2
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
650 1
        if ($this->n > 1) {
651
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n - 1), "previous", localize ("paging.previous.alternate"));
652 1
        }
653
        return NULL;
654
    }
655 2
656
    public function getMaxPage ()
657 2
    {
658 2
        return ceil ($this->totalNumber / getCurrentOption ("max_item_per_page"));
659 1
    }
660
661 2
    public function containsBook ()
662
    {
663
        if (count ($this->entryArray) == 0) return false;
664 2
        if (get_class ($this->entryArray [0]) == "EntryBook") return true;
665
        return false;
666 2
    }
667
}
668
669 70
class PageAllAuthors extends Page
670
{
671 70
    public function InitializeContent ()
672 68
    {
673 46
        $this->title = localize("authors.title");
674
        if (getCurrentOption ("author_split_first_letter") == 1) {
675
            $this->entryArray = Author::getAllAuthorsByFirstLetter();
676
        }
677
        else {
678
            $this->entryArray = Author::getAllAuthors();
679 3
        }
680
        $this->idPage = Author::ALL_AUTHORS_ID;
681 3
    }
682 3
}
683 2
684 2
class PageAllAuthorsLetter extends Page
685
{
686 1
    public function InitializeContent ()
687
    {
688 3
        $this->idPage = Author::getEntryIdByLetter ($this->idGet);
689 3
        $this->entryArray = Author::getAuthorsByStartingLetter ($this->idGet);
690
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("authorword", count ($this->entryArray)), count ($this->entryArray)), $this->idGet);
691
    }
692
}
693
694 1
class PageAuthorDetail extends Page
695
{
696 1
    public function InitializeContent ()
697 1
    {
698 1
        $author = Author::getAuthorById ($this->idGet);
699 1
        $this->idPage = $author->getEntryId ();
700
        $this->title = $author->name;
701
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByAuthor ($this->idGet, $this->n);
702
    }
703
}
704 7
705
class PageAllPublishers extends Page
706 7
{
707 7
    public function InitializeContent ()
708 7
    {
709 7
        $this->title = localize("publishers.title");
710 7
        $this->entryArray = Publisher::getAllPublishers();
711
        $this->idPage = Publisher::ALL_PUBLISHERS_ID;
712
    }
713
}
714
715 2
class PagePublisherDetail extends Page
716
{
717 2
    public function InitializeContent ()
718 2
    {
719 2
        $publisher = Publisher::getPublisherById ($this->idGet);
720 2
        $this->title = $publisher->name;
721
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByPublisher ($this->idGet, $this->n);
722
        $this->idPage = $publisher->getEntryId ();
723
    }
724
}
725 1
726
class PageAllTags extends Page
727 1
{
728 1
    public function InitializeContent ()
729 1
    {
730 1
        $this->title = localize("tags.title");
731 1
        $this->entryArray = Tag::getAllTags();
732
        $this->idPage = Tag::ALL_TAGS_ID;
733
    }
734
}
735
736 2
class PageAllLanguages extends Page
737
{
738 2
    public function InitializeContent ()
739 2
    {
740 2
        $this->title = localize("languages.title");
741 2
        $this->entryArray = Language::getAllLanguages();
742
        $this->idPage = Language::ALL_LANGUAGES_ID;
743
    }
744
}
745
746 2
class PageCustomDetail extends Page
747
{
748 2
    public function InitializeContent ()
749 2
    {
750 2
        $customId = getURLParam ("custom", NULL);
751 2
        $custom = CustomColumn::getCustomById ($customId, $this->idGet);
752
        $this->idPage = $custom->getEntryId ();
753
        $this->title = $custom->name;
754
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByCustom ($customId, $this->idGet, $this->n);
755
    }
756 3
}
757
758 3
class PageAllCustoms extends Page
759 3
{
760 3
    public function InitializeContent ()
761 3
    {
762 3
        $customId = getURLParam ("custom", NULL);
763 3
        $this->title = CustomColumn::getAllTitle ($customId);
764
        $this->entryArray = CustomColumn::getAllCustoms($customId);
765
        $this->idPage = CustomColumn::getAllCustomsId ($customId);
766
    }
767
}
768 3
769
class PageTagDetail extends Page
770 3
{
771 3
    public function InitializeContent ()
772 3
    {
773 3
        $tag = Tag::getTagById ($this->idGet);
774 3
        $this->idPage = $tag->getEntryId ();
775
        $this->title = $tag->name;
776
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByTag ($this->idGet, $this->n);
777
    }
778
}
779 1
780
class PageLanguageDetail extends Page
781 1
{
782 1
    public function InitializeContent ()
783 1
    {
784 1
        $language = Language::getLanguageById ($this->idGet);
785 1
        $this->idPage = $language->getEntryId ();
786
        $this->title = $language->lang_code;
787
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByLanguage ($this->idGet, $this->n);
788
    }
789
}
790 1
791
class PageAllSeries extends Page
792 1
{
793 1
    public function InitializeContent ()
794 1
    {
795 1
        $this->title = localize("series.title");
796 1
        $this->entryArray = Serie::getAllSeries();
797
        $this->idPage = Serie::ALL_SERIES_ID;
798
    }
799
}
800
801 2
class PageSerieDetail extends Page
802
{
803 2
    public function InitializeContent ()
804 2
    {
805 2
        $serie = Serie::getSerieById ($this->idGet);
806 2
        $this->title = $serie->name;
807
        list ($this->entryArray, $this->totalNumber) = Book::getBooksBySeries ($this->idGet, $this->n);
808
        $this->idPage = $serie->getEntryId ();
809
    }
810
}
811 1
812
class PageAllRating extends Page
813 1
{
814 1
    public function InitializeContent ()
815 1
    {
816 1
        $this->title = localize("ratings.title");
817 1
        $this->entryArray = Rating::getAllRatings();
818
        $this->idPage = Rating::ALL_RATING_ID;
819
    }
820
}
821
822 1
class PageRatingDetail extends Page
823
{
824 1
    public function InitializeContent ()
825 1
    {
826 1
        $rating = Rating::getRatingById ($this->idGet);
827 1
        $this->idPage = $rating->getEntryId ();
828
        $this->title =str_format (localize ("ratingword", $rating->name/2), $rating->name/2);
829
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByRating ($this->idGet, $this->n);
830
    }
831
}
832 1
833
class PageAllBooks extends Page
834 1
{
835 1
    public function InitializeContent ()
836 1
    {
837 1
        $this->title = localize ("allbooks.title");
838 1
        if (getCurrentOption ("titles_split_first_letter") == 1) {
839
            $this->entryArray = Book::getAllBooks();
840
        }
841
        else {
842
            list ($this->entryArray, $this->totalNumber) = Book::getBooks ($this->n);
843 3
        }
844
        $this->idPage = Book::ALL_BOOKS_ID;
845 3
    }
846 3
}
847 2
848 2
class PageAllBooksLetter extends Page
849
{
850 1
    public function InitializeContent ()
851
    {
852 3
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByStartingLetter ($this->idGet, $this->n);
853 3
        $this->idPage = Book::getEntryIdByLetter ($this->idGet);
854
855
        $count = $this->totalNumber;
856
        if ($count == -1)
857
            $count = count ($this->entryArray);
858 1
859
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("bookword", $count), $count), $this->idGet);
860 1
    }
861 1
}
862
863 1
class PageRecentBooks extends Page
864 1
{
865 1
    public function InitializeContent ()
866
    {
867 1
        $this->title = localize ("recent.title");
868 1
        $this->entryArray = Book::getAllRecentBooks ();
869
        $this->idPage = Book::ALL_RECENT_BOOKS_ID;
870
    }
871
}
872
873 4
class PageQueryResult extends Page
874
{
875 4
    const SCOPE_TAG = "tag";
876 4
    const SCOPE_RATING = "rating";
877 4
    const SCOPE_SERIES = "series";
878 4
    const SCOPE_AUTHOR = "author";
879
    const SCOPE_BOOK = "book";
880
    const SCOPE_PUBLISHER = "publisher";
881
882
    private function useTypeahead () {
883
        return !is_null (getURLParam ("search"));
884
    }
885
886
    private function searchByScope ($scope, $limit = FALSE) {
887
        $n = $this->n;
888
        $numberPerPage = NULL;
889
        $queryNormedAndUp = $this->query;
890 24
        if (useNormAndUp ()) {
891 24
            $queryNormedAndUp = normAndUp ($this->query);
892
        }
893
        if ($limit) {
894 29
            $n = 1;
895 29
            $numberPerPage = 5;
896 29
        }
897 29
        switch ($scope) {
898 29
            case self::SCOPE_BOOK :
899 7
                $array = Book::getBooksByStartingLetter ('%' . $queryNormedAndUp, $n, NULL, $numberPerPage);
900 7
                break;
901 29
            case self::SCOPE_AUTHOR :
902 22
                $array = Author::getAuthorsForSearch ('%' . $queryNormedAndUp);
903 22
                break;
904 22
            case self::SCOPE_SERIES :
905
                $array = Serie::getAllSeriesByQuery ($queryNormedAndUp);
906 29
                break;
907 23
            case self::SCOPE_TAG :
908 23
                $array = Tag::getAllTagsByQuery ($queryNormedAndUp, $n, NULL, $numberPerPage);
909 28
                break;
910 23
            case self::SCOPE_PUBLISHER :
911 23
                $array = Publisher::getAllPublishersByQuery ($queryNormedAndUp);
912 25
                break;
913 22
            default:
914 22
                $array = Book::getBooksByQuery (
915 24
                    array ("all" => "%" . $queryNormedAndUp . "%"), $n);
916 23
        }
917 23
918 23
        return $array;
919 23
    }
920 23
921
    public function doSearchByCategory () {
922
        $database = GetUrlParam (DB);
923
        $out = array ();
924
        $pagequery = Base::PAGE_OPENSEARCH_QUERY;
925
        $dbArray = array ("");
926 29
        $d = $database;
927
        $query = $this->query;
928
        // Special case when no databases were chosen, we search on all databases
929 22
        if (Base::noDatabaseSelected ()) {
930 22
            $dbArray = Base::getDbNameList ();
931 22
            $d = 0;
932 22
        }
933 22
        foreach ($dbArray as $key) {
934 22
            if (Base::noDatabaseSelected ()) {
935 22
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$d}",
936
                                        " ", "text",
937 22
                                        array ( new LinkNavigation ("?" . DB . "={$d}")), "tt-header"));
938 1
                Base::getDb ($d);
939 1
            }
940 1
            foreach (array (PageQueryResult::SCOPE_BOOK,
941 22
                            PageQueryResult::SCOPE_AUTHOR,
942 22
                            PageQueryResult::SCOPE_SERIES,
943 1
                            PageQueryResult::SCOPE_TAG,
944 1
                            PageQueryResult::SCOPE_PUBLISHER) as $key) {
945 1
                if (in_array($key, getCurrentOption ('ignored_categories'))) {
946 1
                    continue;
947 1
                }
948 22
                $array = $this->searchByScope ($key, TRUE);
949 22
950 22
                $i = 0;
951 22
                if (count ($array) == 2 && is_array ($array [0])) {
952 22
                    $total = $array [1];
953 22
                    $array = $array [0];
954 3
                } else {
955
                    $total = count($array);
956 22
                }
957
                if ($total > 0) {
958 22
                    // Comment to help the perl i18n script
959 22
                    // str_format (localize("bookword", count($array))
960 22
                    // str_format (localize("authorword", count($array))
961 22
                    // str_format (localize("seriesword", count($array))
962 22
                    // str_format (localize("tagword", count($array))
963 22
                    // str_format (localize("publisherword", count($array))
964
                    array_push ($this->entryArray, new Entry (str_format (localize ("search.result.{$key}"), $this->query), DB . ":query:{$d}:{$key}",
965 22
                                        str_format (localize("{$key}word", $total), $total), "text",
966
                                        array ( new LinkNavigation ("?page={$pagequery}&query={$query}&db={$d}&scope={$key}")),
967
                                        Base::noDatabaseSelected () ? "" : "tt-header", $total));
968
                }
969
                if (!Base::noDatabaseSelected () && $this->useTypeahead ()) {
970
                    foreach ($array as $entry) {
971
                        array_push ($this->entryArray, $entry);
972 21
                        $i++;
973 21
                        if ($i > 4) { break; };
974 21
                    }
975 21
                }
976 21
            }
977 22
            $d++;
978 6
            if (Base::noDatabaseSelected ()) {
979 6
                Base::clearDb ();
980 6
            }
981 6
        }
982 6
        return $out;
983 6
    }
984 22
985 22
    public function InitializeContent ()
986 22
    {
987 1
        $scope = getURLParam ("scope");
988 1
        if (empty ($scope)) {
989 22
            $this->title = str_format (localize ("search.result"), $this->query);
990 22
        } else {
991
            // Comment to help the perl i18n script
992
            // str_format (localize ("search.result.author"), $this->query)
993 31
            // str_format (localize ("search.result.tag"), $this->query)
994
            // str_format (localize ("search.result.series"), $this->query)
995 31
            // str_format (localize ("search.result.book"), $this->query)
996 31
            // str_format (localize ("search.result.publisher"), $this->query)
997 24
            $this->title = str_format (localize ("search.result.{$scope}"), $this->query);
998 24
        }
999
1000
        $crit = "%" . $this->query . "%";
1001
1002
        // Special case when we are doing a search and no database is selected
1003
        if (Base::noDatabaseSelected () && !$this->useTypeahead ()) {
1004
            $i = 0;
1005 7
            foreach (Base::getDbNameList () as $key) {
1006
                Base::clearDb ();
1007
                list ($array, $totalNumber) = Book::getBooksByQuery (array ("all" => $crit), 1, $i, 1);
0 ignored issues
show
Unused Code introduced by
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...
1008 31
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$i}",
1009
                                        str_format (localize ("bookword", $totalNumber), $totalNumber), "text",
1010
                                        array ( new LinkNavigation ("?" . DB . "={$i}&page=9&query=" . $this->query)), "", $totalNumber));
1011 31
                $i++;
1012 2
            }
1013 2
            return;
1014 2
        }
1015 2
        if (empty ($scope)) {
1016 2
            $this->doSearchByCategory ();
1017 2
            return;
1018 2
        }
1019 2
1020 2
        $array = $this->searchByScope ($scope);
1021 2
        if (count ($array) == 2 && is_array ($array [0])) {
1022
            list ($this->entryArray, $this->totalNumber) = $array;
1023 29
        } else {
1024 22
            $this->entryArray = $array;
1025 22
        }
1026
    }
1027
}
1028 7
1029 7
class PageBookDetail extends Page
1030 2
{
1031 2
    public function InitializeContent ()
1032 5
    {
1033
        $this->book = Book::getBookById ($this->idGet);
1034 7
        $this->title = $this->book->title;
1035
    }
1036
}
1037
1038
class PageAbout extends Page
1039 1
{
1040
    public function InitializeContent ()
1041 1
    {
1042 1
        $this->title = localize ("about.title");
1043 1
    }
1044
}
1045
1046
class PageCustomize extends Page
1047
{
1048
    private function isChecked ($key, $testedValue = 1) {
1049
        $value = getCurrentOption ($key);
1050
        if (is_array ($value)) {
1051
            if (in_array ($testedValue, $value)) {
1052
                return "checked='checked'";
1053
            }
1054
        } else {
1055
            if ($value == $testedValue) {
1056
                return "checked='checked'";
1057
            }
1058
        }
1059
        return "";
1060
    }
1061
1062
    private function isSelected ($key, $value) {
1063
        if (getCurrentOption ($key) == $value) {
1064
            return "selected='selected'";
1065
        }
1066
        return "";
1067
    }
1068
1069
    private function getStyleList () {
1070
        $result = array ();
1071
        foreach (glob ("templates/" . getCurrentTemplate () . "/styles/style-*.css") as $filename) {
1072
            if (preg_match ('/styles\/style-(.*?)\.css/', $filename, $m)) {
1073
                array_push ($result, $m [1]);
1074
            }
1075
        }
1076
        return $result;
1077
    }
1078
1079
    public function InitializeContent ()
1080
    {
1081
        $this->title = localize ("customize.title");
1082
        $this->entryArray = array ();
1083
1084
        $ignoredBaseArray = array (PageQueryResult::SCOPE_AUTHOR,
1085
                                   PageQueryResult::SCOPE_TAG,
1086
                                   PageQueryResult::SCOPE_SERIES,
1087
                                   PageQueryResult::SCOPE_PUBLISHER,
1088
                                   PageQueryResult::SCOPE_RATING,
1089
                                   "language");
1090
1091
        $content = "";
1092
        array_push ($this->entryArray, new Entry ("Template", "",
1093
                                        "<span style='cursor: pointer;' onclick='$.cookie(\"template\", \"bootstrap\", { expires: 365 });window.location=$(\".headleft\").attr(\"href\");'>Click to switch to Bootstrap</span>", "text",
1094
                                        array ()));
1095
        if (!preg_match("/(Kobo|Kindle\/3.0|EBRD1101)/", $_SERVER['HTTP_USER_AGENT'])) {
1096
            $content .= '<select id="style" onchange="updateCookie (this);">';
1097
            foreach ($this-> getStyleList () as $filename) {
1098
                $content .= "<option value='{$filename}' " . $this->isSelected ("style", $filename) . ">{$filename}</option>";
1099
            }
1100
            $content .= '</select>';
1101
        } else {
1102
            foreach ($this-> getStyleList () as $filename) {
1103
                $content .= "<input type='radio' onchange='updateCookieFromCheckbox (this);' id='style-{$filename}' name='style' value='{$filename}' " . $this->isChecked ("style", $filename) . " /><label for='style-{$filename}'> {$filename} </label>";
1104
            }
1105
        }
1106
        array_push ($this->entryArray, new Entry (localize ("customize.style"), "",
1107
                                        $content, "text",
1108
                                        array ()));
1109
        if (!useServerSideRendering ()) {
1110
            $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="use_fancyapps" ' . $this->isChecked ("use_fancyapps") . ' />';
1111
            array_push ($this->entryArray, new Entry (localize ("customize.fancybox"), "",
1112
                                            $content, "text",
1113
                                            array ()));
1114
        }
1115
        $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]+$" />';
1116
        array_push ($this->entryArray, new Entry (localize ("customize.paging"), "",
1117
                                        $content, "text",
1118
                                        array ()));
1119
        $content = '<input type="text" onchange="updateCookie (this);" id="email" value="' . getCurrentOption ("email") . '" />';
1120
        array_push ($this->entryArray, new Entry (localize ("customize.email"), "",
1121
                                        $content, "text",
1122
                                        array ()));
1123
        $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="html_tag_filter" ' . $this->isChecked ("html_tag_filter") . ' />';
1124
        array_push ($this->entryArray, new Entry (localize ("customize.filter"), "",
1125
                                        $content, "text",
1126
                                        array ()));
1127
        $content = "";
1128
        foreach ($ignoredBaseArray as $key) {
1129
            $keyPlural = preg_replace ('/(ss)$/', 's', $key . "s");
1130
            $content .=  '<input type="checkbox" name="ignored_categories[]" onchange="updateCookieFromCheckboxGroup (this);" id="ignored_categories_' . $key . '" ' . $this->isChecked ("ignored_categories", $key) . ' > ' . localize ("{$keyPlural}.title") . '</input> ';
1131
        }
1132
1133
        array_push ($this->entryArray, new Entry (localize ("customize.ignored"), "",
1134
                                        $content, "text",
1135
                                        array ()));
1136
    }
1137
}
1138
1139
1140
abstract class Base
1141
{
1142
    const PAGE_INDEX = "index";
1143
    const PAGE_ALL_AUTHORS = "1";
1144
    const PAGE_AUTHORS_FIRST_LETTER = "2";
1145
    const PAGE_AUTHOR_DETAIL = "3";
1146
    const PAGE_ALL_BOOKS = "4";
1147
    const PAGE_ALL_BOOKS_LETTER = "5";
1148
    const PAGE_ALL_SERIES = "6";
1149
    const PAGE_SERIE_DETAIL = "7";
1150
    const PAGE_OPENSEARCH = "8";
1151
    const PAGE_OPENSEARCH_QUERY = "9";
1152
    const PAGE_ALL_RECENT_BOOKS = "10";
1153
    const PAGE_ALL_TAGS = "11";
1154
    const PAGE_TAG_DETAIL = "12";
1155
    const PAGE_BOOK_DETAIL = "13";
1156
    const PAGE_ALL_CUSTOMS = "14";
1157
    const PAGE_CUSTOM_DETAIL = "15";
1158
    const PAGE_ABOUT = "16";
1159
    const PAGE_ALL_LANGUAGES = "17";
1160
    const PAGE_LANGUAGE_DETAIL = "18";
1161
    const PAGE_CUSTOMIZE = "19";
1162
    const PAGE_ALL_PUBLISHERS = "20";
1163
    const PAGE_PUBLISHER_DETAIL = "21";
1164
    const PAGE_ALL_RATINGS = "22";
1165
    const PAGE_RATING_DETAIL = "23";
1166
1167
    const COMPATIBILITY_XML_ALDIKO = "aldiko";
1168
1169
    private static $db = NULL;
1170
1171
    public static function isMultipleDatabaseEnabled () {
1172
        global $config;
1173
        return is_array ($config['calibre_directory']);
1174
    }
1175
1176
    public static function useAbsolutePath () {
1177
        global $config;
1178
        $path = self::getDbDirectory();
1179
        return preg_match ('/^\//', $path) || // Linux /
1180
               preg_match ('/^\w\:/', $path); // Windows X:
1181 108
    }
1182 108
1183 108
    public static function noDatabaseSelected () {
1184
        return self::isMultipleDatabaseEnabled () && is_null (GetUrlParam (DB));
1185
    }
1186 46
1187 46
    public static function getDbList () {
1188 46
        global $config;
1189 46
        if (self::isMultipleDatabaseEnabled ()) {
1190 46
            return $config['calibre_directory'];
1191
        } else {
1192
            return array ("" => $config['calibre_directory']);
1193 45
        }
1194 45
    }
1195 45
1196
    public static function getDbNameList () {
1197
        global $config;
1198 4
        if (self::isMultipleDatabaseEnabled ()) {
1199 4
            return array_keys ($config['calibre_directory']);
1200 4
        } else {
1201 4
            return array ("");
1202
        }
1203 1
    }
1204
1205
    public static function getDbName ($database = NULL) {
1206
        global $config;
1207 5
        if (self::isMultipleDatabaseEnabled ()) {
1208 5
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1209 5
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1210 5
                return self::error ($database);
1211
            }
1212
            $array = array_keys ($config['calibre_directory']);
1213
            return  $array[$database];
1214
        }
1215
        return "";
1216 1
    }
1217 1
1218 1
    public static function getDbDirectory ($database = NULL) {
1219 1
        global $config;
1220 1
        if (self::isMultipleDatabaseEnabled ()) {
1221
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1222
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1223 1
                return self::error ($database);
1224 1
            }
1225
            $array = array_values ($config['calibre_directory']);
1226
            return  $array[$database];
1227
        }
1228
        return $config['calibre_directory'];
1229 90
    }
1230 90
1231 90
1232 9
    public static function getDbFileName ($database = NULL) {
1233 9
        return self::getDbDirectory ($database) .'metadata.db';
1234
    }
1235
1236 9
    private static function error ($database) {
1237 9
        if (php_sapi_name() != "cli") {
1238
            header("location: checkconfig.php?err=1");
1239 81
        }
1240
        throw new Exception("Database <{$database}> not found.");
1241
    }
1242
1243 61
    public static function getDb ($database = NULL) {
1244 61
        if (is_null (self::$db)) {
1245
            try {
1246
                if (is_readable (self::getDbFileName ($database))) {
1247 2
                    self::$db = new PDO('sqlite:'. self::getDbFileName ($database));
1248 2
                    if (useNormAndUp ()) {
1249
                        self::$db->sqliteCreateFunction ('normAndUp', 'normAndUp', 1);
1250
                    }
1251 2
                } else {
1252
                    self::error ($database);
1253
                }
1254 126
            } catch (Exception $e) {
1255 126
                self::error ($database);
1256
            }
1257 61
        }
1258 60
        return self::$db;
1259 60
    }
1260 7
1261 7
    public static function checkDatabaseAvailability () {
1262 60
        if (self::noDatabaseSelected ()) {
1263 2
            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...
1264
                self::getDb ($i);
1265 61
                self::clearDb ();
1266 2
            }
1267
        } else {
1268 60
            self::getDb ();
1269 125
        }
1270
        return true;
1271
    }
1272 4
1273 4
    public static function clearDb () {
1274 3
        self::$db = NULL;
1275 3
    }
1276 2
1277 2
    public static function executeQuerySingle ($query, $database = NULL) {
1278 1
        return self::getDb ($database)->query($query)->fetchColumn();
1279 1
    }
1280
1281 2
    public static function getCountGeneric($table, $id, $pageId, $numberOfString = NULL) {
1282
        if (!$numberOfString) {
1283
            $numberOfString = $table . ".alphabetical";
1284 58
        }
1285 58
        $count = self::executeQuerySingle ('select count(*) from ' . $table);
1286 58
        if ($count == 0) return NULL;
1287
        $entry = new Entry (localize($table . ".title"), $id,
1288 13
            str_format (localize($numberOfString, $count), $count), "text",
1289 13
            array ( new LinkNavigation ("?page=".$pageId)), "", $count);
1290
        return $entry;
1291
    }
1292 8
1293 8
    public static function getEntryArrayWithBookNumber ($query, $columns, $params, $category) {
1294 7
        list (, $result) = self::executeQuery ($query, $columns, "", $params, -1);
1295 7
        $entryArray = array();
1296 8
        while ($post = $result->fetchObject ())
1297 8
        {
1298 8
            $instance = new $category ($post);
1299 8
            if (property_exists($post, "sort")) {
1300 8
                $title = $post->sort;
1301 8
            } else {
1302
                $title = $post->name;
1303
            }
1304 35
            array_push ($entryArray, new Entry ($title, $instance->getEntryId (),
1305 35
                str_format (localize("bookword", $post->count), $post->count), "text",
1306 35
                array ( new LinkNavigation ($instance->getUri ())), "", $post->count));
1307 35
        }
1308
        return $entryArray;
1309 25
    }
1310 25
1311 17
    public static function executeQuery($query, $columns, $filter, $params, $n, $database = NULL, $numberPerPage = NULL) {
1312 17
        $totalResult = -1;
1313 8
1314
        if (useNormAndUp ()) {
1315 25
            $query = preg_replace("/upper/", "normAndUp", $query);
1316 25
            $columns = preg_replace("/upper/", "normAndUp", $columns);
1317 25
        }
1318 25
1319 35
        if (is_null ($numberPerPage)) {
1320
            $numberPerPage = getCurrentOption ("max_item_per_page");
1321
        }
1322 73
1323 73
        if ($numberPerPage != -1 && $n != -1)
1324
        {
1325 73
            // First check total number of results
1326 7
            $result = self::getDb ($database)->prepare (str_format ($query, "count(*)", $filter));
1327 7
            $result->execute ($params);
1328 7
            $totalResult = $result->fetchColumn ();
1329
1330 73
            // Next modify the query and params
1331 71
            $query .= " limit ?, ?";
1332 71
            array_push ($params, ($n - 1) * $numberPerPage, $numberPerPage);
1333
        }
1334 73
1335 73
        $result = self::getDb ($database)->prepare(str_format ($query, $columns, $filter));
1336
        $result->execute ($params);
1337 28
        return array ($totalResult, $result);
1338 28
    }
1339 28
1340
}
1341