Created
June 24, 2020 17:11
-
-
Save j-dexx/1bc9cab5728a99ffb7c5f1166b5c011d to your computer and use it in GitHub Desktop.
Replacing Upload URLs in WYSIWYG Content
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Services\Wysiwyg; | |
use Spatie\MediaLibrary\MediaCollections\Models\Media; | |
use Spatie\MediaLibrary\ResponsiveImages\ResponsiveImage; | |
class ResponsiveImageUrlsGenerator | |
{ | |
private Media $media; | |
public function __construct(Media $media) | |
{ | |
$this->media = $media; | |
} | |
public function call(): array | |
{ | |
// responsive is the collection name | |
$files = $this->media->responsiveImages('responsive')->files; | |
// Returns the responsive images as width => url | |
$imageUrls = $files->mapWithKeys(function (ResponsiveImage $responsiveImage) { | |
return [ | |
$responsiveImage->width() => $responsiveImage->url(), | |
]; | |
}); | |
// Add the default key to the start | |
$imageUrls->prepend($this->media->getUrl('responsive'), 'default'); | |
return $imageUrls->toArray(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Services\Wysiwyg; | |
use DOMDocument; | |
use DOMElement; | |
use Config; | |
use Illuminate\Support\Collection; | |
use Spatie\MediaLibrary\MediaCollections\Models\Media; | |
class UploadUrlReplacer | |
{ | |
private string $htmlContent; | |
private string $disk; | |
public function __construct(string $htmlContent, string $disk = 'public') | |
{ | |
$this->htmlContent = $htmlContent; | |
$this->disk = $disk; | |
} | |
/** | |
* Done this way because the wysiwyg content isn't technically valid html and DOMDocument seems to try to fix | |
* e.g. '<figure></figure><ul></ul>' becomes '<figure><ul></ul></figure>' | |
*/ | |
public function call(): string | |
{ | |
libxml_use_internal_errors(true); | |
$dom = new DOMDocument(); | |
$dom->loadHTML($this->htmlContent, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); | |
$imageTags = $dom->getElementsByTagName('img'); | |
$newHtmlContent = $this->htmlContent; | |
foreach ($imageTags as $imageTag) { | |
$beforeHtml = $dom->saveHTML($imageTag); | |
$this->updateImageTag($imageTag); | |
$afterHtml = $dom->saveHTML($imageTag); | |
if ($beforeHtml && $afterHtml) { | |
$newHtmlContent = str_replace($beforeHtml, $afterHtml, $newHtmlContent); | |
} | |
} | |
libxml_use_internal_errors(false); | |
return $newHtmlContent; | |
} | |
private function updateImageTag(DOMElement $imageTag): void | |
{ | |
$imageSrc = $imageTag->getAttribute('src'); | |
$mediaId = $this->mediaId($imageSrc); | |
$media = Media::findOrFail($mediaId); | |
$responsiveUrlGenerator = new ResponsiveImageUrlsGenerator($media); | |
$urls = $responsiveUrlGenerator->call(); | |
$urlCollection = collect($urls); | |
$defaultUrl = $urlCollection->get('default'); | |
$urlsWithWidths = $urlCollection->filter(function ($value, $key) { | |
return $key !== 'default'; | |
}); | |
$srcSet = $this->calculateSrcSet($urlsWithWidths); | |
$imageTag->setAttribute('src', $defaultUrl); | |
$imageTag->setAttribute('srcset', $srcSet); | |
} | |
private function calculateSrcSet(Collection $urls): string | |
{ | |
return $urls->map(function ($url, $key) { | |
return $url . ' ' . $key . 'w'; | |
})->implode(', '); | |
} | |
private function mediaId(string $imageSrc): string | |
{ | |
$newImageSrc = $this->stripDiskUrlFromImageSource($imageSrc); | |
$parts = explode('/', $newImageSrc); | |
// If the string began with / we get an empty string | |
$parts = array_values(array_filter($parts)); | |
return $parts[0]; | |
} | |
private function stripDiskUrlFromImageSource(string $imageSrc): string | |
{ | |
$url = $this->diskUrl(); | |
if (is_null($url)) { | |
return $imageSrc; | |
} | |
$newSrc = str_replace($url, "", $imageSrc); | |
return $newSrc; | |
} | |
private function diskUrl(): ?string | |
{ | |
$config = Config::get('filesystems.disks.' . $this->disk . '.url'); | |
return $config; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment