Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
/*
3
pCache - speed up the rendering by caching up the pictures
4
 
5
Version     : 2.1.4
6
Made by     : Jean-Damien POGOLOTTI
7
Last Update : 19/01/2014
8
 
9
This file can be distributed under the license you can find at :
10
 
11
http://www.pchart.net/license
12
 
13
You can find the whole class documentation on the pChart web site.
14
*/
15
/* pData class definition */
16
 
17
class pCache
18
{
19
	var $CacheFolder;
20
	var $CacheIndex;
21
	var $CacheDB;
22
	/* Class creator */
23
	function __construct(array $Settings = [])
24
	{
25
 
26
		#if (!is_dir("cache")){
27
		#	mkdir("cache", 0775);
28
		#}
29
 
30
		$this->CacheFolder = isset($Settings["CacheFolder"]) ? $Settings["CacheFolder"] : "cache";
31
 
32
		$this->CacheIndex = isset($Settings["CacheIndex"]) ? $Settings["CacheIndex"] : "index.db";
33
		$this->CacheIndex = $this->CacheFolder . "/" . $this->CacheIndex;
34
 
35
		$this->CacheDB = isset($Settings["CacheDB"]) ? $Settings["CacheDB"] : "cache.db";
36
		$this->CacheDB = $this->CacheFolder . "/" . $this->CacheDB;
37
 
38
		if (!file_exists($this->CacheIndex)) {
39
			touch($this->CacheIndex);
40
		}
41
 
42
		if (!file_exists($this->CacheDB)) {
43
			touch($this->CacheDB);
44
		}
45
	}
46
 
47
	/* Flush the cache contents */
48
	function flush()
49
	{
50
		file_put_contents($this->CacheIndex, "");
51
		file_put_contents($this->CacheDB, "");
52
	}
53
 
54
	/* Return the MD5 of the data array to clearly identify the chart */
55
	function getHash($Data, $Marker = "")
56
	{
57
		return (md5($Marker . serialize($Data->Data)));
58
	}
59
 
60
	/* Write the generated picture to the cache */
61
	function writeToCache($ID, $pChartObject)
62
	{
63
		/* Compute the paths */
64
		$TemporaryFile = $this->CacheFolder . "/tmp_" . rand(0, 1000) . ".png";
65
 
66
		/* Flush the picture to a temporary file */
67
		imagepng($pChartObject->Picture, $TemporaryFile);
68
		/* Retrieve the files size */
69
		$PictureSize = filesize($TemporaryFile);
70
		$DBSize = filesize($this->CacheDB);
71
		/* Save the index */
72
		$Handle = fopen($this->CacheIndex, "a");
73
		fwrite($Handle, $ID . "," . $DBSize . "," . $PictureSize . "," . time() . ",0      \r\n");
74
		fclose($Handle);
75
		/* Get the picture raw contents */
76
		$Handle = fopen($TemporaryFile, "r");
77
		$Raw = fread($Handle, $PictureSize);
78
		fclose($Handle);
79
		/* Save the picture in the solid database file */
80
		$Handle = fopen($this->CacheDB, "a");
81
		fwrite($Handle, $Raw);
82
		fclose($Handle);
83
		/* Remove temporary file */
84
		unlink($TemporaryFile);
85
	}
86
 
87
	/* Remove object older than the specified TS */
88
	function removeOlderThan($Expiry)
89
	{
90
		$this->dbRemoval(["Expiry" => $Expiry]);
91
	}
92
 
93
	/* Remove an object from the cache */
94
	function remove($ID)
95
	{
96
		$this->dbRemoval(["Name" => $ID]);
97
	}
98
 
99
	/* Remove with specified criterias */
100
	function dbRemoval($Settings)
101
	{
102
		$ID = isset($Settings["Name"]) ? $Settings["Name"] : NULL;
103
		$Expiry = isset($Settings["Expiry"]) ? $Settings["Expiry"] : -(24 * 60 * 60);
104
		$TS = time() - $Expiry;
105
		/* Compute the paths */
106
		$DatabaseTemp = $this->CacheDB . ".tmp";
107
		$IndexTemp = $this->CacheIndex . ".tmp";
108
		/* Single file removal */
109
		if ($ID != NULL) {
110
			/* If it's not in the cache DB, go away */
111
			if (!$this->isInCache($ID, TRUE)) {
112
				return 0;
113
			}
114
		}
115
 
116
		/* Create the temporary files */
117
		if (!file_exists($DatabaseTemp)) {
118
			touch($DatabaseTemp);
119
		}
120
 
121
		if (!file_exists($IndexTemp)) {
122
			touch($IndexTemp);
123
		}
124
 
125
		/* Open the file handles */
126
		$IndexHandle = fopen($this->CacheIndex, "r");
127
		$IndexTempHandle = fopen($IndexTemp, "w");
128
		$DBHandle = fopen($this->CacheDB, "r");
129
		$DBTempHandle = fopen($DatabaseTemp, "w");
130
		/* Remove the selected ID from the database */
131
		if ($IndexHandle && $IndexTempHandle && $DBHandle && $DBTempHandle) {
132
			while (!feof($IndexHandle)) {
133
				$Entry = fgets($IndexHandle, 4096);
134
				$Entry = str_replace("\r", "", $Entry);
135
				$Entry = str_replace("\n", "", $Entry);
136
				$Settings = explode(",", $Entry);
137
				if ($Entry != "") {
138
					$PicID = $Settings[0];
139
					$DBPos = $Settings[1];
140
					$PicSize = $Settings[2];
141
					$GeneratedTS = $Settings[3];
142
					$Hits = $Settings[4];
143
					if ($Settings[0] != $ID && $GeneratedTS > $TS) {
144
						$CurrentPos = ftell($DBTempHandle);
145
						fwrite($IndexTempHandle, $PicID . "," . $CurrentPos . "," . $PicSize . "," . $GeneratedTS . "," . $Hits . "\r\n");
146
						fseek($DBHandle, $DBPos);
147
						$Picture = fread($DBHandle, $PicSize);
148
						fwrite($DBTempHandle, $Picture);
149
					}
150
				}
151
			}
152
			/* Close the handles */
153
			fclose($IndexHandle);
154
			fclose($IndexTempHandle);
155
			fclose($DBHandle);
156
			fclose($DBTempHandle);
157
		}
158
 
159
		/* Remove the prod files */
160
		unlink($this->CacheDB);
161
		unlink($this->CacheIndex);
162
		/* Swap the temp & prod DB */
163
		rename($DatabaseTemp, $this->CacheDB);
164
		rename($IndexTemp, $this->CacheIndex);
165
	}
166
 
167
	function isInCache($ID, $Verbose = FALSE, $UpdateHitsCount = FALSE)
168
	{
169
		/* Search the picture in the index file */
170
		$Handle = fopen($this->CacheIndex, "r");
171
		if ($Handle){
172
			while (!feof($Handle)) {
173
				$IndexPos = ftell($Handle);
174
				$Entry = fgets($Handle, 4096);
175
				if ($Entry != "") {
176
					$Settings = explode(",", $Entry);
177
					$PicID = $Settings[0];
178
					if ($PicID == $ID) {
179
						fclose($Handle);
180
						$DBPos = $Settings[1];
181
						$PicSize = $Settings[2];
182
						$GeneratedTS = $Settings[3];
183
						$Hits = intval($Settings[4]);
184
						if ($UpdateHitsCount) {
185
							$Hits++;
186
							if (strlen($Hits) < 7) {
187
								$Hits = $Hits . str_repeat(" ", 7 - strlen($Hits));
188
							}
189
 
190
							$Handle = fopen($this->CacheIndex, "r+");
191
							fseek($Handle, $IndexPos);
192
							fwrite($Handle, $PicID . "," . $DBPos . "," . $PicSize . "," . $GeneratedTS . "," . $Hits . "\r\n");
193
							fclose($Handle);
194
						}
195
 
196
						if ($Verbose) {
197
							return ["DBPos" => $DBPos,"PicSize" => $PicSize,"GeneratedTS" => $GeneratedTS,"Hits" => $Hits];
198
						} else {
199
							return TRUE;
200
						}
201
					}
202
				}
203
			}
204
 
205
			fclose($Handle);
206
		}
207
 
208
		/* Picture isn't in the cache */
209
		return FALSE;
210
	}
211
 
212
	/* Automatic output method based on the calling interface */
213
	function autoOutput($ID, $Destination = "output.png")
214
	{
215
		if (php_sapi_name() == "cli") {
216
			$this->saveFromCache($ID, $Destination);
217
		} else {
218
			$this->strokeFromCache($ID);
219
		}
220
	}
221
 
222
	function strokeFromCache($ID)
223
	{
224
		/* Get the raw picture from the cache */
225
		$Picture = $this->getFromCache($ID);
226
		/* Do we have a hit? */
227
		if ($Picture == FALSE) {
228
			return FALSE;
229
		}
230
 
231
		header('Content-type: image/png');
232
		echo $Picture;
233
	}
234
 
235
	function saveFromCache($ID, $Destination)
236
	{
237
		/* Get the raw picture from the cache */
238
		$Picture = $this->getFromCache($ID);
239
		/* Do we have a hit? */
240
		if ($Picture == FALSE) {
241
			return FALSE;
242
		}
243
 
244
		/* Flush the picture to a file */
245
		file_put_contents($Destination, $Picture);
246
	}
247
 
248
	function getFromCache($ID)
249
	{
250
		/* Lookup for the picture in the cache */
251
		$CacheInfo = $this->isInCache($ID, TRUE, TRUE);
252
		/* Not in the cache */
253
		if (!$CacheInfo) {
254
			# Momchil: fread returns FALSE on failure. Return FALSE here as well and not NULL
255
			return FALSE;
256
		}
257
 
258
		/* Get the database extended information */
259
		$DBPos = $CacheInfo["DBPos"];
260
		$PicSize = $CacheInfo["PicSize"];
261
		/* Extract the picture from the solid cache file */
262
		$Handle = fopen($this->CacheDB, "r");
263
		fseek($Handle, $DBPos);
264
		$Picture = fread($Handle, $PicSize);
265
		fclose($Handle);
266
		/* Return back the raw picture data */
267
		return $Picture;
268
	}
269
}
270
 
271
?>