Completed
Pull Request — master (#278)
by
unknown
03:21
created

base.php ➔ localize()   D

Complexity

Conditions 11
Paths 160

Size

Total Lines 44
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 11.0269

Importance

Changes 0
Metric Value
cc 11
eloc 28
nc 160
nop 3
dl 0
loc 44
ccs 31
cts 33
cp 0.9394
crap 11.0269
rs 4.9629
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
/** @var array $config */
10
11
define ("VERSION", "1.0.0RC4");
12
define ("DB", "db");
13
date_default_timezone_set($config['default_timezone']);
14
15
16
function useServerSideRendering () {
17 3
    global $config;
18 3
    return preg_match("/" . $config['cops_server_side_render'] . "/", $_SERVER['HTTP_USER_AGENT']);
19
}
20
21
function serverSideRender ($data) {
22
    // Get the templates
23 2
    $theme = getCurrentTemplate ();
24 2
    $header = file_get_contents('templates/' . $theme . '/header.html');
25 2
    $footer = file_get_contents('templates/' . $theme . '/footer.html');
26 2
    $main = file_get_contents('templates/' . $theme . '/main.html');
27 2
    $bookdetail = file_get_contents('templates/' . $theme . '/bookdetail.html');
28 2
    $page = file_get_contents('templates/' . $theme . '/page.html');
29
30
    // Generate the function for the template
31 2
    $template = new doT ();
32 2
    $dot = $template->template ($page, array ("bookdetail" => $bookdetail,
33 2
                                              "header" => $header,
34 2
                                              "footer" => $footer,
35 2
                                              "main" => $main));
36
    // If there is a syntax error in the function created
37
    // $dot will be equal to FALSE
38 2
    if (!$dot) {
39
        return FALSE;
40
    }
41
    // Execute the template
42 2
    if (!empty ($data)) {
43
        return $dot ($data);
44
    }
45
46 2
    return NULL;
47
}
48
49
function getQueryString () {
50 18
    if ( isset($_SERVER['QUERY_STRING']) ) {
51 16
        return $_SERVER['QUERY_STRING'];
52
    }
53 2
    return "";
54
}
55
56
function notFound () {
57
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
58
    header("Status: 404 Not Found");
59
60
    $_SERVER['REDIRECT_STATUS'] = 404;
61
}
62
63
function getURLParam ($name, $default = NULL) {
64 134
    if (!empty ($_GET) && isset($_GET[$name]) && $_GET[$name] != "") {
65 34
        return $_GET[$name];
66
    }
67 122
    return $default;
68
}
69
70
function getCurrentOption ($option) {
71 100
    global $config;
72 100
    if (isset($_COOKIE[$option])) {
73 2
        if (isset($config ["cops_" . $option]) && is_array ($config ["cops_" . $option])) {
74
            return explode (",", $_COOKIE[$option]);
75
        } else {
76 2
            return $_COOKIE[$option];
77
        }
78
    }
79 98
    if (isset($config ["cops_" . $option])) {
80 98
        return $config ["cops_" . $option];
81
    }
82
83
    return "";
84
}
85
86
function getCurrentCss () {
87 2
    return "templates/" . getCurrentTemplate () . "/styles/style-" . getCurrentOption ("style") . ".css";
88
}
89
90
function getCurrentTemplate () {
91 4
    return getCurrentOption ("template");
92
}
93
94
function getUrlWithVersion ($url) {
95 69
    return $url . "?v=" . VERSION;
96
}
97
98
function xml2xhtml($xml) {
99 37
    return preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', create_function('$m', '
100
        $xhtml_tags = array("br", "hr", "input", "frame", "img", "area", "link", "col", "base", "basefont", "param");
101
        return in_array($m[1], $xhtml_tags) ? "<$m[1]$m[2] />" : "<$m[1]$m[2]></$m[1]>";
102 37
    '), $xml);
103
}
104
105
function display_xml_error($error)
106
{
107
    $return = "";
108
    $return .= str_repeat('-', $error->column) . "^\n";
109
110
    switch ($error->level) {
111
        case LIBXML_ERR_WARNING:
112
            $return .= "Warning $error->code: ";
113
            break;
114
         case LIBXML_ERR_ERROR:
115
            $return .= "Error $error->code: ";
116
            break;
117
        case LIBXML_ERR_FATAL:
118
            $return .= "Fatal Error $error->code: ";
119
            break;
120
    }
121
122
    $return .= trim($error->message) .
123
               "\n  Line: $error->line" .
124
               "\n  Column: $error->column";
125
126
    if ($error->file) {
127
        $return .= "\n  File: $error->file";
128
    }
129
130
    return "$return\n\n--------------------------------------------\n\n";
131
}
132
133
function are_libxml_errors_ok ()
134
{
135 37
    $errors = libxml_get_errors();
136
137 37
    foreach ($errors as $error) {
138
        if ($error->code == 801) return false;
139 37
    }
140 37
    return true;
141
}
142
143
function html2xhtml ($html) {
144 37
    $doc = new DOMDocument();
145 37
    libxml_use_internal_errors(true);
146
147 37
    $doc->loadHTML('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>' .
148 37
                        $html  . '</body></html>'); // Load the HTML
149 37
    $output = $doc->saveXML($doc->documentElement); // Transform to an Ansi xml stream
150 37
    $output = xml2xhtml($output);
151 37
    if (preg_match ('#<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></meta></head><body>(.*)</body></html>#ms', $output, $matches)) {
152 37
        $output = $matches [1]; // Remove <html><body>
153 37
    }
154
    /*
155
    // In case of error with summary, use it to debug
156
    $errors = libxml_get_errors();
157
158
    foreach ($errors as $error) {
159
        $output .= display_xml_error($error);
160
    }
161
    */
162
163 37
    if (!are_libxml_errors_ok ()) $output = "HTML code not valid.";
164
165 37
    libxml_use_internal_errors(false);
166 37
    return $output;
167
}
168
169
/**
170
 * This method is a direct copy-paste from
171
 * http://tmont.com/blargh/2010/1/string-format-in-php
172
 */
173
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...
174 116
    $args = func_get_args();
175 116
    $format = array_shift($args);
176
177 116
    preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
178 116
    $offset = 0;
179 116
    foreach ($matches[1] as $data) {
180 116
        $i = $data[0];
181 116
        $format = substr_replace($format, @$args[$i], $offset + $data[1] - 1, 2 + strlen($i));
182 116
        $offset += strlen(@$args[$i]) - 2 - strlen($i);
183 116
    }
184
185 116
    return $format;
186
}
187
188
/**
189
 * Get all accepted languages from the browser and put them in a sorted array
190
 * languages id are normalized : fr-fr -> fr_FR
191
 * @return array of languages
192
 */
193
function getAcceptLanguages() {
194 16
    $langs = array();
195
196 16
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
197
        // break up string into pieces (languages and q factors)
198 16
        $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
199 16
        if (preg_match('/^(\w{2})-\w{2}$/', $accept, $matches)) {
200
            // Special fix for IE11 which send fr-FR and nothing else
201 3
            $accept = $accept . "," . $matches[1] . ";q=0.8";
202 3
        }
203 16
        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $lang_parse);
204
205 16
        if (count($lang_parse[1])) {
206 16
            $langs = array();
207 16
            foreach ($lang_parse[1] as $lang) {
208
                // Format the language code (not standard among browsers)
209 16
                if (strlen($lang) == 5) {
210 11
                    $lang = str_replace("-", "_", $lang);
211 11
                    $splitted = preg_split("/_/", $lang);
212 11
                    $lang = $splitted[0] . "_" . strtoupper($splitted[1]);
213 11
                }
214 16
                array_push($langs, $lang);
215 16
            }
216
            // create a list like "en" => 0.8
217 16
            $langs = array_combine($langs, $lang_parse[4]);
218
219
            // set default to 1 for any without q factor
220 16
            foreach ($langs as $lang => $val) {
221 16
                if ($val === '') $langs[$lang] = 1;
222 16
            }
223
224
            // sort list based on value
225 16
            arsort($langs, SORT_NUMERIC);
226 16
        }
227 16
    }
228
229 16
    return $langs;
230
}
231
232
/**
233
 * Find the best translation file possible based on the accepted languages
234
 * @return array of language and language file
235
 */
236
function getLangAndTranslationFile() {
237 17
    global $config;
238 17
    $langs = array();
239 17
    $lang = "en";
240 17
    if (!empty($config['cops_language'])) {
241
        $lang = $config['cops_language'];
242
    }
243 17
    elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
244 16
        $langs = getAcceptLanguages();
245 16
    }
246
    //echo var_dump($langs);
247 17
    $lang_file = NULL;
248 17
    foreach ($langs as $language => $val) {
249 16
        $temp_file = dirname(__FILE__). '/lang/Localization_' . $language . '.json';
250 16
        if (file_exists($temp_file)) {
251 16
            $lang = $language;
252 16
            $lang_file = $temp_file;
253 16
            break;
254
        }
255 17
    }
256 17
    if (empty ($lang_file)) {
257 3
        $lang_file = dirname(__FILE__). '/lang/Localization_' . $lang . '.json';
258 3
    }
259 17
    return array($lang, $lang_file);
260
}
261
262
/**
263
 * This method is based on this page
264
 * http://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php/
265
 */
266
function localize($phrase, $count=-1, $reset=false) {
267 136
    global $config;
268 136
    if ($count == 0)
269 136
        $phrase .= ".none";
270 136
    if ($count == 1)
271 136
        $phrase .= ".one";
272 136
    if ($count > 1)
273 136
        $phrase .= ".many";
274
275
    /* Static keyword is used to ensure the file is loaded only once */
276 136
    static $translations = NULL;
277 136
    if ($reset) {
278 16
        $translations = NULL;
279 16
    }
280
    /* If no instance of $translations has occured load the language file */
281 136
    if (is_null($translations)) {
282 17
        $lang_file_en = NULL;
283 17
        list ($lang, $lang_file) = getLangAndTranslationFile();
284 17
        if ($lang != "en") {
285 1
            $lang_file_en = dirname(__FILE__). '/lang/' . 'Localization_en.json';
286 1
        }
287
288 17
        $lang_file_content = file_get_contents($lang_file);
289
        /* Load the language file as a JSON object and transform it into an associative array */
290 17
        $translations = json_decode($lang_file_content, true);
291
292
        /* Clean the array of all unfinished translations */
293 17
        foreach (array_keys ($translations) as $key) {
294 17
            if (preg_match ("/^##TODO##/", $key)) {
295
                unset ($translations [$key]);
296
            }
297 17
        }
298
        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...
299 17
        {
300 1
            $lang_file_content = file_get_contents($lang_file_en);
301 1
            $translations_en = json_decode($lang_file_content, true);
302 1
            $translations = array_merge ($translations_en, $translations);
303 1
        }
304 17
    }
305 136
    if (array_key_exists ($phrase, $translations)) {
306 136
        return $translations[$phrase];
307
    }
308 3
    return $phrase;
309
}
310
311
function addURLParameter($urlParams, $paramName, $paramValue) {
312 61
    if (empty ($urlParams)) {
313 51
        $urlParams = "";
314 51
    }
315 61
    $start = "";
316 61
    if (preg_match ("#^\?(.*)#", $urlParams, $matches)) {
317 15
        $start = "?";
318 15
        $urlParams = $matches[1];
319 15
    }
320 61
    $params = array();
321 61
    parse_str($urlParams, $params);
322 61
    if (empty ($paramValue) && $paramValue != 0) {
323
        unset ($params[$paramName]);
324
    } else {
325 61
        $params[$paramName] = $paramValue;
326
    }
327 61
    return $start . http_build_query($params);
328
}
329
330
function useNormAndUp () {
331 144
    global $config;
332 144
    return $config ['cops_normalized_search'] == "1";
333
}
334
335
function normalizeUtf8String( $s) {
336 8
    include_once 'transliteration.php';
337 8
    return _transliteration_process($s);
338
}
339
340
function normAndUp ($s) {
341 7
    return mb_strtoupper (normalizeUtf8String($s), 'UTF-8');
342
}
343
344
class Link
345
{
346
    const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail";
347
    const OPDS_IMAGE_TYPE = "http://opds-spec.org/image";
348
    const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition";
349
    const OPDS_NAVIGATION_TYPE = "application/atom+xml;profile=opds-catalog;kind=navigation";
350
    const OPDS_PAGING_TYPE = "application/atom+xml;profile=opds-catalog;kind=acquisition";
351
352
    public $href;
353
    public $type;
354
    public $rel;
355
    public $title;
356
    public $facetGroup;
357
    public $activeFacet;
358
359 117
    public function __construct($phref, $ptype, $prel = NULL, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
360 117
        $this->href = $phref;
361 117
        $this->type = $ptype;
362 117
        $this->rel = $prel;
363 117
        $this->title = $ptitle;
364 117
        $this->facetGroup = $pfacetGroup;
365 117
        $this->activeFacet = $pactiveFacet;
366 117
    }
367
368 11
    public function hrefXhtml () {
369 11
        return $this->href;
370
    }
371
372 116
    public function getScriptName() {
373 116
        $parts = explode('/', $_SERVER["SCRIPT_NAME"]);
374 116
        return $parts[count($parts) - 1];
375
    }
376
}
377
378
class LinkNavigation extends Link
379
{
380 116
    public function __construct($phref, $prel = NULL, $ptitle = NULL) {
381 116
        parent::__construct ($phref, Link::OPDS_NAVIGATION_TYPE, $prel, $ptitle);
382 116
        if (!is_null (GetUrlParam (DB))) $this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
383 116
        if (!preg_match ("#^\?(.*)#", $this->href) && !empty ($this->href)) $this->href = "?" . $this->href;
384 116
        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...
385
            $this->href = "index.php" . $this->href;
386
        } else {
387 116
            $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...
388
        }
389 116
    }
390
}
391
392
class LinkFacet extends Link
393
{
394 1
    public function __construct($phref, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
395 1
        parent::__construct ($phref, Link::OPDS_PAGING_TYPE, "http://opds-spec.org/facet", $ptitle, $pfacetGroup, $pactiveFacet);
396 1
        if (!is_null (GetUrlParam (DB))) $this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
397 1
        $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...
398 1
    }
399
}
400
401
class Entry
402
{
403
    public $title;
404
    public $id;
405
    public $content;
406
    public $numberOfElement;
407
    public $contentType;
408
    public $linkArray;
409
    public $localUpdated;
410
    public $className;
411
    private static $updated = NULL;
412
413
    public static $icons = array(
414
        Author::ALL_AUTHORS_ID           => 'images/author.png',
415
        Serie::ALL_SERIES_ID             => 'images/serie.png',
416
        Book::ALL_RECENT_BOOKS_ID        => 'images/recent.png',
417
        Tag::ALL_TAGS_ID                 => 'images/tag.png',
418
        Language::ALL_LANGUAGES_ID       => 'images/language.png',
419
        CustomColumnType::ALL_CUSTOMS_ID => 'images/custom.png',
420
        Rating::ALL_RATING_ID            => 'images/rating.png',
421
        "cops:books$"                    => 'images/allbook.png',
422
        "cops:books:letter"              => 'images/allbook.png',
423
        Publisher::ALL_PUBLISHERS_ID     => 'images/publisher.png'
424
    );
425
426
    public function getUpdatedTime () {
427
        if (!is_null ($this->localUpdated)) {
428
            return date (DATE_ATOM, $this->localUpdated);
429
        }
430
        if (is_null (self::$updated)) {
431
            self::$updated = time();
432
        }
433
        return date (DATE_ATOM, self::$updated);
434
    }
435
436 7
    public function getNavLink () {
437 7
        foreach ($this->linkArray as $link) {
438
            /* @var $link LinkNavigation */
439
440 7
            if ($link->type != Link::OPDS_NAVIGATION_TYPE) { continue; }
441
442 7
            return $link->hrefXhtml ();
443
        }
444
        return "#";
445
    }
446
447 109
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pclass = "", $pcount = 0) {
448 109
        global $config;
449 109
        $this->title = $ptitle;
450 109
        $this->id = $pid;
451 109
        $this->content = $pcontent;
452 109
        $this->contentType = $pcontentType;
453 109
        $this->linkArray = $plinkArray;
454 109
        $this->className = $pclass;
455 109
        $this->numberOfElement = $pcount;
456
457 109
        if ($config['cops_show_icons'] == 1)
458 109
        {
459 109
            foreach (self::$icons as $reg => $image)
460
            {
461 109
                if (preg_match ("/" . $reg . "/", $pid)) {
462 69
                    array_push ($this->linkArray, new Link (getUrlWithVersion ($image), "image/png", Link::OPDS_THUMBNAIL_TYPE));
463 69
                    break;
464
                }
465 109
            }
466 109
        }
467
468 109
        if (!is_null (GetUrlParam (DB))) $this->id = str_replace ("cops:", "cops:" . GetUrlParam (DB) . ":", $this->id);
469 109
    }
470
}
471
472
class EntryBook extends Entry
473
{
474
    public $book;
475
476
    /**
477
     * EntryBook constructor.
478
     * @param string $ptitle
479
     * @param integer $pid
480
     * @param string $pcontent
481
     * @param string $pcontentType
482
     * @param array $plinkArray
483
     * @param Book $pbook
484
     */
485 41
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pbook) {
486 41
        parent::__construct ($ptitle, $pid, $pcontent, $pcontentType, $plinkArray);
487 41
        $this->book = $pbook;
488 41
        $this->localUpdated = $pbook->timestamp;
489 41
    }
490
491
    public function getCoverThumbnail () {
492
        foreach ($this->linkArray as $link) {
493
            /* @var $link LinkNavigation */
494
495
            if ($link->rel == Link::OPDS_THUMBNAIL_TYPE)
496
                return $link->hrefXhtml ();
497
        }
498
        return null;
499
    }
500
501
    public function getCover () {
502
        foreach ($this->linkArray as $link) {
503
            /* @var $link LinkNavigation */
504
505
            if ($link->rel == Link::OPDS_IMAGE_TYPE)
506
                return $link->hrefXhtml ();
507
        }
508
        return null;
509
    }
510
}
511
512
class Page
513
{
514
    public $title;
515
    public $subtitle = "";
516
    public $authorName = "";
517
    public $authorUri = "";
518
    public $authorEmail = "";
519
    public $idPage;
520
    public $idGet;
521
    public $query;
522
    public $favicon;
523
    public $n;
524
    public $book;
525
    public $totalNumber = -1;
526
527
    /* @var Entry[] */
528
    public $entryArray = array();
529
530 102
    public static function getPage ($pageId, $id, $query, $n)
531
    {
532
        switch ($pageId) {
533 102
            case Base::PAGE_ALL_AUTHORS :
534 3
                return new PageAllAuthors ($id, $query, $n);
535 99
            case Base::PAGE_AUTHORS_FIRST_LETTER :
536 1
                return new PageAllAuthorsLetter ($id, $query, $n);
537 98
            case Base::PAGE_AUTHOR_DETAIL :
538 7
                return new PageAuthorDetail ($id, $query, $n);
539 91
            case Base::PAGE_ALL_TAGS :
540 2
                return new PageAllTags ($id, $query, $n);
541 89
            case Base::PAGE_TAG_DETAIL :
542 1
                return new PageTagDetail ($id, $query, $n);
543 88
            case Base::PAGE_ALL_LANGUAGES :
544 2
                return new PageAllLanguages ($id, $query, $n);
545 86
            case Base::PAGE_LANGUAGE_DETAIL :
546 1
                return new PageLanguageDetail ($id, $query, $n);
547 85
            case Base::PAGE_ALL_CUSTOMS :
548 12
                return new PageAllCustoms ($id, $query, $n);
549 73
            case Base::PAGE_CUSTOM_DETAIL :
550 4
                return new PageCustomDetail ($id, $query, $n);
551 69
            case Base::PAGE_ALL_RATINGS :
552 1
                return new PageAllRating ($id, $query, $n);
553 68
            case Base::PAGE_RATING_DETAIL :
554 1
                return new PageRatingDetail ($id, $query, $n);
555 67
            case Base::PAGE_ALL_SERIES :
556 2
                return new PageAllSeries ($id, $query, $n);
557 65
            case Base::PAGE_ALL_BOOKS :
558 3
                return new PageAllBooks ($id, $query, $n);
559 62
            case Base::PAGE_ALL_BOOKS_LETTER:
560 1
                return new PageAllBooksLetter ($id, $query, $n);
561 61
            case Base::PAGE_ALL_RECENT_BOOKS :
562 4
                return new PageRecentBooks ($id, $query, $n);
563 57
            case Base::PAGE_SERIE_DETAIL :
564 1
                return new PageSerieDetail ($id, $query, $n);
565 56
            case Base::PAGE_OPENSEARCH_QUERY :
566 31
                return new PageQueryResult ($id, $query, $n);
567 25
            case Base::PAGE_BOOK_DETAIL :
568 1
                return new PageBookDetail ($id, $query, $n);
569 24
            case Base::PAGE_ALL_PUBLISHERS:
570 2
                return new PageAllPublishers ($id, $query, $n);
571 22
            case Base::PAGE_PUBLISHER_DETAIL :
572 1
                return new PagePublisherDetail ($id, $query, $n);
573 21
            case Base::PAGE_ABOUT :
574
                return new PageAbout ($id, $query, $n);
575 21
            case Base::PAGE_CUSTOMIZE :
576
                return new PageCustomize ($id, $query, $n);
577 21
            default:
578 21
                $page = new Page ($id, $query, $n);
579 21
                $page->idPage = "cops:catalog";
580 21
                return $page;
581 21
        }
582
    }
583
584 102
    public function __construct($pid, $pquery, $pn) {
585 102
        global $config;
586
587 102
        $this->idGet = $pid;
588 102
        $this->query = $pquery;
589 102
        $this->n = $pn;
590 102
        $this->favicon = $config['cops_icon'];
591 102
        $this->authorName = empty($config['cops_author_name']) ? utf8_encode('Sébastien Lucas') : $config['cops_author_name'];
592 102
        $this->authorUri = empty($config['cops_author_uri']) ? 'http://blog.slucas.fr' : $config['cops_author_uri'];
593 102
        $this->authorEmail = empty($config['cops_author_email']) ? '[email protected]' : $config['cops_author_email'];
594 102
    }
595
596 21
    public function InitializeContent ()
597
    {
598 21
        global $config;
599 21
        $this->title = $config['cops_title_default'];
600 21
        $this->subtitle = $config['cops_subtitle_default'];
601 21
        if (Base::noDatabaseSelected ()) {
602 2
            $i = 0;
603 2
            foreach (Base::getDbNameList () as $key) {
604 2
                $nBooks = Book::getBookCount ($i);
605 2
                array_push ($this->entryArray, new Entry ($key, "cops:{$i}:catalog",
606 2
                                        str_format (localize ("bookword", $nBooks), $nBooks), "text",
607 2
                                        array ( new LinkNavigation ("?" . DB . "={$i}")), "", $nBooks));
608 2
                $i++;
609 2
                Base::clearDb ();
610 2
            }
611 2
        } else {
612 19
            if (!in_array (PageQueryResult::SCOPE_AUTHOR, getCurrentOption ('ignored_categories'))) {
613 18
                array_push ($this->entryArray, Author::getCount());
614 18
            }
615 19
            if (!in_array (PageQueryResult::SCOPE_SERIES, getCurrentOption ('ignored_categories'))) {
616 18
                $series = Serie::getCount();
617 18
                if (!is_null ($series)) array_push ($this->entryArray, $series);
618 18
            }
619 19
            if (!in_array (PageQueryResult::SCOPE_PUBLISHER, getCurrentOption ('ignored_categories'))) {
620 18
                $publisher = Publisher::getCount();
621 18
                if (!is_null ($publisher)) array_push ($this->entryArray, $publisher);
622 18
            }
623 19
            if (!in_array (PageQueryResult::SCOPE_TAG, getCurrentOption ('ignored_categories'))) {
624 18
                $tags = Tag::getCount();
625 18
                if (!is_null ($tags)) array_push ($this->entryArray, $tags);
626 18
            }
627 19
            if (!in_array (PageQueryResult::SCOPE_RATING, getCurrentOption ('ignored_categories'))) {
628 19
                $rating = Rating::getCount();
629 19
                if (!is_null ($rating)) array_push ($this->entryArray, $rating);
630 19
            }
631 19
            if (!in_array ("language", getCurrentOption ('ignored_categories'))) {
632 18
                $languages = Language::getCount();
633 18
                if (!is_null ($languages)) array_push ($this->entryArray, $languages);
634 18
            }
635 19
            foreach ($config['cops_calibre_custom_column'] as $lookup) {
636 15
                $customColumn = CustomColumnType::createByLookup($lookup);
637 15
                if (!is_null ($customColumn) && $customColumn->isSearchable()) {
638 14
                    array_push ($this->entryArray, $customColumn->getCount());
639 14
                }
640 19
            }
641 19
            $this->entryArray = array_merge ($this->entryArray, Book::getCount());
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->entryArray, \Book::getCount()) of type array is incompatible with the declared type array<integer,object<Entry>> of property $entryArray.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
642
643 19
            if (Base::isMultipleDatabaseEnabled ()) $this->title =  Base::getDbName ();
644
        }
645 21
    }
646
647 17
    public function isPaginated ()
648
    {
649 17
        return (getCurrentOption ("max_item_per_page") != -1 &&
650 17
                $this->totalNumber != -1 &&
651 17
                $this->totalNumber > getCurrentOption ("max_item_per_page"));
652
    }
653
654 2
    public function getNextLink ()
655
    {
656 2
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
657 2
        if (($this->n) * getCurrentOption ("max_item_per_page") < $this->totalNumber) {
658 1
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n + 1), "next", localize ("paging.next.alternate"));
659
        }
660 1
        return NULL;
661
    }
662
663 2
    public function getPrevLink ()
664
    {
665 2
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
666 2
        if ($this->n > 1) {
667 1
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n - 1), "previous", localize ("paging.previous.alternate"));
668
        }
669 2
        return NULL;
670
    }
671
672 2
    public function getMaxPage ()
673
    {
674 2
        return ceil ($this->totalNumber / getCurrentOption ("max_item_per_page"));
675
    }
676
677 70
    public function containsBook ()
678
    {
679 70
        if (count ($this->entryArray) == 0) return false;
680 68
        if (get_class ($this->entryArray [0]) == "EntryBook") return true;
681 46
        return false;
682
    }
683
}
684
685
class PageAllAuthors extends Page
686
{
687 3
    public function InitializeContent ()
688
    {
689 3
        $this->title = localize("authors.title");
690 3
        if (getCurrentOption ("author_split_first_letter") == 1) {
691 2
            $this->entryArray = Author::getAllAuthorsByFirstLetter();
692 2
        }
693
        else {
694 1
            $this->entryArray = Author::getAllAuthors();
695
        }
696 3
        $this->idPage = Author::ALL_AUTHORS_ID;
697 3
    }
698
}
699
700
class PageAllAuthorsLetter extends Page
701
{
702 1
    public function InitializeContent ()
703
    {
704 1
        $this->idPage = Author::getEntryIdByLetter ($this->idGet);
705 1
        $this->entryArray = Author::getAuthorsByStartingLetter ($this->idGet);
706 1
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("authorword", count ($this->entryArray)), count ($this->entryArray)), $this->idGet);
707 1
    }
708
}
709
710
class PageAuthorDetail extends Page
711
{
712 7
    public function InitializeContent ()
713
    {
714 7
        $author = Author::getAuthorById ($this->idGet);
715 7
        $this->idPage = $author->getEntryId ();
716 7
        $this->title = $author->name;
717 7
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByAuthor ($this->idGet, $this->n);
718 7
    }
719
}
720
721
class PageAllPublishers extends Page
722
{
723 2
    public function InitializeContent ()
724
    {
725 2
        $this->title = localize("publishers.title");
726 2
        $this->entryArray = Publisher::getAllPublishers();
727 2
        $this->idPage = Publisher::ALL_PUBLISHERS_ID;
728 2
    }
729
}
730
731
class PagePublisherDetail extends Page
732
{
733 1
    public function InitializeContent ()
734
    {
735 1
        $publisher = Publisher::getPublisherById ($this->idGet);
736 1
        $this->title = $publisher->name;
737 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByPublisher ($this->idGet, $this->n);
738 1
        $this->idPage = $publisher->getEntryId ();
739 1
    }
740
}
741
742
class PageAllTags extends Page
743
{
744 2
    public function InitializeContent ()
745
    {
746 2
        $this->title = localize("tags.title");
747 2
        $this->entryArray = Tag::getAllTags();
748 2
        $this->idPage = Tag::ALL_TAGS_ID;
749 2
    }
750
}
751
752
class PageAllLanguages extends Page
753
{
754 2
    public function InitializeContent ()
755
    {
756 2
        $this->title = localize("languages.title");
757 2
        $this->entryArray = Language::getAllLanguages();
758 2
        $this->idPage = Language::ALL_LANGUAGES_ID;
759 2
    }
760
}
761
762
class PageCustomDetail extends Page
763
{
764 4
    public function InitializeContent ()
765
    {
766 4
        $customId = getURLParam ("custom", NULL);
767 4
        $custom = CustomColumn::createCustom ($customId, $this->idGet);
768 4
        $this->idPage = $custom->getEntryId ();
769 4
        $this->title = $custom->value;
770 4
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByCustom ($custom, $this->idGet, $this->n);
771 4
    }
772
}
773
774
class PageAllCustoms extends Page
775
{
776 12
    public function InitializeContent ()
777
    {
778 12
        $customId = getURLParam ("custom", NULL);
779 12
        $columnType = CustomColumnType::createByCustomID($customId);
780
        
781 12
        $this->title = $columnType->getTitle();
782 12
        $this->entryArray = $columnType->getAllCustomValues();
783 12
        $this->idPage = $columnType->getAllCustomsId();
784 12
    }
785
}
786
787
class PageTagDetail extends Page
788
{
789 1
    public function InitializeContent ()
790
    {
791 1
        $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
}
797
798
class PageLanguageDetail extends Page
799
{
800 1
    public function InitializeContent ()
801
    {
802 1
        $language = Language::getLanguageById ($this->idGet);
803 1
        $this->idPage = $language->getEntryId ();
804 1
        $this->title = $language->lang_code;
805 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByLanguage ($this->idGet, $this->n);
806 1
    }
807
}
808
809
class PageAllSeries extends Page
810
{
811 2
    public function InitializeContent ()
812
    {
813 2
        $this->title = localize("series.title");
814 2
        $this->entryArray = Serie::getAllSeries();
815 2
        $this->idPage = Serie::ALL_SERIES_ID;
816 2
    }
817
}
818
819
class PageSerieDetail extends Page
820
{
821 1
    public function InitializeContent ()
822
    {
823 1
        $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
}
839
840
class PageRatingDetail extends Page
841
{
842 1
    public function InitializeContent ()
843
    {
844 1
        $rating = Rating::getRatingById ($this->idGet);
845 1
        $this->idPage = $rating->getEntryId ();
846 1
        $this->title =str_format (localize ("ratingword", $rating->name/2), $rating->name/2);
847 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByRating ($this->idGet, $this->n);
848 1
    }
849
}
850
851
class PageAllBooks extends Page
852
{
853 3
    public function InitializeContent ()
854
    {
855 3
        $this->title = localize ("allbooks.title");
856 3
        if (getCurrentOption ("titles_split_first_letter") == 1) {
857 2
            $this->entryArray = Book::getAllBooks();
858 2
        }
859
        else {
860 1
            list ($this->entryArray, $this->totalNumber) = Book::getBooks ($this->n);
861
        }
862 3
        $this->idPage = Book::ALL_BOOKS_ID;
863 3
    }
864
}
865
866
class PageAllBooksLetter extends Page
867
{
868 1
    public function InitializeContent ()
869
    {
870 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByStartingLetter ($this->idGet, $this->n);
871 1
        $this->idPage = Book::getEntryIdByLetter ($this->idGet);
872
873 1
        $count = $this->totalNumber;
874 1
        if ($count == -1)
875 1
            $count = count ($this->entryArray);
876
877 1
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("bookword", $count), $count), $this->idGet);
878 1
    }
879
}
880
881
class PageRecentBooks extends Page
882
{
883 4
    public function InitializeContent ()
884
    {
885 4
        $this->title = localize ("recent.title");
886 4
        $this->entryArray = Book::getAllRecentBooks ();
887 4
        $this->idPage = Book::ALL_RECENT_BOOKS_ID;
888 4
    }
889
}
890
891
class PageQueryResult extends Page
892
{
893
    const SCOPE_TAG = "tag";
894
    const SCOPE_RATING = "rating";
895
    const SCOPE_SERIES = "series";
896
    const SCOPE_AUTHOR = "author";
897
    const SCOPE_BOOK = "book";
898
    const SCOPE_PUBLISHER = "publisher";
899
900 24
    private function useTypeahead () {
901 24
        return !is_null (getURLParam ("search"));
902
    }
903
904 29
    private function searchByScope ($scope, $limit = FALSE) {
905 29
        $n = $this->n;
906 29
        $numberPerPage = NULL;
907 29
        $queryNormedAndUp = trim($this->query);
908 29
        if (useNormAndUp ()) {
909 7
            $queryNormedAndUp = normAndUp ($this->query);
910 7
        }
911 29
        if ($limit) {
912 22
            $n = 1;
913 22
            $numberPerPage = 5;
914 22
        }
915
        switch ($scope) {
916 29
            case self::SCOPE_BOOK :
917 23
                $array = Book::getBooksByStartingLetter ('%' . $queryNormedAndUp, $n, NULL, $numberPerPage);
918 23
                break;
919 28
            case self::SCOPE_AUTHOR :
920 23
                $array = Author::getAuthorsForSearch ('%' . $queryNormedAndUp);
921 23
                break;
922 25
            case self::SCOPE_SERIES :
923 22
                $array = Serie::getAllSeriesByQuery ($queryNormedAndUp);
924 22
                break;
925 24
            case self::SCOPE_TAG :
926 23
                $array = Tag::getAllTagsByQuery ($queryNormedAndUp, $n, NULL, $numberPerPage);
927 23
                break;
928 23
            case self::SCOPE_PUBLISHER :
929 23
                $array = Publisher::getAllPublishersByQuery ($queryNormedAndUp);
930 23
                break;
931
            default:
932
                $array = Book::getBooksByQuery (
933
                    array ("all" => "%" . $queryNormedAndUp . "%"), $n);
934
        }
935
936 29
        return $array;
937
    }
938
939 22
    public function doSearchByCategory () {
940 22
        $database = GetUrlParam (DB);
941 22
        $out = array ();
942 22
        $pagequery = Base::PAGE_OPENSEARCH_QUERY;
943 22
        $dbArray = array ("");
944 22
        $d = $database;
945 22
        $query = $this->query;
946
        // Special case when no databases were chosen, we search on all databases
947 22
        if (Base::noDatabaseSelected ()) {
948 1
            $dbArray = Base::getDbNameList ();
949 1
            $d = 0;
950 1
        }
951 22
        foreach ($dbArray as $key) {
952 22
            if (Base::noDatabaseSelected ()) {
953 1
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$d}",
954 1
                                        " ", "text",
955 1
                                        array ( new LinkNavigation ("?" . DB . "={$d}")), "tt-header"));
956 1
                Base::getDb ($d);
957 1
            }
958 22
            foreach (array (PageQueryResult::SCOPE_BOOK,
959 22
                            PageQueryResult::SCOPE_AUTHOR,
960 22
                            PageQueryResult::SCOPE_SERIES,
961 22
                            PageQueryResult::SCOPE_TAG,
962 22
                            PageQueryResult::SCOPE_PUBLISHER) as $key) {
963 22
                if (in_array($key, getCurrentOption ('ignored_categories'))) {
964 3
                    continue;
965
                }
966 22
                $array = $this->searchByScope ($key, TRUE);
967
968 22
                $i = 0;
969 22
                if (count ($array) == 2 && is_array ($array [0])) {
970 22
                    $total = $array [1];
971 22
                    $array = $array [0];
972 22
                } else {
973 22
                    $total = count($array);
974
                }
975 22
                if ($total > 0) {
976
                    // Comment to help the perl i18n script
977
                    // str_format (localize("bookword", count($array))
978
                    // str_format (localize("authorword", count($array))
979
                    // str_format (localize("seriesword", count($array))
980
                    // str_format (localize("tagword", count($array))
981
                    // str_format (localize("publisherword", count($array))
982 21
                    array_push ($this->entryArray, new Entry (str_format (localize ("search.result.{$key}"), $this->query), DB . ":query:{$d}:{$key}",
983 21
                                        str_format (localize("{$key}word", $total), $total), "text",
984 21
                                        array ( new LinkNavigation ("?page={$pagequery}&query={$query}&db={$d}&scope={$key}")),
985 21
                                        Base::noDatabaseSelected () ? "" : "tt-header", $total));
986 21
                }
987 22
                if (!Base::noDatabaseSelected () && $this->useTypeahead ()) {
988 6
                    foreach ($array as $entry) {
989 6
                        array_push ($this->entryArray, $entry);
990 6
                        $i++;
991 6
                        if ($i > 4) { break; };
992 6
                    }
993 6
                }
994 22
            }
995 22
            $d++;
996 22
            if (Base::noDatabaseSelected ()) {
997 1
                Base::clearDb ();
998 1
            }
999 22
        }
1000 22
        return $out;
1001
    }
1002
1003 31
    public function InitializeContent ()
1004
    {
1005 31
        $scope = getURLParam ("scope");
1006 31
        if (empty ($scope)) {
1007 24
            $this->title = str_format (localize ("search.result"), $this->query);
1008 24
        } else {
1009
            // Comment to help the perl i18n script
1010
            // str_format (localize ("search.result.author"), $this->query)
1011
            // str_format (localize ("search.result.tag"), $this->query)
1012
            // str_format (localize ("search.result.series"), $this->query)
1013
            // str_format (localize ("search.result.book"), $this->query)
1014
            // str_format (localize ("search.result.publisher"), $this->query)
1015 7
            $this->title = str_format (localize ("search.result.{$scope}"), $this->query);
1016
        }
1017
1018 31
        $crit = "%" . $this->query . "%";
1019
1020
        // Special case when we are doing a search and no database is selected
1021 31
        if (Base::noDatabaseSelected () && !$this->useTypeahead ()) {
1022 2
            $i = 0;
1023 2
            foreach (Base::getDbNameList () as $key) {
1024 2
                Base::clearDb ();
1025 2
                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...
1026 2
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$i}",
1027 2
                                        str_format (localize ("bookword", $totalNumber), $totalNumber), "text",
1028 2
                                        array ( new LinkNavigation ("?" . DB . "={$i}&page=9&query=" . $this->query)), "", $totalNumber));
1029 2
                $i++;
1030 2
            }
1031 2
            return;
1032
        }
1033 29
        if (empty ($scope)) {
1034 22
            $this->doSearchByCategory ();
1035 22
            return;
1036
        }
1037
1038 7
        $array = $this->searchByScope ($scope);
1039 7
        if (count ($array) == 2 && is_array ($array [0])) {
1040 2
            list ($this->entryArray, $this->totalNumber) = $array;
1041 2
        } else {
1042 5
            $this->entryArray = $array;
1043
        }
1044 7
    }
1045
}
1046
1047
class PageBookDetail extends Page
1048
{
1049 1
    public function InitializeContent ()
1050
    {
1051 1
        $this->book = Book::getBookById ($this->idGet);
1052 1
        $this->title = $this->book->title;
1053 1
    }
1054
}
1055
1056
class PageAbout extends Page
1057
{
1058
    public function InitializeContent ()
1059
    {
1060
        $this->title = localize ("about.title");
1061
    }
1062
}
1063
1064
class PageCustomize extends Page
1065
{
1066
    private function isChecked ($key, $testedValue = 1) {
1067
        $value = getCurrentOption ($key);
1068
        if (is_array ($value)) {
1069
            if (in_array ($testedValue, $value)) {
1070
                return "checked='checked'";
1071
            }
1072
        } else {
1073
            if ($value == $testedValue) {
1074
                return "checked='checked'";
1075
            }
1076
        }
1077
        return "";
1078
    }
1079
1080
    private function isSelected ($key, $value) {
1081
        if (getCurrentOption ($key) == $value) {
1082
            return "selected='selected'";
1083
        }
1084
        return "";
1085
    }
1086
1087
    private function getStyleList () {
1088
        $result = array ();
1089
        foreach (glob ("templates/" . getCurrentTemplate () . "/styles/style-*.css") as $filename) {
1090
            if (preg_match ('/styles\/style-(.*?)\.css/', $filename, $m)) {
1091
                array_push ($result, $m [1]);
1092
            }
1093
        }
1094
        return $result;
1095
    }
1096
1097
    public function InitializeContent ()
1098
    {
1099
        $this->title = localize ("customize.title");
1100
        $this->entryArray = array ();
1101
1102
        $ignoredBaseArray = array (PageQueryResult::SCOPE_AUTHOR,
1103
                                   PageQueryResult::SCOPE_TAG,
1104
                                   PageQueryResult::SCOPE_SERIES,
1105
                                   PageQueryResult::SCOPE_PUBLISHER,
1106
                                   PageQueryResult::SCOPE_RATING,
1107
                                   "language");
1108
1109
        $content = "";
1110
        array_push ($this->entryArray, new Entry ("Template", "",
1111
                                        "<span style='cursor: pointer;' onclick='$.cookie(\"template\", \"bootstrap\", { expires: 365 });window.location=$(\".headleft\").attr(\"href\");'>Click to switch to Bootstrap</span>", "text",
1112
                                        array ()));
1113
        if (!preg_match("/(Kobo|Kindle\/3.0|EBRD1101)/", $_SERVER['HTTP_USER_AGENT'])) {
1114
            $content .= '<select id="style" onchange="updateCookie (this);">';
1115
            foreach ($this-> getStyleList () as $filename) {
1116
                $content .= "<option value='{$filename}' " . $this->isSelected ("style", $filename) . ">{$filename}</option>";
1117
            }
1118
            $content .= '</select>';
1119
        } else {
1120
            foreach ($this-> getStyleList () as $filename) {
1121
                $content .= "<input type='radio' onchange='updateCookieFromCheckbox (this);' id='style-{$filename}' name='style' value='{$filename}' " . $this->isChecked ("style", $filename) . " /><label for='style-{$filename}'> {$filename} </label>";
1122
            }
1123
        }
1124
        array_push ($this->entryArray, new Entry (localize ("customize.style"), "",
1125
                                        $content, "text",
1126
                                        array ()));
1127
        if (!useServerSideRendering ()) {
1128
            $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="use_fancyapps" ' . $this->isChecked ("use_fancyapps") . ' />';
1129
            array_push ($this->entryArray, new Entry (localize ("customize.fancybox"), "",
1130
                                            $content, "text",
1131
                                            array ()));
1132
        }
1133
        $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]+$" />';
1134
        array_push ($this->entryArray, new Entry (localize ("customize.paging"), "",
1135
                                        $content, "text",
1136
                                        array ()));
1137
        $content = '<input type="text" onchange="updateCookie (this);" id="email" value="' . getCurrentOption ("email") . '" />';
1138
        array_push ($this->entryArray, new Entry (localize ("customize.email"), "",
1139
                                        $content, "text",
1140
                                        array ()));
1141
        $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="html_tag_filter" ' . $this->isChecked ("html_tag_filter") . ' />';
1142
        array_push ($this->entryArray, new Entry (localize ("customize.filter"), "",
1143
                                        $content, "text",
1144
                                        array ()));
1145
        $content = "";
1146
        foreach ($ignoredBaseArray as $key) {
1147
            $keyPlural = preg_replace ('/(ss)$/', 's', $key . "s");
1148
            $content .=  '<input type="checkbox" name="ignored_categories[]" onchange="updateCookieFromCheckboxGroup (this);" id="ignored_categories_' . $key . '" ' . $this->isChecked ("ignored_categories", $key) . ' > ' . localize ("{$keyPlural}.title") . '</input> ';
1149
        }
1150
1151
        array_push ($this->entryArray, new Entry (localize ("customize.ignored"), "",
1152
                                        $content, "text",
1153
                                        array ()));
1154
    }
1155
}
1156
1157
abstract class Base
1158
{
1159
    const PAGE_INDEX = "index";
1160
    const PAGE_ALL_AUTHORS = "1";
1161
    const PAGE_AUTHORS_FIRST_LETTER = "2";
1162
    const PAGE_AUTHOR_DETAIL = "3";
1163
    const PAGE_ALL_BOOKS = "4";
1164
    const PAGE_ALL_BOOKS_LETTER = "5";
1165
    const PAGE_ALL_SERIES = "6";
1166
    const PAGE_SERIE_DETAIL = "7";
1167
    const PAGE_OPENSEARCH = "8";
1168
    const PAGE_OPENSEARCH_QUERY = "9";
1169
    const PAGE_ALL_RECENT_BOOKS = "10";
1170
    const PAGE_ALL_TAGS = "11";
1171
    const PAGE_TAG_DETAIL = "12";
1172
    const PAGE_BOOK_DETAIL = "13";
1173
    const PAGE_ALL_CUSTOMS = "14";
1174
    const PAGE_CUSTOM_DETAIL = "15";
1175
    const PAGE_ABOUT = "16";
1176
    const PAGE_ALL_LANGUAGES = "17";
1177
    const PAGE_LANGUAGE_DETAIL = "18";
1178
    const PAGE_CUSTOMIZE = "19";
1179
    const PAGE_ALL_PUBLISHERS = "20";
1180
    const PAGE_PUBLISHER_DETAIL = "21";
1181
    const PAGE_ALL_RATINGS = "22";
1182
    const PAGE_RATING_DETAIL = "23";
1183
1184
    const COMPATIBILITY_XML_ALDIKO = "aldiko";
1185
1186
    private static $db = NULL;
1187
1188 144
    public static function isMultipleDatabaseEnabled () {
1189 144
        global $config;
1190 144
        return is_array ($config['calibre_directory']);
1191
    }
1192
1193 49
    public static function useAbsolutePath () {
1194 49
        global $config;
1195 49
        $path = self::getDbDirectory();
1196 49
        return preg_match ('/^\//', $path) || // Linux /
1197 49
               preg_match ('/^\w\:/', $path); // Windows X:
1198
    }
1199
1200 56
    public static function noDatabaseSelected () {
1201 56
        return self::isMultipleDatabaseEnabled () && is_null (GetUrlParam (DB));
1202
    }
1203
1204 4
    public static function getDbList () {
1205 4
        global $config;
1206 4
        if (self::isMultipleDatabaseEnabled ()) {
1207 4
            return $config['calibre_directory'];
1208
        } else {
1209 1
            return array ("" => $config['calibre_directory']);
1210
        }
1211
    }
1212
1213 5
    public static function getDbNameList () {
1214 5
        global $config;
1215 5
        if (self::isMultipleDatabaseEnabled ()) {
1216 5
            return array_keys ($config['calibre_directory']);
1217
        } else {
1218
            return array ("");
1219
        }
1220
    }
1221
1222 1
    public static function getDbName ($database = NULL) {
1223 1
        global $config;
1224 1
        if (self::isMultipleDatabaseEnabled ()) {
1225 1
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1226 1
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1227
                self::error ($database);
1228
            }
1229 1
            $array = array_keys ($config['calibre_directory']);
1230 1
            return  $array[$database];
1231
        }
1232
        return "";
1233
    }
1234
1235 126
    public static function getDbDirectory ($database = NULL) {
1236 126
        global $config;
1237 126
        if (self::isMultipleDatabaseEnabled ()) {
1238 9
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1239 9
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1240
                self::error ($database);
1241
            }
1242 9
            $array = array_values ($config['calibre_directory']);
1243 9
            return  $array[$database];
1244
        }
1245 117
        return $config['calibre_directory'];
1246
    }
1247
1248
1249 98
    public static function getDbFileName ($database = NULL) {
1250 98
        return self::getDbDirectory ($database) .'metadata.db';
1251
    }
1252
1253 2
    private static function error ($database) {
1254 2
        if (php_sapi_name() != "cli") {
1255
            header("location: checkconfig.php?err=1");
1256
        }
1257 2
        throw new Exception("Database <{$database}> not found.");
1258
    }
1259
1260 159
    public static function getDb ($database = NULL) {
1261 159
        if (is_null (self::$db)) {
1262
            try {
1263 98
                if (is_readable (self::getDbFileName ($database))) {
1264 97
                    self::$db = new PDO('sqlite:'. self::getDbFileName ($database));
1265 97
                    if (useNormAndUp ()) {
1266 7
                        self::$db->sqliteCreateFunction ('normAndUp', 'normAndUp', 1);
1267 7
                    }
1268 97
                } else {
1269 2
                    self::error ($database);
1270
                }
1271 98
            } catch (Exception $e) {
1272 2
                self::error ($database);
1273
            }
1274 97
        }
1275 158
        return self::$db;
1276
    }
1277
1278 4
    public static function checkDatabaseAvailability () {
1279 4
        if (self::noDatabaseSelected ()) {
1280 3
            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...
1281 3
                self::getDb ($i);
1282 2
                self::clearDb ();
1283 2
            }
1284 1
        } else {
1285 1
            self::getDb ();
1286
        }
1287 2
        return true;
1288
    }
1289
1290 103
    public static function clearDb () {
1291 103
        self::$db = NULL;
1292 103
    }
1293
1294 24
    public static function executeQuerySingle ($query, $database = NULL) {
1295 24
        return self::getDb ($database)->query($query)->fetchColumn();
1296
    }
1297
1298 19
    public static function getCountGeneric($table, $id, $pageId, $numberOfString = NULL) {
1299 19
        if (!$numberOfString) {
1300 18
            $numberOfString = $table . ".alphabetical";
1301 18
        }
1302 19
        $count = self::executeQuerySingle ('select count(*) from ' . $table);
1303 19
        if ($count == 0) return NULL;
1304 19
        $entry = new Entry (localize($table . ".title"), $id,
1305 19
            str_format (localize($numberOfString, $count), $count), "text",
1306 19
            array ( new LinkNavigation ("?page=".$pageId)), "", $count);
1307 19
        return $entry;
1308
    }
1309
1310 35
    public static function getEntryArrayWithBookNumber ($query, $columns, $params, $category) {
1311
        /* @var $result PDOStatement */
1312
1313 35
        list (, $result) = self::executeQuery ($query, $columns, "", $params, -1);
1314 35
        $entryArray = array();
1315 35
        while ($post = $result->fetchObject ())
1316
        {
1317
            /* @var $instance Author|Tag|Serie|Publisher */
1318
1319 25
            $instance = new $category ($post);
1320 25
            if (property_exists($post, "sort")) {
1321 17
                $title = $post->sort;
1322 17
            } else {
1323 8
                $title = $post->name;
1324
            }
1325 25
            array_push ($entryArray, new Entry ($title, $instance->getEntryId (),
1326 25
                str_format (localize("bookword", $post->count), $post->count), "text",
1327 25
                array ( new LinkNavigation ($instance->getUri ())), "", $post->count));
1328 25
        }
1329 35
        return $entryArray;
1330
    }
1331
1332 75
    public static function executeQuery($query, $columns, $filter, $params, $n, $database = NULL, $numberPerPage = NULL) {
1333 75
        $totalResult = -1;
1334
1335 75
        if (useNormAndUp ()) {
1336 7
            $query = preg_replace("/upper/", "normAndUp", $query);
1337 7
            $columns = preg_replace("/upper/", "normAndUp", $columns);
1338 7
        }
1339
1340 75
        if (is_null ($numberPerPage)) {
1341 73
            $numberPerPage = getCurrentOption ("max_item_per_page");
1342 73
        }
1343
1344 75
        if ($numberPerPage != -1 && $n != -1)
1345 75
        {
1346
            // First check total number of results
1347 28
            $result = self::getDb ($database)->prepare (str_format ($query, "count(*)", $filter));
1348 28
            $result->execute ($params);
1349 28
            $totalResult = $result->fetchColumn ();
1350
1351
            // Next modify the query and params
1352 28
            $query .= " limit ?, ?";
1353 28
            array_push ($params, ($n - 1) * $numberPerPage, $numberPerPage);
1354 28
        }
1355
1356 75
        $result = self::getDb ($database)->prepare(str_format ($query, $columns, $filter));
1357 75
        $result->execute ($params);
1358 75
        return array ($totalResult, $result);
1359
    }
1360
1361
}
1362