Test Setup Failed
Pull Request — master (#424)
by
unknown
03:11
created

Book::getBookColumns()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 11
ccs 5
cts 5
cp 1
crap 2
rs 9.9
c 0
b 0
f 0
1
<?php
2
/**
3
 * COPS (Calibre OPDS PHP Server) class file
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 * @author     Sébastien Lucas <[email protected]>
7
 */
8
9
// 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
        			// Try with the epub file name
149
        			$data = $this->getDataFormat('EPUB');
150
        			if ($data) {
151
        				$this->coverFileName = sprintf('%s%s/%s', $imgDirectory, $data->name, $line->cover);
152
        				if (!file_exists($this->coverFileName)) {
153
        					$this->coverFileName = NULL;
154
        				}
155 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...
156 49
        					$this->coverFileName = sprintf('%s%s.jpg', $imgDirectory, $data->name);
157 49
        					if (!file_exists($this->coverFileName)) {
158 49
        						$this->coverFileName = NULL;
159
        					}
160 49
        				}
161
        			}
162
        		}
163
        	}
164
        	// Else try with default cover file name
165
        	if (empty($this->coverFileName)) {
166
        		$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...
167
        		if ($cover === false || !file_exists($cover)) {
168
        			$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...
169
        		}
170
        		if ($cover === false || !file_exists($cover)) {
171 5
        			$this->hasCover = 0;
172 5
        		}
173 5
        		else {
174
        			$this->coverFileName = $cover;
175 5
        		}
176
        	}
177
        }
178
        $this->rating = $line->rating;
179
    }
180
181 48
    // -DC- Get customisable book columns
182 48
    private static function getBookColumns()
183 48
    {
184
    	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...
185 48
186
    	$res = self::BOOK_COLUMNS;
187
    	if (!empty($config['calibre_database_field_cover'])) {
188
    		$res = str_replace('has_cover,', 'has_cover, ' . $config['calibre_database_field_cover'] . ',', $res);
189
    	}
190
191 10
    	return $res;
192 10
    }
193 10
194
    public function getEntryId() {
195
        return self::ALL_BOOKS_UUID.':'.$this->uuid;
196
    }
197
198 10
    public static function getEntryIdByLetter ($startingLetter) {
199 10
        return self::ALL_BOOKS_ID.':letter:'.$startingLetter;
200
    }
201 10
202
    public function getUri () {
203 10
        return '?page='.parent::PAGE_BOOK_DETAIL.'&id=' . $this->id;
204
    }
205
206
    public function getDetailUrl () {
207
        $urlParam = $this->getUri();
208 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...
209 10
        return 'index.php' . $urlParam;
210 10
    }
211 10
212
    public function getTitle () {
213 10
        return $this->title;
214
    }
215
216
    /* Other class (author, series, tag, ...) initialization and accessors */
217
218 10
    /**
219 10
     * @return Author[]
220
     */
221 9
    public function getAuthors () {
222
        if (is_null($this->authors)) {
223
            $this->authors = Author::getAuthorByBookId($this->id);
224 10
        }
225
        return $this->authors;
226
    }
227
228
    public function getAuthorsName () {
229
        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...
230
    }
231
232
    public function getAuthorsSort () {
233
        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...
234 62
    }
235
236 62
    public function getPublisher () {
237 62
        if (is_null($this->publisher)) {
238
            $this->publisher = Publisher::getPublisherByBookId($this->id);
239 62
        }
240
        return $this->publisher;
241
    }
242
243
    /**
244 58
     * @return Serie
245 58
     */
246 58
    public function getSerie() {
247
        if (is_null($this->serie)) {
248 3
            $this->serie = Serie::getSerieByBookId($this->id);
249 3
        }
250 1
        return $this->serie;
251 1
    }
252
253
    /**
254 3
     * @return string
255
     */
256 3
    public function getLanguages() {
257 1
        $lang = array();
258
        $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...
259
                from books_languages_link, languages
260 3
                where books_languages_link.lang_code = languages.id
261
                and book = ?
262
                order by item_order');
263 4
        $result->execute(array($this->id));
264
        while ($post = $result->fetchObject())
265 4
        {
266 4
            array_push($lang, Language::getLanguageString($post->lang_code));
267 4
        }
268 4
        return implode(', ', $lang);
269 4
    }
270 4
271 4
    /**
272 4
     * @return Tag[]
273
     */
274
    public function getTags() {
275 4
        if (is_null ($this->tags)) {
276
            $this->tags = array();
277
278 3
            $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...
279
                from books_tags_link, tags
280
                where tag = tags.id
281 3
                and book = ?
282 3
                order by name');
283 3
            $result->execute(array($this->id));
284
            while ($post = $result->fetchObject())
285
            {
286 8
                array_push($this->tags, new Tag($post));
287 8
            }
288 3
        }
289
        return $this->tags;
290 5
    }
291 5
292 5
    public function getTagsName() {
293
        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...
294 5
    }
295 3
296
    /**
297 5
     * @return Data[]
298
     */
299
    public function getDatas()
300 15
    {
301 15
        if (is_null($this->datas)) {
302 2
            $this->datas = Data::getDataByBook($this);
303
        }
304 13
        return $this->datas;
305 13
    }
306 12
307
    /* End of other class (author, series, tag, ...) initialization and accessors */
308 1
309
    public static function getFilterString() {
310
        $filter = getURLParam('tag', NULL);
311 43
        if (empty($filter)) return '';
312 43
313 43
        $exists = true;
314 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...
315 38
            $exists = false;
316
            $filter = $matches[1];
317 43
        }
318
319 37
        $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 . '")';
320
321
        if (!$exists) {
322
            $result = 'not ' . $result;
323 31
        }
324
325
        return 'and ' . $result;
326
    }
327
328 12
    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...
329 12
    {
330 12
        $bestFormatForKindle = array('EPUB', 'PDF', 'AZW3', 'MOBI');
331 12
        $bestRank = -1;
332
        $bestData = NULL;
333
        foreach ($this->getDatas() as $data) {
334 78
            $key = array_search($data->format, $bestFormatForKindle);
335
            if ($key !== false && $key > $bestRank) {
336 78
                $bestRank = $key;
337
                $bestData = $data;
338 78
            }
339
        }
340
        return $bestData;
341
    }
342 2
343 2
    public function getDataById($idData)
344 2
    {
345
        $reduced = array_filter($this->getDatas(), function ($data) use ($idData) {
346
            return $data->id == $idData;
347 78
        });
348
        return reset($reduced);
349 3
    }
350
351
    public function getRating() {
352
        if (is_null($this->rating) || $this->rating == 0) {
353 78
            return '';
354
        }
355
        $retour = '';
356
        for ($i = 0; $i < $this->rating / 2; $i++) {
357
            $retour .= '&#9733;';
358
        }
359
        for ($i = 0; $i < 5 - $this->rating / 2; $i++) {
360
            $retour .= '&#9734;';
361
        }
362
        return $retour;
363
    }
364
365
    public function getPubDate() {
366
        if (empty ($this->pubdate)) {
367
            return '';
368
        }
369
        $dateY = (int) substr($this->pubdate, 0, 4);
370
        if ($dateY > 102) {
371
            return str_pad($dateY, 4, '0', STR_PAD_LEFT);
372
        }
373
        return '';
374
    }
375
376
    public function getComment($withSerie = true) {
377
        $addition = '';
378
        $se = $this->getSerie ();
379
        if (!is_null ($se) && $withSerie) {
380
            $addition = $addition . '<strong>' . localize('content.series') . '</strong>' . str_format(localize('content.series.data'), $this->seriesIndex, htmlspecialchars($se->name)) . "<br />\n";
381
        }
382
        if (preg_match('/<\/(div|p|a|span)>/', $this->comment))
383
        {
384
            return $addition . html2xhtml($this->comment);
385
        }
386
        else
387
        {
388
            return $addition . htmlspecialchars($this->comment);
389
        }
390
    }
391
392
    public function getDataFormat($format) {
393
        $reduced = array_filter($this->getDatas(), function ($data) use ($format) {
394
            return $data->format == $format;
395 3
        });
396 3
        return reset($reduced);
397 1
    }
398
399
    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...
400 3
    {
401
        /*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...
402 3
        {
403 3
            $file = 'cover.jpg';
404 3
        }
405
        else
406 3
        {
407 2
            $data = $this->getDataById($idData);
408 2
            if (!$data) return NULL;
409 1
            $file = $data->name . '.' . strtolower($data->format);
410
        }
411 2
412 2
        if ($relative)
413 2
        {
414
            return $this->relativePath.'/'.$file;
415
        }
416
        else
417
        {
418
            return $this->path.'/'.$file;
419
        }*/
420 2
    	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...
421 2
    		if (empty($this->coverFileName)) {
422 2
    			return $this->path . '/cover.' . $extension;
423 2
    		}
424 2
    		else {
425 2
    			$ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION));
426
    			if ($ext == $extension) {
427 2
    				return $this->coverFileName;
428
    			}
429
    		}
430 44
    		return false;
431
    	}
432 44
    	else {
433
    		$data = $this->getDataById($idData);
434 44
    		if (!$data) {
435
    			return NULL;
436 18
    		}
437
    		$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...
438 18
    		return $this->path . '/' . $file;
439
    	}
440
    }
441 44
442
    public function getUpdatedEpub($idData)
443 44
    {
444
        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...
445 44
        $data = $this->getDataById($idData);
446
447
        try
448
        {
449 44
            $epub = new EPub($data->getLocalPath());
450
451 44
            $epub->Title($this->title);
452
            $authorArray = array();
453
            foreach ($this->getAuthors() as $author) {
454 44
                $authorArray[$author->sort] = $author->name;
455 44
            }
456 41
            $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...
457
            $epub->Language($this->getLanguages());
458
            $epub->Description ($this->getComment(false));
459 44
            $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...
460
            // -DC- Use cover file name
461
            // $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...
462
            $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...
463 41
            $epub->Calibre($this->uuid);
464 41
            $se = $this->getSerie();
465 41
            if (!is_null($se)) {
466 41
                $epub->Serie($se->name);
467
                $epub->SerieIndex($this->seriesIndex);
468
            }
469 3
            $filename = $data->getUpdatedFilenameEpub();
470 3
            if ($config['cops_provide_kepub'] == '1'  && preg_match('/Kobo/', $_SERVER['HTTP_USER_AGENT'])) {
471
                $epub->updateForKepub();
472
                $filename = $data->getUpdatedFilenameKepub();
473 21
            }
474 21
            $epub->download($filename);
475 21
        }
476 21
        catch (Exception $e)
477 21
        {
478 21
            echo 'Exception : ' . $e->getMessage();
479 21
        }
480 21
    }
481 21
482 21
    public function getThumbnail($width, $height, $outputfile = NULL, $inType = 'jpg') {
483 21
        if (is_null($width) && is_null($height)) {
484 21
            return false;
485 21
        }
486 21
487 21
        // -DC- Use cover file name
488
        //$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...
489 21
        $file = $this->coverFileName;
490
        // get image size
491
        if ($size = GetImageSize($file)) {
492 8
            $w = $size[0];
493 8
            $h = $size[1];
494
            //set new size
495
            if (!is_null($width)) {
496 1
                $nw = $width;
497 1
                if ($nw >= $w) { return false; }
498
                $nh = ($nw*$h)/$w;
499
            } else {
500 2
                $nh = $height;
501 2
                if ($nh >= $h) { return false; }
502
                $nw = ($nh*$w)/$h;
503
            }
504 2
        } else {
505 2
            return false;
506
        }
507
508 2
        // Draw the image
509 2
        if ($inType == 'png') {
510
        	$src_img = imagecreatefrompng($file);
511
        }
512 2
        else {
513 2
        	$src_img = imagecreatefromjpeg($file);
514
        }
515
        $dst_img = imagecreatetruecolor($nw,$nh);
516
        if (!imagecopyresampled($dst_img, $src_img, 0, 0, 0, 0, $nw, $nh, $w, $h)) {
517
        	return false;
518
        }
519
        if ($inType == 'png') {
520
        	if (!imagepng($dst_img, $outputfile, 9)) {
521
        		return false;
522 4
        	}
523 4
        }
524
        else {
525 4
        	if (!imagejpeg($dst_img, $outputfile, 80)) {
526
        		return false;
527
        	}
528 37
        }
529 37
        imagedestroy($src_img);
530 37
        imagedestroy($dst_img);
531
532 37
        return true;
533 37
    }
534
535 36
    public function getLinkArray ()
536 36
    {
537
        $linkArray = array();
538 1
539
        if ($this->hasCover) {
540
        	// -DC- Use cover file name
541 1
        	//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...
542 1
        	//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...
543 1
        	$ext = strtolower(pathinfo($this->coverFileName, PATHINFO_EXTENSION));
544
        	if ($ext == 'png') {
545 1
        		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...
546 1
        		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...
547
        	}
548 1
        	else {
549 1
        		array_push($linkArray, Data::getLink($this, 'jpg', 'image/jpeg', Link::OPDS_IMAGE_TYPE, 'cover.jpg', NULL));
550 1
        		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...
551 1
        	}
552 1
        }
553
554
        foreach ($this->getDatas() as $data)
555
        {
556
            if ($data->isKnownType())
557 2
            {
558 2
                array_push($linkArray, $data->getDataLink(Link::OPDS_ACQUISITION_TYPE, $data->format));
559 2
            }
560 2
        }
561 2
562 2
        foreach ($this->getAuthors() as $author) {
563 2
            /* @var $author Author */
564 2
            array_push($linkArray, new LinkNavigation($author->getUri(), 'related', str_format(localize('bookentry.author'), localize('splitByLetter.book.other'), $author->name)));
565 2
        }
566 2
567
        $serie = $this->getSerie();
568
        if (!is_null ($serie)) {
569
            array_push($linkArray, new LinkNavigation($serie->getUri(), 'related', str_format(localize('content.series.data'), $this->seriesIndex, $serie->name)));
570 2
        }
571
572
        return $linkArray;
573 2
    }
574
575
576 2
    public function getEntry() {
577
        return new EntryBook($this->getTitle(), $this->getEntryId(),
578 2
            $this->getComment(), 'text/html',
579
            $this->getLinkArray(), $this);
580
    }
581 1
582 1
    public static function getBookCount($database = NULL) {
583 1
        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...
584
    }
585
586 3
    public static function getCount() {
587
        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...
588
        $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...
589 3
        $result = array();
590
        $entry = new Entry(localize('allbooks.title'),
591
                          self::ALL_BOOKS_ID,
592 3
                          str_format(localize('allbooks.alphabetical', $nBooks), $nBooks), 'text',
593
                          array(new LinkNavigation('?page='.parent::PAGE_ALL_BOOKS)), '', $nBooks);
594 3
        array_push($result, $entry);
595 3
        if ($config['cops_recentbooks_limit'] > 0) {
596
            $entry = new Entry(localize('recent.title'),
597 3
                              self::ALL_RECENT_BOOKS_ID,
598 3
                              str_format(localize('recent.list'), $config['cops_recentbooks_limit']), 'text',
599 3
                              array ( new LinkNavigation ('?page='.parent::PAGE_ALL_RECENT_BOOKS)), '', $config['cops_recentbooks_limit']);
600
            array_push($result, $entry);
601 3
        }
602
        return $result;
603
    }
604 25
605 25
    public static function getBooksByAuthor($authorId, $n) {
606
        return self::getEntryArray(self::SQL_BOOKS_BY_AUTHOR, array($authorId), $n);
607
    }
608 55
609
    public static function getBooksByRating($ratingId, $n) {
610
        return self::getEntryArray(self::SQL_BOOKS_BY_RATING, array($ratingId), $n);
611 55
    }
612
613 55
    public static function getBooksByPublisher($publisherId, $n) {
614 55
        return self::getEntryArray(self::SQL_BOOKS_BY_PUBLISHER, array($publisherId), $n);
615
    }
616 41
617 41
    public static function getBooksBySeries($serieId, $n) {
618
        return self::getEntryArray(self::SQL_BOOKS_BY_SERIE, array($serieId), $n);
619 55
    }
620
621
    public static function getBooksByTag($tagId, $n) {
622 5
        return self::getEntryArray(self::SQL_BOOKS_BY_TAG, array($tagId), $n);
623 5
    }
624 5
625 5
    public static function getBooksByLanguage($languageId, $n) {
626
        return self::getEntryArray(self::SQL_BOOKS_BY_LANGUAGE, array($languageId), $n);
627
    }
628
629
    /**
630
     * @param $customColumn CustomColumn
631
     * @param $id integer
632
     * @param $n integer
633
     * @return array
634 5
     */
635 5
    public static function getBooksByCustom($customColumn, $id, $n) {
636
        list($query, $params) = $customColumn->getQuery($id);
637 5
638 2
        return self::getEntryArray($query, $params, $n);
639 2
    }
640 2
641 2
    public static function getBookById($bookId) {
642 2
    	$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...
643 1
from books ' . self::SQL_BOOKS_LEFT_JOIN . '
644
where books.id = ?');
645 2
        $result->execute(array($bookId));
646
        while ($post = $result->fetchObject())
647
        {
648
            $book = new Book($post);
649
            return $book;
650
        }
651 5
        return NULL;
652
    }
653
654
    public static function getBookByDataId($dataId) {
655
    	$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...
656
from data, books ' . self::SQL_BOOKS_LEFT_JOIN . '
657
where data.book = books.id and data.id = ?');
658
        $result->execute(array($dataId));
659
        while ($post = $result->fetchObject())
660
        {
661
            $book = new Book($post);
662
            $data = new Data($post, $book);
663
            $data->id = $dataId;
664
            $book->datas = array($data);
665
            return $book;
666
        }
667
        return NULL;
668
    }
669
670
    public static function getBooksByQuery($query, $n, $database = NULL, $numberPerPage = NULL) {
671
        $i = 0;
672
        $critArray = array();
673
        foreach (array(PageQueryResult::SCOPE_AUTHOR,
674
                       PageQueryResult::SCOPE_TAG,
675
                       PageQueryResult::SCOPE_SERIES,
676
                       PageQueryResult::SCOPE_PUBLISHER,
677
                       PageQueryResult::SCOPE_BOOK) as $key) {
678
            if (in_array($key, getCurrentOption('ignored_categories')) ||
679
                (!array_key_exists($key, $query) && !array_key_exists('all', $query))) {
680
                $critArray[$i] = self::BAD_SEARCH;
681
            }
682
            else {
683
                if (array_key_exists($key, $query)) {
684
                    $critArray[$i] = $query[$key];
685
                } else {
686
                    $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...
687
                }
688
            }
689
            $i++;
690
        }
691
        return self::getEntryArray(self::SQL_BOOKS_QUERY, $critArray, $n, $database, $numberPerPage);
692
    }
693
694
    public static function getBooks($n) {
695
        list ($entryArray, $totalNumber) = self::getEntryArray(self::SQL_BOOKS_ALL , array (), $n);
696
        return array($entryArray, $totalNumber);
697
    }
698
699 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...
700
        /* @var $result PDOStatement */
701
702
        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...
703
from books
704
group by substr (upper (sort), 1, 1)
705
order by substr (upper (sort), 1, 1)', 'substr (upper (sort), 1, 1) as title, count(*) as count', self::getFilterString(), array(), -1);
706
707
        $entryArray = array();
708
        while ($post = $result->fetchObject())
709
        {
710
            array_push($entryArray, new Entry($post->title, Book::getEntryIdByLetter($post->title),
711
                str_format(localize('bookword', $post->count), $post->count), 'text',
712
                array(new LinkNavigation('?page='.parent::PAGE_ALL_BOOKS_LETTER.'&id='. rawurlencode($post->title))), '', $post->count));
713
        }
714
        return $entryArray;
715
    }
716
717
    public static function getBooksByStartingLetter($letter, $n, $database = NULL, $numberPerPage = NULL) {
718
        return self::getEntryArray(self::SQL_BOOKS_BY_FIRST_LETTER, array($letter . '%'), $n, $database, $numberPerPage);
719
    }
720
721
    public static function getEntryArray($query, $params, $n, $database = NULL, $numberPerPage = NULL) {
722
        /* @var $totalNumber integer */
723
        /* @var $result PDOStatement */
724
    	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...
725
726
        $entryArray = array();
727
        while ($post = $result->fetchObject())
728
        {
729
            $book = new Book($post);
730
            array_push($entryArray, $book->getEntry());
731
        }
732
        return array($entryArray, $totalNumber);
733
    }
734
735
    public static function getAllRecentBooks() {
736
        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...
737
        list ($entryArray, ) = self::getEntryArray(self::SQL_BOOKS_RECENT . $config['cops_recentbooks_limit'], array(), -1);
738
        return $entryArray;
739
    }
740
741
    /**
742
     * The values of all the specified columns
743
     *
744
     * @param string[] $columns
745
     * @return CustomColumn[]
746
     */
747
    public function getCustomColumnValues($columns, $asArray = false) {
748
        $result = array();
749
750
        foreach ($columns as $lookup) {
751
            $col = CustomColumnType::createByLookup($lookup);
752
            if (!is_null($col)) {
753
                $cust = $col->getCustomByBook($this);
754
                if (!is_null($cust)) {
755
                    if ($asArray) {
756
                        array_push($result, $cust->toArray());
757
                    } else {
758
                        array_push($result, $cust);
759
                    }
760
                }
761
            }
762
        }
763
764
        return $result;
765
    }
766
}
767