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