Completed
Pull Request — master (#296)
by
unknown
11:06
created

PagePublishdateMonth::InitializeContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
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.1");
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
        Publishdate::ALL_PUBLISHDATES_ID => 'images/publishdate.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
        return date (DATE_ATOM, self::$updated);
435
    }
436 7
437 7
    public function getNavLink () {
438
        foreach ($this->linkArray as $link) {
439
            /* @var $link LinkNavigation */
440 7
441
            if ($link->type != Link::OPDS_NAVIGATION_TYPE) { continue; }
442 7
443
            return $link->hrefXhtml ();
444
        }
445
        return "#";
446
    }
447 109
448 109
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pclass = "", $pcount = 0) {
449 109
        global $config;
450 109
        $this->title = $ptitle;
451 109
        $this->id = $pid;
452 109
        $this->content = $pcontent;
453 109
        $this->contentType = $pcontentType;
454 109
        $this->linkArray = $plinkArray;
455 109
        $this->className = $pclass;
456
        $this->numberOfElement = $pcount;
457 109
458 109
        if ($config['cops_show_icons'] == 1)
459 109
        {
460
            foreach (self::$icons as $reg => $image)
461 109
            {
462 69
                if (preg_match ("/" . $reg . "/", $pid)) {
463 69
                    array_push ($this->linkArray, new Link (getUrlWithVersion ($image), "image/png", Link::OPDS_THUMBNAIL_TYPE));
464
                    break;
465 109
                }
466 109
            }
467
        }
468 109
469 109
        if (!is_null (GetUrlParam (DB))) $this->id = str_replace ("cops:", "cops:" . GetUrlParam (DB) . ":", $this->id);
470
    }
471
}
472
473
class EntryBook extends Entry
474
{
475
    public $book;
476
477
    /**
478
     * EntryBook constructor.
479
     * @param string $ptitle
480
     * @param integer $pid
481
     * @param string $pcontent
482
     * @param string $pcontentType
483
     * @param array $plinkArray
484
     * @param Book $pbook
485 41
     */
486 41
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pbook) {
487 41
        parent::__construct ($ptitle, $pid, $pcontent, $pcontentType, $plinkArray);
488 41
        $this->book = $pbook;
489 41
        $this->localUpdated = $pbook->timestamp;
490
    }
491
492
    public function getCoverThumbnail () {
493
        foreach ($this->linkArray as $link) {
494
            /* @var $link LinkNavigation */
495
496
            if ($link->rel == Link::OPDS_THUMBNAIL_TYPE)
497
                return $link->hrefXhtml ();
498
        }
499
        return null;
500
    }
501
502
    public function getCover () {
503
        foreach ($this->linkArray as $link) {
504
            /* @var $link LinkNavigation */
505
506
            if ($link->rel == Link::OPDS_IMAGE_TYPE)
507
                return $link->hrefXhtml ();
508
        }
509
        return null;
510
    }
511
}
512
513
class Page
514
{
515
    public $title;
516
    public $subtitle = "";
517
    public $authorName = "";
518
    public $authorUri = "";
519
    public $authorEmail = "";
520
    public $idPage;
521
    public $idGet;
522
    public $query;
523
    public $favicon;
524
    public $n;
525
    public $book;
526
    public $totalNumber = -1;
527
528
    /* @var Entry[] */
529
    public $entryArray = array();
530 102
531
    public static function getPage ($pageId, $id, $query, $n)
532
    {
533 102
        switch ($pageId) {
534 3
            case Base::PAGE_ALL_AUTHORS :
535 99
                return new PageAllAuthors ($id, $query, $n);
536 1
            case Base::PAGE_AUTHORS_FIRST_LETTER :
537 98
                return new PageAllAuthorsLetter ($id, $query, $n);
538 7
            case Base::PAGE_AUTHOR_DETAIL :
539 91
                return new PageAuthorDetail ($id, $query, $n);
540 2
            case Base::PAGE_ALL_TAGS :
541 89
                return new PageAllTags ($id, $query, $n);
542 1
            case Base::PAGE_TAG_DETAIL :
543 88
                return new PageTagDetail ($id, $query, $n);
544 2
            case Base::PAGE_ALL_LANGUAGES :
545 86
                return new PageAllLanguages ($id, $query, $n);
546 1
            case Base::PAGE_LANGUAGE_DETAIL :
547 85
                return new PageLanguageDetail ($id, $query, $n);
548 12
            case Base::PAGE_ALL_CUSTOMS :
549 73
                return new PageAllCustoms ($id, $query, $n);
550 4
            case Base::PAGE_CUSTOM_DETAIL :
551 69
                return new PageCustomDetail ($id, $query, $n);
552 1
            case Base::PAGE_ALL_RATINGS :
553 68
                return new PageAllRating ($id, $query, $n);
554 1
            case Base::PAGE_RATING_DETAIL :
555 67
                return new PageRatingDetail ($id, $query, $n);
556 2
            case Base::PAGE_ALL_SERIES :
557 65
                return new PageAllSeries ($id, $query, $n);
558 3
            case Base::PAGE_ALL_BOOKS :
559 62
                return new PageAllBooks ($id, $query, $n);
560 1
            case Base::PAGE_ALL_BOOKS_LETTER:
561 61
                return new PageAllBooksLetter ($id, $query, $n);
562 4
            case Base::PAGE_ALL_RECENT_BOOKS :
563 57
                return new PageRecentBooks ($id, $query, $n);
564 1
            case Base::PAGE_SERIE_DETAIL :
565 56
                return new PageSerieDetail ($id, $query, $n);
566 31
            case Base::PAGE_OPENSEARCH_QUERY :
567 25
                return new PageQueryResult ($id, $query, $n);
568 1
            case Base::PAGE_BOOK_DETAIL :
569 24
                return new PageBookDetail ($id, $query, $n);
570 2
            case Base::PAGE_ALL_PUBLISHERS:
571 22
                return new PageAllPublishers ($id, $query, $n);
572 1
            case Base::PAGE_PUBLISHER_DETAIL :
573 21
                return new PagePublisherDetail ($id, $query, $n);
574
            case Base::PAGE_ALL_PUBLISHDATES:
575 21
                return new PageAllPublishdates ($id, $query, $n);
576
            case Base::PAGE_PUBLISHDATE_YEAR :
577 21
                return new PagePublishdateYear($id, $query, $n);
578 21
            case Base::PAGE_PUBLISHDATE_MONTH :
579 21
                return new PagePublishdateMonth ($id, $query, $n);
580 21
            case Base::PAGE_ABOUT :
581 21
                return new PageAbout ($id, $query, $n);
582
            case Base::PAGE_CUSTOMIZE :
583
                return new PageCustomize ($id, $query, $n);
584 102
            default:
585 102
                $page = new Page ($id, $query, $n);
586
                $page->idPage = "cops:catalog";
587 102
                return $page;
588 102
        }
589 102
    }
590 102
591 102
    public function __construct($pid, $pquery, $pn) {
592 102
        global $config;
593 102
594 102
        $this->idGet = $pid;
595
        $this->query = $pquery;
596 21
        $this->n = $pn;
597
        $this->favicon = $config['cops_icon'];
598 21
        $this->authorName = empty($config['cops_author_name']) ? utf8_encode('Sébastien Lucas') : $config['cops_author_name'];
599 21
        $this->authorUri = empty($config['cops_author_uri']) ? 'http://blog.slucas.fr' : $config['cops_author_uri'];
600 21
        $this->authorEmail = empty($config['cops_author_email']) ? '[email protected]' : $config['cops_author_email'];
601 21
    }
602 2
603 2
    public function InitializeContent ()
604 2
    {
605 2
        global $config;
606 2
        $this->title = $config['cops_title_default'];
607 2
        $this->subtitle = $config['cops_subtitle_default'];
608 2
        if (Base::noDatabaseSelected ()) {
609 2
            $i = 0;
610 2
            foreach (Base::getDbNameList () as $key) {
611 2
                $nBooks = Book::getBookCount ($i);
612 19
                array_push ($this->entryArray, new Entry ($key, "cops:{$i}:catalog",
613 18
                                        str_format (localize ("bookword", $nBooks), $nBooks), "text",
614 18
                                        array ( new LinkNavigation ("?" . DB . "={$i}")), "", $nBooks));
615 19
                $i++;
616 18
                Base::clearDb ();
617 18
            }
618 18
        } else {
619 19
            if (!in_array (PageQueryResult::SCOPE_AUTHOR, getCurrentOption ('ignored_categories'))) {
620 18
                array_push ($this->entryArray, Author::getCount());
621 18
            }
622 18
            if (!in_array (PageQueryResult::SCOPE_SERIES, getCurrentOption ('ignored_categories'))) {
623 19
                $series = Serie::getCount();
624 18
                if (!is_null ($series)) array_push ($this->entryArray, $series);
625 18
            }
626 18
            if (!in_array (PageQueryResult::SCOPE_PUBLISHER, getCurrentOption ('ignored_categories'))) {
627 19
                $publisher = Publisher::getCount();
628 19
                if (!is_null ($publisher)) array_push ($this->entryArray, $publisher);
629 19
            }
630 19
            if (!in_array (PageQueryResult::SCOPE_PUBLISHDATE, getCurrentOption ('ignored_categories'))) {
631 19
                $publishdates = Publishdate::getCount();
632 18
                if (!is_null ($publishdates)) array_push ($this->entryArray, $publishdates);
633 18
            }
634 18
            if (!in_array (PageQueryResult::SCOPE_TAG, getCurrentOption ('ignored_categories'))) {
635 19
                $tags = Tag::getCount();
636 15
                if (!is_null ($tags)) array_push ($this->entryArray, $tags);
637 15
            }
638 14
            if (!in_array (PageQueryResult::SCOPE_RATING, getCurrentOption ('ignored_categories'))) {
639 14
                $rating = Rating::getCount();
640 19
                if (!is_null ($rating)) array_push ($this->entryArray, $rating);
641 19
            }
642
            if (!in_array ("language", getCurrentOption ('ignored_categories'))) {
643 19
                $languages = Language::getCount();
644
                if (!is_null ($languages)) array_push ($this->entryArray, $languages);
645 21
            }
646
            foreach ($config['cops_calibre_custom_column'] as $lookup) {
647 17
                $customColumn = CustomColumnType::createByLookup($lookup);
648
                if (!is_null ($customColumn) && $customColumn->isSearchable()) {
649 17
                    array_push ($this->entryArray, $customColumn->getCount());
650 17
                }
651 17
            }
652
            $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...
653
654 2
            if (Base::isMultipleDatabaseEnabled ()) $this->title =  Base::getDbName ();
655
        }
656 2
    }
657 2
658 1
    public function isPaginated ()
659
    {
660 1
        return (getCurrentOption ("max_item_per_page") != -1 &&
661
                $this->totalNumber != -1 &&
662
                $this->totalNumber > getCurrentOption ("max_item_per_page"));
663 2
    }
664
665 2
    public function getNextLink ()
666 2
    {
667 1
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
668
        if (($this->n) * getCurrentOption ("max_item_per_page") < $this->totalNumber) {
669 2
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n + 1), "next", localize ("paging.next.alternate"));
670
        }
671
        return NULL;
672 2
    }
673
674 2
    public function getPrevLink ()
675
    {
676
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
677 70
        if ($this->n > 1) {
678
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n - 1), "previous", localize ("paging.previous.alternate"));
679 70
        }
680 68
        return NULL;
681 46
    }
682
683
    public function getMaxPage ()
684
    {
685
        return ceil ($this->totalNumber / getCurrentOption ("max_item_per_page"));
686
    }
687 3
688
    public function containsBook ()
689 3
    {
690 3
        if (count ($this->entryArray) == 0) return false;
691 2
        if (get_class ($this->entryArray [0]) == "EntryBook") return true;
692 2
        return false;
693
    }
694 1
}
695
696 3
class PageAllAuthors extends Page
697 3
{
698
    public function InitializeContent ()
699
    {
700
        $this->title = localize("authors.title");
701
        if (getCurrentOption ("author_split_first_letter") == 1) {
702 1
            $this->entryArray = Author::getAllAuthorsByFirstLetter();
703
        }
704 1
        else {
705 1
            $this->entryArray = Author::getAllAuthors();
706 1
        }
707 1
        $this->idPage = Author::ALL_AUTHORS_ID;
708
    }
709
}
710
711
class PageAllAuthorsLetter extends Page
712 7
{
713
    public function InitializeContent ()
714 7
    {
715 7
        $this->idPage = Author::getEntryIdByLetter ($this->idGet);
716 7
        $this->entryArray = Author::getAuthorsByStartingLetter ($this->idGet);
717 7
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("authorword", count ($this->entryArray)), count ($this->entryArray)), $this->idGet);
718 7
    }
719
}
720
721
class PageAuthorDetail extends Page
722
{
723 2
    public function InitializeContent ()
724
    {
725 2
        $author = Author::getAuthorById ($this->idGet);
726 2
        $this->idPage = $author->getEntryId ();
727 2
        $this->title = $author->name;
728 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByAuthor ($this->idGet, $this->n);
729
    }
730
}
731
732
class PageAllPublishers extends Page
733 1
{
734
    public function InitializeContent ()
735 1
    {
736 1
        $this->title = localize("publishers.title");
737 1
        $this->entryArray = Publisher::getAllPublishers();
738 1
        $this->idPage = Publisher::ALL_PUBLISHERS_ID;
739 1
    }
740
}
741
742
class PagePublisherDetail extends Page
743
{
744 2
    public function InitializeContent ()
745
    {
746 2
        $publisher = Publisher::getPublisherById ($this->idGet);
747 2
        $this->title = $publisher->name;
748 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByPublisher ($this->idGet, $this->n);
749 2
        $this->idPage = $publisher->getEntryId ();
750
    }
751
}
752
753
class PageAllPublishdates extends Page
754 2
{
755
    public function InitializeContent ()
756 2
    {
757 2
        $this->title = localize("pubdate.title");
758 2
        $this->entryArray = Publishdate::getAllPublishdates();
759 2
        $this->idPage = Publishdate::ALL_PUBLISHDATES_ID;
760
    }
761
}
762
763
class PagePublishdateYear extends Page
764 4
{
765
    public function InitializeContent ()
766 4
    {
767 4
        $publishdateYear = $this->idGet;
0 ignored issues
show
Unused Code introduced by
$publishdateYear is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
768 4
        $this->title = $this->idGet;
769 4
        $this->entryArray = PublishdateYear::getAllPublishdateMonth ($this->idGet);
770 4
        $this->idPage = PublishdateYear::PUBLISHDATE_YEAR_ID;
771 4
    }
772
}
773
774
class PagePublishdateMonth extends Page
775
{
776 12
    public function InitializeContent ()
777
    {
778 12
        $publishdateMonth = PublishdateYear::getPublishdateMonth ($this->idGet);
779 12
        $this->title = $this->idGet;
780
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByPublishdate ($this->idGet, $this->n);
781 12
        $this->idPage = $publishdateMonth->getEntryId ();
782 12
    }
783 12
}
784 12
785
class PageAllTags extends Page
786
{
787
    public function InitializeContent ()
788
    {
789 1
        $this->title = localize("tags.title");
790
        $this->entryArray = Tag::getAllTags();
791 1
        $this->idPage = Tag::ALL_TAGS_ID;
792 1
    }
793 1
}
794 1
795 1
class PageAllLanguages extends Page
796
{
797
    public function InitializeContent ()
798
    {
799
        $this->title = localize("languages.title");
800 1
        $this->entryArray = Language::getAllLanguages();
801
        $this->idPage = Language::ALL_LANGUAGES_ID;
802 1
    }
803 1
}
804 1
805 1
class PageCustomDetail extends Page
806 1
{
807
    public function InitializeContent ()
808
    {
809
        $customId = getURLParam ("custom", NULL);
810
        $custom = CustomColumn::createCustom ($customId, $this->idGet);
811 2
        $this->idPage = $custom->getEntryId ();
812
        $this->title = $custom->value;
813 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByCustom ($custom, $this->idGet, $this->n);
814 2
    }
815 2
}
816 2
817
class PageAllCustoms extends Page
818
{
819
    public function InitializeContent ()
820
    {
821 1
        $customId = getURLParam ("custom", NULL);
822
        $columnType = CustomColumnType::createByCustomID($customId);
823 1
        
824 1
        $this->title = $columnType->getTitle();
825 1
        $this->entryArray = $columnType->getAllCustomValues();
826 1
        $this->idPage = $columnType->getAllCustomsId();
827 1
    }
828
}
829
830
class PageTagDetail extends Page
831
{
832 1
    public function InitializeContent ()
833
    {
834 1
        $tag = Tag::getTagById ($this->idGet);
835 1
        $this->idPage = $tag->getEntryId ();
836 1
        $this->title = $tag->name;
837 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByTag ($this->idGet, $this->n);
838
    }
839
}
840
841
class PageLanguageDetail extends Page
842 1
{
843
    public function InitializeContent ()
844 1
    {
845 1
        $language = Language::getLanguageById ($this->idGet);
846 1
        $this->idPage = $language->getEntryId ();
847 1
        $this->title = $language->lang_code;
848 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByLanguage ($this->idGet, $this->n);
849
    }
850
}
851
852
class PageAllSeries extends Page
853 3
{
854
    public function InitializeContent ()
855 3
    {
856 3
        $this->title = localize("series.title");
857 2
        $this->entryArray = Serie::getAllSeries();
858 2
        $this->idPage = Serie::ALL_SERIES_ID;
859
    }
860 1
}
861
862 3
class PageSerieDetail extends Page
863 3
{
864
    public function InitializeContent ()
865
    {
866
        $serie = Serie::getSerieById ($this->idGet);
867
        $this->title = $serie->name;
868 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksBySeries ($this->idGet, $this->n);
869
        $this->idPage = $serie->getEntryId ();
870 1
    }
871 1
}
872
873 1
class PageAllRating extends Page
874 1
{
875 1
    public function InitializeContent ()
876
    {
877 1
        $this->title = localize("ratings.title");
878 1
        $this->entryArray = Rating::getAllRatings();
879
        $this->idPage = Rating::ALL_RATING_ID;
880
    }
881
}
882
883 4
class PageRatingDetail extends Page
884
{
885 4
    public function InitializeContent ()
886 4
    {
887 4
        $rating = Rating::getRatingById ($this->idGet);
888 4
        $this->idPage = $rating->getEntryId ();
889
        $this->title =str_format (localize ("ratingword", $rating->name/2), $rating->name/2);
890
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByRating ($this->idGet, $this->n);
891
    }
892
}
893
894
class PageAllBooks extends Page
895
{
896
    public function InitializeContent ()
897
    {
898
        $this->title = localize ("allbooks.title");
899
        if (getCurrentOption ("titles_split_first_letter") == 1) {
900 24
            $this->entryArray = Book::getAllBooks();
901 24
        }
902
        else {
903
            list ($this->entryArray, $this->totalNumber) = Book::getBooks ($this->n);
904 29
        }
905 29
        $this->idPage = Book::ALL_BOOKS_ID;
906 29
    }
907 29
}
908 29
909 7
class PageAllBooksLetter extends Page
910 7
{
911 29
    public function InitializeContent ()
912 22
    {
913 22
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByStartingLetter ($this->idGet, $this->n);
914 22
        $this->idPage = Book::getEntryIdByLetter ($this->idGet);
915
916 29
        $count = $this->totalNumber;
917 23
        if ($count == -1)
918 23
            $count = count ($this->entryArray);
919 28
920 23
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("bookword", $count), $count), $this->idGet);
921 23
    }
922 25
}
923 22
924 22
class PageRecentBooks extends Page
925 24
{
926 23
    public function InitializeContent ()
927 23
    {
928 23
        $this->title = localize ("recent.title");
929 23
        $this->idPage = Book::ALL_RECENT_BOOKS_ID;
930 23
        list ($this->entryArray, $this->totalNumber) = Book::getAllRecentBooks ($this->n);
931
    }
932
}
933
934
class PageQueryResult extends Page
935
{
936 29
    const SCOPE_TAG = "tag";
937
    const SCOPE_RATING = "rating";
938
    const SCOPE_SERIES = "series";
939 22
    const SCOPE_AUTHOR = "author";
940 22
    const SCOPE_BOOK = "book";
941 22
    const SCOPE_PUBLISHER = "publisher";
942 22
    const SCOPE_PUBLISHDATE = "publishdate";
943 22
944 22
    private function useTypeahead () {
945 22
        return !is_null (getURLParam ("search"));
946
    }
947 22
948 1
    private function searchByScope ($scope, $limit = FALSE) {
949 1
        $n = $this->n;
950 1
        $numberPerPage = NULL;
951 22
        $queryNormedAndUp = trim($this->query);
952 22
        if (useNormAndUp ()) {
953 1
            $queryNormedAndUp = normAndUp ($this->query);
954 1
        }
955 1
        if ($limit) {
956 1
            $n = 1;
957 1
            $numberPerPage = 5;
958 22
        }
959 22
        switch ($scope) {
960 22
            case self::SCOPE_BOOK :
961 22
                $array = Book::getBooksByStartingLetter ('%' . $queryNormedAndUp, $n, NULL, $numberPerPage);
962 22
                break;
963 22
            case self::SCOPE_AUTHOR :
964 3
                $array = Author::getAuthorsForSearch ('%' . $queryNormedAndUp);
965
                break;
966 22
            case self::SCOPE_SERIES :
967
                $array = Serie::getAllSeriesByQuery ($queryNormedAndUp);
968 22
                break;
969 22
            case self::SCOPE_TAG :
970 22
                $array = Tag::getAllTagsByQuery ($queryNormedAndUp, $n, NULL, $numberPerPage);
971 22
                break;
972 22
            case self::SCOPE_PUBLISHER :
973 22
                $array = Publisher::getAllPublishersByQuery ($queryNormedAndUp);
974
                break;
975 22
            default:
976
                $array = Book::getBooksByQuery (
977
                    array ("all" => "%" . $queryNormedAndUp . "%"), $n);
978
        }
979
980
        return $array;
981
    }
982 21
983 21
    public function doSearchByCategory () {
984 21
        $database = GetUrlParam (DB);
985 21
        $out = array ();
986 21
        $pagequery = Base::PAGE_OPENSEARCH_QUERY;
987 22
        $dbArray = array ("");
988 6
        $d = $database;
989 6
        $query = $this->query;
990 6
        // Special case when no databases were chosen, we search on all databases
991 6
        if (Base::noDatabaseSelected ()) {
992 6
            $dbArray = Base::getDbNameList ();
993 6
            $d = 0;
994 22
        }
995 22
        foreach ($dbArray as $key) {
996 22
            if (Base::noDatabaseSelected ()) {
997 1
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$d}",
998 1
                                        " ", "text",
999 22
                                        array ( new LinkNavigation ("?" . DB . "={$d}")), "tt-header"));
1000 22
                Base::getDb ($d);
1001
            }
1002
            foreach (array (PageQueryResult::SCOPE_BOOK,
1003 31
                            PageQueryResult::SCOPE_AUTHOR,
1004
                            PageQueryResult::SCOPE_SERIES,
1005 31
                            PageQueryResult::SCOPE_TAG,
1006 31
                            PageQueryResult::SCOPE_PUBLISHER,
1007 24
                            PageQueryResult::SCOPE_PUBLISHDATE) as $key) {
1008 24
                if (in_array($key, getCurrentOption ('ignored_categories'))) {
1009
                    continue;
1010
                }
1011
                $array = $this->searchByScope ($key, TRUE);
1012
1013
                $i = 0;
1014
                if (count ($array) == 2 && is_array ($array [0])) {
1015 7
                    $total = $array [1];
1016
                    $array = $array [0];
1017
                } else {
1018 31
                    $total = count($array);
1019
                }
1020
                if ($total > 0) {
1021 31
                    // Comment to help the perl i18n script
1022 2
                    // str_format (localize("bookword", count($array))
1023 2
                    // str_format (localize("authorword", count($array))
1024 2
                    // str_format (localize("seriesword", count($array))
1025 2
                    // str_format (localize("tagword", count($array))
1026 2
                    // str_format (localize("publisherword", count($array))
1027 2
                    array_push ($this->entryArray, new Entry (str_format (localize ("search.result.{$key}"), $this->query), DB . ":query:{$d}:{$key}",
1028 2
                                        str_format (localize("{$key}word", $total), $total), "text",
1029 2
                                        array ( new LinkNavigation ("?page={$pagequery}&query={$query}&db={$d}&scope={$key}")),
1030 2
                                        Base::noDatabaseSelected () ? "" : "tt-header", $total));
1031 2
                }
1032
                if (!Base::noDatabaseSelected () && $this->useTypeahead ()) {
1033 29
                    foreach ($array as $entry) {
1034 22
                        array_push ($this->entryArray, $entry);
1035 22
                        $i++;
1036
                        if ($i > 4) { break; };
1037
                    }
1038 7
                }
1039 7
            }
1040 2
            $d++;
1041 2
            if (Base::noDatabaseSelected ()) {
1042 5
                Base::clearDb ();
1043
            }
1044 7
        }
1045
        return $out;
1046
    }
1047
1048
    public function InitializeContent ()
1049 1
    {
1050
        $scope = getURLParam ("scope");
1051 1
        if (empty ($scope)) {
1052 1
            $this->title = str_format (localize ("search.result"), $this->query);
1053 1
        } else {
1054
            // Comment to help the perl i18n script
1055
            // str_format (localize ("search.result.author"), $this->query)
1056
            // str_format (localize ("search.result.tag"), $this->query)
1057
            // str_format (localize ("search.result.series"), $this->query)
1058
            // str_format (localize ("search.result.book"), $this->query)
1059
            // str_format (localize ("search.result.publisher"), $this->query)
1060
            $this->title = str_format (localize ("search.result.{$scope}"), $this->query);
1061
        }
1062
1063
        $crit = "%" . $this->query . "%";
1064
1065
        // Special case when we are doing a search and no database is selected
1066
        if (Base::noDatabaseSelected () && !$this->useTypeahead ()) {
1067
            $i = 0;
1068
            foreach (Base::getDbNameList () as $key) {
1069
                Base::clearDb ();
1070
                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...
1071
                array_push ($this->entryArray, new Entry ($key, DB . ":query:{$i}",
1072
                                        str_format (localize ("bookword", $totalNumber), $totalNumber), "text",
1073
                                        array ( new LinkNavigation ("?" . DB . "={$i}&page=9&query=" . $this->query)), "", $totalNumber));
1074
                $i++;
1075
            }
1076
            return;
1077
        }
1078
        if (empty ($scope)) {
1079
            $this->doSearchByCategory ();
1080
            return;
1081
        }
1082
1083
        $array = $this->searchByScope ($scope);
1084
        if (count ($array) == 2 && is_array ($array [0])) {
1085
            list ($this->entryArray, $this->totalNumber) = $array;
1086
        } else {
1087
            $this->entryArray = $array;
1088
        }
1089
    }
1090
}
1091
1092
class PageBookDetail extends Page
1093
{
1094
    public function InitializeContent ()
1095
    {
1096
        $this->book = Book::getBookById ($this->idGet);
1097
        $this->title = $this->book->title;
1098
    }
1099
}
1100
1101
class PageAbout extends Page
1102
{
1103
    public function InitializeContent ()
1104
    {
1105
        $this->title = localize ("about.title");
1106
    }
1107
}
1108
1109
class PageCustomize extends Page
1110
{
1111
    private function isChecked ($key, $testedValue = 1) {
1112
        $value = getCurrentOption ($key);
1113
        if (is_array ($value)) {
1114
            if (in_array ($testedValue, $value)) {
1115
                return "checked='checked'";
1116
            }
1117
        } else {
1118
            if ($value == $testedValue) {
1119
                return "checked='checked'";
1120
            }
1121
        }
1122
        return "";
1123
    }
1124
1125
    private function isSelected ($key, $value) {
1126
        if (getCurrentOption ($key) == $value) {
1127
            return "selected='selected'";
1128
        }
1129
        return "";
1130
    }
1131
1132
    private function getStyleList () {
1133
        $result = array ();
1134
        foreach (glob ("templates/" . getCurrentTemplate () . "/styles/style-*.css") as $filename) {
1135
            if (preg_match ('/styles\/style-(.*?)\.css/', $filename, $m)) {
1136
                array_push ($result, $m [1]);
1137
            }
1138
        }
1139
        return $result;
1140
    }
1141
1142
    public function InitializeContent ()
1143
    {
1144
        $this->title = localize ("customize.title");
1145
        $this->entryArray = array ();
1146
1147
        $ignoredBaseArray = array (PageQueryResult::SCOPE_AUTHOR,
1148
                                   PageQueryResult::SCOPE_TAG,
1149
                                   PageQueryResult::SCOPE_SERIES,
1150
                                   PageQueryResult::SCOPE_PUBLISHER,
1151
                                   PageQueryResult::SCOPE_PUBLISHDATE,
1152
                                   PageQueryResult::SCOPE_RATING,
1153
                                   "language");
1154
1155
        $content = "";
1156
        array_push ($this->entryArray, new Entry ("Template", "",
1157
                                        "<span style='cursor: pointer;' onclick='$.cookie(\"template\", \"bootstrap\", { expires: 365 });window.location=$(\".headleft\").attr(\"href\");'>Click to switch to Bootstrap</span>", "text",
1158
                                        array ()));
1159
        if (!preg_match("/(Kobo|Kindle\/3.0|EBRD1101)/", $_SERVER['HTTP_USER_AGENT'])) {
1160
            $content .= '<select id="style" onchange="updateCookie (this);">';
1161
            foreach ($this-> getStyleList () as $filename) {
1162
                $content .= "<option value='{$filename}' " . $this->isSelected ("style", $filename) . ">{$filename}</option>";
1163
            }
1164
            $content .= '</select>';
1165
        } else {
1166
            foreach ($this-> getStyleList () as $filename) {
1167
                $content .= "<input type='radio' onchange='updateCookieFromCheckbox (this);' id='style-{$filename}' name='style' value='{$filename}' " . $this->isChecked ("style", $filename) . " /><label for='style-{$filename}'> {$filename} </label>";
1168
            }
1169
        }
1170
        array_push ($this->entryArray, new Entry (localize ("customize.style"), "",
1171
                                        $content, "text",
1172
                                        array ()));
1173
        if (!useServerSideRendering ()) {
1174
            $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="use_fancyapps" ' . $this->isChecked ("use_fancyapps") . ' />';
1175
            array_push ($this->entryArray, new Entry (localize ("customize.fancybox"), "",
1176
                                            $content, "text",
1177
                                            array ()));
1178
        }
1179
        $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]+$" />';
1180
        array_push ($this->entryArray, new Entry (localize ("customize.paging"), "",
1181
                                        $content, "text",
1182
                                        array ()));
1183
        $content = '<input type="text" onchange="updateCookie (this);" id="email" value="' . getCurrentOption ("email") . '" />';
1184
        array_push ($this->entryArray, new Entry (localize ("customize.email"), "",
1185
                                        $content, "text",
1186
                                        array ()));
1187
        $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="html_tag_filter" ' . $this->isChecked ("html_tag_filter") . ' />';
1188 144
        array_push ($this->entryArray, new Entry (localize ("customize.filter"), "",
1189 144
                                        $content, "text",
1190 144
                                        array ()));
1191
        $content = "";
1192
        foreach ($ignoredBaseArray as $key) {
1193 49
            $keyPlural = preg_replace ('/(ss)$/', 's', $key . "s");
1194 49
            $content .=  '<input type="checkbox" name="ignored_categories[]" onchange="updateCookieFromCheckboxGroup (this);" id="ignored_categories_' . $key . '" ' . $this->isChecked ("ignored_categories", $key) . ' > ' . localize ("{$keyPlural}.title") . '</input> ';
1195 49
        }
1196 49
1197 49
        array_push ($this->entryArray, new Entry (localize ("customize.ignored"), "",
1198
                                        $content, "text",
1199
                                        array ()));
1200 56
    }
1201 56
}
1202
1203
abstract class Base
1204 4
{
1205 4
    const PAGE_INDEX = "index";
1206 4
    const PAGE_ALL_AUTHORS = "1";
1207 4
    const PAGE_AUTHORS_FIRST_LETTER = "2";
1208
    const PAGE_AUTHOR_DETAIL = "3";
1209 1
    const PAGE_ALL_BOOKS = "4";
1210
    const PAGE_ALL_BOOKS_LETTER = "5";
1211
    const PAGE_ALL_SERIES = "6";
1212
    const PAGE_SERIE_DETAIL = "7";
1213 5
    const PAGE_OPENSEARCH = "8";
1214 5
    const PAGE_OPENSEARCH_QUERY = "9";
1215 5
    const PAGE_ALL_RECENT_BOOKS = "10";
1216 5
    const PAGE_ALL_TAGS = "11";
1217
    const PAGE_TAG_DETAIL = "12";
1218
    const PAGE_BOOK_DETAIL = "13";
1219
    const PAGE_ALL_CUSTOMS = "14";
1220
    const PAGE_CUSTOM_DETAIL = "15";
1221
    const PAGE_ABOUT = "16";
1222 1
    const PAGE_ALL_LANGUAGES = "17";
1223 1
    const PAGE_LANGUAGE_DETAIL = "18";
1224 1
    const PAGE_CUSTOMIZE = "19";
1225 1
    const PAGE_ALL_PUBLISHERS = "20";
1226 1
    const PAGE_ALL_PUBLISHDATES = "24";
1227
    const PAGE_PUBLISHDATE_YEAR = "25";
1228
    const PAGE_PUBLISHDATE_MONTH = "26";
1229 1
    const PAGE_PUBLISHER_DETAIL = "21";
1230 1
    const PAGE_ALL_RATINGS = "22";
1231
    const PAGE_RATING_DETAIL = "23";
1232
1233
    const COMPATIBILITY_XML_ALDIKO = "aldiko";
1234
1235 126
    private static $db = NULL;
1236 126
1237 126
    public static function isMultipleDatabaseEnabled () {
1238 9
        global $config;
1239 9
        return is_array ($config['calibre_directory']);
1240
    }
1241
1242 9
    public static function useAbsolutePath () {
1243 9
        global $config;
1244
        $path = self::getDbDirectory();
1245 117
        return preg_match ('/^\//', $path) || // Linux /
1246
               preg_match ('/^\w\:/', $path); // Windows X:
1247
    }
1248
1249 98
    public static function noDatabaseSelected () {
1250 98
        return self::isMultipleDatabaseEnabled () && is_null (GetUrlParam (DB));
1251
    }
1252
1253 2
    public static function getDbList () {
1254 2
        global $config;
1255
        if (self::isMultipleDatabaseEnabled ()) {
1256
            return $config['calibre_directory'];
1257 2
        } else {
1258
            return array ("" => $config['calibre_directory']);
1259
        }
1260 159
    }
1261 159
1262
    public static function getDbNameList () {
1263 98
        global $config;
1264 97
        if (self::isMultipleDatabaseEnabled ()) {
1265 97
            return array_keys ($config['calibre_directory']);
1266 7
        } else {
1267 7
            return array ("");
1268 97
        }
1269 2
    }
1270
1271 98
    public static function getDbName ($database = NULL) {
1272 2
        global $config;
1273
        if (self::isMultipleDatabaseEnabled ()) {
1274 97
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1275 158
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1276
                self::error ($database);
1277
            }
1278 4
            $array = array_keys ($config['calibre_directory']);
1279 4
            return  $array[$database];
1280 3
        }
1281 3
        return "";
1282 2
    }
1283 2
1284 1
    public static function getDbDirectory ($database = NULL) {
1285 1
        global $config;
1286
        if (self::isMultipleDatabaseEnabled ()) {
1287 2
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1288
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1289
                self::error ($database);
1290 103
            }
1291 103
            $array = array_values ($config['calibre_directory']);
1292 103
            return  $array[$database];
1293
        }
1294 24
        return $config['calibre_directory'];
1295 24
    }
1296
1297
1298 19
    public static function getDbFileName ($database = NULL) {
1299 19
        return self::getDbDirectory ($database) .'metadata.db';
1300 18
    }
1301 18
1302 19
    private static function error ($database) {
1303 19
        if (php_sapi_name() != "cli") {
1304 19
            header("location: checkconfig.php?err=1");
1305 19
        }
1306 19
        throw new Exception("Database <{$database}> not found.");
1307 19
    }
1308
1309
    public static function getDb ($database = NULL) {
1310 35
        if (is_null (self::$db)) {
1311
            try {
1312
                if (is_readable (self::getDbFileName ($database))) {
1313 35
                    self::$db = new PDO('sqlite:'. self::getDbFileName ($database));
1314 35
                    if (useNormAndUp ()) {
1315 35
                        self::$db->sqliteCreateFunction ('normAndUp', 'normAndUp', 1);
1316
                    }
1317
                } else {
1318
                    self::error ($database);
1319 25
                }
1320 25
            } catch (Exception $e) {
1321 17
                self::error ($database);
1322 17
            }
1323 8
        }
1324
        return self::$db;
1325 25
    }
1326 25
1327 25
    public static function checkDatabaseAvailability () {
1328 25
        if (self::noDatabaseSelected ()) {
1329 35
            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...
1330
                self::getDb ($i);
1331
                self::clearDb ();
1332 75
            }
1333 75
        } else {
1334
            self::getDb ();
1335 75
        }
1336 7
        return true;
1337 7
    }
1338 7
1339
    public static function clearDb () {
1340 75
        self::$db = NULL;
1341 73
    }
1342 73
1343
    public static function executeQuerySingle ($query, $database = NULL) {
1344 75
        return self::getDb ($database)->query($query)->fetchColumn();
1345 75
    }
1346
1347 28
    public static function getCountGeneric($table, $id, $pageId, $numberOfString = NULL, $sql = NULL) {
1348 28
        if (!$numberOfString) {
1349 28
            $numberOfString = $table . ".alphabetical";
1350
        }
1351
        if (is_null($sql)) {
1352 28
            $count = self::executeQuerySingle ('select count(*) from ' . $table);
1353 28
        } else {
1354 28
            $count = self::executeQuerySingle ($sql);
1355
        }
1356 75
        if ($count == 0) return NULL;
1357 75
        $entry = new Entry (localize($table . ".title"), $id,
1358 75
            str_format (localize($numberOfString, $count), $count), "text",
1359
            array ( new LinkNavigation ("?page=".$pageId)), "", $count);
1360
        return $entry;
1361
    }
1362
1363
    public static function getEntryArrayWithBookNumber ($query, $columns, $params, $category) {
1364
        /* @var $result PDOStatement */
1365
1366
        list (, $result) = self::executeQuery ($query, $columns, "", $params, -1);
1367
        $entryArray = array();
1368
        while ($post = $result->fetchObject ())
1369
        {
1370
            /* @var $instance Author|Tag|Serie|Publisher */
1371
1372
            $instance = new $category ($post);
1373
            if (property_exists($post, "sort")) {
1374
                $title = $post->sort;
1375
            } else {
1376
                $title = $post->name;
1377
            }
1378
            array_push ($entryArray, new Entry ($title, $instance->getEntryId (),
1379
                str_format (localize("bookword", $post->count), $post->count), "text",
1380
                array ( new LinkNavigation ($instance->getUri ())), "", $post->count));
1381
        }
1382
        return $entryArray;
1383
    }
1384
1385
    public static function executeQuery($query, $columns, $filter, $params, $n, $database = NULL, $numberPerPage = NULL, $max = NULL) {
1386
        $totalResult = -1;
1387
1388
        if (useNormAndUp ()) {
1389
            $query = preg_replace("/upper/", "normAndUp", $query);
1390
            $columns = preg_replace("/upper/", "normAndUp", $columns);
1391
        }
1392
1393
        if (is_null ($numberPerPage)) {
1394
            $numberPerPage = getCurrentOption ("max_item_per_page");
1395
        }
1396
1397
        if ($numberPerPage != -1 && $n != -1)
1398
        {
1399
            // First check total number of results
1400
            $result = self::getDb ($database)->prepare (str_format ($query, "count(*)", $filter));
1401
            $result->execute ($params);
1402
            $totalResult = $result->fetchColumn ();
1403
            $count = $numberPerPage;
1404
            if (!is_null($max) && $totalResult > $max) {
1405
                $totalResult = $max;
1406
                $left = $max - (($n - 1) * $numberPerPage);
1407
                if ($left < $count) {
1408
                    $count = $left;
1409
                }
1410
            }
1411
            
1412
            // Next modify the query and params
1413
            $query .= " limit ?, ?";
1414
            array_push ($params, ($n - 1) * $numberPerPage, $count);
1415
        }
1416
        
1417
        $result = self::getDb ($database)->prepare(str_format ($query, $columns, $filter));
1418
        $result->execute ($params);
1419
        return array ($totalResult, $result);
1420
    }
1421
1422
}
1423