Faza 7: White-label per tenant — logo + theme color dinamic
- spatie/laravel-medialibrary instalat (migration media table)
- filament/spatie-laravel-media-library-plugin
- Company implements HasMedia + InteractsWithMedia
- collections: 'logo' + 'favicon' (singleFile)
- getLogoUrl() / getFaviconUrl() helpers
- Settings page extins: secțiune Logo & favicon cu FileUpload
- On save: clear collection + addMedia from temp upload + cleanup tmp file
- TenantPanelProvider render hooks:
- HEAD_END: theme-color meta + favicon + CSS vars override
(--primary-50 → --primary-950 generate din hex theme_color)
- SIDEBAR_LOGO_BEFORE: afișare logo upload-uit, max-height 56px
Cum funcționează:
- Tenant uploadează logo în Settings
- La fiecare request, render hook injectează <style> cu CSS vars custom
- Filament respectă --primary-* → toate butoanele/badge-urile primesc culoarea brand
- Logo apare deasupra meniului (sidebar)
This commit is contained in:
@@ -85,6 +85,27 @@ class Settings extends Page
|
|||||||
->label('Mărci auto suportate (separate prin virgulă)')
|
->label('Mărci auto suportate (separate prin virgulă)')
|
||||||
->rows(2),
|
->rows(2),
|
||||||
]),
|
]),
|
||||||
|
Schemas\Components\Section::make('Logo & favicon')
|
||||||
|
->columns(2)
|
||||||
|
->schema([
|
||||||
|
Forms\Components\FileUpload::make('logo')
|
||||||
|
->label('Logo')
|
||||||
|
->image()
|
||||||
|
->imageEditor()
|
||||||
|
->disk('public')
|
||||||
|
->directory('tmp-uploads')
|
||||||
|
->visibility('public')
|
||||||
|
->maxSize(2048)
|
||||||
|
->helperText('PNG/SVG, max 2 MB. Apare în sidebar.'),
|
||||||
|
Forms\Components\FileUpload::make('favicon')
|
||||||
|
->label('Favicon')
|
||||||
|
->image()
|
||||||
|
->disk('public')
|
||||||
|
->directory('tmp-uploads')
|
||||||
|
->visibility('public')
|
||||||
|
->maxSize(512)
|
||||||
|
->helperText('PNG/ICO, max 512 KB.'),
|
||||||
|
]),
|
||||||
])
|
])
|
||||||
->statePath('data');
|
->statePath('data');
|
||||||
}
|
}
|
||||||
@@ -113,6 +134,18 @@ class Settings extends Page
|
|||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Logo + favicon → Spatie Media Library
|
||||||
|
foreach (['logo', 'favicon'] as $col) {
|
||||||
|
$path = $data[$col] ?? null;
|
||||||
|
if (! $path) continue;
|
||||||
|
$abs = \Illuminate\Support\Facades\Storage::disk('public')->path($path);
|
||||||
|
if (file_exists($abs)) {
|
||||||
|
$company->clearMediaCollection($col);
|
||||||
|
$company->addMedia($abs)->preservingOriginal()->toMediaCollection($col);
|
||||||
|
@unlink($abs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Notification::make()->title('Setări salvate')->success()->send();
|
Notification::make()->title('Setări salvate')->success()->send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ namespace App\Models\Central;
|
|||||||
|
|
||||||
use App\Models\Tenant\User;
|
use App\Models\Tenant\User;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
|
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||||
|
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||||
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
|
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
|
||||||
use Stancl\Tenancy\Contracts\TenantWithDatabase;
|
|
||||||
use Stancl\Tenancy\Database\Concerns\HasDatabase;
|
|
||||||
use Stancl\Tenancy\Database\Concerns\HasDomains;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tenant model — extends Stancl Tenant for compatibility with the package
|
* Tenant model — extends Stancl Tenant for compatibility with the package
|
||||||
@@ -16,9 +16,9 @@ use Stancl\Tenancy\Database\Concerns\HasDomains;
|
|||||||
* In single-DB mode we don't use HasDatabase. Domain identification is
|
* In single-DB mode we don't use HasDatabase. Domain identification is
|
||||||
* handled by our own ResolveTenant middleware (slug-based, not DNS records).
|
* handled by our own ResolveTenant middleware (slug-based, not DNS records).
|
||||||
*/
|
*/
|
||||||
class Company extends BaseTenant
|
class Company extends BaseTenant implements HasMedia
|
||||||
{
|
{
|
||||||
use SoftDeletes;
|
use InteractsWithMedia, SoftDeletes;
|
||||||
|
|
||||||
protected $table = 'companies';
|
protected $table = 'companies';
|
||||||
|
|
||||||
@@ -78,4 +78,22 @@ class Company extends BaseTenant
|
|||||||
$central = config('app.central_domain') ?: 'service.mir.md';
|
$central = config('app.central_domain') ?: 'service.mir.md';
|
||||||
return "https://{$this->slug}.{$central}{$path}";
|
return "https://{$this->slug}.{$central}{$path}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function registerMediaCollections(): void
|
||||||
|
{
|
||||||
|
$this->addMediaCollection('logo')->singleFile();
|
||||||
|
$this->addMediaCollection('favicon')->singleFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogoUrl(): ?string
|
||||||
|
{
|
||||||
|
$m = $this->getFirstMedia('logo');
|
||||||
|
return $m ? $m->getUrl() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFaviconUrl(): ?string
|
||||||
|
{
|
||||||
|
$m = $this->getFirstMedia('favicon');
|
||||||
|
return $m ? $m->getUrl() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,12 +79,53 @@ class TenantPanelProvider extends PanelProvider
|
|||||||
$t = app(\App\Tenancy\TenantManager::class)->current();
|
$t = app(\App\Tenancy\TenantManager::class)->current();
|
||||||
$themeColor = $t?->settings['theme_color'] ?? '#3B82F6';
|
$themeColor = $t?->settings['theme_color'] ?? '#3B82F6';
|
||||||
$name = $t?->display_name ?? $t?->name ?? 'AutoCRM';
|
$name = $t?->display_name ?? $t?->name ?? 'AutoCRM';
|
||||||
|
$favicon = $t?->getFaviconUrl();
|
||||||
|
// Generate primary color shades from theme_color hex.
|
||||||
|
$hex = ltrim($themeColor, '#');
|
||||||
|
if (strlen($hex) === 6) {
|
||||||
|
$r = hexdec(substr($hex, 0, 2));
|
||||||
|
$g = hexdec(substr($hex, 2, 2));
|
||||||
|
$b = hexdec(substr($hex, 4, 2));
|
||||||
|
} else { $r = 59; $g = 130; $b = 246; }
|
||||||
@endphp
|
@endphp
|
||||||
<link rel="manifest" href="/manifest.json">
|
<link rel="manifest" href="/manifest.json">
|
||||||
<meta name="theme-color" content="{{ $themeColor }}">
|
<meta name="theme-color" content="{{ $themeColor }}">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
||||||
<meta name="apple-mobile-web-app-title" content="{{ $name }}">
|
<meta name="apple-mobile-web-app-title" content="{{ $name }}">
|
||||||
|
@if ($favicon)
|
||||||
|
<link rel="icon" type="image/png" href="{{ $favicon }}">
|
||||||
|
<link rel="apple-touch-icon" href="{{ $favicon }}">
|
||||||
|
@endif
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
--primary-50: {{ "rgb({$r} {$g} {$b} / 0.05)" }};
|
||||||
|
--primary-100: {{ "rgb({$r} {$g} {$b} / 0.10)" }};
|
||||||
|
--primary-200: {{ "rgb({$r} {$g} {$b} / 0.20)" }};
|
||||||
|
--primary-300: {{ "rgb({$r} {$g} {$b} / 0.35)" }};
|
||||||
|
--primary-400: {{ "rgb({$r} {$g} {$b} / 0.55)" }};
|
||||||
|
--primary-500: {{ "rgb({$r} {$g} {$b})" }};
|
||||||
|
--primary-600: {{ "rgb({$r} {$g} {$b})" }};
|
||||||
|
--primary-700: {{ "rgb(" . max(0,$r-20) . " " . max(0,$g-20) . " " . max(0,$b-20) . ")" }};
|
||||||
|
--primary-800: {{ "rgb(" . max(0,$r-40) . " " . max(0,$g-40) . " " . max(0,$b-40) . ")" }};
|
||||||
|
--primary-900: {{ "rgb(" . max(0,$r-60) . " " . max(0,$g-60) . " " . max(0,$b-60) . ")" }};
|
||||||
|
--primary-950: {{ "rgb(" . max(0,$r-80) . " " . max(0,$g-80) . " " . max(0,$b-80) . ")" }};
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
BLADE)
|
||||||
|
)
|
||||||
|
->renderHook(
|
||||||
|
PanelsRenderHook::SIDEBAR_LOGO_BEFORE,
|
||||||
|
fn (): string => Blade::render(<<<'BLADE'
|
||||||
|
@php
|
||||||
|
$t = app(\App\Tenancy\TenantManager::class)->current();
|
||||||
|
$logo = $t?->getLogoUrl();
|
||||||
|
@endphp
|
||||||
|
@if ($logo)
|
||||||
|
<div style="padding: 12px 16px; display: flex; justify-content: center; border-bottom: 1px solid rgba(0,0,0,.06);">
|
||||||
|
<img src="{{ $logo }}" alt="logo" style="max-height: 56px; max-width: 100%;">
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
BLADE)
|
BLADE)
|
||||||
)
|
)
|
||||||
->renderHook(
|
->renderHook(
|
||||||
|
|||||||
@@ -8,11 +8,13 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"php": "^8.2",
|
"php": "^8.2",
|
||||||
"filament/filament": "^5.6",
|
"filament/filament": "^5.6",
|
||||||
|
"filament/spatie-laravel-media-library-plugin": "^5.6",
|
||||||
"laravel/framework": "^12.0",
|
"laravel/framework": "^12.0",
|
||||||
"laravel/octane": "^2.17",
|
"laravel/octane": "^2.17",
|
||||||
"laravel/sanctum": "^4.3",
|
"laravel/sanctum": "^4.3",
|
||||||
"laravel/tinker": "^2.10.1",
|
"laravel/tinker": "^2.10.1",
|
||||||
"spatie/laravel-activitylog": "^5.0",
|
"spatie/laravel-activitylog": "^5.0",
|
||||||
|
"spatie/laravel-medialibrary": "^11.22",
|
||||||
"spatie/laravel-permission": "^7.4",
|
"spatie/laravel-permission": "^7.4",
|
||||||
"stancl/tenancy": "^3.10"
|
"stancl/tenancy": "^3.10"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+492
-1
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "713924b790dbcc09ec033ae5ac62cd50",
|
"content-hash": "5125ba119dd13de03ede18bda2cbaae5",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "blade-ui-kit/blade-heroicons",
|
"name": "blade-ui-kit/blade-heroicons",
|
||||||
@@ -447,6 +447,83 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-03-20T21:10:52+00:00"
|
"time": "2026-03-20T21:10:52+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "composer/semver",
|
||||||
|
"version": "3.4.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/composer/semver.git",
|
||||||
|
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||||
|
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^1.11",
|
||||||
|
"symfony/phpunit-bridge": "^3 || ^7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Composer\\Semver\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nils Adermann",
|
||||||
|
"email": "naderman@naderman.de",
|
||||||
|
"homepage": "http://www.naderman.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Rob Bast",
|
||||||
|
"email": "rob.bast@gmail.com",
|
||||||
|
"homepage": "http://robbast.nl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Semver library that offers utilities, version constraint parsing and validation.",
|
||||||
|
"keywords": [
|
||||||
|
"semantic",
|
||||||
|
"semver",
|
||||||
|
"validation",
|
||||||
|
"versioning"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||||
|
"issues": "https://github.com/composer/semver/issues",
|
||||||
|
"source": "https://github.com/composer/semver/tree/3.4.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://packagist.com",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/composer",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-08-20T19:15:30+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "danharrin/date-format-converter",
|
"name": "danharrin/date-format-converter",
|
||||||
"version": "v0.3.1",
|
"version": "v0.3.1",
|
||||||
@@ -1316,6 +1393,43 @@
|
|||||||
},
|
},
|
||||||
"time": "2026-05-02T08:33:42+00:00"
|
"time": "2026-05-02T08:33:42+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "filament/spatie-laravel-media-library-plugin",
|
||||||
|
"version": "v5.6.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/filamentphp/spatie-laravel-media-library-plugin.git",
|
||||||
|
"reference": "19509b0d4a96dafd515f99682645f4123a4b9847"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/filamentphp/spatie-laravel-media-library-plugin/zipball/19509b0d4a96dafd515f99682645f4123a4b9847",
|
||||||
|
"reference": "19509b0d4a96dafd515f99682645f4123a4b9847",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"filament/support": "self.version",
|
||||||
|
"php": "^8.2",
|
||||||
|
"spatie/laravel-medialibrary": "^11.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Filament\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "Filament support for `spatie/laravel-medialibrary`.",
|
||||||
|
"homepage": "https://github.com/filamentphp/filament",
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/filamentphp/filament/issues",
|
||||||
|
"source": "https://github.com/filamentphp/filament"
|
||||||
|
},
|
||||||
|
"time": "2026-04-21T15:36:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "filament/support",
|
"name": "filament/support",
|
||||||
"version": "v5.6.2",
|
"version": "v5.6.2",
|
||||||
@@ -3530,6 +3644,84 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-05-01T00:46:07+00:00"
|
"time": "2026-05-01T00:46:07+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "maennchen/zipstream-php",
|
||||||
|
"version": "3.2.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/maennchen/ZipStream-PHP.git",
|
||||||
|
"reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
|
||||||
|
"reference": "77bebeb4c6c340bb3c11c843b2cffd8bbfde4d5e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"ext-zlib": "*",
|
||||||
|
"php-64bit": "^8.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"brianium/paratest": "^7.7",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.86",
|
||||||
|
"guzzlehttp/guzzle": "^7.5",
|
||||||
|
"mikey179/vfsstream": "^1.6",
|
||||||
|
"php-coveralls/php-coveralls": "^2.5",
|
||||||
|
"phpunit/phpunit": "^12.0",
|
||||||
|
"vimeo/psalm": "^6.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"guzzlehttp/psr7": "^2.4",
|
||||||
|
"psr/http-message": "^2.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"ZipStream\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Paul Duncan",
|
||||||
|
"email": "pabs@pablotron.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jonatan Männchen",
|
||||||
|
"email": "jonatan@maennchen.ch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Jesse Donat",
|
||||||
|
"email": "donatj@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "András Kolesár",
|
||||||
|
"email": "kolesar@kolesar.hu"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||||
|
"keywords": [
|
||||||
|
"stream",
|
||||||
|
"zip"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
|
||||||
|
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.2.2"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/maennchen",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-04-11T18:38:28+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "monolog/monolog",
|
"name": "monolog/monolog",
|
||||||
"version": "3.10.0",
|
"version": "3.10.0",
|
||||||
@@ -5316,6 +5508,134 @@
|
|||||||
],
|
],
|
||||||
"time": "2022-12-17T21:53:22+00:00"
|
"time": "2022-12-17T21:53:22+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spatie/image",
|
||||||
|
"version": "3.9.4",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/spatie/image.git",
|
||||||
|
"reference": "6a322b5e9268e3903d4fb6e1ff08b7dcc3aa9429"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/spatie/image/zipball/6a322b5e9268e3903d4fb6e1ff08b7dcc3aa9429",
|
||||||
|
"reference": "6a322b5e9268e3903d4fb6e1ff08b7dcc3aa9429",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-exif": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"ext-mbstring": "*",
|
||||||
|
"php": "^8.2",
|
||||||
|
"spatie/image-optimizer": "^1.7.5",
|
||||||
|
"spatie/temporary-directory": "^2.2",
|
||||||
|
"symfony/process": "^6.4|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-gd": "*",
|
||||||
|
"ext-imagick": "*",
|
||||||
|
"laravel/sail": "^1.34",
|
||||||
|
"pestphp/pest": "^3.0|^4.0",
|
||||||
|
"phpstan/phpstan": "^1.10.50",
|
||||||
|
"spatie/pest-plugin-snapshots": "^2.1",
|
||||||
|
"spatie/pixelmatch-php": "^1.0",
|
||||||
|
"spatie/ray": "^1.40.1",
|
||||||
|
"symfony/var-dumper": "^6.4|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Spatie\\Image\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Freek Van der Herten",
|
||||||
|
"email": "freek@spatie.be",
|
||||||
|
"homepage": "https://spatie.be",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Manipulate images with an expressive API",
|
||||||
|
"homepage": "https://github.com/spatie/image",
|
||||||
|
"keywords": [
|
||||||
|
"image",
|
||||||
|
"spatie"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/spatie/image/tree/3.9.4"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://spatie.be/open-source/support-us",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/spatie",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-03-13T14:23:45+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "spatie/image-optimizer",
|
||||||
|
"version": "1.8.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/spatie/image-optimizer.git",
|
||||||
|
"reference": "2ad9ac7c19501739183359ae64ea6c15869c23d9"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/spatie/image-optimizer/zipball/2ad9ac7c19501739183359ae64ea6c15869c23d9",
|
||||||
|
"reference": "2ad9ac7c19501739183359ae64ea6c15869c23d9",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-fileinfo": "*",
|
||||||
|
"php": "^7.3|^8.0",
|
||||||
|
"psr/log": "^1.0 | ^2.0 | ^3.0",
|
||||||
|
"symfony/process": "^4.2|^5.0|^6.0|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"pestphp/pest": "^1.21|^2.0|^3.0|^4.0",
|
||||||
|
"phpunit/phpunit": "^8.5.21|^9.4.4|^10.0|^11.0|^12.0",
|
||||||
|
"symfony/var-dumper": "^4.2|^5.0|^6.0|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Spatie\\ImageOptimizer\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Freek Van der Herten",
|
||||||
|
"email": "freek@spatie.be",
|
||||||
|
"homepage": "https://spatie.be",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Easily optimize images using PHP",
|
||||||
|
"homepage": "https://github.com/spatie/image-optimizer",
|
||||||
|
"keywords": [
|
||||||
|
"image-optimizer",
|
||||||
|
"spatie"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/spatie/image-optimizer/issues",
|
||||||
|
"source": "https://github.com/spatie/image-optimizer/tree/1.8.1"
|
||||||
|
},
|
||||||
|
"time": "2025-11-26T10:57:19+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/invade",
|
"name": "spatie/invade",
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@@ -5468,6 +5788,116 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-03-25T10:04:54+00:00"
|
"time": "2026-03-25T10:04:54+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spatie/laravel-medialibrary",
|
||||||
|
"version": "11.22.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/spatie/laravel-medialibrary.git",
|
||||||
|
"reference": "808424a4b7dc9811b5633c28a97c530919aea7b8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/spatie/laravel-medialibrary/zipball/808424a4b7dc9811b5633c28a97c530919aea7b8",
|
||||||
|
"reference": "808424a4b7dc9811b5633c28a97c530919aea7b8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"composer/semver": "^3.4",
|
||||||
|
"ext-exif": "*",
|
||||||
|
"ext-fileinfo": "*",
|
||||||
|
"ext-json": "*",
|
||||||
|
"illuminate/bus": "^10.2|^11.0|^12.0|^13.0",
|
||||||
|
"illuminate/conditionable": "^10.2|^11.0|^12.0|^13.0",
|
||||||
|
"illuminate/console": "^10.2|^11.0|^12.0|^13.0",
|
||||||
|
"illuminate/database": "^10.2|^11.0|^12.0|^13.0",
|
||||||
|
"illuminate/pipeline": "^10.2|^11.0|^12.0|^13.0",
|
||||||
|
"illuminate/support": "^10.2|^11.0|^12.0|^13.0",
|
||||||
|
"maennchen/zipstream-php": "^3.1",
|
||||||
|
"php": "^8.2",
|
||||||
|
"spatie/image": "^3.3.2",
|
||||||
|
"spatie/laravel-package-tools": "^1.16.1",
|
||||||
|
"spatie/temporary-directory": "^2.2",
|
||||||
|
"symfony/console": "^6.4.1|^7.0|^8.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"php-ffmpeg/php-ffmpeg": "<0.6.1"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"aws/aws-sdk-php": "^3.293.10",
|
||||||
|
"ext-imagick": "*",
|
||||||
|
"ext-pdo_sqlite": "*",
|
||||||
|
"ext-zip": "*",
|
||||||
|
"guzzlehttp/guzzle": "^7.8.1",
|
||||||
|
"larastan/larastan": "^2.7|^3.0",
|
||||||
|
"league/flysystem-aws-s3-v3": "^3.22",
|
||||||
|
"mockery/mockery": "^1.6.7",
|
||||||
|
"orchestra/testbench": "^8.36|^9.15|^10.8|^11.0",
|
||||||
|
"pestphp/pest": "^2.36|^3.0|^4.0",
|
||||||
|
"phpstan/extension-installer": "^1.3.1",
|
||||||
|
"spatie/laravel-ray": "^1.33",
|
||||||
|
"spatie/pdf-to-image": "^2.2|^3.0",
|
||||||
|
"spatie/pest-expectations": "^1.13",
|
||||||
|
"spatie/pest-plugin-snapshots": "^2.1"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"league/flysystem-aws-s3-v3": "Required to use AWS S3 file storage",
|
||||||
|
"php-ffmpeg/php-ffmpeg": "Required for generating video thumbnails",
|
||||||
|
"spatie/pdf-to-image": "Required for generating thumbnails of PDFs and SVGs"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Spatie\\MediaLibrary\\MediaLibraryServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Spatie\\MediaLibrary\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Freek Van der Herten",
|
||||||
|
"email": "freek@spatie.be",
|
||||||
|
"homepage": "https://spatie.be",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Associate files with Eloquent models",
|
||||||
|
"homepage": "https://github.com/spatie/laravel-medialibrary",
|
||||||
|
"keywords": [
|
||||||
|
"cms",
|
||||||
|
"conversion",
|
||||||
|
"downloads",
|
||||||
|
"images",
|
||||||
|
"laravel",
|
||||||
|
"laravel-medialibrary",
|
||||||
|
"media",
|
||||||
|
"spatie"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/spatie/laravel-medialibrary/issues",
|
||||||
|
"source": "https://github.com/spatie/laravel-medialibrary/tree/11.22.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://spatie.be/open-source/support-us",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/spatie",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-05-04T11:42:39+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "spatie/laravel-package-tools",
|
"name": "spatie/laravel-package-tools",
|
||||||
"version": "1.93.0",
|
"version": "1.93.0",
|
||||||
@@ -5681,6 +6111,67 @@
|
|||||||
],
|
],
|
||||||
"time": "2026-04-27T14:27:52+00:00"
|
"time": "2026-04-27T14:27:52+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "spatie/temporary-directory",
|
||||||
|
"version": "2.3.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/spatie/temporary-directory.git",
|
||||||
|
"reference": "662e481d6ec07ef29fd05010433428851a42cd07"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/spatie/temporary-directory/zipball/662e481d6ec07ef29fd05010433428851a42cd07",
|
||||||
|
"reference": "662e481d6ec07ef29fd05010433428851a42cd07",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^9.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Spatie\\TemporaryDirectory\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Alex Vanderbist",
|
||||||
|
"email": "alex@spatie.be",
|
||||||
|
"homepage": "https://spatie.be",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Easily create, use and destroy temporary directories",
|
||||||
|
"homepage": "https://github.com/spatie/temporary-directory",
|
||||||
|
"keywords": [
|
||||||
|
"php",
|
||||||
|
"spatie",
|
||||||
|
"temporary-directory"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/spatie/temporary-directory/issues",
|
||||||
|
"source": "https://github.com/spatie/temporary-directory/tree/2.3.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://spatie.be/open-source/support-us",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/spatie",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2026-01-12T07:42:22+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "stancl/jobpipeline",
|
"name": "stancl/jobpipeline",
|
||||||
"version": "v1.9.0",
|
"version": "v1.9.0",
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('media', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
|
||||||
|
$table->morphs('model');
|
||||||
|
$table->uuid()->nullable()->unique();
|
||||||
|
$table->string('collection_name');
|
||||||
|
$table->string('name');
|
||||||
|
$table->string('file_name');
|
||||||
|
$table->string('mime_type')->nullable();
|
||||||
|
$table->string('disk');
|
||||||
|
$table->string('conversions_disk')->nullable();
|
||||||
|
$table->unsignedBigInteger('size');
|
||||||
|
$table->json('manipulations');
|
||||||
|
$table->json('custom_properties');
|
||||||
|
$table->json('generated_conversions');
|
||||||
|
$table->json('responsive_images');
|
||||||
|
$table->unsignedInteger('order_column')->nullable()->index();
|
||||||
|
|
||||||
|
$table->nullableTimestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user