xref: /plugin/ireadit/action/migration.php (revision 62105ebd375b3bc89d3c622525667ce80554a64e)
185300102SSzymon Olewniczak<?php
285300102SSzymon Olewniczak/**
385300102SSzymon Olewniczak * DokuWiki Plugin bez (Action Component)
485300102SSzymon Olewniczak *
585300102SSzymon Olewniczak */
685300102SSzymon Olewniczak
7fcd65f6aSSzymon Olewniczakuse dokuwiki\Cache\CacheRenderer;
8fcd65f6aSSzymon Olewniczak
985300102SSzymon Olewniczak// must be run within Dokuwiki
1085300102SSzymon Olewniczak
1185300102SSzymon Olewniczakif (!defined('DOKU_INC')) die();
1285300102SSzymon Olewniczak
1385300102SSzymon Olewniczak/**
1485300102SSzymon Olewniczak * Class action_plugin_bez_migration
1585300102SSzymon Olewniczak *
1685300102SSzymon Olewniczak * Handle migrations that need more than just SQL
1785300102SSzymon Olewniczak */
1885300102SSzymon Olewniczakclass action_plugin_ireadit_migration extends DokuWiki_Action_Plugin
1985300102SSzymon Olewniczak{
2085300102SSzymon Olewniczak    /**
2185300102SSzymon Olewniczak     * @inheritDoc
2285300102SSzymon Olewniczak     */
2385300102SSzymon Olewniczak    public function register(Doku_Event_Handler $controller)
2485300102SSzymon Olewniczak    {
2585300102SSzymon Olewniczak        $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'AFTER', $this, 'handle_migrations');
2685300102SSzymon Olewniczak    }
2785300102SSzymon Olewniczak
2885300102SSzymon Olewniczak    /**
2985300102SSzymon Olewniczak     * Call our custom migrations when defined
3085300102SSzymon Olewniczak     *
3185300102SSzymon Olewniczak     * @param Doku_Event $event
3285300102SSzymon Olewniczak     * @param $param
3385300102SSzymon Olewniczak     */
3485300102SSzymon Olewniczak    public function handle_migrations(Doku_Event $event, $param)
3585300102SSzymon Olewniczak    {
3685300102SSzymon Olewniczak        if ($event->data['sqlite']->getAdapter()->getDbname() !== 'ireadit') {
3785300102SSzymon Olewniczak            return;
3885300102SSzymon Olewniczak        }
3985300102SSzymon Olewniczak        $to = $event->data['to'];
4085300102SSzymon Olewniczak
415d3fb867SSzymon Olewniczak        if (is_callable([$this, "migration$to"])) {
425d3fb867SSzymon Olewniczak            $event->result = call_user_func([$this, "migration$to"], $event->data);
4385300102SSzymon Olewniczak        }
4485300102SSzymon Olewniczak    }
4585300102SSzymon Olewniczak
4685300102SSzymon Olewniczak    /**
4785300102SSzymon Olewniczak     * Convenience function to run an INSERT ... ON CONFLICT IGNORE operation
4885300102SSzymon Olewniczak     *
4985300102SSzymon Olewniczak     * The function takes a key-value array with the column names in the key and the actual value in the value,
5085300102SSzymon Olewniczak     * build the appropriate query and executes it.
5185300102SSzymon Olewniczak     *
5285300102SSzymon Olewniczak     * @param string $table the table the entry should be saved to (will not be escaped)
5385300102SSzymon Olewniczak     * @param array $entry A simple key-value pair array (only values will be escaped)
5485300102SSzymon Olewniczak     * @return bool|SQLiteResult
5585300102SSzymon Olewniczak     */
5685300102SSzymon Olewniczak    protected function insertOrIgnore(helper_plugin_sqlite $sqlite, $table, $entry) {
5785300102SSzymon Olewniczak        $keys = join(',', array_keys($entry));
5885300102SSzymon Olewniczak        $vals = join(',', array_fill(0,count($entry),'?'));
5985300102SSzymon Olewniczak
6085300102SSzymon Olewniczak        $sql = "INSERT OR IGNORE INTO $table ($keys) VALUES ($vals)";
6185300102SSzymon Olewniczak        return $sqlite->query($sql, array_values($entry));
6285300102SSzymon Olewniczak    }
6385300102SSzymon Olewniczak
64fcd65f6aSSzymon Olewniczak    protected function migration7($data)
65fcd65f6aSSzymon Olewniczak    {
66fcd65f6aSSzymon Olewniczak        global $conf;
67fcd65f6aSSzymon Olewniczak        $data = array();
68fcd65f6aSSzymon Olewniczak        search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true));
69fcd65f6aSSzymon Olewniczak        foreach($data as $val) {
70fcd65f6aSSzymon Olewniczak            //import current data
71fcd65f6aSSzymon Olewniczak            $wikiFN = wikiFN($val['id']);
72fcd65f6aSSzymon Olewniczak            $content = file_get_contents($wikiFN);
73fcd65f6aSSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
74fcd65f6aSSzymon Olewniczak            // we use ireadit here
75fcd65f6aSSzymon Olewniczak            if ($status === 1) {
76fcd65f6aSSzymon Olewniczak                $cachefile = new CacheRenderer($val['id'], wikiFN($val['id']), 'metadata');
77fcd65f6aSSzymon Olewniczak                $cachefile->removeCache();
78fcd65f6aSSzymon Olewniczak                p_get_metadata($val['id'], 'plugin_ireadit=0.2'); // render metadata
79fcd65f6aSSzymon Olewniczak                idx_addPage($val['id'], false, true); // regenerate index for the plugin
80fcd65f6aSSzymon Olewniczak            }
81fcd65f6aSSzymon Olewniczak        }
82fcd65f6aSSzymon Olewniczak    }
83fcd65f6aSSzymon Olewniczak
848d45c5a6SSzymon Olewniczak    protected function migration5($data)
8558604840SSzymon Olewniczak    {
8658604840SSzymon Olewniczak        /** @var DokuWiki_Auth_Plugin */
8758604840SSzymon Olewniczak        global $auth;
8858604840SSzymon Olewniczak
8958604840SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
9058604840SSzymon Olewniczak        $sqlite = $data['sqlite'];
9158604840SSzymon Olewniczak
9258604840SSzymon Olewniczak        /** @var helper_plugin_ireadit $helper */
9358604840SSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
9458604840SSzymon Olewniczak
958d45c5a6SSzymon Olewniczak        //remove old rows
968d45c5a6SSzymon Olewniczak        $sqlite->query('DELETE FROM ireadit WHERE timestamp IS NULL');
978d45c5a6SSzymon Olewniczak
9858604840SSzymon Olewniczak        $res = $sqlite->query('SELECT page,meta FROM meta');
9958604840SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
10058604840SSzymon Olewniczak            $page = $row['page'];
10158604840SSzymon Olewniczak            $meta = json_decode($row['meta'], true);
102d2cf7c78SSzymon Olewniczak            $user_set = $helper->users_set($meta);
10358604840SSzymon Olewniczak            $last_change_date = p_get_metadata($page, 'last_change date');
10458604840SSzymon Olewniczak
10558604840SSzymon Olewniczak            $users = $auth->retrieveUsers();
10658604840SSzymon Olewniczak            foreach ($users as $user => $info) {
10732c1cbe3SSzymon Olewniczak                $res2 = $sqlite->query('SELECT user FROM ireadit WHERE page=? AND rev=? AND user=?', $page, $last_change_date, $user);
10832c1cbe3SSzymon Olewniczak                $existsAlready = $sqlite->res2single($res2);
109d2cf7c78SSzymon Olewniczak                if (!$existsAlready && in_array($user, $user_set)) {
11058604840SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', [
11158604840SSzymon Olewniczak                        'page' => $page,
11258604840SSzymon Olewniczak                        'rev' => $last_change_date,
11358604840SSzymon Olewniczak                        'user' => $user
11458604840SSzymon Olewniczak                    ]);
11558604840SSzymon Olewniczak                }
11658604840SSzymon Olewniczak            }
11758604840SSzymon Olewniczak        }
11858604840SSzymon Olewniczak    }
11958604840SSzymon Olewniczak
120ce9be9e9SSzymon Olewniczak    protected function migration3($data)
121ce9be9e9SSzymon Olewniczak    {
122ce9be9e9SSzymon Olewniczak        global $conf;
123ce9be9e9SSzymon Olewniczak
124ce9be9e9SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
125ce9be9e9SSzymon Olewniczak        $sqlite = $data['sqlite'];
126ce9be9e9SSzymon Olewniczak
127ce9be9e9SSzymon Olewniczak        $res = $sqlite->query('SELECT page,meta FROM meta');
128ce9be9e9SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
129ce9be9e9SSzymon Olewniczak            $last_change_date = p_get_metadata($row['page'], 'last_change date');
130ce9be9e9SSzymon Olewniczak            $sqlite->storeEntry('meta2', [
131ce9be9e9SSzymon Olewniczak                'page' => $row['page'],
132ce9be9e9SSzymon Olewniczak                'meta' => $row['meta'],
133ce9be9e9SSzymon Olewniczak                'last_change_date' => $last_change_date
134ce9be9e9SSzymon Olewniczak            ]);
135ce9be9e9SSzymon Olewniczak        }
136ce9be9e9SSzymon Olewniczak        $sqlite->query('DROP TABLE meta');
137ce9be9e9SSzymon Olewniczak        $sqlite->query('ALTER TABLE meta2 RENAME TO meta');
138ce9be9e9SSzymon Olewniczak    }
139ce9be9e9SSzymon Olewniczak
140d0cab33cSSzymon Olewniczak    protected function migration2($data)
141d0cab33cSSzymon Olewniczak    {
142d0cab33cSSzymon Olewniczak        global $conf;
143d0cab33cSSzymon Olewniczak
144d0cab33cSSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
145d0cab33cSSzymon Olewniczak        $sqlite = $data['sqlite'];
146*62105ebdSSzymon Olewniczak        $db = $sqlite->getAdapter()->getPdo();
147d0cab33cSSzymon Olewniczak
148d0cab33cSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
149d0cab33cSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
150d0cab33cSSzymon Olewniczak
151d0cab33cSSzymon Olewniczak
152d0cab33cSSzymon Olewniczak        $datadir = $conf['datadir'];
153d0cab33cSSzymon Olewniczak        if (substr($datadir, -1) != '/') {
154d0cab33cSSzymon Olewniczak            $datadir .= '/';
155d0cab33cSSzymon Olewniczak        }
156d0cab33cSSzymon Olewniczak
157d0cab33cSSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
158d0cab33cSSzymon Olewniczak        $pages = [];
159d0cab33cSSzymon Olewniczak        foreach ($rii as $file) {
160d0cab33cSSzymon Olewniczak            if ($file->isDir()){
161d0cab33cSSzymon Olewniczak                continue;
162d0cab33cSSzymon Olewniczak            }
163d0cab33cSSzymon Olewniczak
164d0cab33cSSzymon Olewniczak            //remove start path and extension
165d0cab33cSSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
166d0cab33cSSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
167d0cab33cSSzymon Olewniczak        }
168d0cab33cSSzymon Olewniczak
169d0cab33cSSzymon Olewniczak        $db->beginTransaction();
170d0cab33cSSzymon Olewniczak
171d0cab33cSSzymon Olewniczak        foreach ($pages as $page) {
172d0cab33cSSzymon Olewniczak            //import historic data
173d0cab33cSSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin ireadit');
174d0cab33cSSzymon Olewniczak            if (!$meta) continue;
175d0cab33cSSzymon Olewniczak
176d0cab33cSSzymon Olewniczak            $sqlite->storeEntry('meta', [
177d0cab33cSSzymon Olewniczak                'page' => $page,
178d0cab33cSSzymon Olewniczak                'meta' => json_encode($meta)
179d0cab33cSSzymon Olewniczak            ]);
180d0cab33cSSzymon Olewniczak        }
181d0cab33cSSzymon Olewniczak        $db->commit();
182d0cab33cSSzymon Olewniczak
183d0cab33cSSzymon Olewniczak
184d0cab33cSSzymon Olewniczak    }
185d0cab33cSSzymon Olewniczak
18685300102SSzymon Olewniczak    protected function migration1($data)
18785300102SSzymon Olewniczak    {
18885300102SSzymon Olewniczak        global $conf;
18985300102SSzymon Olewniczak
19085300102SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
19185300102SSzymon Olewniczak        $sqlite = $data['sqlite'];
192*62105ebdSSzymon Olewniczak        $db = $sqlite->getAdapter()->getPdo();
19385300102SSzymon Olewniczak
1947b5bedfeSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
1957b5bedfeSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
1967b5bedfeSSzymon Olewniczak
19785300102SSzymon Olewniczak
19885300102SSzymon Olewniczak        $datadir = $conf['datadir'];
19985300102SSzymon Olewniczak        if (substr($datadir, -1) != '/') {
20085300102SSzymon Olewniczak            $datadir .= '/';
20185300102SSzymon Olewniczak        }
20285300102SSzymon Olewniczak
20385300102SSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
2045d3fb867SSzymon Olewniczak        $pages = [];
20585300102SSzymon Olewniczak        foreach ($rii as $file) {
20685300102SSzymon Olewniczak            if ($file->isDir()){
20785300102SSzymon Olewniczak                continue;
20885300102SSzymon Olewniczak            }
20985300102SSzymon Olewniczak
21085300102SSzymon Olewniczak            //remove start path and extension
21185300102SSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
21285300102SSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
21385300102SSzymon Olewniczak        }
21485300102SSzymon Olewniczak        $db->beginTransaction();
21585300102SSzymon Olewniczak
21685300102SSzymon Olewniczak        foreach ($pages as $page) {
21785300102SSzymon Olewniczak            //import historic data
21885300102SSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin_ireadit');
219fcd65f6aSSzymon Olewniczak            if (!$meta) continue; //no metadata
22085300102SSzymon Olewniczak
22185300102SSzymon Olewniczak            foreach ($meta as $rev => $data) {
22285300102SSzymon Olewniczak                if ($rev === '' || count($data) == 0) continue;
2237b5bedfeSSzymon Olewniczak                foreach ($data as $user_read) {
2245d3fb867SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', [
22585300102SSzymon Olewniczak                        'page' => $page,
2267b5bedfeSSzymon Olewniczak                        'rev' => $rev,
22785300102SSzymon Olewniczak                        'user' => $user_read['client'],
22885300102SSzymon Olewniczak                        'timestamp' => date('c', $user_read['time'])
2295d3fb867SSzymon Olewniczak                    ]);
23085300102SSzymon Olewniczak                }
23185300102SSzymon Olewniczak            }
23285300102SSzymon Olewniczak
23385300102SSzymon Olewniczak            //import current data
23485300102SSzymon Olewniczak            $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt');
23585300102SSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
23685300102SSzymon Olewniczak            //no ireadit on page
23785300102SSzymon Olewniczak            if ($status !== 1) continue;
23885300102SSzymon Olewniczak
23985300102SSzymon Olewniczak            $match = trim(substr($matches[0], strlen('~~IREADIT'), -2));
24085300102SSzymon Olewniczak            $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY);
24185300102SSzymon Olewniczak
2425d3fb867SSzymon Olewniczak            $users = [];
2435d3fb867SSzymon Olewniczak            $groups = [];
24485300102SSzymon Olewniczak            foreach ($splits as $split) {
24585300102SSzymon Olewniczak                if ($split[0] == '@') {
2467b5bedfeSSzymon Olewniczak                    $group = substr($split, 1);
24785300102SSzymon Olewniczak                    $groups[] = $group;
24885300102SSzymon Olewniczak                } else {
24985300102SSzymon Olewniczak                    $users[] = $split;
25085300102SSzymon Olewniczak                }
25185300102SSzymon Olewniczak            }
25285300102SSzymon Olewniczak
2537b5bedfeSSzymon Olewniczak            $usersToInsert = $helper->users_set($users, $groups);
25485300102SSzymon Olewniczak
25585300102SSzymon Olewniczak            if ($usersToInsert) {
2567b5bedfeSSzymon Olewniczak                $last_change_date = p_get_metadata($page, 'last_change date');
257d2cf7c78SSzymon Olewniczak                foreach ($usersToInsert as $user) {
2585d3fb867SSzymon Olewniczak                    $this->insertOrIgnore($sqlite,'ireadit', [
2597b5bedfeSSzymon Olewniczak                        'page' => $page,
2607b5bedfeSSzymon Olewniczak                        'rev' => $last_change_date,
26185300102SSzymon Olewniczak                        'user' => $user
2625d3fb867SSzymon Olewniczak                    ]);
26385300102SSzymon Olewniczak                }
26485300102SSzymon Olewniczak            }
26585300102SSzymon Olewniczak
26685300102SSzymon Olewniczak        }
26785300102SSzymon Olewniczak        $db->commit();
26885300102SSzymon Olewniczak
26985300102SSzymon Olewniczak        return true;
27085300102SSzymon Olewniczak    }
27185300102SSzymon Olewniczak}
272