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