Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 91 additions & 13 deletions classes/Resizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@
use Exception;
use Event;
use File;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\ImageManagerStatic as Image;
use Validator;

class Resizer
{
public const CACHE_PREFIX = 'image_resize_';

public const EVENT_PREFIX = 'abweb.imageresize.';

/**
* A list of computed values to override $options
*
Expand Down Expand Up @@ -100,6 +103,77 @@ public function setFormatCache(array $cache)
return $this;
}

/**
* Get the absolute path of an image by passing it a local URL (https://mysite.com/themes/demo/assets/logo.png)
*
* @param string $url
* @return string|null Null if remote URL or file not exists
*/
protected function getAbsolutePathOfLocalUrl(string $url): ?string
{
if (empty($url)) {
return false;
}

// Local path (allow events to override logic)
$localPath = null;

/* Root paths to check files against, first we'll try relative to the base_path (document root) followed by a local disk check */
$roots = [
base_path(),
];

// Add local storage path too, if it exists
$localDisk = Storage::disk('local');
if ($localDisk) {
$roots[] = $localDisk->getDriver()->getAdapter()->getPathPrefix();
}

Event::fire(static::EVENT_PREFIX . 'getAbsolutePathOfLocalUrl', [
&$url,
&$roots,
&$localPath,
]);

// If the event sets localPath to false, then assume it's not local (is remote URL)
if ($localPath === false) {
return null;
}

// If the event sets localPath to a string, then assume it's a local path
if (is_string($localPath)) {
// Convert to absolute, if needed.
return (strpos($localPath, '/') === 0) ? $localPath : base_path($localPath);
}

// No event handler

// Check if hosts match (without www. prefix)
$host = preg_replace('/^www\./', '', parse_url((string) url('/'), PHP_URL_HOST), 1);
$found = preg_replace('/^www\./', '', parse_url((string) $url, PHP_URL_HOST), 1);

// It's local if the hosts match, or if no host was found in the URL, or both are localhost/127.0.0.1
$isLocal = ($host === $found) ||
empty($found) ||
(($host === '127.0.0.1' || $host === 'localhost') && ($found === '127.0.0.1' || $found === 'localhost'));

if ($isLocal) {
$path = parse_url($url, PHP_URL_PATH);

// iterate each possible root directory to try find the file
foreach ($roots as $root) {
$maybe = $root . DIRECTORY_SEPARATOR . ltrim($path, '/');

if (file_exists($maybe)) {
// if the file exists, assume this is the path to the file we're expecting
return $maybe;
}
}
}

return null;
}

/**
* Specify the image to use
*
Expand All @@ -115,8 +189,6 @@ public function setImage(string $image = null, bool $doNotModifyPath = false)
}

if ($image !== null) {
$absolutePath = false;

// Support JSON objects containing path property, e.g: {"path":"USETHISPATH",...}
if (substr($image, 0, 2) === '{"') {
$attempt = json_decode($image);
Expand All @@ -126,17 +198,19 @@ public function setImage(string $image = null, bool $doNotModifyPath = false)
}
}

// Check if the image is an absolute url to the same server, if so get the storage path of the image
$regex = '/^(?:https?:\/\/)?' . $_SERVER['SERVER_NAME'] . '(?::\d+)?\/(.+)$/';
if (preg_match($regex, $image, $m)) {
// Convert spaces, not going to urldecode as it will mess with pluses
$image = base_path(str_replace('%20', ' ', $m[1]));
$absolutePath = true;
}
if (preg_match('/^(https?:\/\/)/i', $image)) {
$path = $this->getAbsolutePathOfLocalUrl($image);

// If not an absolute path, set it to an absolute path
if (!$absolutePath) {
$image = base_path(trim($image, '/'));
// If path is string (If URL was local, it will be the local path)
if ($path !== null) {
$image = $path;
}
} elseif (strpos($image, '/') !== 0) {
$path = base_path($image);

if (file_exists($path)) {
$image = $path;
}
}
}

Expand Down Expand Up @@ -850,15 +924,19 @@ public function modify()
break;
case 'colorize':
list($r, $g, $b) = explode(',', $value);

$this->im->colorize($r, $g, $b);

break;
case 'insert':
$exp = explode(',', $value);
$path = $exp[0];
$position = (isset($exp[1])) ? $exp[1] : null;
$x = (isset($exp[2])) ? $exp[2] : null;
$y = (isset($exp[3])) ? $exp[3] : null;

$this->im->insert($path, $position, $x, $y);

break;
default:
// Pass argument if configured to do so:
Expand Down Expand Up @@ -926,7 +1004,7 @@ public static function clearFiles(Carbon $minAge = null, string $directory = nul
});

// Fire event to hook into and modify $files before deleting
Event::fire('abweb.imageresize.clearFiles', [&$files, $minAge]);
Event::fire(static::EVENT_PREFIX . 'clearFiles', [&$files, $minAge]);

// Delete the files
File::delete($files);
Expand Down
4 changes: 3 additions & 1 deletion updates/version.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@
2.1.6:
- Fix migration (2.1.2 migration) that causes installations to fail (due to plugin settings not existing for new projects at time of execution)
2.1.7:
- Fix - Update plugin's boot method to not directly reference Settings until DB connection is established
- Fix - Update plugin's boot method to not directly reference Settings until DB connection is established
2.2.0:
- Fix - Update Local URL detection facility to cater for more scenarios