Fix Event & EventType resource issues and apply formatting
- Fix EventType deletion error handling (constraint violations) - Fix Event update error (package_id column missing) - Fix Event Type dropdown options (JSON display issue) - Fix EventPackagesRelationManager query error - Add missing translations for deletion errors - Apply Pint formatting
This commit is contained in:
@@ -7,7 +7,6 @@ use App\Models\Tenant;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Console\Attributes\AsCommand;
|
use Illuminate\Console\Attributes\AsCommand;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
#[AsCommand(name: 'tenant:attach-demo-event')]
|
#[AsCommand(name: 'tenant:attach-demo-event')]
|
||||||
class AttachDemoEvent extends Command
|
class AttachDemoEvent extends Command
|
||||||
@@ -25,10 +24,12 @@ class AttachDemoEvent extends Command
|
|||||||
{
|
{
|
||||||
if (! \Illuminate\Support\Facades\Schema::hasTable('events')) {
|
if (! \Illuminate\Support\Facades\Schema::hasTable('events')) {
|
||||||
$this->error("Table 'events' does not exist. Run: php artisan migrate");
|
$this->error("Table 'events' does not exist. Run: php artisan migrate");
|
||||||
|
|
||||||
return self::FAILURE;
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
if (! \Illuminate\Support\Facades\Schema::hasColumn('events', 'tenant_id')) {
|
if (! \Illuminate\Support\Facades\Schema::hasColumn('events', 'tenant_id')) {
|
||||||
$this->error("Column 'events.tenant_id' does not exist. Add it and rerun. Suggested: create a migration to add a nullable foreignId to tenants.");
|
$this->error("Column 'events.tenant_id' does not exist. Add it and rerun. Suggested: create a migration to add a nullable foreignId to tenants.");
|
||||||
|
|
||||||
return self::FAILURE;
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
$tenant = null;
|
$tenant = null;
|
||||||
@@ -45,6 +46,7 @@ class AttachDemoEvent extends Command
|
|||||||
}
|
}
|
||||||
if (! $tenant) {
|
if (! $tenant) {
|
||||||
$this->error('Tenant not found. Provide --tenant-slug or a user with tenant_id via --tenant-email.');
|
$this->error('Tenant not found. Provide --tenant-slug or a user with tenant_id via --tenant-email.');
|
||||||
|
|
||||||
return self::FAILURE;
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,12 +69,14 @@ class AttachDemoEvent extends Command
|
|||||||
|
|
||||||
if (! $event) {
|
if (! $event) {
|
||||||
$this->error('Event not found. Provide --event-id or --event-slug.');
|
$this->error('Event not found. Provide --event-id or --event-slug.');
|
||||||
|
|
||||||
return self::FAILURE;
|
return self::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Idempotent update
|
// Idempotent update
|
||||||
if ((int) $event->tenant_id === (int) $tenant->id) {
|
if ((int) $event->tenant_id === (int) $tenant->id) {
|
||||||
$this->info("Event #{$event->id} already attached to tenant #{$tenant->id} ({$tenant->slug}).");
|
$this->info("Event #{$event->id} already attached to tenant #{$tenant->id} ({$tenant->slug}).");
|
||||||
|
|
||||||
return self::SUCCESS;
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,6 +84,7 @@ class AttachDemoEvent extends Command
|
|||||||
$event->save();
|
$event->save();
|
||||||
|
|
||||||
$this->info("Attached event #{$event->id} ({$event->slug}) to tenant #{$tenant->id} ({$tenant->slug}).");
|
$this->info("Attached event #{$event->id} ({$event->slug}) to tenant #{$tenant->id} ({$tenant->slug}).");
|
||||||
|
|
||||||
return self::SUCCESS;
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
class BackfillThumbnails extends Command
|
class BackfillThumbnails extends Command
|
||||||
{
|
{
|
||||||
protected $signature = 'media:backfill-thumbnails {--limit=500}';
|
protected $signature = 'media:backfill-thumbnails {--limit=500}';
|
||||||
|
|
||||||
protected $description = 'Generate thumbnails for photos missing thumbnail_path or where thumbnail equals original.';
|
protected $description = 'Generate thumbnails for photos missing thumbnail_path or where thumbnail equals original.';
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
@@ -24,8 +25,12 @@ class BackfillThumbnails extends Command
|
|||||||
foreach ($rows as $r) {
|
foreach ($rows as $r) {
|
||||||
$orig = $this->relativeFromUrl((string) $r->file_path);
|
$orig = $this->relativeFromUrl((string) $r->file_path);
|
||||||
$thumb = (string) ($r->thumbnail_path ?? '');
|
$thumb = (string) ($r->thumbnail_path ?? '');
|
||||||
if ($thumb && $thumb !== $r->file_path) continue; // already set to different thumb
|
if ($thumb && $thumb !== $r->file_path) {
|
||||||
if (! $orig) continue;
|
continue;
|
||||||
|
} // already set to different thumb
|
||||||
|
if (! $orig) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$baseName = pathinfo($orig, PATHINFO_FILENAME);
|
$baseName = pathinfo($orig, PATHINFO_FILENAME);
|
||||||
$destRel = "events/{$r->event_id}/photos/thumbs/{$baseName}_thumb.jpg";
|
$destRel = "events/{$r->event_id}/photos/thumbs/{$baseName}_thumb.jpg";
|
||||||
$made = ImageHelper::makeThumbnailOnDisk('public', $orig, $destRel, 640, 82);
|
$made = ImageHelper::makeThumbnailOnDisk('public', $orig, $destRel, 640, 82);
|
||||||
@@ -39,6 +44,7 @@ class BackfillThumbnails extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->info("Done. Thumbnails generated: {$count}");
|
$this->info("Done. Thumbnails generated: {$count}");
|
||||||
|
|
||||||
return self::SUCCESS;
|
return self::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +55,7 @@ class BackfillThumbnails extends Command
|
|||||||
if (str_starts_with($p, '/storage/')) {
|
if (str_starts_with($p, '/storage/')) {
|
||||||
return substr($p, strlen('/storage/'));
|
return substr($p, strlen('/storage/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ namespace App\Console\Commands;
|
|||||||
|
|
||||||
use App\Models\PackagePurchase;
|
use App\Models\PackagePurchase;
|
||||||
use App\Models\Tenant;
|
use App\Models\Tenant;
|
||||||
use App\Models\User;
|
|
||||||
use App\Models\TenantPackage;
|
use App\Models\TenantPackage;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class MigrateLegacyPurchases extends Command
|
class MigrateLegacyPurchases extends Command
|
||||||
{
|
{
|
||||||
protected $signature = 'packages:migrate-legacy';
|
protected $signature = 'packages:migrate-legacy';
|
||||||
|
|
||||||
protected $description = 'Migrate legacy purchases to new system with temp tenants';
|
protected $description = 'Migrate legacy purchases to new system with temp tenants';
|
||||||
|
|
||||||
public function handle()
|
public function handle()
|
||||||
@@ -21,6 +21,7 @@ class MigrateLegacyPurchases extends Command
|
|||||||
|
|
||||||
if ($legacyPurchases->isEmpty()) {
|
if ($legacyPurchases->isEmpty()) {
|
||||||
$this->info('No legacy purchases found.');
|
$this->info('No legacy purchases found.');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,6 +74,7 @@ class MigrateLegacyPurchases extends Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->info('Legacy migration completed.');
|
$this->info('Legacy migration completed.');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ class SendAbandonedCheckoutReminders extends Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->info("✅ Reminder process completed!");
|
$this->info('✅ Reminder process completed!');
|
||||||
$this->info(" Processed: {$totalProcessed} checkouts");
|
$this->info(" Processed: {$totalProcessed} checkouts");
|
||||||
|
|
||||||
if (! $isDryRun) {
|
if (! $isDryRun) {
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ namespace App\Exports;
|
|||||||
use App\Models\EventPurchase;
|
use App\Models\EventPurchase;
|
||||||
use Filament\Actions\Exports\Exporter;
|
use Filament\Actions\Exports\Exporter;
|
||||||
use Filament\Actions\Exports\Models\Export;
|
use Filament\Actions\Exports\Models\Export;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
|
|
||||||
class EventPurchaseExporter extends Exporter
|
class EventPurchaseExporter extends Exporter
|
||||||
{
|
{
|
||||||
@@ -28,7 +26,6 @@ class EventPurchaseExporter extends Exporter
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function getCompletedNotificationBody(Export $export): string
|
public static function getCompletedNotificationBody(Export $export): string
|
||||||
{
|
{
|
||||||
$body = "Your Event Purchases export has completed and is ready for download. {$export->successful_rows} purchases were exported.";
|
$body = "Your Event Purchases export has completed and is ready for download. {$export->successful_rows} purchases were exported.";
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ use Illuminate\Support\Facades\Storage;
|
|||||||
class ImportEmotions extends Page
|
class ImportEmotions extends Page
|
||||||
{
|
{
|
||||||
protected static string $resource = EmotionResource::class;
|
protected static string $resource = EmotionResource::class;
|
||||||
|
|
||||||
protected string $view = 'filament.resources.emotion-resource.pages.import-emotions';
|
protected string $view = 'filament.resources.emotion-resource.pages.import-emotions';
|
||||||
|
|
||||||
protected ?string $heading = null;
|
protected ?string $heading = null;
|
||||||
|
|
||||||
public ?string $file = null;
|
public ?string $file = null;
|
||||||
@@ -36,6 +38,7 @@ class ImportEmotions extends Page
|
|||||||
$path = $this->form->getState()['file'] ?? null;
|
$path = $this->form->getState()['file'] ?? null;
|
||||||
if (! $path || ! Storage::disk('public')->exists($path)) {
|
if (! $path || ! Storage::disk('public')->exists($path)) {
|
||||||
Notification::make()->danger()->title(__('admin.notifications.file_not_found'))->send();
|
Notification::make()->danger()->title(__('admin.notifications.file_not_found'))->send();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,14 +65,15 @@ class EventResource extends Resource
|
|||||||
->required(),
|
->required(),
|
||||||
Select::make('event_type_id')
|
Select::make('event_type_id')
|
||||||
->label(__('admin.events.fields.type'))
|
->label(__('admin.events.fields.type'))
|
||||||
->options(EventType::query()->pluck('name', 'id'))
|
->options(fn () => EventType::all()->pluck('name.de', 'id'))
|
||||||
->searchable(),
|
->searchable(),
|
||||||
Select::make('package_id')
|
Select::make('package_id')
|
||||||
->label(__('admin.events.fields.package'))
|
->label(__('admin.events.fields.package'))
|
||||||
->options(\App\Models\Package::query()->where('type', 'endcustomer')->pluck('name', 'id'))
|
->options(\App\Models\Package::query()->where('type', 'endcustomer')->pluck('name', 'id'))
|
||||||
->searchable()
|
->searchable()
|
||||||
->preload()
|
->preload()
|
||||||
->required(),
|
->required()
|
||||||
|
->visibleOn('create'),
|
||||||
TextInput::make('default_locale')
|
TextInput::make('default_locale')
|
||||||
->label(__('admin.events.fields.default_locale'))
|
->label(__('admin.events.fields.default_locale'))
|
||||||
->default('de')
|
->default('de')
|
||||||
|
|||||||
@@ -8,4 +8,25 @@ use App\Filament\Resources\Pages\AuditedCreateRecord;
|
|||||||
class CreateEvent extends AuditedCreateRecord
|
class CreateEvent extends AuditedCreateRecord
|
||||||
{
|
{
|
||||||
protected static string $resource = EventResource::class;
|
protected static string $resource = EventResource::class;
|
||||||
|
|
||||||
|
public ?int $packageId = null;
|
||||||
|
|
||||||
|
protected function mutateFormDataBeforeCreate(array $data): array
|
||||||
|
{
|
||||||
|
$this->packageId = $data['package_id'] ?? null;
|
||||||
|
unset($data['package_id']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function afterCreate(): void
|
||||||
|
{
|
||||||
|
if ($this->packageId) {
|
||||||
|
$this->record->eventPackages()->create([
|
||||||
|
'package_id' => $this->packageId,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::afterCreate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ use Filament\Tables\Table;
|
|||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
|
||||||
|
|
||||||
class EventPackagesRelationManager extends RelationManager
|
class EventPackagesRelationManager extends RelationManager
|
||||||
{
|
{
|
||||||
@@ -59,6 +58,7 @@ class EventPackagesRelationManager extends RelationManager
|
|||||||
public function table(Table $table): Table
|
public function table(Table $table): Table
|
||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
|
->modifyQueryUsing(fn (Builder $query) => $query->with('package'))
|
||||||
->recordTitleAttribute('package.name')
|
->recordTitleAttribute('package.name')
|
||||||
->columns([
|
->columns([
|
||||||
TextColumn::make('package.name')
|
TextColumn::make('package.name')
|
||||||
@@ -147,9 +147,4 @@ class EventPackagesRelationManager extends RelationManager
|
|||||||
{
|
{
|
||||||
return __('admin.events.relation_managers.event_packages.title');
|
return __('admin.events.relation_managers.event_packages.title');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTableQuery(): Builder|Relation
|
|
||||||
{
|
|
||||||
return parent::getTableQuery()->with('package');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,18 +113,64 @@ class EventTypeResource extends Resource
|
|||||||
SuperAdminAuditLogger::fieldsMetadata($data),
|
SuperAdminAuditLogger::fieldsMetadata($data),
|
||||||
static::class
|
static::class
|
||||||
)),
|
)),
|
||||||
])
|
Actions\DeleteAction::make()
|
||||||
->bulkActions([
|
->action(function (EventType $record, Actions\DeleteAction $action) {
|
||||||
Actions\DeleteBulkAction::make()
|
try {
|
||||||
->after(function (Collection $records): void {
|
$record->delete();
|
||||||
$logger = app(SuperAdminAuditLogger::class);
|
} catch (\Exception $e) {
|
||||||
|
$isConstraint = ($e instanceof \Illuminate\Database\QueryException && ($e->getCode() == 23000 || ($e->errorInfo[0] ?? '') == 23000));
|
||||||
|
|
||||||
foreach ($records as $record) {
|
if ($isConstraint) {
|
||||||
$logger->recordModelMutation(
|
\Filament\Notifications\Notification::make()
|
||||||
|
->title(__('admin.common.error'))
|
||||||
|
->body(__('admin.event_types.messages.delete_constraint_error'))
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
$action->halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
->after(fn (EventType $record) => app(SuperAdminAuditLogger::class)->recordModelMutation(
|
||||||
'deleted',
|
'deleted',
|
||||||
$record,
|
$record,
|
||||||
source: static::class
|
source: static::class
|
||||||
);
|
)),
|
||||||
|
])
|
||||||
|
->bulkActions([
|
||||||
|
Actions\DeleteBulkAction::make()
|
||||||
|
->action(function (Collection $records, Actions\DeleteBulkAction $action) {
|
||||||
|
$logger = app(SuperAdminAuditLogger::class);
|
||||||
|
$deletedCount = 0;
|
||||||
|
$failedCount = 0;
|
||||||
|
|
||||||
|
foreach ($records as $record) {
|
||||||
|
try {
|
||||||
|
$record->delete();
|
||||||
|
$logger->recordModelMutation('deleted', $record, source: static::class);
|
||||||
|
$deletedCount++;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$isConstraint = ($e instanceof \Illuminate\Database\QueryException && ($e->getCode() == 23000 || ($e->errorInfo[0] ?? '') == 23000));
|
||||||
|
if ($isConstraint) {
|
||||||
|
$failedCount++;
|
||||||
|
} else {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($failedCount > 0) {
|
||||||
|
\Filament\Notifications\Notification::make()
|
||||||
|
->title(__('admin.common.error'))
|
||||||
|
->body(__('admin.event_types.messages.delete_constraint_error')." ($failedCount failed, $deletedCount deleted)")
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
if ($deletedCount === 0) {
|
||||||
|
$action->halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -17,4 +17,3 @@ class ListMediaStorageTargets extends ListRecords
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,3 @@ class ListPurchaseHistories extends ListRecords
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,3 @@ class ViewPurchaseHistory extends ViewRecord
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
namespace App\Filament\SuperAdmin\Pages\Auth;
|
namespace App\Filament\SuperAdmin\Pages\Auth;
|
||||||
|
|
||||||
use Filament\Auth\Pages\EditProfile as BaseEditProfile;
|
use Filament\Auth\Pages\EditProfile as BaseEditProfile;
|
||||||
use Filament\Forms\Components\TextInput;
|
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ namespace App\Filament\Widgets;
|
|||||||
|
|
||||||
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
||||||
use Filament\Widgets\StatsOverviewWidget\Stat;
|
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class PlatformStatsWidget extends BaseWidget
|
class PlatformStatsWidget extends BaseWidget
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use Filament\Widgets\LineChartWidget;
|
|||||||
|
|
||||||
class RevenueTrendWidget extends LineChartWidget
|
class RevenueTrendWidget extends LineChartWidget
|
||||||
{
|
{
|
||||||
|
|
||||||
protected static ?int $sort = 1;
|
protected static ?int $sort = 1;
|
||||||
|
|
||||||
protected int|string|array $columnSpan = 'full';
|
protected int|string|array $columnSpan = 'full';
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Filament\Widgets;
|
namespace App\Filament\Widgets;
|
||||||
|
|
||||||
|
use App\Models\Tenant;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Filament\Widgets\TableWidget as BaseWidget;
|
use Filament\Widgets\TableWidget as BaseWidget;
|
||||||
use App\Models\Tenant;
|
|
||||||
|
|
||||||
class TopTenantsByUploads extends BaseWidget
|
class TopTenantsByUploads extends BaseWidget
|
||||||
{
|
{
|
||||||
@@ -14,6 +14,7 @@ class TopTenantsByUploads extends BaseWidget
|
|||||||
{
|
{
|
||||||
return __('admin.widgets.top_tenants_by_uploads.heading');
|
return __('admin.widgets.top_tenants_by_uploads.heading');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ?string $pollingInterval = '60s';
|
protected ?string $pollingInterval = '60s';
|
||||||
|
|
||||||
public function table(Tables\Table $table): Tables\Table
|
public function table(Tables\Table $table): Tables\Table
|
||||||
@@ -33,4 +34,3 @@ class TopTenantsByUploads extends BaseWidget
|
|||||||
->paginated(false);
|
->paginated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Admin;
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
use SimpleSoftwareIO\QrCode\Facades\QrCode;
|
use SimpleSoftwareIO\QrCode\Facades\QrCode;
|
||||||
|
|
||||||
class QrController extends BaseController
|
class QrController extends BaseController
|
||||||
@@ -15,7 +15,7 @@ class QrController extends BaseController
|
|||||||
return response('missing data', 400);
|
return response('missing data', 400);
|
||||||
}
|
}
|
||||||
$png = QrCode::format('png')->size(300)->generate($data);
|
$png = QrCode::format('png')->size(300)->generate($data);
|
||||||
|
|
||||||
return response($png, 200, ['Content-Type' => 'image/png']);
|
return response($png, 200, ['Content-Type' => 'image/png']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ class LegalController extends BaseController
|
|||||||
'allow_unsafe_links' => false,
|
'allow_unsafe_links' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$environment->addExtension(new CommonMarkCoreExtension());
|
$environment->addExtension(new CommonMarkCoreExtension);
|
||||||
$environment->addExtension(new TableExtension());
|
$environment->addExtension(new TableExtension);
|
||||||
$environment->addExtension(new AutolinkExtension());
|
$environment->addExtension(new AutolinkExtension);
|
||||||
$environment->addExtension(new StrikethroughExtension());
|
$environment->addExtension(new StrikethroughExtension);
|
||||||
$environment->addExtension(new TaskListExtension());
|
$environment->addExtension(new TaskListExtension);
|
||||||
|
|
||||||
$this->markdown = new MarkdownConverter($environment);
|
$this->markdown = new MarkdownConverter($environment);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use App\Models\Event;
|
|||||||
use App\Services\Analytics\EventAnalyticsService;
|
use App\Services\Analytics\EventAnalyticsService;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
|
|
||||||
class EventAnalyticsController extends Controller
|
class EventAnalyticsController extends Controller
|
||||||
{
|
{
|
||||||
@@ -29,7 +28,7 @@ class EventAnalyticsController extends Controller
|
|||||||
if (! $hasAccess) {
|
if (! $hasAccess) {
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'message' => 'This feature is only available in the Premium package.',
|
'message' => 'This feature is only available in the Premium package.',
|
||||||
'code' => 'feature_locked'
|
'code' => 'feature_locked',
|
||||||
], 403);
|
], 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,4 +112,3 @@ class FontController extends Controller
|
|||||||
return $fonts;
|
return $fonts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,11 +112,11 @@ class LegalPageController extends Controller
|
|||||||
'allow_unsafe_links' => false,
|
'allow_unsafe_links' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$environment->addExtension(new CommonMarkCoreExtension());
|
$environment->addExtension(new CommonMarkCoreExtension);
|
||||||
$environment->addExtension(new TableExtension());
|
$environment->addExtension(new TableExtension);
|
||||||
$environment->addExtension(new AutolinkExtension());
|
$environment->addExtension(new AutolinkExtension);
|
||||||
$environment->addExtension(new StrikethroughExtension());
|
$environment->addExtension(new StrikethroughExtension);
|
||||||
$environment->addExtension(new TaskListExtension());
|
$environment->addExtension(new TaskListExtension);
|
||||||
|
|
||||||
$converter = new MarkdownConverter($environment);
|
$converter = new MarkdownConverter($environment);
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class EventPhotoArchiveController extends Controller
|
|||||||
abort(404, 'No approved photos available for this event.');
|
abort(404, 'No approved photos available for this event.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$zip = new ZipArchive();
|
$zip = new ZipArchive;
|
||||||
$tempPath = tempnam(sys_get_temp_dir(), 'fotospiel-photos-');
|
$tempPath = tempnam(sys_get_temp_dir(), 'fotospiel-photos-');
|
||||||
|
|
||||||
if ($tempPath === false || $zip->open($tempPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
if ($tempPath === false || $zip->open($tempPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
||||||
@@ -129,4 +129,3 @@ class EventPhotoArchiveController extends Controller
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Support\LocaleConfig;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use App\Support\LocaleConfig;
|
|
||||||
|
|
||||||
class SetLocaleFromRequest
|
class SetLocaleFromRequest
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,4 +19,3 @@ class SetLocaleFromUser
|
|||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,3 @@ class ProfileUpdateRequest extends FormRequest
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Requests\Tenant;
|
namespace App\Http\Requests\Tenant;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class PhotoStoreRequest extends FormRequest
|
class PhotoStoreRequest extends FormRequest
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -88,4 +88,3 @@ class SettingsStoreRequest extends FormRequest
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class EmotionResource extends JsonResource
|
|||||||
}
|
}
|
||||||
|
|
||||||
$first = reset($value);
|
$first = reset($value);
|
||||||
|
|
||||||
return $first !== false ? (string) $first : $fallback;
|
return $first !== false ? (string) $first : $fallback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class ArchiveEventMediaAssets implements ShouldQueue
|
|||||||
|
|
||||||
if (! $event) {
|
if (! $event) {
|
||||||
Log::warning('Archive job aborted: event missing', ['event_id' => $this->eventId]);
|
Log::warning('Archive job aborted: event missing', ['event_id' => $this->eventId]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ class ArchiveEventMediaAssets implements ShouldQueue
|
|||||||
|
|
||||||
if (! $archiveDisk) {
|
if (! $archiveDisk) {
|
||||||
Log::warning('Archive job aborted: no archive disk configured', ['event_id' => $event->id]);
|
Log::warning('Archive job aborted: no archive disk configured', ['event_id' => $event->id]);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Concerns;
|
namespace App\Jobs\Concerns;
|
||||||
|
|
||||||
|
use App\Models\Tenant;
|
||||||
use App\Models\TenantNotificationLog;
|
use App\Models\TenantNotificationLog;
|
||||||
use App\Models\TenantNotificationReceipt;
|
use App\Models\TenantNotificationReceipt;
|
||||||
use App\Models\Tenant;
|
|
||||||
use App\Services\Packages\TenantNotificationLogger;
|
use App\Services\Packages\TenantNotificationLogger;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
trait LogsTenantNotifications
|
trait LogsTenantNotifications
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ class ContactConfirmation extends Mailable
|
|||||||
use Queueable;
|
use Queueable;
|
||||||
use SerializesModels;
|
use SerializesModels;
|
||||||
|
|
||||||
public function __construct(public string $name)
|
public function __construct(public string $name) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public function envelope(): Envelope
|
public function envelope(): Envelope
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
class BlogCategory extends Model
|
class BlogCategory extends Model
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,19 +8,18 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Spatie\Translatable\HasTranslations;
|
|
||||||
use League\CommonMark\Environment\Environment;
|
use League\CommonMark\Environment\Environment;
|
||||||
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
|
||||||
use League\CommonMark\Extension\Table\TableExtension;
|
|
||||||
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
||||||
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
||||||
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
||||||
|
use League\CommonMark\Extension\Table\TableExtension;
|
||||||
use League\CommonMark\Extension\TaskList\TaskListExtension;
|
use League\CommonMark\Extension\TaskList\TaskListExtension;
|
||||||
use League\CommonMark\MarkdownConverter;
|
use League\CommonMark\MarkdownConverter;
|
||||||
|
use Spatie\Translatable\HasTranslations;
|
||||||
|
|
||||||
class BlogPost extends Model
|
class BlogPost extends Model
|
||||||
{
|
{
|
||||||
use HasFactory, SoftDeletes, HasTranslations;
|
use HasFactory, HasTranslations, SoftDeletes;
|
||||||
|
|
||||||
protected $table = 'blog_posts';
|
protected $table = 'blog_posts';
|
||||||
|
|
||||||
@@ -78,14 +77,15 @@ class BlogPost extends Model
|
|||||||
return Attribute::get(function () {
|
return Attribute::get(function () {
|
||||||
$markdown = $this->getTranslation('content', app()->getLocale());
|
$markdown = $this->getTranslation('content', app()->getLocale());
|
||||||
|
|
||||||
$environment = new Environment();
|
$environment = new Environment;
|
||||||
$environment->addExtension(new CommonMarkCoreExtension());
|
$environment->addExtension(new CommonMarkCoreExtension);
|
||||||
$environment->addExtension(new TableExtension());
|
$environment->addExtension(new TableExtension);
|
||||||
$environment->addExtension(new AutolinkExtension());
|
$environment->addExtension(new AutolinkExtension);
|
||||||
$environment->addExtension(new StrikethroughExtension());
|
$environment->addExtension(new StrikethroughExtension);
|
||||||
$environment->addExtension(new TaskListExtension());
|
$environment->addExtension(new TaskListExtension);
|
||||||
|
|
||||||
$converter = new MarkdownConverter($environment);
|
$converter = new MarkdownConverter($environment);
|
||||||
|
|
||||||
return (string) $converter->convert($markdown);
|
return (string) $converter->convert($markdown);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,13 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Spatie\Tags\Tag;
|
use Spatie\Tags\Tag;
|
||||||
use Spatie\Translatable\HasTranslations;
|
use Spatie\Translatable\HasTranslations;
|
||||||
|
|
||||||
class BlogTag extends Tag
|
class BlogTag extends Tag
|
||||||
{
|
{
|
||||||
use HasFactory, SoftDeletes, HasTranslations;
|
use HasFactory, HasTranslations, SoftDeletes;
|
||||||
|
|
||||||
protected $translatable = [
|
protected $translatable = [
|
||||||
'name',
|
'name',
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ class Emotion extends Model
|
|||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $table = 'emotions';
|
protected $table = 'emotions';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'name' => 'array',
|
'name' => 'array',
|
||||||
'description' => 'array',
|
'description' => 'array',
|
||||||
@@ -34,4 +36,3 @@ class Emotion extends Model
|
|||||||
return $this->hasMany(Task::class);
|
return $this->hasMany(Task::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,4 +47,3 @@ class EventJoinTokenEvent extends Model
|
|||||||
return $this->belongsTo(Tenant::class);
|
return $this->belongsTo(Tenant::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,4 +51,3 @@ class EventMediaAsset extends Model
|
|||||||
return $this->belongsTo(Photo::class);
|
return $this->belongsTo(Photo::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ class EventPurchase extends Model
|
|||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $table = 'event_purchases';
|
protected $table = 'event_purchases';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'purchased_at' => 'datetime',
|
'purchased_at' => 'datetime',
|
||||||
'amount' => 'decimal:2',
|
'amount' => 'decimal:2',
|
||||||
|
|||||||
@@ -36,4 +36,3 @@ class EventStorageAssignment extends Model
|
|||||||
return $this->belongsTo(MediaStorageTarget::class, 'media_storage_target_id');
|
return $this->belongsTo(MediaStorageTarget::class, 'media_storage_target_id');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ class EventType extends Model
|
|||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $table = 'event_types';
|
protected $table = 'event_types';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'name' => 'array',
|
'name' => 'array',
|
||||||
'settings' => 'array',
|
'settings' => 'array',
|
||||||
@@ -28,4 +30,3 @@ class EventType extends Model
|
|||||||
return $this->hasMany(Event::class);
|
return $this->hasMany(Event::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
class LegalPage extends Model
|
class LegalPage extends Model
|
||||||
{
|
{
|
||||||
protected $table = 'legal_pages';
|
protected $table = 'legal_pages';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'title' => 'array',
|
'title' => 'array',
|
||||||
'body_markdown' => 'array',
|
'body_markdown' => 'array',
|
||||||
@@ -15,4 +17,3 @@ class LegalPage extends Model
|
|||||||
'effective_from' => 'datetime',
|
'effective_from' => 'datetime',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,4 +63,3 @@ class MediaStorageTarget extends Model
|
|||||||
return array_merge($base, $config);
|
return array_merge($base, $config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|||||||
class PhotoLike extends Model
|
class PhotoLike extends Model
|
||||||
{
|
{
|
||||||
protected $table = 'photo_likes';
|
protected $table = 'photo_likes';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
|
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
|
|
||||||
public function photo(): BelongsTo
|
public function photo(): BelongsTo
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ class PurchaseHistory extends Model
|
|||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $table = 'purchase_history';
|
protected $table = 'purchase_history';
|
||||||
|
|
||||||
public $timestamps = false;
|
public $timestamps = false;
|
||||||
|
|
||||||
public $incrementing = false;
|
public $incrementing = false;
|
||||||
|
|
||||||
protected $keyType = 'string';
|
protected $keyType = 'string';
|
||||||
|
|
||||||
protected $guarded = [];
|
protected $guarded = [];
|
||||||
@@ -28,4 +31,3 @@ class PurchaseHistory extends Model
|
|||||||
return $this->belongsTo(Tenant::class);
|
return $this->belongsTo(Tenant::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Services\Analytics;
|
namespace App\Services\Analytics;
|
||||||
|
|
||||||
use App\Models\Event;
|
use App\Models\Event;
|
||||||
use App\Models\Photo;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class EventAnalyticsService
|
class EventAnalyticsService
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace App\Services\Analytics;
|
|||||||
use App\Models\EventJoinToken;
|
use App\Models\EventJoinToken;
|
||||||
use App\Models\EventJoinTokenEvent;
|
use App\Models\EventJoinTokenEvent;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class JoinTokenAnalyticsRecorder
|
class JoinTokenAnalyticsRecorder
|
||||||
@@ -109,4 +108,3 @@ class JoinTokenAnalyticsRecorder
|
|||||||
return Str::substr($token, 0, 6).'…'.Str::substr($token, -4);
|
return Str::substr($token, 0, 6).'…'.Str::substr($token, -4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class EmotionImportService
|
|||||||
$headers = fgetcsv($handle, 0, ',');
|
$headers = fgetcsv($handle, 0, ',');
|
||||||
if (! $headers) {
|
if (! $headers) {
|
||||||
fclose($handle);
|
fclose($handle);
|
||||||
|
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -192,4 +192,3 @@ class PhotoSecurityScanner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ use App\Models\EventStorageAssignment;
|
|||||||
use App\Models\MediaStorageTarget;
|
use App\Models\MediaStorageTarget;
|
||||||
use Illuminate\Support\Facades\Config;
|
use Illuminate\Support\Facades\Config;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class EventStorageManager
|
class EventStorageManager
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,4 +60,3 @@ class StorageHealthService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ class LocaleConfig
|
|||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return configured locales from env/config as provided (may include region codes).
|
* Return configured locales from env/config as provided (may include region codes).
|
||||||
|
*
|
||||||
* @return array<int, string>
|
* @return array<int, string>
|
||||||
*/
|
*/
|
||||||
public static function configured(): array
|
public static function configured(): array
|
||||||
@@ -34,6 +35,7 @@ class LocaleConfig
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Return normalized short codes (language only, lowercase).
|
* Return normalized short codes (language only, lowercase).
|
||||||
|
*
|
||||||
* @return array<int, string>
|
* @return array<int, string>
|
||||||
*/
|
*/
|
||||||
public static function normalized(): array
|
public static function normalized(): array
|
||||||
|
|||||||
@@ -14,4 +14,3 @@ return [
|
|||||||
'name' => env('SECURITY_SCAN_QUEUE', 'media-security'),
|
'name' => env('SECURITY_SCAN_QUEUE', 'media-security'),
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -29,4 +29,3 @@ class EmotionFactory extends Factory
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,4 +64,3 @@ class EventFactory extends Factory
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,4 +28,3 @@ class EventTypeFactory extends Factory
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,4 +25,3 @@ class PurchaseHistoryFactory extends Factory
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\EventType;
|
use App\Models\EventType;
|
||||||
use App\Models\Task;
|
|
||||||
use App\Models\TaskCollection;
|
use App\Models\TaskCollection;
|
||||||
use App\Models\Tenant;
|
use App\Models\Tenant;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ return new class extends Migration
|
|||||||
|
|
||||||
private function impressumDe(): string
|
private function impressumDe(): string
|
||||||
{
|
{
|
||||||
return <<<MD
|
return <<<'MD'
|
||||||
# Impressum
|
# Impressum
|
||||||
|
|
||||||
Anbieter dieser Seiten:
|
Anbieter dieser Seiten:
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,4 +33,3 @@ return new class extends Migration
|
|||||||
Schema::dropIfExists('media_storage_targets');
|
Schema::dropIfExists('media_storage_targets');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -34,4 +34,3 @@ return new class extends Migration
|
|||||||
Schema::dropIfExists('event_storage_assignments');
|
Schema::dropIfExists('event_storage_assignments');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -43,4 +43,3 @@ return new class extends Migration
|
|||||||
Schema::dropIfExists('event_media_assets');
|
Schema::dropIfExists('event_media_assets');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -24,4 +24,3 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,4 +23,3 @@ return new class extends Migration
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -35,4 +35,3 @@ return new class extends Migration
|
|||||||
Schema::dropIfExists('event_join_token_events');
|
Schema::dropIfExists('event_join_token_events');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
return new class extends Migration
|
return new class extends Migration
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
use App\Models\Emotion;
|
use App\Models\Emotion;
|
||||||
use App\Models\EventType;
|
use App\Models\EventType;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class EmotionsSeeder extends Seeder
|
class EmotionsSeeder extends Seeder
|
||||||
@@ -38,4 +38,3 @@ class EmotionsSeeder extends Seeder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
use App\Models\EventType;
|
use App\Models\EventType;
|
||||||
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class EventTypesSeeder extends Seeder
|
class EventTypesSeeder extends Seeder
|
||||||
{
|
{
|
||||||
@@ -22,4 +22,3 @@ class EventTypesSeeder extends Seeder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,4 +90,3 @@ class LegalPagesSeeder extends Seeder
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ return [
|
|||||||
],
|
],
|
||||||
|
|
||||||
'common' => [
|
'common' => [
|
||||||
|
'error' => 'Fehler',
|
||||||
'key' => 'Schlüssel',
|
'key' => 'Schlüssel',
|
||||||
'value' => 'Wert',
|
'value' => 'Wert',
|
||||||
'locale' => 'Sprache',
|
'locale' => 'Sprache',
|
||||||
@@ -466,6 +467,9 @@ return [
|
|||||||
'icon' => 'Icon',
|
'icon' => 'Icon',
|
||||||
'created_at' => 'Erstellt',
|
'created_at' => 'Erstellt',
|
||||||
],
|
],
|
||||||
|
'messages' => [
|
||||||
|
'delete_constraint_error' => 'Dieser Eventtyp wird derzeit verwendet und kann nicht gelöscht werden.',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'tasks' => [
|
'tasks' => [
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ return [
|
|||||||
],
|
],
|
||||||
|
|
||||||
'common' => [
|
'common' => [
|
||||||
|
'error' => 'Error',
|
||||||
'key' => 'Key',
|
'key' => 'Key',
|
||||||
'value' => 'Value',
|
'value' => 'Value',
|
||||||
'locale' => 'Locale',
|
'locale' => 'Locale',
|
||||||
@@ -459,6 +460,9 @@ return [
|
|||||||
'settings' => 'Settings',
|
'settings' => 'Settings',
|
||||||
'emotions' => 'Emotions',
|
'emotions' => 'Emotions',
|
||||||
],
|
],
|
||||||
|
'messages' => [
|
||||||
|
'delete_constraint_error' => 'This event type is currently in use and cannot be deleted.',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'tasks' => [
|
'tasks' => [
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace Tests\Feature\Api;
|
namespace Tests\Feature\Api;
|
||||||
|
|
||||||
|
use App\Mail\GiftVoucherIssued;
|
||||||
use App\Models\GiftVoucher;
|
use App\Models\GiftVoucher;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
use App\Mail\GiftVoucherIssued;
|
|
||||||
|
|
||||||
class GiftVoucherResendTest extends TestCase
|
class GiftVoucherResendTest extends TestCase
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -142,5 +142,4 @@ class CheckEventPackagesCommandTest extends TestCase
|
|||||||
Carbon::setTestNow();
|
Carbon::setTestNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ class ProcessPhotoSecurityScanTest extends TestCase
|
|||||||
{
|
{
|
||||||
[$photo, $asset] = $this->seedPhotoWithAsset();
|
[$photo, $asset] = $this->seedPhotoWithAsset();
|
||||||
|
|
||||||
$scanner = new class extends PhotoSecurityScanner {
|
$scanner = new class extends PhotoSecurityScanner
|
||||||
|
{
|
||||||
public function scan(string $disk, ?string $relativePath): array
|
public function scan(string $disk, ?string $relativePath): array
|
||||||
{
|
{
|
||||||
return ['status' => 'clean', 'message' => 'ok'];
|
return ['status' => 'clean', 'message' => 'ok'];
|
||||||
@@ -49,7 +50,8 @@ class ProcessPhotoSecurityScanTest extends TestCase
|
|||||||
{
|
{
|
||||||
[$photo] = $this->seedPhotoWithAsset();
|
[$photo] = $this->seedPhotoWithAsset();
|
||||||
|
|
||||||
$scanner = new class extends PhotoSecurityScanner {
|
$scanner = new class extends PhotoSecurityScanner
|
||||||
|
{
|
||||||
public function scan(string $disk, ?string $relativePath): array
|
public function scan(string $disk, ?string $relativePath): array
|
||||||
{
|
{
|
||||||
return ['status' => 'skipped', 'message' => 'disabled'];
|
return ['status' => 'skipped', 'message' => 'disabled'];
|
||||||
@@ -73,7 +75,8 @@ class ProcessPhotoSecurityScanTest extends TestCase
|
|||||||
{
|
{
|
||||||
[$photo, $asset] = $this->seedPhotoWithAsset();
|
[$photo, $asset] = $this->seedPhotoWithAsset();
|
||||||
|
|
||||||
$scanner = new class extends PhotoSecurityScanner {
|
$scanner = new class extends PhotoSecurityScanner
|
||||||
|
{
|
||||||
public function scan(string $disk, ?string $relativePath): array
|
public function scan(string $disk, ?string $relativePath): array
|
||||||
{
|
{
|
||||||
return ['status' => 'infected', 'message' => 'bad'];
|
return ['status' => 'infected', 'message' => 'bad'];
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
namespace Tests\Feature\Marketing;
|
namespace Tests\Feature\Marketing;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Inertia\Testing\AssertableInertia as Assert;
|
use Inertia\Testing\AssertableInertia as Assert;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
||||||
|
|
||||||
class MarketingLocaleRoutingTest extends TestCase
|
class MarketingLocaleRoutingTest extends TestCase
|
||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|
||||||
public function test_home_route_accepts_german_locale_prefix(): void
|
public function test_home_route_accepts_german_locale_prefix(): void
|
||||||
{
|
{
|
||||||
$response = $this->get('/de');
|
$response = $this->get('/de');
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class PackageSeederTest extends TestCase
|
|||||||
{
|
{
|
||||||
use RefreshDatabase;
|
use RefreshDatabase;
|
||||||
|
|
||||||
public function testStarterPackageHasSingleEventQuota(): void
|
public function test_starter_package_has_single_event_quota(): void
|
||||||
{
|
{
|
||||||
$this->seed(PackageSeeder::class);
|
$this->seed(PackageSeeder::class);
|
||||||
|
|
||||||
|
|||||||
@@ -75,4 +75,3 @@ KEY;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class AdminDashboardWidgetsTest extends TestCase
|
|||||||
'created_at' => now()->subMonth(),
|
'created_at' => now()->subMonth(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$widget = new RevenueTrendWidget();
|
$widget = new RevenueTrendWidget;
|
||||||
$data = $this->invokeProtectedMethod($widget, 'getData');
|
$data = $this->invokeProtectedMethod($widget, 'getData');
|
||||||
|
|
||||||
$this->assertArrayHasKey('datasets', $data);
|
$this->assertArrayHasKey('datasets', $data);
|
||||||
@@ -68,8 +68,6 @@ class AdminDashboardWidgetsTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @template T
|
* @template T
|
||||||
*
|
*
|
||||||
* @param object $object
|
|
||||||
* @param string $method
|
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
private function invokeProtectedMethod(object $object, string $method)
|
private function invokeProtectedMethod(object $object, string $method)
|
||||||
|
|||||||
Reference in New Issue
Block a user