* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. * @license GNU General Public License version 3 or later; see LICENSE */ defined('_JEXEC') or die; use Joomla\CMS\Factory; use Joomla\CMS\Installer\InstallerAdapter; use Joomla\Database\DatabaseInterface; class Com_MokoOGInstallerScript { /** * Called after install. * * @param InstallerAdapter $parent Installer adapter * * @return void */ public function install(InstallerAdapter $parent): void { // Be honest about success: don't claim a clean install if the component's // own tables never landed. Fails open (see missingTables) so a query/IO // glitch never fakes a failure. $missing = $this->missingTables(); if (!empty($missing)) { echo '

MokoSuiteOpenGraph component did not install correctly. ' . 'Missing database table(s): ' . htmlspecialchars(implode(', ', $missing), ENT_QUOTES) . '.

'; return; } echo '

MokoSuiteOpenGraph component installed successfully.

'; } /** * Called after update. * * @param InstallerAdapter $parent Installer adapter * * @return void */ public function update(InstallerAdapter $parent): void { $missing = $this->missingTables(); if (!empty($missing)) { echo '

MokoSuiteOpenGraph component did not update correctly. ' . 'Missing database table(s): ' . htmlspecialchars(implode(', ', $missing), ENT_QUOTES) . '.

'; return; } echo '

MokoSuiteOpenGraph component updated successfully.

'; } /** * Verify the component's declared tables actually exist. Reads the shipped * install SQL, extracts every CREATE TABLE #__name, resolves the live prefix, * and checks each against the database's table list (case-insensitive). * * FAILS OPEN: any error (unreadable SQL, query failure) returns [] so a * transient glitch never turns a good install into a false failure. * * @return string[] Prefixed names of any missing tables. */ private function missingTables(): array { try { $sqlFile = JPATH_ADMINISTRATOR . '/components/com_mokoog/sql/install.mysql.sql'; if (!is_file($sqlFile)) { return []; } $sql = (string) file_get_contents($sqlFile); if ($sql === '' || !preg_match_all('/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`"\']?(#__[A-Za-z0-9_]+)/i', $sql, $m)) { return []; } $db = Factory::getContainer()->get(DatabaseInterface::class); $prefix = $db->getPrefix(); $existing = array_map('strtolower', (array) $db->getTableList()); $missing = []; foreach (array_unique($m[1]) as $table) { $real = str_replace('#__', $prefix, $table); if (!in_array(strtolower($real), $existing, true)) { $missing[] = $real; } } return $missing; } catch (\Throwable $e) { // Fail open — never fake a failure on a glitch. return []; } } }