1<?php 2/** 3 * DokuWiki Plugin bez (Action Component) 4 * 5 */ 6 7// must be run within Dokuwiki 8 9if(!defined('DOKU_INC')) die(); 10 11/** 12 * Class action_plugin_bez_migration 13 * 14 * Handle migrations that need more than just SQL 15 */ 16class action_plugin_bez_migration extends DokuWiki_Action_Plugin { 17 /** 18 * @inheritDoc 19 */ 20 public function register(Doku_Event_Handler $controller) { 21 $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handle_migrations'); 22 } 23 24 /** 25 * Call our custom migrations when defined 26 * 27 * @param Doku_Event $event 28 * @param $param 29 */ 30 public function handle_migrations(Doku_Event $event, $param) { 31 if ($event->data['sqlite']->getAdapter()->getDbname() !== 'b3p') { 32 return; 33 } 34 $to = $event->data['to']; 35 36 if(is_callable(array($this, "migration$to"))) { 37 $event->preventDefault(); 38 $event->result = call_user_func(array($this, "migration$to"), $event->data); 39 } 40 } 41 42 /** 43 * Executes Migration 1 44 * 45 * Add a latest column to all existing multi tables 46 * 47 * @param helper_plugin_sqlite $sqlite 48 * @return bool 49 */ 50 protected function migration1($data) { 51 global $INFO; 52 53 $file = $data['file']; 54 /** @var helper_plugin_sqlite $sqlite */ 55 $sqlite = $data['sqlite']; 56 57 $sql = file_get_contents($file); 58 if ($sql === false) { 59 throw new Exception('cannot open file '.$file); 60 } 61 62 $matches = array(); 63 preg_match_all('/.*?(?(?=BEGIN)BEGIN.*?END)\s*;/is', $sql, $matches); 64 $queries = $matches[0]; 65 66 $db = $sqlite->getAdapter()->getDb(); 67 68 $db->beginTransaction(); 69 foreach ($queries as $query) { 70 $res = $db->query($query); 71 if($res === false) { 72 $err = $db->errorInfo(); 73 msg($err[0].' '.$err[1].' '.$err[2].':<br /><pre>'.hsc($query).'</pre>', -1); 74 $db->rollBack(); 75 return false; 76 } 77 } 78 79 $bez_file = DOKU_INC . 'data/meta/bez.sqlite3'; 80 if (!file_exists($bez_file)) { 81 $db->commit(); 82 return true; 83 } 84 85 //import from bez 86 $bez = new \PDO('sqlite:' . $bez_file); 87 88 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 89 90 $stmt = $bez->query('SELECT * FROM issuetypes'); 91 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { 92 $sqlite->storeEntry('label', array('id' => $row['id'], 93 'name' => $row['pl'], 94 'added_by' => $INFO['client'], 95 'added_date' => date('c'))); 96 } 97 98 $stmt = $bez->query('SELECT * FROM tasktypes'); 99 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { 100 $sqlite->storeEntry('task_program', array('id' => $row['id'], 101 'name' => $row['pl'], 102 'added_by' => $INFO['client'], 103 'added_date' => date('c'))); 104 } 105 106 $stmt = $bez->query('SELECT *, (SELECT COUNT(*) FROM tasks 107 WHERE tasks.cause = commcauses.id) AS task_count FROM commcauses'); 108 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { 109 if ($row['type'] == '0') { 110 $type = 'comment'; 111 } elseif ($row['type'] == '1') { 112 $type = 'cause_real'; 113 } elseif ($row['type'] == '2') { 114 $type = 'cause_potential'; 115 } 116 $sqlite->storeEntry('thread_comment', 117 array('id' => $row['id'], 118 'thread_id' => $row['issue'], 119 'type' => $type, 120 'author' => $row['reporter'], 121 'create_date' => date('c', strtotime($row['datetime'])), 122 'last_modification_date' => date('c', strtotime($row['datetime'])), 123 'content' => $row['content'], 124 'content_html' => $row['content_cache'], 125 'task_count' => $row['task_count'])); 126 } 127 128 $stmt = $bez->query('SELECT tasks.*, commcauses.type AS cause_type 129 FROM tasks 130 LEFT JOIN commcauses ON tasks.cause = commcauses.id'); 131 //thread_id => array('user_id' => 'user_id') 132 $task_assignee = array(); 133 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { 134 if ($row['close_date'] != '') { 135 $last_mod = date('c', (int) $row['close_date']); 136 } else { 137 $last_mod = date('c', (int) $row['date']); 138 } 139 140 $data = array('id' => $row['id'], 141 'original_poster' => $row['reporter'], 142 'assignee' => $row['executor'], 143 'create_date' => date('c', (int) $row['date']), 144 'last_activity_date' => $last_mod, 145 'last_modification_date' => $last_mod, 146 'plan_date' => $row['plan_date'], 147 'all_day_event' => $row['all_day_event'], 148 'start_time' => $row['start_time'], 149 'finish_time' => $row['finish_time'], 150 'content' => $row['task'], 151 'content_html' => $row['task_cache'], 152 'thread_id' => $row['issue'], 153 'thread_comment_id' => $row['cause'], 154 'task_program_id' => $row['tasktype'] 155 ); 156 157 if ($data['thread_id'] != '') { 158 if (!is_array($task_assignee[$data['thread_id']])) { 159 $task_assignee[$data['thread_id']] = array(); 160 } 161 $task_assignee[$data['thread_id']][$row['executor']] = $row['executor']; 162 } 163 164 if ($row['cost'] != '0') { 165 $data['cost'] = $row['cost']; 166 } 167 168 if ($row['issue'] == '') { 169 $data['type'] = 'program'; 170 } elseif ($row['cause'] == '') { 171 $data['type'] = 'correction'; 172 } elseif ($row['cause_type'] == '1') { 173 $data['type'] = 'corrective'; 174 } else { 175 $data['type'] = 'preventive'; 176 } 177 178 if ($row['state'] == '0') { 179 $data['state'] = 'opened'; 180 } elseif ($row['state'] == '1' || $row['state'] == '2') { 181 $data['state'] = 'done'; 182 $data['closed_by'] = $row['executor']; 183 $data['close_date'] = date('c', (int) $row['close_date']); 184 185 if ($row['reason'] != '') { 186 $sqlite->storeEntry('task_comment', 187 array('task_id' => $row['id'], 188 'author' => $row['executor'], 189 'create_date' => $data['close_date'], 190 'last_modification_date' => $data['close_date'], 191 'content' => $row['reason'], 192 'content_html' => $row['reason_cache'])); 193 } 194 } 195 196 //user_id => array() 197 $participants = array(); 198 $subscribents = explode(',', $row['subscribents']); 199 foreach ($subscribents as $user_id) { 200 $participants[$user_id] = array('user_id' => $user_id, 'subscribent' => '1'); 201 } 202 203 $op = $data['original_poster']; 204 if (!isset($participants[$op])) { 205 $participants[$op] = array('user_id' => $op, 'original_poster' => '1'); 206 } else { 207 $participants[$op]['original_poster'] = '1'; 208 } 209 210 $as = $data['assignee']; 211 if (!isset($participants[$as])) { 212 $participants[$as] = array('user_id' => $as, 'assignee' => '1'); 213 } else { 214 $participants[$as]['assignee'] = '1'; 215 } 216 217 foreach($participants as $part) { 218 $part['task_id'] = $row['id']; 219 $part['added_by'] = $INFO['client']; 220 $part['added_date'] = date('c'); 221 222 $res = $sqlite->storeEntry('task_participant', $part); 223 if ($res === false) { 224 throw new Exception($db->errorInfo()); 225 } 226 } 227 228 $sqlite->storeEntry('task', $data); 229 } 230 231 232 233 $stmt = $bez->query('SELECT *, 234 (SELECT COUNT(*) FROM tasks 235 WHERE tasks.issue = issues.id) AS task_count, 236 (SELECT COUNT(*) FROM tasks 237 WHERE tasks.issue = issues.id AND tasks.state != 0) AS task_closed_count, 238 (SELECT SUM(cost) FROM tasks 239 WHERE tasks.issue = issues.id) AS task_sum_cost 240 FROM issues'); 241 242 while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { 243 244 $data = array('id' => $row['id'], 245 'original_poster' => $row['reporter'], 246 'coordinator' => $row['coordinator'], 247 'create_date' => date('c', (int) $row['date']), 248 'last_activity_date' => date('c', strtotime($row['last_activity'])), 249 'last_modification_date' => date('c', (int) $row['last_mod']), 250 'title' => $row['title'], 251 'content' => $row['description'], 252 'content_html' => $row['description_cache'], 253 'task_count' => $row['task_count'], 254 'task_count_closed' => $row['task_closed_count'] 255 ); 256 257 if ($row['task_sum_cost'] != '0') { 258 $data['task_sum_cost'] = $row['task_sum_cost']; 259 } 260 261 if ($row['coordinator'] == '') { 262 $data['state'] = 'proposal'; 263 } elseif ($row['state'] == '1') { 264 $data['closed_by'] = $row['coordinator']; 265 $data['state'] = 'closed'; 266 $data['close_date'] = $data['last_modification_date']; 267 268 $sqlite->storeEntry('thread_comment', 269 array('thread_id' => $row['id'], 270 'type' => 'comment', 271 'author' => $row['coordinator'], 272 'create_date' => $data['close_date'], 273 'last_modification_date' => $data['close_date'], 274 'content' => $row['opinion'], 275 'content_html' => $row['opinion_cache'])); 276 277 278 } elseif ($row['state'] == '2') { 279 $data['closed_by'] = $row['coordinator']; 280 $data['state'] = 'rejected'; 281 $data['close_date'] = $data['last_modification_date']; 282 283 if ($row['opinion'] != '') { 284 $res = $sqlite->storeEntry('thread_comment', 285 array('thread_id' => $row['id'], 286 'type' => 'comment', 287 'author' => $row['coordinator'], 288 'create_date' => $data['close_date'], 289 'last_modification_date' => $data['close_date'], 290 'content' => $row['opinion'], 291 'content_html' => $row['opinion_cache'])); 292 if ($res === false) { 293 throw new Exception($db->errorInfo()); 294 } 295 } 296 297 } elseif ($row['task_count'] != '0' && $row['task_count'] == $row['task_closed_count']) { 298 $data['state'] = 'done'; 299 } else { 300 $data['state'] = 'opened'; 301 } 302 303 $sqlite->storeEntry('thread', $data); 304 305 $sqlite->storeEntry('thread_label', 306 array('thread_id' => $row['id'], 307 'label_id' => $row['type'])); 308 309 //participants 310 //user_id => array() 311 $participants = array(); 312 $org_participants = array_filter(explode(',', $row['participants'])); 313 foreach ($org_participants as $user_id) { 314 $participants[$user_id] = array('user_id' => $user_id); 315 } 316 317 $subscribents = array_filter(explode(',', $row['subscribents'])); 318 foreach ($subscribents as $user_id) { 319 if (!isset($participants[$user_id])) { 320 $participants[$user_id] = array('user_id' => $user_id); 321 } 322 $participants[$user_id]['subscribent'] = '1'; 323 } 324 325 $stmt_i = $bez->query('SELECT reporter FROM commcauses WHERE issue=' . $row['id']); 326 while ($commcause = $stmt_i->fetch(\PDO::FETCH_ASSOC)) { 327 $user_id = $commcause['reporter']; 328 if (!isset($participants[$user_id])) { 329 $participants[$user_id] = array('user_id' => $user_id); 330 } 331 $participants[$user_id]['commentator'] = '1'; 332 } 333 334 if (is_array($task_assignee[$row['id']])) foreach ($task_assignee[$row['id']] as $user_id) { 335 if (!isset($participants[$user_id])) { 336 $participants[$user_id] = array('user_id' => $user_id); 337 } 338 $participants[$user_id]['task_assignee'] = '1'; 339 } 340 341 $op = $data['original_poster']; 342 if (!isset($participants[$op])) { 343 $participants[$op] = array('user_id' => $op, 'original_poster' => '1'); 344 } else { 345 $participants[$op]['original_poster'] = '1'; 346 } 347 348 $cor = $data['coordinator']; 349 if (!isset($participants[$cor])) { 350 $participants[$cor] = array('user_id' => $cor, 'coordinator' => '1'); 351 } else { 352 $participants[$cor]['coordinator'] = '1'; 353 } 354 355 foreach($participants as $part) { 356 $part['thread_id'] = $row['id']; 357 $part['added_by'] = $INFO['client']; 358 $part['added_date'] = date('c'); 359 360 $sqlite->storeEntry('thread_participant', $part); 361 } 362 363 } 364 365 $db->commit(); 366 367 return true; 368 } 369 370} 371