<?php
+/**
+ * @copyright Copyright (C) 2010-2022, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
namespace Friendica\Util;
-use Friendica\Core\Cache;
use Friendica\Core\Logger;
-use Friendica\Core\System;
use Friendica\DI;
-use Imagick;
+use Friendica\Model\Photo;
/**
* Image utilities
return $m;
}
+ /**
+ * Return file extension for mime type
+ * @param string $mimetype
+ * @return string
+ */
+ public static function getExtensionByMimeType(string $mimetype): string
+ {
+ switch ($mimetype) {
+ case 'image/png':
+ $imagetype = IMAGETYPE_PNG;
+ break;
+
+ case 'image/gif':
+ $imagetype = IMAGETYPE_GIF;
+ break;
+
+ default:
+ $imagetype = IMAGETYPE_JPEG;
+ break;
+ }
+
+ return image_type_to_extension($imagetype);
+ }
+
/**
* Returns supported image mimetypes and corresponding file extensions
*
}
/**
- * Guess image mimetype from filename or from Content-Type header
+ * Fetch image mimetype from the image data or guessing from the file name
*
- * @param string $filename Image filename
- * @param boolean $fromcurl Check Content-Type header from curl request
- * @param string $header passed headers to take into account
+ * @param string $image_data Image data
+ * @param string $filename File name (for guessing the type via the extension)
+ * @param string $mime default mime type
*
- * @return string|null
+ * @return string
* @throws \Exception
*/
- public static function guessType($filename, $fromcurl = false, $header = '')
+ public static function getMimeTypeByData(string $image_data, string $filename = '', string $mime = '')
{
- 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 (substr($mime, 0, 6) == 'image/') {
+ Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]);
+ return $mime;
+ }
- if (array_key_exists('Content-Type', $headers)) {
- $type = $headers['Content-Type'];
- }
+ $image = @getimagesizefromstring($image_data);
+ if (!empty($image['mime'])) {
+ Logger::info('Mime type detected via data', ['filename' => $filename, 'default' => $mime, 'mime' => $image['mime']]);
+ return $image['mime'];
}
- 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;
- }
- }
+ return self::guessTypeByExtension($filename);
+ }
+
+ /**
+ * Fetch image mimetype from the image data or guessing from the file name
+ *
+ * @param string $sourcefile Source file of the image
+ * @param string $filename File name (for guessing the type via the extension)
+ * @param string $mime default mime type
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public static function getMimeTypeBySource(string $sourcefile, string $filename = '', string $mime = '')
+ {
+ if (substr($mime, 0, 6) == 'image/') {
+ Logger::info('Using default mime type', ['filename' => $filename, 'mime' => $mime]);
+ return $mime;
+ }
+
+ $image = @getimagesize($sourcefile);
+ if (!empty($image['mime'])) {
+ Logger::info('Mime type detected via file', ['filename' => $filename, 'default' => $mime, 'image' => $image]);
+ return $image['mime'];
+ }
+
+ return self::guessTypeByExtension($filename);
+ }
+
+ /**
+ * Guess image mimetype from the filename
+ *
+ * @param string $filename Image filename
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public static function guessTypeByExtension(string $filename)
+ {
+ $ext = pathinfo(parse_url($filename, PHP_URL_PATH), PATHINFO_EXTENSION);
+ $types = self::supportedTypes();
+ $type = 'image/jpeg';
+ foreach ($types as $m => $e) {
+ if ($ext == $e) {
+ $type = $m;
}
}
- Logger::info('Image: guessType: type=' . $type);
+ Logger::info('Mime type guessed via extension', ['filename' => $filename, 'type' => $type]);
return $type;
}
-
/**
* @param string $url
* @return array
return $data;
}
- $data = Cache::get($url);
+ $cacheKey = 'getInfoFromURL:' . sha1($url);
+
+ $data = DI::cache()->get($cacheKey);
if (empty($data) || !is_array($data)) {
$data = self::getInfoFromURL($url);
- DI::cache()->set($url, $data);
+ DI::cache()->set($cacheKey, $data);
}
return $data;
return $data;
}
- $img_str = Network::fetchUrl($url, true, 4);
+ if (Network::isLocalLink($url) && ($data = Photo::getResourceData($url))) {
+ $photo = Photo::selectFirst([], ['resource-id' => $data['guid'], 'scale' => $data['scale']]);
+ if (!empty($photo)) {
+ $img_str = Photo::getImageDataForPhoto($photo);
+ }
+ // @todo Possibly add a check for locally stored files
+ }
+
+ if (empty($img_str)) {
+ $img_str = DI::httpClient()->fetch($url, 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);
- DI::profiler()->saveTimestamp($stamp1, "file", System::callstack());
-
- $data = getimagesize($tempfile);
- unlink($tempfile);
- }
+ $data = @getimagesizefromstring($img_str);
} catch (\Exception $e) {
return [];
}