Skip to content

Commit 0c214a1

Browse files
tabacituCopilotpxpm
authored
v2 - refactor, fix bugs and support Backpack v7 (#38)
Co-authored-by: Cristian Tăbăcitu <[email protected]> Co-authored-by: tabacitu <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Pedro Martins <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 267e1a2 commit 0c214a1

31 files changed

+1234
-289
lines changed

.github/workflows/tests.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
pull_request:
6+
schedule:
7+
- cron: '0 0 * * *'
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
strategy:
15+
fail-fast: false
16+
matrix:
17+
php: [8.2, 8.3]
18+
19+
name: PHP ${{ matrix.php }}
20+
21+
steps:
22+
- name: Checkout code
23+
uses: actions/checkout@v4
24+
25+
- name: Setup PHP
26+
uses: shivammathur/setup-php@v2
27+
with:
28+
php-version: ${{ matrix.php }}
29+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv
30+
coverage: none
31+
32+
- name: Install dependencies
33+
run: composer install --prefer-dist --no-interaction --no-progress
34+
35+
- name: Execute tests
36+
run: composer test

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.idea/
2+
vendor/
3+
node_modules/
4+
.DS_Store
5+
.composer.lock
6+
composer.lock
7+
.phpunit.result.cache
8+
src/public/packages/
9+
/.phpunit.cache

composer.json

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,27 @@
1414
"Laravel", "Backpack", "Backpack for Laravel", "Backpack Addon", "spatie medialibrary uploaders"
1515
],
1616
"require": {
17-
"backpack/crud": "^6.0",
18-
"spatie/laravel-medialibrary": "^10.7|^11.3"
17+
"backpack/crud": "^7.0",
18+
"spatie/laravel-medialibrary": "^10.7||^11.3"
1919
},
2020
"require-dev": {
21-
"phpunit/phpunit": "^9.0|^10.0",
22-
"orchestra/testbench": "~6|^8.0"
21+
"phpunit/phpunit": "^11.0",
22+
"orchestra/testbench": "^10.0",
23+
"spatie/laravel-translatable": "^6.0"
2324
},
25+
"minimum-stability": "dev",
26+
"prefer-stable": true,
2427
"autoload": {
2528
"psr-4": {
2629
"Backpack\\MediaLibraryUploaders\\": "src/"
2730
}
2831
},
32+
"autoload-dev": {
33+
"psr-4": {
34+
"Backpack\\MediaLibraryUploaders\\Tests\\": "tests",
35+
"Backpack\\CRUD\\Tests\\": "vendor/backpack/crud/tests"
36+
}
37+
},
2938
"scripts": {
3039
"test": "vendor/bin/phpunit --testdox"
3140
},

phpunit.xml

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit bootstrap="vendor/autoload.php"
3-
backupGlobals="false"
4-
backupStaticAttributes="false"
5-
colors="true"
6-
verbose="true"
7-
convertErrorsToExceptions="true"
8-
convertNoticesToExceptions="true"
9-
convertWarningsToExceptions="true"
10-
processIsolation="false"
11-
stopOnFailure="false">
12-
<testsuites>
13-
<testsuite name="Package">
14-
<directory suffix=".php">./tests/</directory>
15-
</testsuite>
16-
</testsuites>
17-
<filter>
18-
<whitelist>
19-
<directory>src/</directory>
20-
</whitelist>
21-
</filter>
2+
<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">
3+
<testsuites>
4+
<testsuite name="Feature">
5+
<directory suffix=".php">./tests/Feature</directory>
6+
</testsuite>
7+
</testsuites>
8+
<php>
9+
<env name="APP_ENV" value="testing"/>
10+
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
11+
<env name="BCRYPT_ROUNDS" value="12"/>
12+
<env name="CACHE_DRIVER" value="array"/>
13+
<env name="DB_CONNECTION" value="sqlite"/>
14+
<env name="DB_DATABASE" value=":memory:"/>
15+
<env name="MAIL_MAILER" value="array"/>
16+
<env name="QUEUE_CONNECTION" value="sync"/>
17+
<env name="SESSION_DRIVER" value="array"/>
18+
<env name="TELESCOPE_ENABLED" value="false"/>
19+
</php>
20+
<source>
21+
<include>
22+
<directory>src/</directory>
23+
</include>
24+
</source>
2225
</phpunit>

readme.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ More exactly, it provides the `->withMedia()` helper, that will handle the file
1212

1313
## Requirements
1414

15-
**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):
15+
**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):
1616

1717
``` bash
1818
# require the package
19-
composer require "spatie/laravel-medialibrary:^10.0.0"
19+
composer require "spatie/laravel-medialibrary:^11.0"
2020

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

3434
```
3535

36-
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).
36+
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).
3737

3838
## Installation
3939

@@ -100,11 +100,11 @@ CRUD::field('main_image')
100100
]);
101101
```
102102

103-
**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.
103+
**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.
104104

105105
### Defining media collection in the model
106106

107-
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.
107+
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.
108108

109109
```php
110110
// In your Model.php
@@ -151,7 +151,7 @@ CRUD::field('main_image')
151151
'displayConversions' => 'thumb'
152152
]);
153153

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

184184
## Change log
185185

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

188188
## Testing
189189

src/AddonServiceProvider.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Backpack\CRUD\app\Library\CrudPanel\CrudColumn;
66
use Backpack\CRUD\app\Library\CrudPanel\CrudField;
77
use Backpack\CRUD\app\Library\Uploaders\Support\RegisterUploadEvents;
8-
use Backpack\MediaLibraryUploaders\Uploaders\MediaAjaxUploader;
8+
use Backpack\MediaLibraryUploaders\Uploaders\MediaDropzoneUploader;
99
use Backpack\MediaLibraryUploaders\Uploaders\MediaMultipleFiles;
1010
use Backpack\MediaLibraryUploaders\Uploaders\MediaSingleBase64Image;
1111
use Backpack\MediaLibraryUploaders\Uploaders\MediaSingleFile;
@@ -30,14 +30,21 @@ public function boot()
3030
'image' => MediaSingleBase64Image::class,
3131
'upload' => MediaSingleFile::class,
3232
'upload_multiple' => MediaMultipleFiles::class,
33-
'dropzone' => MediaAjaxUploader::class,
3433
], 'withMedia');
3534

35+
if (class_exists(\Backpack\Pro\Uploads\BackpackAjaxUploader::class)) {
36+
app('UploadersRepository')->addUploaderClasses([
37+
'dropzone' => MediaDropzoneUploader::class,
38+
], 'withMedia');
39+
}
40+
3641
// register media upload macros on crud fields and columns.
3742
if (! CrudField::hasMacro('withMedia')) {
3843
CrudField::macro('withMedia', function ($uploadDefinition = [], $subfield = null, $registerEvents = true) {
39-
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
4044
/** @var CrudField $this */
45+
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
46+
$this->setAttributeValue('withMedia', $uploadDefinition);
47+
$this->save();
4148
RegisterUploadEvents::handle($this, $uploadDefinition, 'withMedia', $subfield, $registerEvents);
4249

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

4754
if (! CrudColumn::hasMacro('withMedia')) {
4855
CrudColumn::macro('withMedia', function ($uploadDefinition = [], $subfield = null, $registerEvents = true) {
49-
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
5056
/** @var CrudColumn $this */
57+
$uploadDefinition = is_array($uploadDefinition) ? $uploadDefinition : [];
58+
$this->setAttributeValue('withMedia', $uploadDefinition);
59+
$this->save();
5160
RegisterUploadEvents::handle($this, $uploadDefinition, 'withMedia', $subfield, $registerEvents);
5261

5362
return $this;

src/Uploaders/MediaAjaxUploader.php

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,48 +3,28 @@
33
namespace Backpack\MediaLibraryUploaders\Uploaders;
44

55
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade as CRUD;
6-
use Backpack\CRUD\app\Library\Uploaders\Support\Interfaces\UploaderInterface;
7-
use Illuminate\Database\Eloquent\Model;
6+
use Backpack\Pro\Uploads\BackpackAjaxUploader;
87
use Illuminate\Support\Facades\Storage;
98
use Symfony\Component\HttpFoundation\File\File;
109

11-
class MediaAjaxUploader extends MediaUploader
10+
class MediaAjaxUploader extends BackpackAjaxUploader
1211
{
13-
public static function for(array $field, $configuration): UploaderInterface
12+
use Traits\IdentifiesMedia;
13+
use Traits\AddMediaToModels;
14+
use Traits\HasConstrainedFileAdder;
15+
use Traits\HasCustomProperties;
16+
use Traits\HasSavingCallback;
17+
use Traits\HasCollections;
18+
use Traits\RetrievesUploadedFiles;
19+
use Traits\HandleRepeatableUploads;
20+
use Traits\DeletesUploadedFiles;
21+
22+
public function __construct(array $crudObject, array $configuration)
1423
{
15-
return (new self($field, $configuration))->multiple();
16-
}
17-
18-
public function uploadFiles(Model $entry, $value = null)
19-
{
20-
$temporaryDisk = CRUD::get('dropzone.temporary_disk');
21-
$temporaryFolder = CRUD::get('dropzone.temporary_folder');
22-
23-
$uploads = $value ?? CRUD::getRequest()->input($this->getName()) ?? [];
24-
25-
$uploads = is_array($uploads) ? $uploads : (json_decode($uploads, true) ?? []);
26-
27-
$uploadedFiles = array_filter($uploads, function ($value) use ($temporaryFolder, $temporaryDisk) {
28-
return strpos($value, $temporaryFolder) !== false && Storage::disk($temporaryDisk)->exists($value);
29-
});
30-
31-
$previousSentFiles = array_filter($uploads, function ($value) use ($temporaryFolder) {
32-
return strpos($value, $temporaryFolder) === false;
33-
});
34-
35-
$previousFiles = $this->get($entry);
36-
37-
foreach ($previousFiles as $previousFile) {
38-
if (! in_array($this->getMediaIdentifier($previousFile, $entry), $previousSentFiles)) {
39-
$previousFile->delete();
40-
}
41-
}
42-
43-
foreach ($uploadedFiles as $key => $value) {
44-
$file = new File(Storage::disk($temporaryDisk)->path($value));
45-
46-
$this->addMediaFile($entry, $file);
47-
}
24+
parent::__construct($crudObject, $configuration);
25+
$this->mediaName = $configuration['mediaName'] ?? $crudObject['name'];
26+
$this->savingEventCallback = $configuration['whenSaving'] ?? null;
27+
$this->collection = $configuration['collection'] ?? 'default';
4828
}
4929

5030
public function uploadRepeatableFiles($values, $previousValues, $entry = null)
@@ -83,15 +63,16 @@ public function uploadRepeatableFiles($values, $previousValues, $entry = null)
8363
$fileIdentifier = $this->getMediaIdentifier($previousFile, $entry);
8464
if (empty($sentFiles)) {
8565
$previousFile->delete();
66+
8667
continue;
8768
}
88-
69+
8970
$foundInSentFiles = false;
90-
foreach($sentFiles as $row => $sentFilesInRow) {
71+
foreach ($sentFiles as $row => $sentFilesInRow) {
9172
$fileWasSent = array_search($fileIdentifier, $sentFilesInRow, true);
92-
if($fileWasSent !== false) {
73+
if ($fileWasSent !== false) {
9374
$foundInSentFiles = true;
94-
if($row !== $previousFile->getCustomProperty('repeatableRow')) {
75+
if ($row !== $previousFile->getCustomProperty('repeatableRow')) {
9576
$previousFile->setCustomProperty('repeatableRow', $row);
9677
$previousFile->save();
9778
// avoid checking the same file twice. This is a performance improvement.
@@ -102,7 +83,7 @@ public function uploadRepeatableFiles($values, $previousValues, $entry = null)
10283
}
10384

10485
if ($foundInSentFiles === false) {
105-
$previousFile->delete();
86+
$previousFile->delete();
10687
}
10788
}
10889
}

0 commit comments

Comments
 (0)