1<?php 2 3class action_plugin_structpublish_migration extends DokuWiki_Action_Plugin 4{ 5 const MIN_DB_STRUCT = 19; 6 7 /** 8 * @inheritDoc 9 */ 10 public function register(Doku_Event_Handler $controller) 11 { 12 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleMigrations'); 13 } 14 15 /** 16 * Call our custom migrations when defined 17 * 18 * @param Doku_Event $event 19 * @return bool 20 * @throws Exception 21 */ 22 public function handleMigrations(Doku_Event $event) 23 { 24 /** @var \helper_plugin_struct_db $helper */ 25 $helper = plugin_load('helper', 'struct_db'); 26 27 // abort if struct is not installed 28 if (!$helper) { 29 throw new Exception('Plugin struct is required!'); 30 } 31 32 $sqlite = $helper->getDB(); 33 34 list($dbVersionStruct, $dbVersionStructpublish) = $this->getDbVersions($sqlite); 35 36 // check if struct has required version 37 if ($dbVersionStruct < self::MIN_DB_STRUCT) { 38 throw new Exception('Plugin struct is outdated. Minimum required database version is ' . self::MIN_DB_STRUCT); 39 } 40 41 // check whether we are already up-to-date 42 $latestVersion = $this->getLatestVersion(); 43 if (isset($dbVersionStructpublish) && (int) $dbVersionStructpublish >= $latestVersion) { 44 return true; 45 } 46 47 // check whether we have any pending migrations 48 $pending = range($dbVersionStructpublish ?: 1, $latestVersion); 49 if (empty($pending)) { 50 return true; 51 } 52 53 // execute the migrations 54 $ok = true; 55 foreach ($pending as $version) { 56 $call = 'migration' . $version; 57 $ok = $ok && $this->$call($sqlite); 58 } 59 60 return $ok; 61 } 62 63 /** 64 * Read the current versions for struct and struct publish from the database 65 * 66 * @param helper_plugin_sqlite $sqlite 67 * @return array [structversion, structpublishversion] 68 */ 69 protected function getDbVersions($sqlite) 70 { 71 $dbVersionStruct = null; 72 $dbVersionStructpublish = null; 73 74 $sql = 'SELECT opt, val FROM opts WHERE opt=? OR opt=?'; 75 $res = $sqlite->query($sql, 'dbversion', 'dbversion_structpublish'); 76 $vals = $sqlite->res2arr($res); 77 78 foreach ($vals as $val) { 79 if ($val['opt'] === 'dbversion') { 80 $dbVersionStruct = $val['val']; 81 } 82 if ($val['opt'] === 'dbversion_structpublish') { 83 $dbVersionStructpublish = $val['val']; 84 } 85 } 86 return [$dbVersionStruct, $dbVersionStructpublish]; 87 } 88 89 /** 90 * @return int 91 */ 92 protected function getLatestVersion() 93 { 94 return (int) trim(file_get_contents(DOKU_PLUGIN . 'structpublish/db/latest.version', false)); 95 } 96 97 /** 98 * Database setup 99 * 100 * @param helper_plugin_sqlite $sqlite 101 * @return bool 102 */ 103 protected function migration1($sqlite) 104 { 105 $sql = io_readFile(DOKU_PLUGIN . 'structpublish/db/update0001.sql', false); 106 107 $sql = $sqlite->SQLstring2array($sql); 108 array_unshift($sql, 'BEGIN TRANSACTION'); 109 array_push($sql, "INSERT OR REPLACE INTO opts (val,opt) VALUES (1,'dbversion_structpublish')"); 110 array_push($sql, "COMMIT TRANSACTION"); 111 $ok = $sqlite->doTransaction($sql); 112 113 if ($ok) { 114 $file = DOKU_PLUGIN . 'structpublish/db/json/structpublish0001.struct.json'; 115 $schemaJson = file_get_contents($file); 116 $importer = new \dokuwiki\plugin\struct\meta\SchemaImporter('structpublish', $schemaJson); 117 $ok = (bool) $importer->build(); 118 } 119 120 return $ok; 121 } 122} 123