I am using laravel spatie medialibrary and I want to store files in a directory structure like /year/month/date
I read here https://spatie.be/docs/laravel-medialibrary/v11/advanced-usage/using-a-custom-directory-structure
and I created this file in /app/Services/MediaLibrary/CustomPathGenerator.php which I list below.
Now files are stored in the correct place as I want.
But my problem is that when I try to READ the file, this CANNOT BE FOUND, because same rule applies when trying to read the file location and the date has changed and then it points to different path that does not exist.
Any idea how to solve this?
Thanks!
Here is my file /app/Services/MediaLibrary/CustomPathGenerator.php:
<?php
namespace App\Services\MediaLibrary;
use \Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\PathGenerator as BasePathGenerator;
class CustomPathGenerator implements BasePathGenerator
{
/**
* Get the path for the given media, relative to the root storage path.
*
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
*
* @return string
*/
public function getPath(Media $media): string
{
//return $this->getBasePath($media).'/';
//return md5($media->id . config('app.key')) . '/';
$md5_var=md5($media->id . config('app.key'));
$myPath=date("Y").'/'.date("m").'/'.substr($md5_var,0,4). '/'.substr($md5_var,4,4) . '/'.substr($md5_var,8,4).'/'.$md5_var.'/';
return $myPath;
}
/**
* Get the path for conversions of the given media, relative to the root storage path.
*
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
*
* @return string
*/
public function getPathForConversions(Media $media): string
{
//return $this->getBasePath($media).'/conversions/';
//return md5($media->id . config('app.key')) . '/conversions/';
$md5_var=md5($media->id . config('app.key'));
$myPath=date("Y").'/'.date("m").'/'.substr($md5_var,0,4). '/'.substr($md5_var,4,4) . '/'.substr($md5_var,8,4).'/'.$md5_var. '/conversions/';
return $myPath;
}
/**
* Get the path for responsive images of the given media, relative to the root storage path.
*
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
*
* @return string
*/
public function getPathForResponsiveImages(Media $media): string
{
//return $this->getBasePath($media).'/responsive-images/';
//return md5($media->id . config('app.key')) . '/responsive-images/';
$md5_var=md5($media->id . config('app.key'));
$myPath=date("Y").'/'.date("m").'/'.substr($md5_var,0,4). '/'.substr($md5_var,4,4) . '/'.substr($md5_var,8,4).'/'.$md5_var. '/responsive-images/';
return $myPath;
}
}
You can change your path creator class to use the created_at date if the Media model has already been saved.
I've written an example of the approach, it may need tweaks to work in your environment of course:
<?php
namespace App\Services\MediaLibrary;
use \Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\PathGenerator as BasePathGenerator;
class CustomPathGenerator implements BasePathGenerator
{
private function getFilePath(Media $media, ?string $extra = null): string
{
$datePart = date('Y/m');
if ($media->exists) {
$datePart = $media->created_at->format('Y/m');
}
$md5_var = md5($media->id . config('app.key'));
return implode('/', array_filter([
$datePart,
substr($md5_var, 0, 4),
substr($md5_var, 4, 4),
substr($md5_var, 8, 4),
$md5_var,
$extra
])) . '/';
}
/**
* Get the path for the given media, relative to the root storage path.
*
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
*
* @return string
*/
public function getPath(Media $media): string
{
return $this->getFilePath($media);
}
/**
* Get the path for conversions of the given media, relative to the root storage path.
*
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
*
* @return string
*/
public function getPathForConversions(Media $media): string
{
return $this->getFilePath($media, 'conversions');
}
/**
* Get the path for responsive images of the given media, relative to the root storage path.
*
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
*
* @return string
*/
public function getPathForResponsiveImages(Media $media): string
{
return $this->getFilePath($media, 'responsive-images');
}
}