oont-contents/plugins/mailpoet/lib/NewsletterTemplates/TemplateImageLoader.php
2025-02-08 15:10:23 +01:00

88 lines
2.3 KiB
PHP

<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\NewsletterTemplates;
if (!defined('ABSPATH')) exit;
use MailPoet\WP\Functions as WPFunctions;
class TemplateImageLoader {
const TIMEOUT = 30; // seconds
/** @var WPFunctions */
private $wp;
public function __construct(
WPFunctions $wp
) {
$this->wp = $wp;
}
/**
* Acts as a proxy for html2canvas
*/
public function loadExternalImage(string $url) {
if (!$this->isUrlAllowed($url)) {
// URL not allowed
return false;
}
$image = $this->downloadUrl($url);
if ($this->wp->isWpError($image)) {
// Failed to load the image
return false;
}
$mime = $this->wp->wpGetImageMime($image);
if (!$this->isTypeAllowed($image, $mime)) {
// Wrong file type
@unlink($image);
return false;
}
header('Content-Type: ' . $mime);
readfile($image);
@unlink($image);
return true;
}
protected function downloadUrl($url) {
require_once ABSPATH . '/wp-admin/includes/file.php';
return download_url($url, self::TIMEOUT);
}
private function isUrlAllowed($url) {
$urlParts = $this->wp->wpParseUrl($url);
$allowedExtensions = ['gif', 'png', 'jpg', 'jpeg'];
if (
!isset($urlParts['path'])
|| !preg_match('/\.(' . join('|', $allowedExtensions) . ')$/i', $urlParts['path'])
) {
return false;
}
/** @var string[] */
$allowedUrls = (array)$this->wp->applyFilters('mailpoet_template_image_allowed_urls', [
'https://ps.w.org/mailpoet/assets/newsletter-templates/',
]);
foreach ($allowedUrls as $allowedUrl) {
$allowedUrlParts = $this->wp->wpParseUrl($allowedUrl);
if (
isset($urlParts['host'], $urlParts['scheme'])
&& isset($allowedUrlParts['host'], $allowedUrlParts['scheme'], $allowedUrlParts['path'])
&& $urlParts['host'] === $allowedUrlParts['host']
&& $urlParts['scheme'] === $allowedUrlParts['scheme']
&& strpos($urlParts['path'], $allowedUrlParts['path']) === 0
) {
return true;
}
}
return false;
}
private function isTypeAllowed($image, $mime) {
$allowedMimeTypes = [
'image/gif',
'image/jpeg',
'image/png',
];
return $mime && in_array($mime, $allowedMimeTypes);
}
}