|
1 <?php |
|
2 // $Id: page.inc,v 1.10.2.21 2009/02/20 00:44:05 ufku Exp $ |
|
3 |
|
4 /** |
|
5 * q = imce. |
|
6 */ |
|
7 function imce_page() { |
|
8 $jsop = isset($_GET['jsop']) ? $_GET['jsop'] : NULL; |
|
9 print theme('imce_page', imce_content($GLOBALS['user'], $jsop)); |
|
10 exit(); |
|
11 } |
|
12 |
|
13 /** |
|
14 * q = user/x/imce. |
|
15 */ |
|
16 function imce_user_page($account) { |
|
17 drupal_set_title($account->name); |
|
18 $jsop = isset($_GET['jsop']) ? $_GET['jsop'] : NULL; |
|
19 return imce_content($account, $jsop); |
|
20 } |
|
21 |
|
22 /** |
|
23 * Content of the file browser. |
|
24 */ |
|
25 function imce_content($user, $jsop = '') { |
|
26 |
|
27 //execute ajax calls. |
|
28 if ($jsop) { |
|
29 return imce_js($user, $jsop); |
|
30 } |
|
31 |
|
32 //initiate configuration profile |
|
33 if (!$imce = imce_initiate_profile($user)) { |
|
34 return ''; |
|
35 } |
|
36 imce_process_profile($imce);//get active directory content |
|
37 |
|
38 //Before creating the content let's add main files required for imce to function properly. |
|
39 drupal_add_js('misc/jquery.form.js'); |
|
40 drupal_add_js(drupal_get_path('module', 'imce') .'/js/imce.js'); |
|
41 |
|
42 //process forms. |
|
43 //reference imce inside an array so it will stay referenced during argument copy of drupal_get_form |
|
44 //when php4-support drops(dr7?), use an object with no reference. |
|
45 $imce_ref = array('imce' => &$imce); |
|
46 $forms = ''; |
|
47 |
|
48 if (!$imce['error']) { |
|
49 //process file upload. |
|
50 if (imce_perm_exists($imce, 'upload')) { |
|
51 $forms .= drupal_get_form('imce_upload_form', $imce_ref); |
|
52 } |
|
53 //process file operations. |
|
54 $forms .= drupal_get_form('imce_fileop_form', $imce_ref); |
|
55 } |
|
56 |
|
57 //run custom content functions. possible to insert extra forms. content is invisible when js is enabled. |
|
58 foreach (variable_get('imce_custom_content', array()) as $func => $state) { |
|
59 if ($state && function_exists($func) && $output = $func($imce)) { |
|
60 $forms .= $output; |
|
61 } |
|
62 } |
|
63 |
|
64 $content = theme('imce_content', imce_create_tree($imce), $forms, $imce_ref); |
|
65 |
|
66 //make necessary changes for js conversion |
|
67 $imce['dir'] = str_replace('%2F', '/', rawurlencode($imce['dir'])); |
|
68 unset($imce['files'], $imce['name'], $imce['directories'], $imce['subdirectories'], $imce['filesize'], $imce['quota'], $imce['tuquota'], $imce['thumbnails'], $imce['uid']); |
|
69 |
|
70 drupal_add_js($imce_ref, 'setting'); |
|
71 |
|
72 return $content; |
|
73 } |
|
74 |
|
75 /** |
|
76 * Ajax operations. q=imce&jsop={op} |
|
77 */ |
|
78 function imce_js($user, $jsop = '') { |
|
79 $response = array(); |
|
80 |
|
81 //data |
|
82 if ($imce = imce_initiate_profile($user)) { |
|
83 imce_process_profile($imce); |
|
84 if (!$imce['error']) { |
|
85 include_once './'. drupal_get_path('module', 'imce') .'/inc/js.inc'; |
|
86 if (function_exists($func = 'imce_js_'. $jsop)) { |
|
87 $response['data'] = $func($imce); |
|
88 } |
|
89 } |
|
90 } |
|
91 //messages |
|
92 $response['messages'] = drupal_get_messages(); |
|
93 |
|
94 //for upload we must return plain text header. |
|
95 drupal_set_header('Content-Type: text/'. ($jsop == 'upload' ? 'html' : 'javascript') .'; charset=utf-8'); |
|
96 print drupal_to_js($response); |
|
97 exit(); |
|
98 } |
|
99 |
|
100 /** |
|
101 * Upload form. |
|
102 */ |
|
103 function imce_upload_form(&$form_state, $ref) { |
|
104 $imce =& $ref['imce']; |
|
105 $form['imce'] = array( |
|
106 '#type' => 'file', |
|
107 '#title' => t('File'), |
|
108 '#size' => 30, |
|
109 '#prefix' => '<div class="container-inline">', |
|
110 ); |
|
111 $form['upload'] = array( |
|
112 '#type' => 'submit', |
|
113 '#value' => t('Upload'), |
|
114 '#submit' => $imce['perm']['upload'] ? array('imce_upload_submit') : NULL,//permission for submission |
|
115 '#suffix' => '</div>', |
|
116 ); |
|
117 if (!empty($imce['thumbnails'])) { |
|
118 $form['thumbnails'] = array( |
|
119 '#type' => 'checkboxes', |
|
120 '#title' => t('Create thumbnails'), |
|
121 '#options' => imce_thumbnail_options($imce['thumbnails']), |
|
122 ); |
|
123 } |
|
124 $form = array('fset_upload' => array('#type' => 'fieldset', '#title' => t('Upload file')) + $form); |
|
125 $form['#attributes']['enctype'] = 'multipart/form-data'; |
|
126 $form['#action'] = $imce['url']; |
|
127 return $form; |
|
128 } |
|
129 |
|
130 /** |
|
131 * File operations form. |
|
132 */ |
|
133 function imce_fileop_form(&$form_state, $ref) { |
|
134 $imce =& $ref['imce']; |
|
135 $form['filenames'] = array( |
|
136 '#type' => 'textfield', |
|
137 '#title' => t('Selected files'), |
|
138 '#maxlength' => $imce['filenum'] ? $imce['filenum']*255 : NULL, |
|
139 ); |
|
140 |
|
141 //thumbnail |
|
142 if (!empty($imce['thumbnails']) && imce_perm_exists($imce, 'thumb')) { |
|
143 $form['fset_thumb'] = array( |
|
144 '#type' => 'fieldset', |
|
145 '#title' => t('Thumbnails'), |
|
146 ) + imce_thumb_form($imce); |
|
147 } |
|
148 |
|
149 //delete |
|
150 if (imce_perm_exists($imce, 'delete')) { |
|
151 $form['fset_delete'] = array( |
|
152 '#type' => 'fieldset', |
|
153 '#title' => t('Delete'), |
|
154 ) + imce_delete_form($imce); |
|
155 } |
|
156 |
|
157 //resize |
|
158 if (imce_perm_exists($imce, 'resize')) { |
|
159 $form['fset_resize'] = array( |
|
160 '#type' => 'fieldset', |
|
161 '#title' => t('Resize'), |
|
162 ) + imce_resize_form($imce); |
|
163 } |
|
164 |
|
165 $form['#action'] = $imce['url']; |
|
166 return $form; |
|
167 } |
|
168 |
|
169 /** |
|
170 * Thumbnail form. |
|
171 */ |
|
172 function imce_thumb_form(&$imce) { |
|
173 $form['thumbnails'] = array( |
|
174 '#type' => 'checkboxes', |
|
175 '#title' => t('Thumbnails'), |
|
176 '#options' => imce_thumbnail_options($imce['thumbnails']), |
|
177 ); |
|
178 $form['thumb'] = array( |
|
179 '#type' => 'submit', |
|
180 '#value' => t('Create thumbnails'), |
|
181 '#submit' => $imce['perm']['thumb'] ? array('imce_thumb_submit') : NULL,//permission for submission |
|
182 ); |
|
183 return $form; |
|
184 } |
|
185 |
|
186 /** |
|
187 * Delete form. |
|
188 */ |
|
189 function imce_delete_form(&$imce) { |
|
190 $form['delete'] = array( |
|
191 '#type' => 'submit', |
|
192 '#value' => t('Delete'), |
|
193 '#submit' => $imce['perm']['delete'] ? array('imce_delete_submit') : NULL,//permission for submission |
|
194 ); |
|
195 return $form; |
|
196 } |
|
197 |
|
198 /** |
|
199 * Resizing form. |
|
200 */ |
|
201 function imce_resize_form(&$imce) { |
|
202 $form['width'] = array( |
|
203 '#type' => 'textfield', |
|
204 '#title' => t('Width x Height'), |
|
205 '#size' => 5, |
|
206 '#maxlength' => 4, |
|
207 '#prefix' => '<div class="container-inline">', |
|
208 ); |
|
209 $form['height'] = array( |
|
210 '#type' => 'textfield', |
|
211 '#size' => 5, |
|
212 '#maxlength' => 4, |
|
213 '#prefix' => 'x', |
|
214 ); |
|
215 $form['resize'] = array( |
|
216 '#type' => 'submit', |
|
217 '#value' => t('Resize'), |
|
218 '#submit' => $imce['perm']['resize'] ? array('imce_resize_submit') : NULL,//permission for submission |
|
219 '#suffix' => '</div>', |
|
220 ); |
|
221 $form['copy'] = array( |
|
222 '#type' => 'checkbox', |
|
223 '#title' => t('Create a new image'), |
|
224 '#default_value' => 1, |
|
225 ); |
|
226 return $form; |
|
227 } |
|
228 |
|
229 /** |
|
230 * Validate file operations form. |
|
231 */ |
|
232 function imce_fileop_form_validate($form, &$form_state) { |
|
233 $imce =& $form['#parameters'][2]['imce']; |
|
234 |
|
235 //check if the filenames is empty |
|
236 if ($form_state['values']['filenames'] == '') { |
|
237 return form_error($form['filenames'], t('Please select a file.')); |
|
238 } |
|
239 |
|
240 //filenames come seperated by colon |
|
241 $filenames = explode(':', $form_state['values']['filenames']); |
|
242 $cnt = count($filenames); |
|
243 //check the number of files. |
|
244 if ($imce['filenum'] && $cnt > $imce['filenum']) { |
|
245 return form_error($form['filenames'], t('You are not allowed to operate on more than %num files.', array('%num' => $imce['filenum']))); |
|
246 } |
|
247 |
|
248 //check if there is any illegal choice |
|
249 for ($i = 0; $i < $cnt; $i++) { |
|
250 $filenames[$i] = $filename = rawurldecode($filenames[$i]); |
|
251 if (!isset($imce['files'][$filename])) { |
|
252 watchdog('imce', 'Illegal choice %choice in !name element.', array('%choice' => $filename, '!name' => t('directory (%dir)', array('%dir' => file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir'])))), WATCHDOG_ERROR); |
|
253 return form_error($form['filenames'], t('An illegal choice has been detected. Please contact the site administrator.')); |
|
254 } |
|
255 } |
|
256 |
|
257 $form_state['values']['filenames'] = $filenames; |
|
258 } |
|
259 |
|
260 /** |
|
261 * Submit upload form. |
|
262 */ |
|
263 function imce_upload_submit($form, &$form_state) { |
|
264 $form_state['redirect'] = FALSE; |
|
265 $imce =& $form['#parameters'][2]['imce']; |
|
266 $validators = array('imce_validate_all' => array(&$imce)); |
|
267 $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']); |
|
268 |
|
269 //save uploaded file. |
|
270 $replace = variable_get('imce_settings_replace', FILE_EXISTS_RENAME); |
|
271 if ($file = file_save_upload('imce', $validators, $dirpath, $replace)) { |
|
272 |
|
273 //core bug #203204. |
|
274 @chmod($file->filepath, 0664); |
|
275 |
|
276 //core bug #54223. |
|
277 if ($replace == FILE_EXISTS_RENAME) { |
|
278 $name = basename($file->filepath); |
|
279 if ($name != $file->filename) { |
|
280 $file->filename = $name; |
|
281 drupal_set_message(t('The file is renamed to %filename.', array('%filename' => $file->filename))); |
|
282 } |
|
283 } |
|
284 else if ($replace == FILE_EXISTS_REPLACE) {//check duplicates |
|
285 if ($_file = db_fetch_object(db_query("SELECT fid FROM {files} WHERE filepath = '%s' AND fid <> %d", $file->filepath, $file->fid))) { |
|
286 db_query("DELETE FROM {files} WHERE fid = %d", $file->fid); |
|
287 $file->fid = $_file->fid; |
|
288 } |
|
289 } |
|
290 |
|
291 $file->uid = $imce['uid'];//global user may not be the owner. |
|
292 $file->status = FILE_STATUS_PERMANENT;//make permanent |
|
293 drupal_write_record('files', $file, array('fid'));//update |
|
294 drupal_set_message(t('%filename is uploaded.', array('%filename' => $file->filename))); |
|
295 |
|
296 //update file list |
|
297 $img = imce_image_info($file->filepath); |
|
298 $file->width = $img ? $img['width'] : 0; |
|
299 $file->height = $img ? $img['height'] : 0; |
|
300 imce_add_file($file, $imce); |
|
301 |
|
302 //create thumbnails |
|
303 if (isset($form_state['values']['thumbnails']) && $img) { |
|
304 imce_create_thumbnails($file->filename, $imce, $form_state['values']['thumbnails']); |
|
305 } |
|
306 } |
|
307 else { |
|
308 drupal_set_message(t('Upload failed.'), 'error'); |
|
309 } |
|
310 } |
|
311 |
|
312 /** |
|
313 * Submit thumbnail form. |
|
314 */ |
|
315 function imce_thumb_submit($form, &$form_state) { |
|
316 $form_state['redirect'] = FALSE; |
|
317 $imce =& $form['#parameters'][2]['imce']; |
|
318 //create thumbnails |
|
319 imce_process_files($form_state['values']['filenames'], $imce, 'imce_create_thumbnails', array($form_state['values']['thumbnails'])); |
|
320 } |
|
321 |
|
322 /** |
|
323 * Submit delete form. |
|
324 */ |
|
325 function imce_delete_submit($form, &$form_state) { |
|
326 $form_state['redirect'] = FALSE; |
|
327 $imce =& $form['#parameters'][2]['imce']; |
|
328 |
|
329 $deleted = imce_process_files($form_state['values']['filenames'], $imce, 'imce_delete_file'); |
|
330 |
|
331 if (!empty($deleted)) { |
|
332 drupal_set_message(t('File deletion successful: %files.', array('%files' => utf8_encode(implode(', ', $deleted))))); |
|
333 } |
|
334 |
|
335 } |
|
336 |
|
337 /** |
|
338 * Submit resize form. |
|
339 */ |
|
340 function imce_resize_submit($form, &$form_state) { |
|
341 $form_state['redirect'] = FALSE; |
|
342 $imce =& $form['#parameters'][2]['imce']; |
|
343 |
|
344 //check dimensions |
|
345 $width = (int) $form_state['values']['width']; |
|
346 $height = (int) $form_state['values']['height']; |
|
347 list($maxw, $maxh) = explode('x', $imce['dimensions']); |
|
348 if ($width < 1 || $height < 1 || ($maxw && ($width > $maxw || $height > $maxh))) { |
|
349 drupal_set_message(t('Please specify dimensions within the allowed range that is from 1x1 to @dimensions.', array('@dimensions' => $imce['dimensions'] ? $imce['dimensions'] : t('unlimited'))), 'error'); |
|
350 return; |
|
351 } |
|
352 |
|
353 $resized = imce_process_files($form_state['values']['filenames'], $imce, 'imce_resize_image', array($width, $height, $form_state['values']['copy'])); |
|
354 |
|
355 if (!empty($resized)) { |
|
356 drupal_set_message(t('File resizing successful: %files.', array('%files' => utf8_encode(implode(', ', $resized))))); |
|
357 } |
|
358 |
|
359 } |
|
360 |
|
361 /** |
|
362 * Do batch operations on files. |
|
363 * Used by delete, resize, create thumbnail submissions. |
|
364 */ |
|
365 function imce_process_files($filenames, &$imce, $function, $args = array()) { |
|
366 $args = array_merge(array('', &$imce), $args); |
|
367 $processed = array(); |
|
368 |
|
369 foreach ($filenames as $filename) { |
|
370 $args[0] = $filename; |
|
371 if (call_user_func_array($function, $args)) { |
|
372 $processed[] = $filename; |
|
373 } |
|
374 } |
|
375 |
|
376 return $processed; |
|
377 } |
|
378 |
|
379 /** |
|
380 * Delete a file in the file list. |
|
381 */ |
|
382 function imce_delete_file($filename, &$imce) { |
|
383 $filepath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']) .'/'. $filename; |
|
384 if (!file_delete($filepath)) { |
|
385 return FALSE; |
|
386 } |
|
387 db_query("DELETE FROM {files} WHERE filepath = '%s'", $filepath); |
|
388 imce_remove_file($filename, $imce); |
|
389 return TRUE; |
|
390 } |
|
391 |
|
392 /** |
|
393 * Create all selected thumbnails. |
|
394 */ |
|
395 function imce_create_thumbnails($filename, &$imce, $values) { |
|
396 $created = array(); |
|
397 foreach ($imce['thumbnails'] as $thumbnail) { |
|
398 if ($values[$thumbnail['name']] && imce_create_thumbnail($filename, $imce, $thumbnail)) { |
|
399 $created[] = $thumbnail['name']; |
|
400 } |
|
401 } |
|
402 if (!empty($created)) { |
|
403 drupal_set_message(t('Thumbnail creation (%thumbnames) successful for %filename.', array('%thumbnames' => implode(', ', $created), '%filename' => utf8_encode($filename)))); |
|
404 } |
|
405 return $created; |
|
406 } |
|
407 |
|
408 /** |
|
409 * Create a thumbnail. |
|
410 */ |
|
411 function imce_create_thumbnail($filename, &$imce, $thumbnail) { |
|
412 //generate thumbnail name |
|
413 $name = $thumbnail['prefix']; |
|
414 if ($thumbnail['suffix'] != '' && $dot = strrpos($filename, '.')) { |
|
415 $name .= substr($filename, 0, $dot); |
|
416 $name .= $thumbnail['suffix']; |
|
417 $name .= substr($filename, $dot); |
|
418 } |
|
419 else { |
|
420 $name .= $filename; |
|
421 } |
|
422 //scale the image |
|
423 list($width, $height) = explode('x', $thumbnail['dimensions']); |
|
424 return imce_resize_image($filename, $imce, $width, $height, TRUE, $name, variable_get('imce_settings_thumb_method', 'scale_and_crop')); |
|
425 } |
|
426 |
|
427 /** |
|
428 * Resize an image in the file list. Also used for thumbnail creation. |
|
429 */ |
|
430 function imce_resize_image($filename, &$imce, $width, $height, $copy = TRUE, $dest = FALSE, $op = 'resize') { |
|
431 $dirpath = file_directory_path() . ($imce['dir'] == '.' ? '' : '/'. $imce['dir']); |
|
432 $filepath = $dirpath .'/'. $filename; |
|
433 |
|
434 //check if the file is an image |
|
435 if (!$imce['files'][$filename]['width'] || !$img = imce_image_info($filepath)) { |
|
436 drupal_set_message(t('%filename is not an image.', array('%filename' => utf8_encode($filename))), 'error', FALSE); |
|
437 return FALSE; |
|
438 } |
|
439 |
|
440 if (substr($op, 0, 5) == 'scale' && !($width < $img['width'] || $height < $img['height'])) { |
|
441 drupal_set_message(t('Scaling up is not allowed.'), 'error', FALSE); |
|
442 return FALSE; |
|
443 } |
|
444 |
|
445 //create file object |
|
446 $file = new stdClass(); |
|
447 $file->filepath = $dirpath .'/'. $dest; |
|
448 if (!$dest || $dest == $filename) { |
|
449 $file->filepath = $copy ? file_create_filename($filename, $dirpath) : $filepath; |
|
450 } |
|
451 $file->filename = basename($file->filepath); |
|
452 |
|
453 //check if a file having the same properties exists already. |
|
454 if (isset($imce['files'][$file->filename])) { |
|
455 if (($f = $imce['files'][$file->filename]) && $f['width'] == $width && $f['height'] == $height) { |
|
456 drupal_set_message(t('%filename(%dimensions) already exists.', array('%filename' => utf8_encode($file->filename), '%dimensions' => $width .'x'. $height)), 'error'); |
|
457 return FALSE; |
|
458 } |
|
459 } |
|
460 |
|
461 //validate file name |
|
462 $errors = file_validate_name_length($file); |
|
463 if (!empty($errors)) { |
|
464 drupal_set_message($errors[0], 'error'); |
|
465 return FALSE; |
|
466 } |
|
467 |
|
468 //resize image to a temp file |
|
469 $temp = tempnam(realpath(file_directory_temp()), 'imc'); |
|
470 register_shutdown_function('file_delete', $temp); |
|
471 $function = 'image_'. $op; |
|
472 if (!$function($filepath, $temp, $width, $height)) { |
|
473 drupal_set_message(t('%filename cannot be resized to %dimensions', array('%filename' => utf8_encode($filename), '%dimensions' => $width .'x'. $height)), 'error', FALSE); |
|
474 return FALSE; |
|
475 } |
|
476 |
|
477 //validate quota |
|
478 $file->filesize = filesize($temp); |
|
479 $overwrite = $file->filename == $filename; |
|
480 if (!imce_validate_quotas($file, $imce, $overwrite ? -$imce['files'][$filename]['size'] : 0)) { |
|
481 return FALSE; |
|
482 } |
|
483 |
|
484 //copy from temp to filepath |
|
485 if (!@copy($temp, $file->filepath)) { |
|
486 drupal_set_message(t('The selected file %file could not be copied.', array('%file' => utf8_encode($file->filename))), 'error', FALSE); |
|
487 return FALSE; |
|
488 } |
|
489 @chmod($file->filepath, 0664); |
|
490 |
|
491 //build the rest of the file object |
|
492 $file->uid = $imce['uid']; |
|
493 $file->filemime = $img['mime']; |
|
494 $file->status = FILE_STATUS_PERMANENT; |
|
495 $file->timestamp = time(); |
|
496 |
|
497 //if we are overwriting the file and it is already in database. |
|
498 $update = array(); |
|
499 if ($overwrite && $_file = db_fetch_object(db_query("SELECT f.* FROM {files} f WHERE f.filepath = '%s'", $file->filepath))) { |
|
500 $file->fid = $_file->fid; |
|
501 $file->uid = $_file->uid; |
|
502 $update[] = 'fid'; |
|
503 } |
|
504 |
|
505 //save the file |
|
506 drupal_write_record('files', $file, $update); |
|
507 |
|
508 //update file list |
|
509 //if the file was scaled get the new dimensions |
|
510 if ($op == 'scale') { |
|
511 $img = imce_image_info($file->filepath); |
|
512 $width = $img['width']; |
|
513 $height = $img['height']; |
|
514 } |
|
515 $file->width = $width; |
|
516 $file->height = $height; |
|
517 imce_add_file($file, $imce); |
|
518 |
|
519 return $file; |
|
520 } |
|
521 |
|
522 /** |
|
523 * Add a new file to the file list. |
|
524 */ |
|
525 function imce_add_file($file, &$imce) { |
|
526 $imce['dirsize'] += $file->filesize; |
|
527 if (isset($imce['files'][$file->filename])) { |
|
528 $imce['dirsize'] -= $imce['files'][$file->filename]['size']; |
|
529 } |
|
530 $imce['files'][$file->filename] = array( |
|
531 'name' => $file->filename, |
|
532 'size' => $file->filesize, |
|
533 'width' => $file->width, |
|
534 'height' => $file->height, |
|
535 'date' => $file->timestamp |
|
536 ); |
|
537 if (isset($_GET['jsop'])) { |
|
538 $add = $imce['files'][$file->filename]; |
|
539 $add['name'] = rawurlencode($file->filename); |
|
540 $add['fsize'] = format_size($file->filesize); |
|
541 $add['fdate'] = format_date($file->timestamp, 'small'); |
|
542 $imce['added'][] = $add; |
|
543 } |
|
544 } |
|
545 |
|
546 /** |
|
547 * Remove a file from the file list. |
|
548 */ |
|
549 function imce_remove_file($filename, &$imce) { |
|
550 if (isset($imce['files'][$filename])) { |
|
551 $imce['dirsize'] -= $imce['files'][$filename]['size']; |
|
552 unset($imce['files'][$filename]); |
|
553 if (isset($_GET['jsop'])) { |
|
554 $imce['removed'][] = rawurlencode($filename); |
|
555 } |
|
556 } |
|
557 } |
|
558 |
|
559 /** |
|
560 * Validate uploaded file. |
|
561 */ |
|
562 function imce_validate_all(&$file, $imce) { |
|
563 |
|
564 //fix FILE_EXISTS_ERROR bug. core bug #54223. |
|
565 if (!$file->destination && variable_get('imce_settings_replace', FILE_EXISTS_RENAME) == FILE_EXISTS_ERROR) { |
|
566 return array(t('File browser is set to reject the upload of existing files.')); |
|
567 } |
|
568 |
|
569 //validate image resolution only if filesize validation passes. |
|
570 //because user might have uploaded a very big image |
|
571 //and scaling it may exploit system memory. |
|
572 $errors = imce_validate_filesize($file, $imce['filesize']); |
|
573 if (empty($errors)) {//image resolution validation |
|
574 $errors = array_merge($errors, file_validate_image_resolution($file, $imce['dimensions'])); |
|
575 } |
|
576 if ($imce['quota']) {//directory quota validation |
|
577 $errors = array_merge($errors, imce_validate_quota($file, $imce['quota'], $imce['dirsize'])); |
|
578 } |
|
579 if ($imce['extensions'] != '*' && !preg_match('/\.('. str_replace(' ', '|', $imce['extensions']) .')$/i', $file->filename)) { |
|
580 $errors[] = t('Only files with the following extensions are allowed: %files-allowed.', array('%files-allowed' => $imce['extensions'])); |
|
581 } |
|
582 if (empty($errors) && $imce['tuquota']) {//total user quota validation. check everything before hitting the DB |
|
583 $errors = array_merge($errors, imce_validate_quota($file, $imce['tuquota'], file_space_used($imce['uid']), 1)); |
|
584 } |
|
585 return $errors; |
|
586 } |
|
587 |
|
588 /** |
|
589 * Validate filesize for maximum allowed file size. |
|
590 */ |
|
591 function imce_validate_filesize($file, $maxsize = 0) { |
|
592 $errors = array(); |
|
593 if ($maxsize && $file->filesize > $maxsize) { |
|
594 $errors[] = t('The file is %filesize exceeding the maximum file size of %maxsize.', array('%filesize' => format_size($file->filesize), '%maxsize' => format_size($maxsize))); |
|
595 } |
|
596 return $errors; |
|
597 } |
|
598 |
|
599 /** |
|
600 * Validate filesize for directory and total user quota. |
|
601 */ |
|
602 function imce_validate_quota($file, $quota = 0, $current = 0, $type = 0) { |
|
603 $errors = array(); |
|
604 if ($quota && ($current + $file->filesize) > $quota) { |
|
605 $qtypes = array('Directory quota', 'Total user quota'); |
|
606 $errors[] = t('%filename is %filesize which would exceed your %quota_type. You are currently using %size of %quota.', array('%size' => format_size($current), '%quota' => format_size($quota), '%filesize' => format_size($file->filesize), '%filename' => utf8_encode($file->filename), '%quota_type' => t(isset($qtypes[$type]) ? $qtypes[$type] : 'quota'))); |
|
607 } |
|
608 return $errors; |
|
609 } |
|
610 |
|
611 /** |
|
612 * Validate both directory and total user quota. Returns true/false not errors. |
|
613 */ |
|
614 function imce_validate_quotas($file, &$imce, $add = 0) { |
|
615 $errors = imce_validate_quota($file, $imce['quota'], $imce['dirsize'] + $add); |
|
616 if (empty($errors) && $imce['tuquota']) { |
|
617 $errors = imce_validate_quota($file, $imce['tuquota'], file_space_used($imce['uid']) + $add, 1); |
|
618 } |
|
619 if (!empty($errors)) { |
|
620 drupal_set_message($errors[0], 'error'); |
|
621 return FALSE; |
|
622 } |
|
623 return TRUE; |
|
624 } |
|
625 |
|
626 /** |
|
627 * Check if the file is an image and return info. |
|
628 */ |
|
629 function imce_image_info($file) { |
|
630 if (is_file($file) && ($dot = strrpos($file, '.')) && in_array(strtolower(substr($file, $dot+1)), array('jpg', 'jpeg', 'gif', 'png')) && ($info = @getimagesize($file)) && in_array($info[2], array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG)) ) { |
|
631 return array('width' => $info[0], 'height' => $info[1], 'type' => $info[2], 'mime' => $info['mime']); |
|
632 } |
|
633 return FALSE; |
|
634 } |
|
635 |
|
636 /** |
|
637 * Return thumbnails as options to be used in upload form. |
|
638 */ |
|
639 function imce_thumbnail_options($thumbs = array()) { |
|
640 $options = array(); |
|
641 foreach ($thumbs as $thumb) { |
|
642 $options[$thumb['name']] = $thumb['name'] .' ('. $thumb['dimensions'] .')'; |
|
643 } |
|
644 return $options; |
|
645 } |
|
646 |
|
647 /** |
|
648 * Initiate and return configuration profile for the $user. |
|
649 */ |
|
650 function imce_initiate_profile($user) { |
|
651 |
|
652 //check user profile and translate tokens in directory paths and evaluate php paths. |
|
653 if ($imce = imce_user_profile($user)) { |
|
654 $imce['directories'] = imce_process_directories($imce['directories'], $user); |
|
655 if (!empty($imce['directories'])) { |
|
656 $imce['uid'] = (int)$user->uid; |
|
657 $imce['url'] = url($_GET['q']); |
|
658 $imce['clean'] = variable_get('clean_url', 0) == 1; |
|
659 $imce['prvt'] = variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE; |
|
660 $imce['furl'] = $imce['prvt'] ? url('system/files') : base_path() . file_directory_path(); |
|
661 if (variable_get('imce_settings_absurls', 0)) { |
|
662 $imce['furl'] = $GLOBALS['base_root'] . $imce['furl']; |
|
663 } |
|
664 $imce['filesize'] *= 1048576;//convert from Mb to byte |
|
665 $imce['quota'] *= 1048576; |
|
666 $imce['tuquota'] *= 1048576; |
|
667 $imce['filenum'] = (int) $imce['filenum']; |
|
668 //check and set the active directory |
|
669 if ($info = imce_working_directory($imce)) { |
|
670 $imce['direct'] = isset($imce['directories'][$info['name']]); |
|
671 $imce['directories'][$info['name']] = $info; |
|
672 $imce['dir'] = $info['name']; |
|
673 $imce['perm'] = $info;//copy permissions of the active directory. |
|
674 unset($imce['perm']['name']); |
|
675 } |
|
676 else { |
|
677 drupal_set_message(t('Unable to get a working directory for the file browser!'), 'error'); |
|
678 $imce['dir'] = FALSE; |
|
679 $imce['error'] = TRUE; |
|
680 } |
|
681 return $imce; |
|
682 } |
|
683 drupal_set_message(t('There is no valid directory specified for the file browser!'), 'error'); |
|
684 } |
|
685 else { |
|
686 drupal_set_message(t('You don\'t have access to any configuration profile to use the file browser!'), 'error'); |
|
687 } |
|
688 |
|
689 return FALSE; |
|
690 } |
|
691 |
|
692 /** |
|
693 * Get files and folders of the actve directory. Do custom processing. |
|
694 */ |
|
695 function imce_process_profile(&$imce) { |
|
696 //get directory content. do a custom scan if it is set |
|
697 $scan = ($scan = variable_get('imce_custom_scan', '')) && function_exists($scan) ? $scan : 'imce_scan_directory'; |
|
698 $imce += $scan($imce['dir'], $imce); |
|
699 |
|
700 //run custom process functions |
|
701 foreach (variable_get('imce_custom_process', array()) as $func => $state) { |
|
702 if ($state && function_exists($func)) { |
|
703 $func($imce); |
|
704 } |
|
705 } |
|
706 |
|
707 //set subdirectories |
|
708 if (!$imce['error'] && !imce_subdirectories_accessible($imce)) { |
|
709 $imce['subdirectories'] = array(); |
|
710 } |
|
711 } |
|
712 |
|
713 /** |
|
714 * Translate tokens and evaluate php in directory names. |
|
715 * Return an associative array of directories (dirname => info) |
|
716 */ |
|
717 function imce_process_directories($directories, $user) { |
|
718 $paths = array(); |
|
719 $translate = array('%uid' => $user->uid); |
|
720 |
|
721 foreach ($directories as $directory) { |
|
722 if (substr($directory['name'], 0, 4) == 'php:') { |
|
723 //not using drupal_eval since we need $user to be accessible as it may be different from $GLOBALS['user'] |
|
724 $directory['name'] = eval(substr($directory['name'], 4)); |
|
725 //php may return an array of directories |
|
726 if (is_array($directory['name'])) { |
|
727 foreach ($directory['name'] as $name) { |
|
728 $paths[$name] = array('name' => $name) + $directory; |
|
729 } |
|
730 continue; |
|
731 } |
|
732 } |
|
733 else { |
|
734 $directory['name'] = strtr($directory['name'], $translate); |
|
735 } |
|
736 if ($directory['name']) { |
|
737 $paths[$directory['name']] = $directory; |
|
738 } |
|
739 } |
|
740 |
|
741 return $paths; |
|
742 } |
|
743 |
|
744 /** |
|
745 * Return an avaliable directory for the profile. |
|
746 */ |
|
747 function imce_working_directory($imce) { |
|
748 //check GET. |
|
749 if (isset($_GET['dir'])) { |
|
750 if ($info = imce_directory_info($_GET['dir'], $imce)) { |
|
751 if (imce_check_directory($_GET['dir'])) { |
|
752 $_SESSION['imce_directory'] = rawurlencode($info['name']); |
|
753 } |
|
754 else { |
|
755 $info = FALSE; |
|
756 } |
|
757 } |
|
758 else { |
|
759 imce_inaccessible_directory($_GET['dir']); |
|
760 } |
|
761 return $info; |
|
762 } |
|
763 |
|
764 //check session |
|
765 if (isset($_SESSION['imce_directory'])) { |
|
766 $dirname = rawurldecode($_SESSION['imce_directory']); |
|
767 if ($info = imce_directory_info($dirname, $imce)) { |
|
768 if (imce_check_directory($dirname)) { |
|
769 return $info; |
|
770 } |
|
771 } |
|
772 } |
|
773 |
|
774 //or the whole list. |
|
775 foreach ($imce['directories'] as $dirname => $info) { |
|
776 if (imce_check_directory($dirname)) { |
|
777 $_SESSION['imce_directory'] = rawurlencode($dirname); |
|
778 return $info; |
|
779 } |
|
780 } |
|
781 |
|
782 return FALSE; |
|
783 } |
|
784 |
|
785 /** |
|
786 * Create a writable directory(any level) under file system directory. |
|
787 */ |
|
788 function imce_check_directory($dirname) { |
|
789 |
|
790 $root = file_directory_path(); |
|
791 $dirpath = $root .'/'. $dirname; |
|
792 |
|
793 if (!file_check_directory($dirpath)) {//directory does not exist. try to create it. |
|
794 $path = $root; |
|
795 foreach (explode('/', $dirname) as $arg) { |
|
796 $path .= '/'. $arg; |
|
797 if (!file_check_location($path, $root) || !file_check_directory($path, FILE_CREATE_DIRECTORY)) { |
|
798 return imce_inaccessible_directory($dirname); |
|
799 } |
|
800 } |
|
801 } |
|
802 else if (!file_check_location($dirpath, $root)) {//directory exists outside of root. |
|
803 return imce_inaccessible_directory($dirname); |
|
804 } |
|
805 |
|
806 return TRUE; |
|
807 } |
|
808 |
|
809 /** |
|
810 * Generate and log a directory access error. |
|
811 */ |
|
812 function imce_inaccessible_directory($dirname) { |
|
813 if (is_string($dirname)) { |
|
814 $msg = 'Directory "%dir" is not accessible under file system!'; |
|
815 $token = array('%dir' => utf8_encode($dirname)); |
|
816 drupal_set_message(t($msg, $token), 'error'); |
|
817 watchdog('imce', $msg, $token, WATCHDOG_ERROR); |
|
818 } |
|
819 return FALSE; |
|
820 } |
|
821 |
|
822 /** |
|
823 * Return the permissions for a directory that is accessed directly or indirectly. |
|
824 * A child of a predefined directory in the directory list takes its parent's properties. |
|
825 * If it has multiple parents, it gets the properties of the latter in the list. |
|
826 */ |
|
827 function imce_directory_info($dirname, $imce) { |
|
828 |
|
829 if (isset($imce['directories'][$dirname])) { |
|
830 return $imce['directories'][$dirname]; |
|
831 } |
|
832 |
|
833 $info = FALSE; |
|
834 $root = file_directory_path(); |
|
835 $dirpath = $root .'/'. $dirname; |
|
836 if (imce_reg_dir($dirname) && file_check_directory($dirpath)) { |
|
837 foreach ($imce['directories'] as $name => $prop) { |
|
838 if ($prop['subnav'] && file_check_location($dirpath, $root .'/'. $name)) { |
|
839 $info = $prop; |
|
840 $info['name'] = $dirname; |
|
841 } |
|
842 } |
|
843 } |
|
844 |
|
845 return $info; |
|
846 } |
|
847 |
|
848 /** |
|
849 * Detect if the subdirectories are accessible through any directory(not just the current one) in the list. |
|
850 */ |
|
851 function imce_subdirectories_accessible(&$imce) { |
|
852 |
|
853 if (!empty($imce['subdirectories'])) { |
|
854 $root = file_directory_path() .'/'; |
|
855 //checking only the first one is sufficient. |
|
856 $dirname = ($imce['dir'] == '.' ? '' : $imce['dir'] .'/') . $imce['subdirectories'][0]; |
|
857 $dirpath = $root . $dirname; |
|
858 |
|
859 //check if any setting is applicable for this subdirectory through any directory in the list. |
|
860 foreach ($imce['directories'] as $name => $info) { |
|
861 if ($info['subnav'] && $dirname != $name && file_check_location($dirpath, $root . $name)) { |
|
862 return TRUE; |
|
863 } |
|
864 } |
|
865 } |
|
866 |
|
867 return FALSE; |
|
868 } |
|
869 |
|
870 /** |
|
871 * Check if a permission is given to at least one directory in the list. |
|
872 */ |
|
873 function imce_perm_exists(&$imce, $perm) { |
|
874 static $perms = array(); |
|
875 |
|
876 if (isset($perms[$perm])) { |
|
877 return $perms[$perm]; |
|
878 } |
|
879 |
|
880 if (isset($imce['perm'][$perm]) && $imce['perm'][$perm]) { |
|
881 return $perms[$perm] = TRUE; |
|
882 } |
|
883 |
|
884 foreach ($imce['directories'] as $name => $info) { |
|
885 if (isset($info[$perm]) && $info[$perm]) { |
|
886 return $perms[$perm] = TRUE; |
|
887 } |
|
888 } |
|
889 |
|
890 return $perms[$perm] = FALSE; |
|
891 } |
|
892 |
|
893 /** |
|
894 * Scan directory and return file list, subdirectories, and total size. |
|
895 */ |
|
896 function imce_scan_directory($dirname) { |
|
897 |
|
898 $directory = array('dirsize' => 0, 'files' => array(), 'subdirectories' => array(), 'error' => FALSE); |
|
899 $dirpath = file_directory_path() .'/'. $dirname; |
|
900 |
|
901 if (!is_string($dirname) || $dirname == '' || !$handle = opendir($dirpath)) { |
|
902 imce_inaccessible_directory($dirname); |
|
903 $directory['error'] = TRUE; |
|
904 return $directory; |
|
905 } |
|
906 |
|
907 $exclude = array('.' => 1, '..' => 1, 'CVS' => 1, '.svn' => 1, '.htaccess' => 1); |
|
908 while (($file = readdir($handle)) !== FALSE) { |
|
909 if (isset($exclude[$file])) { |
|
910 continue; |
|
911 } |
|
912 |
|
913 $path = $dirpath .'/'. $file; |
|
914 |
|
915 if (is_dir($path)) { |
|
916 $directory['subdirectories'][] = $file; |
|
917 continue; |
|
918 } |
|
919 |
|
920 $width = $height = 0; |
|
921 if ($img = imce_image_info($path)) { |
|
922 $width = $img['width']; |
|
923 $height = $img['height']; |
|
924 } |
|
925 $size = filesize($path); |
|
926 $date = filemtime($path); |
|
927 $directory['files'][$file] = array( |
|
928 'name' => $file, |
|
929 'size' => $size, |
|
930 'width' => $width, |
|
931 'height' => $height, |
|
932 'date' => $date |
|
933 ); |
|
934 $directory['dirsize'] += $size; |
|
935 } |
|
936 |
|
937 closedir($handle); |
|
938 sort($directory['subdirectories']); |
|
939 return $directory; |
|
940 } |
|
941 |
|
942 /** |
|
943 * Create directory tree. |
|
944 */ |
|
945 function imce_create_tree(&$imce) { |
|
946 $paths = array(); |
|
947 //rearrange paths as arg0=>arg1=>... |
|
948 foreach ($imce['directories'] as $path => $arr) { |
|
949 $tmp =& $paths; |
|
950 if ($path != '.') { |
|
951 $args = explode('/', $path); |
|
952 foreach ($args as $arg) { |
|
953 if (!isset($tmp[$arg])) { |
|
954 $tmp[$arg] = array(); |
|
955 } |
|
956 $tmp =& $tmp[$arg]; |
|
957 } |
|
958 $tmp[':access:'] = TRUE; |
|
959 } |
|
960 if ("$path" == $imce['dir']) { |
|
961 $tmp[':active:'] = TRUE; |
|
962 foreach ($imce['subdirectories'] as $arg) { |
|
963 $tmp[$arg][':access:'] = TRUE; |
|
964 } |
|
965 } |
|
966 } |
|
967 //set root branch |
|
968 $root = variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE && !user_access('administer site configuration') ? t('Directory root') : file_directory_path(); |
|
969 $q = $imce['clean'] ? '?' : '&'; |
|
970 if (isset($imce['directories']['.'])) { |
|
971 $root = '<a href="'. $imce['url'] . $q .'dir=." title="." class="folder'. ($imce['dir'] == '.' ? ' active' : '') .'">'. $root .'</a>'; |
|
972 } |
|
973 else { |
|
974 $root = '<a title="." class="folder disabled">'. $root .'</a>'; |
|
975 } |
|
976 |
|
977 return $root . imce_tree_html($imce, $paths, $q); |
|
978 } |
|
979 |
|
980 /** |
|
981 * Return tree html. |
|
982 * This is not themable because it is complex and needs to be in a proper format for js processing. |
|
983 */ |
|
984 function imce_tree_html(&$imce, $paths, $q = '?', $prefix = '', $eprefix = '') { |
|
985 unset($paths[':access:'], $paths[':active:']); |
|
986 $html = ''; |
|
987 foreach ($paths as $arg => $children) { |
|
988 $path = $prefix . $arg; |
|
989 $earg = rawurlencode($arg); |
|
990 $epath = $eprefix . $earg; |
|
991 if (isset($children[':access:']) || imce_directory_info($path, $imce)) { |
|
992 $a = '<a href="'. $imce['url'] . $q .'dir='. $epath .'" title="'. $epath .'" class="folder'. (isset($children[':active:']) ? ' active' : '') .'">'. $earg .'</a>'; |
|
993 } |
|
994 else { |
|
995 $a = '<a title="'. $epath .'" class="folder disabled">'. $earg .'</a>'; |
|
996 } |
|
997 $ul = imce_tree_html($imce, $children, $q, $path .'/', $epath .'/'); |
|
998 $html .= '<li class="'. ($ul ? 'expanded' : (isset($children[':active:']) ? 'leaf' : '')) .'">'. $a . $ul .'</li>'; |
|
999 } |
|
1000 if ($html) { |
|
1001 $html = '<ul>'. $html .'</ul>'; |
|
1002 } |
|
1003 return $html; |
|
1004 } |