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