Skip to content

Commit

Permalink
Merge pull request #149 from plank/4.0
Browse files Browse the repository at this point in the history
4.0 Release
  • Loading branch information
frasmage authored Oct 11, 2019
2 parents a322bc9 + 8f3d356 commit ca1cc54
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 256 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ coverage/
.env
.idea/
.phpunit.result.cache
infection/
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ script:
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
after_script:
- php vendor/bin/php-coveralls -v
branches:
only:
- master
- develop
cache:
directories:
- $HOME/.composer/cache
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 4.0.0
- changed UrlGenerators to use the underlying filesystemAdapter's `url()` method
- UrlGenerators no longer throw `MediaUrlException` when the file does not have public visibility. This removes the need to read IO for files local disks or to make HTTP calls for files on s3 disks.
- Removed `LocalUrlGenerator::getPublicPath()`
- No longer reading the `'prefix'` config of local disks. Value should be included in the `'url'` config instead.

## 3.0.1 - 2019-09-18
- Fixed public visibility not being respected when generating URLs for local files that are not in the webroot.

Expand Down
6 changes: 6 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Upgrading

## 3.x to 4.x

* UrlGenerators no longer throw `MediaUrlException` when the file does not have public visibility. This removes the need to read IO for files local disks or to make HTTP calls for files on s3 disks. Visibility can still checked with `$media->isPubliclyAccessible()`, if necessary.
* Highly recommended to explicitly specify the `'url'` config value on all disks used to generate URLs.
* No longer reading the `'prefix'` config of local disks. Value should be included in the `'url'` config instead.

## 2.x to 3.x

* Minimum PHP version moved to 7.2
Expand Down
122 changes: 5 additions & 117 deletions docs/source/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ Disks
------------------------
Laravel-Mediable is built on top of Laravel's Filesystem component. Before you use the package, you will need to configure the filesystem disks where you would like files to be stored in ``config/filesystems.php``. `Learn more about filesystem disk <https://laravel.com/docs/5.2/filesystem>`_.

An example setup with one private disk (``local``) and one publicly accessible disk (``uploads``):

::

<?php
Expand All @@ -20,11 +18,15 @@ An example setup with one private disk (``local``) and one publicly accessible d
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
'url' => 'https://example.com/storage/app',
'visibility' => 'public'
],

'uploads' => [
'driver' => 'local',
'root' => public_path('uploads'),
'url' => 'https://example.com/uploads',
'visibility' => 'public'
],
]
//...
Expand All @@ -45,125 +47,11 @@ Once you have set up as many disks as you need, edit ``config/mediable.php`` to
* Filesystems that can be used for media storage
*/
'allowed_disks' => [
'local',
'uploads',
],
//...

.. _disk_visibility:

Disk Visibility
^^^^^^^^^^^^^^^

This package is able to generate public URLs for accessing media, and uses the disk config to determine how this should be done.

URLs can always be generated for ``Media`` placed on a disk located below the webroot.

::

<?php
'disks' => [
'uploads' => [
'driver' => 'local',
'root' => public_path('uploads'),
],
]

//...

$media->getUrl(); // returns http://domain.com/uploads/foo.jpg

``Media`` placed on a disk located elsewhere will throw an exception.

::

<?php
'disks' => [
'private' => [
'driver' => 'local',
'root' => storage_path('private'),
],
]

//...

$media->getUrl(); // Throws a Plank\Mediable\Exceptions\MediableUrlException

If you are using symbolic links to make local disks accessible, you can instruct the package to generate URLs with the ``'visibility' => 'public'`` key. By default, the package will assume that the symlink is named ``'storage'``, as per `laravel's documentation <https://laravel.com/docs/5.3/filesystem#the-public-disk>`_. This can be modified with the ``'prefix'`` key.

::

<?php
'disks' => [
'public' => [
'driver' => 'local',
'root' => storage_path('public'),
'visibility' => 'public',
'prefix' => 'assets'
],
]

//...

$media->getUrl(); // returns http://domain.com/assets/foo.jpg

Whether you are using symbolic links or not, you can set the ``'url'`` config value to generate disk urls on another domain. Note that you can specify any path in the url, as the root path doesn't have to match, as long as you have set up your web server accordingly.

::

<?php
'disks' => [
'uploads' => [
'driver' => 'local',
'root' => public_path('uploads'),
'url' => 'http://example.com/assets',
],
]

//...

$media->getUrl(); // returns http://example.com/assets/foo.jpg

However, if you are using a symbolic link to make a local disk accessible, the prefix will be appended to the disk url.

::

<?php
'disks' => [
'public' => [
'driver' => 'local',
'root' => storage_path('public'),
'visibility' => 'public',
'prefix' => 'assets',
'url' => 'http://example.com',
],
]

//...

$media->getUrl(); // returns http://example.com/assets/foo.jpg


Permissions for S3-based disks is set on the buckets themselves. You can inform the package that ``Media`` on an S3 disk can be linked by URL by adding the ``'visibility' => 'public'`` key to the disk config.

::

<?php
'disks' => [
'cloud' => [
'driver' => 's3',
'key' => env('S3_KEY'),
'secret' => env('S3_SECRET'),
'region' => env('S3_REGION'),
'bucket' => env('S3_BUCKET'),
'version' => 'latest',
'visibility' => 'public'
],
]

//...

$media->getUrl(); // returns https://s3.amazonaws.com/bucket/foo.jpg


.. _validation:

Expand Down
14 changes: 14 additions & 0 deletions infection.json.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"timeout": 10,
"source": {
"directories": [
"src"
]
},
"logs": {
"text": "infection\/infection.log"
},
"mutators": {
"@default": true
}
}
2 changes: 2 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
executionOrder="random"
resolveDependencies="true"
>
<testsuites>
<testsuite name="Package Test Suite">
Expand Down
2 changes: 0 additions & 2 deletions src/Exceptions/MediaUpload/ConfigurationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ public static function unrecognizedSource($source): self
$source = get_class($source);
} elseif (is_resource($source)) {
$source = get_resource_type($source);
} else {
$source = (string)$source;
}

return new static("Could not recognize source, `{$source}` provided.");
Expand Down
11 changes: 0 additions & 11 deletions src/Exceptions/MediaUrlException.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,4 @@ public static function invalidGenerator(string $class): self
{
return new static("Could not set UrlGenerator, class `{$class}` does not extend `Plank\Mediable\UrlGenerators\UrlGenerator`");
}

public static function mediaNotPubliclyAccessible(string $path): self
{
$public_path = public_path();
return new static("Media file `{$path}` is not part of the public path `{$public_path}`");
}

public static function cloudMediaNotPubliclyAccessible(string $disk): self
{
return new static("Media files on cloud disk `{$disk}` are not publicly accessible");
}
}
90 changes: 13 additions & 77 deletions src/UrlGenerators/LocalUrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,34 @@
namespace Plank\Mediable\UrlGenerators;

use Illuminate\Contracts\Config\Repository as Config;
use Illuminate\Contracts\Routing\UrlGenerator;
use Plank\Mediable\Exceptions\MediaUrlException;
use Illuminate\Contracts\Filesystem\Cloud;
use Illuminate\Filesystem\FilesystemManager;

class LocalUrlGenerator extends BaseUrlGenerator
{
/**
* @var UrlGenerator
* @var FilesystemManager
*/
protected $url;
protected $filesystem;

/**
* Constructor.
* @param Config $config
* @param UrlGenerator $url
* @param FilesystemManager $filesystem
*/
public function __construct(Config $config, UrlGenerator $url)
public function __construct(Config $config, FilesystemManager $filesystem)
{
parent::__construct($config);
$this->url = $url;
$this->filesystem = $filesystem;
}

/**
* {@inheritdoc}
*/
public function isPubliclyAccessible(): bool
{
return (parent::isPubliclyAccessible() || $this->isInWebroot()) && $this->media->isVisible();
}

/**
* Get the path to relative to the webroot.
* @return string
* @throws MediaUrlException If media's disk is not publicly accessible
*/
public function getPublicPath(): string
{
if (!$this->isPubliclyAccessible()) {
throw MediaUrlException::mediaNotPubliclyAccessible($this->getAbsolutePath());
}
if ($this->isInWebroot()) {
$path = str_replace(public_path(), '', $this->getAbsolutePath());
} else {
$path = rtrim($this->getPrefix(), '/') . '/' . $this->media->getDiskPath();
}

return $this->cleanDirectorySeparators($path);
return ($this->getDiskConfig('visibility', 'private') == 'public' || $this->isInWebroot())
&& $this->media->isVisible();
}

/**
Expand All @@ -58,19 +40,9 @@ public function getPublicPath(): string
*/
public function getUrl(): string
{
$path = $this->getPublicPath();

$url = $this->getDiskConfig('url');

if ($url) {
if ($this->isInWebroot()) {
$path = $this->media->getDiskPath();
}

return rtrim($url, '/') . '/' . trim($path, '/');
}

return $this->url->asset($path);
/** @var Cloud $filesystem */
$filesystem = $this->filesystem->disk($this->media->disk);
return $filesystem->url($this->media->getDiskPath());
}

/**
Expand All @@ -81,44 +53,8 @@ public function getAbsolutePath(): string
return $this->getDiskConfig('root') . DIRECTORY_SEPARATOR . $this->media->getDiskPath();
}

/**
* Correct directory separator slashes on non-unix systems.
* @param string $path
* @return string
*/
protected function cleanDirectorySeparators(string $path): string
{
if (DIRECTORY_SEPARATOR != '/') {
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
}

return $path;
}

private function isInWebroot(): bool
{
return strpos(realpath($this->getAbsolutePath()), realpath(public_path())) === 0;
}

/**
* Get the prefix.
*
* If the prefix and the url are not set, we will assume the prefix
* is "storage", in order to point to the default symbolic link.
*
* Otherwise, we will trust the user has correctly set the prefix and/or the url.
*
* @return string
*/
private function getPrefix()
{
$prefix = $this->getDiskConfig('prefix', '');
$url = $this->getDiskConfig('url');

if (!$prefix && !$url) {
return 'storage';
}

return $prefix;
return strpos($this->getAbsolutePath(), public_path()) === 0;
}
}
5 changes: 0 additions & 5 deletions src/UrlGenerators/S3UrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Illuminate\Contracts\Config\Repository as Config;
use Illuminate\Contracts\Filesystem\Cloud;
use Illuminate\Filesystem\FilesystemManager;
use Plank\Mediable\Exceptions\MediaUrlException;

class S3UrlGenerator extends BaseUrlGenerator
{
Expand Down Expand Up @@ -40,10 +39,6 @@ public function getAbsolutePath(): string
*/
public function getUrl(): string
{
if (!$this->isPubliclyAccessible()) {
throw MediaUrlException::cloudMediaNotPubliclyAccessible($this->media->disk);
}

/** @var Cloud $filesystem */
$filesystem = $this->filesystem->disk($this->media->disk);
return $filesystem->url($this->media->getDiskPath());
Expand Down
Loading

0 comments on commit ca1cc54

Please sign in to comment.