Issues (459)

src/image/ImgStreamCache.php (6 issues)

1
<?php
2
3
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Image;
8
9
use Amenadiel\JpGraph\Util;
10
11
/**
12
 * @class ImgStreamCache
13
 * // Description: Handle caching of graphs to files. All image output goes
14
 * //              through this class
15
 */
16
class ImgStreamCache
17
{
18
    private $cache_dir;
19
    private $timeout = 0;
20
21
    // Infinite timeout
22
23
    /**
24
     * CONSTRUCTOR.
25
     *
26
     * @param mixed $aCacheDir
27
     */
28 21
    public function __construct($aCacheDir = CACHE_DIR)
29
    {
30 21
        $this->cache_dir = $aCacheDir;
31 21
    }
32
33
    /**
34
     * PUBLIC METHODS.
35
     *
36
     * @param mixed $aTimeout
37
     */
38
    // Specify a timeout (in minutes) for the file. If the file is older then the
39
    // timeout value it will be overwritten with a newer version.
40
    // If timeout is set to 0 this is the same as infinite large timeout and if
41
    // timeout is set to -1 this is the same as infinite small timeout
42 21
    public function SetTimeout($aTimeout)
43
    {
44 21
        $this->timeout = $aTimeout;
45 21
    }
46
47
    // Output image to browser and also write it to the cache
48 21
    public function PutAndStream($aImage, $aCacheFileName, $aInline, $aStrokeFileName)
49
    {
50
        // Check if we should always stroke the image to a file
51 21
        if (_FORCE_IMGTOFILE) {
52
            $aStrokeFileName = _FORCE_IMGDIR . Util\Helper::GenImgName();
53
        }
54
55 21
        if ($aStrokeFileName != '') {
56
            if ($aStrokeFileName == 'auto') {
57
                $aStrokeFileName = Util\Helper::GenImgName();
58
            }
59
60
            if (file_exists($aStrokeFileName)) {
61
                // Wait for lock (to make sure no readers are trying to access the image)
62
                $fd   = fopen($aStrokeFileName, 'w');
63
                $lock = flock($fd, LOCK_EX);
0 ignored issues
show
The assignment to $lock is dead and can be removed.
Loading history...
64
65
                // Since the image write routines only accepts a filename which must not
66
                // exist we need to delete the old file first
67
                if (!@unlink($aStrokeFileName)) {
68
                    $lock = flock($fd, LOCK_UN);
69
                    Util\JpGraphError::RaiseL(25111, $aStrokeFileName);
70
                    //(" Can't delete cached image $aStrokeFileName. Permission problem?");
71
                }
72
                $aImage->Stream($aStrokeFileName);
73
                $lock = flock($fd, LOCK_UN);
74
                fclose($fd);
75
            } else {
76
                $aImage->Stream($aStrokeFileName);
77
            }
78
79
            return;
80
        }
81
82 21
        if ($aCacheFileName != '' && USE_CACHE) {
83
            $aCacheFileName = $this->cache_dir . $aCacheFileName;
84
            if (file_exists($aCacheFileName)) {
85
                if (!$aInline) {
86
                    // If we are generating image off-line (just writing to the cache)
87
                    // and the file exists and is still valid (no timeout)
88
                    // then do nothing, just return.
89
                    $diff = time() - filemtime($aCacheFileName);
90
                    if ($diff < 0) {
91
                        Util\JpGraphError::RaiseL(25112, $aCacheFileName);
92
                        //(" Cached imagefile ($aCacheFileName) has file date in the future!!");
93
                    }
94
                    if ($this->timeout > 0 && ($diff <= $this->timeout * 60)) {
95
                        return;
96
                    }
97
                }
98
99
                // Wait for lock (to make sure no readers are trying to access the image)
100
                $fd   = fopen($aCacheFileName, 'w');
101
                $lock = flock($fd, LOCK_EX);
102
103
                if (!@unlink($aCacheFileName)) {
104
                    $lock = flock($fd, LOCK_UN);
105
                    Util\JpGraphError::RaiseL(25113, $aStrokeFileName);
106
                    //(" Can't delete cached image $aStrokeFileName. Permission problem?");
107
                }
108
                $aImage->Stream($aCacheFileName);
109
                $lock = flock($fd, LOCK_UN);
110
                fclose($fd);
111
            } else {
112
                $this->MakeDirs(dirname($aCacheFileName));
113
                if (!is_writeable(dirname($aCacheFileName))) {
114
                    Util\JpGraphError::RaiseL(25114, $aCacheFileName);
115
                    //('PHP has not enough permissions to write to the cache file '.$aCacheFileName.'. Please make sure that the user running PHP has write permission for this file if you wan to use the cache system with JpGraph.');
116
                }
117
                $aImage->Stream($aCacheFileName);
118
            }
119
120
            $res = true;
121
            // Set group to specified
122
            if (CACHE_FILE_GROUP != '') {
0 ignored issues
show
The condition Amenadiel\JpGraph\Image\CACHE_FILE_GROUP != '' is always true.
Loading history...
123
                $res = @chgrp($aCacheFileName, CACHE_FILE_GROUP);
124
            }
125
            if (CACHE_FILE_MOD != '') {
0 ignored issues
show
The condition Amenadiel\JpGraph\Image\CACHE_FILE_MOD != '' is always true.
Loading history...
126
                $res = @chmod($aCacheFileName, CACHE_FILE_MOD);
127
            }
128
            if (!$res) {
129
                Util\JpGraphError::RaiseL(25115, $aStrokeFileName);
130
                //(" Can't set permission for cached image $aStrokeFileName. Permission problem?");
131
            }
132
133
            $aImage->Destroy();
134
            if ($aInline) {
135
                if ($fh = @fopen($aCacheFileName, 'rb')) {
136
                    $aImage->Headers();
137
                    fpassthru($fh);
138
139
                    return;
140
                }
141
                Util\JpGraphError::RaiseL(25116, $aFile); //(" Cant open file from cache [$aFile]");
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $aFile seems to be never defined.
Loading history...
142
            }
143 21
        } elseif ($aInline) {
144 21
            $aImage->Headers();
145 21
            $aImage->Stream();
146
147 21
            return;
148
        }
149
    }
150
151
    public function IsValid($aCacheFileName)
152
    {
153
        $aCacheFileName = $this->cache_dir . $aCacheFileName;
154
        if (USE_CACHE && file_exists($aCacheFileName)) {
155
            $diff = time() - filemtime($aCacheFileName);
156
            if ($this->timeout > 0 && ($diff > $this->timeout * 60)) {
157
                return false;
158
            }
159
160
            return true;
161
        }
162
163
        return false;
164
    }
165
166
    public function StreamImgFile($aImage, $aCacheFileName)
167
    {
168
        $aCacheFileName = $this->cache_dir . $aCacheFileName;
169
        if ($fh = @fopen($aCacheFileName, 'rb')) {
170
            $lock = flock($fh, LOCK_SH);
0 ignored issues
show
The assignment to $lock is dead and can be removed.
Loading history...
171
            $aImage->Headers();
172
            fpassthru($fh);
173
            $lock = flock($fh, LOCK_UN);
174
            fclose($fh);
175
176
            return true;
177
        }
178
        Util\JpGraphError::RaiseL(25117, $aCacheFileName); //(" Can't open cached image \"$aCacheFileName\" for reading.");
179
    }
180
181
    // Check if a given image is in cache and in that case
182
    // pass it directly on to web browser. Return false if the
183
    // image file doesn't exist or exists but is to old
184
    public function GetAndStream($aImage, $aCacheFileName)
185
    {
186
        if ($this->Isvalid($aCacheFileName)) {
187
            return $this->StreamImgFile($aImage, $aCacheFileName);
188
        } else {
189
            return false;
190
        }
191
    }
192
193
    /**
194
     * PRIVATE METHODS.
195
     *
196
     * @param mixed $aFile
197
     */
198
199
    // Create all necessary directories in a path
200
    public function MakeDirs($aFile)
201
    {
202
        $dirs = [];
203
        // In order to better work when open_basedir is enabled
204
        // we do not create directories in the root path
205
        while ($aFile != '/' && !(file_exists($aFile))) {
206
            $dirs[] = $aFile . '/';
207
            $aFile  = dirname($aFile);
208
        }
209
        for ($i = safe_count($dirs) - 1; $i >= 0; --$i) {
210
            if (!@mkdir($dirs[$i], 0777)) {
211
                Util\JpGraphError::RaiseL(25118, $aFile); //(" Can't create directory $aFile. Make sure PHP has write permission to this directory.");
212
            }
213
            // We also specify mode here after we have changed group.
214
            // This is necessary if Apache user doesn't belong the
215
            // default group and hence can't specify group permission
216
            // in the previous mkdir() call
217
            if (CACHE_FILE_GROUP != '') {
218
                $res = true;
0 ignored issues
show
The assignment to $res is dead and can be removed.
Loading history...
219
                $res = @chgrp($dirs[$i], CACHE_FILE_GROUP);
220
                $res = @chmod($dirs[$i], 0777);
221
                if (!$res) {
222
                    Util\JpGraphError::RaiseL(25119, $aFile); //(" Can't set permissions for $aFile. Permission problems?");
223
                }
224
            }
225
        }
226
227
        return true;
228
    }
229
} // @class Cache
230