Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnysideup committed Feb 7, 2023
1 parent dd72cbd commit b101f21
Show file tree
Hide file tree
Showing 5 changed files with 1,021 additions and 5 deletions.
8 changes: 5 additions & 3 deletions src/Api/ImageManipulations.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Convert;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\ORM\DataObject;
use SilverStripe\SiteConfig\SiteConfig;
use Sunnysideup\PerfectCmsImages\Model\PerfectCMSImageCache;

class ImageManipulations
{
Expand Down Expand Up @@ -52,7 +54,7 @@ public static function get_image_link($image, string $name, ?bool $useRetina = n
)
);
if (empty(self::$imageLinkCache[$cacheKey])) {
$item = DataObject::get_one(PerfectCMSImageCache::class, ['Code' => $cacheKey]);
$item = DataObject::get_one(PerfectCMSImageCache::class, ['Code' => $cacheKey, 'ImageID' => $image->ID]);
if ($item) {
return $item->Link;
}
Expand Down Expand Up @@ -127,11 +129,11 @@ public static function get_image_link($image, string $name, ?bool $useRetina = n
$tmpImage = $image;
}
$link = '';
if($tmpImage) {
if ($tmpImage) {
$link = (string) $tmpImage->getUrl();
PerfectCMSImageCache::add_one($cacheKey, $link, $image);
}
self::$imageLinkCache[$cacheKey] = $link;
PerfectCMSImageCache::add_one($cacheKey, $link);
}

return self::$imageLinkCache[$cacheKey];
Expand Down
316 changes: 316 additions & 0 deletions src/Api/ImageManipulations.php.orig
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
<?php

namespace Sunnysideup\PerfectCmsImages\Api;

use SilverStripe\Assets\Image;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Convert;
<<<<<<< HEAD
use SilverStripe\ORM\DataObject;
=======
use SilverStripe\Core\Injector\Injectable;
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
use SilverStripe\SiteConfig\SiteConfig;
use Sunnysideup\PerfectCmsImages\Model\PerfectCMSImageCache;

class ImageManipulations
{
use Configurable;
use Injectable;

private static $webp_enabled = true;

private static $webp_quality = 77;

private static $imageLinkCache = [];

/**
* work out the best image link.
*
* There are basically three options:
* a. if the height and/or width matches or is smaller than it should be
* then just return natural image
* b. if crop is set to true then Fill
* c. otherwise resize Height/Width/Both
*
* @param Image $image
* @param null|bool $useRetina optional
* @param null|bool $forMobile optional
* @param null|int $resizeToWidth optional
*/
public static function get_image_link($image, string $name, ?bool $useRetina = null, ?bool $forMobile = null, ?int $resizeToWidth = 0): string
{
$cacheKey =
implode(
'_',
array_filter(
[
$image->ID,
$name,
($useRetina ? 'Y' : 'N'),
($forMobile ? 'MY' : 'MN'),
$resizeToWidth
]
)
);
if (empty(self::$imageLinkCache[$cacheKey])) {
<<<<<<< HEAD
$item = DataObject::get_one(PerfectCMSImageCache::class, ['Code' => $cacheKey]);
if ($item) {
return $item->Link;
}
=======
$link = '';
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
//work out perfect width and height
if (null === $useRetina) {
$useRetina = PerfectCMSImages::use_retina($name);
}

$crop = PerfectCMSImages::is_crop($name);

$multiplier = PerfectCMSImages::get_multiplier($useRetina);
$perfectWidth = (int) PerfectCMSImages::get_width($name, true);
$perfectHeight = (int) PerfectCMSImages::get_height($name, true);

if ($forMobile) {
$perfectWidth = (int) PerfectCMSImages::get_mobile_width($name, true);
$perfectHeight = (int) PerfectCMSImages::get_mobile_height($name, true);
}

$perfectWidth *= $multiplier;
$perfectHeight *= $multiplier;

//get current width and height
$myWidth = $image->getWidth();
$myHeight = $image->getHeight();
<<<<<<< HEAD

//if we are trying to resize to a width that is smaller than the perfect width
=======
//if we are trying to resize to a width that is small than the perfect width
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
//and the resize width is small than the current width, then lets resize...
if (0 !== (int) $resizeToWidth) {
if ($resizeToWidth < $perfectWidth && $resizeToWidth < $myWidth) {
$perfectWidth = $resizeToWidth;
}
}

$tmpImage = null;
if ($perfectWidth && $perfectHeight) {
if ($myWidth === $perfectWidth && $myHeight === $perfectHeight) {
<<<<<<< HEAD
// perfect already?
$link = $image->Link();
} elseif ($myWidth < $perfectWidth || $myHeight < $perfectHeight) {
// too small? adding padding.
$link = $image->Pad(
=======
$tmpImage = $image;
} elseif ($myWidth < $perfectWidth || $myHeight < $perfectHeight) {
$tmpImage = $image->Pad(
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
$perfectWidth,
$perfectHeight,
PerfectCMSImages::get_padding_bg_colour($name)
);
} elseif ($crop) {
<<<<<<< HEAD
// first of two situations where we make it smaller.
$link = $image->Fill($perfectWidth, $perfectHeight)->Link();
} else {
// second of two situations where we make it smaller.
$link = $image->FitMax($perfectWidth, $perfectHeight)->Link();
}
} elseif ($perfectWidth) {
if ($myWidth === $perfectWidth) {
// perfect already?
$link = $image->Link();
=======
$tmpImage = $image->Fill($perfectWidth, $perfectHeight);
} else {
$tmpImage = $image->FitMax($perfectWidth, $perfectHeight);
}
} elseif ($perfectWidth) {
if ($myWidth === $perfectWidth) {
$tmpImage = $image;
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
} elseif ($crop) {
$tmpImage = $image->Fill($perfectWidth, $myHeight);
} else {
$tmpImage = $image->ScaleWidth($perfectWidth);
}
} elseif ($perfectHeight) {
if ($myHeight === $perfectHeight) {
$tmpImage = $image;
} elseif ($crop) {
$tmpImage = $image->Fill($myWidth, $perfectHeight);
} else {
$tmpImage = $image->ScaleHeight($perfectHeight);
}
} elseif ($forMobile) {
// todo: expplain this!
// basically, it is for mobile and there is not perfect height nor width
$tmpImage = null;
} else {
$tmpImage = $image;
}
<<<<<<< HEAD
self::$imageLinkCache[$cacheKey] = $link;
PerfectCMSImageCache::add_one($cacheKey, $link);
=======
if ($tmpImage) {
$link = $tmpImage->Link();
}

self::$imageLinkCache[$cacheKey] = (string) $link;
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
}

return self::$imageLinkCache[$cacheKey];
}

/**
* back-up image.
*
* @return null|Image
*/
public static function get_backup_image(string $name)
{
$image = null;
$backupObject = SiteConfig::current_site_config();
if ($backupObject->hasMethod($name)) {
$image = $backupObject->{$name}();
}

return $image;
}

/**
* placeholder image.
*/
public static function get_placeholder_image_tag(string $name): string
{
$multiplier = (int) PerfectCMSImages::get_multiplier(true);
$perfectWidth = (int) PerfectCMSImages::get_width($name, true);
$perfectHeight = (int) PerfectCMSImages::get_height($name, true);
$perfectWidth *= $multiplier;
$perfectHeight *= $multiplier;
if ($perfectWidth || $perfectHeight) {
if (0 === $perfectWidth && $perfectHeight === 0) {
$perfectWidth = 200;
} elseif (0 === $perfectWidth) {
$perfectWidth = $perfectHeight;
<<<<<<< HEAD
} elseif ($perfectHeight === 0) {
=======
}

if (! $perfectHeight) {
>>>>>>> 091b64056c310a6826e99524cafb4e823be247ff
$perfectHeight = $perfectWidth;
}

$text = "{$perfectWidth} x {$perfectHeight} /2 = " . round($perfectWidth / 2) . ' x ' . round($perfectHeight / 2) . '';

return 'https://placehold.it/' . $perfectWidth . 'x' . $perfectHeight . '?text=' . urlencode($text);
}

return 'https://placehold.it/1500x1500?text=' . urlencode('no size set');
}

public static function web_p_link(string $link): string
{
if (self::web_p_enabled() && $link) {
$fileNameWithBaseFolder = Director::baseFolder() . '/public' . $link;
$arrayOfLink = explode('.', $link);
$extension = array_pop($arrayOfLink);
$pathWithoutExtension = rtrim($link, '.' . $extension);
$webPFileName = $pathWithoutExtension . '_' . $extension . '.webp';
$webPFileNameWithBaseFolder = Director::baseFolder() . '/public' . $webPFileName;
if (file_exists($fileNameWithBaseFolder)) {
if (isset($_GET['flush']) && file_exists($webPFileNameWithBaseFolder)) {
unlink($webPFileNameWithBaseFolder);
}

if (file_exists($webPFileNameWithBaseFolder)) {
//todo: check that image is the same ...
} else {
list($width, $height, $type) = getimagesize($fileNameWithBaseFolder);
$img = null;
if ($width && $height) {
if (2 === $type) {
$img = imagecreatefromjpeg($fileNameWithBaseFolder);
} elseif (3 === $type) {
$img = imagecreatefrompng($fileNameWithBaseFolder);
imagesavealpha($img, true);
}

if (null !== $img) {
$quality = Config::inst()->get(ImageManipulations::class, 'webp_quality');
imagewebp($img, $webPFileNameWithBaseFolder, $quality);
}
}
}

return $webPFileName;
}
}

return $link;
}

public static function add_fake_parts($image, string $link): string
{
// first get the timestamp
$time1 = strtotime((string) $image->LastEdited);
$time2 = 0;
$path = Controller::join_links(Director::baseFolder(), PUBLIC_DIR, $link);
if (file_exists($path)) {
$time2 = filemtime($path);
}

// first convert to hash extension
if (class_exists('HashPathExtension')) {
/** @var null|Controller $curr */
$curr = Controller::curr();
if ($curr) {
if ($curr->hasMethod('HashPath')) {
$link = $curr->HashPath($link, false);
}
}
}

// now you can add the time
$link .= '?time=' . max($time1, $time2);

// finally add the title
if ($image->Title) {
$imageClasses = Config::inst()->get(PerfectCMSImages::class, 'perfect_cms_images_append_title_to_image_links_classes');
if (in_array($image->ClassName, $imageClasses, true)) {
$link .= '&title=' . urlencode(Convert::raw2att($image->Title));
}
}

return $link;
}

public static function web_p_enabled(): bool
{
if (Config::inst()->get(ImageManipulations::class, 'webp_enabled')) {
if (function_exists('imagewebp')) {
if (function_exists('imagecreatefromjpeg')) {
if (function_exists('imagecreatefrompng')) {
return true;
}
}
}
}

return false;
}
}
Loading

0 comments on commit b101f21

Please sign in to comment.