Elgg  Version 1.11
filestore.php
Go to the documentation of this file.
1 <?php
18 function get_dir_size($dir, $total_size = 0) {
19  $handle = @opendir($dir);
20  while ($file = @readdir($handle)) {
21  if (in_array($file, array('.', '..'))) {
22  continue;
23  }
24  if (is_dir($dir . $file)) {
25  $total_size = get_dir_size($dir . $file . "/", $total_size);
26  } else {
27  $total_size += filesize($dir . $file);
28  }
29  }
30  @closedir($handle);
31 
32  return($total_size);
33 }
34 
44  $files = _elgg_services()->request->files;
45  if (!$files->has($input_name)) {
46  return false;
47  }
48 
49  $file = $files->get($input_name);
50  if (empty($file)) {
51  // a file input was provided but no file uploaded
52  return false;
53  }
54  if ($file->getError() !== 0) {
55  return false;
56  }
57 
58  return file_get_contents($file->getPathname());
59 }
60 
75 function get_resized_image_from_uploaded_file($input_name, $maxwidth, $maxheight,
76 $square = false, $upscale = false) {
77  $files = _elgg_services()->request->files;
78  if (!$files->has($input_name)) {
79  return false;
80  }
81 
82  $file = $files->get($input_name);
83  if (empty($file)) {
84  // a file input was provided but no file uploaded
85  return false;
86  }
87  if ($file->getError() !== 0) {
88  return false;
89  }
90 
91  return get_resized_image_from_existing_file($file->getPathname(), $maxwidth,
92  $maxheight, $square, 0, 0, 0, 0, $upscale);
93 }
94 
115 function get_resized_image_from_existing_file($input_name, $maxwidth, $maxheight, $square = false,
116 $x1 = 0, $y1 = 0, $x2 = 0, $y2 = 0, $upscale = false) {
117 
118  // Get the size information from the image
119  $imgsizearray = getimagesize($input_name);
120  if ($imgsizearray == false) {
121  return false;
122  }
123 
124  $width = $imgsizearray[0];
125  $height = $imgsizearray[1];
126 
127  $accepted_formats = array(
128  'image/jpeg' => 'jpeg',
129  'image/pjpeg' => 'jpeg',
130  'image/png' => 'png',
131  'image/x-png' => 'png',
132  'image/gif' => 'gif'
133  );
134 
135  // make sure the function is available
136  $load_function = "imagecreatefrom" . $accepted_formats[$imgsizearray['mime']];
137  if (!is_callable($load_function)) {
138  return false;
139  }
140 
141  // get the parameters for resizing the image
142  $options = array(
143  'maxwidth' => $maxwidth,
144  'maxheight' => $maxheight,
145  'square' => $square,
146  'upscale' => $upscale,
147  'x1' => $x1,
148  'y1' => $y1,
149  'x2' => $x2,
150  'y2' => $y2,
151  );
152  $params = get_image_resize_parameters($width, $height, $options);
153  if ($params == false) {
154  return false;
155  }
156 
157  // load original image
158  $original_image = call_user_func($load_function, $input_name);
159  if (!$original_image) {
160  return false;
161  }
162 
163  // allocate the new image
164  $new_image = imagecreatetruecolor($params['newwidth'], $params['newheight']);
165  if (!$new_image) {
166  return false;
167  }
168 
169  // color transparencies white (default is black)
170  imagefilledrectangle(
171  $new_image, 0, 0, $params['newwidth'], $params['newheight'],
172  imagecolorallocate($new_image, 255, 255, 255)
173  );
174 
175  $rtn_code = imagecopyresampled( $new_image,
176  $original_image,
177  0,
178  0,
179  $params['xoffset'],
180  $params['yoffset'],
181  $params['newwidth'],
182  $params['newheight'],
183  $params['selectionwidth'],
184  $params['selectionheight']);
185  if (!$rtn_code) {
186  return false;
187  }
188 
189  // grab a compressed jpeg version of the image
190  ob_start();
191  imagejpeg($new_image, null, 90);
192  $jpeg = ob_get_clean();
193 
194  imagedestroy($new_image);
195  imagedestroy($original_image);
196 
197  return $jpeg;
198 }
199 
210 function get_image_resize_parameters($width, $height, $options) {
211 
212  $defaults = array(
213  'maxwidth' => 100,
214  'maxheight' => 100,
215 
216  'square' => false,
217  'upscale' => false,
218 
219  'x1' => 0,
220  'y1' => 0,
221  'x2' => 0,
222  'y2' => 0,
223  );
224 
225  $options = array_merge($defaults, $options);
226 
227  // Avoiding extract() because it hurts static analysis
228  $maxwidth = $options['maxwidth'];
229  $maxheight = $options['maxheight'];
230  $square = $options['square'];
231  $upscale = $options['upscale'];
232  $x1 = $options['x1'];
233  $y1 = $options['y1'];
234  $x2 = $options['x2'];
235  $y2 = $options['y2'];
236 
237  // crop image first?
238  $crop = true;
239  if ($x1 == 0 && $y1 == 0 && $x2 == 0 && $y2 == 0) {
240  $crop = false;
241  }
242 
243  // how large a section of the image has been selected
244  if ($crop) {
245  $selection_width = $x2 - $x1;
246  $selection_height = $y2 - $y1;
247  } else {
248  // everything selected if no crop parameters
249  $selection_width = $width;
250  $selection_height = $height;
251  }
252 
253  // determine cropping offsets
254  if ($square) {
255  // asking for a square image back
256 
257  // detect case where someone is passing crop parameters that are not for a square
258  if ($crop == true && $selection_width != $selection_height) {
259  return false;
260  }
261 
262  // size of the new square image
263  $new_width = $new_height = min($maxwidth, $maxheight);
264 
265  // find largest square that fits within the selected region
266  $selection_width = $selection_height = min($selection_width, $selection_height);
267 
268  // set offsets for crop
269  if ($crop) {
270  $widthoffset = $x1;
271  $heightoffset = $y1;
272  $width = $x2 - $x1;
273  $height = $width;
274  } else {
275  // place square region in the center
276  $widthoffset = floor(($width - $selection_width) / 2);
277  $heightoffset = floor(($height - $selection_height) / 2);
278  }
279  } else {
280  // non-square new image
281  $new_width = $maxwidth;
282  $new_height = $maxheight;
283 
284  // maintain aspect ratio of original image/crop
285  if (($selection_height / (float)$new_height) > ($selection_width / (float)$new_width)) {
286  $new_width = floor($new_height * $selection_width / (float)$selection_height);
287  } else {
288  $new_height = floor($new_width * $selection_height / (float)$selection_width);
289  }
290 
291  // by default, use entire image
292  $widthoffset = 0;
293  $heightoffset = 0;
294 
295  if ($crop) {
296  $widthoffset = $x1;
297  $heightoffset = $y1;
298  }
299  }
300 
301  if (!$upscale && ($selection_height < $new_height || $selection_width < $new_width)) {
302  // we cannot upscale and selected area is too small so we decrease size of returned image
303  if ($square) {
304  $new_height = $selection_height;
305  $new_width = $selection_width;
306  } else {
307  if ($selection_height < $new_height && $selection_width < $new_width) {
308  $new_height = $selection_height;
309  $new_width = $selection_width;
310  }
311  }
312  }
313 
314  $params = array(
315  'newwidth' => $new_width,
316  'newheight' => $new_height,
317  'selectionwidth' => $selection_width,
318  'selectionheight' => $selection_height,
319  'xoffset' => $widthoffset,
320  'yoffset' => $heightoffset,
321  );
322 
323  return $params;
324 }
325 
333 function file_delete($guid) {
334  $file = get_entity($guid);
335  if (!$file || !$file->canEdit()) {
336  return false;
337  }
338 
339  $thumbnail = $file->thumbnail;
340  $smallthumb = $file->smallthumb;
341  $largethumb = $file->largethumb;
342  if ($thumbnail) {
343  $delfile = new \ElggFile();
344  $delfile->owner_guid = $file->owner_guid;
345  $delfile->setFilename($thumbnail);
346  $delfile->delete();
347  }
348  if ($smallthumb) {
349  $delfile = new \ElggFile();
350  $delfile->owner_guid = $file->owner_guid;
351  $delfile->setFilename($smallthumb);
352  $delfile->delete();
353  }
354  if ($largethumb) {
355  $delfile = new \ElggFile();
356  $delfile->owner_guid = $file->owner_guid;
357  $delfile->setFilename($largethumb);
358  $delfile->delete();
359  }
360 
361  return $file->delete();
362 }
363 
371 function delete_directory($directory) {
372  // sanity check: must be a directory
373  if (!$handle = opendir($directory)) {
374  return false;
375  }
376 
377  // loop through all files
378  while (($file = readdir($handle)) !== false) {
379  if (in_array($file, array('.', '..'))) {
380  continue;
381  }
382 
383  $path = "$directory/$file";
384  if (is_dir($path)) {
385  // recurse down through directory
386  if (!delete_directory($path)) {
387  return false;
388  }
389  } else {
390  // delete file
391  unlink($path);
392  }
393  }
394 
395  // remove empty directory
396  closedir($handle);
397  return rmdir($directory);
398 }
399 
416  $dir = new \Elgg\EntityDirLocator($entity->guid);
417  $file_path = elgg_get_config('dataroot') . $dir;
418  if (file_exists($file_path)) {
419  delete_directory($file_path);
420  }
421 }
422 
423 
426 
434 
435  return $DEFAULT_FILE_STORE;
436 }
437 
445 function set_default_filestore(\ElggFilestore $filestore) {
447 
448  $DEFAULT_FILE_STORE = $filestore;
449 
450  return true;
451 }
452 
461 function elgg_get_file_simple_type($mime_type) {
462  $params = array('mime_type' => $mime_type);
463  return elgg_trigger_plugin_hook('simple_type', 'file', $params, 'general');
464 }
465 
474  global $CONFIG;
475 
476  // Now register a default filestore
477  if (isset($CONFIG->dataroot)) {
478  set_default_filestore(new \ElggDiskFilestore($CONFIG->dataroot));
479  }
480 
481  // Fix MIME type detection for Microsoft zipped formats
482  elgg_register_plugin_hook_handler('mime_type', 'file', '_elgg_filestore_detect_mimetype');
483 
484  // Parse category of file from MIME type
485  elgg_register_plugin_hook_handler('simple_type', 'file', '_elgg_filestore_parse_simpletype');
486 
487  // Unit testing
488  elgg_register_plugin_hook_handler('unit_test', 'system', '_elgg_filestore_test');
489 }
490 
502 function _elgg_filestore_detect_mimetype($hook, $type, $mime_type, $params) {
503 
504  $original_filename = elgg_extract('original_filename', $params);
505 
506  $info = pathinfo($original_filename);
507 
508  // hack for Microsoft zipped formats
509  $office_formats = array('docx', 'xlsx', 'pptx');
510  if ($mime_type == "application/zip" && in_array($info['extension'], $office_formats)) {
511  switch ($info['extension']) {
512  case 'docx':
513  $mime_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
514  break;
515  case 'xlsx':
516  $mime_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
517  break;
518  case 'pptx':
519  $mime_type = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
520  break;
521  }
522  }
523 
524  // check for bad ppt detection
525  if ($mime_type == "application/vnd.ms-office" && $info['extension'] == "ppt") {
526  $mime_type = "application/vnd.ms-powerpoint";
527  }
528 
529  return $mime_type;
530 }
531 
543 function _elgg_filestore_parse_simpletype($hook, $type, $simple_type, $params) {
544 
545  $mime_type = elgg_extract('mime_type', $params);
546 
547  switch ($mime_type) {
548  case "application/msword":
549  case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
550  case "application/pdf":
551  return "document";
552 
553  case "application/ogg":
554  return "audio";
555  }
556 
557  if (preg_match('~^(audio|image|video)/~', $mime_type, $m)) {
558  return $m[1];
559  }
560  if (0 === strpos($mime_type, 'text/') || false !== strpos($mime_type, 'opendocument')) {
561  return "document";
562  }
563 
564  // unrecognized MIME
565  return $simple_type;
566 }
567 
578 function _elgg_filestore_test($hook, $type, $value) {
579  global $CONFIG;
580  $value[] = "{$CONFIG->path}engine/tests/ElggCoreFilestoreTest.php";
581  return $value;
582 }
583 
584 return function(\Elgg\EventsService $events, \Elgg\HooksRegistrationService $hooks) {
585  $events->registerHandler('init', 'system', '_elgg_filestore_init', 100);
586 };
elgg_get_config($name, $site_guid=0)
Get an Elgg configuration value.
$m
Definition: metadata.php:11
$DEFAULT_FILE_STORE
Variable holding the default datastore.
Definition: filestore.php:425
$defaults
$input_name
Definition: item.php:14
$files
Definition: crop.php:36
$value
Definition: longtext.php:26
get_dir_size($dir, $total_size=0)
Get the size of the specified directory.
Definition: filestore.php:18
_elgg_filestore_parse_simpletype($hook, $type, $simple_type, $params)
Parse a file category of file from a MIME type.
Definition: filestore.php:543
$guid
Removes an admin notice.
elgg_extract($key, array $array, $default=null, $strict=true)
Checks for $array[$key] and returns its value if it exists, else returns $default.
Definition: elgglib.php:1246
elgg_register_plugin_hook_handler($hook, $type, $callback, $priority=500)
Definition: elgglib.php:703
if(!$owner||!($owner instanceof ElggUser)||!$owner->canEdit()) $x1
Definition: crop.php:15
get_image_resize_parameters($width, $height, $options)
Calculate the parameters for resizing an image.
Definition: filestore.php:210
get_default_filestore()
Return the default filestore.
Definition: filestore.php:432
$params
Definition: login.php:72
$options
Definition: index.php:14
get_resized_image_from_existing_file($input_name, $maxwidth, $maxheight, $square=false, $x1=0, $y1=0, $x2=0, $y2=0, $upscale=false)
Gets the jpeg contents of the resized version of an already uploaded image (Returns false if the file...
Definition: filestore.php:115
get_uploaded_file($input_name)
Get the contents of an uploaded file.
Definition: filestore.php:43
_elgg_services()
Definition: autoloader.php:14
global $CONFIG
elgg_trigger_plugin_hook($hook, $type, $params=null, $returnvalue=null)
Definition: elgglib.php:775
elgg global
Pointer to the global context.
Definition: elgglib.js:12
$type
Definition: add.php:8
file_delete($guid)
Delete an file.
Definition: filestore.php:333
$y1
Definition: crop.php:16
_elgg_filestore_detect_mimetype($hook, $type, $mime_type, $params)
Fix MIME type detection for Microsoft zipped formats.
Definition: filestore.php:502
get_resized_image_from_uploaded_file($input_name, $maxwidth, $maxheight, $square=false, $upscale=false)
Gets the jpeg contents of the resized version of an uploaded image (Returns false if the uploaded fil...
Definition: filestore.php:75
delete_directory($directory)
Delete a directory and all its contents.
Definition: filestore.php:371
$x2
Definition: crop.php:17
set_default_filestore(\ElggFilestore $filestore)
Set the default filestore for the system.
Definition: filestore.php:445
$entity
Definition: delete.php:10
_elgg_filestore_init()
Initialize the file library.
Definition: filestore.php:473
$path
Definition: invalid.php:17
_elgg_filestore_test($hook, $type, $value)
Unit tests for files.
Definition: filestore.php:578
_elgg_clear_entity_files($entity)
Removes all entity files.
Definition: filestore.php:415
elgg_get_file_simple_type($mime_type)
Returns the category of a file from its MIME type.
Definition: filestore.php:461
get_entity($guid)
Loads and returns an entity object from a guid.
Definition: entities.php:382
$y2
Definition: crop.php:18