xref: /plugin/ireadit/action/migration.php (revision d0cab33c70741e3b980d195617fdaa5a25767f97)
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*d0cab33cSSzymon Olewniczak    protected function migration2($data)
63*d0cab33cSSzymon Olewniczak    {
64*d0cab33cSSzymon Olewniczak        global $conf;
65*d0cab33cSSzymon Olewniczak
66*d0cab33cSSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
67*d0cab33cSSzymon Olewniczak        $sqlite = $data['sqlite'];
68*d0cab33cSSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
69*d0cab33cSSzymon Olewniczak
70*d0cab33cSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
71*d0cab33cSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
72*d0cab33cSSzymon Olewniczak
73*d0cab33cSSzymon Olewniczak
74*d0cab33cSSzymon Olewniczak        $datadir = $conf['datadir'];
75*d0cab33cSSzymon Olewniczak        if (substr($datadir, -1) != '/') {
76*d0cab33cSSzymon Olewniczak            $datadir .= '/';
77*d0cab33cSSzymon Olewniczak        }
78*d0cab33cSSzymon Olewniczak
79*d0cab33cSSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
80*d0cab33cSSzymon Olewniczak        $pages = [];
81*d0cab33cSSzymon Olewniczak        foreach ($rii as $file) {
82*d0cab33cSSzymon Olewniczak            if ($file->isDir()){
83*d0cab33cSSzymon Olewniczak                continue;
84*d0cab33cSSzymon Olewniczak            }
85*d0cab33cSSzymon Olewniczak
86*d0cab33cSSzymon Olewniczak            //remove start path and extension
87*d0cab33cSSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
88*d0cab33cSSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
89*d0cab33cSSzymon Olewniczak        }
90*d0cab33cSSzymon Olewniczak
91*d0cab33cSSzymon Olewniczak        $db->beginTransaction();
92*d0cab33cSSzymon Olewniczak
93*d0cab33cSSzymon Olewniczak        foreach ($pages as $page) {
94*d0cab33cSSzymon Olewniczak            //import historic data
95*d0cab33cSSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin ireadit');
96*d0cab33cSSzymon Olewniczak            if (!$meta) continue;
97*d0cab33cSSzymon Olewniczak
98*d0cab33cSSzymon Olewniczak            $sqlite->storeEntry('meta', [
99*d0cab33cSSzymon Olewniczak                'page' => $page,
100*d0cab33cSSzymon Olewniczak                'meta' => json_encode($meta)
101*d0cab33cSSzymon Olewniczak            ]);
102*d0cab33cSSzymon Olewniczak        }
103*d0cab33cSSzymon Olewniczak        $db->commit();
104*d0cab33cSSzymon Olewniczak
105*d0cab33cSSzymon Olewniczak
106*d0cab33cSSzymon Olewniczak    }
107*d0cab33cSSzymon Olewniczak
10885300102SSzymon Olewniczak    protected function migration1($data)
10985300102SSzymon Olewniczak    {
11085300102SSzymon Olewniczak        global $conf;
11185300102SSzymon Olewniczak
11285300102SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
11385300102SSzymon Olewniczak        $sqlite = $data['sqlite'];
11485300102SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
11585300102SSzymon Olewniczak
1167b5bedfeSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
1177b5bedfeSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
1187b5bedfeSSzymon Olewniczak
11985300102SSzymon Olewniczak
12085300102SSzymon Olewniczak        $datadir = $conf['datadir'];
12185300102SSzymon Olewniczak        if (substr($datadir, -1) != '/') {
12285300102SSzymon Olewniczak            $datadir .= '/';
12385300102SSzymon Olewniczak        }
12485300102SSzymon Olewniczak
12585300102SSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
1265d3fb867SSzymon Olewniczak        $pages = [];
12785300102SSzymon Olewniczak        foreach ($rii as $file) {
12885300102SSzymon Olewniczak            if ($file->isDir()){
12985300102SSzymon Olewniczak                continue;
13085300102SSzymon Olewniczak            }
13185300102SSzymon Olewniczak
13285300102SSzymon Olewniczak            //remove start path and extension
13385300102SSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
13485300102SSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
13585300102SSzymon Olewniczak        }
13685300102SSzymon Olewniczak        $db->beginTransaction();
13785300102SSzymon Olewniczak
13885300102SSzymon Olewniczak        foreach ($pages as $page) {
13985300102SSzymon Olewniczak            //import historic data
14085300102SSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin_ireadit');
14185300102SSzymon Olewniczak            if (!$meta) continue;
14285300102SSzymon Olewniczak
14385300102SSzymon Olewniczak            foreach ($meta as $rev => $data) {
14485300102SSzymon Olewniczak                if ($rev === '' || count($data) == 0) continue;
1457b5bedfeSSzymon Olewniczak                foreach ($data as $user_read) {
1465d3fb867SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', [
14785300102SSzymon Olewniczak                        'page' => $page,
1487b5bedfeSSzymon Olewniczak                        'rev' => $rev,
14985300102SSzymon Olewniczak                        'user' => $user_read['client'],
15085300102SSzymon Olewniczak                        'timestamp' => date('c', $user_read['time'])
1515d3fb867SSzymon Olewniczak                    ]);
15285300102SSzymon Olewniczak                }
15385300102SSzymon Olewniczak            }
15485300102SSzymon Olewniczak
15585300102SSzymon Olewniczak            //import current data
15685300102SSzymon Olewniczak            $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt');
15785300102SSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
15885300102SSzymon Olewniczak            //no ireadit on page
15985300102SSzymon Olewniczak            if ($status !== 1) continue;
16085300102SSzymon Olewniczak
16185300102SSzymon Olewniczak            $match = trim(substr($matches[0], strlen('~~IREADIT'), -2));
16285300102SSzymon Olewniczak            $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY);
16385300102SSzymon Olewniczak
1645d3fb867SSzymon Olewniczak            $users = [];
1655d3fb867SSzymon Olewniczak            $groups = [];
16685300102SSzymon Olewniczak            foreach ($splits as $split) {
16785300102SSzymon Olewniczak                if ($split[0] == '@') {
1687b5bedfeSSzymon Olewniczak                    $group = substr($split, 1);
16985300102SSzymon Olewniczak                    $groups[] = $group;
17085300102SSzymon Olewniczak                } else {
17185300102SSzymon Olewniczak                    $users[] = $split;
17285300102SSzymon Olewniczak                }
17385300102SSzymon Olewniczak            }
17485300102SSzymon Olewniczak
1757b5bedfeSSzymon Olewniczak            $usersToInsert = $helper->users_set($users, $groups);
17685300102SSzymon Olewniczak
17785300102SSzymon Olewniczak            if ($usersToInsert) {
1787b5bedfeSSzymon Olewniczak                $last_change_date = p_get_metadata($page, 'last_change date');
17985300102SSzymon Olewniczak                foreach ($usersToInsert as $user => $info) {
1805d3fb867SSzymon Olewniczak                    $this->insertOrIgnore($sqlite,'ireadit', [
1817b5bedfeSSzymon Olewniczak                        'page' => $page,
1827b5bedfeSSzymon Olewniczak                        'rev' => $last_change_date,
18385300102SSzymon Olewniczak                        'user' => $user
1845d3fb867SSzymon Olewniczak                    ]);
18585300102SSzymon Olewniczak                }
18685300102SSzymon Olewniczak            }
18785300102SSzymon Olewniczak
18885300102SSzymon Olewniczak        }
18985300102SSzymon Olewniczak        $db->commit();
19085300102SSzymon Olewniczak
19185300102SSzymon Olewniczak        return true;
19285300102SSzymon Olewniczak    }
19385300102SSzymon Olewniczak}
194