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