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*d0cab33cSSzymon Olewniczak protected function migration2($data) 63*d0cab33cSSzymon Olewniczak { 64*d0cab33cSSzymon Olewniczak global $conf; 65*d0cab33cSSzymon Olewniczak 66*d0cab33cSSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 67*d0cab33cSSzymon Olewniczak $sqlite = $data['sqlite']; 68*d0cab33cSSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 69*d0cab33cSSzymon Olewniczak 70*d0cab33cSSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 71*d0cab33cSSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 72*d0cab33cSSzymon Olewniczak 73*d0cab33cSSzymon Olewniczak 74*d0cab33cSSzymon Olewniczak $datadir = $conf['datadir']; 75*d0cab33cSSzymon Olewniczak if (substr($datadir, -1) != '/') { 76*d0cab33cSSzymon Olewniczak $datadir .= '/'; 77*d0cab33cSSzymon Olewniczak } 78*d0cab33cSSzymon Olewniczak 79*d0cab33cSSzymon Olewniczak $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); 80*d0cab33cSSzymon Olewniczak $pages = []; 81*d0cab33cSSzymon Olewniczak foreach ($rii as $file) { 82*d0cab33cSSzymon Olewniczak if ($file->isDir()){ 83*d0cab33cSSzymon Olewniczak continue; 84*d0cab33cSSzymon Olewniczak } 85*d0cab33cSSzymon Olewniczak 86*d0cab33cSSzymon Olewniczak //remove start path and extension 87*d0cab33cSSzymon Olewniczak $page = substr($file->getPathname(), strlen($datadir), -4); 88*d0cab33cSSzymon Olewniczak $pages[] = str_replace('/', ':', $page); 89*d0cab33cSSzymon Olewniczak } 90*d0cab33cSSzymon Olewniczak 91*d0cab33cSSzymon Olewniczak $db->beginTransaction(); 92*d0cab33cSSzymon Olewniczak 93*d0cab33cSSzymon Olewniczak foreach ($pages as $page) { 94*d0cab33cSSzymon Olewniczak //import historic data 95*d0cab33cSSzymon Olewniczak $meta = p_get_metadata($page, 'plugin ireadit'); 96*d0cab33cSSzymon Olewniczak if (!$meta) continue; 97*d0cab33cSSzymon Olewniczak 98*d0cab33cSSzymon Olewniczak $sqlite->storeEntry('meta', [ 99*d0cab33cSSzymon Olewniczak 'page' => $page, 100*d0cab33cSSzymon Olewniczak 'meta' => json_encode($meta) 101*d0cab33cSSzymon Olewniczak ]); 102*d0cab33cSSzymon Olewniczak } 103*d0cab33cSSzymon Olewniczak $db->commit(); 104*d0cab33cSSzymon Olewniczak 105*d0cab33cSSzymon Olewniczak 106*d0cab33cSSzymon Olewniczak } 107*d0cab33cSSzymon Olewniczak 10885300102SSzymon Olewniczak protected function migration1($data) 10985300102SSzymon Olewniczak { 11085300102SSzymon Olewniczak global $conf; 11185300102SSzymon Olewniczak 11285300102SSzymon Olewniczak /** @var helper_plugin_sqlite $sqlite */ 11385300102SSzymon Olewniczak $sqlite = $data['sqlite']; 11485300102SSzymon Olewniczak $db = $sqlite->getAdapter()->getDb(); 11585300102SSzymon Olewniczak 1167b5bedfeSSzymon Olewniczak /* @var \helper_plugin_ireadit $helper */ 1177b5bedfeSSzymon Olewniczak $helper = plugin_load('helper', 'ireadit'); 1187b5bedfeSSzymon Olewniczak 11985300102SSzymon Olewniczak 12085300102SSzymon Olewniczak $datadir = $conf['datadir']; 12185300102SSzymon Olewniczak if (substr($datadir, -1) != '/') { 12285300102SSzymon Olewniczak $datadir .= '/'; 12385300102SSzymon Olewniczak } 12485300102SSzymon Olewniczak 12585300102SSzymon Olewniczak $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($datadir)); 1265d3fb867SSzymon Olewniczak $pages = []; 12785300102SSzymon Olewniczak foreach ($rii as $file) { 12885300102SSzymon Olewniczak if ($file->isDir()){ 12985300102SSzymon Olewniczak continue; 13085300102SSzymon Olewniczak } 13185300102SSzymon Olewniczak 13285300102SSzymon Olewniczak //remove start path and extension 13385300102SSzymon Olewniczak $page = substr($file->getPathname(), strlen($datadir), -4); 13485300102SSzymon Olewniczak $pages[] = str_replace('/', ':', $page); 13585300102SSzymon Olewniczak } 13685300102SSzymon Olewniczak $db->beginTransaction(); 13785300102SSzymon Olewniczak 13885300102SSzymon Olewniczak foreach ($pages as $page) { 13985300102SSzymon Olewniczak //import historic data 14085300102SSzymon Olewniczak $meta = p_get_metadata($page, 'plugin_ireadit'); 14185300102SSzymon Olewniczak if (!$meta) continue; 14285300102SSzymon Olewniczak 14385300102SSzymon Olewniczak foreach ($meta as $rev => $data) { 14485300102SSzymon Olewniczak if ($rev === '' || count($data) == 0) continue; 1457b5bedfeSSzymon Olewniczak foreach ($data as $user_read) { 1465d3fb867SSzymon Olewniczak $sqlite->storeEntry('ireadit', [ 14785300102SSzymon Olewniczak 'page' => $page, 1487b5bedfeSSzymon Olewniczak 'rev' => $rev, 14985300102SSzymon Olewniczak 'user' => $user_read['client'], 15085300102SSzymon Olewniczak 'timestamp' => date('c', $user_read['time']) 1515d3fb867SSzymon Olewniczak ]); 15285300102SSzymon Olewniczak } 15385300102SSzymon Olewniczak } 15485300102SSzymon Olewniczak 15585300102SSzymon Olewniczak //import current data 15685300102SSzymon Olewniczak $content = file_get_contents($datadir . str_replace(':', '/', $page) . '.txt'); 15785300102SSzymon Olewniczak $status = preg_match('/~~IREADIT.*~~/', $content, $matches); 15885300102SSzymon Olewniczak //no ireadit on page 15985300102SSzymon Olewniczak if ($status !== 1) continue; 16085300102SSzymon Olewniczak 16185300102SSzymon Olewniczak $match = trim(substr($matches[0], strlen('~~IREADIT'), -2)); 16285300102SSzymon Olewniczak $splits = preg_split('/\s+/', $match, -1, PREG_SPLIT_NO_EMPTY); 16385300102SSzymon Olewniczak 1645d3fb867SSzymon Olewniczak $users = []; 1655d3fb867SSzymon Olewniczak $groups = []; 16685300102SSzymon Olewniczak foreach ($splits as $split) { 16785300102SSzymon Olewniczak if ($split[0] == '@') { 1687b5bedfeSSzymon Olewniczak $group = substr($split, 1); 16985300102SSzymon Olewniczak $groups[] = $group; 17085300102SSzymon Olewniczak } else { 17185300102SSzymon Olewniczak $users[] = $split; 17285300102SSzymon Olewniczak } 17385300102SSzymon Olewniczak } 17485300102SSzymon Olewniczak 1757b5bedfeSSzymon Olewniczak $usersToInsert = $helper->users_set($users, $groups); 17685300102SSzymon Olewniczak 17785300102SSzymon Olewniczak if ($usersToInsert) { 1787b5bedfeSSzymon Olewniczak $last_change_date = p_get_metadata($page, 'last_change date'); 17985300102SSzymon Olewniczak foreach ($usersToInsert as $user => $info) { 1805d3fb867SSzymon Olewniczak $this->insertOrIgnore($sqlite,'ireadit', [ 1817b5bedfeSSzymon Olewniczak 'page' => $page, 1827b5bedfeSSzymon Olewniczak 'rev' => $last_change_date, 18385300102SSzymon Olewniczak 'user' => $user 1845d3fb867SSzymon Olewniczak ]); 18585300102SSzymon Olewniczak } 18685300102SSzymon Olewniczak } 18785300102SSzymon Olewniczak 18885300102SSzymon Olewniczak } 18985300102SSzymon Olewniczak $db->commit(); 19085300102SSzymon Olewniczak 19185300102SSzymon Olewniczak return true; 19285300102SSzymon Olewniczak } 19385300102SSzymon Olewniczak} 194