xref: /plugin/structpublish/action/migration.php (revision f734c62f8dcce4b72345d54c58ddabc05ccf5d4f)
187106851SAnna Dabrowska<?php
287106851SAnna Dabrowska
3*f734c62fSAnna Dabrowskause dokuwiki\plugin\sqlite\Tools;
4*f734c62fSAnna Dabrowska
587106851SAnna Dabrowskaclass action_plugin_structpublish_migration extends DokuWiki_Action_Plugin
687106851SAnna Dabrowska{
7bcee0e72SAnna Dabrowska    const MIN_DB_STRUCT = 19;
8bcee0e72SAnna Dabrowska
987106851SAnna Dabrowska    /**
1087106851SAnna Dabrowska     * @inheritDoc
1187106851SAnna Dabrowska     */
1287106851SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
1387106851SAnna Dabrowska    {
1487106851SAnna Dabrowska        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations');
1587106851SAnna Dabrowska    }
1687106851SAnna Dabrowska
1787106851SAnna Dabrowska    /**
1887106851SAnna Dabrowska     * Call our custom migrations when defined
1987106851SAnna Dabrowska     *
2087106851SAnna Dabrowska     * @param Doku_Event $event
2187106851SAnna Dabrowska     * @return bool
228b0ba635SAndreas Gohr     * @throws Exception
2387106851SAnna Dabrowska     */
2487106851SAnna Dabrowska    public function handleMigrations(Doku_Event $event)
2587106851SAnna Dabrowska    {
2687106851SAnna Dabrowska        /** @var \helper_plugin_struct_db $helper */
2787106851SAnna Dabrowska        $helper = plugin_load('helper', 'struct_db');
28bcee0e72SAnna Dabrowska
29bcee0e72SAnna Dabrowska        // abort if struct is not installed
30bcee0e72SAnna Dabrowska        if (!$helper) {
31bcee0e72SAnna Dabrowska            throw new Exception('Plugin struct is required!');
32bcee0e72SAnna Dabrowska        }
33bcee0e72SAnna Dabrowska
3487106851SAnna Dabrowska        $sqlite = $helper->getDB();
3587106851SAnna Dabrowska
3687106851SAnna Dabrowska        list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite);
37bcee0e72SAnna Dabrowska
38bcee0e72SAnna Dabrowska        // check if struct has required version
39bcee0e72SAnna Dabrowska        if ($dbVersionStruct < self::MIN_DB_STRUCT) {
408b0ba635SAndreas Gohr            throw new Exception('Plugin struct is outdated. Minimum required database version is ' . self::MIN_DB_STRUCT);
41bcee0e72SAnna Dabrowska        }
42bcee0e72SAnna Dabrowska
43bcee0e72SAnna Dabrowska        // check whether we are already up-to-date
44bcee0e72SAnna Dabrowska        $latestVersion = $this->getLatestVersion();
45bcee0e72SAnna Dabrowska        if (isset($dbVersionStructpublish) && (int) $dbVersionStructpublish >= $latestVersion) {
468b0ba635SAndreas Gohr            return true;
4787106851SAnna Dabrowska        }
4887106851SAnna Dabrowska
49bcee0e72SAnna Dabrowska        // check whether we have any pending migrations
50bcee0e72SAnna Dabrowska        $pending = range($dbVersionStructpublish ?: 1, $latestVersion);
5187106851SAnna Dabrowska        if (empty($pending)) {
528b0ba635SAndreas Gohr            return true;
5387106851SAnna Dabrowska        }
5487106851SAnna Dabrowska
5587106851SAnna Dabrowska        // execute the migrations
568b0ba635SAndreas Gohr        $ok = true;
5787106851SAnna Dabrowska        foreach ($pending as $version) {
5887106851SAnna Dabrowska            $call = 'migration' . $version;
5987106851SAnna Dabrowska            $ok = $ok && $this->$call($sqlite);
6087106851SAnna Dabrowska        }
6187106851SAnna Dabrowska
6287106851SAnna Dabrowska        return $ok;
6387106851SAnna Dabrowska    }
6487106851SAnna Dabrowska
6587106851SAnna Dabrowska    /**
668b0ba635SAndreas Gohr     * Read the current versions for struct and struct publish from the database
678b0ba635SAndreas Gohr     *
68*f734c62fSAnna Dabrowska     * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite
698b0ba635SAndreas Gohr     * @return array [structversion, structpublishversion]
7087106851SAnna Dabrowska     */
7187106851SAnna Dabrowska    protected function getDbVersions($sqlite)
7287106851SAnna Dabrowska    {
7387106851SAnna Dabrowska        $dbVersionStruct = null;
7487106851SAnna Dabrowska        $dbVersionStructpublish = null;
7587106851SAnna Dabrowska
7687106851SAnna Dabrowska        $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?';
77*f734c62fSAnna Dabrowska        $vals = $sqlite->queryAll($sql, ['dbversion', 'dbversion_structpublish']);
7887106851SAnna Dabrowska
7987106851SAnna Dabrowska        foreach ($vals as $val) {
8087106851SAnna Dabrowska            if ($val['opt'] === 'dbversion') {
8187106851SAnna Dabrowska                $dbVersionStruct = $val['val'];
8287106851SAnna Dabrowska            }
8387106851SAnna Dabrowska            if ($val['opt'] === 'dbversion_structpublish') {
8487106851SAnna Dabrowska                $dbVersionStructpublish = $val['val'];
8587106851SAnna Dabrowska            }
8687106851SAnna Dabrowska        }
8787106851SAnna Dabrowska        return [$dbVersionStruct, $dbVersionStructpublish];
8887106851SAnna Dabrowska    }
8987106851SAnna Dabrowska
9087106851SAnna Dabrowska    /**
91bcee0e72SAnna Dabrowska     * @return int
92bcee0e72SAnna Dabrowska     */
93bcee0e72SAnna Dabrowska    protected function getLatestVersion()
94bcee0e72SAnna Dabrowska    {
95bcee0e72SAnna Dabrowska        return (int) trim(file_get_contents(DOKU_PLUGIN . 'structpublish/db/latest.version', false));
96bcee0e72SAnna Dabrowska    }
97bcee0e72SAnna Dabrowska
98bcee0e72SAnna Dabrowska    /**
99bcee0e72SAnna Dabrowska     * Database setup
10087106851SAnna Dabrowska     *
101*f734c62fSAnna Dabrowska     * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite
10287106851SAnna Dabrowska     * @return bool
10387106851SAnna Dabrowska     */
104bcee0e72SAnna Dabrowska    protected function migration1($sqlite)
10587106851SAnna Dabrowska    {
1067ada453dSAnna Dabrowska        $file = DOKU_PLUGIN . 'structpublish/db/json/structpublish0001.struct.json';
1077ada453dSAnna Dabrowska        $schemaJson = file_get_contents($file);
1087ada453dSAnna Dabrowska        $importer = new \dokuwiki\plugin\struct\meta\SchemaImporter('structpublish', $schemaJson);
1097ada453dSAnna Dabrowska        $ok = (bool) $importer->build();
1107ada453dSAnna Dabrowska
1117ada453dSAnna Dabrowska        if ($ok) {
112bcee0e72SAnna Dabrowska            $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/update0001.sql', false);
113*f734c62fSAnna Dabrowska            $sqlArr = Tools::SQLstring2array($sql);
114*f734c62fSAnna Dabrowska            foreach ($sqlArr as $sql) {
115*f734c62fSAnna Dabrowska                $ok = $ok && $sqlite->query($sql);
116*f734c62fSAnna Dabrowska            }
117*f734c62fSAnna Dabrowska        }
118*f734c62fSAnna Dabrowska        if ($ok) {
119*f734c62fSAnna Dabrowska            $sql = "INSERT OR REPLACE INTO opts (val,opt) VALUES (1,'dbversion_structpublish')";
120*f734c62fSAnna Dabrowska            $ok = $ok && $sqlite->query($sql);
121677c897aSAnna Dabrowska        }
122677c897aSAnna Dabrowska
123677c897aSAnna Dabrowska        return $ok;
12487106851SAnna Dabrowska    }
12587106851SAnna Dabrowska}
126