Add 100+ automated unit tests from .expect file specifications Add session system test Add rsx:constants:regenerate command test Add rsx:logrotate command test Add rsx:clean command test Add rsx:manifest:stats command test Add model enum system test Add model mass assignment prevention test Add rsx:check command test Add migrate:status command test 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
141 lines
4.6 KiB
PHP
141 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\RSpade\Commands\Thumbnails;
|
|
|
|
use Illuminate\Console\Command;
|
|
use App\RSpade\Core\Files\File_Attachment_Model;
|
|
use App\RSpade\Core\Files\File_Attachment_Controller;
|
|
|
|
class Thumbnails_Generate_Command extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'rsx:thumbnails:generate
|
|
{--preset= : Generate specific preset for all attachments (e.g., --preset=profile)}
|
|
{--key= : Generate thumbnails for specific attachment key}
|
|
{--all : Generate all presets for all attachments (default if no options specified)}';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Pre-generate preset thumbnails for attachments (useful for cache warming after deployment)';
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*/
|
|
public function handle()
|
|
{
|
|
$preset_filter = $this->option('preset');
|
|
$key_filter = $this->option('key');
|
|
$generate_all = $this->option('all') || (!$preset_filter && !$key_filter);
|
|
|
|
// Get presets to generate
|
|
$presets = config('rsx.thumbnails.presets', []);
|
|
if (empty($presets)) {
|
|
$this->error('No thumbnail presets defined in config');
|
|
return 1;
|
|
}
|
|
|
|
$presets_to_generate = $presets;
|
|
if ($preset_filter) {
|
|
if (!isset($presets[$preset_filter])) {
|
|
$this->error("Preset '{$preset_filter}' not defined in config");
|
|
return 1;
|
|
}
|
|
$presets_to_generate = [$preset_filter => $presets[$preset_filter]];
|
|
}
|
|
|
|
// Get attachments to process
|
|
$query = File_Attachment_Model::query();
|
|
if ($key_filter) {
|
|
$query->where('key', $key_filter);
|
|
}
|
|
|
|
$attachments = $query->get();
|
|
|
|
if ($attachments->isEmpty()) {
|
|
$this->warn('No attachments found');
|
|
return 0;
|
|
}
|
|
|
|
$this->info("Generating thumbnails for " . count($attachments) . " attachment(s), " . count($presets_to_generate) . " preset(s)");
|
|
|
|
$generated_count = 0;
|
|
$skipped_count = 0;
|
|
$error_count = 0;
|
|
|
|
foreach ($attachments as $attachment) {
|
|
foreach ($presets_to_generate as $preset_name => $preset_config) {
|
|
try {
|
|
$this->generate_thumbnail($attachment, $preset_name, $preset_config);
|
|
$generated_count++;
|
|
} catch (\Exception $e) {
|
|
$this->error("Error generating {$preset_name} for {$attachment->key}: " . $e->getMessage());
|
|
$error_count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->info("Complete: {$generated_count} generated, {$skipped_count} skipped (cached), {$error_count} errors");
|
|
return $error_count > 0 ? 1 : 0;
|
|
}
|
|
|
|
/**
|
|
* Generate thumbnail for attachment/preset combination
|
|
*
|
|
* @param File_Attachment_Model $attachment
|
|
* @param string $preset_name
|
|
* @param array $preset_config
|
|
* @return void
|
|
*/
|
|
protected function generate_thumbnail($attachment, $preset_name, $preset_config)
|
|
{
|
|
$storage = $attachment->file_storage;
|
|
if (!$storage || !file_exists($storage->get_full_path())) {
|
|
throw new \Exception('File not found on disk');
|
|
}
|
|
|
|
// Generate cache filename
|
|
$cache_filename = File_Attachment_Controller::_get_cache_filename_preset(
|
|
$preset_name,
|
|
$storage->hash,
|
|
$attachment->file_extension
|
|
);
|
|
$cache_path = File_Attachment_Controller::_get_cache_path('preset', $cache_filename);
|
|
|
|
// Skip if already cached
|
|
if (file_exists($cache_path)) {
|
|
return;
|
|
}
|
|
|
|
$type = $preset_config['type'];
|
|
$width = $preset_config['width'];
|
|
$height = $preset_config['height'] ?? null;
|
|
|
|
// Generate thumbnail
|
|
if ($attachment->is_image()) {
|
|
$thumbnail_data = File_Attachment_Controller::__generate_thumbnail(
|
|
$storage->get_full_path(),
|
|
$type,
|
|
$width,
|
|
$height
|
|
);
|
|
} else {
|
|
// Use icon-based thumbnail for non-images
|
|
$thumbnail_data = \App\RSpade\Core\Files\File_Attachment_Icons::render_icon_as_thumbnail(
|
|
$attachment->file_extension,
|
|
$width,
|
|
$height ?? $width
|
|
);
|
|
}
|
|
|
|
// Save to cache
|
|
File_Attachment_Controller::_save_thumbnail_to_cache($cache_path, $thumbnail_data);
|
|
}
|
|
}
|