Completed
Push — master ( 2cc4d6...bb97fd )
by Sébastien
03:24
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * COPS (Calibre OPDS PHP Server)
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 * @author     Sébastien Lucas <[email protected]>
7
 */
8
9
    require_once dirname(__FILE__) . '/config.php';
10
    require_once dirname(__FILE__) . '/base.php';
11
12
    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...
13
14
    if ($config['cops_fetch_protect'] == '1') {
15
        session_start();
16
        if (!isset($_SESSION['connected'])) {
17
            notFound();
18
            return;
19
        }
20
    }
21
22
    $expires = 60*60*24*14;
23
    header('Pragma: public');
24
    header('Cache-Control: maxage=' . $expires);
25
    header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$expires) . ' GMT');
26
    $bookId = getURLParam('id', NULL);
27
    $type   = getURLParam('type', 'jpg');
28
    $idData = getURLParam('data', NULL);
29
    if (is_null($bookId)) {
30
        $book = Book::getBookByDataId($idData);
31
    } else {
32
        $book = Book::getBookById($bookId);
33
    }
34
35
    if (!$book) {
36
        notFound ();
37
        return;
38
    }
39
40
    if ($book && ($type == 'jpg' || empty ($config['calibre_internal_directory']))) {
41
        if ($type == 'jpg') {
42
            $file = $book->getFilePath($type);
43
        } else {
44
            $file = $book->getFilePath($type, $idData);
45
        }
46
        if (is_null($file) || !file_exists($file)) {
47
            notFound();
48
            return;
49
        }
50
    }
51
52
    switch ($type)
53
    {
54
        case 'jpg':
55
            header('Content-Type: image/jpeg');
56
            //by default, we don't cache
57
            $thumbnailCacheFullpath = null;
58
            if ( isset($config['cops_thumbnail_cache_directory']) && $config['cops_thumbnail_cache_directory'] !== '' ) {
59
                $thumbnailCacheFullpath = $config['cops_thumbnail_cache_directory'];
60
                //if multiple databases, add a subfolder with the database ID
61
                $thumbnailCacheFullpath .= !is_null(GetUrlParam (DB)) ? 'db-' . GetUrlParam (DB) . DIRECTORY_SEPARATOR : '';
62
                //when there are lots of thumbnails, it's better to save files in subfolders, so if the book's uuid is
63
                //"01234567-89ab-cdef-0123-456789abcdef", we will save the thumbnail in .../0/12/34567-89ab-cdef-0123-456789abcdef-...
64
                $thumbnailCacheFullpath .= substr($book->uuid, 0, 1) . DIRECTORY_SEPARATOR . substr($book->uuid, 1, 2) . DIRECTORY_SEPARATOR;
65
                //check if cache folder exists or create it
66
                if ( file_exists($thumbnailCacheFullpath) || mkdir($thumbnailCacheFullpath, 0700, true) ) {
67
                    //we name the thumbnail from the book's uuid and it's dimensions (width and/or height)
68
                    $thumbnailCacheName = substr($book->uuid, 3) . '-' . getURLParam('width') . 'x' . getURLParam('height') . '.jpg';
69
                    $thumbnailCacheFullpath = $thumbnailCacheFullpath . $thumbnailCacheName;
70
                } else {
71
                    //error creating the folder, so we don't cache
72
                    $thumbnailCacheFullpath = null;
73
                }
74
            }
75
76
            if ( $thumbnailCacheFullpath !== null && file_exists($thumbnailCacheFullpath) ) {
77
                //return the already cached thumbnail
78
                readfile( $thumbnailCacheFullpath );
79
                return;
80
            }
81
82
            if ($book->getThumbnail (getURLParam('width'), getURLParam('height'), $thumbnailCacheFullpath)) {
83
                //if we don't cache the thumbnail, imagejpeg() in $book->getThumbnail() already return the image data
84
                if ( $thumbnailCacheFullpath === null ) {
85
                    // The cover had to be resized
86
                    return;
87
                } else {
88
                    //return the just cached thumbnail
89
                    readfile( $thumbnailCacheFullpath );
90
                    return;
91
                }
92
            }
93
            break;
94
        default:
95
            $data = $book->getDataById($idData);
96
            header('Content-Type: ' . $data->getMimeType());
97
            break;
98
    }
99
    $file = $book->getFilePath($type, $idData, true);
100
    if ($type == 'epub' && $config['cops_update_epub-metadata']) {
101
        $book->getUpdatedEpub($idData);
102
        return;
103
    }
104
    if ($type == 'jpg') {
105
        header('Content-Disposition: filename="' . basename($file) . '"');
106
    } else {
107
        header('Content-Disposition: attachment; filename="' . basename($file) . '"');
108
    }
109
110
    $dir = $config['calibre_internal_directory'];
111
    if (empty($config['calibre_internal_directory'])) {
112
        $dir = Base::getDbDirectory();
113
    }
114
115
    if (empty($config['cops_x_accel_redirect'])) {
116
        $filename = $dir . $file;
117
        $fp = fopen($filename, 'rb');
118
        header('Content-Length: ' . filesize($filename));
119
        fpassthru($fp);
120
    } else {
121
        header($config['cops_x_accel_redirect'] . ': ' . $dir . $file);
122
    }
123