|
<?php |
|
|
|
namespace App\Console\Commands; |
|
|
|
use Illuminate\Console\Command; |
|
use Illuminate\Support\Str; |
|
use Statamic\Facades\Collection; |
|
use Statamic\Eloquent\Entries\UuidEntryModel as EntryModel; |
|
use Statamic\Facades\Entry; |
|
use Statamic\Structures\CollectionTree; |
|
|
|
class TreeSplit extends Command |
|
{ |
|
/** |
|
* The name and signature of the console command. |
|
* |
|
* @var string |
|
*/ |
|
protected $signature = 'tree:split {source} {target}'; |
|
|
|
/** |
|
* The console command description. |
|
* |
|
* @var string |
|
*/ |
|
protected $description = 'Command description'; |
|
|
|
/** |
|
* Create a new command instance. |
|
* |
|
* @return void |
|
*/ |
|
public function __construct() |
|
{ |
|
parent::__construct(); |
|
} |
|
|
|
/** |
|
* Execute the console command. |
|
* |
|
* @return int |
|
*/ |
|
public function handle() |
|
{ |
|
$source = $this->argument('source'); |
|
$collection = Str::before($source, ':'); |
|
$root = Str::after($source, ':'); |
|
$target = $this->argument('target'); |
|
|
|
$source_tree = Collection::findByHandle($collection); |
|
|
|
// Find equivalent $root ids for all locales |
|
$root_ids = EntryModel::where('id', $root) |
|
->orWhere('origin_id', $root) |
|
->get() |
|
->keyBy->id |
|
->map(function ($localised) { |
|
return $localised->site; |
|
}) |
|
->flip(); |
|
|
|
/** |
|
* @var string $locale |
|
* @var CollectionTree $tree |
|
*/ |
|
foreach ($source_tree->structure()->trees() as $locale => $tree) { |
|
$root = $root_ids->get($locale); |
|
|
|
/** |
|
* @var \Statamic\Structures\Page $root_page |
|
*/ |
|
$root_page = $tree->find($root); |
|
|
|
if (! $root_page) { |
|
// Set the original tree to the validated tree to remove any spurious branches |
|
$tree->tree($tree->tree())->save(); |
|
continue; |
|
} |
|
|
|
$this->info("Moving {$root_page->url()} from `{$collection}` collection to `{$target}` collection");; |
|
|
|
$new_branch = collect($tree->tree())->keyBy('entry')->get($root); |
|
|
|
$new_root = [ |
|
[ |
|
'entry' => $root, |
|
], |
|
]; |
|
|
|
$new_branch = $new_branch['children'] ?? []; |
|
|
|
$new_tree_collection = collect(array_merge($new_root, $new_branch)); |
|
|
|
// Change the collection of all the pages |
|
foreach ($new_tree_collection->flatten() as $page_id) { |
|
Entry::find($page_id)->collection($target)->save(); |
|
} |
|
|
|
// Create or load the new tree |
|
/** @var CollectionTree $new_tree */ |
|
$new_tree = Collection::findByHandle($target)->structure()->in($locale) |
|
?? (new CollectionTree()) |
|
->handle($target) |
|
->locale($locale) |
|
->syncOriginal(); |
|
|
|
// Overlay the source page's structure from the current locale to this new structure |
|
$new_tree->tree($new_tree_collection->all()); |
|
|
|
$new_tree->pages()->setParent($root_page); |
|
|
|
try { |
|
$new_tree->save(); |
|
} catch (\ErrorException $e) { |
|
// meh |
|
} |
|
|
|
$tree->remove($root_page); |
|
$tree->save(); |
|
} |
|
|
|
return Command::SUCCESS; |
|
} |
|
} |