Completed
Pull Request — master (#233)
by
unknown
10:59
created

PageQueryResult::doSearchByCategory()   F

Complexity

Conditions 18
Paths 298

Size

Total Lines 79
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 50
CRAP Score 18.0184
Metric Value
dl 0
loc 79
ccs 50
cts 52
cp 0.9615
rs 3.8594
cc 18
eloc 54
nc 298
nop 0
crap 18.0184

How to fix   Long Method    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
define ("VERSION", "1.0.0RC4");
10
define ("DB", "db");     // url parameter for the selected database
11
define ("VL", "vl");     // url parameter for the selected virtual library
12
date_default_timezone_set($config['default_timezone']);
13
14
require_once('virtuallib.php');
15 3
16 3
17
function useServerSideRendering () {
18
    global $config;
19
    return preg_match("/" . $config['cops_server_side_render'] . "/", $_SERVER['HTTP_USER_AGENT']);
20
}
21 2
22 2
function serverSideRender ($data) {
23 2
    // Get the templates
24 2
    $theme = getCurrentTemplate ();
25 2
    $header = file_get_contents('templates/' . $theme . '/header.html');
26 2
    $footer = file_get_contents('templates/' . $theme . '/footer.html');
27
    $main = file_get_contents('templates/' . $theme . '/main.html');
28
    $bookdetail = file_get_contents('templates/' . $theme . '/bookdetail.html');
29 2
    $page = file_get_contents('templates/' . $theme . '/page.html');
30 2
31 2
    // Generate the function for the template
32 2
    $template = new doT ();
33 2
    $dot = $template->template ($page, array ("bookdetail" => $bookdetail,
34
                                              "header" => $header,
35
                                              "footer" => $footer,
36 2
                                              "main" => $main));
37
    // If there is a syntax error in the function created
38
    // $dot will be equal to FALSE
39
    if (!$dot) {
40 2
        return FALSE;
41
    }
42
    // Execute the template
43
    if (!empty ($data)) {
44 2
        return $dot ($data);
45
    }
46
47
    return NULL;
48 18
}
49 16
50
function getQueryString () {
51 2
    if ( isset($_SERVER['QUERY_STRING']) ) {
52
        return $_SERVER['QUERY_STRING'];
53
    }
54
    return "";
55
}
56
57
function notFound () {
58
    header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
59
    header("Status: 404 Not Found");
60
61
    $_SERVER['REDIRECT_STATUS'] = 404;
62 101
}
63 24
64
function getURLParam ($name, $default = NULL) {
65 101
    if (!empty ($_GET) && isset($_GET[$name]) && $_GET[$name] != "") {
66
        return $_GET[$name];
67
    }
68
    return $default;
69 87
}
70 87
71 2
function getCurrentOption ($option) {
72
    global $config;
73
    if (isset($_COOKIE[$option])) {
74 2
        if (isset($config ["cops_" . $option]) && is_array ($config ["cops_" . $option])) {
75
            return explode (",", $_COOKIE[$option]);
76
        } else {
77 85
            return $_COOKIE[$option];
78 2
        }
79
    }
80
    if ($option == "style") {
81 85
        return "default";
82 85
    }
83
84
    if (isset($config ["cops_" . $option])) {
85
        return $config ["cops_" . $option];
86
    }
87
88
    return "";
89 2
}
90
91
function getCurrentCss () {
92
    return "templates/" . getCurrentTemplate () . "/styles/style-" . getCurrentOption ("style") . ".css";
93 4
}
94
95
function getCurrentTemplate () {
96
    return getCurrentOption ("template");
97 51
}
98
99
function getUrlWithVersion ($url) {
100
    return $url . "?v=" . VERSION;
101 35
}
102
103
function xml2xhtml($xml) {
104 35
    return preg_replace_callback('#<(\w+)([^>]*)\s*/>#s', create_function('$m', '
105
        $xhtml_tags = array("br", "hr", "input", "frame", "img", "area", "link", "col", "base", "basefont", "param");
106
        return in_array($m[1], $xhtml_tags) ? "<$m[1]$m[2] />" : "<$m[1]$m[2]></$m[1]>";
107
    '), $xml);
108
}
109
110
function display_xml_error($error)
111
{
112
    $return = "";
113
    $return .= str_repeat('-', $error->column) . "^\n";
114
115
    switch ($error->level) {
116
        case LIBXML_ERR_WARNING:
117
            $return .= "Warning $error->code: ";
118
            break;
119
         case LIBXML_ERR_ERROR:
120
            $return .= "Error $error->code: ";
121
            break;
122
        case LIBXML_ERR_FATAL:
123
            $return .= "Fatal Error $error->code: ";
124
            break;
125
    }
126
127
    $return .= trim($error->message) .
128
               "\n  Line: $error->line" .
129
               "\n  Column: $error->column";
130
131
    if ($error->file) {
132
        $return .= "\n  File: $error->file";
133
    }
134
135
    return "$return\n\n--------------------------------------------\n\n";
136
}
137 35
138
function are_libxml_errors_ok ()
139 35
{
140
    $errors = libxml_get_errors();
141 35
142 35
    foreach ($errors as $error) {
143
        if ($error->code == 801) return false;
144
    }
145
    return true;
146 35
}
147 35
148
function html2xhtml ($html) {
149 35
    $doc = new DOMDocument();
150 35
    libxml_use_internal_errors(true);
151 35
152 35
    $doc->loadHTML('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body>' .
153 35
                        $html  . '</body></html>'); // Load the HTML
154 35
    $output = $doc->saveXML($doc->documentElement); // Transform to an Ansi xml stream
155 35
    $output = xml2xhtml($output);
156
    if (preg_match ('#<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></meta></head><body>(.*)</body></html>#ms', $output, $matches)) {
157
        $output = $matches [1]; // Remove <html><body>
158
    }
159
    /*
160
    // In case of error with summary, use it to debug
161
    $errors = libxml_get_errors();
162
163
    foreach ($errors as $error) {
164
        $output .= display_xml_error($error);
165 35
    }
166
    */
167 35
168 35
    if (!are_libxml_errors_ok ()) $output = "HTML code not valid.";
169
170
    libxml_use_internal_errors(false);
171
    return $output;
172
}
173
174
/**
175
 * This method is a direct copy-paste from
176 94
 * http://tmont.com/blargh/2010/1/string-format-in-php
177 94
 */
178
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...
179 94
    $args = func_get_args();
180 94
    $format = array_shift($args);
181 94
182 94
    preg_match_all('/(?=\{)\{(\d+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
183 94
    $offset = 0;
184 94
    foreach ($matches[1] as $data) {
185 94
        $i = $data[0];
186
        $format = substr_replace($format, @$args[$i], $offset + $data[1] - 1, 2 + strlen($i));
187 94
        $offset += strlen(@$args[$i]) - 2 - strlen($i);
188
    }
189
190
    return $format;
191
}
192
193
/**
194
 * Format strings using named parameters.
195
 *
196 16
 * This method replaces {name} in the format string with the value of $array["name"].
197
 * @param string $format a format string with named parameters.
198 16
 * @param array $array an array with named values to use as parameters.
199
 */
200 16
function str_format_n($format, $array) {
201 16
202
	preg_match_all('/(?=\{)\{([\w\d]+)\}(?!\})/', $format, $matches, PREG_OFFSET_CAPTURE);
203 3
	$offset = 0;
204 3
	foreach ($matches[1] as $data) {
205 16
		$name = $data[0];
206
		if (array_key_exists($name, $array)) {
207 16
			$format = substr_replace($format, $array[$name], $offset + $data[1] - 1, 2 + strlen($name));
208 16
			$offset += strlen($array[$name]) - 2 - strlen($name);
209 16
		} else {
210
			// Replace not existent keys by ""
211 16
			$format = substr_replace($format, "", $offset + $data[1] - 1, 2 + strlen($name));
212 11
			$offset += 0 - 2 - strlen($name);
213 11
		}
214 11
	}
215 11
216 16
	return $format;
217 16
}
218
219 16
/**
220
 * Get all accepted languages from the browser and put them in a sorted array
221
 * languages id are normalized : fr-fr -> fr_FR
222 16
 * @return array of languages
223 16
 */
224 16
function getAcceptLanguages() {
225
    $langs = array();
226
227 16
    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
228 16
        // break up string into pieces (languages and q factors)
229 16
        $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
230
        if (preg_match('/^(\w{2})-\w{2}$/', $accept, $matches)) {
231 16
            // Special fix for IE11 which send fr-FR and nothing else
232
            $accept = $accept . "," . $matches[1] . ";q=0.8";
233
        }
234
        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $accept, $lang_parse);
235
236
        if (count($lang_parse[1])) {
237
            $langs = array();
238
            foreach ($lang_parse[1] as $lang) {
239 17
                // Format the language code (not standard among browsers)
240 17
                if (strlen($lang) == 5) {
241 17
                    $lang = str_replace("-", "_", $lang);
242 17
                    $splitted = preg_split("/_/", $lang);
243
                    $lang = $splitted[0] . "_" . strtoupper($splitted[1]);
244
                }
245 17
                array_push($langs, $lang);
246 16
            }
247 16
            // create a list like "en" => 0.8
248
            $langs = array_combine($langs, $lang_parse[4]);
249 17
250 17
            // set default to 1 for any without q factor
251 16
            foreach ($langs as $lang => $val) {
252 16
                if ($val === '') $langs[$lang] = 1;
253 16
            }
254 16
255 16
            // sort list based on value
256
            arsort($langs, SORT_NUMERIC);
257 17
        }
258 17
    }
259 3
260 3
    return $langs;
261 17
}
262
263
/**
264
 * Find the best translation file possible based on the accepted languages
265
 * @return array of language and language file
266
 */
267
function getLangAndTranslationFile() {
268
    global $config;
269 114
    $langs = array();
270 114
    $lang = "en";
271 114
    if (!empty($config['cops_language'])) {
272 114
        $lang = $config['cops_language'];
273 114
    }
274 114
    elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
275 114
        $langs = getAcceptLanguages();
276
    }
277
    //echo var_dump($langs);
278 114
    $lang_file = NULL;
279 114
    foreach ($langs as $language => $val) {
280 16
        $temp_file = dirname(__FILE__). '/lang/Localization_' . $language . '.json';
281 16
        if (file_exists($temp_file)) {
282
            $lang = $language;
283 114
            $lang_file = $temp_file;
284 17
            break;
285 17
        }
286 17
    }
287 1
    if (empty ($lang_file)) {
288 1
        $lang_file = dirname(__FILE__). '/lang/Localization_' . $lang . '.json';
289
    }
290 17
    return array($lang, $lang_file);
291
}
292 17
293
/**
294
 * This method is based on this page
295 17
 * http://www.mind-it.info/2010/02/22/a-simple-approach-to-localization-in-php/
296 17
 */
297
function localize($phrase, $count=-1, $reset=false) {
298
    global $config;
299 17
    if ($count == 0)
300
        $phrase .= ".none";
301 17
    if ($count == 1)
302 1
        $phrase .= ".one";
303 1
    if ($count > 1)
304 1
        $phrase .= ".many";
305 1
306 17
    /* Static keyword is used to ensure the file is loaded only once */
307 114
    static $translations = NULL;
308 114
    if ($reset) {
309
        $translations = NULL;
310 1
    }
311
    /* If no instance of $translations has occured load the language file */
312
    if (is_null($translations)) {
313
        $lang_file_en = NULL;
314 58
        list ($lang, $lang_file) = getLangAndTranslationFile();
315 48
        if ($lang != "en") {
316 48
            $lang_file_en = dirname(__FILE__). '/lang/' . 'Localization_en.json';
317 58
        }
318 58
319 15
        $lang_file_content = file_get_contents($lang_file);
320 15
        /* Load the language file as a JSON object and transform it into an associative array */
321 15
        $translations = json_decode($lang_file_content, true);
322 58
323 58
        /* Clean the array of all unfinished translations */
324 58
        foreach (array_keys ($translations) as $key) {
325
            if (preg_match ("/^##TODO##/", $key)) {
326
                unset ($translations [$key]);
327 58
            }
328
        }
329 58
        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...
330
        {
331
            $lang_file_content = file_get_contents($lang_file_en);
332
            $translations_en = json_decode($lang_file_content, true);
333 107
            $translations = array_merge ($translations_en, $translations);
334 107
        }
335
    }
336
    if (array_key_exists ($phrase, $translations)) {
337
        return $translations[$phrase];
338 8
    }
339 8
    return $phrase;
340
}
341
342
function addURLParameter($urlParams, $paramName, $paramValue) {
343 7
    if (empty ($urlParams)) {
344
        $urlParams = "";
345
    }
346
    $start = "";
347
    if (preg_match ("#^\?(.*)#", $urlParams, $matches)) {
348
        $start = "?";
349
        $urlParams = $matches[1];
350
    }
351
    $params = array();
352
    parse_str($urlParams, $params);
353
    if (empty ($paramValue) && $paramValue != 0) {
354
        unset ($params[$paramName]);
355
    } else {
356
        $params[$paramName] = $paramValue;
357
    }
358
    return $start . http_build_query($params);
359
}
360
361 96
function useNormAndUp () {
362 96
    global $config;
363 96
    return $config ['cops_normalized_search'] == "1";
364 96
}
365 96
366 96
function normalizeUtf8String( $s) {
367 96
    include_once 'transliteration.php';
368 96
    return _transliteration_process($s);
369
}
370 10
371 10
function normAndUp ($s) {
372
    return mb_strtoupper (normalizeUtf8String($s), 'UTF-8');
373
}
374 95
375 95
class Link
376 95
{
377
    const OPDS_THUMBNAIL_TYPE = "http://opds-spec.org/image/thumbnail";
378
    const OPDS_IMAGE_TYPE = "http://opds-spec.org/image";
379
    const OPDS_ACQUISITION_TYPE = "http://opds-spec.org/acquisition";
380
    const OPDS_NAVIGATION_TYPE = "application/atom+xml;profile=opds-catalog;kind=navigation";
381
    const OPDS_PAGING_TYPE = "application/atom+xml;profile=opds-catalog;kind=acquisition";
382 95
383 95
    public $href;
384 95
    public $type;
385 95
    public $rel;
386 95
    public $title;
387
    public $facetGroup;
388
    public $activeFacet;
389 95
390
    public function __construct($phref, $ptype, $prel = NULL, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
391 95
        $this->href = $phref;
392
        $this->type = $ptype;
393
        $this->rel = $prel;
394
        $this->title = $ptitle;
395
        $this->facetGroup = $pfacetGroup;
396 1
        $this->activeFacet = $pactiveFacet;
397 1
    }
398 1
399 1
    public function hrefXhtml () {
400 1
        return $this->href;
401
    }
402
403
    public function getScriptName() {
404
        $parts = explode('/', $_SERVER["SCRIPT_NAME"]);
405
        return $parts[count($parts) - 1];
406
    }
407
}
408
409
class LinkNavigation extends Link
410
{
411
    public function __construct($phref, $prel = NULL, $ptitle = NULL) {
412
        parent::__construct ($phref, Link::OPDS_NAVIGATION_TYPE, $prel, $ptitle);
413
        if (!is_null (GetUrlParam (DB))) {
414
        	$this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
415
        	$this->href = addURLParameter ($this->href, VL, GetUrlParam (VL, 0));
416
        }
417
        if (!preg_match ("#^\?(.*)#", $this->href) && !empty ($this->href)) $this->href = "?" . $this->href;
418
        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...
419
            $this->href = "index.php" . $this->href;
420
        } else {
421
            $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...
422
        }
423
    }
424
}
425
426
class LinkFacet extends Link
427
{
428
    public function __construct($phref, $ptitle = NULL, $pfacetGroup = NULL, $pactiveFacet = FALSE) {
429
        parent::__construct ($phref, Link::OPDS_PAGING_TYPE, "http://opds-spec.org/facet", $ptitle, $pfacetGroup, $pactiveFacet);
430
        if (!is_null (GetUrlParam (DB))) {
431
        	$this->href = addURLParameter ($this->href, DB, GetUrlParam (DB));
432
        	$this->href = addURLParameter ($this->href, VL, GetUrlParam (VL, 0));
433
        }
434
        $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...
435
    }
436
}
437
438 7
class Entry
439 7
{
440 7
    public $title;
441
    public $id;
442 7
    public $content;
443
    public $numberOfElement;
444
    public $contentType;
445
    public $linkArray;
446
    public $localUpdated;
447 89
    public $className;
448 89
    private static $updated = NULL;
449 89
450 89
    public static $icons = array(
451 89
        Author::ALL_AUTHORS_ID       => 'images/author.png',
452 89
        Serie::ALL_SERIES_ID         => 'images/serie.png',
453 89
        Book::ALL_RECENT_BOOKS_ID    => 'images/recent.png',
454 89
        Tag::ALL_TAGS_ID             => 'images/tag.png',
455 89
        Language::ALL_LANGUAGES_ID   => 'images/language.png',
456
        CustomColumn::ALL_CUSTOMS_ID => 'images/custom.png',
457 89
        Rating::ALL_RATING_ID        => 'images/rating.png',
458 89
        "cops:books$"             => 'images/allbook.png',
459 89
        "cops:books:letter"       => 'images/allbook.png',
460
        Publisher::ALL_PUBLISHERS_ID => 'images/publisher.png'
461 89
    );
462 51
463 51
    public function getUpdatedTime () {
464
        if (!is_null ($this->localUpdated)) {
465 89
            return date (DATE_ATOM, $this->localUpdated);
466 89
        }
467
        if (is_null (self::$updated)) {
468 89
            self::$updated = time();
469 89
        }
470
        return date (DATE_ATOM, self::$updated);
471
    }
472
473
    public function getNavLink () {
474
        foreach ($this->linkArray as $link) {
475
            if ($link->type != Link::OPDS_NAVIGATION_TYPE) { continue; }
476 39
477 39
            return $link->hrefXhtml ();
478 39
        }
479 39
        return "#";
480 39
    }
481
482
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pclass = "", $pcount = 0) {
483
        global $config;
484
        $this->title = $ptitle;
485
        $this->id = $pid;
486
        $this->content = $pcontent;
487
        $this->contentType = $pcontentType;
488
        $this->linkArray = $plinkArray;
489
        $this->className = $pclass;
490
        $this->numberOfElement = $pcount;
491
492
        if ($config['cops_show_icons'] == 1)
493
        {
494
            foreach (self::$icons as $reg => $image)
495
            {
496
                if (preg_match ("/" . $reg . "/", $pid)) {
497
                    array_push ($this->linkArray, new Link (getUrlWithVersion ($image), "image/png", Link::OPDS_THUMBNAIL_TYPE));
498
                    break;
499
                }
500
            }
501
        }
502
503
        if (!is_null (GetUrlParam (DB))) $this->id = str_replace ("cops:", "cops:" . GetUrlParam (DB) . ":" . GetUrlParam (VL,0) . ":", $this->id);
504
    }
505
}
506
507
class EntryBook extends Entry
508
{
509
    public $book;
510
511
    public function __construct($ptitle, $pid, $pcontent, $pcontentType, $plinkArray, $pbook) {
512
        parent::__construct ($ptitle, $pid, $pcontent, $pcontentType, $plinkArray);
513
        $this->book = $pbook;
514
        $this->localUpdated = $pbook->timestamp;
515 81
    }
516
517
    public function getCoverThumbnail () {
518 81
        foreach ($this->linkArray as $link) {
519 3
            if ($link->rel == Link::OPDS_THUMBNAIL_TYPE)
520 78
                return $link->hrefXhtml ();
521 1
        }
522 77
        return null;
523 7
    }
524 70
525 2
    public function getCover () {
526 68
        foreach ($this->linkArray as $link) {
527 1
            if ($link->rel == Link::OPDS_IMAGE_TYPE)
528 67
                return $link->hrefXhtml ();
529 2
        }
530 65
        return null;
531 1
    }
532 64
}
533 3
534 61
class Page
535 3
{
536 58
    public $title;
537 1
    public $subtitle = "";
538 57
    public $authorName = "";
539 1
    public $authorUri = "";
540 56
    public $authorEmail = "";
541 2
    public $idPage;
542 54
    public $idGet;
543 3
    public $query;
544 51
    public $favicon;
545 1
    public $n;
546 50
    public $book;
547 4
    public $totalNumber = -1;
548 46
    public $entryArray = array();
549 1
550 45
    public static function getPage ($pageId, $id, $query, $n)
551 31
    {
552 14
        switch ($pageId) {
553 1
            case Base::PAGE_ALL_AUTHORS :
554 13
                return new PageAllAuthors ($id, $query, $n);
555 2
            case Base::PAGE_AUTHORS_FIRST_LETTER :
556 11
                return new PageAllAuthorsLetter ($id, $query, $n);
557 1
            case Base::PAGE_AUTHOR_DETAIL :
558 10
                return new PageAuthorDetail ($id, $query, $n);
559
            case Base::PAGE_ALL_TAGS :
560 10
                return new PageAllTags ($id, $query, $n);
561
            case Base::PAGE_TAG_DETAIL :
562 10
                return new PageTagDetail ($id, $query, $n);
563 10
            case Base::PAGE_ALL_LANGUAGES :
564 10
                return new PageAllLanguages ($id, $query, $n);
565 10
            case Base::PAGE_LANGUAGE_DETAIL :
566 10
                return new PageLanguageDetail ($id, $query, $n);
567
            case Base::PAGE_ALL_CUSTOMS :
568
                return new PageAllCustoms ($id, $query, $n);
569 81
            case Base::PAGE_CUSTOM_DETAIL :
570 81
                return new PageCustomDetail ($id, $query, $n);
571
            case Base::PAGE_ALL_RATINGS :
572 81
                return new PageAllRating ($id, $query, $n);
573 81
            case Base::PAGE_RATING_DETAIL :
574 81
                return new PageRatingDetail ($id, $query, $n);
575 81
            case Base::PAGE_ALL_SERIES :
576 81
                return new PageAllSeries ($id, $query, $n);
577 81
            case Base::PAGE_ALL_BOOKS :
578 81
                return new PageAllBooks ($id, $query, $n);
579 81
            case Base::PAGE_ALL_BOOKS_LETTER:
580
                return new PageAllBooksLetter ($id, $query, $n);
581 10
            case Base::PAGE_ALL_RECENT_BOOKS :
582
                return new PageRecentBooks ($id, $query, $n);
583 10
            case Base::PAGE_SERIE_DETAIL :
584 10
                return new PageSerieDetail ($id, $query, $n);
585 10
            case Base::PAGE_OPENSEARCH_QUERY :
586 10
                return new PageQueryResult ($id, $query, $n);
587 2
            case Base::PAGE_BOOK_DETAIL :
588 2
                return new PageBookDetail ($id, $query, $n);
589 2
            case Base::PAGE_ALL_PUBLISHERS:
590 2
                return new PageAllPublishers ($id, $query, $n);
591 2
            case Base::PAGE_PUBLISHER_DETAIL :
592 2
                return new PagePublisherDetail ($id, $query, $n);
593 2
            case Base::PAGE_ABOUT :
594 2
                return new PageAbout ($id, $query, $n);
595 2
            case Base::PAGE_CUSTOMIZE :
596 2
                return new PageCustomize ($id, $query, $n);
597 8
            default:
598 7
                $page = new Page ($id, $query, $n);
599 7
                $page->idPage = "cops:catalog";
600 8
                return $page;
601 7
        }
602 7
    }
603 7
604 8
    public function __construct($pid, $pquery, $pn) {
605 7
        global $config;
606 7
607 7
        $this->idGet = $pid;
608 8
        $this->query = $pquery;
609 7
        $this->n = $pn;
610 7
        $this->favicon = $config['cops_icon'];
611 7
        $this->authorName = empty($config['cops_author_name']) ? utf8_encode('Sébastien Lucas') : $config['cops_author_name'];
612 8
        $this->authorUri = empty($config['cops_author_uri']) ? 'http://blog.slucas.fr' : $config['cops_author_uri'];
613 8
        $this->authorEmail = empty($config['cops_author_email']) ? '[email protected]' : $config['cops_author_email'];
614 8
    }
615 8
616 8
    public function InitializeContent ()
617 7
    {
618 7
        global $config;
619 7
        $this->title = $config['cops_title_default'];
620 8
        $this->subtitle = $config['cops_subtitle_default'];
621 4
        if (Base::noDatabaseSelected ()) {
622 4
            $i = 0;
623 4
            foreach (Base::getDbNameList () as $key) {
624 4
            	$j = 0;
625 8
            	// if virtual libraries are nor enabled, getVLNameList() contains just one empty entry
626 8
            	foreach (VirtualLib::getVLNameList($i) as $vlName) {
627
            		$nBooks = Book::getBookCount ($i, $j);
628 8
            		// Only show not-empty virtual libraries
629
            		if ($nBooks > 0)
630 10
	            		array_push ($this->entryArray, new Entry (VirtualLib::getDisplayName($key, $vlName),
631
	            							"cops:{$i}:{$j}:catalog",
632 17
	            							str_format (localize ("bookword", $nBooks), $nBooks), "text",
633
	            							array ( new LinkNavigation ("?" . DB . "={$i}&" . VL . "={$j}")), "", $nBooks));
634 17
            		$j++;
635 17
            	}
636 17
                $i++;
637
                Base::clearDb ();
638
            }
639 2
        } else {
640
            if (!in_array (PageQueryResult::SCOPE_AUTHOR, getCurrentOption ('ignored_categories'))) {
641 2
                array_push ($this->entryArray, Author::getCount());
642 2
            }
643 1
            if (!in_array (PageQueryResult::SCOPE_SERIES, getCurrentOption ('ignored_categories'))) {
644
                $series = Serie::getCount();
645 1
                if (!is_null ($series)) array_push ($this->entryArray, $series);
646
            }
647
            if (!in_array (PageQueryResult::SCOPE_PUBLISHER, getCurrentOption ('ignored_categories'))) {
648 2
                $publisher = Publisher::getCount();
649
                if (!is_null ($publisher)) array_push ($this->entryArray, $publisher);
650 2
            }
651 2
            if (!in_array (PageQueryResult::SCOPE_TAG, getCurrentOption ('ignored_categories'))) {
652 1
                $tags = Tag::getCount();
653
                if (!is_null ($tags)) array_push ($this->entryArray, $tags);
654 2
            }
655
            if (!in_array (PageQueryResult::SCOPE_RATING, getCurrentOption ('ignored_categories'))) {
656
                $rating = Rating::getCount();
657 2
                if (!is_null ($rating)) array_push ($this->entryArray, $rating);
658
            }
659 2
            if (!in_array ("language", getCurrentOption ('ignored_categories'))) {
660
                $languages = Language::getCount();
661
                if (!is_null ($languages)) array_push ($this->entryArray, $languages);
662 70
            }
663
            foreach ($config['cops_calibre_custom_column'] as $lookup) {
664 70
                $customId = CustomColumn::getCustomId ($lookup);
665 68
                if (!is_null ($customId)) {
666 46
                    array_push ($this->entryArray, CustomColumn::getCount($customId));
667
                }
668
            }
669
            $this->entryArray = array_merge ($this->entryArray, Book::getCount());
670
671
            if (Base::isDatabaseArray ()) $this->title =  VirtualLib::getDisplayName();
672 3
        }
673
    }
674 3
675 3
    public function isPaginated ()
676 2
    {
677 2
        return (getCurrentOption ("max_item_per_page") != -1 &&
678
                $this->totalNumber != -1 &&
679 1
                $this->totalNumber > getCurrentOption ("max_item_per_page"));
680
    }
681 3
682 3
    public function getNextLink ()
683
    {
684
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
685
        if (($this->n) * getCurrentOption ("max_item_per_page") < $this->totalNumber) {
686
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n + 1), "next", localize ("paging.next.alternate"));
687 1
        }
688
        return NULL;
689 1
    }
690 1
691 1
    public function getPrevLink ()
692 1
    {
693
        $currentUrl = preg_replace ("/\&n=.*?$/", "", "?" . getQueryString ());
694
        if ($this->n > 1) {
695
            return new LinkNavigation ($currentUrl . "&n=" . ($this->n - 1), "previous", localize ("paging.previous.alternate"));
696
        }
697 7
        return NULL;
698
    }
699 7
700 7
    public function getMaxPage ()
701 7
    {
702 7
        return ceil ($this->totalNumber / getCurrentOption ("max_item_per_page"));
703 7
    }
704
705
    public function containsBook ()
706
    {
707
        if (count ($this->entryArray) == 0) return false;
708 2
        if (get_class ($this->entryArray [0]) == "EntryBook") return true;
709
        return false;
710 2
    }
711 2
}
712 2
713 2
class PageAllAuthors extends Page
714
{
715
    public function InitializeContent ()
716
    {
717
        $this->title = localize("authors.title");
718 1
        if (getCurrentOption ("author_split_first_letter") == 1) {
719
            $this->entryArray = Author::getAllAuthorsFirstLetters();
720 1
        }
721 1
        else {
722 1
            $this->entryArray = Author::getAllAuthors();
723 1
        }
724 1
        $this->idPage = Author::ALL_AUTHORS_ID;
725
    }
726
}
727
728
class PageAllAuthorsLetter extends Page
729 2
{
730
    public function InitializeContent ()
731 2
    {
732 2
        $this->idPage = Author::getEntryIdByLetter ($this->idGet);
733 2
        $this->entryArray = Author::getAuthorsByStartingLetter ($this->idGet);
734 2
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("authorword", count ($this->entryArray)), count ($this->entryArray)), $this->idGet);
735
    }
736
}
737
738
class PageAuthorDetail extends Page
739 2
{
740
    public function InitializeContent ()
741 2
    {
742 2
        $author = Author::getAuthorById ($this->idGet);
743 2
        $this->idPage = $author->getEntryId ();
744 2
        $this->title = $author->name;
745
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByAuthor ($this->idGet, $this->n);
746
    }
747
}
748
749 3
class PageAllPublishers extends Page
750
{
751 3
    public function InitializeContent ()
752 3
    {
753 3
        $this->title = localize("publishers.title");
754 3
        $this->entryArray = Publisher::getAllPublishers();
755 3
        $this->idPage = Publisher::ALL_PUBLISHERS_ID;
756 3
    }
757
}
758
759
class PagePublisherDetail extends Page
760
{
761 3
    public function InitializeContent ()
762
    {
763 3
        $publisher = Publisher::getPublisherById ($this->idGet);
764 3
        $this->title = $publisher->name;
765 3
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByPublisher ($this->idGet, $this->n);
766 3
        $this->idPage = $publisher->getEntryId ();
767 3
    }
768
}
769
770
class PageAllTags extends Page
771
{
772 1
    public function InitializeContent ()
773
    {
774 1
        $this->title = localize("tags.title");
775 1
        $this->entryArray = Tag::getAllTags();
776 1
        $this->idPage = Tag::ALL_TAGS_ID;
777 1
    }
778 1
}
779
780
class PageAllLanguages extends Page
781
{
782
    public function InitializeContent ()
783 1
    {
784
        $this->title = localize("languages.title");
785 1
        $this->entryArray = Language::getAllLanguages();
786 1
        $this->idPage = Language::ALL_LANGUAGES_ID;
787 1
    }
788 1
}
789 1
790
class PageCustomDetail extends Page
791
{
792
    public function InitializeContent ()
793
    {
794 2
        $customId = getURLParam ("custom", NULL);
795
        $custom = CustomColumn::getCustomById ($customId, $this->idGet);
796 2
        $this->idPage = $custom->getEntryId ();
797 2
        $this->title = $custom->name;
798 2
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByCustom ($customId, $this->idGet, $this->n);
799 2
    }
800
}
801
802
class PageAllCustoms extends Page
803
{
804 1
    public function InitializeContent ()
805
    {
806 1
        $customId = getURLParam ("custom", NULL);
807 1
        $this->title = CustomColumn::getAllTitle ($customId);
808 1
        $this->entryArray = CustomColumn::getAllCustoms($customId);
809 1
        $this->idPage = CustomColumn::getAllCustomsId ($customId);
810 1
    }
811
}
812
813
class PageTagDetail extends Page
814
{
815 1
    public function InitializeContent ()
816
    {
817 1
        $tag = Tag::getTagById ($this->idGet);
818 1
        $this->idPage = $tag->getEntryId ();
819 1
        $this->title = $tag->name;
820 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByTag ($this->idGet, $this->n);
821
    }
822
}
823
824
class PageLanguageDetail extends Page
825 1
{
826
    public function InitializeContent ()
827 1
    {
828 1
        $language = Language::getLanguageById ($this->idGet);
829 1
        $this->idPage = $language->getEntryId ();
830 1
        $this->title = $language->lang_code;
831 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByLanguage ($this->idGet, $this->n);
832
    }
833
}
834
835
class PageAllSeries extends Page
836 3
{
837
    public function InitializeContent ()
838 3
    {
839 3
        $this->title = localize("series.title");
840 2
        $this->entryArray = Serie::getAllSeries();
841 2
        $this->idPage = Serie::ALL_SERIES_ID;
842
    }
843 1
}
844
845 3
class PageSerieDetail extends Page
846 3
{
847
    public function InitializeContent ()
848
    {
849
        $serie = Serie::getSerieById ($this->idGet);
850
        $this->title = $serie->name;
851 1
        list ($this->entryArray, $this->totalNumber) = Book::getBooksBySeries ($this->idGet, $this->n);
852
        $this->idPage = $serie->getEntryId ();
853 1
    }
854 1
}
855
856 1
class PageAllRating extends Page
857 1
{
858 1
    public function InitializeContent ()
859
    {
860 1
        $this->title = localize("ratings.title");
861 1
        $this->entryArray = Rating::getAllRatings();
862
        $this->idPage = Rating::ALL_RATING_ID;
863
    }
864
}
865
866 4
class PageRatingDetail extends Page
867
{
868 4
    public function InitializeContent ()
869 4
    {
870 4
        $rating = Rating::getRatingById ($this->idGet);
871 4
        $this->idPage = $rating->getEntryId ();
872
        $this->title =str_format (localize ("ratingword", $rating->name/2), $rating->name/2);
873
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByRating ($this->idGet, $this->n);
874
    }
875
}
876
877
class PageAllBooks extends Page
878
{
879
    public function InitializeContent ()
880
    {
881
        $this->title = localize ("allbooks.title");
882
        if (getCurrentOption ("titles_split_first_letter") == 1) {
883 24
            $this->entryArray = Book::getAllBooks();
884 24
        }
885
        else {
886
            list ($this->entryArray, $this->totalNumber) = Book::getBooks ($this->n);
887 29
        }
888 29
        $this->idPage = Book::ALL_BOOKS_ID;
889 29
    }
890 29
}
891 29
892 7
class PageAllBooksLetter extends Page
893 7
{
894 29
    public function InitializeContent ()
895 22
    {
896 22
        list ($this->entryArray, $this->totalNumber) = Book::getBooksByStartingLetter ($this->idGet, $this->n);
897 22
        $this->idPage = Book::getEntryIdByLetter ($this->idGet);
898
899 29
        $count = $this->totalNumber;
900 23
        if ($count == -1)
901 23
            $count = count ($this->entryArray);
902 28
903 23
        $this->title = str_format (localize ("splitByLetter.letter"), str_format (localize ("bookword", $count), $count), $this->idGet);
904 23
    }
905 25
}
906 22
907 22
class PageRecentBooks extends Page
908 24
{
909 23
    public function InitializeContent ()
910 23
    {
911 23
        $this->title = localize ("recent.title");
912 23
        $this->entryArray = Book::getAllRecentBooks ();
913 23
        $this->idPage = Book::ALL_RECENT_BOOKS_ID;
914
    }
915
}
916
917
class PageQueryResult extends Page
918
{
919 29
    const SCOPE_TAG = "tag";
920
    const SCOPE_RATING = "rating";
921
    const SCOPE_SERIES = "series";
922 22
    const SCOPE_AUTHOR = "author";
923 22
    const SCOPE_BOOK = "book";
924 22
    const SCOPE_PUBLISHER = "publisher";
925 22
926 22
    private function useTypeahead () {
927 22
        return !is_null (getURLParam ("search"));
928 22
    }
929
930 22
    private function searchByScope ($scope, $limit = FALSE) {
931 1
        $n = $this->n;
932 1
        $numberPerPage = NULL;
933 1
        $queryNormedAndUp = $this->query;
934 22
        if (useNormAndUp ()) {
935 22
            $queryNormedAndUp = normAndUp ($this->query);
936 1
        }
937 1
        if ($limit) {
938 1
            $n = 1;
939 1
            $numberPerPage = 5;
940 1
        }
941 22
        switch ($scope) {
942 22
            case self::SCOPE_BOOK :
943 22
                $array = Book::getBooksByStartingLetter ('%' . $queryNormedAndUp, $n, NULL, NULL, $numberPerPage);
944 22
                break;
945 22
            case self::SCOPE_AUTHOR :
946 22
                $array = Author::getAuthorsForSearch ('%' . $queryNormedAndUp);
947 3
                break;
948
            case self::SCOPE_SERIES :
949 22
                $array = Serie::getAllSeriesByQuery ($queryNormedAndUp);
950
                break;
951 22
            case self::SCOPE_TAG :
952 22
                $array = Tag::getAllTagsByQuery ($queryNormedAndUp, $n, NULL, NULL, $numberPerPage);
953 22
                break;
954 22
            case self::SCOPE_PUBLISHER :
955 22
                $array = Publisher::getAllPublishersByQuery ($queryNormedAndUp);
956 22
                break;
957
            default:
958 22
                $array = Book::getBooksByQuery (
959
                    array ("all" => "%" . $queryNormedAndUp . "%"), $n);
960
        }
961
962
        return $array;
963
    }
964
965 21
    public function doSearchByCategory () {
966 21
        $database = GetUrlParam (DB);
967 21
        $virtualLib = getURLParam(VL, 0);
968 21
        $out = array ();
969 21
        $pagequery = Base::PAGE_OPENSEARCH_QUERY;
970 22
        $dbArray = array ("");
971 6
        $d = $database;
972 6
        $query = $this->query;
973 6
        // Special case when no databases were chosen, we search on all databases
974 6
        if (Base::noDatabaseSelected ()) {
975 6
            $dbArray = Base::getDbNameList ();
976 6
            $d = 0;
977 22
        }
978 22
        $vl = $virtualLib;
979 22
        $vlArray = VirtualLib::getVLNameList($d);
980 1
        $vlArray = array($vlArray[$vl]);
981 1
        
982 22
        foreach ($dbArray as $dbKey) {
983 22
        	if (Base::noDatabaseSelected () && VirtualLib::isVLEnabled()) {
984
        		// If virtual libraries are enabled, but no Database is selected, 
985
        		// then iterate over all virtual libraries
986 31
        		$vlArray = VirtualLib::getVLNameList($d);
987
        		$vl = 0;
988 31
        	}
989 31
        	foreach ($vlArray as $vlKey) {	
990 24
	            if (Base::noDatabaseSelected ()) {
991 24
	                array_push ($this->entryArray, new Entry (VirtualLib::getDisplayName($dbKey, $vlKey), 
992
	                						DB . ":query:{$d}:{$vl}",
993
	                                        " ", "text",
994
	                                        array ( new LinkNavigation ("?" . DB . "={$d}&" . VL . "={$vl}")), "tt-header"));
995
	                Base::getDb ($d);
996
	                // TODO: set current virtual library in Base Or VirtualLib
997
	            }
998 7
	            foreach (array (PageQueryResult::SCOPE_BOOK,
999
	                            PageQueryResult::SCOPE_AUTHOR,
1000
	                            PageQueryResult::SCOPE_SERIES,
1001 31
	                            PageQueryResult::SCOPE_TAG,
1002
	                            PageQueryResult::SCOPE_PUBLISHER) as $key) {
1003
	                if (in_array($key, getCurrentOption ('ignored_categories'))) {
1004 31
	                    continue;
1005 2
	                }
1006 2
	                $array = $this->searchByScope ($key, TRUE);
1007 2
	
1008 2
	                $i = 0;
1009 2
	                if (count ($array) == 2 && is_array ($array [0])) {
1010 2
	                    $total = $array [1];
1011 2
	                    $array = $array [0];
1012 2
	                } else {
1013 2
	                    $total = count($array);
1014 2
	                }
1015
	                if ($total > 0) {
1016 29
	                    // Comment to help the perl i18n script
1017 22
	                    // str_format (localize("bookword", count($array))
1018 22
	                    // str_format (localize("authorword", count($array))
1019
	                    // str_format (localize("seriesword", count($array))
1020
	                    // str_format (localize("tagword", count($array))
1021 7
	                    // str_format (localize("publisherword", count($array))
1022 7
	                    array_push ($this->entryArray, new Entry (str_format (localize ("search.result.{$key}"), $this->query), DB . ":query:{$d}:{$key}:{$vl}",
1023 2
	                                        str_format (localize("{$key}word", $total), $total), "text",
1024 2
	                                        array ( new LinkNavigation ("?page={$pagequery}&query={$query}&db={$d}&vl={$vl}&scope={$key}")),
1025 5
	                                        Base::noDatabaseSelected () ? "" : "tt-header", $total));
1026
	                }
1027 7
	                if (!Base::noDatabaseSelected () && $this->useTypeahead ()) {
1028
	                    foreach ($array as $entry) {
1029
	                        array_push ($this->entryArray, $entry);
1030
	                        $i++;
1031
	                        if ($i > 4) { break; };
1032 1
	                    }
1033
	                }
1034 1
	            }
1035 1
	            $vl++;
1036 1
        	}
1037
            $d++;
1038
            if (Base::noDatabaseSelected ()) {
1039
                Base::clearDb ();
1040
            }
1041
        }
1042
        return $out;
1043
    }
1044
1045
	public function InitializeContent ()
1046
    {
1047
        $scope = getURLParam ("scope");
1048
        if (empty ($scope)) {
1049
            $this->title = str_format (localize ("search.result"), $this->query);
1050
        } else {
1051
            // Comment to help the perl i18n script
1052
            // str_format (localize ("search.result.author"), $this->query)
1053
            // str_format (localize ("search.result.tag"), $this->query)
1054
            // str_format (localize ("search.result.series"), $this->query)
1055
            // str_format (localize ("search.result.book"), $this->query)
1056
            // str_format (localize ("search.result.publisher"), $this->query)
1057
            $this->title = str_format (localize ("search.result.{$scope}"), $this->query);
1058
        }
1059
1060
        $crit = "%" . $this->query . "%";
1061
1062
        // Special case when we are doing a search and no database is selected
1063
        if (Base::noDatabaseSelected () && !$this->useTypeahead ()) {
1064
            $i = 0;
1065
            foreach (Base::getDbNameList () as $dbKey) {
1066
                Base::clearDb ();
1067
                $j = 0;
1068
                foreach (VirtualLib::getVLNameList($i) as $vlKey) {
1069
	                list ($array, $totalNumber) = Book::getBooksByQuery (array ("all" => $crit), 1, $i, $j, 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...
1070
	                array_push ($this->entryArray, new Entry (VirtualLib::getDisplayName($dbKey, $vlKey), 
1071
	                						DB . ":query:{$i}:{$j}",
1072
	                                        str_format (localize ("bookword", $totalNumber), $totalNumber), "text",
1073
	                                        array ( new LinkNavigation ("?" . DB . "={$i}&page=9&query=" . $this->query)), "", $totalNumber));
1074
	                $j++;
1075
                }
1076
                $i++;
1077
            }
1078
            return;
1079
        }
1080
        if (empty ($scope)) {
1081
            $this->doSearchByCategory ();
1082
            return;
1083
        }
1084
1085
        $array = $this->searchByScope ($scope);
1086
        if (count ($array) == 2 && is_array ($array [0])) {
1087
            list ($this->entryArray, $this->totalNumber) = $array;
1088
        } else {
1089
            $this->entryArray = $array;
1090
        }
1091
    }
1092
}
1093
1094
class PageBookDetail extends Page
1095
{
1096
    public function InitializeContent ()
1097
    {
1098
        $this->book = Book::getBookById ($this->idGet);
1099
        $this->title = $this->book->title;
1100
    }
1101
}
1102
1103
class PageAbout extends Page
1104
{
1105
    public function InitializeContent ()
1106
    {
1107
        $this->title = localize ("about.title");
1108
    }
1109
}
1110
1111
class PageCustomize extends Page
1112
{
1113
    private function isChecked ($key, $testedValue = 1) {
1114
        $value = getCurrentOption ($key);
1115
        if (is_array ($value)) {
1116
            if (in_array ($testedValue, $value)) {
1117
                return "checked='checked'";
1118
            }
1119
        } else {
1120
            if ($value == $testedValue) {
1121
                return "checked='checked'";
1122
            }
1123
        }
1124
        return "";
1125
    }
1126
1127
    private function isSelected ($key, $value) {
1128
        if (getCurrentOption ($key) == $value) {
1129
            return "selected='selected'";
1130
        }
1131
        return "";
1132
    }
1133
1134
    private function getStyleList () {
1135
        $result = array ();
1136
        foreach (glob ("templates/" . getCurrentTemplate () . "/styles/style-*.css") as $filename) {
1137
            if (preg_match ('/styles\/style-(.*?)\.css/', $filename, $m)) {
1138
                array_push ($result, $m [1]);
1139
            }
1140
        }
1141
        return $result;
1142
    }
1143
1144
    public function InitializeContent ()
1145
    {
1146
        $this->title = localize ("customize.title");
1147
        $this->entryArray = array ();
1148
1149
        $ignoredBaseArray = array (PageQueryResult::SCOPE_AUTHOR,
1150
                                   PageQueryResult::SCOPE_TAG,
1151
                                   PageQueryResult::SCOPE_SERIES,
1152
                                   PageQueryResult::SCOPE_PUBLISHER,
1153
                                   PageQueryResult::SCOPE_RATING,
1154
                                   "language");
1155
1156
        $content = "";
1157
        array_push ($this->entryArray, new Entry ("Template", "",
1158
                                        "<span style='cursor: pointer;' onclick='$.cookie(\"template\", \"bootstrap\", { expires: 365 });window.location=$(\".headleft\").attr(\"href\");'>Click to switch to Bootstrap</span>", "text",
1159
                                        array ()));
1160
        if (!preg_match("/(Kobo|Kindle\/3.0|EBRD1101)/", $_SERVER['HTTP_USER_AGENT'])) {
1161
            $content .= '<select id="style" onchange="updateCookie (this);">';
1162
            foreach ($this-> getStyleList () as $filename) {
1163
                $content .= "<option value='{$filename}' " . $this->isSelected ("style", $filename) . ">{$filename}</option>";
1164
            }
1165
            $content .= '</select>';
1166
        } else {
1167
            foreach ($this-> getStyleList () as $filename) {
1168
                $content .= "<input type='radio' onchange='updateCookieFromCheckbox (this);' id='style-{$filename}' name='style' value='{$filename}' " . $this->isChecked ("style", $filename) . " /><label for='style-{$filename}'> {$filename} </label>";
1169
            }
1170
        }
1171
        array_push ($this->entryArray, new Entry (localize ("customize.style"), "",
1172 108
                                        $content, "text",
1173 108
                                        array ()));
1174 108
        if (!useServerSideRendering ()) {
1175
            $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="use_fancyapps" ' . $this->isChecked ("use_fancyapps") . ' />';
1176
            array_push ($this->entryArray, new Entry (localize ("customize.fancybox"), "",
1177 46
                                            $content, "text",
1178 46
                                            array ()));
1179 46
        }
1180 46
        $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]+$" />';
1181 46
        array_push ($this->entryArray, new Entry (localize ("customize.paging"), "",
1182
                                        $content, "text",
1183
                                        array ()));
1184 45
        $content = '<input type="text" onchange="updateCookie (this);" id="email" value="' . getCurrentOption ("email") . '" />';
1185 45
        array_push ($this->entryArray, new Entry (localize ("customize.email"), "",
1186
                                        $content, "text",
1187
                                        array ()));
1188 4
        $content = '<input type="checkbox" onchange="updateCookieFromCheckbox (this);" id="html_tag_filter" ' . $this->isChecked ("html_tag_filter") . ' />';
1189 4
        array_push ($this->entryArray, new Entry (localize ("customize.filter"), "",
1190 4
                                        $content, "text",
1191 4
                                        array ()));
1192
        $content = "";
1193 1
        foreach ($ignoredBaseArray as $key) {
1194
            $keyPlural = preg_replace ('/(ss)$/', 's', $key . "s");
1195
            $content .=  '<input type="checkbox" name="ignored_categories[]" onchange="updateCookieFromCheckboxGroup (this);" id="ignored_categories_' . $key . '" ' . $this->isChecked ("ignored_categories", $key) . ' > ' . localize ("{$keyPlural}.title") . '</input> ';
1196
        }
1197 5
1198 5
        array_push ($this->entryArray, new Entry (localize ("customize.ignored"), "",
1199 5
                                        $content, "text",
1200 5
                                        array ()));
1201
    }
1202
}
1203
1204
1205
abstract class Base
1206 1
{
1207 1
    const PAGE_INDEX = "index";
1208 1
    const PAGE_ALL_AUTHORS = "1";
1209 1
    const PAGE_AUTHORS_FIRST_LETTER = "2";
1210 1
    const PAGE_AUTHOR_DETAIL = "3";
1211
    const PAGE_ALL_BOOKS = "4";
1212
    const PAGE_ALL_BOOKS_LETTER = "5";
1213 1
    const PAGE_ALL_SERIES = "6";
1214 1
    const PAGE_SERIE_DETAIL = "7";
1215
    const PAGE_OPENSEARCH = "8";
1216
    const PAGE_OPENSEARCH_QUERY = "9";
1217
    const PAGE_ALL_RECENT_BOOKS = "10";
1218
    const PAGE_ALL_TAGS = "11";
1219 90
    const PAGE_TAG_DETAIL = "12";
1220 90
    const PAGE_BOOK_DETAIL = "13";
1221 90
    const PAGE_ALL_CUSTOMS = "14";
1222 9
    const PAGE_CUSTOM_DETAIL = "15";
1223 9
    const PAGE_ABOUT = "16";
1224
    const PAGE_ALL_LANGUAGES = "17";
1225
    const PAGE_LANGUAGE_DETAIL = "18";
1226 9
    const PAGE_CUSTOMIZE = "19";
1227 9
    const PAGE_ALL_PUBLISHERS = "20";
1228
    const PAGE_PUBLISHER_DETAIL = "21";
1229 81
    const PAGE_ALL_RATINGS = "22";
1230
    const PAGE_RATING_DETAIL = "23";
1231
1232
    const COMPATIBILITY_XML_ALDIKO = "aldiko";
1233 61
    
1234 61
    const SQL_SETTING = 'SELECT val FROM preferences WHERE key = "{0}"';
1235
1236
    private static $db = NULL;
1237 2
1238 2
    public static function isDatabaseArray () {
1239
        global $config;
1240
        return is_array ($config['calibre_directory']);
1241 2
    }
1242
    
1243
    public static function isMultipleDatabaseEnabled () {
1244 126
    	return (self::isDatabaseArray () || VirtualLib::isVLEnabled());
1245 126
    }
1246
1247 61
    public static function useAbsolutePath () {
1248 60
        global $config;
1249 60
        $path = self::getDbDirectory();
1250 7
        return preg_match ('/^\//', $path) || // Linux /
1251 7
               preg_match ('/^\w\:/', $path); // Windows X:
1252 60
    }
1253 2
1254
    public static function noDatabaseSelected () {
1255 61
        return self::isMultipleDatabaseEnabled() && is_null (GetUrlParam (DB));
1256 2
    }
1257
1258 60
    public static function getDbList () {
1259 125
        global $config;
1260
        if (self::isDatabaseArray ()) {
1261
            return $config['calibre_directory'];
1262 4
        } else {
1263 4
            return array ("" => $config['calibre_directory']);
1264 3
        }
1265 3
    }
1266 2
1267 2
    public static function getDbNameList () {
1268 1
        global $config;
1269 1
        if (self::isDatabaseArray ()) {
1270
            return array_keys ($config['calibre_directory']);
1271 2
        } else {
1272
            return array ("");
1273
        }
1274 58
    }
1275 58
1276 58
    public static function getDbName ($database = NULL) {
1277
        global $config;
1278 13
        if (self::isDatabaseArray ()) {
1279 13
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1280
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1281
                return self::error ($database);
1282 8
            }
1283 8
            $array = array_keys ($config['calibre_directory']);
1284 7
            return  $array[$database];
1285 7
        }
1286 8
        return "";
1287 8
    }
1288 8
1289 8
    public static function getDbDirectory ($database = NULL) {
1290 8
        global $config;
1291 8
        if (self::isDatabaseArray ()) {
1292
            if (is_null ($database)) $database = GetUrlParam (DB, 0);
1293
            if (!is_null($database) && !preg_match('/^\d+$/', $database)) {
1294 35
                return self::error ($database);
1295 35
            }
1296 35
            $array = array_values ($config['calibre_directory']);
1297 35
            return  $array[$database];
1298
        }
1299 25
        return $config['calibre_directory'];
1300 25
    }
1301 17
1302 17
1303 8
    public static function getDbFileName ($database = NULL) {
1304
        return self::getDbDirectory ($database) .'metadata.db';
1305 25
    }
1306 25
1307 25
    private static function error ($database) {
1308 25
        if (php_sapi_name() != "cli") {
1309 35
            header("location: checkconfig.php?err=1");
1310
        }
1311
        throw new Exception("Database <{$database}> not found.");
1312 73
    }
1313 73
1314
    public static function getDb ($database = NULL) {
1315 73
        if (is_null (self::$db)) {
1316 7
            try {
1317 7
                if (is_readable (self::getDbFileName ($database))) {
1318 7
                    self::$db = new PDO('sqlite:'. self::getDbFileName ($database));
1319
                    if (useNormAndUp ()) {
1320 73
                        self::$db->sqliteCreateFunction ('normAndUp', 'normAndUp', 1);
1321 71
                    }
1322 71
                } else {
1323
                    self::error ($database);
1324 73
                }
1325 73
            } catch (Exception $e) {
1326
                self::error ($database);
1327 28
            }
1328 28
        }
1329 28
        return self::$db;
1330
    }
1331
1332 28
    public static function checkDatabaseAvailability () {
1333 28
        if (self::noDatabaseSelected ()) {
1334 28
            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...
1335
                self::getDb ($i);
1336 73
                self::clearDb ();
1337 73
            }
1338 73
        } else {
1339
            self::getDb ();
1340
        }
1341
        return true;
1342
    }
1343
1344
    public static function clearDb () {
1345
        self::$db = NULL;
1346
    }
1347
1348
    public static function executeQuerySingle ($query, $database = NULL) {
1349
        return self::getDb ($database)->query($query)->fetchColumn();
1350
    }
1351
    
1352
    /**
1353
     * Executes a sql query filtered for a virtual library. The query returns a single value;
1354
     * 
1355
     * @param string $query The sql query. A {0} indicates the space to include the filter query. 
1356
     * @param int $database The database id.
1357
     * @param int $virtualLib The id of the virtual library.
1358
     * @return mixed The single-value result of the query.
1359
     */
1360
    public static function executeFilteredQuerySingle ($query, $database = NULL, $virtualLib = null) {
1361
    	$query = str_format($query, VirtualLib::getVL($database, $virtualLib)->getFilterQuery());
1362
    	return self::getDb ($database)->query($query)->fetchColumn();
1363
    }
1364
1365
    public static function getCountGeneric($table, $id, $pageId, $numberOfString = NULL) {
1366
        if (!$numberOfString) {
1367
            $numberOfString = $table . ".alphabetical";
1368
        }
1369
        $count = self::executeFilteredQuerySingle ('select count(distinct ' . $table .'.id) from ' . Filter::getLinkedTable($table));
1370
        if ($count == 0) return NULL;
1371
        $entry = new Entry (localize($table . ".title"), $id,
1372
            str_format (localize($numberOfString, $count), $count), "text",
1373
            array ( new LinkNavigation ("?page=".$pageId)), "", $count);
1374
        return $entry;
1375
    }
1376
1377
    public static function getEntryArrayWithBookNumber ($query, $params, $category) {
1378
        list (, $result) = self::executeFilteredQuery($query, $params, -1);
1379
        $entryArray = array();
1380
        while ($post = $result->fetchObject ())
1381
        {
1382
            $instance = new $category ($post);
1383
            if (property_exists($post, "sort")) {
1384
                $title = $post->sort;
1385
            } else {
1386
                $title = $post->name;
1387
            }
1388
            array_push ($entryArray, new Entry ($title, $instance->getEntryId (),
1389
                str_format (localize("bookword", $post->count), $post->count), "text",
1390
                array ( new LinkNavigation ($instance->getUri ())), "", $post->count));
1391
        }
1392
        return $entryArray;
1393
    }
1394
    
1395
    /**
1396
     * Executes a sql query filtered for a virtual library.
1397
     * 
1398
     * @param string $query The sql query. A {0} indicates the space to include the filter query. 
1399
     * @param array $params SQL parameter
1400
     * @param int $n Page number
1401
     * @param int $database Database ID
1402
     * @param int $virtualLib ID of the virtual library
1403
     * @param int $numberPerPage Number of shown entries per page
1404
     * @return multitype:number PDOStatement
0 ignored issues
show
Documentation introduced by
The doc-type multitype:number could not be parsed: Unknown type name "multitype:number" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1405
     */
1406
    public static function executeFilteredQuery($query, $params, $n, $database = NULL, $virtualLib = NULL,$numberPerPage = NULL) {
1407
    	$totalResult = -1;
1408
    
1409
    	$query = str_format($query, VirtualLib::getVL($database, $virtualLib)->getFilterQuery());
1410
    	
1411
    	if (useNormAndUp ()) {
1412
    		$query = preg_replace("/upper/", "normAndUp", $query);
1413
    	}
1414
    
1415
    	if (is_null ($numberPerPage)) {
1416
    		$numberPerPage = getCurrentOption ("max_item_per_page");
1417
    	}
1418
    
1419
    	if ($numberPerPage != -1 && $n != -1)
1420
    	{
1421
    		// First check total number of results
1422
    		$result = self::getDb ($database)->prepare (str_format ("select count(*) from ({0})", $query));
1423
    		$result->execute ($params);
1424
    		$totalResult = $result->fetchColumn ();
1425
    
1426
    		// Next modify the query and params
1427
    		$query .= " limit ?, ?";
1428
    		array_push ($params, ($n - 1) * $numberPerPage, $numberPerPage);
1429
    	}
1430
    
1431
    	$result = self::getDb ($database)->prepare($query);
1432
    	$result->execute ($params);
1433
    	return array ($totalResult, $result);
1434
    }
1435
1436
    public static function executeQuery($query, $columns, $filter, $params, $n, $database = NULL, $numberPerPage = NULL) {
1437
        $totalResult = -1;
1438
1439
        if (useNormAndUp ()) {
1440
            $query = preg_replace("/upper/", "normAndUp", $query);
1441
            $columns = preg_replace("/upper/", "normAndUp", $columns);
1442
        }
1443
1444
        if (is_null ($numberPerPage)) {
1445
            $numberPerPage = getCurrentOption ("max_item_per_page");
1446
        }
1447
1448
        if ($numberPerPage != -1 && $n != -1)
1449
        {
1450
            // First check total number of results
1451
            $result = self::getDb ($database)->prepare (str_format ($query, "count(*)", $filter));
1452
            $result->execute ($params);
1453
            $totalResult = $result->fetchColumn ();
1454
1455
            // Next modify the query and params
1456
            $query .= " limit ?, ?";
1457
            array_push ($params, ($n - 1) * $numberPerPage, $numberPerPage);
1458
        }
1459
1460
        $result = self::getDb ($database)->prepare(str_format ($query, $columns, $filter));
1461
        $result->execute ($params);
1462
        return array ($totalResult, $result);
1463
    }
1464
1465
    /**
1466
     * Gets a calibre setting from the database.
1467
     * 
1468
     * @param string $name Name of the property
1469
     * @param int $database Database to query from
1470
     * @return string Value of the property
1471
     */
1472
    public static function getCalibreSetting($name, $database = NULL) {
1473
    	$query = str_format(self::SQL_SETTING, $name);
1474
    	return self::executeQuerySingle($query, $database);
1475
    }
1476
}
1477