Skip to content

Commit

Permalink
Add temporary URLs for media on S3 (#760)
Browse files Browse the repository at this point in the history
* Add temporary URLs for media on S3

* Apply fixes from StyleCI

* Update changelog
  • Loading branch information
AlexVanderbist authored and freekmurze committed Sep 19, 2017
1 parent 0491a18 commit 311634d
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,10 @@

All notable changes to `laravel-medialibrary` will be documented in this file

## 6.1.0 - 2017-09-19

- add `getTemporaryUrl` method for media stored on S3

## 6.0.0 - 2017-08-30

- add compatiblity for Laravel 5.5
Expand Down
5 changes: 5 additions & 0 deletions src/Exceptions/UrlCannotBeDetermined.php
Expand Up @@ -10,4 +10,9 @@ public static function mediaNotPubliclyAvailable(string $storagePath, string $pu
{
return new static("Storagepath `{$storagePath}` is not part of public path `{$publicPath}`");
}

public static function temporaryUrlOnlyWorksOnS3()
{
return new static('Generating temporary URLs only works on the S3 filesystem driver');
}
}
31 changes: 18 additions & 13 deletions src/Media.php
Expand Up @@ -2,6 +2,7 @@

namespace Spatie\MediaLibrary;

use DateTimeInterface;
use Illuminate\Support\Collection;
use Spatie\MediaLibrary\Helpers\File;
use Illuminate\Database\Eloquent\Model;
Expand Down Expand Up @@ -62,15 +63,25 @@ public function getFullUrl(string $conversionName = ''): string
*/
public function getUrl(string $conversionName = ''): string
{
$urlGenerator = UrlGeneratorFactory::createForMedia($this);
$urlGenerator = UrlGeneratorFactory::createForMedia($this, $conversionName);

if ($conversionName !== '') {
$conversion = ConversionCollection::createForMedia($this)->getByName($conversionName);
return $urlGenerator->getUrl();
}

$urlGenerator->setConversion($conversion);
}
/**
* Get a temporary url to a original media file.
*
* @param string $conversionName
* @param \DateTimeInterface $expiration
* @param array $options
*
* @return string
*/
public function getTemporaryUrl(DateTimeInterface $expiration, string $conversionName = '', array $options = []): string
{
$urlGenerator = UrlGeneratorFactory::createForMedia($this, $conversionName);

return $urlGenerator->getUrl();
return $urlGenerator->getTemporaryUrl($expiration, $options);
}

/**
Expand All @@ -84,13 +95,7 @@ public function getUrl(string $conversionName = ''): string
*/
public function getPath(string $conversionName = ''): string
{
$urlGenerator = UrlGeneratorFactory::createForMedia($this);

if ($conversionName != '') {
$conversion = ConversionCollection::createForMedia($this)->getByName($conversionName);

$urlGenerator->setConversion($conversion);
}
$urlGenerator = UrlGeneratorFactory::createForMedia($this, $conversionName);

return $urlGenerator->getPath();
}
Expand Down
14 changes: 14 additions & 0 deletions src/UrlGenerator/LocalUrlGenerator.php
Expand Up @@ -2,6 +2,7 @@

namespace Spatie\MediaLibrary\UrlGenerator;

use DateTimeInterface;
use Spatie\MediaLibrary\Exceptions\UrlCannotBeDetermined;

class LocalUrlGenerator extends BaseUrlGenerator
Expand All @@ -24,6 +25,19 @@ public function getUrl(): string
return $url;
}

/**
* @param \DateTimeInterface $expiration
* @param array $options
*
* @return string
*
* @throws \Spatie\MediaLibrary\Exceptions\UrlCannotBeDetermined
*/
public function getTemporaryUrl(DateTimeInterface $expiration, array $options = []): string
{
throw UrlCannotBeDetermined::temporaryUrlOnlyWorksOnS3();
}

/*
* Get the path for the profile of a media item.
*/
Expand Down
30 changes: 30 additions & 0 deletions src/UrlGenerator/S3UrlGenerator.php
Expand Up @@ -2,8 +2,22 @@

namespace Spatie\MediaLibrary\UrlGenerator;

use DateTimeInterface;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Contracts\Config\Repository as Config;

class S3UrlGenerator extends BaseUrlGenerator
{
/** @var \Illuminate\Filesystem\FilesystemManager */
protected $filesystemManager;

public function __construct(Config $config, FilesystemManager $filesystemManager)
{
$this->filesystemManager = $filesystemManager;

parent::__construct($config);
}

/**
* Get the url for the profile of a media item.
*
Expand All @@ -14,6 +28,22 @@ public function getUrl(): string
return config('medialibrary.s3.domain').'/'.$this->getPathRelativeToRoot();
}

/**
* Get the temporary url for the profile of a media item.
*
* @param \DateTimeInterface $expiration
* @param array $options
*
* @return string
*/
public function getTemporaryUrl(DateTimeInterface $expiration, array $options = []): string
{
return $this
->filesystemManager
->disk($this->media->getDiskDriverName())
->temporaryUrl($this->getPath(), $expiration, $options);
}

/**
* Get the url for the profile of a media item.
*
Expand Down
11 changes: 11 additions & 0 deletions src/UrlGenerator/UrlGenerator.php
Expand Up @@ -2,6 +2,7 @@

namespace Spatie\MediaLibrary\UrlGenerator;

use DateTimeInterface;
use Spatie\MediaLibrary\Media;
use Spatie\MediaLibrary\Conversion\Conversion;
use Spatie\MediaLibrary\PathGenerator\PathGenerator;
Expand All @@ -15,6 +16,16 @@ interface UrlGenerator
*/
public function getUrl(): string;

/**
* Get the temporary url for the profile of a media item.
*
* @param \DateTimeInterface $expiration
* @param array $options
*
* @return string
*/
public function getTemporaryUrl(DateTimeInterface $expiration, array $options = []): string;

/**
* @param \Spatie\MediaLibrary\Media $media
*
Expand Down
9 changes: 8 additions & 1 deletion src/UrlGenerator/UrlGeneratorFactory.php
Expand Up @@ -4,11 +4,12 @@

use Spatie\MediaLibrary\Media;
use Spatie\MediaLibrary\Exceptions\InvalidUrlGenerator;
use Spatie\MediaLibrary\Conversion\ConversionCollection;
use Spatie\MediaLibrary\PathGenerator\PathGeneratorFactory;

class UrlGeneratorFactory
{
public static function createForMedia(Media $media) : UrlGenerator
public static function createForMedia(Media $media, string $conversionName = '') : UrlGenerator
{
$urlGeneratorClass = config('medialibrary.custom_url_generator_class')
?: 'Spatie\MediaLibrary\UrlGenerator\\'.ucfirst($media->getDiskDriverName()).'UrlGenerator';
Expand All @@ -22,6 +23,12 @@ public static function createForMedia(Media $media) : UrlGenerator
->setMedia($media)
->setPathGenerator($pathGenerator);

if ($conversionName !== '') {
$conversion = ConversionCollection::createForMedia($media)->getByName($conversionName);

$urlGenerator->setConversion($conversion);
}

return $urlGenerator;
}

Expand Down
12 changes: 12 additions & 0 deletions tests/Media/GetUrlTest.php
Expand Up @@ -2,8 +2,10 @@

namespace Spatie\MediaLibrary\Test\Media;

use Carbon\Carbon;
use Spatie\MediaLibrary\Test\TestCase;
use Spatie\MediaLibrary\Exceptions\InvalidConversion;
use Spatie\MediaLibrary\Exceptions\UrlCannotBeDetermined;

class GetUrlTest extends TestCase
{
Expand Down Expand Up @@ -60,4 +62,14 @@ public function it_can_get_the_full_url_of_a_derived_image()

$this->assertEquals("http://localhost/media/{$media->id}/conversions/{$conversionName}.jpg", $media->getFullUrl($conversionName));
}

/** @test */
public function it_throws_an_exception_when_trying_to_get_a_temporary_url_on_local_disk()
{
$media = $this->testModelWithConversion->addMedia($this->getTestJpg())->toMediaCollection();

$this->expectException(UrlCannotBeDetermined::class);

$media->getTemporaryUrl(Carbon::now()->addMinutes(5));
}
}
33 changes: 33 additions & 0 deletions tests/S3Integration/S3IntegrationTest.php
Expand Up @@ -2,6 +2,7 @@

namespace Spatie\MediaLibrary\Test\FileAdder;

use Carbon\Carbon;
use Spatie\MediaLibrary\Test\TestCase;
use Illuminate\Support\Facades\Storage;
use Spatie\MediaLibrary\Test\S3Integration\S3TestPathGenerator;
Expand Down Expand Up @@ -116,6 +117,38 @@ public function it_retrieve_a_media_conversion_url_from_s3()
);
}

/** @test */
public function it_retrieves_a_temporary_media_url_from_s3()
{
$media = $this->testModel
->addMedia($this->getTestJpg())
->preservingOriginal()
->toMediaCollection('default', 's3');

$this->assertContains(
"/{$this->s3BaseDirectory}/{$media->id}/test.jpg",
$media->getTemporaryUrl(Carbon::now()->addMinutes(5))
);

$this->assertEquals(
sha1(file_get_contents($this->getTestJpg())),
sha1(file_get_contents($media->getTemporaryUrl(Carbon::now()->addMinutes(5))))
);
}

/** @test */
public function it_retrieve_a_temporary_media_conversion_url_from_s3()
{
$media = $this->testModelWithConversion
->addMedia($this->getTestJpg())
->toMediaCollection('default', 's3');

$this->assertContains(
"/{$this->s3BaseDirectory}/{$media->id}/conversions/thumb.jpg",
$media->getTemporaryUrl(Carbon::now()->addMinutes(5), 'thumb')
);
}

protected function cleanUpS3()
{
collect(Storage::disk('s3')->allDirectories(self::getS3BaseTestDirectory()))->each(function ($directory) {
Expand Down

0 comments on commit 311634d

Please sign in to comment.