46 lines
2.6 KiB
PHP
46 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
/** Category and pin metadata only; article bodies/categories are published through the editorial API. */
|
|
final class OrganizeTutorials extends Command
|
|
{
|
|
protected $signature = 'tutorials:organize {--apply : Save the category name and pin the published guide}';
|
|
|
|
protected $description = 'Rename the beginner category and pin its verified guide, with a private metadata backup';
|
|
|
|
public function handle(): int
|
|
{
|
|
$category = DB::table('categories')->where('sSlug', config('tutorials.beginner_slug'))->where('iStatus', 1)->first();
|
|
$guide = DB::table('articles')->where('sSlug', config('tutorials.guide_slug'))->where('iStatus', 1)->first();
|
|
if (! $category || ! $guide || $guide->iCategoryId !== $category->id) {
|
|
$this->error('Publish the guide in the beginner category before applying metadata.');
|
|
return self::FAILURE;
|
|
}
|
|
$this->line(json_encode(['category' => $category->sSlug, 'name' => config('tutorials.beginner_name'), 'guide' => $guide->sSlug, 'pinned' => true], JSON_UNESCAPED_UNICODE));
|
|
if (! $this->option('apply')) return self::SUCCESS;
|
|
$backup = storage_path('app/private/editorial/tutorial-metadata-'.Str::uuid().'.json');
|
|
$snapshot = ['category_id' => $category->id, 'sName' => $category->sName, 'guide_id' => $guide->id, 'iIsTop' => $guide->iIsTop];
|
|
file_put_contents($backup, json_encode($snapshot, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
|
chmod($backup, 0600);
|
|
DB::transaction(function () use ($category, $guide) {
|
|
$currentCategory = DB::table('categories')->where('id', $category->id)->lockForUpdate()->first();
|
|
$currentGuide = DB::table('articles')->where('id', $guide->id)->lockForUpdate()->first();
|
|
if ($currentCategory->sName !== $category->sName || $currentGuide->iCategoryId !== $category->id || ! $currentGuide->iStatus) {
|
|
throw new \RuntimeException('Tutorial metadata changed; inspect before retrying.');
|
|
}
|
|
DB::table('categories')->where('id', $category->id)->update(['sName' => config('tutorials.beginner_name')]);
|
|
DB::table('articles')->where('id', $guide->id)->update(['iIsTop' => 1]);
|
|
});
|
|
Cache::forget('global_nav_tree');
|
|
\Spatie\ResponseCache\Facades\ResponseCache::clear();
|
|
$this->info('Category renamed and guide pinned. Private backup: '.$backup);
|
|
return self::SUCCESS;
|
|
}
|
|
}
|