xref: /plugin/structpublish/action/migration.php (revision b476f81d46066c318f7a5153cbfadaf4262a2998)
1<?php
2
3use dokuwiki\plugin\sqlite\Tools;
4
5class action_plugin_structpublish_migration extends DokuWiki_Action_Plugin
6{
7    const MIN_DB_STRUCT = 19;
8
9    /**
10     * @inheritDoc
11     */
12    public function register(Doku_Event_Handler $controller)
13    {
14        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations');
15    }
16
17    /**
18     * Call our custom migrations when defined
19     *
20     * @param Doku_Event $event
21     * @return bool
22     * @throws Exception
23     */
24    public function handleMigrations(Doku_Event $event)
25    {
26        /** @var \helper_plugin_struct_db $helper */
27        $helper = plugin_load('helper', 'struct_db');
28
29        // abort if struct is not installed
30        if (!$helper) {
31            throw new Exception('Plugin struct is required!');
32        }
33
34        $sqlite = $helper->getDB();
35
36        list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite);
37
38        // check if struct has required version
39        if ($dbVersionStruct < self::MIN_DB_STRUCT) {
40            throw new Exception('Plugin struct is outdated. Minimum required database version is ' . self::MIN_DB_STRUCT);
41        }
42
43        // check whether we are already up-to-date
44        $latestVersion = $this->getLatestVersion();
45        if (isset($dbVersionStructpublish) && (int) $dbVersionStructpublish >= $latestVersion) {
46            return true;
47        }
48
49        // check whether we have any pending migrations
50        $pending = range($dbVersionStructpublish ?: 1, $latestVersion);
51        if (empty($pending)) {
52            return true;
53        }
54
55        // execute the migrations
56        $ok = true;
57        foreach ($pending as $version) {
58            $call = 'migration' . $version;
59            $ok = $ok && $this->$call($sqlite);
60        }
61
62        return $ok;
63    }
64
65    /**
66     * Read the current versions for struct and struct publish from the database
67     *
68     * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite
69     * @return array [structversion, structpublishversion]
70     */
71    protected function getDbVersions($sqlite)
72    {
73        $dbVersionStruct = null;
74        $dbVersionStructpublish = null;
75
76        $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?';
77        $vals = $sqlite->queryAll($sql, ['dbversion', 'dbversion_structpublish']);
78
79        foreach ($vals as $val) {
80            if ($val['opt'] === 'dbversion') {
81                $dbVersionStruct = $val['val'];
82            }
83            if ($val['opt'] === 'dbversion_structpublish') {
84                $dbVersionStructpublish = $val['val'];
85            }
86        }
87        return [$dbVersionStruct, $dbVersionStructpublish];
88    }
89
90    /**
91     * @return int
92     */
93    protected function getLatestVersion()
94    {
95        return (int) trim(file_get_contents(DOKU_PLUGIN . 'structpublish/db/latest.version', false));
96    }
97
98    /**
99     * Database setup
100     *
101     * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite
102     * @return bool
103     */
104    protected function migration1($sqlite)
105    {
106        $file = DOKU_PLUGIN . 'structpublish/db/json/structpublish0001.struct.json';
107        $schemaJson = file_get_contents($file);
108        $importer = new \dokuwiki\plugin\struct\meta\SchemaImporter('structpublish', $schemaJson);
109        $ok = (bool) $importer->build();
110
111        if ($ok) {
112            $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/update0001.sql', false);
113            $sqlArr = Tools::SQLstring2array($sql);
114            foreach ($sqlArr as $sql) {
115                $ok = $ok && $sqlite->query($sql);
116            }
117        }
118        if ($ok) {
119            $sql = "INSERT OR REPLACE INTO opts (val,opt) VALUES (1,'dbversion_structpublish')";
120            $ok = $ok && $sqlite->query($sql);
121        }
122
123        return $ok;
124    }
125}
126