Workaround buggy mime_content_type on php 5.2.0+etch10 (not tested on other version).
[platal.git] / classes / plupload.php
CommitLineData
abe7e055 1<?php
2/***************************************************************************
179afa7f 3 * Copyright (C) 2003-2008 Polytechnique.org *
abe7e055 4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22/** Class to store per user and per category files
23 */
24class PlUpload
25{
26 private $forlife;
27 private $category;
28 private $file_id;
29
30 private $filename;
31 private $type;
32
380d35f4
FB
33 static public $lastError;
34
abe7e055 35 /** For images
36 */
37 private $x;
38 private $y;
39
40 public function __construct($forlife, $category, $filename = null)
41 {
42 $this->file_id = $filename;
43 $this->category = $category;
44 $this->forlife = $forlife;
45 $this->filename = $this->makeFilename($this->file_id);
46 $this->checkContentType();
47 }
48
49 private function makeFilename($file_id)
50 {
51 global $globals;
52 $filename = $globals->spoolroot . '/spool/uploads/temp/';
53 if (!file_exists($filename)) {
54 if (!mkdir($filename)) {
55 trigger_error('can\'t create upload directory: ' . $filename, E_USER_ERROR);
56 }
57 }
fac5d9eb 58 $filename .= $this->forlife . '--' . $this->category;
abe7e055 59 if ($file_id) {
fac5d9eb 60 $filename .= '--' . $file_id;
abe7e055 61 }
62 return $filename;
63 }
64
65 private function checkContentType()
66 {
67 if ($this->exists()) {
68 $this->type = trim(mime_content_type($this->filename));
fa3300aa
FB
69 if ($this->type == 'text/plain') { // Workaround a bug of php 5.2.0+etch10 (mime_content_type fallback is 'text/plain')
70 $this->type = trim(exec("file -bi " . escapeshellarg($this->filename)));
71 }
abe7e055 72 }
73 }
74
75 public function upload(array &$file)
76 {
380d35f4
FB
77 if (@$file['error']) {
78 PlUpload::$lastError = 'Erreur de téléchargement de ' . $file['name'] . ' : ';
79 switch ($file['error']) {
80 case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE:
81 PlUpload::$lastError .= 'le fichier est trop gros (limite : ' . ini_get('upload_max_filesize') . ')';
82 break;
83 case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_NO_FILE:
84 PlUpload::$lastError .= 'le fichier n\'a pas été transmis intégralement';
85 break;
86 default:
87 PlUpload::$lastError .= 'erreur interne';
88 break;
89 }
90 return false;
91 }
abe7e055 92 if (!is_uploaded_file($file['tmp_name'])) {
93 return false;
94 } else if (!move_uploaded_file($file['tmp_name'], $this->filename)) {
95 return false;
96 }
eaf30d86 97 $this->checkContentType();
abe7e055 98 return true;
99 }
100
101 public function copyFrom($filename)
102 {
103 if (!copy($filename, $this->filename)) {
104 return false;
105 }
106 $this->checkContentType();
107 return true;
108 }
109
110 public function download($url)
111 {
02838718 112 if (!$url || @parse_url($url) === false) {
113 trigger_error('malformed URL given', E_USER_NOTICE);
114 return false;
115 }
abe7e055 116 $data = file_get_contents($url);
117 if (!$data) {
118 return false;
119 }
120 if (!file_put_contents($this->filename, $data)) {
121 return false;
122 }
123 $this->checkContentType();
124 return true;
125 }
126
127 static public function &get(array &$file, $forlife, $category, $uniq = false)
128 {
129 $upload = new PlUpload($forlife, $category, $uniq ? null : $file['name']);
130 if (!$upload->upload($file)) {
131 $upload = null;
132 }
133 return $upload;
134 }
135
136 public function rm()
137 {
138 @unlink($this->filename);
f62bd784 139 @clearstatcache();
abe7e055 140 }
141
142 public function rename($fn)
143 {
144 if (!$this->file_id) {
145 return false;
146 }
147 $filename = $this->makeFilename($fn);
148 if (rename($this->filename)) {
149 $this->filename = $filename;
150 $this->file_id = $fn;
151 clearstatcache();
152 return true;
153 }
154 return false;
155 }
156
157 public function exists()
158 {
159 return file_exists($this->filename);
160 }
161
da419622 162 static public function listRawFiles($forlife = '*', $category = '*', $uniq = false, $basename = false)
abe7e055 163 {
164 global $globals;
165 $filename = $globals->spoolroot . '/spool/uploads/temp/';
fac5d9eb 166 $filename .= $forlife . '--' . $category;
da419622 167 if (!$uniq) {
fac5d9eb 168 $filename .= '--*';
da419622 169 }
abe7e055 170 $files = glob($filename);
171 if ($basename) {
da419622 172 $files = array_map('basename', $files);
173 }
174 return $files;
175 }
176
177 static public function listFilenames($forlife = '*', $category = '*')
178 {
179 $files = PlUpload::listRawFiles($forlife, $category, false, true);
180 foreach ($files as &$name) {
fac5d9eb 181 list($forlife, $cat, $fn) = explode('--', $name, 3);
da419622 182 $name = $fn;
abe7e055 183 }
184 return $files;
185 }
186
da419622 187 static public function &listFiles($forlife = '*', $category = '*', $uniq = false)
188 {
189 $res = array();
190 $files = PlUpload::listRawFiles($forlife, $category, $uniq, true);
191 foreach ($files as $name) {
fac5d9eb 192 list($forlife, $cat, $fn) = explode('--', $name, 3);
da419622 193 $res[$fn] = new PlUpload($forlife, $cat, $fn);
194 }
195 return $res;
196 }
197
198 static public function clear($user = '*', $category = '*', $uniq = false)
abe7e055 199 {
da419622 200 $files = PlUpload::listRawFiles($user, $category, $uniq, false);
201 array_map('unlink', $files);
abe7e055 202 }
203
204 public function contentType()
205 {
206 return $this->type;
207 }
208
02838718 209 public function isType($type, $subtype = null)
210 {
211 list($mytype, $mysubtype) = explode('/', $this->type);
212 if ($mytype != $type || ($subtype && $mysubtype != $subtype)) {
213 return false;
214 }
215 return true;
216 }
217
abe7e055 218 public function imageInfo()
219 {
02838718 220 static $map;
221 if (!isset($map)) {
9e1b4320 222 $tmpmap = array (IMG_GIF => 'gif', IMG_JPG => 'jpeg', IMG_PNG => 'png', IMG_WBMP => 'bmp', IMG_XPM => 'xpm');
223 $map = array();
224 $supported = imagetypes();
225 foreach ($tmpmap as $type=>$mime) {
226 if ($supported & $type) {
227 $map[$type] = $mime;
228 }
229 }
02838718 230 }
231 $array = getimagesize($this->filename);
232 $array[2] = @$map[$array[2]];
233 if (!$array[2]) {
ff95a302
FB
234 list($image, $type) = explode('/', $array['mime']);
235 $array[2] = $type;
236 }
237 if (!$array[2]) {
02838718 238 trigger_error('unknown image type', E_USER_NOTICE);
239 return null;
240 }
241 return $array;
abe7e055 242 }
243
244 public function resizeImage($max_x = -1, $max_y = -1, $min_x = 0, $min_y = 0, $maxsize = -1)
245 {
246 if (!$this->exists() || strpos($this->type, 'image/') !== 0) {
247 trigger_error('not an image', E_USER_NOTICE);
248 return false;
249 }
250 $image_infos = $this->imageInfo();
02838718 251 if (!$image_infos) {
abe7e055 252 trigger_error('invalid image', E_USER_NOTICE);
253 return false;
254 }
255 list($this->x, $this->y, $mimetype) = $image_infos;
abe7e055 256 if ($max_x == -1) {
257 $max_x = $this->x;
258 }
259 if ($max_y == -1) {
260 $max_y = $this->y;
261 }
262 if ($maxsize == -1) {
263 $maxsize = filesize($this->filename);
264 }
265 if (filesize($this->filename) > $maxsize || $this->x > $max_x || $this->y > $max_y
266 || $this->x < $min_x || $this->y < $min_y) {
267 $img = imagecreatefromstring(file_get_contents($this->filename));
268 if (!$img) {
269 trigger_error('too large image, can\'t be resized', E_USER_NOTICE);
270 return false;
271 }
272
273 $nx = $this->x;
274 $ny = $this->y;
275 if ($nx > $max_x) {
276 $ny = intval($ny*$max_x/$nx);
277 $nx = $max_x;
278 }
279 if ($ny > $max_y) {
280 $nx = intval($nx*$max_y/$ny);
281 $ny = $max_y;
282 }
283 if ($nx < $min_x) {
284 $ny = intval($ny*$min_x/$nx);
285 $nx = $min_x;
286 }
287 if ($ny < $min_y) {
288 $nx = intval($nx * $min_y/$ny);
289 $ny = $min_y;
290 }
291
292 $comp = 90;
293 do {
294 $img2 = imagecreatetruecolor($nx, $ny);
295 imagecopyresampled($img2, $img, 0, 0, 0, 0, $nx, $ny, $this->x, $this->y);
296 imagejpeg($img2, $this->filename, $comp);
297 $comp --;
298 clearstatcache();
299 } while (filesize($this->filename) > $maxsize && $comp > 0);
300 $this->type = 'image/jpeg';
301 $this->x = $nx;
302 $this->y = $ny;
303 }
304 return true;
305 }
306
307 public function getContents()
308 {
309 if ($this->exists()) {
310 return file_get_contents($this->filename);
311 }
312 return null;
313 }
314}
315// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
316?>