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*58604840SSzymon Olewniczak protected function migration4($data) 63*58604840SSzymon Olewniczak { 64*58604840SSzymon Olewniczak /** @var DokuWiki_Auth_Plugin */ 65*58604840SSzymon Olewniczak global $auth; 66*58604840SSzymon Olewniczak 67*58604840SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 68*58604840SSzymon Olewniczak $sqlite = $data['sqlite']; 69*58604840SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 70*58604840SSzymon Olewniczak 71*58604840SSzymon Olewniczak /** @var helper_plugin_ireadit $helper */ 72*58604840SSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 73*58604840SSzymon Olewniczak 74*58604840SSzymon Olewniczak $res = $sqlite->query('SELECT page,meta FROM meta'); 75*58604840SSzymon Olewniczak while ($row = $sqlite->res_fetch_assoc($res)) { 76*58604840SSzymon Olewniczak $page = $row['page']; 77*58604840SSzymon Olewniczak $meta = json_decode($row['meta'], true); 78*58604840SSzymon Olewniczak $last_change_date = p_get_metadata($page, 'last_change date'); 79*58604840SSzymon Olewniczak 80*58604840SSzymon Olewniczak $users = $auth->retrieveUsers(); 81*58604840SSzymon Olewniczak foreach ($users as $user => $info) { 82*58604840SSzymon Olewniczak $res2 = $sqlite->query('SELECT user FROM ireadit WHERE page=? AND rev=? AND user=?', $page, $last_change_date, $user); 83*58604840SSzymon Olewniczak $existsAlready = $sqlite->res2single($res2); 84*58604840SSzymon Olewniczak if (!$existsAlready && $helper->in_users_set($user, $meta)) { 85*58604840SSzymon Olewniczak $sqlite->storeEntry('ireadit', [ 86*58604840SSzymon Olewniczak 'page' => $page, 87*58604840SSzymon Olewniczak 'rev' => $last_change_date, 88*58604840SSzymon Olewniczak 'user' => $user 89*58604840SSzymon Olewniczak ]); 90*58604840SSzymon Olewniczak } 91*58604840SSzymon Olewniczak } 92*58604840SSzymon Olewniczak } 93*58604840SSzymon Olewniczak } 94*58604840SSzymon Olewniczak 95ce9be9e9SSzymon Olewniczak protected function migration3($data) 96ce9be9e9SSzymon Olewniczak { 97ce9be9e9SSzymon Olewniczak global $conf; 98ce9be9e9SSzymon Olewniczak 99ce9be9e9SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 100ce9be9e9SSzymon Olewniczak $sqlite = $data['sqlite']; 101ce9be9e9SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 102ce9be9e9SSzymon Olewniczak 103ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT page,meta FROM meta'); 104ce9be9e9SSzymon Olewniczak while ($row = $sqlite->res_fetch_assoc($res)) { 105ce9be9e9SSzymon Olewniczak $last_change_date = p_get_metadata($row['page'], 'last_change date'); 106ce9be9e9SSzymon Olewniczak $sqlite->storeEntry('meta2', [ 107ce9be9e9SSzymon Olewniczak 'page' => $row['page'], 108ce9be9e9SSzymon Olewniczak 'meta' => $row['meta'], 109ce9be9e9SSzymon Olewniczak 'last_change_date' => $last_change_date 110ce9be9e9SSzymon Olewniczak ]); 111ce9be9e9SSzymon Olewniczak } 112ce9be9e9SSzymon Olewniczak $sqlite->query('DROP TABLE meta'); 113ce9be9e9SSzymon Olewniczak $sqlite->query('ALTER TABLE meta2 RENAME TO meta'); 114ce9be9e9SSzymon Olewniczak } 115ce9be9e9SSzymon Olewniczak 116d0cab33cSSzymon Olewniczak protected function migration2($data) 117d0cab33cSSzymon Olewniczak { 118d0cab33cSSzymon Olewniczak global $conf; 119d0cab33cSSzymon Olewniczak 120d0cab33cSSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 121d0cab33cSSzymon Olewniczak $sqlite = $data['sqlite']; 122d0cab33cSSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 123d0cab33cSSzymon Olewniczak 124d0cab33cSSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 125d0cab33cSSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 126d0cab33cSSzymon Olewniczak 127d0cab33cSSzymon Olewniczak 128d0cab33cSSzymon Olewniczak $datadir = $conf['datadir']; 129d0cab33cSSzymon Olewniczak if (substr($datadir, -1) != '/') { 130d0cab33cSSzymon Olewniczak $datadir .= '/'; 131d0cab33cSSzymon Olewniczak } 132d0cab33cSSzymon Olewniczak 133d0cab33cSSzymon Olewniczak $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); 134d0cab33cSSzymon Olewniczak $pages = []; 135d0cab33cSSzymon Olewniczak foreach ($rii as $file) { 136d0cab33cSSzymon Olewniczak if ($file->isDir()){ 137d0cab33cSSzymon Olewniczak continue; 138d0cab33cSSzymon Olewniczak } 139d0cab33cSSzymon Olewniczak 140d0cab33cSSzymon Olewniczak //remove start path and extension 141d0cab33cSSzymon Olewniczak $page = substr($file->getPathname(), strlen($datadir), -4); 142d0cab33cSSzymon Olewniczak $pages[] = str_replace('/', ':', $page); 143d0cab33cSSzymon Olewniczak } 144d0cab33cSSzymon Olewniczak 145d0cab33cSSzymon Olewniczak $db->beginTransaction(); 146d0cab33cSSzymon Olewniczak 147d0cab33cSSzymon Olewniczak foreach ($pages as $page) { 148d0cab33cSSzymon Olewniczak //import historic data 149d0cab33cSSzymon Olewniczak $meta = p_get_metadata($page, 'plugin ireadit'); 150d0cab33cSSzymon Olewniczak if (!$meta) continue; 151d0cab33cSSzymon Olewniczak 152d0cab33cSSzymon Olewniczak $sqlite->storeEntry('meta', [ 153d0cab33cSSzymon Olewniczak 'page' => $page, 154d0cab33cSSzymon Olewniczak 'meta' => json_encode($meta) 155d0cab33cSSzymon Olewniczak ]); 156d0cab33cSSzymon Olewniczak } 157d0cab33cSSzymon Olewniczak $db->commit(); 158d0cab33cSSzymon Olewniczak 159d0cab33cSSzymon Olewniczak 160d0cab33cSSzymon Olewniczak } 161d0cab33cSSzymon Olewniczak 16285300102SSzymon Olewniczak protected function migration1($data) 16385300102SSzymon Olewniczak { 16485300102SSzymon Olewniczak global $conf; 16585300102SSzymon Olewniczak 16685300102SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 16785300102SSzymon Olewniczak $sqlite = $data['sqlite']; 16885300102SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 16985300102SSzymon Olewniczak 1707b5bedfeSSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 1717b5bedfeSSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 1727b5bedfeSSzymon Olewniczak 17385300102SSzymon Olewniczak 17485300102SSzymon Olewniczak $datadir = $conf['datadir']; 17585300102SSzymon Olewniczak if (substr($datadir, -1) != '/') { 17685300102SSzymon Olewniczak $datadir .= '/'; 17785300102SSzymon Olewniczak } 17885300102SSzymon Olewniczak 17985300102SSzymon Olewniczak $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); 1805d3fb867SSzymon Olewniczak $pages = []; 18185300102SSzymon Olewniczak foreach ($rii as $file) { 18285300102SSzymon Olewniczak if ($file->isDir()){ 18385300102SSzymon Olewniczak continue; 18485300102SSzymon Olewniczak } 18585300102SSzymon Olewniczak 18685300102SSzymon Olewniczak //remove start path and extension 18785300102SSzymon Olewniczak $page = substr($file->getPathname(), strlen($datadir), -4); 18885300102SSzymon Olewniczak $pages[] = str_replace('/', ':', $page); 18985300102SSzymon Olewniczak } 19085300102SSzymon Olewniczak $db->beginTransaction(); 19185300102SSzymon Olewniczak 19285300102SSzymon Olewniczak foreach ($pages as $page) { 19385300102SSzymon Olewniczak //import historic data 19485300102SSzymon Olewniczak $meta = p_get_metadata($page, 'plugin_ireadit'); 19585300102SSzymon Olewniczak if (!$meta) continue; 19685300102SSzymon Olewniczak 19785300102SSzymon Olewniczak foreach ($meta as $rev => $data) { 19885300102SSzymon Olewniczak if ($rev === '' || count($data) == 0) continue; 1997b5bedfeSSzymon Olewniczak foreach ($data as $user_read) { 2005d3fb867SSzymon Olewniczak $sqlite->storeEntry('ireadit', [ 20185300102SSzymon Olewniczak 'page' => $page, 2027b5bedfeSSzymon Olewniczak 'rev' => $rev, 20385300102SSzymon Olewniczak 'user' => $user_read['client'], 20485300102SSzymon Olewniczak 'timestamp' => date('c', $user_read['time']) 2055d3fb867SSzymon Olewniczak ]); 20685300102SSzymon Olewniczak } 20785300102SSzymon Olewniczak } 20885300102SSzymon Olewniczak 20985300102SSzymon Olewniczak //import current data 21085300102SSzymon Olewniczak $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt'); 21185300102SSzymon Olewniczak $status = preg_match('/~~IREADIT.*~~/', $content, $matches); 21285300102SSzymon Olewniczak //no ireadit on page 21385300102SSzymon Olewniczak if ($status !== 1) continue; 21485300102SSzymon Olewniczak 21585300102SSzymon Olewniczak $match = trim(substr($matches[0], strlen('~~IREADIT'), -2)); 21685300102SSzymon Olewniczak $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY); 21785300102SSzymon Olewniczak 2185d3fb867SSzymon Olewniczak $users = []; 2195d3fb867SSzymon Olewniczak $groups = []; 22085300102SSzymon Olewniczak foreach ($splits as $split) { 22185300102SSzymon Olewniczak if ($split[0] == '@') { 2227b5bedfeSSzymon Olewniczak $group = substr($split, 1); 22385300102SSzymon Olewniczak $groups[] = $group; 22485300102SSzymon Olewniczak } else { 22585300102SSzymon Olewniczak $users[] = $split; 22685300102SSzymon Olewniczak } 22785300102SSzymon Olewniczak } 22885300102SSzymon Olewniczak 2297b5bedfeSSzymon Olewniczak $usersToInsert = $helper->users_set($users, $groups); 23085300102SSzymon Olewniczak 23185300102SSzymon Olewniczak if ($usersToInsert) { 2327b5bedfeSSzymon Olewniczak $last_change_date = p_get_metadata($page, 'last_change date'); 23385300102SSzymon Olewniczak foreach ($usersToInsert as $user => $info) { 2345d3fb867SSzymon Olewniczak $this->insertOrIgnore($sqlite,'ireadit', [ 2357b5bedfeSSzymon Olewniczak 'page' => $page, 2367b5bedfeSSzymon Olewniczak 'rev' => $last_change_date, 23785300102SSzymon Olewniczak 'user' => $user 2385d3fb867SSzymon Olewniczak ]); 23985300102SSzymon Olewniczak } 24085300102SSzymon Olewniczak } 24185300102SSzymon Olewniczak 24285300102SSzymon Olewniczak } 24385300102SSzymon Olewniczak $db->commit(); 24485300102SSzymon Olewniczak 24585300102SSzymon Olewniczak return true; 24685300102SSzymon Olewniczak } 24785300102SSzymon Olewniczak} 248