xref: /plugin/ireadit/action/migration.php (revision 58604840363f7f258228d4d126cb604f32b1df03)
185300102SSzymon Olewniczak<?php
285300102SSzymon Olewniczak/**
385300102SSzymon Olewniczak * DokuWiki Plugin bez (Action Component)
485300102SSzymon Olewniczak *
585300102SSzymon Olewniczak */
685300102SSzymon Olewniczak
785300102SSzymon Olewniczak// must be run within Dokuwiki
885300102SSzymon Olewniczak
985300102SSzymon Olewniczakif (!defined('DOKU_INC')) die();
1085300102SSzymon Olewniczak
1185300102SSzymon Olewniczak/**
1285300102SSzymon Olewniczak * Class action_plugin_bez_migration
1385300102SSzymon Olewniczak *
1485300102SSzymon Olewniczak * Handle migrations that need more than just SQL
1585300102SSzymon Olewniczak */
1685300102SSzymon Olewniczakclass action_plugin_ireadit_migration extends DokuWiki_Action_Plugin
1785300102SSzymon Olewniczak{
1885300102SSzymon Olewniczak    /**
1985300102SSzymon Olewniczak     * @inheritDoc
2085300102SSzymon Olewniczak     */
2185300102SSzymon Olewniczak    public function register(Doku_Event_Handler $controller)
2285300102SSzymon Olewniczak    {
2385300102SSzymon Olewniczak        $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'AFTER', $this, 'handle_migrations');
2485300102SSzymon Olewniczak    }
2585300102SSzymon Olewniczak
2685300102SSzymon Olewniczak    /**
2785300102SSzymon Olewniczak     * Call our custom migrations when defined
2885300102SSzymon Olewniczak     *
2985300102SSzymon Olewniczak     * @param Doku_Event $event
3085300102SSzymon Olewniczak     * @param $param
3185300102SSzymon Olewniczak     */
3285300102SSzymon Olewniczak    public function handle_migrations(Doku_Event $event, $param)
3385300102SSzymon Olewniczak    {
3485300102SSzymon Olewniczak        if ($event->data['sqlite']->getAdapter()->getDbname() !== 'ireadit') {
3585300102SSzymon Olewniczak            return;
3685300102SSzymon Olewniczak        }
3785300102SSzymon Olewniczak        $to = $event->data['to'];
3885300102SSzymon Olewniczak
395d3fb867SSzymon Olewniczak        if (is_callable([$this, "migration$to"])) {
405d3fb867SSzymon Olewniczak            $event->result = call_user_func([$this, "migration$to"], $event->data);
4185300102SSzymon Olewniczak        }
4285300102SSzymon Olewniczak    }
4385300102SSzymon Olewniczak
4485300102SSzymon Olewniczak    /**
4585300102SSzymon Olewniczak     * Convenience function to run an INSERT ... ON CONFLICT IGNORE operation
4685300102SSzymon Olewniczak     *
4785300102SSzymon Olewniczak     * The function takes a key-value array with the column names in the key and the actual value in the value,
4885300102SSzymon Olewniczak     * build the appropriate query and executes it.
4985300102SSzymon Olewniczak     *
5085300102SSzymon Olewniczak     * @param string $table the table the entry should be saved to (will not be escaped)
5185300102SSzymon Olewniczak     * @param array $entry A simple key-value pair array (only values will be escaped)
5285300102SSzymon Olewniczak     * @return bool|SQLiteResult
5385300102SSzymon Olewniczak     */
5485300102SSzymon Olewniczak    protected function insertOrIgnore(helper_plugin_sqlite $sqlite, $table, $entry) {
5585300102SSzymon Olewniczak        $keys = join(',', array_keys($entry));
5685300102SSzymon Olewniczak        $vals = join(',', array_fill(0,count($entry),'?'));
5785300102SSzymon Olewniczak
5885300102SSzymon Olewniczak        $sql = "INSERT OR IGNORE INTO $table ($keys) VALUES ($vals)";
5985300102SSzymon Olewniczak        return $sqlite->query($sql, array_values($entry));
6085300102SSzymon Olewniczak    }
6185300102SSzymon Olewniczak
62*58604840SSzymon Olewniczak    protected function migration4($data)
63*58604840SSzymon Olewniczak    {
64*58604840SSzymon Olewniczak        /** @var DokuWiki_Auth_Plugin */
65*58604840SSzymon Olewniczak        global $auth;
66*58604840SSzymon Olewniczak
67*58604840SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
68*58604840SSzymon Olewniczak        $sqlite = $data['sqlite'];
69*58604840SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
70*58604840SSzymon Olewniczak
71*58604840SSzymon Olewniczak        /** @var helper_plugin_ireadit $helper */
72*58604840SSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
73*58604840SSzymon Olewniczak
74*58604840SSzymon Olewniczak        $res = $sqlite->query('SELECT page,meta FROM meta');
75*58604840SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
76*58604840SSzymon Olewniczak            $page = $row['page'];
77*58604840SSzymon Olewniczak            $meta = json_decode($row['meta'], true);
78*58604840SSzymon Olewniczak            $last_change_date = p_get_metadata($page, 'last_change date');
79*58604840SSzymon Olewniczak
80*58604840SSzymon Olewniczak            $users = $auth->retrieveUsers();
81*58604840SSzymon Olewniczak            foreach ($users as $user => $info) {
82*58604840SSzymon Olewniczak                $res2 = $sqlite->query('SELECT user FROM ireadit WHERE page=? AND rev=? AND user=?', $page, $last_change_date, $user);
83*58604840SSzymon Olewniczak                $existsAlready = $sqlite->res2single($res2);
84*58604840SSzymon Olewniczak                if (!$existsAlready && $helper->in_users_set($user, $meta)) {
85*58604840SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', [
86*58604840SSzymon Olewniczak                        'page' => $page,
87*58604840SSzymon Olewniczak                        'rev' => $last_change_date,
88*58604840SSzymon Olewniczak                        'user' => $user
89*58604840SSzymon Olewniczak                    ]);
90*58604840SSzymon Olewniczak                }
91*58604840SSzymon Olewniczak            }
92*58604840SSzymon Olewniczak        }
93*58604840SSzymon Olewniczak    }
94*58604840SSzymon Olewniczak
95ce9be9e9SSzymon Olewniczak    protected function migration3($data)
96ce9be9e9SSzymon Olewniczak    {
97ce9be9e9SSzymon Olewniczak        global $conf;
98ce9be9e9SSzymon Olewniczak
99ce9be9e9SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
100ce9be9e9SSzymon Olewniczak        $sqlite = $data['sqlite'];
101ce9be9e9SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
102ce9be9e9SSzymon Olewniczak
103ce9be9e9SSzymon Olewniczak        $res = $sqlite->query('SELECT page,meta FROM meta');
104ce9be9e9SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
105ce9be9e9SSzymon Olewniczak            $last_change_date = p_get_metadata($row['page'], 'last_change date');
106ce9be9e9SSzymon Olewniczak            $sqlite->storeEntry('meta2', [
107ce9be9e9SSzymon Olewniczak                'page' => $row['page'],
108ce9be9e9SSzymon Olewniczak                'meta' => $row['meta'],
109ce9be9e9SSzymon Olewniczak                'last_change_date' => $last_change_date
110ce9be9e9SSzymon Olewniczak            ]);
111ce9be9e9SSzymon Olewniczak        }
112ce9be9e9SSzymon Olewniczak        $sqlite->query('DROP TABLE meta');
113ce9be9e9SSzymon Olewniczak        $sqlite->query('ALTER TABLE meta2 RENAME TO meta');
114ce9be9e9SSzymon Olewniczak    }
115ce9be9e9SSzymon Olewniczak
116d0cab33cSSzymon Olewniczak    protected function migration2($data)
117d0cab33cSSzymon Olewniczak    {
118d0cab33cSSzymon Olewniczak        global $conf;
119d0cab33cSSzymon Olewniczak
120d0cab33cSSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
121d0cab33cSSzymon Olewniczak        $sqlite = $data['sqlite'];
122d0cab33cSSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
123d0cab33cSSzymon Olewniczak
124d0cab33cSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
125d0cab33cSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
126d0cab33cSSzymon Olewniczak
127d0cab33cSSzymon Olewniczak
128d0cab33cSSzymon Olewniczak        $datadir = $conf['datadir'];
129d0cab33cSSzymon Olewniczak        if (substr($datadir, -1) != '/') {
130d0cab33cSSzymon Olewniczak            $datadir .= '/';
131d0cab33cSSzymon Olewniczak        }
132d0cab33cSSzymon Olewniczak
133d0cab33cSSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
134d0cab33cSSzymon Olewniczak        $pages = [];
135d0cab33cSSzymon Olewniczak        foreach ($rii as $file) {
136d0cab33cSSzymon Olewniczak            if ($file->isDir()){
137d0cab33cSSzymon Olewniczak                continue;
138d0cab33cSSzymon Olewniczak            }
139d0cab33cSSzymon Olewniczak
140d0cab33cSSzymon Olewniczak            //remove start path and extension
141d0cab33cSSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
142d0cab33cSSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
143d0cab33cSSzymon Olewniczak        }
144d0cab33cSSzymon Olewniczak
145d0cab33cSSzymon Olewniczak        $db->beginTransaction();
146d0cab33cSSzymon Olewniczak
147d0cab33cSSzymon Olewniczak        foreach ($pages as $page) {
148d0cab33cSSzymon Olewniczak            //import historic data
149d0cab33cSSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin ireadit');
150d0cab33cSSzymon Olewniczak            if (!$meta) continue;
151d0cab33cSSzymon Olewniczak
152d0cab33cSSzymon Olewniczak            $sqlite->storeEntry('meta', [
153d0cab33cSSzymon Olewniczak                'page' => $page,
154d0cab33cSSzymon Olewniczak                'meta' => json_encode($meta)
155d0cab33cSSzymon Olewniczak            ]);
156d0cab33cSSzymon Olewniczak        }
157d0cab33cSSzymon Olewniczak        $db->commit();
158d0cab33cSSzymon Olewniczak
159d0cab33cSSzymon Olewniczak
160d0cab33cSSzymon Olewniczak    }
161d0cab33cSSzymon Olewniczak
16285300102SSzymon Olewniczak    protected function migration1($data)
16385300102SSzymon Olewniczak    {
16485300102SSzymon Olewniczak        global $conf;
16585300102SSzymon Olewniczak
16685300102SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
16785300102SSzymon Olewniczak        $sqlite = $data['sqlite'];
16885300102SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
16985300102SSzymon Olewniczak
1707b5bedfeSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
1717b5bedfeSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
1727b5bedfeSSzymon Olewniczak
17385300102SSzymon Olewniczak
17485300102SSzymon Olewniczak        $datadir = $conf['datadir'];
17585300102SSzymon Olewniczak        if (substr($datadir, -1) != '/') {
17685300102SSzymon Olewniczak            $datadir .= '/';
17785300102SSzymon Olewniczak        }
17885300102SSzymon Olewniczak
17985300102SSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
1805d3fb867SSzymon Olewniczak        $pages = [];
18185300102SSzymon Olewniczak        foreach ($rii as $file) {
18285300102SSzymon Olewniczak            if ($file->isDir()){
18385300102SSzymon Olewniczak                continue;
18485300102SSzymon Olewniczak            }
18585300102SSzymon Olewniczak
18685300102SSzymon Olewniczak            //remove start path and extension
18785300102SSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
18885300102SSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
18985300102SSzymon Olewniczak        }
19085300102SSzymon Olewniczak        $db->beginTransaction();
19185300102SSzymon Olewniczak
19285300102SSzymon Olewniczak        foreach ($pages as $page) {
19385300102SSzymon Olewniczak            //import historic data
19485300102SSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin_ireadit');
19585300102SSzymon Olewniczak            if (!$meta) continue;
19685300102SSzymon Olewniczak
19785300102SSzymon Olewniczak            foreach ($meta as $rev => $data) {
19885300102SSzymon Olewniczak                if ($rev === '' || count($data) == 0) continue;
1997b5bedfeSSzymon Olewniczak                foreach ($data as $user_read) {
2005d3fb867SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', [
20185300102SSzymon Olewniczak                        'page' => $page,
2027b5bedfeSSzymon Olewniczak                        'rev' => $rev,
20385300102SSzymon Olewniczak                        'user' => $user_read['client'],
20485300102SSzymon Olewniczak                        'timestamp' => date('c', $user_read['time'])
2055d3fb867SSzymon Olewniczak                    ]);
20685300102SSzymon Olewniczak                }
20785300102SSzymon Olewniczak            }
20885300102SSzymon Olewniczak
20985300102SSzymon Olewniczak            //import current data
21085300102SSzymon Olewniczak            $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt');
21185300102SSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
21285300102SSzymon Olewniczak            //no ireadit on page
21385300102SSzymon Olewniczak            if ($status !== 1) continue;
21485300102SSzymon Olewniczak
21585300102SSzymon Olewniczak            $match = trim(substr($matches[0], strlen('~~IREADIT'), -2));
21685300102SSzymon Olewniczak            $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY);
21785300102SSzymon Olewniczak
2185d3fb867SSzymon Olewniczak            $users = [];
2195d3fb867SSzymon Olewniczak            $groups = [];
22085300102SSzymon Olewniczak            foreach ($splits as $split) {
22185300102SSzymon Olewniczak                if ($split[0] == '@') {
2227b5bedfeSSzymon Olewniczak                    $group = substr($split, 1);
22385300102SSzymon Olewniczak                    $groups[] = $group;
22485300102SSzymon Olewniczak                } else {
22585300102SSzymon Olewniczak                    $users[] = $split;
22685300102SSzymon Olewniczak                }
22785300102SSzymon Olewniczak            }
22885300102SSzymon Olewniczak
2297b5bedfeSSzymon Olewniczak            $usersToInsert = $helper->users_set($users, $groups);
23085300102SSzymon Olewniczak
23185300102SSzymon Olewniczak            if ($usersToInsert) {
2327b5bedfeSSzymon Olewniczak                $last_change_date = p_get_metadata($page, 'last_change date');
23385300102SSzymon Olewniczak                foreach ($usersToInsert as $user => $info) {
2345d3fb867SSzymon Olewniczak                    $this->insertOrIgnore($sqlite,'ireadit', [
2357b5bedfeSSzymon Olewniczak                        'page' => $page,
2367b5bedfeSSzymon Olewniczak                        'rev' => $last_change_date,
23785300102SSzymon Olewniczak                        'user' => $user
2385d3fb867SSzymon Olewniczak                    ]);
23985300102SSzymon Olewniczak                }
24085300102SSzymon Olewniczak            }
24185300102SSzymon Olewniczak
24285300102SSzymon Olewniczak        }
24385300102SSzymon Olewniczak        $db->commit();
24485300102SSzymon Olewniczak
24585300102SSzymon Olewniczak        return true;
24685300102SSzymon Olewniczak    }
24785300102SSzymon Olewniczak}
248