'integer', 'optimized_size' => 'integer', 'percentage_saved' => 'integer', 'quality' => 'integer', ]; /** * The workspace this optimization belongs to. * * Returns a relationship to the Workspace model if it exists, * otherwise returns null. */ public function workspace(): ?BelongsTo { if (! class_exists('Core\\Mod\\Tenant\\Models\\Workspace')) { return null; } return $this->belongsTo('Core\\Mod\\Tenant\\Models\\Workspace'); } /** * Get the parent optimizable model (Page, User, etc.). */ public function optimizable(): MorphTo { return $this->morphTo(); } /** * Scope to a specific workspace. * * @param Model|null $workspace The workspace model to filter by */ public function scopeForWorkspace($query, ?Model $workspace) { if ($workspace === null) { return $query; } return $query->where('workspace_id', $workspace->id); } /** * Get human-readable savings summary. * * Example: "45% saved (120KB → 66KB)" */ public function getSavingsHumanAttribute(): string { $originalKb = round($this->original_size / 1024, 1); $optimizedKb = round($this->optimized_size / 1024, 1); // Format with appropriate unit $original = $this->formatBytes($this->original_size); $optimized = $this->formatBytes($this->optimized_size); return sprintf( '%d%% saved (%s → %s)', $this->percentage_saved, $original, $optimized ); } /** * Get human-readable size saved. */ public function getSizeSavedHumanAttribute(): string { $saved = $this->original_size - $this->optimized_size; return $this->formatBytes($saved); } /** * Format bytes to human-readable size. */ protected function formatBytes(int $bytes): string { if ($bytes < 1024) { return $bytes.'B'; } if ($bytes < 1024 * 1024) { return round($bytes / 1024, 1).'KB'; } if ($bytes < 1024 * 1024 * 1024) { return round($bytes / (1024 * 1024), 1).'MB'; } return round($bytes / (1024 * 1024 * 1024), 2).'GB'; } /** * Get total savings statistics for a workspace. * * @param Model|null $workspace Optional workspace model to filter by */ public static function getWorkspaceStats(?Model $workspace = null): array { $query = static::query(); if ($workspace) { $query->where('workspace_id', $workspace->id); } $optimizations = $query->get(); $totalOriginal = $optimizations->sum('original_size'); $totalOptimized = $optimizations->sum('optimized_size'); $totalSaved = $totalOriginal - $totalOptimized; $averagePercentage = $optimizations->count() > 0 ? $optimizations->avg('percentage_saved') : 0; return [ 'count' => $optimizations->count(), 'total_original' => $totalOriginal, 'total_optimized' => $totalOptimized, 'total_saved' => $totalSaved, 'average_percentage' => round($averagePercentage, 1), 'total_saved_human' => static::formatBytesStatic($totalSaved), ]; } /** * Static version of formatBytes for use in getWorkspaceStats. */ public static function formatBytesStatic(int $bytes): string { if ($bytes < 1024) { return $bytes.'B'; } if ($bytes < 1024 * 1024) { return round($bytes / 1024, 1).'KB'; } if ($bytes < 1024 * 1024 * 1024) { return round($bytes / (1024 * 1024), 1).'MB'; } return round($bytes / (1024 * 1024 * 1024), 2).'GB'; } }