From ab9c13fe0d348b6f894f24a6b21a0644c5f9847b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 13 May 2025 01:59:54 -0600 Subject: [PATCH] New supported formats, Preserve ICC Color Profiles, libvips support Update image pipeline to handle avif, heic and webp and preserve ICC color profiles and added libvips support. --- .../Commands/CatchUnoptimizedMedia.php | 1 + app/Console/Commands/FixMediaDriver.php | 239 ++--- app/Console/Commands/ImportEmojis.php | 2 +- app/Console/Commands/RegenerateThumbnails.php | 2 +- app/Http/Controllers/Api/ApiV1Controller.php | 4 +- .../Controllers/Api/ApiV1Dot1Controller.php | 1 + app/Http/Controllers/Api/ApiV2Controller.php | 1 + app/Http/Controllers/ImportPostController.php | 2 +- .../Stories/StoryApiV1Controller.php | 2 +- .../Controllers/StoryComposeController.php | 2 +- .../ImageOptimizePipeline/ImageOptimize.php | 3 + app/Media.php | 2 +- app/Services/MediaStorageService.php | 7 +- app/Status.php | 696 +++++++------- app/Util/Media/Blurhash.php | 95 +- app/Util/Media/Image.php | 488 +++++----- composer.json | 2 +- composer.lock | 876 ++++++++++-------- config/image.php | 8 +- 19 files changed, 1288 insertions(+), 1145 deletions(-) diff --git a/app/Console/Commands/CatchUnoptimizedMedia.php b/app/Console/Commands/CatchUnoptimizedMedia.php index a5bb22f98..9c5dba5e9 100644 --- a/app/Console/Commands/CatchUnoptimizedMedia.php +++ b/app/Console/Commands/CatchUnoptimizedMedia.php @@ -48,6 +48,7 @@ class CatchUnoptimizedMedia extends Command ->whereNotNull('status_id') ->whereNotNull('media_path') ->whereIn('mime', [ + 'image/jpg', 'image/jpeg', 'image/png', ]) diff --git a/app/Console/Commands/FixMediaDriver.php b/app/Console/Commands/FixMediaDriver.php index a20b0574e..b8537d4ab 100644 --- a/app/Console/Commands/FixMediaDriver.php +++ b/app/Console/Commands/FixMediaDriver.php @@ -11,123 +11,124 @@ use App\Jobs\MediaPipeline\MediaFixLocalFilesystemCleanupPipeline; class FixMediaDriver extends Command { - /** - * The name and signature of the console command. - * - * @var string - */ - protected $signature = 'media:fix-nonlocal-driver'; - - /** - * The console command description. - * - * @var string - */ - protected $description = 'Fix filesystem when FILESYSTEM_DRIVER not set to local'; - - /** - * Execute the console command. - * - * @return int - */ - public function handle() - { - if(config('filesystems.default') !== 'local') { - $this->error('Invalid default filesystem, set FILESYSTEM_DRIVER=local to proceed'); - return Command::SUCCESS; - } - - if((bool) config_cache('pixelfed.cloud_storage') == false) { - $this->error('Cloud storage not enabled, exiting...'); - return Command::SUCCESS; - } - - $this->info(' ____ _ ______ __ '); - $this->info(' / __ \(_) _____ / / __/__ ____/ / '); - $this->info(' / /_/ / / |/_/ _ \/ / /_/ _ \/ __ / '); - $this->info(' / ____/ /> info(' /_/ /_/_/|_|\___/_/_/ \___/\__,_/ '); - $this->info(' '); - $this->info(' Media Filesystem Fix'); - $this->info(' ====================='); - $this->info(' Fix media that was created when FILESYSTEM_DRIVER=local'); - $this->info(' was not properly set. This command will fix media urls'); - $this->info(' and optionally optimize/generate thumbnails when applicable,'); - $this->info(' clean up temporary local media files and clear the app cache'); - $this->info(' to fix media paths/urls.'); - $this->info(' '); - $this->error(' Remember, FILESYSTEM_DRIVER=local must remain set or you will break things!'); - - if(!$this->confirm('Are you sure you want to perform this command?')) { - $this->info('Exiting...'); - return Command::SUCCESS; - } - - $optimize = $this->choice( - 'Do you want to optimize media and generate thumbnails? This will store s3 locally and re-upload optimized versions.', - ['no', 'yes'], - 1 - ); - - $cloud = Storage::disk(config('filesystems.cloud')); - $mountManager = new MountManager([ - 's3' => $cloud->getDriver(), - 'local' => Storage::disk('local')->getDriver(), - ]); - - $this->info('Fixing media, this may take a while...'); - $this->line(' '); - $bar = $this->output->createProgressBar(Media::whereNotNull('status_id')->whereNull('cdn_url')->count()); - $bar->start(); - - foreach(Media::whereNotNull('status_id')->whereNull('cdn_url')->lazyById(20) as $media) { - if($cloud->exists($media->media_path)) { - if($optimize === 'yes') { - $mountManager->copy( - 's3://' . $media->media_path, - 'local://' . $media->media_path - ); - sleep(1); - if(empty($media->original_sha256)) { - $hash = \hash_file('sha256', Storage::disk('local')->path($media->media_path)); - $media->original_sha256 = $hash; - $media->save(); - sleep(1); - } - if( - $media->mime && - in_array($media->mime, [ - 'image/jpeg', - 'image/png', - 'image/webp' - ]) - ) { - ImageOptimize::dispatch($media); - sleep(3); - } - } else { - $media->cdn_url = $cloud->url($media->media_path); - $media->save(); - } - } - $bar->advance(); - } - - $bar->finish(); - $this->line(' '); - $this->line(' '); - - $this->callSilently('cache:clear'); - - $this->info('Successfully fixed media paths and cleared cached!'); - - if($optimize === 'yes') { - MediaFixLocalFilesystemCleanupPipeline::dispatch()->delay(now()->addMinutes(15))->onQueue('default'); - $this->line(' '); - $this->info('A cleanup job has been dispatched to delete media stored locally, it may take a few minutes to process!'); - } - - $this->line(' '); - return Command::SUCCESS; - } + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'media:fix-nonlocal-driver'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Fix filesystem when FILESYSTEM_DRIVER not set to local'; + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + if(config('filesystems.default') !== 'local') { + $this->error('Invalid default filesystem, set FILESYSTEM_DRIVER=local to proceed'); + return Command::SUCCESS; + } + + if((bool) config_cache('pixelfed.cloud_storage') == false) { + $this->error('Cloud storage not enabled, exiting...'); + return Command::SUCCESS; + } + + $this->info(' ____ _ ______ __ '); + $this->info(' / __ \(_) _____ / / __/__ ____/ / '); + $this->info(' / /_/ / / |/_/ _ \/ / /_/ _ \/ __ / '); + $this->info(' / ____/ /> info(' /_/ /_/_/|_|\___/_/_/ \___/\__,_/ '); + $this->info(' '); + $this->info(' Media Filesystem Fix'); + $this->info(' ====================='); + $this->info(' Fix media that was created when FILESYSTEM_DRIVER=local'); + $this->info(' was not properly set. This command will fix media urls'); + $this->info(' and optionally optimize/generate thumbnails when applicable,'); + $this->info(' clean up temporary local media files and clear the app cache'); + $this->info(' to fix media paths/urls.'); + $this->info(' '); + $this->error(' Remember, FILESYSTEM_DRIVER=local must remain set or you will break things!'); + + if(!$this->confirm('Are you sure you want to perform this command?')) { + $this->info('Exiting...'); + return Command::SUCCESS; + } + + $optimize = $this->choice( + 'Do you want to optimize media and generate thumbnails? This will store s3 locally and re-upload optimized versions.', + ['no', 'yes'], + 1 + ); + + $cloud = Storage::disk(config('filesystems.cloud')); + $mountManager = new MountManager([ + 's3' => $cloud->getDriver(), + 'local' => Storage::disk('local')->getDriver(), + ]); + + $this->info('Fixing media, this may take a while...'); + $this->line(' '); + $bar = $this->output->createProgressBar(Media::whereNotNull('status_id')->whereNull('cdn_url')->count()); + $bar->start(); + + foreach(Media::whereNotNull('status_id')->whereNull('cdn_url')->lazyById(20) as $media) { + if($cloud->exists($media->media_path)) { + if($optimize === 'yes') { + $mountManager->copy( + 's3://' . $media->media_path, + 'local://' . $media->media_path + ); + sleep(1); + if(empty($media->original_sha256)) { + $hash = \hash_file('sha256', Storage::disk('local')->path($media->media_path)); + $media->original_sha256 = $hash; + $media->save(); + sleep(1); + } + if( + $media->mime && + in_array($media->mime, [ + 'image/jpg', + 'image/jpeg', + 'image/png', + 'image/webp' + ]) + ) { + ImageOptimize::dispatch($media); + sleep(3); + } + } else { + $media->cdn_url = $cloud->url($media->media_path); + $media->save(); + } + } + $bar->advance(); + } + + $bar->finish(); + $this->line(' '); + $this->line(' '); + + $this->callSilently('cache:clear'); + + $this->info('Successfully fixed media paths and cleared cached!'); + + if($optimize === 'yes') { + MediaFixLocalFilesystemCleanupPipeline::dispatch()->delay(now()->addMinutes(15))->onQueue('default'); + $this->line(' '); + $this->info('A cleanup job has been dispatched to delete media stored locally, it may take a few minutes to process!'); + } + + $this->line(' '); + return Command::SUCCESS; + } } diff --git a/app/Console/Commands/ImportEmojis.php b/app/Console/Commands/ImportEmojis.php index 77a0c29a4..aea3d9e08 100644 --- a/app/Console/Commands/ImportEmojis.php +++ b/app/Console/Commands/ImportEmojis.php @@ -110,7 +110,7 @@ class ImportEmojis extends Command private function isEmoji($filename) { - $allowedMimeTypes = ['image/png', 'image/jpeg', 'image/webp']; + $allowedMimeTypes = ['image/png', 'image/jpeg', 'image/webp', 'image/jpg']; $mimeType = mime_content_type($filename); return in_array($mimeType, $allowedMimeTypes); diff --git a/app/Console/Commands/RegenerateThumbnails.php b/app/Console/Commands/RegenerateThumbnails.php index f5759c36f..488baa041 100644 --- a/app/Console/Commands/RegenerateThumbnails.php +++ b/app/Console/Commands/RegenerateThumbnails.php @@ -40,7 +40,7 @@ class RegenerateThumbnails extends Command public function handle() { DB::transaction(function() { - Media::whereIn('mime', ['image/jpeg', 'image/png']) + Media::whereIn('mime', ['image/jpeg', 'image/png', 'image/jpg']) ->chunk(50, function($medias) { foreach($medias as $media) { \App\Jobs\ImageOptimizePipeline\ImageThumbnail::dispatch($media); diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 0e6317197..467df3a7b 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -243,7 +243,7 @@ class ApiV1Controller extends Controller } $this->validate($request, [ - 'avatar' => 'sometimes|mimetypes:image/jpeg,image/png|max:'.config('pixelfed.max_avatar_size'), + 'avatar' => 'sometimes|mimetypes:image/jpeg,image/jpg,image/png|max:'.config('pixelfed.max_avatar_size'), 'display_name' => 'nullable|string|max:30', 'note' => 'nullable|string|max:200', 'locked' => 'nullable', @@ -1907,6 +1907,7 @@ class ApiV1Controller extends Controller $media->save(); switch ($media->mime) { + case 'image/jpg': case 'image/jpeg': case 'image/png': case 'image/webp': @@ -2137,6 +2138,7 @@ class ApiV1Controller extends Controller $media->save(); switch ($media->mime) { + case 'image/jpg': case 'image/jpeg': case 'image/png': case 'image/webp': diff --git a/app/Http/Controllers/Api/ApiV1Dot1Controller.php b/app/Http/Controllers/Api/ApiV1Dot1Controller.php index f9cac94be..a7c796592 100644 --- a/app/Http/Controllers/Api/ApiV1Dot1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Dot1Controller.php @@ -1307,6 +1307,7 @@ class ApiV1Dot1Controller extends Controller $media->save(); switch ($media->mime) { + case 'image/jpg': case 'image/jpeg': case 'image/png': ImageOptimize::dispatch($media)->onQueue('mmo'); diff --git a/app/Http/Controllers/Api/ApiV2Controller.php b/app/Http/Controllers/Api/ApiV2Controller.php index bf248bf0e..f8794b323 100644 --- a/app/Http/Controllers/Api/ApiV2Controller.php +++ b/app/Http/Controllers/Api/ApiV2Controller.php @@ -310,6 +310,7 @@ class ApiV2Controller extends Controller switch ($media->mime) { case 'image/jpeg': + case 'image/jpg': case 'image/png': ImageOptimize::dispatch($media)->onQueue('mmo'); break; diff --git a/app/Http/Controllers/ImportPostController.php b/app/Http/Controllers/ImportPostController.php index e491019f8..39a6257b2 100644 --- a/app/Http/Controllers/ImportPostController.php +++ b/app/Http/Controllers/ImportPostController.php @@ -201,7 +201,7 @@ class ImportPostController extends Controller $this->checkPermissions($request); - $allowedMimeTypes = ['image/png', 'image/jpeg']; + $allowedMimeTypes = ['image/png', 'image/jpeg', 'image/jpg']; if (config('import.instagram.allow_image_webp') && str_contains(config_cache('pixelfed.media_types'), 'image/webp')) { $allowedMimeTypes[] = 'image/webp'; diff --git a/app/Http/Controllers/Stories/StoryApiV1Controller.php b/app/Http/Controllers/Stories/StoryApiV1Controller.php index 48599fc3a..a1f55c7ef 100644 --- a/app/Http/Controllers/Stories/StoryApiV1Controller.php +++ b/app/Http/Controllers/Stories/StoryApiV1Controller.php @@ -260,7 +260,7 @@ class StoryApiV1Controller extends Controller 'file' => function () { return [ 'required', - 'mimetypes:image/jpeg,image/png,video/mp4', + 'mimetypes:image/jpeg,image/jpg,image/png,video/mp4', 'max:'.config_cache('pixelfed.max_photo_size'), ]; }, diff --git a/app/Http/Controllers/StoryComposeController.php b/app/Http/Controllers/StoryComposeController.php index e02e2d219..44aff1e23 100644 --- a/app/Http/Controllers/StoryComposeController.php +++ b/app/Http/Controllers/StoryComposeController.php @@ -34,7 +34,7 @@ class StoryComposeController extends Controller 'file' => function () { return [ 'required', - 'mimetypes:image/jpeg,image/png,video/mp4', + 'mimetypes:image/jpeg,image/png,video/mp4,image/jpg', 'max:'.config_cache('pixelfed.max_photo_size'), ]; }, diff --git a/app/Jobs/ImageOptimizePipeline/ImageOptimize.php b/app/Jobs/ImageOptimizePipeline/ImageOptimize.php index e2d558143..28685d1f7 100644 --- a/app/Jobs/ImageOptimizePipeline/ImageOptimize.php +++ b/app/Jobs/ImageOptimizePipeline/ImageOptimize.php @@ -40,6 +40,9 @@ class ImageOptimize implements ShouldQueue public function handle() { $media = $this->media; + if(!$media) { + return; + } $path = storage_path('app/'.$media->media_path); if (!is_file($path) || $media->skip_optimize) { return; diff --git a/app/Media.php b/app/Media.php index 51bc21152..e1c545729 100644 --- a/app/Media.php +++ b/app/Media.php @@ -64,7 +64,7 @@ class Media extends Model return $this->cdn_url; } - if ($this->media_path && $this->mime && in_array($this->mime, ['image/jpeg', 'image/png'])) { + if ($this->media_path && $this->mime && in_array($this->mime, ['image/jpeg', 'image/png', 'image/jpg'])) { return $this->remote_media || Str::startsWith($this->media_path, 'http') ? $this->media_path : url(Storage::url($this->media_path)); diff --git a/app/Services/MediaStorageService.php b/app/Services/MediaStorageService.php index d4751e102..f746f8acf 100644 --- a/app/Services/MediaStorageService.php +++ b/app/Services/MediaStorageService.php @@ -138,6 +138,7 @@ class MediaStorageService } $mimes = [ + 'image/jpg', 'image/jpeg', 'image/png', 'video/mp4', @@ -166,6 +167,7 @@ class MediaStorageService $ext = '.gif'; break; + case 'image/jpg': case 'image/jpeg': $ext = '.jpg'; break; @@ -219,6 +221,7 @@ class MediaStorageService $mimes = [ 'application/octet-stream', + 'image/jpg', 'image/jpeg', 'image/png', ]; @@ -249,7 +252,7 @@ class MediaStorageService } $base = ($local ? 'public/cache/' : 'cache/').'avatars/'.$avatar->profile_id; - $ext = $head['mime'] == 'image/jpeg' ? 'jpg' : 'png'; + $ext = ($head['mime'] == 'image/png') ? 'png' : 'jpg'; $path = 'avatar_'.strtolower(Str::random(random_int(3, 6))).'.'.$ext; $tmpBase = storage_path('app/remcache/'); $tmpPath = 'avatar_'.$avatar->profile_id.'-'.$path; @@ -262,7 +265,7 @@ class MediaStorageService $mimeCheck = Storage::mimeType('remcache/'.$tmpPath); - if (! $mimeCheck || ! in_array($mimeCheck, ['image/png', 'image/jpeg'])) { + if (! $mimeCheck || ! in_array($mimeCheck, ['image/png', 'image/jpeg', 'image/jpg'])) { $avatar->last_fetched_at = now(); $avatar->save(); unlink($tmpName); diff --git a/app/Status.php b/app/Status.php index 8b69c199c..be209efe4 100644 --- a/app/Status.php +++ b/app/Status.php @@ -15,104 +15,104 @@ use Illuminate\Support\Str; class Status extends Model { - use HasSnowflakePrimary, SoftDeletes; - - /** - * Indicates if the IDs are auto-incrementing. - * - * @var bool - */ - public $incrementing = false; - - /** - * The attributes that should be mutated to dates. - * - * @var array - */ - protected $casts = [ - 'deleted_at' => 'datetime', - 'edited_at' => 'datetime' - ]; - - protected $guarded = []; - - const STATUS_TYPES = [ - 'text', - 'photo', - 'photo:album', - 'video', - 'video:album', - 'photo:video:album', - 'share', - 'reply', - 'story', - 'story:reply', - 'story:reaction', - 'story:live', - 'loop' - ]; - - const MAX_MENTIONS = 20; - - const MAX_HASHTAGS = 60; - - const MAX_LINKS = 5; - - public function profile() - { - return $this->belongsTo(Profile::class); - } - - public function media() - { - return $this->hasMany(Media::class); - } - - public function firstMedia() - { - return $this->hasMany(Media::class)->orderBy('order', 'asc')->first(); - } - - public function viewType() - { - if($this->type) { - return $this->type; - } - return $this->setType(); - } - - public function setType() - { - if(in_array($this->type, self::STATUS_TYPES)) { - return $this->type; - } - $mimes = $this->media->pluck('mime')->toArray(); - $type = StatusController::mimeTypeCheck($mimes); - if($type) { - $this->type = $type; - $this->save(); - return $type; - } - } - - public function thumb($showNsfw = false) - { - $entity = StatusService::get($this->id, false); - - if(!$entity || !isset($entity['media_attachments']) || empty($entity['media_attachments'])) { - return url(Storage::url('public/no-preview.png')); - } - - if((!isset($entity['sensitive']) || $entity['sensitive']) && !$showNsfw) { - return url(Storage::url('public/no-preview.png')); - } + use HasSnowflakePrimary, SoftDeletes; + + /** + * Indicates if the IDs are auto-incrementing. + * + * @var bool + */ + public $incrementing = false; + + /** + * The attributes that should be mutated to dates. + * + * @var array + */ + protected $casts = [ + 'deleted_at' => 'datetime', + 'edited_at' => 'datetime' + ]; + + protected $guarded = []; + + const STATUS_TYPES = [ + 'text', + 'photo', + 'photo:album', + 'video', + 'video:album', + 'photo:video:album', + 'share', + 'reply', + 'story', + 'story:reply', + 'story:reaction', + 'story:live', + 'loop' + ]; + + const MAX_MENTIONS = 20; + + const MAX_HASHTAGS = 60; + + const MAX_LINKS = 5; + + public function profile() + { + return $this->belongsTo(Profile::class); + } + + public function media() + { + return $this->hasMany(Media::class); + } + + public function firstMedia() + { + return $this->hasMany(Media::class)->orderBy('order', 'asc')->first(); + } + + public function viewType() + { + if($this->type) { + return $this->type; + } + return $this->setType(); + } + + public function setType() + { + if(in_array($this->type, self::STATUS_TYPES)) { + return $this->type; + } + $mimes = $this->media->pluck('mime')->toArray(); + $type = StatusController::mimeTypeCheck($mimes); + if($type) { + $this->type = $type; + $this->save(); + return $type; + } + } + + public function thumb($showNsfw = false) + { + $entity = StatusService::get($this->id, false); + + if(!$entity || !isset($entity['media_attachments']) || empty($entity['media_attachments'])) { + return url(Storage::url('public/no-preview.png')); + } + + if((!isset($entity['sensitive']) || $entity['sensitive']) && !$showNsfw) { + return url(Storage::url('public/no-preview.png')); + } if(!isset($entity['visibility']) || !in_array($entity['visibility'], ['public', 'unlisted'])) { return url(Storage::url('public/no-preview.png')); } - return collect($entity['media_attachments']) - ->filter(fn($media) => $media['type'] == 'image' && in_array($media['mime'], ['image/jpeg', 'image/png'])) + return collect($entity['media_attachments']) + ->filter(fn($media) => $media['type'] == 'image' && in_array($media['mime'], ['image/jpeg', 'image/png', 'image/jpg'])) ->map(function($media) { if(!Str::endsWith($media['preview_url'], ['no-preview.png', 'no-preview.jpg'])) { return $media['preview_url']; @@ -121,259 +121,259 @@ class Status extends Model return $media['url']; }) ->first() ?? url(Storage::url('public/no-preview.png')); - } - - public function url($forceLocal = false) - { - if($this->uri) { - return $forceLocal ? "/i/web/post/_/{$this->profile_id}/{$this->id}" : $this->uri; - } else { - $id = $this->id; - $account = AccountService::get($this->profile_id, true); - if(!$account || !isset($account['username'])) { - return '/404'; - } - $path = url(config('app.url')."/p/{$account['username']}/{$id}"); - return $path; - } - } - - public function permalink($suffix = '/activity') - { - $id = $this->id; - $username = $this->profile->username; - $path = config('app.url')."/p/{$username}/{$id}{$suffix}"; - - return url($path); - } - - public function editUrl() - { - return $this->url().'/edit'; - } - - public function mediaUrl() - { - $media = $this->firstMedia(); - $path = $media->media_path; - $hash = is_null($media->processed_at) ? md5('unprocessed') : md5($media->created_at); - $url = $media->cdn_url ? $media->cdn_url . "?v={$hash}" : url(Storage::url($path)."?v={$hash}"); - - return $url; - } - - public function likes() - { - return $this->hasMany(Like::class); - } - - public function liked() : bool - { - if(!Auth::check()) { - return false; - } - - $pid = Auth::user()->profile_id; - - return Like::select('status_id', 'profile_id') - ->whereStatusId($this->id) - ->whereProfileId($pid) - ->exists(); - } - - public function likedBy() - { - return $this->hasManyThrough( - Profile::class, - Like::class, - 'status_id', - 'id', - 'id', - 'profile_id' - ); - } - - public function comments() - { - return $this->hasMany(self::class, 'in_reply_to_id'); - } - - public function bookmarked() - { - if (!Auth::check()) { - return false; - } - $profile = Auth::user()->profile; - - return Bookmark::whereProfileId($profile->id)->whereStatusId($this->id)->count(); - } - - public function shares() - { - return $this->hasMany(self::class, 'reblog_of_id'); - } - - public function shared() : bool - { - if(!Auth::check()) { - return false; - } - $pid = Auth::user()->profile_id; - - return $this->select('profile_id', 'reblog_of_id') - ->whereProfileId($pid) - ->whereReblogOfId($this->id) - ->exists(); - } - - public function sharedBy() - { - return $this->hasManyThrough( - Profile::class, - Status::class, - 'reblog_of_id', - 'id', - 'id', - 'profile_id' - ); - } - - public function parent() - { - $parent = $this->in_reply_to_id ?? $this->reblog_of_id; - if (!empty($parent)) { - return $this->findOrFail($parent); - } else { - return false; - } - } - - public function conversation() - { - return $this->hasOne(Conversation::class); - } - - public function hashtags() - { - return $this->hasManyThrough( - Hashtag::class, - StatusHashtag::class, - 'status_id', - 'id', - 'id', - 'hashtag_id' - ); - } - - public function mentions() - { - return $this->hasManyThrough( - Profile::class, - Mention::class, - 'status_id', - 'id', - 'id', - 'profile_id' - ); - } - - public function reportUrl() - { - return route('report.form')."?type=post&id={$this->id}"; - } - - public function toActivityStream() - { - $media = $this->media; - $mediaCollection = []; - foreach ($media as $image) { - $mediaCollection[] = [ - 'type' => 'Link', - 'href' => $image->url(), - 'mediaType' => $image->mime, - ]; - } - $obj = [ - '@context' => 'https://www.w3.org/ns/activitystreams', - 'type' => 'Image', - 'name' => null, - 'url' => $mediaCollection, - ]; - - return $obj; - } - - public function recentComments() - { - return $this->comments()->orderBy('created_at', 'desc')->take(3); - } - - public function scopeToAudience($audience) - { - if(!in_array($audience, ['to', 'cc']) || $this->local == false) { - return; - } - $res = []; - $res['to'] = []; - $res['cc'] = []; - $scope = $this->scope; - $mentions = $this->mentions->map(function ($mention) { - return $mention->permalink(); - })->toArray(); - - if($this->in_reply_to_id != null) { - $parent = $this->parent(); - if($parent) { - $mentions = array_merge([$parent->profile->permalink()], $mentions); - } - } - - switch ($scope) { - case 'public': - $res['to'] = [ - "https://www.w3.org/ns/activitystreams#Public" - ]; - $res['cc'] = array_merge([$this->profile->permalink('/followers')], $mentions); - break; - - case 'unlisted': - $res['to'] = array_merge([$this->profile->permalink('/followers')], $mentions); - $res['cc'] = [ - "https://www.w3.org/ns/activitystreams#Public" - ]; - break; - - case 'private': - $res['to'] = array_merge([$this->profile->permalink('/followers')], $mentions); - $res['cc'] = []; - break; - - // TODO: Update scope when DMs are supported - case 'direct': - $res['to'] = []; - $res['cc'] = []; - break; - } - return $res[$audience]; - } - - public function place() - { - return $this->belongsTo(Place::class); - } - - public function directMessage() - { - return $this->hasOne(DirectMessage::class); - } - - public function poll() - { - return $this->hasOne(Poll::class); - } - - public function edits() - { - return $this->hasMany(StatusEdit::class); - } + } + + public function url($forceLocal = false) + { + if($this->uri) { + return $forceLocal ? "/i/web/post/_/{$this->profile_id}/{$this->id}" : $this->uri; + } else { + $id = $this->id; + $account = AccountService::get($this->profile_id, true); + if(!$account || !isset($account['username'])) { + return '/404'; + } + $path = url(config('app.url')."/p/{$account['username']}/{$id}"); + return $path; + } + } + + public function permalink($suffix = '/activity') + { + $id = $this->id; + $username = $this->profile->username; + $path = config('app.url')."/p/{$username}/{$id}{$suffix}"; + + return url($path); + } + + public function editUrl() + { + return $this->url().'/edit'; + } + + public function mediaUrl() + { + $media = $this->firstMedia(); + $path = $media->media_path; + $hash = is_null($media->processed_at) ? md5('unprocessed') : md5($media->created_at); + $url = $media->cdn_url ? $media->cdn_url . "?v={$hash}" : url(Storage::url($path)."?v={$hash}"); + + return $url; + } + + public function likes() + { + return $this->hasMany(Like::class); + } + + public function liked() : bool + { + if(!Auth::check()) { + return false; + } + + $pid = Auth::user()->profile_id; + + return Like::select('status_id', 'profile_id') + ->whereStatusId($this->id) + ->whereProfileId($pid) + ->exists(); + } + + public function likedBy() + { + return $this->hasManyThrough( + Profile::class, + Like::class, + 'status_id', + 'id', + 'id', + 'profile_id' + ); + } + + public function comments() + { + return $this->hasMany(self::class, 'in_reply_to_id'); + } + + public function bookmarked() + { + if (!Auth::check()) { + return false; + } + $profile = Auth::user()->profile; + + return Bookmark::whereProfileId($profile->id)->whereStatusId($this->id)->count(); + } + + public function shares() + { + return $this->hasMany(self::class, 'reblog_of_id'); + } + + public function shared() : bool + { + if(!Auth::check()) { + return false; + } + $pid = Auth::user()->profile_id; + + return $this->select('profile_id', 'reblog_of_id') + ->whereProfileId($pid) + ->whereReblogOfId($this->id) + ->exists(); + } + + public function sharedBy() + { + return $this->hasManyThrough( + Profile::class, + Status::class, + 'reblog_of_id', + 'id', + 'id', + 'profile_id' + ); + } + + public function parent() + { + $parent = $this->in_reply_to_id ?? $this->reblog_of_id; + if (!empty($parent)) { + return $this->findOrFail($parent); + } else { + return false; + } + } + + public function conversation() + { + return $this->hasOne(Conversation::class); + } + + public function hashtags() + { + return $this->hasManyThrough( + Hashtag::class, + StatusHashtag::class, + 'status_id', + 'id', + 'id', + 'hashtag_id' + ); + } + + public function mentions() + { + return $this->hasManyThrough( + Profile::class, + Mention::class, + 'status_id', + 'id', + 'id', + 'profile_id' + ); + } + + public function reportUrl() + { + return route('report.form')."?type=post&id={$this->id}"; + } + + public function toActivityStream() + { + $media = $this->media; + $mediaCollection = []; + foreach ($media as $image) { + $mediaCollection[] = [ + 'type' => 'Link', + 'href' => $image->url(), + 'mediaType' => $image->mime, + ]; + } + $obj = [ + '@context' => 'https://www.w3.org/ns/activitystreams', + 'type' => 'Image', + 'name' => null, + 'url' => $mediaCollection, + ]; + + return $obj; + } + + public function recentComments() + { + return $this->comments()->orderBy('created_at', 'desc')->take(3); + } + + public function scopeToAudience($audience) + { + if(!in_array($audience, ['to', 'cc']) || $this->local == false) { + return; + } + $res = []; + $res['to'] = []; + $res['cc'] = []; + $scope = $this->scope; + $mentions = $this->mentions->map(function ($mention) { + return $mention->permalink(); + })->toArray(); + + if($this->in_reply_to_id != null) { + $parent = $this->parent(); + if($parent) { + $mentions = array_merge([$parent->profile->permalink()], $mentions); + } + } + + switch ($scope) { + case 'public': + $res['to'] = [ + "https://www.w3.org/ns/activitystreams#Public" + ]; + $res['cc'] = array_merge([$this->profile->permalink('/followers')], $mentions); + break; + + case 'unlisted': + $res['to'] = array_merge([$this->profile->permalink('/followers')], $mentions); + $res['cc'] = [ + "https://www.w3.org/ns/activitystreams#Public" + ]; + break; + + case 'private': + $res['to'] = array_merge([$this->profile->permalink('/followers')], $mentions); + $res['cc'] = []; + break; + + // TODO: Update scope when DMs are supported + case 'direct': + $res['to'] = []; + $res['cc'] = []; + break; + } + return $res[$audience]; + } + + public function place() + { + return $this->belongsTo(Place::class); + } + + public function directMessage() + { + return $this->hasOne(DirectMessage::class); + } + + public function poll() + { + return $this->hasOne(Poll::class); + } + + public function edits() + { + return $this->hasMany(StatusEdit::class); + } } diff --git a/app/Util/Media/Blurhash.php b/app/Util/Media/Blurhash.php index 8e232ea17..037c2d70a 100644 --- a/app/Util/Media/Blurhash.php +++ b/app/Util/Media/Blurhash.php @@ -7,53 +7,52 @@ use App\Media; class Blurhash { - const DEFAULT_HASH = 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay'; - - public static function generate(Media $media) - { - if(!in_array($media->mime, ['image/png', 'image/jpeg', 'video/mp4'])) { - return self::DEFAULT_HASH; - } - - if($media->thumbnail_path == null) { - return self::DEFAULT_HASH; - } - - $file = storage_path('app/' . $media->thumbnail_path); - - if(!is_file($file)) { - return self::DEFAULT_HASH; - } - - $image = imagecreatefromstring(file_get_contents($file)); - if(!$image) { - return self::DEFAULT_HASH; - } - $width = imagesx($image); - $height = imagesy($image); - - $pixels = []; - for ($y = 0; $y < $height; ++$y) { - $row = []; - for ($x = 0; $x < $width; ++$x) { - $index = imagecolorat($image, $x, $y); - $colors = imagecolorsforindex($image, $index); - - $row[] = [$colors['red'], $colors['green'], $colors['blue']]; - } - $pixels[] = $row; - } - - // Free the allocated GdImage object from memory: - imagedestroy($image); - - $components_x = 4; - $components_y = 4; - $blurhash = BlurhashEngine::encode($pixels, $components_x, $components_y); - if(strlen($blurhash) > 191) { - return self::DEFAULT_HASH; - } - return $blurhash; - } + const DEFAULT_HASH = 'U4Rfzst8?bt7ogayj[j[~pfQ9Goe%Mj[WBay'; + + public static function generate(Media $media) + { + if(!in_array($media->mime, ['image/png', 'image/jpeg', 'image/jpg', 'video/mp4'])) { + return self::DEFAULT_HASH; + } + + if($media->thumbnail_path == null) { + return self::DEFAULT_HASH; + } + + $file = storage_path('app/' . $media->thumbnail_path); + + if(!is_file($file)) { + return self::DEFAULT_HASH; + } + + $image = imagecreatefromstring(file_get_contents($file)); + if(!$image) { + return self::DEFAULT_HASH; + } + $width = imagesx($image); + $height = imagesy($image); + + $pixels = []; + for ($y = 0; $y < $height; ++$y) { + $row = []; + for ($x = 0; $x < $width; ++$x) { + $index = imagecolorat($image, $x, $y); + $colors = imagecolorsforindex($image, $index); + + $row[] = [$colors['red'], $colors['green'], $colors['blue']]; + } + $pixels[] = $row; + } + + imagedestroy($image); + + $components_x = 4; + $components_y = 4; + $blurhash = BlurhashEngine::encode($pixels, $components_x, $components_y); + if(strlen($blurhash) > 191) { + return self::DEFAULT_HASH; + } + return $blurhash; + } } diff --git a/app/Util/Media/Image.php b/app/Util/Media/Image.php index bbd3918ad..f77045046 100644 --- a/app/Util/Media/Image.php +++ b/app/Util/Media/Image.php @@ -3,223 +3,281 @@ namespace App\Util\Media; use App\Media; -use Image as Intervention; +use Intervention\Image\ImageManager; +use Intervention\Image\Encoders\JpegEncoder; +use Intervention\Image\Encoders\WebpEncoder; +use Intervention\Image\Encoders\AvifEncoder; +use Intervention\Image\Encoders\PngEncoder; use Cache, Log, Storage; +use App\Util\Media\Blurhash; class Image { - public $square; - public $landscape; - public $portrait; - public $thumbnail; - public $orientation; - public $acceptedMimes = [ - 'image/png', - 'image/jpeg', - 'image/webp', - 'image/avif', - ]; - - public function __construct() - { - ini_set('memory_limit', config('pixelfed.memory_limit', '1024M')); - - $this->square = $this->orientations()['square']; - $this->landscape = $this->orientations()['landscape']; - $this->portrait = $this->orientations()['portrait']; - $this->thumbnail = [ - 'width' => 640, - 'height' => 640, - ]; - $this->orientation = null; - } - - public function orientations() - { - return [ - 'square' => [ - 'width' => 1080, - 'height' => 1080, - ], - 'landscape' => [ - 'width' => 1920, - 'height' => 1080, - ], - 'portrait' => [ - 'width' => 1080, - 'height' => 1350, - ], - ]; - } - - public function getAspectRatio($mediaPath, $thumbnail = false) - { - if (!is_file($mediaPath)) { - throw new \Exception('Invalid Media Path'); - } - if ($thumbnail) { - return [ - 'dimensions' => $this->thumbnail, - 'orientation' => 'thumbnail', - ]; - } - - list($width, $height) = getimagesize($mediaPath); - $aspect = $width / $height; - $orientation = $aspect === 1 ? 'square' : - ($aspect > 1 ? 'landscape' : 'portrait'); - $this->orientation = $orientation; - - return [ - 'dimensions' => $this->orientations()[$orientation], - 'orientation' => $orientation, - 'width_original' => $width, - 'height_original' => $height, - ]; - } - - public function resizeImage(Media $media) - { - $basePath = storage_path('app/'.$media->media_path); - - $this->handleResizeImage($media); - } - - public function resizeThumbnail(Media $media) - { - $basePath = storage_path('app/'.$media->media_path); - - $this->handleThumbnailImage($media); - } - - public function handleResizeImage(Media $media) - { - $this->handleImageTransform($media, false); - } - - public function handleThumbnailImage(Media $media) - { - $this->handleImageTransform($media, true); - } - - public function handleImageTransform(Media $media, $thumbnail = false) - { - $path = $media->media_path; - $file = storage_path('app/'.$path); - if (!in_array($media->mime, $this->acceptedMimes)) { - return; - } - $ratio = $this->getAspectRatio($file, $thumbnail); - $aspect = $ratio['dimensions']; - $orientation = $ratio['orientation']; - - try { - $img = Intervention::make($file); - $metadata = $img->exif(); - $img->orientate(); - if($thumbnail) { - $img->resize($aspect['width'], $aspect['height'], function ($constraint) { - $constraint->aspectRatio(); - }); - } else { - if(config('media.exif.database', false) == true && $metadata) { - $meta = []; - $keys = [ - "COMPUTED", - "FileName", - "FileSize", - "FileType", - "Make", - "Model", - "MimeType", - "ColorSpace", - "ExifVersion", - "Orientation", - "UserComment", - "XResolution", - "YResolution", - "FileDateTime", - "SectionsFound", - "ExifImageWidth", - "ResolutionUnit", - "ExifImageLength", - "FlashPixVersion", - "Exif_IFD_Pointer", - "YCbCrPositioning", - "ComponentsConfiguration", - "ExposureTime", - "FNumber", - "ISOSpeedRatings", - "ShutterSpeedValue" - ]; - foreach ($metadata as $k => $v) { - if(in_array($k, $keys)) { - $meta[$k] = $v; - } - } - $media->metadata = json_encode($meta); - } - - if ( - ($ratio['width_original'] > $aspect['width']) - || ($ratio['height_original'] > $aspect['height']) - ) { - $img->resize($aspect['width'], $aspect['height'], function ($constraint) { - $constraint->aspectRatio(); - }); - } - } - $converted = $this->setBaseName($path, $thumbnail, $img->extension); - $newPath = storage_path('app/'.$converted['path']); - - $quality = config_cache('pixelfed.image_quality'); - $img->save($newPath, $quality); - - if ($thumbnail == true) { - $media->thumbnail_path = $converted['path']; - $media->thumbnail_url = url(Storage::url($converted['path'])); - } else { - $media->width = $img->width(); - $media->height = $img->height(); - $media->orientation = $orientation; - $media->media_path = $converted['path']; - $media->mime = $img->mime; - } - - $img->destroy(); - $media->save(); - - if($thumbnail) { - $this->generateBlurhash($media); - } - - Cache::forget('status:transformer:media:attachments:'.$media->status_id); - Cache::forget('status:thumb:'.$media->status_id); - - } catch (Exception $e) { - $media->processed_at = now(); - $media->save(); - Log::info('MediaResizeException: Could not process media id: ' . $media->id); - } - } - - public function setBaseName($basePath, $thumbnail, $extension) - { - $png = false; - $path = explode('.', $basePath); - $name = ($thumbnail == true) ? $path[0].'_thumb' : $path[0]; - $ext = last($path); - $basePath = "{$name}.{$ext}"; - - return ['path' => $basePath, 'png' => $png]; - } - - protected function generateBlurhash($media) - { - $blurhash = Blurhash::generate($media); - if($blurhash) { - $media->blurhash = $blurhash; - $media->save(); - } - } + public $square; + public $landscape; + public $portrait; + public $thumbnail; + public $orientation; + public $acceptedMimes = [ + 'image/png', + 'image/jpeg', + 'image/jpg', + 'image/webp', + 'image/avif', + 'image/heic', + ]; + + protected $imageManager; + + public function __construct() + { + ini_set('memory_limit', config('pixelfed.memory_limit', '1024M')); + + $this->square = $this->orientations()['square']; + $this->landscape = $this->orientations()['landscape']; + $this->portrait = $this->orientations()['portrait']; + $this->thumbnail = [ + 'width' => 640, + 'height' => 640, + ]; + $this->orientation = null; + + $driver = match(config('image.driver')) { + 'imagick' => new \Intervention\Image\Drivers\Imagick\Driver(), + 'vips' => new \Intervention\Image\Drivers\Vips\Driver(), + default => new \Intervention\Image\Drivers\Gd\Driver() + }; + + $this->imageManager = new ImageManager( + $driver, + autoOrientation: true, + decodeAnimation: true, + blendingColor: 'ffffff', + strip: true + ); + } + + public function orientations() + { + return [ + 'square' => [ + 'width' => 1080, + 'height' => 1080, + ], + 'landscape' => [ + 'width' => 1920, + 'height' => 1080, + ], + 'portrait' => [ + 'width' => 1080, + 'height' => 1350, + ], + ]; + } + + public function getAspectRatio($mediaPath, $thumbnail = false) + { + if ($thumbnail) { + return [ + 'dimensions' => $this->thumbnail, + 'orientation' => 'thumbnail', + ]; + } + + if (!is_file($mediaPath)) { + throw new \Exception('Invalid Media Path'); + } + + list($width, $height) = getimagesize($mediaPath); + $aspect = $width / $height; + $orientation = $aspect === 1 ? 'square' : + ($aspect > 1 ? 'landscape' : 'portrait'); + $this->orientation = $orientation; + + return [ + 'dimensions' => $this->orientations()[$orientation], + 'orientation' => $orientation, + 'width_original' => $width, + 'height_original' => $height, + ]; + } + + public function resizeImage(Media $media) + { + $this->handleResizeImage($media); + } + + public function resizeThumbnail(Media $media) + { + $this->handleThumbnailImage($media); + } + + public function handleResizeImage(Media $media) + { + $this->handleImageTransform($media, false); + } + + public function handleThumbnailImage(Media $media) + { + $this->handleImageTransform($media, true); + } + + public function handleImageTransform(Media $media, $thumbnail = false) + { + $path = $media->media_path; + $file = storage_path('app/'.$path); + if (!in_array($media->mime, $this->acceptedMimes)) { + return; + } + $ratio = $this->getAspectRatio($file, $thumbnail); + $aspect = $ratio['dimensions']; + $orientation = $ratio['orientation']; + + try { + $fileInfo = pathinfo($file); + $extension = strtolower($fileInfo['extension'] ?? 'jpg'); + + $metadata = null; + if (!$thumbnail && config('media.exif.database', false) == true) { + try { + $exif = @exif_read_data($file); + if ($exif) { + $meta = []; + $keys = [ + "FileName", + "FileSize", + "FileType", + "Make", + "Model", + "MimeType", + "ColorSpace", + "ExifVersion", + "Orientation", + "UserComment", + "XResolution", + "YResolution", + "FileDateTime", + "SectionsFound", + "ExifImageWidth", + "ResolutionUnit", + "ExifImageLength", + "FlashPixVersion", + "Exif_IFD_Pointer", + "YCbCrPositioning", + "ComponentsConfiguration", + "ExposureTime", + "FNumber", + "ISOSpeedRatings", + "ShutterSpeedValue" + ]; + foreach ($exif as $k => $v) { + if (in_array($k, $keys)) { + $meta[$k] = $v; + } + } + $media->metadata = json_encode($meta); + } + } catch (\Exception $e) { + Log::info('EXIF extraction failed: ' . $e->getMessage()); + } + } + + $img = $this->imageManager->read($file); + + if ($thumbnail) { + $img = $img->coverDown( + $aspect['width'], + $aspect['height'] + ); + } else { + if ( + ($ratio['width_original'] > $aspect['width']) + || ($ratio['height_original'] > $aspect['height']) + ) { + $img = $img->scaleDown( + $aspect['width'], + $aspect['height'] + ); + } + } + + $converted = $this->setBaseName($path, $thumbnail, $extension); + $newPath = storage_path('app/'.$converted['path']); + + $quality = config_cache('pixelfed.image_quality'); + + $encoder = null; + switch ($extension) { + case 'jpeg': + case 'jpg': + $encoder = new JpegEncoder($quality); + break; + case 'png': + $encoder = new PngEncoder(); + break; + case 'webp': + $encoder = new WebpEncoder($quality); + break; + case 'avif': + $encoder = new AvifEncoder($quality); + break; + case 'heic': + $encoder = new JpegEncoder($quality); + $extension = 'jpg'; + break; + default: + $encoder = new JpegEncoder($quality); + $extension = 'jpg'; + } + + $encoded = $encoder->encode($img); + + file_put_contents($newPath, $encoded->toString()); + + if ($thumbnail == true) { + $media->thumbnail_path = $converted['path']; + $media->thumbnail_url = url(Storage::url($converted['path'])); + } else { + $media->width = $img->width(); + $media->height = $img->height(); + $media->orientation = $orientation; + $media->media_path = $converted['path']; + $media->mime = 'image/' . $extension; + } + + $media->save(); + + if ($thumbnail) { + $this->generateBlurhash($media); + } + + Cache::forget('status:transformer:media:attachments:'.$media->status_id); + Cache::forget('status:thumb:'.$media->status_id); + + } catch (\Exception $e) { + $media->processed_at = now(); + $media->save(); + Log::info('MediaResizeException: ' . $e->getMessage() . ' | Could not process media id: ' . $media->id); + } + } + + public function setBaseName($basePath, $thumbnail, $extension) + { + $png = false; + $path = explode('.', $basePath); + $name = ($thumbnail == true) ? $path[0].'_thumb' : $path[0]; + $ext = last($path); + $basePath = "{$name}.{$ext}"; + + return ['path' => $basePath, 'png' => $png]; + } + + protected function generateBlurhash($media) + { + $blurhash = Blurhash::generate($media); + if ($blurhash) { + $media->blurhash = $blurhash; + $media->save(); + } + } } diff --git a/composer.json b/composer.json index 07f7a61e2..583079928 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "buzz/laravel-h-captcha": "^1.0.4", "doctrine/dbal": "^3.0", "endroid/qr-code": "^6.0", - "intervention/image": "^2.4", + "intervention/image": "^3.11.2", "jenssegers/agent": "^2.6", "laravel-notification-channels/expo": "^2.0.0", "laravel-notification-channels/webpush": "^10.2", diff --git a/composer.lock b/composer.lock index 098e0d7d5..cbe80a276 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ac363dfc5037ce5d118b7b4a8e75bffe", + "content-hash": "fc7f320209f9bd3f731d3de6e6f1755f", "packages": [ { "name": "aws/aws-crt-php", @@ -62,16 +62,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.342.4", + "version": "3.343.9", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "65cc842b9998d415b05d635b6146d0728934ff4a" + "reference": "6ca5eb1c60b879cf516e5fadefec87afc6219e74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/65cc842b9998d415b05d635b6146d0728934ff4a", - "reference": "65cc842b9998d415b05d635b6146d0728934ff4a", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6ca5eb1c60b879cf516e5fadefec87afc6219e74", + "reference": "6ca5eb1c60b879cf516e5fadefec87afc6219e74", "shasum": "" }, "require": { @@ -153,9 +153,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.342.4" + "source": "https://github.com/aws/aws-sdk-php/tree/3.343.9" }, - "time": "2025-03-11T18:27:07+00:00" + "time": "2025-05-12T18:11:31+00:00" }, { "name": "bacon/bacon-qr-code", @@ -793,26 +793,29 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.4", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", - "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=13" + }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12", - "phpstan/phpstan": "1.4.10 || 2.0.3", + "doctrine/coding-standard": "^9 || ^12 || ^13", + "phpstan/phpstan": "1.4.10 || 2.1.11", "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", "psr/log": "^1 || ^2 || ^3" }, "suggest": { @@ -832,9 +835,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.4" + "source": "https://github.com/doctrine/deprecations/tree/1.1.5" }, - "time": "2024-12-07T21:18:45+00:00" + "time": "2025-04-07T20:06:18+00:00" }, { "name": "doctrine/event-manager", @@ -1217,16 +1220,16 @@ }, { "name": "egulias/email-validator", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "b115554301161fa21467629f1e1391c1936de517" + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/b115554301161fa21467629f1e1391c1936de517", - "reference": "b115554301161fa21467629f1e1391c1936de517", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", "shasum": "" }, "require": { @@ -1272,7 +1275,7 @@ ], "support": { "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.3" + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" }, "funding": [ { @@ -1280,20 +1283,20 @@ "type": "github" } ], - "time": "2024-12-27T00:36:43+00:00" + "time": "2025-03-06T22:45:56+00:00" }, { "name": "endroid/qr-code", - "version": "6.0.5", + "version": "6.0.8", "source": { "type": "git", "url": "https://github.com/endroid/qr-code.git", - "reference": "238baddf22500bbfeb2fa1ddc1eb2bd9374a6998" + "reference": "8102273afbcd5e3d95f1faaab2c5aa31e3637f61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/endroid/qr-code/zipball/238baddf22500bbfeb2fa1ddc1eb2bd9374a6998", - "reference": "238baddf22500bbfeb2fa1ddc1eb2bd9374a6998", + "url": "https://api.github.com/repos/endroid/qr-code/zipball/8102273afbcd5e3d95f1faaab2c5aa31e3637f61", + "reference": "8102273afbcd5e3d95f1faaab2c5aa31e3637f61", "shasum": "" }, "require": { @@ -1344,7 +1347,7 @@ ], "support": { "issues": "https://github.com/endroid/qr-code/issues", - "source": "https://github.com/endroid/qr-code/tree/6.0.5" + "source": "https://github.com/endroid/qr-code/tree/6.0.8" }, "funding": [ { @@ -1352,7 +1355,7 @@ "type": "github" } ], - "time": "2025-03-07T08:15:43+00:00" + "time": "2025-05-10T14:28:45+00:00" }, { "name": "evenement/evenement", @@ -1464,16 +1467,16 @@ }, { "name": "firebase/php-jwt", - "version": "v6.11.0", + "version": "v6.11.1", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "8f718f4dfc9c5d5f0c994cdfd103921b43592712" + "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/8f718f4dfc9c5d5f0c994cdfd103921b43592712", - "reference": "8f718f4dfc9c5d5f0c994cdfd103921b43592712", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", + "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", "shasum": "" }, "require": { @@ -1521,9 +1524,9 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.11.0" + "source": "https://github.com/firebase/php-jwt/tree/v6.11.1" }, - "time": "2025-01-23T05:11:06+00:00" + "time": "2025-04-09T20:32:01+00:00" }, { "name": "fruitcake/php-cors", @@ -1660,16 +1663,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.9.2", + "version": "7.9.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "d281ed313b989f213357e3be1a179f02196ac99b" + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", - "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", "shasum": "" }, "require": { @@ -1766,7 +1769,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.9.2" + "source": "https://github.com/guzzle/guzzle/tree/7.9.3" }, "funding": [ { @@ -1782,20 +1785,20 @@ "type": "tidelift" } ], - "time": "2024-07-24T11:22:20+00:00" + "time": "2025-03-27T13:37:11+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.4", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", - "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c", + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c", "shasum": "" }, "require": { @@ -1849,7 +1852,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.4" + "source": "https://github.com/guzzle/promises/tree/2.2.0" }, "funding": [ { @@ -1865,20 +1868,20 @@ "type": "tidelift" } ], - "time": "2024-10-17T10:06:22+00:00" + "time": "2025-03-27T13:27:01+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", - "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16", "shasum": "" }, "require": { @@ -1965,7 +1968,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.7.0" + "source": "https://github.com/guzzle/psr7/tree/2.7.1" }, "funding": [ { @@ -1981,7 +1984,7 @@ "type": "tidelift" } ], - "time": "2024-07-18T11:15:46+00:00" + "time": "2025-03-27T12:30:47+00:00" }, { "name": "guzzlehttp/uri-template", @@ -2069,51 +2072,107 @@ ], "time": "2025-02-03T10:55:03+00:00" }, + { + "name": "intervention/gif", + "version": "4.2.2", + "source": { + "type": "git", + "url": "https://github.com/Intervention/gif.git", + "reference": "5999eac6a39aa760fb803bc809e8909ee67b451a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/gif/zipball/5999eac6a39aa760fb803bc809e8909ee67b451a", + "reference": "5999eac6a39aa760fb803bc809e8909ee67b451a", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Gif\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "Native PHP GIF Encoder/Decoder", + "homepage": "https://github.com/intervention/gif", + "keywords": [ + "animation", + "gd", + "gif", + "image" + ], + "support": { + "issues": "https://github.com/Intervention/gif/issues", + "source": "https://github.com/Intervention/gif/tree/4.2.2" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2025-03-29T07:46:21+00:00" + }, { "name": "intervention/image", - "version": "2.7.2", + "version": "3.11.2", "source": { "type": "git", "url": "https://github.com/Intervention/image.git", - "reference": "04be355f8d6734c826045d02a1079ad658322dad" + "reference": "ebbb711871fb261c064cf4c422f5f3c124fe1842" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/04be355f8d6734c826045d02a1079ad658322dad", - "reference": "04be355f8d6734c826045d02a1079ad658322dad", + "url": "https://api.github.com/repos/Intervention/image/zipball/ebbb711871fb261c064cf4c422f5f3c124fe1842", + "reference": "ebbb711871fb261c064cf4c422f5f3c124fe1842", "shasum": "" }, "require": { - "ext-fileinfo": "*", - "guzzlehttp/psr7": "~1.1 || ^2.0", - "php": ">=5.4.0" + "ext-mbstring": "*", + "intervention/gif": "^4.2", + "php": "^8.1" }, "require-dev": { - "mockery/mockery": "~0.9.2", - "phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15" + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" }, "suggest": { - "ext-gd": "to use GD library based image processing.", - "ext-imagick": "to use Imagick based image processing.", - "intervention/imagecache": "Caching extension for the Intervention Image library" + "ext-exif": "Recommended to be able to read EXIF data properly." }, "type": "library", - "extra": { - "laravel": { - "aliases": { - "Image": "Intervention\\Image\\Facades\\Image" - }, - "providers": [ - "Intervention\\Image\\ImageServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "2.4-dev" - } - }, "autoload": { "psr-4": { - "Intervention\\Image\\": "src/Intervention/Image" + "Intervention\\Image\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2127,19 +2186,19 @@ "homepage": "https://intervention.io/" } ], - "description": "Image handling and manipulation library with support for Laravel integration", - "homepage": "http://image.intervention.io/", + "description": "PHP image manipulation", + "homepage": "https://image.intervention.io/", "keywords": [ "gd", "image", "imagick", - "laravel", + "resize", "thumbnail", "watermark" ], "support": { "issues": "https://github.com/Intervention/image/issues", - "source": "https://github.com/Intervention/image/tree/2.7.2" + "source": "https://github.com/Intervention/image/tree/3.11.2" }, "funding": [ { @@ -2149,9 +2208,13 @@ { "url": "https://github.com/Intervention", "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" } ], - "time": "2022-05-21T17:30:32+00:00" + "time": "2025-02-27T13:08:55+00:00" }, { "name": "jaybizzle/crawler-detect", @@ -2420,16 +2483,16 @@ }, { "name": "laravel/framework", - "version": "v12.1.1", + "version": "v12.13.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "9be5738f1ca1530055bb9d6db81f909a7ed34842" + "reference": "52b588bcd8efc6d01bc1493d2d67848f8065f269" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9be5738f1ca1530055bb9d6db81f909a7ed34842", - "reference": "9be5738f1ca1530055bb9d6db81f909a7ed34842", + "url": "https://api.github.com/repos/laravel/framework/zipball/52b588bcd8efc6d01bc1493d2d67848f8065f269", + "reference": "52b588bcd8efc6d01bc1493d2d67848f8065f269", "shasum": "" }, "require": { @@ -2450,7 +2513,7 @@ "guzzlehttp/uri-template": "^1.0", "laravel/prompts": "^0.3.0", "laravel/serializable-closure": "^1.3|^2.0", - "league/commonmark": "^2.6", + "league/commonmark": "^2.7", "league/flysystem": "^3.25.1", "league/flysystem-local": "^3.25.1", "league/uri": "^7.5.1", @@ -2538,11 +2601,11 @@ "league/flysystem-sftp-v3": "^3.25.1", "mockery/mockery": "^1.6.10", "orchestra/testbench-core": "^10.0.0", - "pda/pheanstalk": "^5.0.6", + "pda/pheanstalk": "^5.0.6|^7.0.0", "php-http/discovery": "^1.15", "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1", - "predis/predis": "^2.3", + "predis/predis": "^2.3|^3.0", "resend/resend-php": "^0.10.0", "symfony/cache": "^7.2.0", "symfony/http-client": "^7.2.0", @@ -2574,7 +2637,7 @@ "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1).", - "predis/predis": "Required to use the predis connector (^2.3).", + "predis/predis": "Required to use the predis connector (^2.3|^3.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", @@ -2631,7 +2694,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-03-05T15:31:19+00:00" + "time": "2025-05-07T17:29:01+00:00" }, { "name": "laravel/helpers", @@ -2692,16 +2755,16 @@ }, { "name": "laravel/horizon", - "version": "v5.31.0", + "version": "v5.31.2", "source": { "type": "git", "url": "https://github.com/laravel/horizon.git", - "reference": "a21e7d64784b24eaf3bf873f82affbf67707a72a" + "reference": "e6068c65be6c02a01e34531abf3143fab91f0de0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/a21e7d64784b24eaf3bf873f82affbf67707a72a", - "reference": "a21e7d64784b24eaf3bf873f82affbf67707a72a", + "url": "https://api.github.com/repos/laravel/horizon/zipball/e6068c65be6c02a01e34531abf3143fab91f0de0", + "reference": "e6068c65be6c02a01e34531abf3143fab91f0de0", "shasum": "" }, "require": { @@ -2766,9 +2829,9 @@ ], "support": { "issues": "https://github.com/laravel/horizon/issues", - "source": "https://github.com/laravel/horizon/tree/v5.31.0" + "source": "https://github.com/laravel/horizon/tree/v5.31.2" }, - "time": "2025-03-04T14:56:42+00:00" + "time": "2025-04-18T12:57:39+00:00" }, { "name": "laravel/passport", @@ -2907,16 +2970,16 @@ }, { "name": "laravel/pulse", - "version": "v1.4.0", + "version": "v1.4.1", "source": { "type": "git", "url": "https://github.com/laravel/pulse.git", - "reference": "62099ede70df2272544f0c0657eda0c73d25a6b2" + "reference": "b3cf86e88fa78ea8e6aeb86a7d9ea25ba2c1d31f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pulse/zipball/62099ede70df2272544f0c0657eda0c73d25a6b2", - "reference": "62099ede70df2272544f0c0657eda0c73d25a6b2", + "url": "https://api.github.com/repos/laravel/pulse/zipball/b3cf86e88fa78ea8e6aeb86a7d9ea25ba2c1d31f", + "reference": "b3cf86e88fa78ea8e6aeb86a7d9ea25ba2c1d31f", "shasum": "" }, "require": { @@ -2949,7 +3012,7 @@ "orchestra/testbench": "^8.23.1|^9.0|^10.0", "pestphp/pest": "^2.0", "pestphp/pest-plugin-laravel": "^2.2", - "phpstan/phpstan": "^1.11", + "phpstan/phpstan": "^1.12.21", "predis/predis": "^1.0|^2.0" }, "type": "library", @@ -2990,20 +3053,20 @@ "issues": "https://github.com/laravel/pulse/issues", "source": "https://github.com/laravel/pulse" }, - "time": "2025-02-11T13:36:44+00:00" + "time": "2025-03-30T16:25:37+00:00" }, { "name": "laravel/serializable-closure", - "version": "v2.0.3", + "version": "v2.0.4", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "f379c13663245f7aa4512a7869f62eb14095f23f" + "reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/f379c13663245f7aa4512a7869f62eb14095f23f", - "reference": "f379c13663245f7aa4512a7869f62eb14095f23f", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b352cf0534aa1ae6b4d825d1e762e35d43f8a841", + "reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841", "shasum": "" }, "require": { @@ -3051,7 +3114,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2025-02-11T15:03:05+00:00" + "time": "2025-03-19T13:51:03+00:00" }, { "name": "laravel/tinker", @@ -3321,16 +3384,16 @@ }, { "name": "league/commonmark", - "version": "2.6.1", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "d990688c91cedfb69753ffc2512727ec646df2ad" + "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d990688c91cedfb69753ffc2512727ec646df2ad", - "reference": "d990688c91cedfb69753ffc2512727ec646df2ad", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", + "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", "shasum": "" }, "require": { @@ -3367,7 +3430,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.7-dev" + "dev-main": "2.8-dev" } }, "autoload": { @@ -3424,7 +3487,7 @@ "type": "tidelift" } ], - "time": "2024-12-29T14:10:59+00:00" + "time": "2025-05-05T12:20:28+00:00" }, { "name": "league/config", @@ -3510,20 +3573,20 @@ }, { "name": "league/event", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/thephpleague/event.git", - "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119" + "reference": "062ebb450efbe9a09bc2478e89b7c933875b0935" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119", - "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "url": "https://api.github.com/repos/thephpleague/event/zipball/062ebb450efbe9a09bc2478e89b7c933875b0935", + "reference": "062ebb450efbe9a09bc2478e89b7c933875b0935", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=7.1.0" }, "require-dev": { "henrikbjorn/phpspec-code-coverage": "~1.0.1", @@ -3558,9 +3621,9 @@ ], "support": { "issues": "https://github.com/thephpleague/event/issues", - "source": "https://github.com/thephpleague/event/tree/master" + "source": "https://github.com/thephpleague/event/tree/2.3.0" }, - "time": "2018-11-26T11:52:41+00:00" + "time": "2025-03-14T19:51:10+00:00" }, { "name": "league/flysystem", @@ -4201,16 +4264,16 @@ }, { "name": "livewire/livewire", - "version": "v3.6.1", + "version": "v3.6.3", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "0df0a762698176d714e42e2dfed92b6b9e24b8e4" + "reference": "56aa1bb63a46e06181c56fa64717a7287e19115e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/0df0a762698176d714e42e2dfed92b6b9e24b8e4", - "reference": "0df0a762698176d714e42e2dfed92b6b9e24b8e4", + "url": "https://api.github.com/repos/livewire/livewire/zipball/56aa1bb63a46e06181c56fa64717a7287e19115e", + "reference": "56aa1bb63a46e06181c56fa64717a7287e19115e", "shasum": "" }, "require": { @@ -4265,7 +4328,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.6.1" + "source": "https://github.com/livewire/livewire/tree/v3.6.3" }, "funding": [ { @@ -4273,7 +4336,7 @@ "type": "github" } ], - "time": "2025-03-04T21:48:52+00:00" + "time": "2025-04-12T22:26:52+00:00" }, { "name": "minishlink/web-push", @@ -4404,16 +4467,16 @@ }, { "name": "monolog/monolog", - "version": "3.8.1", + "version": "3.9.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", - "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", "shasum": "" }, "require": { @@ -4491,7 +4554,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.8.1" + "source": "https://github.com/Seldaek/monolog/tree/3.9.0" }, "funding": [ { @@ -4503,7 +4566,7 @@ "type": "tidelift" } ], - "time": "2024-12-05T17:15:07+00:00" + "time": "2025-03-24T10:02:05+00:00" }, { "name": "mtdowling/jmespath.php", @@ -4573,16 +4636,16 @@ }, { "name": "nesbot/carbon", - "version": "3.8.6", + "version": "3.9.1", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd" + "reference": "ced71f79398ece168e24f7f7710462f462310d4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ff2f20cf83bd4d503720632ce8a426dc747bf7fd", - "reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ced71f79398ece168e24f7f7710462f462310d4d", + "reference": "ced71f79398ece168e24f7f7710462f462310d4d", "shasum": "" }, "require": { @@ -4675,7 +4738,7 @@ "type": "tidelift" } ], - "time": "2025-02-20T17:33:38+00:00" + "time": "2025-05-01T19:51:51+00:00" }, { "name": "nette/schema", @@ -4741,16 +4804,16 @@ }, { "name": "nette/utils", - "version": "v4.0.5", + "version": "v4.0.6", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" + "reference": "ce708655043c7050eb050df361c5e313cf708309" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", - "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309", + "reference": "ce708655043c7050eb050df361c5e313cf708309", "shasum": "" }, "require": { @@ -4821,9 +4884,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.5" + "source": "https://github.com/nette/utils/tree/v4.0.6" }, - "time": "2024-08-07T15:39:19+00:00" + "time": "2025-03-30T21:06:30+00:00" }, { "name": "nikic/php-parser", @@ -4885,31 +4948,31 @@ }, { "name": "nunomaduro/termwind", - "version": "v2.3.0", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/nunomaduro/termwind.git", - "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda" + "reference": "dfa08f390e509967a15c22493dc0bac5733d9123" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/52915afe6a1044e8b9cee1bcff836fb63acf9cda", - "reference": "52915afe6a1044e8b9cee1bcff836fb63acf9cda", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/dfa08f390e509967a15c22493dc0bac5733d9123", + "reference": "dfa08f390e509967a15c22493dc0bac5733d9123", "shasum": "" }, "require": { "ext-mbstring": "*", "php": "^8.2", - "symfony/console": "^7.1.8" + "symfony/console": "^7.2.6" }, "require-dev": { - "illuminate/console": "^11.33.2", - "laravel/pint": "^1.18.2", + "illuminate/console": "^11.44.7", + "laravel/pint": "^1.22.0", "mockery/mockery": "^1.6.12", - "pestphp/pest": "^2.36.0", - "phpstan/phpstan": "^1.12.11", - "phpstan/phpstan-strict-rules": "^1.6.1", - "symfony/var-dumper": "^7.1.8", + "pestphp/pest": "^2.36.0 || ^3.8.2", + "phpstan/phpstan": "^1.12.25", + "phpstan/phpstan-strict-rules": "^1.6.2", + "symfony/var-dumper": "^7.2.6", "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", @@ -4952,7 +5015,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.3.0" + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.1" }, "funding": [ { @@ -4968,7 +5031,7 @@ "type": "github" } ], - "time": "2024-11-21T10:39:51+00:00" + "time": "2025-05-08T08:14:37+00:00" }, { "name": "nyholm/psr7", @@ -5258,16 +5321,16 @@ }, { "name": "pbmedia/laravel-ffmpeg", - "version": "8.7.0", + "version": "8.7.1", "source": { "type": "git", "url": "https://github.com/protonemedia/laravel-ffmpeg.git", - "reference": "01249a226bce0172a7e87a43fc5448b975a56282" + "reference": "596804eee95b97bca146653770e7622159976bb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/protonemedia/laravel-ffmpeg/zipball/01249a226bce0172a7e87a43fc5448b975a56282", - "reference": "01249a226bce0172a7e87a43fc5448b975a56282", + "url": "https://api.github.com/repos/protonemedia/laravel-ffmpeg/zipball/596804eee95b97bca146653770e7622159976bb1", + "reference": "596804eee95b97bca146653770e7622159976bb1", "shasum": "" }, "require": { @@ -5277,6 +5340,7 @@ "ramsey/collection": "^2.0" }, "require-dev": { + "laravel/pint": "^1.21", "league/flysystem-memory": "^3.10", "mockery/mockery": "^1.4.4", "nesbot/carbon": "^2.66|^3.0", @@ -5324,7 +5388,7 @@ ], "support": { "issues": "https://github.com/protonemedia/laravel-ffmpeg/issues", - "source": "https://github.com/protonemedia/laravel-ffmpeg/tree/8.7.0" + "source": "https://github.com/protonemedia/laravel-ffmpeg/tree/8.7.1" }, "funding": [ { @@ -5332,20 +5396,20 @@ "type": "github" } ], - "time": "2025-02-16T22:06:08+00:00" + "time": "2025-04-01T21:11:35+00:00" }, { "name": "php-ffmpeg/php-ffmpeg", - "version": "v1.3.1", + "version": "v1.3.2", "source": { "type": "git", "url": "https://github.com/PHP-FFMpeg/PHP-FFMpeg.git", - "reference": "0fbbc4c6a6336155679adc800616001ae3328c7a" + "reference": "8e74bdc07ad200da7a6cfb21ec2652875e4368e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-FFMpeg/PHP-FFMpeg/zipball/0fbbc4c6a6336155679adc800616001ae3328c7a", - "reference": "0fbbc4c6a6336155679adc800616001ae3328c7a", + "url": "https://api.github.com/repos/PHP-FFMpeg/PHP-FFMpeg/zipball/8e74bdc07ad200da7a6cfb21ec2652875e4368e0", + "reference": "8e74bdc07ad200da7a6cfb21ec2652875e4368e0", "shasum": "" }, "require": { @@ -5419,9 +5483,9 @@ ], "support": { "issues": "https://github.com/PHP-FFMpeg/PHP-FFMpeg/issues", - "source": "https://github.com/PHP-FFMpeg/PHP-FFMpeg/tree/v1.3.1" + "source": "https://github.com/PHP-FFMpeg/PHP-FFMpeg/tree/v1.3.2" }, - "time": "2025-01-10T20:23:57+00:00" + "time": "2025-04-01T20:36:46+00:00" }, { "name": "phpoption/phpoption", @@ -5788,16 +5852,16 @@ }, { "name": "predis/predis", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/predis/predis.git", - "reference": "bac46bfdb78cd6e9c7926c697012aae740cb9ec9" + "reference": "f49e13ee3a2a825631562aa0223ac922ec5d058b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/predis/predis/zipball/bac46bfdb78cd6e9c7926c697012aae740cb9ec9", - "reference": "bac46bfdb78cd6e9c7926c697012aae740cb9ec9", + "url": "https://api.github.com/repos/predis/predis/zipball/f49e13ee3a2a825631562aa0223ac922ec5d058b", + "reference": "f49e13ee3a2a825631562aa0223ac922ec5d058b", "shasum": "" }, "require": { @@ -5806,6 +5870,7 @@ "require-dev": { "friendsofphp/php-cs-fixer": "^3.3", "phpstan/phpstan": "^1.9", + "phpunit/phpcov": "^6.0 || ^8.0", "phpunit/phpunit": "^8.0 || ^9.4" }, "suggest": { @@ -5828,7 +5893,7 @@ "role": "Maintainer" } ], - "description": "A flexible and feature-complete Redis client for PHP.", + "description": "A flexible and feature-complete Redis/Valkey client for PHP.", "homepage": "http://github.com/predis/predis", "keywords": [ "nosql", @@ -5837,7 +5902,7 @@ ], "support": { "issues": "https://github.com/predis/predis/issues", - "source": "https://github.com/predis/predis/tree/v2.3.0" + "source": "https://github.com/predis/predis/tree/v2.4.0" }, "funding": [ { @@ -5845,7 +5910,7 @@ "type": "github" } ], - "time": "2024-11-21T20:00:02+00:00" + "time": "2025-04-30T15:16:02+00:00" }, { "name": "psr/cache", @@ -6310,16 +6375,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.7", + "version": "v0.12.8", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "d73fa3c74918ef4522bb8a3bf9cab39161c4b57c" + "reference": "85057ceedee50c49d4f6ecaff73ee96adb3b3625" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/d73fa3c74918ef4522bb8a3bf9cab39161c4b57c", - "reference": "d73fa3c74918ef4522bb8a3bf9cab39161c4b57c", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/85057ceedee50c49d4f6ecaff73ee96adb3b3625", + "reference": "85057ceedee50c49d4f6ecaff73ee96adb3b3625", "shasum": "" }, "require": { @@ -6383,9 +6448,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.7" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.8" }, - "time": "2024-12-10T01:58:33+00:00" + "time": "2025-03-16T03:05:19+00:00" }, { "name": "pusher/pusher-php-server", @@ -6494,16 +6559,16 @@ }, { "name": "ramsey/collection", - "version": "2.1.0", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109" + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109", - "reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", "shasum": "" }, "require": { @@ -6564,9 +6629,9 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.1.0" + "source": "https://github.com/ramsey/collection/tree/2.1.1" }, - "time": "2025-03-02T04:48:29+00:00" + "time": "2025-03-22T05:38:12+00:00" }, { "name": "ramsey/uuid", @@ -6837,16 +6902,16 @@ }, { "name": "spatie/laravel-backup", - "version": "9.2.9", + "version": "9.3.2", "source": { "type": "git", "url": "https://github.com/spatie/laravel-backup.git", - "reference": "997c781a38bc701ab7623954b2e0438680caa0bf" + "reference": "c5ced5777fa1c6e89a11afb6520e37e2b98d9a47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-backup/zipball/997c781a38bc701ab7623954b2e0438680caa0bf", - "reference": "997c781a38bc701ab7623954b2e0438680caa0bf", + "url": "https://api.github.com/repos/spatie/laravel-backup/zipball/c5ced5777fa1c6e89a11afb6520e37e2b98d9a47", + "reference": "c5ced5777fa1c6e89a11afb6520e37e2b98d9a47", "shasum": "" }, "require": { @@ -6859,7 +6924,7 @@ "illuminate/support": "^10.10.0|^11.0|^12.0", "league/flysystem": "^3.0", "php": "^8.2", - "spatie/db-dumper": "^3.7", + "spatie/db-dumper": "^3.8", "spatie/laravel-package-tools": "^1.6.2", "spatie/laravel-signal-aware-command": "^1.2|^2.0", "spatie/temporary-directory": "^2.0", @@ -6921,7 +6986,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-backup/issues", - "source": "https://github.com/spatie/laravel-backup/tree/9.2.9" + "source": "https://github.com/spatie/laravel-backup/tree/9.3.2" }, "funding": [ { @@ -6933,7 +6998,7 @@ "type": "other" } ], - "time": "2025-03-03T12:10:03+00:00" + "time": "2025-04-25T13:42:20+00:00" }, { "name": "spatie/laravel-image-optimizer", @@ -7005,16 +7070,16 @@ }, { "name": "spatie/laravel-package-tools", - "version": "1.19.0", + "version": "1.92.4", "source": { "type": "git", "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa" + "reference": "d20b1969f836d210459b78683d85c9cd5c5f508c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa", - "reference": "1c9c30ac6a6576b8d15c6c37b6cf23d748df2faa", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d20b1969f836d210459b78683d85c9cd5c5f508c", + "reference": "d20b1969f836d210459b78683d85c9cd5c5f508c", "shasum": "" }, "require": { @@ -7025,6 +7090,7 @@ "mockery/mockery": "^1.5", "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0", "pestphp/pest": "^1.23|^2.1|^3.1", + "phpunit/php-code-coverage": "^9.0|^10.0|^11.0", "phpunit/phpunit": "^9.5.24|^10.5|^11.5", "spatie/pest-plugin-test-time": "^1.1|^2.2" }, @@ -7053,7 +7119,7 @@ ], "support": { "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.19.0" + "source": "https://github.com/spatie/laravel-package-tools/tree/1.92.4" }, "funding": [ { @@ -7061,7 +7127,7 @@ "type": "github" } ], - "time": "2025-02-06T14:58:20+00:00" + "time": "2025-04-11T15:27:14+00:00" }, { "name": "spatie/laravel-signal-aware-command", @@ -7266,20 +7332,20 @@ }, { "name": "spomky-labs/pki-framework", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/Spomky-Labs/pki-framework.git", - "reference": "5ac374c3e295c8b917208ff41b4d30f76668478c" + "reference": "5ff1dcc21e961b60149a80e77f744fc047800b31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/5ac374c3e295c8b917208ff41b4d30f76668478c", - "reference": "5ac374c3e295c8b917208ff41b4d30f76668478c", + "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/5ff1dcc21e961b60149a80e77f744fc047800b31", + "reference": "5ff1dcc21e961b60149a80e77f744fc047800b31", "shasum": "" }, "require": { - "brick/math": "^0.10|^0.11|^0.12", + "brick/math": "^0.10|^0.11|^0.12|^0.13", "ext-mbstring": "*", "php": ">=8.1" }, @@ -7294,7 +7360,7 @@ "phpstan/phpstan-deprecation-rules": "^1.0|^2.0", "phpstan/phpstan-phpunit": "^1.1|^2.0", "phpstan/phpstan-strict-rules": "^1.3|^2.0", - "phpunit/phpunit": "^10.1|^11.0", + "phpunit/phpunit": "^10.1|^11.0|^12.0", "rector/rector": "^1.0|^2.0", "roave/security-advisories": "dev-latest", "symfony/string": "^6.4|^7.0", @@ -7359,7 +7425,7 @@ ], "support": { "issues": "https://github.com/Spomky-Labs/pki-framework/issues", - "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.2.2" + "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.2.3" }, "funding": [ { @@ -7371,7 +7437,7 @@ "type": "patreon" } ], - "time": "2025-01-03T09:35:48+00:00" + "time": "2025-04-25T15:57:13+00:00" }, { "name": "stevebauman/purify", @@ -7441,16 +7507,16 @@ }, { "name": "symfony/cache", - "version": "v7.2.4", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "d33cd9e14326e14a4145c21e600602eaf17cc9e7" + "reference": "8b49dde3f5a5e9867595a3a269977f78418d75ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/d33cd9e14326e14a4145c21e600602eaf17cc9e7", - "reference": "d33cd9e14326e14a4145c21e600602eaf17cc9e7", + "url": "https://api.github.com/repos/symfony/cache/zipball/8b49dde3f5a5e9867595a3a269977f78418d75ee", + "reference": "8b49dde3f5a5e9867595a3a269977f78418d75ee", "shasum": "" }, "require": { @@ -7519,7 +7585,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.2.4" + "source": "https://github.com/symfony/cache/tree/v7.2.6" }, "funding": [ { @@ -7535,7 +7601,7 @@ "type": "tidelift" } ], - "time": "2025-02-26T09:57:54+00:00" + "time": "2025-04-08T09:06:23+00:00" }, { "name": "symfony/cache-contracts", @@ -7689,16 +7755,16 @@ }, { "name": "symfony/console", - "version": "v7.2.1", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" + "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", - "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", + "reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", "shasum": "" }, "require": { @@ -7762,7 +7828,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.1" + "source": "https://github.com/symfony/console/tree/v7.2.6" }, "funding": [ { @@ -7778,7 +7844,7 @@ "type": "tidelift" } ], - "time": "2024-12-11T03:49:26+00:00" + "time": "2025-04-07T19:09:28+00:00" }, { "name": "symfony/css-selector", @@ -7914,16 +7980,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.2.4", + "version": "v7.2.5", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "aabf79938aa795350c07ce6464dd1985607d95d5" + "reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/aabf79938aa795350c07ce6464dd1985607d95d5", - "reference": "aabf79938aa795350c07ce6464dd1985607d95d5", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b", + "reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b", "shasum": "" }, "require": { @@ -7969,7 +8035,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.2.4" + "source": "https://github.com/symfony/error-handler/tree/v7.2.5" }, "funding": [ { @@ -7985,7 +8051,7 @@ "type": "tidelift" } ], - "time": "2025-02-02T20:27:07+00:00" + "time": "2025-03-03T07:12:39+00:00" }, { "name": "symfony/event-dispatcher", @@ -8380,16 +8446,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.2.3", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0" + "reference": "6023ec7607254c87c5e69fb3558255aca440d72b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ee1b504b8926198be89d05e5b6fc4c3810c090f0", - "reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6023ec7607254c87c5e69fb3558255aca440d72b", + "reference": "6023ec7607254c87c5e69fb3558255aca440d72b", "shasum": "" }, "require": { @@ -8438,7 +8504,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.2.3" + "source": "https://github.com/symfony/http-foundation/tree/v7.2.6" }, "funding": [ { @@ -8454,20 +8520,20 @@ "type": "tidelift" } ], - "time": "2025-01-17T10:56:55+00:00" + "time": "2025-04-09T08:14:01+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.2.4", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "9f1103734c5789798fefb90e91de4586039003ed" + "reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9f1103734c5789798fefb90e91de4586039003ed", - "reference": "9f1103734c5789798fefb90e91de4586039003ed", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f9dec01e6094a063e738f8945ef69c0cfcf792ec", + "reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec", "shasum": "" }, "require": { @@ -8552,7 +8618,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.2.4" + "source": "https://github.com/symfony/http-kernel/tree/v7.2.6" }, "funding": [ { @@ -8568,20 +8634,20 @@ "type": "tidelift" } ], - "time": "2025-02-26T11:01:22+00:00" + "time": "2025-05-02T09:04:03+00:00" }, { "name": "symfony/mailer", - "version": "v7.2.3", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "f3871b182c44997cf039f3b462af4a48fb85f9d3" + "reference": "998692469d6e698c6eadc7ef37a6530a9eabb356" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/f3871b182c44997cf039f3b462af4a48fb85f9d3", - "reference": "f3871b182c44997cf039f3b462af4a48fb85f9d3", + "url": "https://api.github.com/repos/symfony/mailer/zipball/998692469d6e698c6eadc7ef37a6530a9eabb356", + "reference": "998692469d6e698c6eadc7ef37a6530a9eabb356", "shasum": "" }, "require": { @@ -8632,7 +8698,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.2.3" + "source": "https://github.com/symfony/mailer/tree/v7.2.6" }, "funding": [ { @@ -8648,7 +8714,7 @@ "type": "tidelift" } ], - "time": "2025-01-27T11:08:17+00:00" + "time": "2025-04-04T09:50:51+00:00" }, { "name": "symfony/mailgun-mailer", @@ -8721,16 +8787,16 @@ }, { "name": "symfony/mime", - "version": "v7.2.4", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "87ca22046b78c3feaff04b337f33b38510fd686b" + "reference": "706e65c72d402539a072d0d6ad105fff6c161ef1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/87ca22046b78c3feaff04b337f33b38510fd686b", - "reference": "87ca22046b78c3feaff04b337f33b38510fd686b", + "url": "https://api.github.com/repos/symfony/mime/zipball/706e65c72d402539a072d0d6ad105fff6c161ef1", + "reference": "706e65c72d402539a072d0d6ad105fff6c161ef1", "shasum": "" }, "require": { @@ -8785,7 +8851,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.2.4" + "source": "https://github.com/symfony/mime/tree/v7.2.6" }, "funding": [ { @@ -8801,11 +8867,11 @@ "type": "tidelift" } ], - "time": "2025-02-19T08:51:20+00:00" + "time": "2025-04-27T13:34:41+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -8864,7 +8930,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, "funding": [ { @@ -8884,7 +8950,7 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", @@ -8942,7 +9008,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" }, "funding": [ { @@ -8962,16 +9028,16 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", - "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", "shasum": "" }, "require": { @@ -9025,7 +9091,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" }, "funding": [ { @@ -9041,11 +9107,11 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-09-10T14:38:51+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -9106,7 +9172,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" }, "funding": [ { @@ -9126,19 +9192,20 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { @@ -9186,7 +9253,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, "funding": [ { @@ -9202,20 +9269,20 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { @@ -9266,7 +9333,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" }, "funding": [ { @@ -9282,11 +9349,11 @@ "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", @@ -9342,7 +9409,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.32.0" }, "funding": [ { @@ -9362,7 +9429,7 @@ }, { "name": "symfony/polyfill-uuid", - "version": "v1.31.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-uuid.git", @@ -9421,7 +9488,7 @@ "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.32.0" }, "funding": [ { @@ -9441,16 +9508,16 @@ }, { "name": "symfony/process", - "version": "v7.2.4", + "version": "v7.2.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf" + "reference": "87b7c93e57df9d8e39a093d32587702380ff045d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", - "reference": "d8f411ff3c7ddc4ae9166fb388d1190a2df5b5cf", + "url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d", + "reference": "87b7c93e57df9d8e39a093d32587702380ff045d", "shasum": "" }, "require": { @@ -9482,7 +9549,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.2.4" + "source": "https://github.com/symfony/process/tree/v7.2.5" }, "funding": [ { @@ -9498,7 +9565,7 @@ "type": "tidelift" } ], - "time": "2025-02-05T08:33:46+00:00" + "time": "2025-03-13T12:21:46+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -9749,16 +9816,16 @@ }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", + "reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", "shasum": "" }, "require": { @@ -9816,7 +9883,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v7.2.6" }, "funding": [ { @@ -9832,20 +9899,20 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2025-04-20T20:18:16+00:00" }, { "name": "symfony/translation", - "version": "v7.2.4", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "283856e6981286cc0d800b53bd5703e8e363f05a" + "reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/283856e6981286cc0d800b53bd5703e8e363f05a", - "reference": "283856e6981286cc0d800b53bd5703e8e363f05a", + "url": "https://api.github.com/repos/symfony/translation/zipball/e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6", + "reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6", "shasum": "" }, "require": { @@ -9911,7 +9978,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.2.4" + "source": "https://github.com/symfony/translation/tree/v7.2.6" }, "funding": [ { @@ -9927,7 +9994,7 @@ "type": "tidelift" } ], - "time": "2025-02-13T10:27:23+00:00" + "time": "2025-04-07T19:09:28+00:00" }, { "name": "symfony/translation-contracts", @@ -10083,16 +10150,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.2.3", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "82b478c69745d8878eb60f9a049a4d584996f73a" + "reference": "9c46038cd4ed68952166cf7001b54eb539184ccb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/82b478c69745d8878eb60f9a049a4d584996f73a", - "reference": "82b478c69745d8878eb60f9a049a4d584996f73a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9c46038cd4ed68952166cf7001b54eb539184ccb", + "reference": "9c46038cd4ed68952166cf7001b54eb539184ccb", "shasum": "" }, "require": { @@ -10146,7 +10213,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.2.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.6" }, "funding": [ { @@ -10162,20 +10229,20 @@ "type": "tidelift" } ], - "time": "2025-01-17T11:39:41+00:00" + "time": "2025-04-09T08:14:01+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.2.4", + "version": "v7.2.6", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "4ede73aa7a73d81506002d2caadbbdad1ef5b69a" + "reference": "422b8de94c738830a1e071f59ad14d67417d7007" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/4ede73aa7a73d81506002d2caadbbdad1ef5b69a", - "reference": "4ede73aa7a73d81506002d2caadbbdad1ef5b69a", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/422b8de94c738830a1e071f59ad14d67417d7007", + "reference": "422b8de94c738830a1e071f59ad14d67417d7007", "shasum": "" }, "require": { @@ -10222,7 +10289,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.2.4" + "source": "https://github.com/symfony/var-exporter/tree/v7.2.6" }, "funding": [ { @@ -10238,7 +10305,7 @@ "type": "tidelift" } ], - "time": "2025-02-13T10:27:23+00:00" + "time": "2025-05-02T08:36:00+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -10297,16 +10364,16 @@ }, { "name": "vlucas/phpdotenv", - "version": "v5.6.1", + "version": "v5.6.2", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2" + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2", - "reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af", "shasum": "" }, "require": { @@ -10365,7 +10432,7 @@ ], "support": { "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1" + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2" }, "funding": [ { @@ -10377,7 +10444,7 @@ "type": "tidelift" } ], - "time": "2024-07-20T21:52:34+00:00" + "time": "2025-04-30T23:37:27+00:00" }, { "name": "voku/portable-ascii", @@ -10455,16 +10522,16 @@ }, { "name": "web-token/jwt-library", - "version": "3.4.7", + "version": "3.4.8", "source": { "type": "git", "url": "https://github.com/web-token/jwt-library.git", - "reference": "1a25c8ced3e2b3c31d32dcfad215cbd8cb812f28" + "reference": "92445671cc788fa5f639898a67c06f9fd0bf491f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/web-token/jwt-library/zipball/1a25c8ced3e2b3c31d32dcfad215cbd8cb812f28", - "reference": "1a25c8ced3e2b3c31d32dcfad215cbd8cb812f28", + "url": "https://api.github.com/repos/web-token/jwt-library/zipball/92445671cc788fa5f639898a67c06f9fd0bf491f", + "reference": "92445671cc788fa5f639898a67c06f9fd0bf491f", "shasum": "" }, "require": { @@ -10474,7 +10541,7 @@ "paragonie/constant_time_encoding": "^2.6|^3.0", "paragonie/sodium_compat": "^1.20|^2.0", "php": ">=8.1", - "psr/cache": "^3.0", + "psr/cache": "^2.0|^3.0", "psr/clock": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", @@ -10537,7 +10604,7 @@ ], "support": { "issues": "https://github.com/web-token/jwt-library/issues", - "source": "https://github.com/web-token/jwt-library/tree/3.4.7" + "source": "https://github.com/web-token/jwt-library/tree/3.4.8" }, "funding": [ { @@ -10549,7 +10616,7 @@ "type": "patreon" } ], - "time": "2024-07-02T16:35:11+00:00" + "time": "2025-05-07T09:11:18+00:00" }, { "name": "webmozart/assert", @@ -10676,16 +10743,16 @@ }, { "name": "filp/whoops", - "version": "2.17.0", + "version": "2.18.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "075bc0c26631110584175de6523ab3f1652eb28e" + "reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/075bc0c26631110584175de6523ab3f1652eb28e", - "reference": "075bc0c26631110584175de6523ab3f1652eb28e", + "url": "https://api.github.com/repos/filp/whoops/zipball/a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", + "reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", "shasum": "" }, "require": { @@ -10735,7 +10802,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.17.0" + "source": "https://github.com/filp/whoops/tree/2.18.0" }, "funding": [ { @@ -10743,24 +10810,24 @@ "type": "github" } ], - "time": "2025-01-25T12:00:00+00:00" + "time": "2025-03-15T12:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", - "version": "v2.0.1", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", "shasum": "" }, "require": { - "php": "^5.3|^7.0|^8.0" + "php": "^7.4|^8.0" }, "replace": { "cordoval/hamcrest-php": "*", @@ -10768,8 +10835,8 @@ "kodova/hamcrest-php": "*" }, "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" }, "type": "library", "extra": { @@ -10792,22 +10859,22 @@ ], "support": { "issues": "https://github.com/hamcrest/hamcrest-php/issues", - "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" }, - "time": "2020-07-09T08:09:16+00:00" + "time": "2025-04-30T06:54:44+00:00" }, { "name": "laravel/pint", - "version": "v1.21.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86" + "reference": "941d1927c5ca420c22710e98420287169c7bcaf7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/c44bffbb2334e90fba560933c45948fa4a3f3e86", - "reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86", + "url": "https://api.github.com/repos/laravel/pint/zipball/941d1927c5ca420c22710e98420287169c7bcaf7", + "reference": "941d1927c5ca420c22710e98420287169c7bcaf7", "shasum": "" }, "require": { @@ -10818,12 +10885,12 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.70.2", - "illuminate/view": "^11.44.1", - "larastan/larastan": "^3.1.0", + "friendsofphp/php-cs-fixer": "^3.75.0", + "illuminate/view": "^11.44.7", + "larastan/larastan": "^3.4.0", "laravel-zero/framework": "^11.36.1", "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^2.3", + "nunomaduro/termwind": "^2.3.1", "pestphp/pest": "^2.36.0" }, "bin": [ @@ -10860,20 +10927,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2025-03-11T03:22:21+00:00" + "time": "2025-05-08T08:38:12+00:00" }, { "name": "laravel/telescope", - "version": "v5.5.0", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/laravel/telescope.git", - "reference": "2594b20b946155ba767002d8af971e33e1095637" + "reference": "440908cb856cfbef9323244f7978ad4bf8cd2daa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/telescope/zipball/2594b20b946155ba767002d8af971e33e1095637", - "reference": "2594b20b946155ba767002d8af971e33e1095637", + "url": "https://api.github.com/repos/laravel/telescope/zipball/440908cb856cfbef9323244f7978ad4bf8cd2daa", + "reference": "440908cb856cfbef9323244f7978ad4bf8cd2daa", "shasum": "" }, "require": { @@ -10927,9 +10994,9 @@ ], "support": { "issues": "https://github.com/laravel/telescope/issues", - "source": "https://github.com/laravel/telescope/tree/v5.5.0" + "source": "https://github.com/laravel/telescope/tree/v5.7.0" }, - "time": "2025-02-11T15:01:27+00:00" + "time": "2025-03-27T17:25:52+00:00" }, { "name": "mockery/mockery", @@ -11016,16 +11083,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414" + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", "shasum": "" }, "require": { @@ -11064,7 +11131,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" }, "funding": [ { @@ -11072,42 +11139,43 @@ "type": "tidelift" } ], - "time": "2025-02-12T12:17:51+00:00" + "time": "2025-04-29T12:36:36+00:00" }, { "name": "nunomaduro/collision", - "version": "v8.6.1", + "version": "v8.8.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "86f003c132143d5a2ab214e19933946409e0cae7" + "reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/86f003c132143d5a2ab214e19933946409e0cae7", - "reference": "86f003c132143d5a2ab214e19933946409e0cae7", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/4cf9f3b47afff38b139fb79ce54fc71799022ce8", + "reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8", "shasum": "" }, "require": { - "filp/whoops": "^2.16.0", + "filp/whoops": "^2.18.0", "nunomaduro/termwind": "^2.3.0", "php": "^8.2.0", - "symfony/console": "^7.2.1" + "symfony/console": "^7.2.5" }, "conflict": { - "laravel/framework": "<11.39.1 || >=13.0.0", - "phpunit/phpunit": "<11.5.3 || >=12.0.0" + "laravel/framework": "<11.44.2 || >=13.0.0", + "phpunit/phpunit": "<11.5.15 || >=13.0.0" }, "require-dev": { - "larastan/larastan": "^2.9.12", - "laravel/framework": "^11.39.1", - "laravel/pint": "^1.20.0", - "laravel/sail": "^1.40.0", - "laravel/sanctum": "^4.0.7", - "laravel/tinker": "^2.10.0", - "orchestra/testbench-core": "^9.9.2", - "pestphp/pest": "^3.7.3", - "sebastian/environment": "^6.1.0 || ^7.2.0" + "brianium/paratest": "^7.8.3", + "larastan/larastan": "^3.2", + "laravel/framework": "^11.44.2 || ^12.6", + "laravel/pint": "^1.21.2", + "laravel/sail": "^1.41.0", + "laravel/sanctum": "^4.0.8", + "laravel/tinker": "^2.10.1", + "orchestra/testbench-core": "^9.12.0 || ^10.1", + "pestphp/pest": "^3.8.0", + "sebastian/environment": "^7.2.0 || ^8.0" }, "type": "library", "extra": { @@ -11170,7 +11238,7 @@ "type": "patreon" } ], - "time": "2025-01-23T13:41:43+00:00" + "time": "2025-04-03T14:33:09+00:00" }, { "name": "phar-io/manifest", @@ -11615,16 +11683,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.5.12", + "version": "11.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d42785840519401ed2113292263795eb4c0f95da" + "reference": "e6bdea63ecb7a8287d2cdab25bdde3126e0cfe6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d42785840519401ed2113292263795eb4c0f95da", - "reference": "d42785840519401ed2113292263795eb4c0f95da", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6bdea63ecb7a8287d2cdab25bdde3126e0cfe6f", + "reference": "e6bdea63ecb7a8287d2cdab25bdde3126e0cfe6f", "shasum": "" }, "require": { @@ -11634,7 +11702,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.0", + "myclabs/deep-copy": "^1.13.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", @@ -11644,14 +11712,14 @@ "phpunit/php-text-template": "^4.0.1", "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.2", + "sebastian/code-unit": "^3.0.3", "sebastian/comparator": "^6.3.1", "sebastian/diff": "^6.0.2", "sebastian/environment": "^7.2.0", "sebastian/exporter": "^6.3.0", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", - "sebastian/type": "^5.1.0", + "sebastian/type": "^5.1.2", "sebastian/version": "^5.0.2", "staabm/side-effects-detector": "^1.0.5" }, @@ -11696,7 +11764,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.12" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.20" }, "funding": [ { @@ -11707,12 +11775,20 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2025-03-07T07:31:03+00:00" + "time": "2025-05-11T06:39:52+00:00" }, { "name": "sebastian/cli-parser", @@ -11773,16 +11849,16 @@ }, { "name": "sebastian/code-unit", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", - "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", "shasum": "" }, "require": { @@ -11818,7 +11894,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" }, "funding": [ { @@ -11826,7 +11902,7 @@ "type": "github" } ], - "time": "2024-12-12T09:59:06+00:00" + "time": "2025-03-19T07:56:08+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -12531,16 +12607,16 @@ }, { "name": "sebastian/type", - "version": "5.1.0", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", - "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", "shasum": "" }, "require": { @@ -12576,7 +12652,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" + "source": "https://github.com/sebastianbergmann/type/tree/5.1.2" }, "funding": [ { @@ -12584,7 +12660,7 @@ "type": "github" } ], - "time": "2024-09-17T13:12:04+00:00" + "time": "2025-03-18T13:35:50+00:00" }, { "name": "sebastian/version", @@ -12745,7 +12821,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { @@ -12758,6 +12834,6 @@ "ext-mbstring": "*", "ext-openssl": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/config/image.php b/config/image.php index eb77c9089..dd6df3137 100644 --- a/config/image.php +++ b/config/image.php @@ -7,14 +7,12 @@ return [ | Image Driver |-------------------------------------------------------------------------- | - | Intervention Image supports "GD Library" and "Imagick" to process images - | internally. You may choose one of them according to your PHP + | Intervention Image supports "GD Library", "Imagick" and "libvips" to process + | images internally. You may choose one of them according to your PHP | configuration. By default PHP's "GD Library" implementation is used. | - | Supported: "gd", "imagick" + | Supported: "gd", "imagick", "libvips" | */ - 'driver' => env('IMAGE_DRIVER', 'gd'), - ];