From 03bf1dcbd3c9760a15b22df9c04cc6f7b30fbb2d Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Thu, 17 Oct 2019 21:26:15 -0400 Subject: [PATCH] Move Object\Image static methods to Util\Images - Optimize imports in modified files --- include/api.php | 17 +- mod/fbrowser.php | 4 +- mod/photos.php | 7 +- mod/wall_upload.php | 8 +- src/Content/Text/BBCode.php | 7 +- src/Core/Installer.php | 4 +- src/Model/Contact.php | 3 +- src/Model/Photo.php | 6 +- src/Model/User.php | 3 +- src/Object/Image.php | 205 ++++---------------- src/Protocol/ActivityPub/Transmitter.php | 26 +-- src/Protocol/DFRN.php | 3 +- src/Protocol/OStatus.php | 5 +- src/Util/Images.php | 236 +++++++++++++++++++++++ src/Util/ParseUrl.php | 5 +- 15 files changed, 322 insertions(+), 217 deletions(-) create mode 100644 src/Util/Images.php diff --git a/include/api.php b/include/api.php index 24a0585ee5..3bed2aa62c 100644 --- a/include/api.php +++ b/include/api.php @@ -45,6 +45,7 @@ use Friendica\Object\Image; use Friendica\Protocol\Activity; use Friendica\Protocol\Diaspora; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Strings; @@ -1167,7 +1168,7 @@ function api_statuses_update($type) api_user() ); if (DBA::isResult($r)) { - $phototypes = Image::supportedTypes(); + $phototypes = Images::supportedTypes(); $ext = $phototypes[$r[0]['type']]; $description = $r[0]['desc'] ?? ''; $_REQUEST['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $r[0]['nickname'] . '/image/' . $r[0]['resource-id'] . ']'; @@ -2564,7 +2565,7 @@ function api_get_attachments(&$body) $attachments = []; foreach ($images[1] as $image) { - $imagedata = Image::getInfoFromURL($image); + $imagedata = Images::getInfoFromURLCached($image); if ($imagedata) { $attachments[] = ["url" => $image, "mimetype" => $imagedata["mime"], "size" => $imagedata["size"]]; @@ -2711,7 +2712,7 @@ function api_get_entitities(&$text, $bbcode) $start = iconv_strpos($text, $url, $offset, "UTF-8"); if (!($start === false)) { - $image = Image::getInfoFromURL($url); + $image = Images::getInfoFromURLCached($url); if ($image) { // If image cache is activated, then use the following sizes: // thumb (150), small (340), medium (600) and large (1024) @@ -2719,19 +2720,19 @@ function api_get_entitities(&$text, $bbcode) $media_url = ProxyUtils::proxifyUrl($url); $sizes = []; - $scale = Image::getScalingDimensions($image[0], $image[1], 150); + $scale = Images::getScalingDimensions($image[0], $image[1], 150); $sizes["thumb"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; if (($image[0] > 150) || ($image[1] > 150)) { - $scale = Image::getScalingDimensions($image[0], $image[1], 340); + $scale = Images::getScalingDimensions($image[0], $image[1], 340); $sizes["small"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; } - $scale = Image::getScalingDimensions($image[0], $image[1], 600); + $scale = Images::getScalingDimensions($image[0], $image[1], 600); $sizes["medium"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; if (($image[0] > 600) || ($image[1] > 600)) { - $scale = Image::getScalingDimensions($image[0], $image[1], 1024); + $scale = Images::getScalingDimensions($image[0], $image[1], 1024); $sizes["large"] = ["w" => $scale["width"], "h" => $scale["height"], "resize" => "fit"]; } } else { @@ -4740,7 +4741,7 @@ function save_media_to_database($mediatype, $media, $type, $album, $allow_cid, $ } if ($filetype == "") { - $filetype=Image::guessType($filename); + $filetype = Images::guessType($filename); } $imagedata = @getimagesize($src); if ($imagedata) { diff --git a/mod/fbrowser.php b/mod/fbrowser.php index 102d0c613d..b6df3304d4 100644 --- a/mod/fbrowser.php +++ b/mod/fbrowser.php @@ -10,7 +10,7 @@ use Friendica\Core\L10n; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Database\DBA; -use Friendica\Object\Image; +use Friendica\Util\Images; use Friendica\Util\Strings; /** @@ -79,7 +79,7 @@ function fbrowser_content(App $a) function _map_files1($rr) { $a = \get_app(); - $types = Image::supportedTypes(); + $types = Images::supportedTypes(); $ext = $types[$rr['type']]; $filename_e = $rr['filename']; diff --git a/mod/photos.php b/mod/photos.php index 037da64b10..f6b03aa3cb 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -29,6 +29,7 @@ use Friendica\Protocol\Activity; use Friendica\Util\ACLFormatter; use Friendica\Util\Crypto; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Map; use Friendica\Util\Security; use Friendica\Util\Strings; @@ -142,7 +143,7 @@ function photos_post(App $a) Logger::log('mod_photos: REQUEST ' . print_r($_REQUEST, true), Logger::DATA); Logger::log('mod_photos: FILES ' . print_r($_FILES, true), Logger::DATA); - $phototypes = Image::supportedTypes(); + $phototypes = Images::supportedTypes(); $can_post = false; $visitor = 0; @@ -694,7 +695,7 @@ function photos_post(App $a) } if ($type == "") { - $type = Image::guessType($filename); + $type = Images::guessType($filename); } Logger::log('photos: upload: received file: ' . $filename . ' as ' . $src . ' ('. $type . ') ' . $filesize . ' bytes', Logger::DEBUG); @@ -846,7 +847,7 @@ function photos_content(App $a) return; } - $phototypes = Image::supportedTypes(); + $phototypes = Images::supportedTypes(); $_SESSION['photo_return'] = $a->cmd; diff --git a/mod/wall_upload.php b/mod/wall_upload.php index 1224b6dab0..871b9ff141 100644 --- a/mod/wall_upload.php +++ b/mod/wall_upload.php @@ -9,16 +9,16 @@ */ use Friendica\App; +use Friendica\Core\Config; use Friendica\Core\L10n; use Friendica\Core\Logger; -use Friendica\Core\System; use Friendica\Core\Session; -use Friendica\Core\Config; +use Friendica\Core\System; use Friendica\Database\DBA; -use Friendica\Model\Contact; use Friendica\Model\Photo; use Friendica\Model\User; use Friendica\Object\Image; +use Friendica\Util\Images; use Friendica\Util\Strings; function wall_upload_post(App $a, $desktopmode = true) @@ -166,7 +166,7 @@ function wall_upload_post(App $a, $desktopmode = true) } if ($filetype == "") { - $filetype = Image::guessType($filename); + $filetype = Images::guessType($filename); } // If there is a temp name, then do a manual check diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index c3ad23941d..1dffb05073 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -25,6 +25,7 @@ use Friendica\Model\Photo; use Friendica\Network\Probe; use Friendica\Object\Image; use Friendica\Protocol\Activity; +use Friendica\Util\Images; use Friendica\Util\Map; use Friendica\Util\Network; use Friendica\Util\ParseUrl; @@ -76,7 +77,7 @@ class BBCode extends BaseObject if (preg_match("/\[img\](.*?)\[\/img\]/ism", $attacheddata, $matches)) { - $picturedata = Image::getInfoFromURL($matches[1]); + $picturedata = Images::getInfoFromURLCached($matches[1]); if ($picturedata) { if (($picturedata[0] >= 500) && ($picturedata[0] >= $picturedata[1])) { @@ -305,7 +306,7 @@ class BBCode extends BaseObject $post['preview'] = $pictures[0][2]; $post['text'] = trim(str_replace($pictures[0][0], '', $body)); } else { - $imgdata = Image::getInfoFromURL($pictures[0][1]); + $imgdata = Images::getInfoFromURLCached($pictures[0][1]); if ($imgdata && substr($imgdata['mime'], 0, 6) == 'image/') { $post['type'] = 'photo'; $post['image'] = $pictures[0][1]; @@ -446,7 +447,7 @@ class BBCode extends BaseObject } // guess mimetype from headers or filename - $type = Image::guessType($mtch[1], true); + $type = Images::guessType($mtch[1], true); if ($i) { $Image = new Image($i, $type); diff --git a/src/Core/Installer.php b/src/Core/Installer.php index 16d7bf0aad..8bdb00f045 100644 --- a/src/Core/Installer.php +++ b/src/Core/Installer.php @@ -9,7 +9,7 @@ use Exception; use Friendica\Core\Config\Cache\ConfigCache; use Friendica\Database\Database; use Friendica\Database\DBStructure; -use Friendica\Object\Image; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Strings; @@ -569,7 +569,7 @@ class Installer if (class_exists('Imagick')) { $imagick = true; - $supported = Image::supportedTypes(); + $supported = Images::supportedTypes(); if (array_key_exists('image/gif', $supported)) { $gif = true; } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index c7cfddbb84..383d915f56 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -25,6 +25,7 @@ use Friendica\Protocol\Diaspora; use Friendica\Protocol\OStatus; use Friendica\Protocol\Salmon; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Strings; @@ -719,7 +720,7 @@ class Contact extends BaseObject } // Creating the path to the avatar, beginning with the file suffix - $types = Image::supportedTypes(); + $types = Images::supportedTypes(); if (isset($types[$avatar['type']])) { $file_suffix = $types[$avatar['type']]; } diff --git a/src/Model/Photo.php b/src/Model/Photo.php index 4baef04b9b..5de7358f75 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -17,8 +17,8 @@ use Friendica\Database\DBA; use Friendica\Database\DBStructure; use Friendica\Model\Storage\IStorage; use Friendica\Object\Image; -use Friendica\Protocol\DFRN; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Security; use Friendica\Util\Strings; @@ -425,7 +425,7 @@ class Photo extends BaseObject } if (empty($type)) { - $type = Image::guessType($image_url, true); + $type = Images::guessType($image_url, true); } $Image = new Image($img_str, $type); @@ -664,7 +664,7 @@ class Photo extends BaseObject public static function stripExtension($name) { $name = str_replace([".jpg", ".png", ".gif"], ["", "", ""], $name); - foreach (Image::supportedTypes() as $m => $e) { + foreach (Images::supportedTypes() as $m => $e) { $name = str_replace("." . $e, "", $name); } return $name; diff --git a/src/Model/User.php b/src/Model/User.php index 83375115ec..fd12bdaaf2 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -22,6 +22,7 @@ use Friendica\Model\TwoFactor\AppSpecificPassword; use Friendica\Object\Image; use Friendica\Util\Crypto; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Strings; use Friendica\Worker\Delivery; @@ -829,7 +830,7 @@ class User $filename = basename($photo); $img_str = Network::fetchUrl($photo, true); // guess mimetype from headers or filename - $type = Image::guessType($photo, true); + $type = Images::guessType($photo, true); $Image = new Image($img_str, $type); if ($Image->isValid()) { diff --git a/src/Object/Image.php b/src/Object/Image.php index 803aa08b38..972b48359f 100644 --- a/src/Object/Image.php +++ b/src/Object/Image.php @@ -6,11 +6,9 @@ namespace Friendica\Object; use Exception; -use Friendica\Core\Cache; use Friendica\Core\Config; -use Friendica\Core\Logger; use Friendica\Core\System; -use Friendica\Util\Network; +use Friendica\Util\Images; use Imagick; use ImagickPixel; @@ -32,31 +30,6 @@ class Image private $type; private $types; - /** - * @brief supported mimetypes and corresponding file extensions - * @return array - */ - public static function supportedTypes() - { - if (class_exists('Imagick')) { - // Imagick::queryFormats won't help us a lot there... - // At least, not yet, other parts of friendica uses this array - $t = [ - 'image/jpeg' => 'jpg', - 'image/png' => 'png', - 'image/gif' => 'gif' - ]; - } else { - $t = []; - $t['image/jpeg'] ='jpg'; - if (imagetypes() & IMG_PNG) { - $t['image/png'] = 'png'; - } - } - - return $t; - } - /** * @brief Constructor * @param string $data @@ -67,9 +40,9 @@ class Image public function __construct($data, $type = null) { $this->imagick = class_exists('Imagick'); - $this->types = static::supportedTypes(); + $this->types = Images::supportedTypes(); if (!array_key_exists($type, $this->types)) { - $type='image/jpeg'; + $type = 'image/jpeg'; } $this->type = $type; @@ -108,20 +81,6 @@ class Image return $this->imagick; } - /** - * @brief Maps Mime types to Imagick formats - * @return array With with image formats (mime type as key) - */ - public static function getFormatsMap() - { - $m = [ - 'image/jpeg' => 'JPG', - 'image/png' => 'PNG', - 'image/gif' => 'GIF' - ]; - return $m; - } - /** * @param string $data data * @return boolean @@ -142,7 +101,7 @@ class Image /* * Setup the image to the format it will be saved to */ - $map = self::getFormatsMap(); + $map = Images::getFormatsMap(); $format = $map[$this->type]; $this->image->setFormat($format); @@ -712,6 +671,26 @@ class Image return $string; } + /** + * @brief supported mimetypes and corresponding file extensions + * @return array + * @deprecated in version 2019.12 please use Util\Images::supportedTypes() instead. + */ + public static function supportedTypes() + { + return Images::supportedTypes(); + } + + /** + * @brief Maps Mime types to Imagick formats + * @return array With with image formats (mime type as key) + * @deprecated in version 2019.12 please use Util\Images::getFormatsMap() instead. + */ + public static function getFormatsMap() + { + return Images::getFormatsMap(); + } + /** * Guess image mimetype from filename or from Content-Type header * @@ -719,102 +698,24 @@ class Image * @param boolean $fromcurl Check Content-Type header from curl request * @param string $header passed headers to take into account * - * @return object - * @throws \ImagickException + * @return string|null + * @throws Exception + * @deprecated in version 2019.12 please use Util\Images::guessType() instead. */ public static function guessType($filename, $fromcurl = false, $header = '') { - Logger::log('Image: guessType: '.$filename . ($fromcurl?' from curl headers':''), Logger::DEBUG); - $type = null; - if ($fromcurl) { - $headers=[]; - $h = explode("\n", $header); - foreach ($h as $l) { - $data = array_map("trim", explode(":", trim($l), 2)); - if (count($data) > 1) { - list($k,$v) = $data; - $headers[$k] = $v; - } - } - if (array_key_exists('Content-Type', $headers)) - $type = $headers['Content-Type']; - } - if (is_null($type)) { - // Guessing from extension? Isn't that... dangerous? - if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) { - /** - * Well, this not much better, - * but at least it comes from the data inside the image, - * we won't be tricked by a manipulated extension - */ - $image = new Imagick($filename); - $type = $image->getImageMimeType(); - $image->setInterlaceScheme(Imagick::INTERLACE_PLANE); - } else { - $ext = pathinfo($filename, PATHINFO_EXTENSION); - $types = self::supportedTypes(); - $type = "image/jpeg"; - foreach ($types as $m => $e) { - if ($ext == $e) { - $type = $m; - } - } - } - } - Logger::log('Image: guessType: type='.$type, Logger::DEBUG); - return $type; + return Images::guessType($filename, $fromcurl, $header); } /** * @param string $url url - * @return object + * @return array * @throws \Friendica\Network\HTTPException\InternalServerErrorException + * @deprecated in version 2019.12 please use Util\Images::getInfoFromURLCached() instead. */ public static function getInfoFromURL($url) { - $data = []; - - if (empty($url)) { - return $data; - } - - $data = Cache::get($url); - - if (is_null($data) || !$data || !is_array($data)) { - $img_str = Network::fetchUrl($url, true, 4); - - if (!$img_str) { - return false; - } - - $filesize = strlen($img_str); - - try { - if (function_exists("getimagesizefromstring")) { - $data = @getimagesizefromstring($img_str); - } else { - $tempfile = tempnam(get_temppath(), "cache"); - - $a = \get_app(); - $stamp1 = microtime(true); - file_put_contents($tempfile, $img_str); - $a->getProfiler()->saveTimestamp($stamp1, "file", System::callstack()); - - $data = getimagesize($tempfile); - unlink($tempfile); - } - } catch (Exception $e) { - return false; - } - - if ($data) { - $data["size"] = $filesize; - } - - Cache::set($url, $data); - } - - return $data; + return Images::getInfoFromURLCached($url); } /** @@ -822,50 +723,10 @@ class Image * @param integer $height height * @param integer $max max * @return array + * @deprecated in version 2019.12 please use Util\Images::getScalingDimensions() instead. */ public static function getScalingDimensions($width, $height, $max) { - if ((!$width) || (!$height)) { - return false; - } - - if ($width > $max && $height > $max) { - // very tall image (greater than 16:9) - // constrain the width - let the height float. - - if ((($height * 9) / 16) > $width) { - $dest_width = $max; - $dest_height = intval(($height * $max) / $width); - } elseif ($width > $height) { - // else constrain both dimensions - $dest_width = $max; - $dest_height = intval(($height * $max) / $width); - } else { - $dest_width = intval(($width * $max) / $height); - $dest_height = $max; - } - } else { - if ($width > $max) { - $dest_width = $max; - $dest_height = intval(($height * $max) / $width); - } else { - if ($height > $max) { - // very tall image (greater than 16:9) - // but width is OK - don't do anything - - if ((($height * 9) / 16) > $width) { - $dest_width = $width; - $dest_height = $height; - } else { - $dest_width = intval(($width * $max) / $height); - $dest_height = $max; - } - } else { - $dest_width = $width; - $dest_height = $height; - } - } - } - return ["width" => $dest_width, "height" => $dest_height]; + return Images::getScalingDimensions($width, $height, $max); } } diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php index 531b4c6621..d804d7ca4f 100644 --- a/src/Protocol/ActivityPub/Transmitter.php +++ b/src/Protocol/ActivityPub/Transmitter.php @@ -6,31 +6,33 @@ namespace Friendica\Protocol\ActivityPub; use Friendica\BaseObject; use Friendica\Content\Feature; -use Friendica\Database\DBA; +use Friendica\Content\Text\BBCode; +use Friendica\Content\Text\Plaintext; +use Friendica\Core\Cache; use Friendica\Core\Config; use Friendica\Core\Logger; use Friendica\Core\System; use Friendica\Protocol\Activity; use Friendica\Util\HTTPSignature; use Friendica\Core\Protocol; -use Friendica\Model\Conversation; -use Friendica\Model\Contact; +use Friendica\Core\System; +use Friendica\Database\DBA; use Friendica\Model\APContact; +use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\Item; +use Friendica\Model\Profile; use Friendica\Model\Term; use Friendica\Model\User; +use Friendica\Protocol\ActivityPub; use Friendica\Util\DateTimeFormat; -use Friendica\Content\Text\BBCode; -use Friendica\Content\Text\Plaintext; -use Friendica\Util\XML; +use Friendica\Util\HTTPSignature; +use Friendica\Util\Images; use Friendica\Util\JsonLD; use Friendica\Util\LDSignature; -use Friendica\Model\Profile; -use Friendica\Object\Image; -use Friendica\Protocol\ActivityPub; -use Friendica\Core\Cache; use Friendica\Util\Map; use Friendica\Util\Network; +use Friendica\Util\XML; require_once 'include/api.php'; require_once 'mod/share.php'; @@ -1049,7 +1051,7 @@ class Transmitter // Grab all pictures without alternative descriptions and create attachments out of them if (preg_match_all("/\[img\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures)) { foreach ($pictures[1] as $picture) { - $imgdata = Image::getInfoFromURL($picture); + $imgdata = Images::getInfoFromURLCached($picture); if ($imgdata) { $attachments[] = ['type' => 'Document', 'mediaType' => $imgdata['mime'], @@ -1062,7 +1064,7 @@ class Transmitter // Grab all pictures with alternative description and create attachments out of them if (preg_match_all("/\[img=([^\[\]]*)\]([^\[\]]*)\[\/img\]/Usi", $body, $pictures, PREG_SET_ORDER)) { foreach ($pictures as $picture) { - $imgdata = Image::getInfoFromURL($picture[1]); + $imgdata = Images::getInfoFromURLCached($picture[1]); if ($imgdata) { $attachments[] = ['type' => 'Document', 'mediaType' => $imgdata['mime'], diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 2016c7339d..0b6e02f096 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -35,6 +35,7 @@ use Friendica\Object\Image; use Friendica\Protocol\ActivityNamespace; use Friendica\Util\Crypto; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Strings; use Friendica\Util\XML; @@ -504,7 +505,7 @@ class DFRN $uid ); $photos = []; - $ext = Image::supportedTypes(); + $ext = Images::supportedTypes(); foreach ($rp as $p) { $photos[$p['scale']] = System::baseUrl().'/photo/'.$p['resource-id'].'-'.$p['scale'].'.'.$ext[$p['type']]; diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index c88a740c0e..597645a8ec 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -27,6 +27,7 @@ use Friendica\Network\Probe; use Friendica\Object\Image; use Friendica\Protocol\ActivityNamespace; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Images; use Friendica\Util\Network; use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Strings; @@ -1389,7 +1390,7 @@ class OStatus switch ($siteinfo["type"]) { case 'photo': if (!empty($siteinfo["image"])) { - $imgdata = Image::getInfoFromURL($siteinfo["image"]); + $imgdata = Images::getInfoFromURLCached($siteinfo["image"]); if ($imgdata) { $attributes = ["rel" => "enclosure", "href" => $siteinfo["image"], @@ -1413,7 +1414,7 @@ class OStatus } if (!Config::get('system', 'ostatus_not_attach_preview') && ($siteinfo["type"] != "photo") && isset($siteinfo["image"])) { - $imgdata = Image::getInfoFromURL($siteinfo["image"]); + $imgdata = Images::getInfoFromURLCached($siteinfo["image"]); if ($imgdata) { $attributes = ["rel" => "enclosure", "href" => $siteinfo["image"], diff --git a/src/Util/Images.php b/src/Util/Images.php new file mode 100644 index 0000000000..c69c944c0e --- /dev/null +++ b/src/Util/Images.php @@ -0,0 +1,236 @@ + 'JPG', + 'image/png' => 'PNG', + 'image/gif' => 'GIF' + ]; + + return $m; + } + + /** + * Returns supported image mimetypes and corresponding file extensions + * + * @return array + */ + public static function supportedTypes() + { + $types = [ + 'image/jpeg' => 'jpg' + ]; + if (class_exists('Imagick')) { + // Imagick::queryFormats won't help us a lot there... + // At least, not yet, other parts of friendica uses this array + $types += [ + 'image/png' => 'png', + 'image/gif' => 'gif' + ]; + } elseif (imagetypes() & IMG_PNG) { + $types += [ + 'image/png' => 'png' + ]; + } + + return $types; + } + + /** + * Guess image mimetype from filename or from Content-Type header + * + * @param string $filename Image filename + * @param boolean $fromcurl Check Content-Type header from curl request + * @param string $header passed headers to take into account + * + * @return string|null + * @throws \Exception + */ + public static function guessType($filename, $fromcurl = false, $header = '') + { + Logger::info('Image: guessType: ' . $filename . ($fromcurl ? ' from curl headers' : '')); + $type = null; + if ($fromcurl) { + $headers = []; + $h = explode("\n", $header); + foreach ($h as $l) { + $data = array_map("trim", explode(":", trim($l), 2)); + if (count($data) > 1) { + list($k, $v) = $data; + $headers[$k] = $v; + } + } + + if (array_key_exists('Content-Type', $headers)) { + $type = $headers['Content-Type']; + } + } + + if (is_null($type)) { + // Guessing from extension? Isn't that... dangerous? + if (class_exists('Imagick') && file_exists($filename) && is_readable($filename)) { + /** + * Well, this not much better, + * but at least it comes from the data inside the image, + * we won't be tricked by a manipulated extension + */ + $image = new Imagick($filename); + $type = $image->getImageMimeType(); + } else { + $ext = pathinfo($filename, PATHINFO_EXTENSION); + $types = self::supportedTypes(); + $type = 'image/jpeg'; + foreach ($types as $m => $e) { + if ($ext == $e) { + $type = $m; + } + } + } + } + + Logger::info('Image: guessType: type=' . $type); + return $type; + } + + + /** + * @param string $url + * @return array + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + public static function getInfoFromURLCached($url) + { + $data = []; + + if (empty($url)) { + return $data; + } + + $data = Cache::get($url); + + if (empty($data) || !is_array($data)) { + $data = self::getInfoFromURL($url); + + Cache::set($url, $data); + } + + return $data; + } + + /** + * @param string $url + * @return array + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + public static function getInfoFromURL($url) + { + $data = []; + + if (empty($url)) { + return $data; + } + + $img_str = Network::fetchUrl($url, true, 4); + + if (!$img_str) { + return []; + } + + $filesize = strlen($img_str); + + try { + if (function_exists("getimagesizefromstring")) { + $data = @getimagesizefromstring($img_str); + } else { + $tempfile = tempnam(get_temppath(), "cache"); + + $stamp1 = microtime(true); + file_put_contents($tempfile, $img_str); + BaseObject::getApp()->getProfiler()->saveTimestamp($stamp1, "file", System::callstack()); + + $data = getimagesize($tempfile); + unlink($tempfile); + } + } catch (\Exception $e) { + return []; + } + + if ($data) { + $data['size'] = $filesize; + } + + return $data; + } + + /** + * @param integer $width + * @param integer $height + * @param integer $max + * @return array + */ + public static function getScalingDimensions($width, $height, $max) + { + if ((!$width) || (!$height)) { + return ['width' => 0, 'height' => 0]; + } + + if ($width > $max && $height > $max) { + // very tall image (greater than 16:9) + // constrain the width - let the height float. + + if ((($height * 9) / 16) > $width) { + $dest_width = $max; + $dest_height = intval(($height * $max) / $width); + } elseif ($width > $height) { + // else constrain both dimensions + $dest_width = $max; + $dest_height = intval(($height * $max) / $width); + } else { + $dest_width = intval(($width * $max) / $height); + $dest_height = $max; + } + } else { + if ($width > $max) { + $dest_width = $max; + $dest_height = intval(($height * $max) / $width); + } else { + if ($height > $max) { + // very tall image (greater than 16:9) + // but width is OK - don't do anything + + if ((($height * 9) / 16) > $width) { + $dest_width = $width; + $dest_height = $height; + } else { + $dest_width = intval(($width * $max) / $height); + $dest_height = $max; + } + } else { + $dest_width = $width; + $dest_height = $height; + } + } + } + + return ['width' => $dest_width, 'height' => $dest_height]; + } +} diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index 4590f39a99..1f8fbdeabe 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -11,7 +11,6 @@ use Friendica\Content\OEmbed; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Database\DBA; -use Friendica\Object\Image; /** * @brief Class with methods for extracting certain content from an url @@ -348,7 +347,7 @@ class ParseUrl } $src = self::completeUrl($img_tag['src'], $url); - $photodata = Image::getInfoFromURL($src); + $photodata = Images::getInfoFromURLCached($src); if (($photodata) && ($photodata[0] > 150) && ($photodata[1] > 150)) { if ($photodata[0] > 300) { @@ -371,7 +370,7 @@ class ParseUrl unset($siteinfo['image']); - $photodata = Image::getInfoFromURL($src); + $photodata = Images::getInfoFromURLCached($src); if (($photodata) && ($photodata[0] > 10) && ($photodata[1] > 10)) { $siteinfo['images'][] = ['src' => $src,