xref: /plugin/structpublish/action/migration.php (revision 677c897aab05e424810827fc196287ad07eb618d)
187106851SAnna Dabrowska<?php
287106851SAnna Dabrowska
387106851SAnna Dabrowskaclass action_plugin_structpublish_migration extends DokuWiki_Action_Plugin
487106851SAnna Dabrowska{
587106851SAnna Dabrowska    /**
687106851SAnna Dabrowska     * @inheritDoc
787106851SAnna Dabrowska     */
887106851SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
987106851SAnna Dabrowska    {
1087106851SAnna Dabrowska        $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handleMigrations');
1187106851SAnna Dabrowska        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations');
1287106851SAnna Dabrowska    }
1387106851SAnna Dabrowska
1487106851SAnna Dabrowska    /**
1587106851SAnna Dabrowska     * Call our custom migrations when defined
1687106851SAnna Dabrowska     *
1787106851SAnna Dabrowska     * @param Doku_Event $event
1887106851SAnna Dabrowska     * @return bool
1987106851SAnna Dabrowska     */
2087106851SAnna Dabrowska    public function handleMigrations(Doku_Event $event)
2187106851SAnna Dabrowska    {
2287106851SAnna Dabrowska        /** @var \helper_plugin_struct_db $helper */
2387106851SAnna Dabrowska        $helper = plugin_load('helper', 'struct_db');
2487106851SAnna Dabrowska        $sqlite = $helper->getDB();
2587106851SAnna Dabrowska
2687106851SAnna Dabrowska        $ok = true;
2787106851SAnna Dabrowska
2887106851SAnna Dabrowska        // check whether we are already up-to-date
2987106851SAnna Dabrowska        list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite);
30e394901aSAnna Dabrowska        if (isset($dbVersionStructpublish) && (string)$dbVersionStructpublish == (string)$dbVersionStruct) {
3187106851SAnna Dabrowska            return $ok;
3287106851SAnna Dabrowska        }
3387106851SAnna Dabrowska
3487106851SAnna Dabrowska        // check whether we have any pending migrations for the current version of struct db
3587106851SAnna Dabrowska        $pending = array_filter(array_map(function ($version) use ($dbVersionStruct) {
3687106851SAnna Dabrowska            return $version >= $dbVersionStruct &&
3787106851SAnna Dabrowska            is_callable([$this, "migration$version"]) ? $version : null;
3887106851SAnna Dabrowska        }, $this->diffVersions($dbVersionStruct, $dbVersionStructpublish)));
3987106851SAnna Dabrowska        if (empty($pending)) {
4087106851SAnna Dabrowska            return $ok;
4187106851SAnna Dabrowska        }
4287106851SAnna Dabrowska
4387106851SAnna Dabrowska        // execute the migrations
4487106851SAnna Dabrowska        foreach ($pending as $version) {
4587106851SAnna Dabrowska            $call = 'migration' . $version;
4687106851SAnna Dabrowska            $ok = $ok && $this->$call($sqlite);
4787106851SAnna Dabrowska        }
4887106851SAnna Dabrowska
4987106851SAnna Dabrowska        return $ok;
5087106851SAnna Dabrowska    }
5187106851SAnna Dabrowska
5287106851SAnna Dabrowska    /**
5387106851SAnna Dabrowska     * Detect which migrations should be executed. Start conservatively with version 1.
5487106851SAnna Dabrowska     *
5587106851SAnna Dabrowska     * @param int $dbVersionStruct Current version of struct DB as found in 'opts' table
5687106851SAnna Dabrowska     * @param int|null $dbVersionStructpublish Current version in 'opts', may not exist yet
5787106851SAnna Dabrowska     * @return int[]
5887106851SAnna Dabrowska     */
5987106851SAnna Dabrowska    protected function diffVersions($dbVersionStruct, $dbVersionStructpublish)
6087106851SAnna Dabrowska    {
6187106851SAnna Dabrowska        $pluginDbVersion = $dbVersionStructpublish ?: 1;
6287106851SAnna Dabrowska        return range($pluginDbVersion, $dbVersionStruct);
6387106851SAnna Dabrowska    }
6487106851SAnna Dabrowska
6587106851SAnna Dabrowska    /**
6687106851SAnna Dabrowska     * @param $sqlite
6787106851SAnna Dabrowska     * @return array
6887106851SAnna Dabrowska     */
6987106851SAnna Dabrowska    protected function getDbVersions($sqlite)
7087106851SAnna Dabrowska    {
7187106851SAnna Dabrowska        $dbVersionStruct = null;
7287106851SAnna Dabrowska        $dbVersionStructpublish = null;
7387106851SAnna Dabrowska
7487106851SAnna Dabrowska        $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?';
7587106851SAnna Dabrowska        $res = $sqlite->query($sql, 'dbversion', 'dbversion_structpublish');
7687106851SAnna Dabrowska        $vals = $sqlite->res2arr($res);
7787106851SAnna Dabrowska
7887106851SAnna Dabrowska        foreach ($vals as $val) {
7987106851SAnna Dabrowska            if ($val['opt'] === 'dbversion') {
8087106851SAnna Dabrowska                $dbVersionStruct = $val['val'];
8187106851SAnna Dabrowska            }
8287106851SAnna Dabrowska            if ($val['opt'] === 'dbversion_structpublish') {
8387106851SAnna Dabrowska                $dbVersionStructpublish = $val['val'];
8487106851SAnna Dabrowska            }
8587106851SAnna Dabrowska        }
8687106851SAnna Dabrowska        return [$dbVersionStruct, $dbVersionStructpublish];
8787106851SAnna Dabrowska    }
8887106851SAnna Dabrowska
8987106851SAnna Dabrowska    /**
9087106851SAnna Dabrowska     * Database setup, required struct db version is 19
9187106851SAnna Dabrowska     *
9287106851SAnna Dabrowska     * @param helper_plugin_sqlite $sqlite
9387106851SAnna Dabrowska     * @return bool
9487106851SAnna Dabrowska     */
9587106851SAnna Dabrowska    protected function migration19($sqlite)
9687106851SAnna Dabrowska    {
9787106851SAnna Dabrowska        $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/struct/update0019.sql', false);
9887106851SAnna Dabrowska
9987106851SAnna Dabrowska        $sql = $sqlite->SQLstring2array($sql);
10087106851SAnna Dabrowska        array_unshift($sql, 'BEGIN TRANSACTION');
10187106851SAnna Dabrowska        array_push($sql, "INSERT OR REPLACE INTO opts (val,opt) VALUES (19,'dbversion_structpublish')");
10287106851SAnna Dabrowska        array_push($sql, "COMMIT TRANSACTION");
103*677c897aSAnna Dabrowska        $ok =  $sqlite->doTransaction($sql);
104*677c897aSAnna Dabrowska
105*677c897aSAnna Dabrowska        if ($ok) {
106*677c897aSAnna Dabrowska            $file = __DIR__ . "../db/json/structpublish_19.struct.json";
107*677c897aSAnna Dabrowska            $schemaJson = file_get_contents($file);
108*677c897aSAnna Dabrowska            $importer = new \dokuwiki\plugin\struct\meta\SchemaImporter('structpublish', $schemaJson);
109*677c897aSAnna Dabrowska            $ok = (bool)$importer->build();
110*677c897aSAnna Dabrowska        }
111*677c897aSAnna Dabrowska
112*677c897aSAnna Dabrowska        return $ok;
11387106851SAnna Dabrowska    }
11487106851SAnna Dabrowska}
115