xref: /plugin/structpublish/action/migration.php (revision 871068513738e2832d0b57dbff724df27f613c49)
1*87106851SAnna Dabrowska<?php
2*87106851SAnna Dabrowska
3*87106851SAnna Dabrowskaclass action_plugin_structpublish_migration extends DokuWiki_Action_Plugin
4*87106851SAnna Dabrowska{
5*87106851SAnna Dabrowska    /**
6*87106851SAnna Dabrowska     * @inheritDoc
7*87106851SAnna Dabrowska     */
8*87106851SAnna Dabrowska    public function register(Doku_Event_Handler $controller)
9*87106851SAnna Dabrowska    {
10*87106851SAnna Dabrowska        $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handleMigrations');
11*87106851SAnna Dabrowska        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations');
12*87106851SAnna Dabrowska    }
13*87106851SAnna Dabrowska
14*87106851SAnna Dabrowska    /**
15*87106851SAnna Dabrowska     * Call our custom migrations when defined
16*87106851SAnna Dabrowska     *
17*87106851SAnna Dabrowska     * @param Doku_Event $event
18*87106851SAnna Dabrowska     * @return bool
19*87106851SAnna Dabrowska     */
20*87106851SAnna Dabrowska    public function handleMigrations(Doku_Event $event)
21*87106851SAnna Dabrowska    {
22*87106851SAnna Dabrowska        /** @var \helper_plugin_struct_db $helper */
23*87106851SAnna Dabrowska        $helper = plugin_load('helper', 'struct_db');
24*87106851SAnna Dabrowska        $sqlite = $helper->getDB();
25*87106851SAnna Dabrowska
26*87106851SAnna Dabrowska        $ok = true;
27*87106851SAnna Dabrowska
28*87106851SAnna Dabrowska        // check whether we are already up-to-date
29*87106851SAnna Dabrowska        list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite);
30*87106851SAnna Dabrowska        if (isset($dbVersionStructpublish) && $dbVersionStructpublish === $dbVersionStruct) {
31*87106851SAnna Dabrowska            return $ok;
32*87106851SAnna Dabrowska        }
33*87106851SAnna Dabrowska
34*87106851SAnna Dabrowska        // check whether we have any pending migrations for the current version of struct db
35*87106851SAnna Dabrowska        $pending = array_filter(array_map(function ($version) use ($dbVersionStruct) {
36*87106851SAnna Dabrowska            return $version >= $dbVersionStruct &&
37*87106851SAnna Dabrowska            is_callable([$this, "migration$version"]) ? $version : null;
38*87106851SAnna Dabrowska        }, $this->diffVersions($dbVersionStruct, $dbVersionStructpublish)));
39*87106851SAnna Dabrowska        if (empty($pending)) {
40*87106851SAnna Dabrowska            return $ok;
41*87106851SAnna Dabrowska        }
42*87106851SAnna Dabrowska
43*87106851SAnna Dabrowska        // execute the migrations
44*87106851SAnna Dabrowska        foreach ($pending as $version) {
45*87106851SAnna Dabrowska            $call = 'migration' . $version;
46*87106851SAnna Dabrowska            $ok = $ok && $this->$call($sqlite);
47*87106851SAnna Dabrowska        }
48*87106851SAnna Dabrowska
49*87106851SAnna Dabrowska        return $ok;
50*87106851SAnna Dabrowska    }
51*87106851SAnna Dabrowska
52*87106851SAnna Dabrowska    /**
53*87106851SAnna Dabrowska     * Detect which migrations should be executed. Start conservatively with version 1.
54*87106851SAnna Dabrowska     *
55*87106851SAnna Dabrowska     * @param int $dbVersionStruct Current version of struct DB as found in 'opts' table
56*87106851SAnna Dabrowska     * @param int|null $dbVersionStructpublish Current version in 'opts', may not exist yet
57*87106851SAnna Dabrowska     * @return int[]
58*87106851SAnna Dabrowska     */
59*87106851SAnna Dabrowska    protected function diffVersions($dbVersionStruct, $dbVersionStructpublish)
60*87106851SAnna Dabrowska    {
61*87106851SAnna Dabrowska        $pluginDbVersion = $dbVersionStructpublish ?: 1;
62*87106851SAnna Dabrowska        return range($pluginDbVersion, $dbVersionStruct);
63*87106851SAnna Dabrowska    }
64*87106851SAnna Dabrowska
65*87106851SAnna Dabrowska    /**
66*87106851SAnna Dabrowska     * @param $sqlite
67*87106851SAnna Dabrowska     * @return array
68*87106851SAnna Dabrowska     */
69*87106851SAnna Dabrowska    protected function getDbVersions($sqlite)
70*87106851SAnna Dabrowska    {
71*87106851SAnna Dabrowska        $dbVersionStruct = null;
72*87106851SAnna Dabrowska        $dbVersionStructpublish = null;
73*87106851SAnna Dabrowska
74*87106851SAnna Dabrowska        $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?';
75*87106851SAnna Dabrowska        $res = $sqlite->query($sql, 'dbversion', 'dbversion_structpublish');
76*87106851SAnna Dabrowska        $vals = $sqlite->res2arr($res);
77*87106851SAnna Dabrowska
78*87106851SAnna Dabrowska        foreach ($vals as $val) {
79*87106851SAnna Dabrowska            if ($val['opt'] === 'dbversion') {
80*87106851SAnna Dabrowska                $dbVersionStruct = $val['val'];
81*87106851SAnna Dabrowska            }
82*87106851SAnna Dabrowska            if ($val['opt'] === 'dbversion_structpublish') {
83*87106851SAnna Dabrowska                $dbVersionStructpublish = $val['val'];
84*87106851SAnna Dabrowska            }
85*87106851SAnna Dabrowska        }
86*87106851SAnna Dabrowska        return [$dbVersionStruct, $dbVersionStructpublish];
87*87106851SAnna Dabrowska    }
88*87106851SAnna Dabrowska
89*87106851SAnna Dabrowska    /**
90*87106851SAnna Dabrowska     * Database setup, required struct db version is 19
91*87106851SAnna Dabrowska     *
92*87106851SAnna Dabrowska     * @param helper_plugin_sqlite $sqlite
93*87106851SAnna Dabrowska     * @param array $schema
94*87106851SAnna Dabrowska     * @return bool
95*87106851SAnna Dabrowska     */
96*87106851SAnna Dabrowska    protected function migration19($sqlite)
97*87106851SAnna Dabrowska    {
98*87106851SAnna Dabrowska        $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/struct/update0019.sql', false);
99*87106851SAnna Dabrowska
100*87106851SAnna Dabrowska        $sql = $sqlite->SQLstring2array($sql);
101*87106851SAnna Dabrowska        array_unshift($sql, 'BEGIN TRANSACTION');
102*87106851SAnna Dabrowska        array_push($sql, "INSERT OR REPLACE INTO opts (val,opt) VALUES (19,'dbversion_structpublish')");
103*87106851SAnna Dabrowska        array_push($sql, "COMMIT TRANSACTION");
104*87106851SAnna Dabrowska        return $sqlite->doTransaction($sql);
105*87106851SAnna Dabrowska    }
106*87106851SAnna Dabrowska}
107