187106851SAnna Dabrowska<?php 287106851SAnna Dabrowska 387106851SAnna Dabrowskaclass action_plugin_structpublish_migration extends DokuWiki_Action_Plugin 487106851SAnna Dabrowska{ 587106851SAnna Dabrowska /** 687106851SAnna Dabrowska * @inheritDoc 787106851SAnna Dabrowska */ 887106851SAnna Dabrowska public function register(Doku_Event_Handler $controller) 987106851SAnna Dabrowska { 1087106851SAnna Dabrowska $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handleMigrations'); 1187106851SAnna Dabrowska $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations'); 1287106851SAnna Dabrowska } 1387106851SAnna Dabrowska 1487106851SAnna Dabrowska /** 1587106851SAnna Dabrowska * Call our custom migrations when defined 1687106851SAnna Dabrowska * 1787106851SAnna Dabrowska * @param Doku_Event $event 1887106851SAnna Dabrowska * @return bool 1987106851SAnna Dabrowska */ 2087106851SAnna Dabrowska public function handleMigrations(Doku_Event $event) 2187106851SAnna Dabrowska { 2287106851SAnna Dabrowska /** @var \helper_plugin_struct_db $helper */ 2387106851SAnna Dabrowska $helper = plugin_load('helper', 'struct_db'); 2487106851SAnna Dabrowska $sqlite = $helper->getDB(); 2587106851SAnna Dabrowska 2687106851SAnna Dabrowska $ok = true; 2787106851SAnna Dabrowska 2887106851SAnna Dabrowska // check whether we are already up-to-date 2987106851SAnna Dabrowska list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite); 30e394901aSAnna Dabrowska if (isset($dbVersionStructpublish) && (string)$dbVersionStructpublish == (string)$dbVersionStruct) { 3187106851SAnna Dabrowska return $ok; 3287106851SAnna Dabrowska } 3387106851SAnna Dabrowska 3487106851SAnna Dabrowska // check whether we have any pending migrations for the current version of struct db 3587106851SAnna Dabrowska $pending = array_filter(array_map(function ($version) use ($dbVersionStruct) { 3687106851SAnna Dabrowska return $version >= $dbVersionStruct && 3787106851SAnna Dabrowska is_callable([$this, "migration$version"]) ? $version : null; 3887106851SAnna Dabrowska }, $this->diffVersions($dbVersionStruct, $dbVersionStructpublish))); 3987106851SAnna Dabrowska if (empty($pending)) { 4087106851SAnna Dabrowska return $ok; 4187106851SAnna Dabrowska } 4287106851SAnna Dabrowska 4387106851SAnna Dabrowska // execute the migrations 4487106851SAnna Dabrowska foreach ($pending as $version) { 4587106851SAnna Dabrowska $call = 'migration' . $version; 4687106851SAnna Dabrowska $ok = $ok && $this->$call($sqlite); 4787106851SAnna Dabrowska } 4887106851SAnna Dabrowska 4987106851SAnna Dabrowska return $ok; 5087106851SAnna Dabrowska } 5187106851SAnna Dabrowska 5287106851SAnna Dabrowska /** 5387106851SAnna Dabrowska * Detect which migrations should be executed. Start conservatively with version 1. 5487106851SAnna Dabrowska * 5587106851SAnna Dabrowska * @param int $dbVersionStruct Current version of struct DB as found in 'opts' table 5687106851SAnna Dabrowska * @param int|null $dbVersionStructpublish Current version in 'opts', may not exist yet 5787106851SAnna Dabrowska * @return int[] 5887106851SAnna Dabrowska */ 5987106851SAnna Dabrowska protected function diffVersions($dbVersionStruct, $dbVersionStructpublish) 6087106851SAnna Dabrowska { 6187106851SAnna Dabrowska $pluginDbVersion = $dbVersionStructpublish ?: 1; 6287106851SAnna Dabrowska return range($pluginDbVersion, $dbVersionStruct); 6387106851SAnna Dabrowska } 6487106851SAnna Dabrowska 6587106851SAnna Dabrowska /** 6687106851SAnna Dabrowska * @param $sqlite 6787106851SAnna Dabrowska * @return array 6887106851SAnna Dabrowska */ 6987106851SAnna Dabrowska protected function getDbVersions($sqlite) 7087106851SAnna Dabrowska { 7187106851SAnna Dabrowska $dbVersionStruct = null; 7287106851SAnna Dabrowska $dbVersionStructpublish = null; 7387106851SAnna Dabrowska 7487106851SAnna Dabrowska $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?'; 7587106851SAnna Dabrowska $res = $sqlite->query($sql, 'dbversion', 'dbversion_structpublish'); 7687106851SAnna Dabrowska $vals = $sqlite->res2arr($res); 7787106851SAnna Dabrowska 7887106851SAnna Dabrowska foreach ($vals as $val) { 7987106851SAnna Dabrowska if ($val['opt'] === 'dbversion') { 8087106851SAnna Dabrowska $dbVersionStruct = $val['val']; 8187106851SAnna Dabrowska } 8287106851SAnna Dabrowska if ($val['opt'] === 'dbversion_structpublish') { 8387106851SAnna Dabrowska $dbVersionStructpublish = $val['val']; 8487106851SAnna Dabrowska } 8587106851SAnna Dabrowska } 8687106851SAnna Dabrowska return [$dbVersionStruct, $dbVersionStructpublish]; 8787106851SAnna Dabrowska } 8887106851SAnna Dabrowska 8987106851SAnna Dabrowska /** 9087106851SAnna Dabrowska * Database setup, required struct db version is 19 9187106851SAnna Dabrowska * 9287106851SAnna Dabrowska * @param helper_plugin_sqlite $sqlite 9387106851SAnna Dabrowska * @return bool 9487106851SAnna Dabrowska */ 9587106851SAnna Dabrowska protected function migration19($sqlite) 9687106851SAnna Dabrowska { 9787106851SAnna Dabrowska $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/struct/update0019.sql', false); 9887106851SAnna Dabrowska 9987106851SAnna Dabrowska $sql = $sqlite->SQLstring2array($sql); 10087106851SAnna Dabrowska array_unshift($sql, 'BEGIN TRANSACTION'); 10187106851SAnna Dabrowska array_push($sql, "INSERT OR REPLACE INTO opts (val,opt) VALUES (19,'dbversion_structpublish')"); 10287106851SAnna Dabrowska array_push($sql, "COMMIT TRANSACTION"); 103*677c897aSAnna Dabrowska $ok = $sqlite->doTransaction($sql); 104*677c897aSAnna Dabrowska 105*677c897aSAnna Dabrowska if ($ok) { 106*677c897aSAnna Dabrowska $file = __DIR__ . "../db/json/structpublish_19.struct.json"; 107*677c897aSAnna Dabrowska $schemaJson = file_get_contents($file); 108*677c897aSAnna Dabrowska $importer = new \dokuwiki\plugin\struct\meta\SchemaImporter('structpublish', $schemaJson); 109*677c897aSAnna Dabrowska $ok = (bool)$importer->build(); 110*677c897aSAnna Dabrowska } 111*677c897aSAnna Dabrowska 112*677c897aSAnna Dabrowska return $ok; 11387106851SAnna Dabrowska } 11487106851SAnna Dabrowska} 115