Skip to content

Commit 0d58f31

Browse files
committed
Merge branch 'main' of github.com:spatie/laravel-medialibrary
2 parents ce0c4d3 + 74cbdfc commit 0d58f31

File tree

15 files changed

+150
-21
lines changed

15 files changed

+150
-21
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: true
2+
contact_links:
3+
- name: Feature Request
4+
url: https://github.com/spatie/laravel-medialibrary/discussions/new?category=ideas
5+
about: Share ideas for new features
6+
- name: Ask a Question
7+
url: https://github.com/spatie/laravel-medialibrary/discussions/new?category=q-a
8+
about: Ask the community for help

.github/workflows/pint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ jobs:
1616
uses: aglipanci/laravel-pint-action@v2
1717

1818
- name: Commit changes
19-
uses: stefanzweifel/git-auto-commit-action@v6
19+
uses: stefanzweifel/git-auto-commit-action@v7
2020
with:
2121
commit_message: Fix styling

.github/workflows/run-tests.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
fail-fast: false
1111
matrix:
12-
php: [8.4, 8.3, 8.2]
12+
php: [8.5, 8.4, 8.3, 8.2]
1313
laravel: [10.*, 11.*, 12.*]
1414
dependency-version: [prefer-lowest, prefer-stable]
1515
include:
@@ -18,7 +18,10 @@ jobs:
1818
- laravel: 11.*
1919
testbench: ^9.0
2020
- laravel: 12.*
21-
testbench: ^10.0
21+
testbench: ^10.6
22+
exclude:
23+
- laravel: 10.*
24+
php: 8.5
2225

2326
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.dependency-version }}
2427

.github/workflows/update-changelog.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
release-notes: ${{ github.event.release.body }}
2222

2323
- name: Commit updated CHANGELOG
24-
uses: stefanzweifel/git-auto-commit-action@v6
24+
uses: stefanzweifel/git-auto-commit-action@v7
2525
with:
2626
branch: main
2727
commit_message: Update CHANGELOG

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,35 @@
22

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

5+
## 11.16.0 - 2025-10-21
6+
7+
### What's Changed
8+
9+
* Test PHP 8.5 by @erikn69 in https://github.com/spatie/laravel-medialibrary/pull/3857
10+
* Add Support for Defining Custom Path Generators in Models or Service Providers by @alissn in https://github.com/spatie/laravel-medialibrary/pull/3828
11+
* Bump stefanzweifel/git-auto-commit-action from 6 to 7 by @dependabot[bot] in https://github.com/spatie/laravel-medialibrary/pull/3860
12+
13+
### New Contributors
14+
15+
* @alissn made their first contribution in https://github.com/spatie/laravel-medialibrary/pull/3828
16+
17+
**Full Changelog**: https://github.com/spatie/laravel-medialibrary/compare/11.15.0...11.16.0
18+
19+
## 11.15.0 - 2025-09-19
20+
21+
### What's Changed
22+
23+
* docs: add installation instructions for image optimizers on Alpine Linux by @nastoychev in https://github.com/spatie/laravel-medialibrary/pull/3845
24+
* Feat: allow null expiration for model get temporary url method by @chinmaypurav in https://github.com/spatie/laravel-medialibrary/pull/3851
25+
* Update issue template by @AlexVanderbist in https://github.com/spatie/laravel-medialibrary/pull/3850
26+
* Optimize filename suffix generation in MediaStream by @iizno in https://github.com/spatie/laravel-medialibrary/pull/3855
27+
28+
### New Contributors
29+
30+
* @iizno made their first contribution in https://github.com/spatie/laravel-medialibrary/pull/3855
31+
32+
**Full Changelog**: https://github.com/spatie/laravel-medialibrary/compare/11.14.0...11.15.0
33+
534
## 11.14.0 - 2025-08-19
635

736
### What's Changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"league/flysystem-aws-s3-v3": "^3.22",
5050
"mockery/mockery": "^1.6.7",
5151
"orchestra/testbench": "^7.0|^8.17|^9.0|^10.0",
52-
"pestphp/pest": "^2.28|^3.5",
52+
"pestphp/pest": "^2.28|^3.5|^4.0",
5353
"phpstan/extension-installer": "^1.3.1",
5454
"spatie/laravel-ray": "^1.33",
5555
"spatie/pdf-to-image": "^2.2|^3.0",

docs/advanced-usage/using-a-custom-directory-structure.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,31 @@ interface PathGenerator
5555

5656
There aren't any restrictions on how the directories can be named. When a `Media`-object gets deleted the package will delete its entire associated directory. To avoid tears or worse, make sure that every media gets stored its own unique directory.
5757

58+
### Model-specific Custom Path Generators
59+
In addition to setting a global path generator in the config file, You can also define a `CustomPathGenerator` class for specific models directly inside the model's `booting()` method or within a service provider:
60+
61+
```php
62+
use Spatie\MediaLibrary\Support\PathGenerator\PathGeneratorFactory;
63+
use Spatie\MediaLibrary\Tests\Support\PathGenerator\CustomPathGenerator;
64+
65+
class YourModel extends Model
66+
{
67+
protected static function booting(): void
68+
{
69+
PathGeneratorFactory::setCustomPathGenerators(static::class, CustomPathGenerator::class);
70+
}
71+
}
72+
```
73+
74+
This allows you to customize the directory structure on a per-model basis.
75+
76+
Keep in mind that path generators set in the model override those defined in the config file.
77+
78+
79+
### Defining a Custom Path Generator Inside a Model or Service Provider
80+
81+
This approach allows for fine-grained control over the media directory structure on a per-model basis, without affecting global configuration.
82+
5883
## Are you a visual learner?
5984

6085
Here's a video that shows custom paths:

src/MediaCollections/Exceptions/InvalidPathGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ public static function doesNotImplementPathGenerator(string $class): self
1616
{
1717
$pathGeneratorClass = PathGenerator::class;
1818

19-
return new static("Path generator class `{$class}` must implement `$pathGeneratorClass}`");
19+
return new static("Path generator class `{$class}` must implement `{$pathGeneratorClass}`");
2020
}
2121
}

src/Support/MediaStream.php

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ class MediaStream implements Responsable
1212
{
1313
protected Collection $mediaItems;
1414

15+
private array $nameCounters = [];
16+
1517
protected array $zipOptions;
1618

1719
public static function create(string $zipName): self
@@ -108,28 +110,22 @@ protected function getZipStreamContents(): Collection
108110

109111
protected function getFileNameWithSuffix(Collection $mediaItems, int $currentIndex): string
110112
{
111-
$fileNameCount = 0;
112-
113113
$fileName = $mediaItems[$currentIndex]->getDownloadFilename();
114114

115-
foreach ($mediaItems as $index => $media) {
116-
if ($index >= $currentIndex) {
117-
break;
118-
}
115+
$prefix = $this->getZipFileNamePrefix($mediaItems, $currentIndex);
116+
$key = $prefix.$fileName;
119117

120-
if ($this->getZipFileNamePrefix($mediaItems, $index).$media->getDownloadFilename() === $this->getZipFileNamePrefix($mediaItems, $currentIndex).$fileName) {
121-
$fileNameCount++;
122-
}
123-
}
118+
$count = ($this->nameCounters[$key] ?? 0);
119+
$this->nameCounters[$key] = $count + 1;
124120

125-
if ($fileNameCount === 0) {
121+
if ($count === 0) {
126122
return $fileName;
127123
}
128124

129125
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
130126
$fileNameWithoutExtension = pathinfo($fileName, PATHINFO_FILENAME);
131127

132-
return "{$fileNameWithoutExtension} ({$fileNameCount}).{$extension}";
128+
return "{$fileNameWithoutExtension} ({$count}).{$extension}";
133129
}
134130

135131
protected function getZipFileNamePrefix(Collection $mediaItems, int $currentIndex): string

src/Support/PathGenerator/PathGeneratorFactory.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
class PathGeneratorFactory
1010
{
11+
protected static array $customPathGenerators = [];
12+
1113
public static function create(Media $media): PathGenerator
1214
{
1315
$pathGeneratorClass = static::getPathGeneratorClass($media);
@@ -17,11 +19,21 @@ public static function create(Media $media): PathGenerator
1719
return app($pathGeneratorClass);
1820
}
1921

22+
/**
23+
* @throws InvalidPathGenerator
24+
*/
25+
public static function setCustomPathGenerators(string $model, string $pathGeneratorClass): void
26+
{
27+
static::guardAgainstInvalidPathGenerator($pathGeneratorClass);
28+
29+
self::$customPathGenerators[$model] = $pathGeneratorClass;
30+
}
31+
2032
protected static function getPathGeneratorClass(Media $media)
2133
{
2234
$defaultPathGeneratorClass = config('media-library.path_generator');
2335

24-
foreach (config('media-library.custom_path_generators', []) as $modelClass => $customPathGeneratorClass) {
36+
foreach (array_merge(config('media-library.custom_path_generators', []), self::$customPathGenerators) as $modelClass => $customPathGeneratorClass) {
2537
if (static::mediaBelongToModelClass($media, $modelClass)) {
2638
return $customPathGeneratorClass;
2739
}

0 commit comments

Comments
 (0)