xref: /plugin/ireadit/action/migration.php (revision 85300102eeb4c8e415de0f1ac21287aaee10e4bc)
1*85300102SSzymon Olewniczak<?php
2*85300102SSzymon Olewniczak/**
3*85300102SSzymon Olewniczak * DokuWiki Plugin bez (Action Component)
4*85300102SSzymon Olewniczak *
5*85300102SSzymon Olewniczak */
6*85300102SSzymon Olewniczak
7*85300102SSzymon Olewniczak// must be run within Dokuwiki
8*85300102SSzymon Olewniczak
9*85300102SSzymon Olewniczakif (!defined('DOKU_INC')) die();
10*85300102SSzymon Olewniczak
11*85300102SSzymon Olewniczak/**
12*85300102SSzymon Olewniczak * Class action_plugin_bez_migration
13*85300102SSzymon Olewniczak *
14*85300102SSzymon Olewniczak * Handle migrations that need more than just SQL
15*85300102SSzymon Olewniczak */
16*85300102SSzymon Olewniczakclass action_plugin_ireadit_migration extends DokuWiki_Action_Plugin
17*85300102SSzymon Olewniczak{
18*85300102SSzymon Olewniczak    /**
19*85300102SSzymon Olewniczak     * @inheritDoc
20*85300102SSzymon Olewniczak     */
21*85300102SSzymon Olewniczak    public function register(Doku_Event_Handler $controller)
22*85300102SSzymon Olewniczak    {
23*85300102SSzymon Olewniczak        $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'AFTER', $this, 'handle_migrations');
24*85300102SSzymon Olewniczak    }
25*85300102SSzymon Olewniczak
26*85300102SSzymon Olewniczak    /**
27*85300102SSzymon Olewniczak     * Call our custom migrations when defined
28*85300102SSzymon Olewniczak     *
29*85300102SSzymon Olewniczak     * @param Doku_Event $event
30*85300102SSzymon Olewniczak     * @param $param
31*85300102SSzymon Olewniczak     */
32*85300102SSzymon Olewniczak    public function handle_migrations(Doku_Event $event, $param)
33*85300102SSzymon Olewniczak    {
34*85300102SSzymon Olewniczak        if ($event->data['sqlite']->getAdapter()->getDbname() !== 'ireadit') {
35*85300102SSzymon Olewniczak            return;
36*85300102SSzymon Olewniczak        }
37*85300102SSzymon Olewniczak        $to = $event->data['to'];
38*85300102SSzymon Olewniczak
39*85300102SSzymon Olewniczak        if (is_callable(array($this, "migration$to"))) {
40*85300102SSzymon Olewniczak            $event->result = call_user_func(array($this, "migration$to"), $event->data);
41*85300102SSzymon Olewniczak        }
42*85300102SSzymon Olewniczak    }
43*85300102SSzymon Olewniczak
44*85300102SSzymon Olewniczak    /**
45*85300102SSzymon Olewniczak     * Convenience function to run an INSERT ... ON CONFLICT IGNORE operation
46*85300102SSzymon Olewniczak     *
47*85300102SSzymon Olewniczak     * The function takes a key-value array with the column names in the key and the actual value in the value,
48*85300102SSzymon Olewniczak     * build the appropriate query and executes it.
49*85300102SSzymon Olewniczak     *
50*85300102SSzymon Olewniczak     * @param string $table the table the entry should be saved to (will not be escaped)
51*85300102SSzymon Olewniczak     * @param array $entry A simple key-value pair array (only values will be escaped)
52*85300102SSzymon Olewniczak     * @return bool|SQLiteResult
53*85300102SSzymon Olewniczak     */
54*85300102SSzymon Olewniczak    protected function insertOrIgnore(helper_plugin_sqlite $sqlite, $table, $entry) {
55*85300102SSzymon Olewniczak        $keys = join(',', array_keys($entry));
56*85300102SSzymon Olewniczak        $vals = join(',', array_fill(0,count($entry),'?'));
57*85300102SSzymon Olewniczak
58*85300102SSzymon Olewniczak        $sql = "INSERT OR IGNORE INTO $table ($keys) VALUES ($vals)";
59*85300102SSzymon Olewniczak        return $sqlite->query($sql, array_values($entry));
60*85300102SSzymon Olewniczak    }
61*85300102SSzymon Olewniczak
62*85300102SSzymon Olewniczak    protected function migration1($data)
63*85300102SSzymon Olewniczak    {
64*85300102SSzymon Olewniczak        global $conf;
65*85300102SSzymon Olewniczak        /** @var $auth DokuWiki_Auth_Plugin */
66*85300102SSzymon Olewniczak        global $auth;
67*85300102SSzymon Olewniczak
68*85300102SSzymon Olewniczak        /** @var helper_plugin_sqlite $sqlite */
69*85300102SSzymon Olewniczak        $sqlite = $data['sqlite'];
70*85300102SSzymon Olewniczak        $db = $sqlite->getAdapter()->getDb();
71*85300102SSzymon Olewniczak
72*85300102SSzymon Olewniczak
73*85300102SSzymon Olewniczak        $datadir = $conf['datadir'];
74*85300102SSzymon Olewniczak        if (substr($datadir, -1) != '/') {
75*85300102SSzymon Olewniczak            $datadir .= '/';
76*85300102SSzymon Olewniczak        }
77*85300102SSzymon Olewniczak
78*85300102SSzymon Olewniczak        $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir));
79*85300102SSzymon Olewniczak        $pages = array();
80*85300102SSzymon Olewniczak        foreach ($rii as $file) {
81*85300102SSzymon Olewniczak            if ($file->isDir()){
82*85300102SSzymon Olewniczak                continue;
83*85300102SSzymon Olewniczak            }
84*85300102SSzymon Olewniczak
85*85300102SSzymon Olewniczak            //remove start path and extension
86*85300102SSzymon Olewniczak            $page = substr($file->getPathname(), strlen($datadir), -4);
87*85300102SSzymon Olewniczak            $pages[] = str_replace('/', ':', $page);
88*85300102SSzymon Olewniczak        }
89*85300102SSzymon Olewniczak        $db->beginTransaction();
90*85300102SSzymon Olewniczak
91*85300102SSzymon Olewniczak        foreach ($pages as $page) {
92*85300102SSzymon Olewniczak            //import historic data
93*85300102SSzymon Olewniczak            $meta = p_get_metadata($page, 'plugin_ireadit');
94*85300102SSzymon Olewniczak            if (!$meta) continue;
95*85300102SSzymon Olewniczak            $date = p_get_metadata($page, 'date modified');
96*85300102SSzymon Olewniczak
97*85300102SSzymon Olewniczak            if (isset($meta[$date])) {
98*85300102SSzymon Olewniczak                $meta[0] = $meta[$date];
99*85300102SSzymon Olewniczak                unset($meta[$date]);
100*85300102SSzymon Olewniczak            }
101*85300102SSzymon Olewniczak
102*85300102SSzymon Olewniczak            $current = null;
103*85300102SSzymon Olewniczak            foreach ($meta as $rev => $data) {
104*85300102SSzymon Olewniczak                if ($rev === '' || count($data) == 0) continue;
105*85300102SSzymon Olewniczak                $sqlite->storeEntry('ireadit', array(
106*85300102SSzymon Olewniczak                    'page' => $page,
107*85300102SSzymon Olewniczak                    'rev' => $rev
108*85300102SSzymon Olewniczak                ));
109*85300102SSzymon Olewniczak                $id = $db->lastInsertId();
110*85300102SSzymon Olewniczak                if ($rev === 0) {
111*85300102SSzymon Olewniczak                    $current = $id;
112*85300102SSzymon Olewniczak                }
113*85300102SSzymon Olewniczak                foreach ($data as $user_read) {
114*85300102SSzymon Olewniczak                    $sqlite->storeEntry('ireadit_user', array(
115*85300102SSzymon Olewniczak                        'ireadit_id' => $id,
116*85300102SSzymon Olewniczak                        'user' => $user_read['client'],
117*85300102SSzymon Olewniczak                        'timestamp' => date('c', $user_read['time'])
118*85300102SSzymon Olewniczak                    ));
119*85300102SSzymon Olewniczak                }
120*85300102SSzymon Olewniczak            }
121*85300102SSzymon Olewniczak
122*85300102SSzymon Olewniczak            //import current data
123*85300102SSzymon Olewniczak            $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt');
124*85300102SSzymon Olewniczak            $status = preg_match('/~~IREADIT.*~~/', $content, $matches);
125*85300102SSzymon Olewniczak            //no ireadit on page
126*85300102SSzymon Olewniczak            if ($status !== 1) continue;
127*85300102SSzymon Olewniczak
128*85300102SSzymon Olewniczak            $match = trim(substr($matches[0], strlen('~~IREADIT'), -2));
129*85300102SSzymon Olewniczak            $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY);
130*85300102SSzymon Olewniczak
131*85300102SSzymon Olewniczak            $users = array();
132*85300102SSzymon Olewniczak            $groups = array();
133*85300102SSzymon Olewniczak            foreach ($splits as $split) {
134*85300102SSzymon Olewniczak                if ($split[0] == '@') {
135*85300102SSzymon Olewniczak                    $group = substr($match, 1);
136*85300102SSzymon Olewniczak                    $groups[] = $group;
137*85300102SSzymon Olewniczak                } else {
138*85300102SSzymon Olewniczak                    $users[] = $split;
139*85300102SSzymon Olewniczak                }
140*85300102SSzymon Olewniczak            }
141*85300102SSzymon Olewniczak
142*85300102SSzymon Olewniczak            $usersToInsert = array();
143*85300102SSzymon Olewniczak            if (empty($users) && empty($groups)) {
144*85300102SSzymon Olewniczak                $usersToInsert = $auth->retrieveUsers();
145*85300102SSzymon Olewniczak            } else {
146*85300102SSzymon Olewniczak                $all_users = $auth->retrieveUsers();
147*85300102SSzymon Olewniczak                foreach ($all_users as $user => $info) {
148*85300102SSzymon Olewniczak                    if (in_array($user, $users)) {
149*85300102SSzymon Olewniczak                        $usersToInsert[$user] = $info;
150*85300102SSzymon Olewniczak                    } elseif (array_intersect($groups, $info['grps'])) {
151*85300102SSzymon Olewniczak                        $usersToInsert[$user] = $info;
152*85300102SSzymon Olewniczak                    }
153*85300102SSzymon Olewniczak                }
154*85300102SSzymon Olewniczak            }
155*85300102SSzymon Olewniczak
156*85300102SSzymon Olewniczak            if ($usersToInsert) {
157*85300102SSzymon Olewniczak                if ($current === NULL) {
158*85300102SSzymon Olewniczak                    $sqlite->storeEntry('ireadit', array(
159*85300102SSzymon Olewniczak                        'page' => $page,
160*85300102SSzymon Olewniczak                        'rev' => 0
161*85300102SSzymon Olewniczak                    ));
162*85300102SSzymon Olewniczak                    $current = $db->lastInsertId();
163*85300102SSzymon Olewniczak                }
164*85300102SSzymon Olewniczak                foreach ($usersToInsert as $user => $info) {
165*85300102SSzymon Olewniczak                    $this->insertOrIgnore($sqlite,'ireadit_user', array(
166*85300102SSzymon Olewniczak                        'ireadit_id' => $current,
167*85300102SSzymon Olewniczak                        'user' => $user
168*85300102SSzymon Olewniczak                    ));
169*85300102SSzymon Olewniczak                }
170*85300102SSzymon Olewniczak            }
171*85300102SSzymon Olewniczak
172*85300102SSzymon Olewniczak        }
173*85300102SSzymon Olewniczak        $db->commit();
174*85300102SSzymon Olewniczak
175*85300102SSzymon Olewniczak        return true;
176*85300102SSzymon Olewniczak    }
177*85300102SSzymon Olewniczak}
178