Last active
October 15, 2025 10:24
-
-
Save aaronbushnell/91dd215930ffcb8fdcbb42fe368b5634 to your computer and use it in GitHub Desktop.
A helper class to create Statamic assets out of URLs. Uses intervention/image for compression and resizing
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\Helpers; | |
| use Illuminate\Support\Facades\Http; | |
| use Illuminate\Support\Facades\Storage; | |
| use Intervention\Image\ImageManagerStatic as Image; | |
| use Statamic\Contracts\Assets\AssetContainer; | |
| use Statamic\Facades\Asset; | |
| class AssetImport | |
| { | |
| protected string $url; | |
| protected AssetContainer $container; | |
| protected ?string $path = null; | |
| protected ?array $data = []; | |
| protected ?int $quality = null; | |
| protected ?int $height = null; | |
| protected ?int $width = null; | |
| protected bool $replace = false; | |
| /** | |
| * The URL of the asset to download and store | |
| */ | |
| public static function fromUrl(string $url): self | |
| { | |
| $self = new self; | |
| $self->url = $url; | |
| return $self; | |
| } | |
| /** | |
| * The handle of the Statamic container to use for the file upload | |
| */ | |
| public function container(string $container): self | |
| { | |
| $this->container = \Statamic\Facades\AssetContainer::findOrFail($container); | |
| return $this; | |
| } | |
| /** | |
| * The path to use for the locally-stored asset. This will default to the filename of the source URL if not supplied. | |
| * Ex: `my-folder/filename.jpg` | |
| */ | |
| public function path(string $path): self | |
| { | |
| $this->path = $path; | |
| return $this; | |
| } | |
| /** | |
| * For images, set a quality level from `1-100` to compress images before saving. | |
| */ | |
| public function quality(int $quality): self | |
| { | |
| $this->quality = max(1, min(100, $quality)); | |
| return $this; | |
| } | |
| /** | |
| * For images, supply a height, width, both, or neither to resize them before saving | |
| */ | |
| public function resize(?int $width, ?int $height): self | |
| { | |
| $this->width = $width; | |
| $this->height = $height; | |
| return $this; | |
| } | |
| /** | |
| * Additional data to pass to Statamic when creating the asset | |
| * Ex: `["alt" => "An alt description"]` | |
| */ | |
| public function data(array $data): self | |
| { | |
| $this->data = $data; | |
| return $this; | |
| } | |
| /** | |
| * Replaces an existing file at the specified path if it exists | |
| */ | |
| public function replaceExisting(): self | |
| { | |
| $this->replace = true; | |
| return $this; | |
| } | |
| /** | |
| * Adds the file the appropriate storage disk and creates a Statamic asset for it | |
| */ | |
| public function create(): void | |
| { | |
| if (! $this->replace && Storage::disk($this->container->disk)->exists($this->getPath())) { | |
| throw new \Exception("The file at path [{$this->getPath()}] already exists in the [{$this->container->handle()}] container."); | |
| } | |
| // Get the file blob from the URL and store it in the specified container and folder | |
| $blob = Http::get($this->url)->throw(); | |
| Storage::disk($this->container->disk)->put($this->getPath(), $blob); | |
| // If we need to resize or compress the image, we'll do that now | |
| if ($this->quality || $this->width || $this->height) { | |
| $image = Image::make(Storage::disk($this->container->disk)->path($this->getPath())); | |
| // Resize the image if necessary while preserving the aspect ratio and not allowing it to be upsized | |
| if ($this->width || $this->height) { | |
| $image->resize($this->width, $this->height, function ($constraint) { | |
| $constraint->aspectRatio(); | |
| $constraint->upsize(); | |
| }); | |
| } | |
| // Save the image with the specified quality | |
| $image->save(null, $this->quality); | |
| } | |
| // Create the asset in Statamic | |
| Asset::make() | |
| ->container($this->container->handle()) | |
| ->path($this->getPath()) | |
| ->data($this->data) | |
| ->save(); | |
| } | |
| /** | |
| * Creates a relative path for the uploaded asset using the one set by the user or the original filename | |
| */ | |
| protected function getPath(): string | |
| { | |
| return $this->path ? $this->path : basename($this->url); | |
| } | |
| } |
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 | |
| use App\Helpers\AssetImport; | |
| // Take an image, rename it, apply alt text, resize it, and compress it. Replace any existing versions | |
| AssetImport::fromUrl("https://example.com/path/to/an/image.jpg") | |
| ->container('uploads') | |
| ->path('headshots/john-smith.jpg') | |
| ->data(['alt' => 'John Smith']) | |
| ->resize(800, 800) | |
| ->quality(80) | |
| ->replaceExisting() | |
| ->create(); | |
| // Creates a report.pdf in the root of the uploads container | |
| AssetImport::fromUrl("https://example.com/report.pdf") | |
| ->container('uploads') | |
| ->create(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment