register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'AFTER', $this, 'handle_migrations'); } /** * Call our custom migrations when defined * * @param Doku_Event $event * @param $param */ public function handle_migrations(Doku_Event $event, $param) { if ($event->data['sqlite']->getAdapter()->getDbname() !== 'ireadit') { return; } $to = $event->data['to']; if (is_callable([$this, "migration$to"])) { $event->result = call_user_func([$this, "migration$to"], $event->data); } } /** * Convenience function to run an INSERT ... ON CONFLICT IGNORE operation * * The function takes a key-value array with the column names in the key and the actual value in the value, * build the appropriate query and executes it. * * @param string $table the table the entry should be saved to (will not be escaped) * @param array $entry A simple key-value pair array (only values will be escaped) * @return bool|SQLiteResult */ protected function insertOrIgnore(helper_plugin_sqlite $sqlite, $table, $entry) { $keys = join(',', array_keys($entry)); $vals = join(',', array_fill(0,count($entry),'?')); $sql = "INSERT OR IGNORE INTO $table ($keys) VALUES ($vals)"; return $sqlite->query($sql, array_values($entry)); } protected function migration7($data) { global $conf; $data = array(); search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true)); foreach($data as $val) { //import current data $wikiFN = wikiFN($val['id']); $content = file_get_contents($wikiFN); $status = preg_match('/~~IREADIT.*~~/', $content, $matches); // we use ireadit here if ($status === 1) { $cachefile = new CacheRenderer($val['id'], wikiFN($val['id']), 'metadata'); $cachefile->removeCache(); p_get_metadata($val['id'], 'plugin_ireadit=0.2'); // render metadata idx_addPage($val['id'], false, true); // regenerate index for the plugin } } } protected function migration5($data) { /** @var DokuWiki_Auth_Plugin */ global $auth; /** @var helper_plugin_sqlite $sqlite */ $sqlite = $data['sqlite']; /** @var helper_plugin_ireadit $helper */ $helper = plugin_load('helper', 'ireadit'); //remove old rows $sqlite->query('DELETE FROM ireadit WHERE timestamp IS NULL'); $res = $sqlite->query('SELECT page,meta FROM meta'); while ($row = $sqlite->res_fetch_assoc($res)) { $page = $row['page']; $meta = json_decode($row['meta'], true); $user_set = $helper->users_set($meta); $last_change_date = p_get_metadata($page, 'last_change date'); $users = $auth->retrieveUsers(); foreach ($users as $user => $info) { $res2 = $sqlite->query('SELECT user FROM ireadit WHERE page=? AND rev=? AND user=?', $page, $last_change_date, $user); $existsAlready = $sqlite->res2single($res2); if (!$existsAlready && in_array($user, $user_set)) { $sqlite->storeEntry('ireadit', [ 'page' => $page, 'rev' => $last_change_date, 'user' => $user ]); } } } } protected function migration3($data) { global $conf; /** @var helper_plugin_sqlite $sqlite */ $sqlite = $data['sqlite']; $res = $sqlite->query('SELECT page,meta FROM meta'); while ($row = $sqlite->res_fetch_assoc($res)) { $last_change_date = p_get_metadata($row['page'], 'last_change date'); $sqlite->storeEntry('meta2', [ 'page' => $row['page'], 'meta' => $row['meta'], 'last_change_date' => $last_change_date ]); } $sqlite->query('DROP TABLE meta'); $sqlite->query('ALTER TABLE meta2 RENAME TO meta'); } protected function migration2($data) { global $conf; /** @var helper_plugin_sqlite $sqlite */ $sqlite = $data['sqlite']; $db = $sqlite->getAdapter()->getPdo(); /* @var \helper_plugin_ireadit $helper */ $helper = plugin_load('helper', 'ireadit'); $datadir = $conf['datadir']; if (substr($datadir, -1) != '/') { $datadir .= '/'; } $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); $pages = []; foreach ($rii as $file) { if ($file->isDir()){ continue; } //remove start path and extension $page = substr($file->getPathname(), strlen($datadir), -4); $pages[] = str_replace('/', ':', $page); } $db->beginTransaction(); foreach ($pages as $page) { //import historic data $meta = p_get_metadata($page, 'plugin ireadit'); if (!$meta) continue; $sqlite->storeEntry('meta', [ 'page' => $page, 'meta' => json_encode($meta) ]); } $db->commit(); } protected function migration1($data) { global $conf; /** @var helper_plugin_sqlite $sqlite */ $sqlite = $data['sqlite']; $db = $sqlite->getAdapter()->getPdo(); /* @var \helper_plugin_ireadit $helper */ $helper = plugin_load('helper', 'ireadit'); $datadir = $conf['datadir']; if (substr($datadir, -1) != '/') { $datadir .= '/'; } $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); $pages = []; foreach ($rii as $file) { if ($file->isDir()){ continue; } //remove start path and extension $page = substr($file->getPathname(), strlen($datadir), -4); $pages[] = str_replace('/', ':', $page); } $db->beginTransaction(); foreach ($pages as $page) { //import historic data $meta = p_get_metadata($page, 'plugin_ireadit'); if (!$meta) continue; //no metadata foreach ($meta as $rev => $data) { if ($rev === '' || count($data) == 0) continue; foreach ($data as $user_read) { $sqlite->storeEntry('ireadit', [ 'page' => $page, 'rev' => $rev, 'user' => $user_read['client'], 'timestamp' => date('c', $user_read['time']) ]); } } //import current data $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt'); $status = preg_match('/~~IREADIT.*~~/', $content, $matches); //no ireadit on page if ($status !== 1) continue; $match = trim(substr($matches[0], strlen('~~IREADIT'), -2)); $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY); $users = []; $groups = []; foreach ($splits as $split) { if ($split[0] == '@') { $group = substr($split, 1); $groups[] = $group; } else { $users[] = $split; } } $usersToInsert = $helper->users_set($users, $groups); if ($usersToInsert) { $last_change_date = p_get_metadata($page, 'last_change date'); foreach ($usersToInsert as $user) { $this->insertOrIgnore($sqlite,'ireadit', [ 'page' => $page, 'rev' => $last_change_date, 'user' => $user ]); } } } $db->commit(); return true; } }