Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Next medialibrary-uploaders version #38

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.idea/
vendor/
node_modules/
.DS_Store
.composer.lock
composer.lock
.phpunit.result.cache
src/public/packages/
/.phpunit.cache
12 changes: 9 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,24 @@
"Laravel", "Backpack", "Backpack for Laravel", "Backpack Addon", "spatie medialibrary uploaders"
],
"require": {
"backpack/crud": "^6.0",
"backpack/crud": "^6.99.99|dev-next",
"spatie/laravel-medialibrary": "^10.7|^11.3"
},
"require-dev": {
"phpunit/phpunit": "^9.0|^10.0",
"orchestra/testbench": "~6|^8.0"
"phpunit/phpunit": "^10.0|^11.0",
"orchestra/testbench": "^8.0|^9.0|^10.0"
},
"autoload": {
"psr-4": {
"Backpack\\MediaLibraryUploaders\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Backpack\\MediaLibraryUploaders\\Tests\\": "tests",
"Backpack\\CRUD\\Tests\\": "vendor/backpack/crud/tests"
}
},
"scripts": {
"test": "vendor/bin/phpunit --testdox"
},
Expand Down
43 changes: 23 additions & 20 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Package">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src/</directory>
</whitelist>
</filter>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/11.1/phpunit.xsd" bootstrap="vendor/autoload.php" backupGlobals="false" colors="true" processIsolation="false" stopOnFailure="false" cacheDirectory=".phpunit.cache" backupStaticProperties="false">
<testsuites>
<testsuite name="Feature">
<directory suffix=".php">./tests/Feature</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
<env name="BCRYPT_ROUNDS" value="12"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="TELESCOPE_ENABLED" value="false"/>
</php>
<source>
<include>
<directory>src/</directory>
</include>
</source>
</phpunit>
14 changes: 7 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ More exactly, it provides the `->withMedia()` helper, that will handle the file

## Requirements

**Install and use `spatie/laravel-medialibrary` v10**. If you haven't already, please make sure you've installed `spatie/laravel-medialibrary` and followed all installation steps in [their docs](https://spatie.be/docs/laravel-medialibrary/v10/installation-setup):
**Install and use `spatie/laravel-medialibrary` v10|v11**. If you haven't already, please make sure you've installed `spatie/laravel-medialibrary` and followed all installation steps in [their docs](https://spatie.be/docs/laravel-medialibrary/v11/installation-setup):

``` bash
# require the package
composer require "spatie/laravel-medialibrary:^10.0.0"
composer require "spatie/laravel-medialibrary:^11.0"

# prepare the database
# NOTE: Spatie migration does not come with a `down()` method by default, add one now if you need it
Expand All @@ -33,7 +33,7 @@ php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServicePr

```

Then prepare your Models to use `spatie/laravel-medialibrary`, by adding the `InteractsWithMedia` trait to your model and implement the `HasMedia` interface like explained on [Media Library Documentation](https://spatie.be/docs/laravel-medialibrary/v10/basic-usage/preparing-your-model).
Then prepare your Models to use `spatie/laravel-medialibrary`, by adding the `InteractsWithMedia` trait to your model and implement the `HasMedia` interface like explained on [Media Library Documentation](https://spatie.be/docs/laravel-medialibrary/v11/basic-usage/preparing-your-model).

## Installation

Expand Down Expand Up @@ -100,11 +100,11 @@ CRUD::field('main_image')
]);
```

**NOTE:** Some methods will be called automatically by Backpack; You shoudn't call them inside the closure used for configuration: `toMediaCollection()`, `setName()`, `usingName()`, `setOrder()`, `toMediaCollectionFromRemote()` and `toMediaLibrary()`. They will throw an error if you manually try to call them in the closure.
**NOTE:** Some methods will be called automatically by Backpack; You shouldn't call them inside the closure used for configuration: `toMediaCollection()`, `setName()`, `usingName()`, `setOrder()`, `toMediaCollectionFromRemote()` and `toMediaLibrary()`. They will throw an error if you manually try to call them in the closure.

### Defining media collection in the model

You can also have the collection configured in your model as explained in [Spatie Documentation](https://spatie.be/docs/laravel-medialibrary/v10/working-with-media-collections/defining-media-collections), in that case, you just need to pass the `collection` configuration key. But you are still able to configure all the other options including the `whenSaving` callback.
You can also have the collection configured in your model as explained in [Spatie Documentation](https://spatie.be/docs/laravel-medialibrary/v11/working-with-media-collections/defining-media-collections), in that case, you just need to pass the `collection` configuration key. But you are still able to configure all the other options including the `whenSaving` callback.

```php
// In your Model.php
Expand Down Expand Up @@ -151,7 +151,7 @@ CRUD::field('main_image')
'displayConversions' => 'thumb'
]);

// you can also configure aditional manipulations in the `whenSaving` callback
// you can also configure additional manipulations in the `whenSaving` callback
->withMedia([
'displayConversions' => 'thumb',
'whenSaving' => function($media) {
Expand Down Expand Up @@ -183,7 +183,7 @@ You can normally assign custom properties to your media with `->withCustomProper

## Change log

Changes are documented here on Github. Please see the [Releases tab](https://github.com/backpack/media-library-connector/releases).
Changes are documented here on Github. Please see the [Releases tab](https://github.com/Laravel-Backpack/medialibrary-uploaders/releases).

## Testing

Expand Down
17 changes: 13 additions & 4 deletions src/AddonServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Backpack\CRUD\app\Library\CrudPanel\CrudColumn;
use Backpack\CRUD\app\Library\CrudPanel\CrudField;
use Backpack\CRUD\app\Library\Uploaders\Support\RegisterUploadEvents;
use Backpack\MediaLibraryUploaders\Uploaders\MediaAjaxUploader;
use Backpack\MediaLibraryUploaders\Uploaders\MediaDropzoneUploader;
use Backpack\MediaLibraryUploaders\Uploaders\MediaMultipleFiles;
use Backpack\MediaLibraryUploaders\Uploaders\MediaSingleBase64Image;
use Backpack\MediaLibraryUploaders\Uploaders\MediaSingleFile;
Expand All @@ -30,14 +30,21 @@ public function boot()
'image' => MediaSingleBase64Image::class,
'upload' => MediaSingleFile::class,
'upload_multiple' => MediaMultipleFiles::class,
'dropzone' => MediaAjaxUploader::class,
], 'withMedia');

if (class_exists(\Backpack\Pro\Uploads\BackpackAjaxUploader::class)) {
app('UploadersRepository')->addUploaderClasses([
'dropzone' => MediaDropzoneUploader::class,
], 'withMedia');
}

// register media upload macros on crud fields and columns.
if (! CrudField::hasMacro('withMedia')) {
CrudField::macro('withMedia', function ($uploadDefinition = [], $subfield = null, $registerEvents = true) {
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
/** @var CrudField $this */
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
$this->setAttributeValue('withMedia', $uploadDefinition);
$this->save();
RegisterUploadEvents::handle($this, $uploadDefinition, 'withMedia', $subfield, $registerEvents);

return $this;
Expand All @@ -46,8 +53,10 @@ public function boot()

if (! CrudColumn::hasMacro('withMedia')) {
CrudColumn::macro('withMedia', function ($uploadDefinition = [], $subfield = null, $registerEvents = true) {
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
/** @var CrudColumn $this */
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
$this->setAttributeValue('withMedia', $uploadDefinition);
$this->save();
RegisterUploadEvents::handle($this, $uploadDefinition, 'withMedia', $subfield, $registerEvents);

return $this;
Expand Down
65 changes: 23 additions & 42 deletions src/Uploaders/MediaAjaxUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,28 @@
namespace Backpack\MediaLibraryUploaders\Uploaders;

use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
use Backpack\CRUD\app\Library\Uploaders\Support\Interfaces\UploaderInterface;
use Illuminate\Database\Eloquent\Model;
use Backpack\Pro\Uploads\BackpackAjaxUploader;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\File\File;

class MediaAjaxUploader extends MediaUploader
class MediaAjaxUploader extends BackpackAjaxUploader
{
public static function for(array $field, $configuration): UploaderInterface
use Traits\IdentifiesMedia;
use Traits\AddMediaToModels;
use Traits\HasConstrainedFileAdder;
use Traits\HasCustomProperties;
use Traits\HasSavingCallback;
use Traits\HasCollections;
use Traits\RetrievesUploadedFiles;
use Traits\HandleRepeatableUploads;
use Traits\DeletesUploadedFiles;

public function __construct(array $crudObject, array $configuration)
{
return (new self($field, $configuration))->multiple();
}

public function uploadFiles(Model $entry, $value = null)
{
$temporaryDisk = CRUD::get('dropzone.temporary_disk');
$temporaryFolder = CRUD::get('dropzone.temporary_folder');

$uploads = $value ?? CRUD::getRequest()->input($this->getName()) ?? [];

$uploads = is_array($uploads) ? $uploads : (json_decode($uploads, true) ?? []);

$uploadedFiles = array_filter($uploads, function ($value) use ($temporaryFolder, $temporaryDisk) {
return strpos($value, $temporaryFolder) !== false && Storage::disk($temporaryDisk)->exists($value);
});

$previousSentFiles = array_filter($uploads, function ($value) use ($temporaryFolder) {
return strpos($value, $temporaryFolder) === false;
});

$previousFiles = $this->get($entry);

foreach ($previousFiles as $previousFile) {
if (! in_array($this->getMediaIdentifier($previousFile, $entry), $previousSentFiles)) {
$previousFile->delete();
}
}

foreach ($uploadedFiles as $key => $value) {
$file = new File(Storage::disk($temporaryDisk)->path($value));

$this->addMediaFile($entry, $file);
}
parent::__construct($crudObject, $configuration);
$this->mediaName = $configuration['mediaName'] ?? $crudObject['name'];
$this->savingEventCallback = $configuration['whenSaving'] ?? null;
$this->collection = $configuration['collection'] ?? 'default';
}

public function uploadRepeatableFiles($values, $previousValues, $entry = null)
Expand Down Expand Up @@ -83,15 +63,16 @@ public function uploadRepeatableFiles($values, $previousValues, $entry = null)
$fileIdentifier = $this->getMediaIdentifier($previousFile, $entry);
if (empty($sentFiles)) {
$previousFile->delete();

continue;
}

$foundInSentFiles = false;
foreach($sentFiles as $row => $sentFilesInRow) {
foreach ($sentFiles as $row => $sentFilesInRow) {
$fileWasSent = array_search($fileIdentifier, $sentFilesInRow, true);
if($fileWasSent !== false) {
if ($fileWasSent !== false) {
$foundInSentFiles = true;
if($row !== $previousFile->getCustomProperty('repeatableRow')) {
if ($row !== $previousFile->getCustomProperty('repeatableRow')) {
$previousFile->setCustomProperty('repeatableRow', $row);
$previousFile->save();
// avoid checking the same file twice. This is a performance improvement.
Expand All @@ -102,7 +83,7 @@ public function uploadRepeatableFiles($values, $previousValues, $entry = null)
}

if ($foundInSentFiles === false) {
$previousFile->delete();
$previousFile->delete();
}
}
}
Expand Down
Loading