xref: /plugin/ireadit/action/migration.php (revision 7b5bedfed36b5ea7cb81cbeab7903b2328a1935b)
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
3985300102SSzymon Olewniczak        if (is_callable(array($this, "migration$to"))) {
4085300102SSzymon Olewniczak            $event->result = call_user_func(array($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
6285300102SSzymon Olewniczak    protected function migration1($data)
6385300102SSzymon Olewniczak    {
6485300102SSzymon Olewniczak        global $conf;
6585300102SSzymon Olewniczak
6685300102SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
6785300102SSzymon Olewniczak        $sqlite = $data['sqlite'];
6885300102SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
6985300102SSzymon Olewniczak
70*7b5bedfeSSzymon Olewniczak        /* @var \helper_plugin_ireadit $helper */
71*7b5bedfeSSzymon Olewniczak        $helper = plugin_load('helper', 'ireadit');
72*7b5bedfeSSzymon Olewniczak
7385300102SSzymon Olewniczak
7485300102SSzymon Olewniczak        $datadir = $conf['datadir'];
7585300102SSzymon Olewniczak        if (substr($datadir, -1) != '/') {
7685300102SSzymon Olewniczak            $datadir .= '/';
7785300102SSzymon Olewniczak        }
7885300102SSzymon Olewniczak
7985300102SSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
8085300102SSzymon Olewniczak        $pages = array();
8185300102SSzymon Olewniczak        foreach ($rii as $file) {
8285300102SSzymon Olewniczak            if ($file->isDir()){
8385300102SSzymon Olewniczak                continue;
8485300102SSzymon Olewniczak            }
8585300102SSzymon Olewniczak
8685300102SSzymon Olewniczak            //remove start path and extension
8785300102SSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
8885300102SSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
8985300102SSzymon Olewniczak        }
9085300102SSzymon Olewniczak        $db->beginTransaction();
9185300102SSzymon Olewniczak
9285300102SSzymon Olewniczak        foreach ($pages as $page) {
9385300102SSzymon Olewniczak            //import historic data
9485300102SSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin_ireadit');
9585300102SSzymon Olewniczak            if (!$meta) continue;
9685300102SSzymon Olewniczak
9785300102SSzymon Olewniczak            foreach ($meta as $rev => $data) {
9885300102SSzymon Olewniczak                if ($rev === '' || count($data) == 0) continue;
99*7b5bedfeSSzymon Olewniczak                foreach ($data as $user_read) {
10085300102SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', array(
10185300102SSzymon Olewniczak                        'page' => $page,
102*7b5bedfeSSzymon Olewniczak                        'rev' => $rev,
10385300102SSzymon Olewniczak                        'user' => $user_read['client'],
10485300102SSzymon Olewniczak                        'timestamp' => date('c', $user_read['time'])
10585300102SSzymon Olewniczak                    ));
10685300102SSzymon Olewniczak                }
10785300102SSzymon Olewniczak            }
10885300102SSzymon Olewniczak
10985300102SSzymon Olewniczak            //import current data
11085300102SSzymon Olewniczak            $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt');
11185300102SSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
11285300102SSzymon Olewniczak            //no ireadit on page
11385300102SSzymon Olewniczak            if ($status !== 1) continue;
11485300102SSzymon Olewniczak
11585300102SSzymon Olewniczak            $match = trim(substr($matches[0], strlen('~~IREADIT'), -2));
11685300102SSzymon Olewniczak            $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY);
11785300102SSzymon Olewniczak
11885300102SSzymon Olewniczak            $users = array();
11985300102SSzymon Olewniczak            $groups = array();
12085300102SSzymon Olewniczak            foreach ($splits as $split) {
12185300102SSzymon Olewniczak                if ($split[0] == '@') {
122*7b5bedfeSSzymon Olewniczak                    $group = substr($split, 1);
12385300102SSzymon Olewniczak                    $groups[] = $group;
12485300102SSzymon Olewniczak                } else {
12585300102SSzymon Olewniczak                    $users[] = $split;
12685300102SSzymon Olewniczak                }
12785300102SSzymon Olewniczak            }
12885300102SSzymon Olewniczak
129*7b5bedfeSSzymon Olewniczak            $usersToInsert = $helper->users_set($users, $groups);
13085300102SSzymon Olewniczak
13185300102SSzymon Olewniczak            if ($usersToInsert) {
132*7b5bedfeSSzymon Olewniczak                $last_change_date = p_get_metadata($page, 'last_change date');
13385300102SSzymon Olewniczak                foreach ($usersToInsert as $user => $info) {
134*7b5bedfeSSzymon Olewniczak                    $this->insertOrIgnore($sqlite,'ireadit', array(
135*7b5bedfeSSzymon Olewniczak                        'page' => $page,
136*7b5bedfeSSzymon Olewniczak                        'rev' => $last_change_date,
13785300102SSzymon Olewniczak                        'user' => $user
13885300102SSzymon Olewniczak                    ));
13985300102SSzymon Olewniczak                }
14085300102SSzymon Olewniczak            }
14185300102SSzymon Olewniczak
14285300102SSzymon Olewniczak        }
14385300102SSzymon Olewniczak        $db->commit();
14485300102SSzymon Olewniczak
14585300102SSzymon Olewniczak        return true;
14685300102SSzymon Olewniczak    }
14785300102SSzymon Olewniczak}
148