185300102SSzymon Olewniczak<?php 285300102SSzymon Olewniczak/** 385300102SSzymon Olewniczak * DokuWiki Plugin bez (Action Component) 485300102SSzymon Olewniczak * 585300102SSzymon Olewniczak */ 685300102SSzymon Olewniczak 7*fcd65f6aSSzymon Olewniczakuse dokuwiki\Cache\CacheRenderer; 8*fcd65f6aSSzymon Olewniczak 985300102SSzymon Olewniczak// must be run within Dokuwiki 1085300102SSzymon Olewniczak 1185300102SSzymon Olewniczakif (!defined('DOKU_INC')) die(); 1285300102SSzymon Olewniczak 1385300102SSzymon Olewniczak/** 1485300102SSzymon Olewniczak * Class action_plugin_bez_migration 1585300102SSzymon Olewniczak * 1685300102SSzymon Olewniczak * Handle migrations that need more than just SQL 1785300102SSzymon Olewniczak */ 1885300102SSzymon Olewniczakclass action_plugin_ireadit_migration extends DokuWiki_Action_Plugin 1985300102SSzymon Olewniczak{ 2085300102SSzymon Olewniczak /** 2185300102SSzymon Olewniczak * @inheritDoc 2285300102SSzymon Olewniczak */ 2385300102SSzymon Olewniczak public function register(Doku_Event_Handler $controller) 2485300102SSzymon Olewniczak { 2585300102SSzymon Olewniczak $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'AFTER', $this, 'handle_migrations'); 2685300102SSzymon Olewniczak } 2785300102SSzymon Olewniczak 2885300102SSzymon Olewniczak /** 2985300102SSzymon Olewniczak * Call our custom migrations when defined 3085300102SSzymon Olewniczak * 3185300102SSzymon Olewniczak * @param Doku_Event $event 3285300102SSzymon Olewniczak * @param $param 3385300102SSzymon Olewniczak */ 3485300102SSzymon Olewniczak public function handle_migrations(Doku_Event $event, $param) 3585300102SSzymon Olewniczak { 3685300102SSzymon Olewniczak if ($event->data['sqlite']->getAdapter()->getDbname() !== 'ireadit') { 3785300102SSzymon Olewniczak return; 3885300102SSzymon Olewniczak } 3985300102SSzymon Olewniczak $to = $event->data['to']; 4085300102SSzymon Olewniczak 415d3fb867SSzymon Olewniczak if (is_callable([$this, "migration$to"])) { 425d3fb867SSzymon Olewniczak $event->result = call_user_func([$this, "migration$to"], $event->data); 4385300102SSzymon Olewniczak } 4485300102SSzymon Olewniczak } 4585300102SSzymon Olewniczak 4685300102SSzymon Olewniczak /** 4785300102SSzymon Olewniczak * Convenience function to run an INSERT ... ON CONFLICT IGNORE operation 4885300102SSzymon Olewniczak * 4985300102SSzymon Olewniczak * The function takes a key-value array with the column names in the key and the actual value in the value, 5085300102SSzymon Olewniczak * build the appropriate query and executes it. 5185300102SSzymon Olewniczak * 5285300102SSzymon Olewniczak * @param string $table the table the entry should be saved to (will not be escaped) 5385300102SSzymon Olewniczak * @param array $entry A simple key-value pair array (only values will be escaped) 5485300102SSzymon Olewniczak * @return bool|SQLiteResult 5585300102SSzymon Olewniczak */ 5685300102SSzymon Olewniczak protected function insertOrIgnore(helper_plugin_sqlite $sqlite, $table, $entry) { 5785300102SSzymon Olewniczak $keys = join(',', array_keys($entry)); 5885300102SSzymon Olewniczak $vals = join(',', array_fill(0,count($entry),'?')); 5985300102SSzymon Olewniczak 6085300102SSzymon Olewniczak $sql = "INSERT OR IGNORE INTO $table ($keys) VALUES ($vals)"; 6185300102SSzymon Olewniczak return $sqlite->query($sql, array_values($entry)); 6285300102SSzymon Olewniczak } 6385300102SSzymon Olewniczak 64*fcd65f6aSSzymon Olewniczak protected function migration7($data) 65*fcd65f6aSSzymon Olewniczak { 66*fcd65f6aSSzymon Olewniczak global $conf; 67*fcd65f6aSSzymon Olewniczak $data = array(); 68*fcd65f6aSSzymon Olewniczak search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true)); 69*fcd65f6aSSzymon Olewniczak foreach($data as $val) { 70*fcd65f6aSSzymon Olewniczak //import current data 71*fcd65f6aSSzymon Olewniczak $wikiFN = wikiFN($val['id']); 72*fcd65f6aSSzymon Olewniczak $content = file_get_contents($wikiFN); 73*fcd65f6aSSzymon Olewniczak $status = preg_match('/~~IREADIT.*~~/', $content, $matches); 74*fcd65f6aSSzymon Olewniczak // we use ireadit here 75*fcd65f6aSSzymon Olewniczak if ($status === 1) { 76*fcd65f6aSSzymon Olewniczak $cachefile = new CacheRenderer($val['id'], wikiFN($val['id']), 'metadata'); 77*fcd65f6aSSzymon Olewniczak $cachefile->removeCache(); 78*fcd65f6aSSzymon Olewniczak p_get_metadata($val['id'], 'plugin_ireadit=0.2'); // render metadata 79*fcd65f6aSSzymon Olewniczak idx_addPage($val['id'], false, true); // regenerate index for the plugin 80*fcd65f6aSSzymon Olewniczak } 81*fcd65f6aSSzymon Olewniczak } 82*fcd65f6aSSzymon Olewniczak } 83*fcd65f6aSSzymon Olewniczak 848d45c5a6SSzymon Olewniczak protected function migration5($data) 8558604840SSzymon Olewniczak { 8658604840SSzymon Olewniczak /** @var DokuWiki_Auth_Plugin */ 8758604840SSzymon Olewniczak global $auth; 8858604840SSzymon Olewniczak 8958604840SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 9058604840SSzymon Olewniczak $sqlite = $data['sqlite']; 9158604840SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 9258604840SSzymon Olewniczak 9358604840SSzymon Olewniczak /** @var helper_plugin_ireadit $helper */ 9458604840SSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 9558604840SSzymon Olewniczak 968d45c5a6SSzymon Olewniczak //remove old rows 978d45c5a6SSzymon Olewniczak $sqlite->query('DELETE FROM ireadit WHERE timestamp IS NULL'); 988d45c5a6SSzymon Olewniczak 9958604840SSzymon Olewniczak $res = $sqlite->query('SELECT page,meta FROM meta'); 10058604840SSzymon Olewniczak while ($row = $sqlite->res_fetch_assoc($res)) { 10158604840SSzymon Olewniczak $page = $row['page']; 10258604840SSzymon Olewniczak $meta = json_decode($row['meta'], true); 103d2cf7c78SSzymon Olewniczak $user_set = $helper->users_set($meta); 10458604840SSzymon Olewniczak $last_change_date = p_get_metadata($page, 'last_change date'); 10558604840SSzymon Olewniczak 10658604840SSzymon Olewniczak $users = $auth->retrieveUsers(); 10758604840SSzymon Olewniczak foreach ($users as $user => $info) { 10832c1cbe3SSzymon Olewniczak $res2 = $sqlite->query('SELECT user FROM ireadit WHERE page=? AND rev=? AND user=?', $page, $last_change_date, $user); 10932c1cbe3SSzymon Olewniczak $existsAlready = $sqlite->res2single($res2); 110d2cf7c78SSzymon Olewniczak if (!$existsAlready && in_array($user, $user_set)) { 11158604840SSzymon Olewniczak $sqlite->storeEntry('ireadit', [ 11258604840SSzymon Olewniczak 'page' => $page, 11358604840SSzymon Olewniczak 'rev' => $last_change_date, 11458604840SSzymon Olewniczak 'user' => $user 11558604840SSzymon Olewniczak ]); 11658604840SSzymon Olewniczak } 11758604840SSzymon Olewniczak } 11858604840SSzymon Olewniczak } 11958604840SSzymon Olewniczak } 12058604840SSzymon Olewniczak 121ce9be9e9SSzymon Olewniczak protected function migration3($data) 122ce9be9e9SSzymon Olewniczak { 123ce9be9e9SSzymon Olewniczak global $conf; 124ce9be9e9SSzymon Olewniczak 125ce9be9e9SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 126ce9be9e9SSzymon Olewniczak $sqlite = $data['sqlite']; 127ce9be9e9SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 128ce9be9e9SSzymon Olewniczak 129ce9be9e9SSzymon Olewniczak $res = $sqlite->query('SELECT page,meta FROM meta'); 130ce9be9e9SSzymon Olewniczak while ($row = $sqlite->res_fetch_assoc($res)) { 131ce9be9e9SSzymon Olewniczak $last_change_date = p_get_metadata($row['page'], 'last_change date'); 132ce9be9e9SSzymon Olewniczak $sqlite->storeEntry('meta2', [ 133ce9be9e9SSzymon Olewniczak 'page' => $row['page'], 134ce9be9e9SSzymon Olewniczak 'meta' => $row['meta'], 135ce9be9e9SSzymon Olewniczak 'last_change_date' => $last_change_date 136ce9be9e9SSzymon Olewniczak ]); 137ce9be9e9SSzymon Olewniczak } 138ce9be9e9SSzymon Olewniczak $sqlite->query('DROP TABLE meta'); 139ce9be9e9SSzymon Olewniczak $sqlite->query('ALTER TABLE meta2 RENAME TO meta'); 140ce9be9e9SSzymon Olewniczak } 141ce9be9e9SSzymon Olewniczak 142d0cab33cSSzymon Olewniczak protected function migration2($data) 143d0cab33cSSzymon Olewniczak { 144d0cab33cSSzymon Olewniczak global $conf; 145d0cab33cSSzymon Olewniczak 146d0cab33cSSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 147d0cab33cSSzymon Olewniczak $sqlite = $data['sqlite']; 148d0cab33cSSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 149d0cab33cSSzymon Olewniczak 150d0cab33cSSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 151d0cab33cSSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 152d0cab33cSSzymon Olewniczak 153d0cab33cSSzymon Olewniczak 154d0cab33cSSzymon Olewniczak $datadir = $conf['datadir']; 155d0cab33cSSzymon Olewniczak if (substr($datadir, -1) != '/') { 156d0cab33cSSzymon Olewniczak $datadir .= '/'; 157d0cab33cSSzymon Olewniczak } 158d0cab33cSSzymon Olewniczak 159d0cab33cSSzymon Olewniczak $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); 160d0cab33cSSzymon Olewniczak $pages = []; 161d0cab33cSSzymon Olewniczak foreach ($rii as $file) { 162d0cab33cSSzymon Olewniczak if ($file->isDir()){ 163d0cab33cSSzymon Olewniczak continue; 164d0cab33cSSzymon Olewniczak } 165d0cab33cSSzymon Olewniczak 166d0cab33cSSzymon Olewniczak //remove start path and extension 167d0cab33cSSzymon Olewniczak $page = substr($file->getPathname(), strlen($datadir), -4); 168d0cab33cSSzymon Olewniczak $pages[] = str_replace('/', ':', $page); 169d0cab33cSSzymon Olewniczak } 170d0cab33cSSzymon Olewniczak 171d0cab33cSSzymon Olewniczak $db->beginTransaction(); 172d0cab33cSSzymon Olewniczak 173d0cab33cSSzymon Olewniczak foreach ($pages as $page) { 174d0cab33cSSzymon Olewniczak //import historic data 175d0cab33cSSzymon Olewniczak $meta = p_get_metadata($page, 'plugin ireadit'); 176d0cab33cSSzymon Olewniczak if (!$meta) continue; 177d0cab33cSSzymon Olewniczak 178d0cab33cSSzymon Olewniczak $sqlite->storeEntry('meta', [ 179d0cab33cSSzymon Olewniczak 'page' => $page, 180d0cab33cSSzymon Olewniczak 'meta' => json_encode($meta) 181d0cab33cSSzymon Olewniczak ]); 182d0cab33cSSzymon Olewniczak } 183d0cab33cSSzymon Olewniczak $db->commit(); 184d0cab33cSSzymon Olewniczak 185d0cab33cSSzymon Olewniczak 186d0cab33cSSzymon Olewniczak } 187d0cab33cSSzymon Olewniczak 18885300102SSzymon Olewniczak protected function migration1($data) 18985300102SSzymon Olewniczak { 19085300102SSzymon Olewniczak global $conf; 19185300102SSzymon Olewniczak 19285300102SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 19385300102SSzymon Olewniczak $sqlite = $data['sqlite']; 19485300102SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 19585300102SSzymon Olewniczak 1967b5bedfeSSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 1977b5bedfeSSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 1987b5bedfeSSzymon Olewniczak 19985300102SSzymon Olewniczak 20085300102SSzymon Olewniczak $datadir = $conf['datadir']; 20185300102SSzymon Olewniczak if (substr($datadir, -1) != '/') { 20285300102SSzymon Olewniczak $datadir .= '/'; 20385300102SSzymon Olewniczak } 20485300102SSzymon Olewniczak 20585300102SSzymon Olewniczak $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); 2065d3fb867SSzymon Olewniczak $pages = []; 20785300102SSzymon Olewniczak foreach ($rii as $file) { 20885300102SSzymon Olewniczak if ($file->isDir()){ 20985300102SSzymon Olewniczak continue; 21085300102SSzymon Olewniczak } 21185300102SSzymon Olewniczak 21285300102SSzymon Olewniczak //remove start path and extension 21385300102SSzymon Olewniczak $page = substr($file->getPathname(), strlen($datadir), -4); 21485300102SSzymon Olewniczak $pages[] = str_replace('/', ':', $page); 21585300102SSzymon Olewniczak } 21685300102SSzymon Olewniczak $db->beginTransaction(); 21785300102SSzymon Olewniczak 21885300102SSzymon Olewniczak foreach ($pages as $page) { 21985300102SSzymon Olewniczak //import historic data 22085300102SSzymon Olewniczak $meta = p_get_metadata($page, 'plugin_ireadit'); 221*fcd65f6aSSzymon Olewniczak if (!$meta) continue; //no metadata 22285300102SSzymon Olewniczak 22385300102SSzymon Olewniczak foreach ($meta as $rev => $data) { 22485300102SSzymon Olewniczak if ($rev === '' || count($data) == 0) continue; 2257b5bedfeSSzymon Olewniczak foreach ($data as $user_read) { 2265d3fb867SSzymon Olewniczak $sqlite->storeEntry('ireadit', [ 22785300102SSzymon Olewniczak 'page' => $page, 2287b5bedfeSSzymon Olewniczak 'rev' => $rev, 22985300102SSzymon Olewniczak 'user' => $user_read['client'], 23085300102SSzymon Olewniczak 'timestamp' => date('c', $user_read['time']) 2315d3fb867SSzymon Olewniczak ]); 23285300102SSzymon Olewniczak } 23385300102SSzymon Olewniczak } 23485300102SSzymon Olewniczak 23585300102SSzymon Olewniczak //import current data 23685300102SSzymon Olewniczak $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt'); 23785300102SSzymon Olewniczak $status = preg_match('/~~IREADIT.*~~/', $content, $matches); 23885300102SSzymon Olewniczak //no ireadit on page 23985300102SSzymon Olewniczak if ($status !== 1) continue; 24085300102SSzymon Olewniczak 24185300102SSzymon Olewniczak $match = trim(substr($matches[0], strlen('~~IREADIT'), -2)); 24285300102SSzymon Olewniczak $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY); 24385300102SSzymon Olewniczak 2445d3fb867SSzymon Olewniczak $users = []; 2455d3fb867SSzymon Olewniczak $groups = []; 24685300102SSzymon Olewniczak foreach ($splits as $split) { 24785300102SSzymon Olewniczak if ($split[0] == '@') { 2487b5bedfeSSzymon Olewniczak $group = substr($split, 1); 24985300102SSzymon Olewniczak $groups[] = $group; 25085300102SSzymon Olewniczak } else { 25185300102SSzymon Olewniczak $users[] = $split; 25285300102SSzymon Olewniczak } 25385300102SSzymon Olewniczak } 25485300102SSzymon Olewniczak 2557b5bedfeSSzymon Olewniczak $usersToInsert = $helper->users_set($users, $groups); 25685300102SSzymon Olewniczak 25785300102SSzymon Olewniczak if ($usersToInsert) { 2587b5bedfeSSzymon Olewniczak $last_change_date = p_get_metadata($page, 'last_change date'); 259d2cf7c78SSzymon Olewniczak foreach ($usersToInsert as $user) { 2605d3fb867SSzymon Olewniczak $this->insertOrIgnore($sqlite,'ireadit', [ 2617b5bedfeSSzymon Olewniczak 'page' => $page, 2627b5bedfeSSzymon Olewniczak 'rev' => $last_change_date, 26385300102SSzymon Olewniczak 'user' => $user 2645d3fb867SSzymon Olewniczak ]); 26585300102SSzymon Olewniczak } 26685300102SSzymon Olewniczak } 26785300102SSzymon Olewniczak 26885300102SSzymon Olewniczak } 26985300102SSzymon Olewniczak $db->commit(); 27085300102SSzymon Olewniczak 27185300102SSzymon Olewniczak return true; 27285300102SSzymon Olewniczak } 27385300102SSzymon Olewniczak} 274