Test Setup Failed
Pull Request — master (#424)
by
unknown
02:29
created

Book::__construct()   F

Complexity

Conditions 17
Paths 492

Size

Total Lines 68

Duplication

Lines 12
Ratio 17.65 %

Code Coverage

Tests 35
CRAP Score 17

Importance

Changes 0
Metric Value
cc 17
nc 492
nop 1
dl 12
loc 68
ccs 35
cts 35
cp 1
crap 17
rs 1.7555
c 0
b 0
f 0

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
// Silly thing because PHP forbid string concatenation in class const
10
define ('SQL_BOOKS_LEFT_JOIN', 'left outer join comments on comments.book = books.id
11
                                left outer join books_ratings_link on books_ratings_link.book = books.id
12
                                left outer join ratings on books_ratings_link.rating = ratings.id ');
13
define ('SQL_BOOKS_ALL', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . ' order by books.sort ');
14
define ('SQL_BOOKS_BY_PUBLISHER', 'select {0} from books_publishers_link, books ' . SQL_BOOKS_LEFT_JOIN . '
15
                                                    where books_publishers_link.book = books.id and publisher = ? {1} order by publisher');
16
define ('SQL_BOOKS_BY_FIRST_LETTER', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
17
                                                    where upper (books.sort) like ? order by books.sort');
18
define ('SQL_BOOKS_BY_AUTHOR', 'select {0} from books_authors_link, books ' . SQL_BOOKS_LEFT_JOIN . '
19
                                                    left outer join books_series_link on books_series_link.book = books.id
20
                                                    where books_authors_link.book = books.id and author = ? {1} order by series desc, series_index asc, pubdate asc');
21
define ('SQL_BOOKS_BY_SERIE', 'select {0} from books_series_link, books ' . SQL_BOOKS_LEFT_JOIN . '
22
                                                    where books_series_link.book = books.id and series = ? {1} order by series_index');
23
define ('SQL_BOOKS_BY_TAG', 'select {0} from books_tags_link, books ' . SQL_BOOKS_LEFT_JOIN . '
24
                                                    where books_tags_link.book = books.id and tag = ? {1} order by sort');
25
define ('SQL_BOOKS_BY_LANGUAGE', 'select {0} from books_languages_link, books ' . SQL_BOOKS_LEFT_JOIN . '
26
                                                    where books_languages_link.book = books.id and lang_code = ? {1} order by sort');
27
define ('SQL_BOOKS_BY_CUSTOM', 'select {0} from {2}, books ' . SQL_BOOKS_LEFT_JOIN . '
28
                                                    where {2}.book = books.id and {2}.{3} = ? {1} order by sort');
29
define ('SQL_BOOKS_BY_CUSTOM_BOOL_TRUE', 'select {0} from {2}, books ' . SQL_BOOKS_LEFT_JOIN . '
30
                                                    where {2}.book = books.id and {2}.value = 1 {1} order by sort');
31
define ('SQL_BOOKS_BY_CUSTOM_BOOL_FALSE', 'select {0} from {2}, books ' . SQL_BOOKS_LEFT_JOIN . '
32
                                                    where {2}.book = books.id and {2}.value = 0 {1} order by sort');
33
define ('SQL_BOOKS_BY_CUSTOM_BOOL_NULL', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
34
                                                    where books.id not in (select book from {2}) {1} order by sort');
35
define ('SQL_BOOKS_BY_CUSTOM_RATING', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
36
                                                    left join {2} on {2}.book = books.id
37
                                                    left join {3} on {3}.id = {2}.{4}
38
                                                    where {3}.value = ?  order by sort');
39
define ('SQL_BOOKS_BY_CUSTOM_RATING_NULL', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
40
								                    left join {2} on {2}.book = books.id
41
								                    left join {3} on {3}.id = {2}.{4}
42
                                                    where ((books.id not in (select {2}.book from {2})) or ({3}.value = 0)) {1} order by sort');
43
define ('SQL_BOOKS_BY_CUSTOM_DATE', 'select {0} from {2}, books ' . SQL_BOOKS_LEFT_JOIN . '
44
                                                    where {2}.book = books.id and date({2}.value) = ? {1} order by sort');
45
define ('SQL_BOOKS_BY_CUSTOM_DIRECT', 'select {0} from {2}, books ' . SQL_BOOKS_LEFT_JOIN . '
46
                                                    where {2}.book = books.id and {2}.value = ? {1} order by sort');
47
define ('SQL_BOOKS_BY_CUSTOM_DIRECT_ID', 'select {0} from {2}, books ' . SQL_BOOKS_LEFT_JOIN . '
48
                                                    where {2}.book = books.id and {2}.id = ? {1} order by sort');
49
define ('SQL_BOOKS_QUERY', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
50
                                                    where (
51
                                                    exists (select null from authors, books_authors_link where book = books.id and author = authors.id and authors.name like ?) or
52
                                                    exists (select null from tags, books_tags_link where book = books.id and tag = tags.id and tags.name like ?) or
53
                                                    exists (select null from series, books_series_link on book = books.id and books_series_link.series = series.id and series.name like ?) or
54
                                                    exists (select null from publishers, books_publishers_link where book = books.id and books_publishers_link.publisher = publishers.id and publishers.name like ?) or
55
                                                    title like ?) {1} order by books.sort');
56
define ('SQL_BOOKS_RECENT', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
57
                                                    where 1=1 {1} order by timestamp desc limit ');
58
define ('SQL_BOOKS_BY_RATING', 'select {0} from books ' . SQL_BOOKS_LEFT_JOIN . '
59
                                                    where books_ratings_link.book = books.id and ratings.id = ? {1} order by sort');
60
61
class Book extends Base
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
62
{
63
    const ALL_BOOKS_UUID = 'urn:uuid';
64
    const ALL_BOOKS_ID = 'cops:books';
65
    const ALL_RECENT_BOOKS_ID = 'cops:recentbooks';
66
    const BOOK_COLUMNS = 'books.id as id, books.title as title, text as comment, path, timestamp, pubdate, series_index, uuid, has_cover, ratings.rating';
67
68
    const SQL_BOOKS_LEFT_JOIN = SQL_BOOKS_LEFT_JOIN;
69
    const SQL_BOOKS_ALL = SQL_BOOKS_ALL;
70
    const SQL_BOOKS_BY_PUBLISHER = SQL_BOOKS_BY_PUBLISHER;
71
    const SQL_BOOKS_BY_FIRST_LETTER = SQL_BOOKS_BY_FIRST_LETTER;
72
    const SQL_BOOKS_BY_AUTHOR = SQL_BOOKS_BY_AUTHOR;
73
    const SQL_BOOKS_BY_SERIE = SQL_BOOKS_BY_SERIE;
74
    const SQL_BOOKS_BY_TAG = SQL_BOOKS_BY_TAG;
75
    const SQL_BOOKS_BY_LANGUAGE = SQL_BOOKS_BY_LANGUAGE;
76
    const SQL_BOOKS_BY_CUSTOM = SQL_BOOKS_BY_CUSTOM;
77
    const SQL_BOOKS_BY_CUSTOM_BOOL_TRUE = SQL_BOOKS_BY_CUSTOM_BOOL_TRUE;
78
    const SQL_BOOKS_BY_CUSTOM_BOOL_FALSE = SQL_BOOKS_BY_CUSTOM_BOOL_FALSE;
79
    const SQL_BOOKS_BY_CUSTOM_BOOL_NULL = SQL_BOOKS_BY_CUSTOM_BOOL_NULL;
80
    const SQL_BOOKS_BY_CUSTOM_RATING = SQL_BOOKS_BY_CUSTOM_RATING;
81
    const SQL_BOOKS_BY_CUSTOM_RATING_NULL = SQL_BOOKS_BY_CUSTOM_RATING_NULL;
82
    const SQL_BOOKS_BY_CUSTOM_DATE = SQL_BOOKS_BY_CUSTOM_DATE;
83
    const SQL_BOOKS_BY_CUSTOM_DIRECT = SQL_BOOKS_BY_CUSTOM_DIRECT;
84
    const SQL_BOOKS_BY_CUSTOM_DIRECT_ID = SQL_BOOKS_BY_CUSTOM_DIRECT_ID;
85
    const SQL_BOOKS_QUERY = SQL_BOOKS_QUERY;
86
    const SQL_BOOKS_RECENT = SQL_BOOKS_RECENT;
87
    const SQL_BOOKS_BY_RATING = SQL_BOOKS_BY_RATING;
88
89
    const BAD_SEARCH = 'QQQQQ';
90
91
    public $id;
92
    public $title;
93
    public $timestamp;
94
    public $pubdate;
95
    public $path;
96
    public $uuid;
97
    public $hasCover;
98
    public $relativePath;
99
    public $seriesIndex;
100
    public $comment;
101
    public $rating;
102
    public $datas = NULL;
103
    public $authors = NULL;
104
    public $publisher = NULL;
105
    public $serie = NULL;
106
    public $tags = NULL;
107
    public $languages = NULL;
108
    public $format = array ();
109
    private $coverFileName = NULL;
110
111 78
    public function __construct($line) {
112 78
    	global $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
113 78
114 78
        $this->id = $line->id;
115 78
        $this->title = $line->title;
116 78
        $this->timestamp = strtotime($line->timestamp);
117 78
        $this->pubdate = $line->pubdate;
118 78
        //$this->path = Base::getDbDirectory() . $line->path;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
119 78
        //$this->relativePath = $line->path;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
120 78
        // -DC- Init relative or full path
121 78
        $this->path = $line->path;
122 78
        if (!is_dir($this->path)) {
123
        	$this->path = Base::getDbDirectory() . $line->path;
124 44
        }
125
        $this->seriesIndex = $line->series_index;
126 78
        $this->comment = $line->comment;
127 78
        $this->uuid = $line->uuid;
128
        $this->hasCover = $line->has_cover;
129 42
        // -DC- Use cover file name
130 42
        //if (!file_exists($this->getFilePath('jpg'))) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
131
        //    // double check
132
        //    $this->hasCover = 0;
0 ignored issues
show
Unused Code Comprehensibility introduced by
45% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
133 4
        //}
134 4
        if ($this->hasCover) {
135
        	if (!empty($config['calibre_database_field_cover'])) {
136
        		$imgDirectory = Base::getImgDirectory();
137 3
        		$this->coverFileName = $line->cover;
138 3
        		if (!file_exists($this->coverFileName)) {
139
        			$this->coverFileName = NULL;
140
        		}
141 3 View Code Duplication
        		if (empty($this->coverFileName)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142 3
        			$this->coverFileName = sprintf('%s%s', $imgDirectory, $line->cover);
143 3
        			if (!file_exists($this->coverFileName)) {
144 3
        				$this->coverFileName = NULL;
145
        			}
146
        		}
147 43
        		if (empty($this->coverFileName)) {
148 43
        			$data = $this->getDataById($this->id);
149
        			if ($data) {
150
        				$this->coverFileName = sprintf('%s%s/%s', $imgDirectory, $data->name, $line->cover);
151
        				if (!file_exists($this->coverFileName)) {
152
        					$this->coverFileName = NULL;
153
        				}
154 View Code Duplication
        				if (empty($this->coverFileName)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
        					$this->coverFileName = sprintf('%s%s.jpg', $imgDirectory, $data->name);
156 49
        					if (!file_exists($this->coverFileName)) {
157 49
        						$this->coverFileName = NULL;
158 49
        					}
159
        				}
160 49
        			}
161
        		}
162
        	}
163
        	// Else try with default cover file name
164
        	if (empty($this->coverFileName)) {
165
        		$cover = $this->getFilePath("jpg");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal jpg does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
166
        		if ($cover === false || !file_exists($cover)) {
167
        			$cover = $this->getFilePath("png");
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
168
        		}
169
        		if ($cover === false || !file_exists($cover)) {
170
        			$this->hasCover = 0;
171 5
        		}
172 5
        		else {
173 5
        			$this->coverFileName = $cover;
174
        		}
175 5
        	}
176
        }
177
        $this->rating = $line->rating;
178
    }
179
180
    // -DC- Get customisable book columns
181 48
    private static function getBookColumns()
182 48
    {
183 48
    	global $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
184
185 48
    	$res = self::BOOK_COLUMNS;
186
    	if (!empty($config['calibre_database_field_cover'])) {
187
    		$res = str_replace('has_cover,', 'has_cover, ' . $config['calibre_database_field_cover'] . ',', $res);
188
    	}
189
190
    	return $res;
191 10
    }
192 10
193 10
    public function getEntryId() {
194
        return self::ALL_BOOKS_UUID.':'.$this->uuid;
195
    }
196
197
    public static function getEntryIdByLetter ($startingLetter) {
198 10
        return self::ALL_BOOKS_ID.':letter:'.$startingLetter;
199 10
    }
200
201 10
    public function getUri () {
202
        return '?page='.parent::PAGE_BOOK_DETAIL.'&id=' . $this->id;
203 10
    }
204
205
    public function getDetailUrl () {
206
        $urlParam = $this->getUri();
207 View Code Duplication
        if (!is_null(GetUrlParam(DB))) $urlParam = addURLParameter($urlParam, DB, GetUrlParam (DB));
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
        return 'index.php' . $urlParam;
209 10
    }
210 10
211 10
    public function getTitle () {
212
        return $this->title;
213 10
    }
214
215
    /* Other class (author, series, tag, ...) initialization and accessors */
216
217
    /**
218 10
     * @return Author[]
219 10
     */
220
    public function getAuthors () {
221 9
        if (is_null($this->authors)) {
222
            $this->authors = Author::getAuthorByBookId($this->id);
223
        }
224 10
        return $this->authors;
225
    }
226
227
    public function getAuthorsName () {
228
        return implode(', ', array_map(function ($author) { return $author->name; }, $this->getAuthors()));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
229
    }
230
231
    public function getAuthorsSort () {
232
        return implode(', ', array_map(function ($author) { return $author->sort; }, $this->getAuthors()));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
233
    }
234 62
235
    public function getPublisher () {
236 62
        if (is_null($this->publisher)) {
237 62
            $this->publisher = Publisher::getPublisherByBookId($this->id);
238
        }
239 62
        return $this->publisher;
240
    }
241
242
    /**
243
     * @return Serie
244 58
     */
245 58
    public function getSerie() {
246 58
        if (is_null($this->serie)) {
247
            $this->serie = Serie::getSerieByBookId($this->id);
248 3
        }
249 3
        return $this->serie;
250 1
    }
251 1
252
    /**
253
     * @return string
254 3
     */
255
    public function getLanguages() {
256 3
        $lang = array();
257 1
        $result = parent::getDb()->prepare('select languages.lang_code
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getDb() instead of getLanguages()). Are you sure this is correct? If so, you might want to change this to $this->getDb().

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...
258
                from books_languages_link, languages
259
                where books_languages_link.lang_code = languages.id
260 3
                and book = ?
261
                order by item_order');
262
        $result->execute(array($this->id));
263 4
        while ($post = $result->fetchObject())
264
        {
265 4
            array_push($lang, Language::getLanguageString($post->lang_code));
266 4
        }
267 4
        return implode(', ', $lang);
268 4
    }
269 4
270 4
    /**
271 4
     * @return Tag[]
272 4
     */
273
    public function getTags() {
274
        if (is_null ($this->tags)) {
275 4
            $this->tags = array();
276
277
            $result = parent::getDb()->prepare('select tags.id as id, name
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getDb() instead of getTags()). Are you sure this is correct? If so, you might want to change this to $this->getDb().

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...
278 3
                from books_tags_link, tags
279
                where tag = tags.id
280
                and book = ?
281 3
                order by name');
282 3
            $result->execute(array($this->id));
283 3
            while ($post = $result->fetchObject())
284
            {
285
                array_push($this->tags, new Tag($post));
286 8
            }
287 8
        }
288 3
        return $this->tags;
289
    }
290 5
291 5
    public function getTagsName() {
292 5
        return implode(', ', array_map(function ($tag) { return $tag->name; }, $this->getTags()));
0 ignored issues
show
Coding Style introduced by
It is generally recommended to place each PHP statement on a line by itself.

Let’s take a look at an example:

// Bad
$a = 5; $b = 6; $c = 7;

// Good
$a = 5;
$b = 6;
$c = 7;
Loading history...
293
    }
294 5
295 3
    /**
296
     * @return Data[]
297 5
     */
298
    public function getDatas()
299
    {
300 15
        if (is_null($this->datas)) {
301 15
            $this->datas = Data::getDataByBook($this);
302 2
        }
303
        return $this->datas;
304 13
    }
305 13
306 12
    /* End of other class (author, series, tag, ...) initialization and accessors */
307
308 1
    public static function getFilterString() {
309
        $filter = getURLParam('tag', NULL);
310
        if (empty($filter)) return '';
311 43
312 43
        $exists = true;
313 43
        if (preg_match("/^!(.*)$/", $filter, $matches)) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal /^!(.*)$/ does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
314 43
            $exists = false;
315 38
            $filter = $matches[1];
316
        }
317 43
318
        $result = 'exists (select null from books_tags_link, tags where books_tags_link.book = books.id and books_tags_link.tag = tags.id and tags.name = "' . $filter . '")';
319 37
320
        if (!$exists) {
321
            $result = 'not ' . $result;
322
        }
323 31
324
        return 'and ' . $result;
325
    }
326
327
    public function GetMostInterestingDataToSendToKindle()
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
328 12
    {
329 12
        $bestFormatForKindle = array('EPUB', 'PDF', 'AZW3', 'MOBI');
330 12
        $bestRank = -1;
331 12
        $bestData = NULL;
332
        foreach ($this->getDatas() as $data) {
333
            $key = array_search($data->format, $bestFormatForKindle);
334 78
            if ($key !== false && $key > $bestRank) {
335
                $bestRank = $key;
336 78
                $bestData = $data;
337
            }
338 78
        }
339
        return $bestData;
340
    }
341
342 2
    public function getDataById($idData)
343 2
    {
344 2
        $reduced = array_filter($this->getDatas(), function ($data) use ($idData) {
345
            return $data->id == $idData;
346
        });
347 78
        return reset($reduced);
348
    }
349 3
350
    public function getRating() {
351
        if (is_null($this->rating) || $this->rating == 0) {
352
            return '';
353 78
        }
354
        $retour = '';
355
        for ($i = 0; $i < $this->rating / 2; $i++) {
356
            $retour .= '&#9733;';
357
        }
358
        for ($i = 0; $i < 5 - $this->rating / 2; $i++) {
359
            $retour .= '&#9734;';
360
        }
361
        return $retour;
362
    }
363
364
    public function getPubDate() {
365
        if (empty ($this->pubdate)) {
366
            return '';
367
        }
368
        $dateY = (int) substr($this->pubdate, 0, 4);
369
        if ($dateY > 102) {
370
            return str_pad($dateY, 4, '0', STR_PAD_LEFT);
371
        }
372
        return '';
373
    }
374
375
    public function getComment($withSerie = true) {
376
        $addition = '';
377
        $se = $this->getSerie ();
378
        if (!is_null ($se) && $withSerie) {
379
            $addition = $addition . '<strong>' . localize('content.series') . '</strong>' . str_format(localize('content.series.data'), $this->seriesIndex, htmlspecialchars($se->name)) . "<br />\n";
380
        }
381
        if (preg_match('/<\/(div|p|a|span)>/', $this->comment))
382
        {
383
            return $addition . html2xhtml($this->comment);
384
        }
385
        else
386
        {
387
            return $addition . htmlspecialchars($this->comment);
388
        }
389
    }
390
391
    public function getDataFormat($format) {
392
        $reduced = array_filter($this->getDatas(), function ($data) use ($format) {
393
            return $data->format == $format;
394
        });
395 3
        return reset($reduced);
396 3
    }
397 1
398
    public function getFilePath($extension, $idData = NULL, $relative = false)
0 ignored issues
show
Unused Code introduced by
The parameter $relative 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...
399
    {
400 3
        /*if ($extension == 'jpg')
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
401
        {
402 3
            $file = 'cover.jpg';
403 3
        }
404 3
        else
405
        {
406 3
            $data = $this->getDataById($idData);
407 2
            if (!$data) return NULL;
408 2
            $file = $data->name . '.' . strtolower($data->format);
409 1
        }
410
411 2
        if ($relative)
412 2
        {
413 2
            return $this->relativePath.'/'.$file;
414
        }
415
        else
416
        {
417
            return $this->path.'/'.$file;
418
        }*/
419
    	if ($extension == "jpg" || $extension == "png") {
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal jpg does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
420 2
    		if (empty($this->coverFileName)) {
421 2
    			return $this->path . '/cover.' . $extension;
422 2
    		}
423 2
    		else {
424 2
    			$ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION));
425 2
    			if ($ext == $extension) {
426
    				return $this->coverFileName;
427 2
    			}
428
    		}
429
    		return false;
430 44
    	}
431
    	else {
432 44
    		$data = $this->getDataById($idData);
433
    		if (!$data) {
434 44
    			return NULL;
435
    		}
436 18
    		$file = $data->name . "." . strtolower($data->format);
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal . does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
437
    		return $this->path . '/' . $file;
438 18
    	}
439
    }
440
441 44
    public function getUpdatedEpub($idData)
442
    {
443 44
        global $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
444
        $data = $this->getDataById($idData);
445 44
446
        try
447
        {
448
            $epub = new EPub($data->getLocalPath());
449 44
450
            $epub->Title($this->title);
451 44
            $authorArray = array();
452
            foreach ($this->getAuthors() as $author) {
453
                $authorArray[$author->sort] = $author->name;
454 44
            }
455 44
            $epub->Authors($authorArray);
0 ignored issues
show
Documentation introduced by
$authorArray is of type array, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
456 41
            $epub->Language($this->getLanguages());
457
            $epub->Description ($this->getComment(false));
458
            $epub->Subjects($this->getTagsName());
0 ignored issues
show
Documentation introduced by
$this->getTagsName() is of type string, but the function expects a false|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
459 44
            // -DC- Use cover file name
460
            // $epub->Cover2($this->getFilePath('jpg'), 'image/jpeg');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
461
            $epub->Cover2($this->coverFileName, 'image/jpeg');
0 ignored issues
show
Documentation introduced by
$this->coverFileName is of type null|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
'image/jpeg' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
462
            $epub->Calibre($this->uuid);
463 41
            $se = $this->getSerie();
464 41
            if (!is_null($se)) {
465 41
                $epub->Serie($se->name);
466 41
                $epub->SerieIndex($this->seriesIndex);
467
            }
468
            $filename = $data->getUpdatedFilenameEpub();
469 3
            if ($config['cops_provide_kepub'] == '1'  && preg_match('/Kobo/', $_SERVER['HTTP_USER_AGENT'])) {
470 3
                $epub->updateForKepub();
471
                $filename = $data->getUpdatedFilenameKepub();
472
            }
473 21
            $epub->download($filename);
474 21
        }
475 21
        catch (Exception $e)
476 21
        {
477 21
            echo 'Exception : ' . $e->getMessage();
478 21
        }
479 21
    }
480 21
481 21
    public function getThumbnail($width, $height, $outputfile = NULL) {
482 21
        if (is_null($width) && is_null($height)) {
483 21
            return false;
484 21
        }
485 21
486 21
        // -DC- Use cover file name
487 21
        //$file = $this->getFilePath('jpg');
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
488
        $file = $this->coverFileName;
489 21
        // get image size
490
        if ($size = GetImageSize($file)) {
491
            $w = $size[0];
492 8
            $h = $size[1];
493 8
            //set new size
494
            if (!is_null($width)) {
495
                $nw = $width;
496 1
                if ($nw >= $w) { return false; }
497 1
                $nh = ($nw*$h)/$w;
498
            } else {
499
                $nh = $height;
500 2
                if ($nh >= $h) { return false; }
501 2
                $nw = ($nh*$w)/$h;
502
            }
503
        } else {
504 2
            return false;
505 2
        }
506
507
        //draw the image
508 2
        $src_img = imagecreatefromjpeg($file);
509 2
        $dst_img = imagecreatetruecolor($nw,$nh);
510
        imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $nw, $nh, $w, $h);//resizing the image
511
        imagejpeg($dst_img,$outputfile,80);
512 2
        imagedestroy($src_img);
513 2
        imagedestroy($dst_img);
514
515
        return true;
516
    }
517
518
    public function getLinkArray ()
519
    {
520
        $linkArray = array();
521
522 4
        if ($this->hasCover) {
523 4
        	// -DC- Use cover file name
524
        	//array_push($linkArray, Data::getLink($this, 'jpg', 'image/jpeg', Link::OPDS_IMAGE_TYPE, 'cover.jpg', NULL));
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
525 4
        	//array_push($linkArray, Data::getLink($this, 'jpg', 'image/jpeg', Link::OPDS_THUMBNAIL_TYPE, 'cover.jpg', NULL));
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
526
        	$ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION));
527
        	if ($ext == 'png') {
528 37
        		array_push($linkArray, Data::getLink($this, "png", "image/png", Link::OPDS_IMAGE_TYPE, "cover.png", NULL));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal image/png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal cover.png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
529 37
        		array_push($linkArray, Data::getLink($this, "png", "image/png", Link::OPDS_THUMBNAIL_TYPE, "cover.png", NULL));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal image/png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal cover.png does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
530 37
        	}
531
        	else {
532 37
        		array_push($linkArray, Data::getLink($this, 'jpg', 'image/jpeg', Link::OPDS_IMAGE_TYPE, 'cover.jpg', NULL));
533 37
        		array_push($linkArray, Data::getLink($this, "jpg", "image/jpeg", Link::OPDS_THUMBNAIL_TYPE, "cover.jpg", NULL));
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal jpg does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal image/jpeg does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
Coding Style Comprehensibility introduced by
The string literal cover.jpg does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
534
        	}
535 36
        }
536 36
537
        foreach ($this->getDatas() as $data)
538 1
        {
539
            if ($data->isKnownType())
540
            {
541 1
                array_push($linkArray, $data->getDataLink(Link::OPDS_ACQUISITION_TYPE, $data->format));
542 1
            }
543 1
        }
544
545 1
        foreach ($this->getAuthors() as $author) {
546 1
            /* @var $author Author */
547
            array_push($linkArray, new LinkNavigation($author->getUri(), 'related', str_format(localize('bookentry.author'), localize('splitByLetter.book.other'), $author->name)));
548 1
        }
549 1
550 1
        $serie = $this->getSerie();
551 1
        if (!is_null ($serie)) {
552 1
            array_push($linkArray, new LinkNavigation($serie->getUri(), 'related', str_format(localize('content.series.data'), $this->seriesIndex, $serie->name)));
553
        }
554
555
        return $linkArray;
556
    }
557 2
558 2
559 2
    public function getEntry() {
560 2
        return new EntryBook($this->getTitle(), $this->getEntryId(),
561 2
            $this->getComment(), 'text/html',
562 2
            $this->getLinkArray(), $this);
563 2
    }
564 2
565 2
    public static function getBookCount($database = NULL) {
566 2
        return parent::executeQuerySingle('select count(*) from books', $database);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (executeQuerySingle() instead of getBookCount()). Are you sure this is correct? If so, you might want to change this to $this->executeQuerySingle().

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...
567
    }
568
569
    public static function getCount() {
570 2
        global $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
571
        $nBooks = parent::executeQuerySingle('select count(*) from books');
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (executeQuerySingle() instead of getCount()). Are you sure this is correct? If so, you might want to change this to $this->executeQuerySingle().

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...
572
        $result = array();
573 2
        $entry = new Entry(localize('allbooks.title'),
574
                          self::ALL_BOOKS_ID,
575
                          str_format(localize('allbooks.alphabetical', $nBooks), $nBooks), 'text',
576 2
                          array(new LinkNavigation('?page='.parent::PAGE_ALL_BOOKS)), '', $nBooks);
577
        array_push($result, $entry);
578 2
        if ($config['cops_recentbooks_limit'] > 0) {
579
            $entry = new Entry(localize('recent.title'),
580
                              self::ALL_RECENT_BOOKS_ID,
581 1
                              str_format(localize('recent.list'), $config['cops_recentbooks_limit']), 'text',
582 1
                              array ( new LinkNavigation ('?page='.parent::PAGE_ALL_RECENT_BOOKS)), '', $config['cops_recentbooks_limit']);
583 1
            array_push($result, $entry);
584
        }
585
        return $result;
586 3
    }
587
588
    public static function getBooksByAuthor($authorId, $n) {
589 3
        return self::getEntryArray(self::SQL_BOOKS_BY_AUTHOR, array($authorId), $n);
590
    }
591
592 3
    public static function getBooksByRating($ratingId, $n) {
593
        return self::getEntryArray(self::SQL_BOOKS_BY_RATING, array($ratingId), $n);
594 3
    }
595 3
596
    public static function getBooksByPublisher($publisherId, $n) {
597 3
        return self::getEntryArray(self::SQL_BOOKS_BY_PUBLISHER, array($publisherId), $n);
598 3
    }
599 3
600
    public static function getBooksBySeries($serieId, $n) {
601 3
        return self::getEntryArray(self::SQL_BOOKS_BY_SERIE, array($serieId), $n);
602
    }
603
604 25
    public static function getBooksByTag($tagId, $n) {
605 25
        return self::getEntryArray(self::SQL_BOOKS_BY_TAG, array($tagId), $n);
606
    }
607
608 55
    public static function getBooksByLanguage($languageId, $n) {
609
        return self::getEntryArray(self::SQL_BOOKS_BY_LANGUAGE, array($languageId), $n);
610
    }
611 55
612
    /**
613 55
     * @param $customColumn CustomColumn
614 55
     * @param $id integer
615
     * @param $n integer
616 41
     * @return array
617 41
     */
618
    public static function getBooksByCustom($customColumn, $id, $n) {
619 55
        list($query, $params) = $customColumn->getQuery($id);
620
621
        return self::getEntryArray($query, $params, $n);
622 5
    }
623 5
624 5
    public static function getBookById($bookId) {
625 5
    	$result = parent::getDb()->prepare('select ' . self::getBookColumns() . '
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getDb() instead of getBookById()). Are you sure this is correct? If so, you might want to change this to $this->getDb().

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...
626
from books ' . self::SQL_BOOKS_LEFT_JOIN . '
627
where books.id = ?');
628
        $result->execute(array($bookId));
629
        while ($post = $result->fetchObject())
630
        {
631
            $book = new Book($post);
632
            return $book;
633
        }
634 5
        return NULL;
635 5
    }
636
637 5
    public static function getBookByDataId($dataId) {
638 2
    	$result = parent::getDb()->prepare('select ' . self::getBookColumns() . ', data.name, data.format
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (getDb() instead of getBookByDataId()). Are you sure this is correct? If so, you might want to change this to $this->getDb().

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...
639 2
from data, books ' . self::SQL_BOOKS_LEFT_JOIN . '
640 2
where data.book = books.id and data.id = ?');
641 2
        $result->execute(array($dataId));
642 2
        while ($post = $result->fetchObject())
643 1
        {
644
            $book = new Book($post);
645 2
            $data = new Data($post, $book);
646
            $data->id = $dataId;
647
            $book->datas = array($data);
648
            return $book;
649
        }
650
        return NULL;
651 5
    }
652
653
    public static function getBooksByQuery($query, $n, $database = NULL, $numberPerPage = NULL) {
654
        $i = 0;
655
        $critArray = array();
656
        foreach (array(PageQueryResult::SCOPE_AUTHOR,
657
                       PageQueryResult::SCOPE_TAG,
658
                       PageQueryResult::SCOPE_SERIES,
659
                       PageQueryResult::SCOPE_PUBLISHER,
660
                       PageQueryResult::SCOPE_BOOK) as $key) {
661
            if (in_array($key, getCurrentOption('ignored_categories')) ||
662
                (!array_key_exists($key, $query) && !array_key_exists('all', $query))) {
663
                $critArray[$i] = self::BAD_SEARCH;
664
            }
665
            else {
666
                if (array_key_exists($key, $query)) {
667
                    $critArray[$i] = $query[$key];
668
                } else {
669
                    $critArray[$i] = $query["all"];
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal all does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
670
                }
671
            }
672
            $i++;
673
        }
674
        return self::getEntryArray(self::SQL_BOOKS_QUERY, $critArray, $n, $database, $numberPerPage);
675
    }
676
677
    public static function getBooks($n) {
678
        list ($entryArray, $totalNumber) = self::getEntryArray(self::SQL_BOOKS_ALL , array (), $n);
679
        return array($entryArray, $totalNumber);
680
    }
681
682 View Code Duplication
    public static function getAllBooks() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
683
        /* @var $result PDOStatement */
684
685
        list (, $result) = parent::executeQuery('select {0}
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (executeQuery() instead of getAllBooks()). Are you sure this is correct? If so, you might want to change this to $this->executeQuery().

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...
686
from books
687
group by substr (upper (sort), 1, 1)
688
order by substr (upper (sort), 1, 1)', 'substr (upper (sort), 1, 1) as title, count(*) as count', self::getFilterString(), array(), -1);
689
690
        $entryArray = array();
691
        while ($post = $result->fetchObject())
692
        {
693
            array_push($entryArray, new Entry($post->title, Book::getEntryIdByLetter($post->title),
694
                str_format(localize('bookword', $post->count), $post->count), 'text',
695
                array(new LinkNavigation('?page='.parent::PAGE_ALL_BOOKS_LETTER.'&id='. rawurlencode($post->title))), '', $post->count));
696
        }
697
        return $entryArray;
698
    }
699
700
    public static function getBooksByStartingLetter($letter, $n, $database = NULL, $numberPerPage = NULL) {
701
        return self::getEntryArray(self::SQL_BOOKS_BY_FIRST_LETTER, array($letter . '%'), $n, $database, $numberPerPage);
702
    }
703
704
    public static function getEntryArray($query, $params, $n, $database = NULL, $numberPerPage = NULL) {
705
        /* @var $totalNumber integer */
706
        /* @var $result PDOStatement */
707
    	list($totalNumber, $result) = parent::executeQuery($query, self::getBookColumns(), self::getFilterString(), $params, $n, $database, $numberPerPage);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (executeQuery() instead of getEntryArray()). Are you sure this is correct? If so, you might want to change this to $this->executeQuery().

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...
708
709
        $entryArray = array();
710
        while ($post = $result->fetchObject())
711
        {
712
            $book = new Book($post);
713
            array_push($entryArray, $book->getEntry());
714
        }
715
        return array($entryArray, $totalNumber);
716
    }
717
718
    public static function getAllRecentBooks() {
719
        global $config;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
720
        list ($entryArray, ) = self::getEntryArray(self::SQL_BOOKS_RECENT . $config['cops_recentbooks_limit'], array(), -1);
721
        return $entryArray;
722
    }
723
724
    /**
725
     * The values of all the specified columns
726
     *
727
     * @param string[] $columns
728
     * @return CustomColumn[]
729
     */
730
    public function getCustomColumnValues($columns, $asArray = false) {
731
        $result = array();
732
733
        foreach ($columns as $lookup) {
734
            $col = CustomColumnType::createByLookup($lookup);
735
            if (!is_null($col)) {
736
                $cust = $col->getCustomByBook($this);
737
                if (!is_null($cust)) {
738
                    if ($asArray) {
739
                        array_push($result, $cust->toArray());
740
                    } else {
741
                        array_push($result, $cust);
742
                    }
743
                }
744
            }
745
        }
746
747
        return $result;
748
    }
749
}
750