You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

168 lines
4.4 KiB

<?php
use Kirby\Cms\Media;
class CroppedImage extends Kirby\CMS\File {
private $original;
private $cropField = null;
private $cropData = null;
const FIELD_TYPE = 'imagecrop';
public function __construct($original) {
$this->__debuginfo();
$this->original = $original;
$cropData = $this->getCropData();
if(is_array($cropData) && count($cropData) != 0){
$w = A::get($cropData, "width", $original->width());
$h = A::get($cropData, "height", $original->height());
$x = A::get($cropData, "x", 0);
$y = A::get($cropData, "y", 0);
$originalParts = pathinfo($original->root());
$croppedFileName = sprintf("%s-cropped-w%sh%s-x%sy%s.%s",
$originalParts['filename'],
$w, $h, $x, $y,
$original->extension()
);
$croppedPath = dirname($original->root());
$croppedRoot = $croppedPath . '/' . $croppedFileName;
$oldRoot = $croppedPath . '/' . $original->filename();
$oldCropped = F::similar($oldRoot, "-cropped-*");
$props = array(
'root' => $croppedRoot,
'filename' => $croppedFileName,
'parent' => $original->parent()
);
parent::__construct($props);
if(!$this->exists()){
if(!file_exists($croppedPath)){
mkdir($croppedPath, 0770, true);
}
foreach($oldCropped as $old){
F::remove($old);
}
$cropped = new ImageResize($original->root());
$cropped->freecrop($w, $h, $x, $y)->setMemory()->save($croppedRoot);
unset($cropped);
$cropConfig = $this->getCropField();
$targetSize = $cropConfig["targetSize"];
if(is_array($targetSize)){
$targetW = abs(A::get($targetSize, "width", 0));
$targetH = abs(A::get($targetSize, "height", 0));
if(0 < $targetW){
$image = new ImageResize($croppedRoot);
$image->resizeToWidth($targetW, $allow_enlarge = true)->setMemory()->save($croppedRoot);
unset($image);
}
if(0 < $targetH){
$image = new ImageResize($croppedRoot);
$image->resizeToHeight($targetH, $allow_enlarge = true)->setMemory()->save($croppedRoot);
unset($image);
}
}
}
} else {
$original->propertyData["filename"] = F::safeName($original->filename());
parent::__construct($this->original->propertiesToArray());
}
}
public function getCropData() {
if($this->cropData){
return $this->cropData;
}
if($this->original){
$field = $this->getCropField();
$fieldName = $field["name"];
if($fieldName) {
$this->cropData = $this->original->content()->{$fieldName}()->yaml();
return $this->cropData;
} else {
return array();
}
}
return null;
}
public function getCropField() {
if($this->cropField){
return $this->cropField;
}
if($this->original){
$fields = $this->original->blueprint()->fields();
foreach($fields as $field){
if($field["type"] == CroppedImage::FIELD_TYPE){
$this->cropField = $field;
return $this->cropField;
}
}
}
return null;
}
public function delete(bool $force = false): bool {
//taken from src/kirby/src/Cms/FileActions.php
// remove all versions in the media folder
$this->unpublish();
// remove the lock of the old file
if ($lock = $this->lock()) {
$lock->remove();
}
if ($this->kirby()->multilang() === true) {
foreach ($this->translations() as $translation) {
F::remove($this->contentFile($translation->code()));
}
} else {
F::remove($this->contentFile());
}
F::remove($this->root());
// remove the file from the sibling collection
$this->parent()->files()->remove($this);
return true;
}
public static function croppedImage($requestedFile) {
$media = new CroppedImage($requestedFile);
if($media && $media->exists()){
return $media;
} else {
return $requestedFile;
}
}
public function __debuginfo(): array {
try {
$parent = $this->toArray();
} catch(Throwable $e) {
$parent = [];
}
return array_merge($parent, [
'original' => $this->original,
'cropField' => $this->cropField,
'cropData' => $this->cropData
]);
}
}