public function saveIcon(ElggEntity $entity, ElggFile $file, $type = 'icon', array $coords = array())
{
$entity_type = $entity->getType();
$entity_subtype = $entity->getSubtype();
$x1 = (int) elgg_extract('x1', $coords);
$y1 = (int) elgg_extract('y1', $coords);
$x2 = (int) elgg_extract('x2', $coords);
$y2 = (int) elgg_extract('y2', $coords);
$file = $this->hooks->trigger("entity:{$type}:prepare", $entity_type, ['entity' => $entity, 'file' => $file], $file);
if (!$file instanceof ElggFile || !$file->exists() || $file->getSimpleType() !== 'image') {
$this->logger->error('Source file passed to ' . __METHOD__ . ' can not be resolved to a valid image');
return false;
}
$cropping_mode = $x2 > $x1 && $y2 > $y1;
if (!$cropping_mode) {
$this->deleteIcon($entity, $type);
}
$success = function () use($entity, $type, $x1, $y1, $x2, $y2) {
if ($type == 'icon') {
$entity->icontime = time();
if ($x1 || $y1 || $x2 || $y2) {
$entity->x1 = $x1;
$entity->y1 = $y1;
$entity->x2 = $x2;
$entity->y2 = $y2;
}
}
$this->hooks->trigger("entity:{$type}:saved", $entity->getType(), ['entity' => $entity, 'x1' => $x1, 'y1' => $y1, 'x2' => $x2, 'y2' => $y2]);
return true;
};
$fail = function () use($entity, $type) {
$this->deleteIcon($entity, $type);
return false;
};
$created = $this->hooks->trigger("entity:{$type}:save", $entity_type, ['entity' => $entity, 'file' => $file, 'x1' => $x1, 'y1' => $y1, 'x2' => $x2, 'y2' => $y2], false);
if ($created === true) {
return $success();
}
$sizes = $this->getSizes($entity_type, $entity_subtype, $type);
foreach ($sizes as $size => $opts) {
$square = (bool) elgg_extract('square', $opts);
if ($type === 'icon' && $cropping_mode) {
// Do not crop out non-square icons if cropping coordinates are a square
$cropping_ratio = ($x2 - $x1) / ($y2 - $y1);
if ($cropping_ratio == 1 && $square === false) {
continue;
}
}
$icon = $this->getIcon($entity, $size, $type);
// We need to make sure that file path is readable by
// Imagine\Image\ImagineInterface::save(), as it fails to
// build the directory structure on owner's filestore otherwise
$icon->open('write');
$icon->close();
// Save the image without resizing or cropping if the
// image size value is an empty array
if (is_array($opts) && empty($opts)) {
copy($file->getFilenameOnFilestore(), $icon->getFilenameOnFilestore());
continue;
}
$source = $file->getFilenameOnFilestore();
$destination = $icon->getFilenameOnFilestore();
$resize_params = array_merge($opts, $coords);
if (!_elgg_services()->imageService->resize($source, $destination, $resize_params)) {
$this->logger->error("Failed to create {$size} icon from\n\t\t\t\t\t{$file->getFilenameOnFilestore()} with coords [{$x1}, {$y1}],[{$x2}, {$y2}]");
return $fail();
}
}
return $success();
}