1*87106851SAnna Dabrowska<?php 2*87106851SAnna Dabrowska 3*87106851SAnna Dabrowskaclass action_plugin_structpublish_migration extends DokuWiki_Action_Plugin 4*87106851SAnna Dabrowska{ 5*87106851SAnna Dabrowska /** 6*87106851SAnna Dabrowska * @inheritDoc 7*87106851SAnna Dabrowska */ 8*87106851SAnna Dabrowska public function register(Doku_Event_Handler $controller) 9*87106851SAnna Dabrowska { 10*87106851SAnna Dabrowska $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handleMigrations'); 11*87106851SAnna Dabrowska $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations'); 12*87106851SAnna Dabrowska } 13*87106851SAnna Dabrowska 14*87106851SAnna Dabrowska /** 15*87106851SAnna Dabrowska * Call our custom migrations when defined 16*87106851SAnna Dabrowska * 17*87106851SAnna Dabrowska * @param Doku_Event $event 18*87106851SAnna Dabrowska * @return bool 19*87106851SAnna Dabrowska */ 20*87106851SAnna Dabrowska public function handleMigrations(Doku_Event $event) 21*87106851SAnna Dabrowska { 22*87106851SAnna Dabrowska /** @var \helper_plugin_struct_db $helper */ 23*87106851SAnna Dabrowska $helper = plugin_load('helper', 'struct_db'); 24*87106851SAnna Dabrowska $sqlite = $helper->getDB(); 25*87106851SAnna Dabrowska 26*87106851SAnna Dabrowska $ok = true; 27*87106851SAnna Dabrowska 28*87106851SAnna Dabrowska // check whether we are already up-to-date 29*87106851SAnna Dabrowska list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite); 30*87106851SAnna Dabrowska if (isset($dbVersionStructpublish) && $dbVersionStructpublish === $dbVersionStruct) { 31*87106851SAnna Dabrowska return $ok; 32*87106851SAnna Dabrowska } 33*87106851SAnna Dabrowska 34*87106851SAnna Dabrowska // check whether we have any pending migrations for the current version of struct db 35*87106851SAnna Dabrowska $pending = array_filter(array_map(function ($version) use ($dbVersionStruct) { 36*87106851SAnna Dabrowska return $version >= $dbVersionStruct && 37*87106851SAnna Dabrowska is_callable([$this, "migration$version"]) ? $version : null; 38*87106851SAnna Dabrowska }, $this->diffVersions($dbVersionStruct, $dbVersionStructpublish))); 39*87106851SAnna Dabrowska if (empty($pending)) { 40*87106851SAnna Dabrowska return $ok; 41*87106851SAnna Dabrowska } 42*87106851SAnna Dabrowska 43*87106851SAnna Dabrowska // execute the migrations 44*87106851SAnna Dabrowska foreach ($pending as $version) { 45*87106851SAnna Dabrowska $call = 'migration' . $version; 46*87106851SAnna Dabrowska $ok = $ok && $this->$call($sqlite); 47*87106851SAnna Dabrowska } 48*87106851SAnna Dabrowska 49*87106851SAnna Dabrowska return $ok; 50*87106851SAnna Dabrowska } 51*87106851SAnna Dabrowska 52*87106851SAnna Dabrowska /** 53*87106851SAnna Dabrowska * Detect which migrations should be executed. Start conservatively with version 1. 54*87106851SAnna Dabrowska * 55*87106851SAnna Dabrowska * @param int $dbVersionStruct Current version of struct DB as found in 'opts' table 56*87106851SAnna Dabrowska * @param int|null $dbVersionStructpublish Current version in 'opts', may not exist yet 57*87106851SAnna Dabrowska * @return int[] 58*87106851SAnna Dabrowska */ 59*87106851SAnna Dabrowska protected function diffVersions($dbVersionStruct, $dbVersionStructpublish) 60*87106851SAnna Dabrowska { 61*87106851SAnna Dabrowska $pluginDbVersion = $dbVersionStructpublish ?: 1; 62*87106851SAnna Dabrowska return range($pluginDbVersion, $dbVersionStruct); 63*87106851SAnna Dabrowska } 64*87106851SAnna Dabrowska 65*87106851SAnna Dabrowska /** 66*87106851SAnna Dabrowska * @param $sqlite 67*87106851SAnna Dabrowska * @return array 68*87106851SAnna Dabrowska */ 69*87106851SAnna Dabrowska protected function getDbVersions($sqlite) 70*87106851SAnna Dabrowska { 71*87106851SAnna Dabrowska $dbVersionStruct = null; 72*87106851SAnna Dabrowska $dbVersionStructpublish = null; 73*87106851SAnna Dabrowska 74*87106851SAnna Dabrowska $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?'; 75*87106851SAnna Dabrowska $res = $sqlite->query($sql, 'dbversion', 'dbversion_structpublish'); 76*87106851SAnna Dabrowska $vals = $sqlite->res2arr($res); 77*87106851SAnna Dabrowska 78*87106851SAnna Dabrowska foreach ($vals as $val) { 79*87106851SAnna Dabrowska if ($val['opt'] === 'dbversion') { 80*87106851SAnna Dabrowska $dbVersionStruct = $val['val']; 81*87106851SAnna Dabrowska } 82*87106851SAnna Dabrowska if ($val['opt'] === 'dbversion_structpublish') { 83*87106851SAnna Dabrowska $dbVersionStructpublish = $val['val']; 84*87106851SAnna Dabrowska } 85*87106851SAnna Dabrowska } 86*87106851SAnna Dabrowska return [$dbVersionStruct, $dbVersionStructpublish]; 87*87106851SAnna Dabrowska } 88*87106851SAnna Dabrowska 89*87106851SAnna Dabrowska /** 90*87106851SAnna Dabrowska * Database setup, required struct db version is 19 91*87106851SAnna Dabrowska * 92*87106851SAnna Dabrowska * @param helper_plugin_sqlite $sqlite 93*87106851SAnna Dabrowska * @param array $schema 94*87106851SAnna Dabrowska * @return bool 95*87106851SAnna Dabrowska */ 96*87106851SAnna Dabrowska protected function migration19($sqlite) 97*87106851SAnna Dabrowska { 98*87106851SAnna Dabrowska $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/struct/update0019.sql', false); 99*87106851SAnna Dabrowska 100*87106851SAnna Dabrowska $sql = $sqlite->SQLstring2array($sql); 101*87106851SAnna Dabrowska array_unshift($sql, 'BEGIN TRANSACTION'); 102*87106851SAnna Dabrowska array_push($sql, "INSERT OR REPLACE INTO opts (val,opt) VALUES (19,'dbversion_structpublish')"); 103*87106851SAnna Dabrowska array_push($sql, "COMMIT TRANSACTION"); 104*87106851SAnna Dabrowska return $sqlite->doTransaction($sql); 105*87106851SAnna Dabrowska } 106*87106851SAnna Dabrowska} 107