feat: rebuild asset table and nested sets after syncpush

After bulk-inserting content, the target site now:
- Rebuilds category and menu nested set trees (lft/rgt/level)
- Creates #__assets entries for articles and categories (ACL)

Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan Miller
2026-05-31 14:51:27 -05:00
parent 2cb28e0286
commit 97dadce289
@@ -2330,6 +2330,9 @@ class MokoWaaS extends CMSPlugin implements BootableExtensionInterface
return;
}
// Rebuild nested set trees and asset table after insert
$this->repairAfterSync($type);
$this->sendHealthResponse(200, [
'status' => 'ok',
'type' => $type,
@@ -2345,6 +2348,101 @@ class MokoWaaS extends CMSPlugin implements BootableExtensionInterface
}
}
/**
* Repair nested set trees and asset table after a bulk sync push.
*
* Categories and menus use nested sets (lft/rgt/level) which need
* rebuilding after direct DB inserts. Content needs asset entries
* for ACL to work.
*
* @param string $type Content type that was pushed
*
* @return void
*
* @since 02.31.00
*/
private function repairAfterSync(string $type): void
{
try
{
$db = Factory::getDbo();
if ($type === 'categories')
{
// Rebuild the category nested set tree
$table = new \Joomla\CMS\Table\Category($db);
$table->rebuild();
// Ensure asset entries exist for each category
$db->setQuery(
$db->getQuery(true)
->select('id, title, extension')
->from($db->quoteName('#__categories'))
->where($db->quoteName('id') . ' > 1')
->where($db->quoteName('asset_id') . ' = 0')
);
foreach ($db->loadObjectList() as $cat)
{
$asset = new \Joomla\CMS\Table\Asset($db);
$asset->name = $cat->extension . '.category.' . $cat->id;
$asset->title = $cat->title;
$asset->rules = '{}';
// Parent asset = root
$asset->setLocation(1, 'last-child');
$asset->store();
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__categories'))
->set($db->quoteName('asset_id') . ' = ' . (int) $asset->id)
->where($db->quoteName('id') . ' = ' . (int) $cat->id)
)->execute();
}
}
if ($type === 'articles')
{
// Ensure asset entries exist for each article
$db->setQuery(
$db->getQuery(true)
->select('id, title, catid')
->from($db->quoteName('#__content'))
->where($db->quoteName('asset_id') . ' = 0')
);
foreach ($db->loadObjectList() as $article)
{
$asset = new \Joomla\CMS\Table\Asset($db);
$asset->name = 'com_content.article.' . $article->id;
$asset->title = $article->title;
$asset->rules = '{}';
$asset->setLocation(1, 'last-child');
$asset->store();
$db->setQuery(
$db->getQuery(true)
->update($db->quoteName('#__content'))
->set($db->quoteName('asset_id') . ' = ' . (int) $asset->id)
->where($db->quoteName('id') . ' = ' . (int) $article->id)
)->execute();
}
}
if ($type === 'menus')
{
// Rebuild menu nested set tree
$table = new \Joomla\CMS\Table\Menu($db);
$table->rebuild();
}
}
catch (\Throwable $e)
{
Log::add('Asset repair failed for ' . $type . ': ' . $e->getMessage(), Log::WARNING, 'mokowaas');
}
}
/**
* List installed extensions with version, status, and update server info.
*