Source of file Image.php
Size: 16,789 Bytes - Last Modified: 2021-12-23T10:02:36+00:00
/var/www/docs.ssmods.com/process/src/src/Model/Image.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 | <?php namespace MadeHQ\Cloudinary\Model; class Image extends File { /** * @var string */ private static $table_name = 'CloudinaryImage'; /** * @var array * @config */ private static $non_gravity_crops = ['fit', 'limit', 'mfit', 'pad', 'lpad']; /** * @var array * @config */ private static $valid_image_formats = [ 'jpg', 'gif', 'png', ]; /** * These are basically defaults * @var array */ protected $options = [ 'secure' => true, 'transformation' => [ [ 'quality' => 'auto:eco', 'gravity' => 'auto', 'fetch_format' => 'auto', ], ], ]; /** * Database fields * @var array */ private static $db = [ 'OriginalWidth' => 'Int', 'OriginalHeight' => 'Int', 'OriginalCaption' => 'Text', 'OriginalCredit' => 'Text', 'OriginalColours' => 'Text', ]; /** * @var array */ private static $belongs_to = [ 'ImageLink' => ImageLink::class, ]; /** * Adds a new transformation to an existing one, or appends * it to a brand new one * * @param array $transformation * @param int $index * @param array $remove * @return CachedImage */ public function Transform(array $transformation, $index = 0, array $remove = []) { $clone = $this->toCache(); if (is_null($transformation) || !is_array($transformation)) { return $clone; } $transformations = []; if (array_key_exists('transformation', $clone->options)) { $transformations = $clone->options['transformation']; } if ((int) $index === -1) { $duplicate = false; foreach ($transformations as $old) { $intersection = array_intersect($old, $transformation); if (count($old) === count($intersection)) { $duplicate = true; } } if ($duplicate === false) { array_push($transformations, $transformation); } } else if (array_key_exists('effect', $transformation)) { array_push($transformations, $transformation); } else { $index = (int) $index; if (array_key_exists($index, $transformations)) { $old = $transformations[$index]; foreach ($old as $key=>$value) { if (array_key_exists($key, $remove)) { unset($old[$key]); } } $transformations[$index] = array_merge($old, $transformation); } else { $transformations[$index] = $transformation; } } $clone->options['transformation'] = $transformations; return $clone; } /** * @param int $width * @param int $height * @return CachedImage */ public function Size($width, $height = false) { return $this->Transform([ 'width' => $width, 'height' => $height ]); } /** * @param string $crop * @return CachedImage */ public function Crop(string $crop = 'fill') { return $this->Transform([ 'crop' => $crop ]); } /** * @param int $quality * @return CachedImage */ public function Quality($quality) { return $quality ? $this->setQuality($quality) : $this->setQuality(); } public function setQuality(string $quality= 'auto') { return $this->Transform([ 'quality' => $quality ]); } /** * @param string $gravity * @return CachedImage */ public function Gravity(string $gravity = 'auto') { return $this->Transform([ 'gravity' => $gravity ]); } /** * @param string $fetchFormat * @return CachedImage */ public function FetchFormat(string $fetchFormat = 'auto') { return $this->Transform([ 'fetch_format' => $fetchFormat ]); } /** * @param int $width * @param string $crop * @return CachedImage */ public function ResizeByWidth($width, string $crop = 'fit') { return $this->Transform([ 'width' => $width, 'crop' => $crop ], 0, ['height']); } /** * @param int $height * @param string $crop * @return CachedImage */ public function ResizeByHeight($height, string $crop = 'fit') { return $this->Transform([ 'height' => $height, 'crop' => $crop ], 0, ['width']); } /** * Adds a radius onto the image to round the corners * @param Mixed $radius pass in an integer value to specify radius, or `max` * to round fully or leave blank/0 to remove radius completely * @return this */ public function Radius($radius = 0) { if ($radius) { return $this->Transform([ 'radius' => $radius ]); } return $this->Transform([], 0, ['radius']); } /** * @param string $overlay * @param string $flags * @param string $width * @param string $height * @return CachedImage */ public function Cutout(string $overlay, string $flags = 'cutter.relative', string $width = '1.0', string $height = '1.0') { if (is_null($overlay) || !strlen($overlay)) { return $this; } $transformation = [ 'overlay' => $overlay, 'flags' => $flags, 'width' => $width, 'height' => $height ]; return $this->Transform($transformation, -1); } /** * Applies a raw transformation * * @param string $effect * @param $value * @return CachedImage */ public function Effect(string $effect, $value = null) { if (is_null($effect) || !strlen($effect)) { return $this; } if ($value) { $value = $effect . ':' . $value; } else { $value = $effect; } return $this->Transform([ 'effect' => $value ]); } /** * @param int $value * @return CachedImage */ public function Brightness($value = 0) { if (is_null($value) || !(int) $value) { return $this; } return $this->Effect('brightness', $value); } /** * @param string $darkColour * @param string $lightcolour * @return CachedImage */ public function DuoTone(string $darkColour = '', string $lightColour = null) { // We need at least one value if (trim($darkColour) === '') { return $this; } // Remove hash from dark colour $darkColour = strtolower(str_replace('#', '', $darkColour)); // If first value is a hex, we need a second value too if (strlen($darkColour) === 3 || strlen($darkColour) === 6) { if (!$lightColour) { return $this; } // Remove hash from light colour $lightColour = strtolower(str_replace('#', '', $lightColour)); // Make sure light colour is valid if (!strlen($lightColour) === 3 && !strlen($lightColour) === 6) { return $this; } $duoTone = 'tint:100:' . $darkColour . ':0p:' . $lightColour . ':100p'; } else { $duoTone = $darkColour; } return $this ->Effect('grayscale') ->Effect($duoTone); } /** * Gets the Cloudinary URL for the image at the requested size, crop etc. * NOTE: Uses the `is_bool` check because SS template passes `true`/`false` as string so uses json_decode * @param Int $width * @param Int $height * @param String $crop * @param String $quality * @param String $gravity * @param Boolean $fetchFormat */ public function URL($width = 100, $height = 100, string $crop = null, string $quality = null, string $gravity = null, string $fetchFormat = 'auto') { $object = $this->Size($width, $height); if ($crop) { $object = $object->Crop($crop); } if ($quality) { $object = $object->Quality($quality); } if ($gravity) { $object = $object->Gravity($gravity); } return $object->FetchFormat($fetchFormat); } /** * @return string */ public function forTemplate() { if (!$this->PublicID) { return ''; } $transformations = []; if (array_key_exists('transformation', $this->options)) { $transformations = $this->options['transformation']; } if (array_key_exists('resource_type', $transformations[0]) === false || !$transformations[0]['resource_type']) { $transformations[0]['resource_type'] = $this->ResourceType; } if ($this->ImageLink()->exists()) { if (array_key_exists('gravity', $transformations[0]) === false || $transformations[0]['gravity'] === 'auto') { $transformations[0]['gravity'] = $this->ImageLink()->Focus; } } else if (array_key_exists('gravity', $transformations[0]) === false || !$transformations[0]['gravity']) { $transformations[0]['gravity'] = 'auto'; } // These crops don't support gravity, Cloudinary returns a 400 if passed $nonGravityCrops = static::config()->get('non_gravity_crops'); $isImage = in_array($this->Format, static::config()->get('valid_image_formats')); // Loop through all and apply the generic stuff foreach ($transformations as &$transformation) { // Remove gravity if specific crop is applied if (array_key_exists('crop', $transformation) && in_array($transformation['crop'], $nonGravityCrops) || !array_key_exists('crop', $transformation)) { unset($transformation['gravity']); } if ( !$isImage && (!array_key_exists('width', $transformation) || empty($transformation['width'])) && (!array_key_exists('height', $transformation) || empty($transformation['height'])) ) { unset($transformation['fetch_format']); } } // Grab options $options = $this->options; // Fix type if (!array_key_exists('type', $options)) { $options['type'] = $this->Type; } // Reset the transformations of the object using what we gawt $options['transformation'] = $transformations; // Determine name $fileName = $this->Format ? $this->PublicID . '.' . $this->Format : $this->PublicID; // Generate image URL using options return \Cloudinary::cloudinary_url($fileName, $options); } /** * Makes a cache object * * @return CachedImage */ public function toCache() { if ($this instanceof CachedImage) { return $this; } return CachedImage::create( $this->toMap() ); } /** * Makes a clone * * @return Image */ public function __clone() { return Image::create( $this->toMap() ); } /** * @return string */ public function __toString() { return $this->forTemplate(); } /** * @inheritdoc */ public function Link() { return $this->Quality('auto')->Gravity('auto')->forTemplate(); } /** * @inheritdoc */ public function PreviewLink($action = null) { // Size to width / height $width = (int)$this->config()->get('asset_preview_width'); $height = (int)$this->config()->get('asset_preview_height'); $link = $this->URL($width, $height, 'fill'); $this->extend('updatePreviewLink', $link, $action); return $link->forTemplate(); } public function getWidth($forceFromCloudinary = false) { if ($this->OriginalWidth && !$forceFromCloudinary) { return $this->OriginalWidth; } $this->OriginalWidth = static::get_remote_data($this->PublicID, $this->ResourceType)['width']; return $this->OriginalWidth; } public function getHeight($forceFromCloudinary = false) { if ($this->OriginalHeight && !$forceFromCloudinary) { return $this->OriginalHeight; } $this->OriginalHeight = static::get_remote_data($this->PublicID, $this->ResourceType)['height']; return $this->OriginalHeight; } public function getCredit($forceFromCloudinary = false) { if (!$forceFromCloudinary) { return $this->OriginalCredit; } $remoteData = static::get_remote_data($this->PublicID, $this->ResourceType); if (!is_array($remoteData)) { return $this->OriginalCredit = ''; } if (!array_key_exists('image_metadata', $remoteData)) { return $this->OriginalCredit = ''; } $metadata = $remoteData['image_metadata']; if (array_key_exists('Copyright', $metadata)) { $this->OriginalCredit = $metadata['Copyright']; } else if (array_key_exists('By-line', $metadata)) { $this->OriginalCredit = $metadata['By-line']; } else if (array_key_exists('Artist', $metadata)) { $this->OriginalCredit = $metadata['Artist']; } else if (array_key_exists('Creator', $metadata)) { $this->OriginalCredit = $metadata['Creator']; } else if (array_key_exists('XPAuthor', $metadata)) { $this->OriginalCredit = $metadata['XPAuthor']; } return $this->OriginalCredit; } public function getCaption($forceFromCloudinary = false) { if (!$forceFromCloudinary) { return $this->OriginalCaption; } $remoteData = static::get_remote_data($this->PublicID, $this->ResourceType); $this->OriginalCaption = static::extract_caption($remoteData); return $this->OriginalCaption; } public static function extract_caption($data) { if (!is_array($data)) { return null; } if (!array_key_exists('context', $data)) { return null; } if (!is_array($data['context'])) { return null; } if (!array_key_exists('custom', $data['context'])) { return null; } if (!is_array($data['context']['custom'])) { return null; } if (!array_key_exists('alt', $data['context']['custom'])) { return null; } return $data['context']['custom']['alt']; } public function getColors($forceFromCloudinary = false) { if ($this->OriginalColours && !$forceFromCloudinary) { return json_decode($this->OriginalColours); } $remoteData = static::get_remote_data($this->PublicID, $this->ResourceType); if (!is_array($remoteData)) { return []; } if (!array_key_exists('colors', $remoteData)) { return []; } $this->OriginalColours = json_encode($remoteData['colors']); return $remoteData['colors']; } public function getColorsMap($forceFromCloudinary = false) { $colours = $this->getColors($forceFromCloudinary); if (!is_array($colours)) { return null; } $map = []; foreach ($colours as $color) { list($hex, $strength) = $color; $map[$hex] = $hex; } return $map; } public function updateFromCloudinary($resource) { parent::updateFromCloudinary($resource); $this->getWidth(true); $this->getHeight(true); $this->getCredit(true); $this->getCaption(true); $this->getColors(true); $this->write(); } public static function createFromCloudinaryResource($resource) { $file = parent::createFromCloudinaryResource($resource); $file->getWidth(true); $file->getHeight(true); $file->getCredit(true); $file->getCaption(true); $file->getColors(true); $file->write(); return $file; } } class CachedImage extends Image { /** * Makes a cache object * * @return CachedImage */ public function __clone() { return CachedImage::create( $this->toMap() ); } } |