xref: /plugin/ireadit/action/migration.php (revision ce9be9e9c1ec866d658e8f1bd79fef3f5ed26fc0)
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*ce9be9e9SSzymon Olewniczak    protected function migration3($data)
63*ce9be9e9SSzymon Olewniczak    {
64*ce9be9e9SSzymon Olewniczak        global $conf;
65*ce9be9e9SSzymon Olewniczak
66*ce9be9e9SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
67*ce9be9e9SSzymon Olewniczak        $sqlite = $data['sqlite'];
68*ce9be9e9SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
69*ce9be9e9SSzymon Olewniczak
70*ce9be9e9SSzymon Olewniczak        $res = $sqlite->query('SELECT page,meta FROM meta');
71*ce9be9e9SSzymon Olewniczak        while ($row = $sqlite->res_fetch_assoc($res)) {
72*ce9be9e9SSzymon Olewniczak            $last_change_date = p_get_metadata($row['page'], 'last_change date');
73*ce9be9e9SSzymon Olewniczak            $sqlite->storeEntry('meta2', [
74*ce9be9e9SSzymon Olewniczak                'page' => $row['page'],
75*ce9be9e9SSzymon Olewniczak                'meta' => $row['meta'],
76*ce9be9e9SSzymon Olewniczak                'last_change_date' => $last_change_date
77*ce9be9e9SSzymon Olewniczak            ]);
78*ce9be9e9SSzymon Olewniczak        }
79*ce9be9e9SSzymon Olewniczak        $sqlite->query('DROP TABLE meta');
80*ce9be9e9SSzymon Olewniczak        $sqlite->query('ALTER TABLE meta2 RENAME TO meta');
81*ce9be9e9SSzymon Olewniczak    }
82*ce9be9e9SSzymon Olewniczak
83d0cab33cSSzymon Olewniczak    protected function migration2($data)
84d0cab33cSSzymon Olewniczak    {
85d0cab33cSSzymon Olewniczak        global $conf;
86d0cab33cSSzymon Olewniczak
87d0cab33cSSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
88d0cab33cSSzymon Olewniczak        $sqlite = $data['sqlite'];
89d0cab33cSSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
90d0cab33cSSzymon Olewniczak
91d0cab33cSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
92d0cab33cSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
93d0cab33cSSzymon Olewniczak
94d0cab33cSSzymon Olewniczak
95d0cab33cSSzymon Olewniczak        $datadir = $conf['datadir'];
96d0cab33cSSzymon Olewniczak        if (substr($datadir, -1) != '/') {
97d0cab33cSSzymon Olewniczak            $datadir .= '/';
98d0cab33cSSzymon Olewniczak        }
99d0cab33cSSzymon Olewniczak
100d0cab33cSSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
101d0cab33cSSzymon Olewniczak        $pages = [];
102d0cab33cSSzymon Olewniczak        foreach ($rii as $file) {
103d0cab33cSSzymon Olewniczak            if ($file->isDir()){
104d0cab33cSSzymon Olewniczak                continue;
105d0cab33cSSzymon Olewniczak            }
106d0cab33cSSzymon Olewniczak
107d0cab33cSSzymon Olewniczak            //remove start path and extension
108d0cab33cSSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
109d0cab33cSSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
110d0cab33cSSzymon Olewniczak        }
111d0cab33cSSzymon Olewniczak
112d0cab33cSSzymon Olewniczak        $db->beginTransaction();
113d0cab33cSSzymon Olewniczak
114d0cab33cSSzymon Olewniczak        foreach ($pages as $page) {
115d0cab33cSSzymon Olewniczak            //import historic data
116d0cab33cSSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin ireadit');
117d0cab33cSSzymon Olewniczak            if (!$meta) continue;
118d0cab33cSSzymon Olewniczak
119d0cab33cSSzymon Olewniczak            $sqlite->storeEntry('meta', [
120d0cab33cSSzymon Olewniczak                'page' => $page,
121d0cab33cSSzymon Olewniczak                'meta' => json_encode($meta)
122d0cab33cSSzymon Olewniczak            ]);
123d0cab33cSSzymon Olewniczak        }
124d0cab33cSSzymon Olewniczak        $db->commit();
125d0cab33cSSzymon Olewniczak
126d0cab33cSSzymon Olewniczak
127d0cab33cSSzymon Olewniczak    }
128d0cab33cSSzymon Olewniczak
12985300102SSzymon Olewniczak    protected function migration1($data)
13085300102SSzymon Olewniczak    {
13185300102SSzymon Olewniczak        global $conf;
13285300102SSzymon Olewniczak
13385300102SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
13485300102SSzymon Olewniczak        $sqlite = $data['sqlite'];
13585300102SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
13685300102SSzymon Olewniczak
1377b5bedfeSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
1387b5bedfeSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
1397b5bedfeSSzymon Olewniczak
14085300102SSzymon Olewniczak
14185300102SSzymon Olewniczak        $datadir = $conf['datadir'];
14285300102SSzymon Olewniczak        if (substr($datadir, -1) != '/') {
14385300102SSzymon Olewniczak            $datadir .= '/';
14485300102SSzymon Olewniczak        }
14585300102SSzymon Olewniczak
14685300102SSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
1475d3fb867SSzymon Olewniczak        $pages = [];
14885300102SSzymon Olewniczak        foreach ($rii as $file) {
14985300102SSzymon Olewniczak            if ($file->isDir()){
15085300102SSzymon Olewniczak                continue;
15185300102SSzymon Olewniczak            }
15285300102SSzymon Olewniczak
15385300102SSzymon Olewniczak            //remove start path and extension
15485300102SSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
15585300102SSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
15685300102SSzymon Olewniczak        }
15785300102SSzymon Olewniczak        $db->beginTransaction();
15885300102SSzymon Olewniczak
15985300102SSzymon Olewniczak        foreach ($pages as $page) {
16085300102SSzymon Olewniczak            //import historic data
16185300102SSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin_ireadit');
16285300102SSzymon Olewniczak            if (!$meta) continue;
16385300102SSzymon Olewniczak
16485300102SSzymon Olewniczak            foreach ($meta as $rev => $data) {
16585300102SSzymon Olewniczak                if ($rev === '' || count($data) == 0) continue;
1667b5bedfeSSzymon Olewniczak                foreach ($data as $user_read) {
1675d3fb867SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', [
16885300102SSzymon Olewniczak                        'page' => $page,
1697b5bedfeSSzymon Olewniczak                        'rev' => $rev,
17085300102SSzymon Olewniczak                        'user' => $user_read['client'],
17185300102SSzymon Olewniczak                        'timestamp' => date('c', $user_read['time'])
1725d3fb867SSzymon Olewniczak                    ]);
17385300102SSzymon Olewniczak                }
17485300102SSzymon Olewniczak            }
17585300102SSzymon Olewniczak
17685300102SSzymon Olewniczak            //import current data
17785300102SSzymon Olewniczak            $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt');
17885300102SSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
17985300102SSzymon Olewniczak            //no ireadit on page
18085300102SSzymon Olewniczak            if ($status !== 1) continue;
18185300102SSzymon Olewniczak
18285300102SSzymon Olewniczak            $match = trim(substr($matches[0], strlen('~~IREADIT'), -2));
18385300102SSzymon Olewniczak            $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY);
18485300102SSzymon Olewniczak
1855d3fb867SSzymon Olewniczak            $users = [];
1865d3fb867SSzymon Olewniczak            $groups = [];
18785300102SSzymon Olewniczak            foreach ($splits as $split) {
18885300102SSzymon Olewniczak                if ($split[0] == '@') {
1897b5bedfeSSzymon Olewniczak                    $group = substr($split, 1);
19085300102SSzymon Olewniczak                    $groups[] = $group;
19185300102SSzymon Olewniczak                } else {
19285300102SSzymon Olewniczak                    $users[] = $split;
19385300102SSzymon Olewniczak                }
19485300102SSzymon Olewniczak            }
19585300102SSzymon Olewniczak
1967b5bedfeSSzymon Olewniczak            $usersToInsert = $helper->users_set($users, $groups);
19785300102SSzymon Olewniczak
19885300102SSzymon Olewniczak            if ($usersToInsert) {
1997b5bedfeSSzymon Olewniczak                $last_change_date = p_get_metadata($page, 'last_change date');
20085300102SSzymon Olewniczak                foreach ($usersToInsert as $user => $info) {
2015d3fb867SSzymon Olewniczak                    $this->insertOrIgnore($sqlite,'ireadit', [
2027b5bedfeSSzymon Olewniczak                        'page' => $page,
2037b5bedfeSSzymon Olewniczak                        'rev' => $last_change_date,
20485300102SSzymon Olewniczak                        'user' => $user
2055d3fb867SSzymon Olewniczak                    ]);
20685300102SSzymon Olewniczak                }
20785300102SSzymon Olewniczak            }
20885300102SSzymon Olewniczak
20985300102SSzymon Olewniczak        }
21085300102SSzymon Olewniczak        $db->commit();
21185300102SSzymon Olewniczak
21285300102SSzymon Olewniczak        return true;
21385300102SSzymon Olewniczak    }
21485300102SSzymon Olewniczak}
215