18f259467SAndreas Gohr<?php 2d6d97f60SAnna Dabrowska 38f259467SAndreas Gohr/** 48f259467SAndreas Gohr * DokuWiki Plugin struct (Action Component) 58f259467SAndreas Gohr * 68f259467SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 78f259467SAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 88f259467SAndreas Gohr */ 98f259467SAndreas Gohr 108f259467SAndreas Gohr/** 118f259467SAndreas Gohr * Class action_plugin_struct_migration 128f259467SAndreas Gohr * 138f259467SAndreas Gohr * Handle migrations that need more than just SQL 148f259467SAndreas Gohr */ 15d6d97f60SAnna Dabrowskaclass action_plugin_struct_migration extends DokuWiki_Action_Plugin 16d6d97f60SAnna Dabrowska{ 178f259467SAndreas Gohr /** 188f259467SAndreas Gohr * @inheritDoc 198f259467SAndreas Gohr */ 20d6d97f60SAnna Dabrowska public function register(Doku_Event_Handler $controller) 21d6d97f60SAnna Dabrowska { 22748e747fSAnna Dabrowska $controller->register_hook('PLUGIN_SQLITE_DATABASE_UPGRADE', 'BEFORE', $this, 'handleMigrations'); 238f259467SAndreas Gohr } 248f259467SAndreas Gohr 258f259467SAndreas Gohr /** 268f259467SAndreas Gohr * Call our custom migrations when defined 278f259467SAndreas Gohr * 288f259467SAndreas Gohr * @param Doku_Event $event 298f259467SAndreas Gohr * @param $param 308f259467SAndreas Gohr */ 31748e747fSAnna Dabrowska public function handleMigrations(Doku_Event $event, $param) 32d6d97f60SAnna Dabrowska { 3379b29326SAnna Dabrowska if ($event->data['adapter']->getDbname() !== 'struct') { 343eafcbabSMichael Große return; 353eafcbabSMichael Große } 368f259467SAndreas Gohr $to = $event->data['to']; 378f259467SAndreas Gohr 388f259467SAndreas Gohr if (is_callable(array($this, "migration$to"))) { 398f259467SAndreas Gohr $event->preventDefault(); 4079b29326SAnna Dabrowska $event->result = call_user_func(array($this, "migration$to"), $event->data['adapter']); 418f259467SAndreas Gohr } 428f259467SAndreas Gohr } 438f259467SAndreas Gohr 448f259467SAndreas Gohr /** 458f259467SAndreas Gohr * Executes Migration 12 468f259467SAndreas Gohr * 478f259467SAndreas Gohr * Add a latest column to all existing multi tables 488f259467SAndreas Gohr * 4979b29326SAnna Dabrowska * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite 508f259467SAndreas Gohr * @return bool 518f259467SAndreas Gohr */ 5279b29326SAnna Dabrowska protected function migration12($sqlite) 53d6d97f60SAnna Dabrowska { 548f259467SAndreas Gohr /** @noinspection SqlResolve */ 558f259467SAndreas Gohr $sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND name LIKE 'multi_%'"; 5679b29326SAnna Dabrowska $tables = $sqlite->queryAll($sql); 578f259467SAndreas Gohr 588f259467SAndreas Gohr foreach ($tables as $row) { 59*66164365SAndreas Gohr $table = $row['name']; // no escaping needed, it's our own tables 60*66164365SAndreas Gohr $sql = "ALTER TABLE $table ADD COLUMN latest INT DEFAULT 1"; 61*66164365SAndreas Gohr $sqlite->query($sql); 628f259467SAndreas Gohr } 638f259467SAndreas Gohr 648f259467SAndreas Gohr return true; 658f259467SAndreas Gohr } 6676a74c23SAnna Dabrowska 6776a74c23SAnna Dabrowska /** 6876a74c23SAnna Dabrowska * Executes Migration 16 6976a74c23SAnna Dabrowska * 7076a74c23SAnna Dabrowska * Unifies previous page and lookup schema types 7176a74c23SAnna Dabrowska * 7279b29326SAnna Dabrowska * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite 7376a74c23SAnna Dabrowska * @return bool 7476a74c23SAnna Dabrowska */ 7579b29326SAnna Dabrowska protected function migration16($sqlite) 7676a74c23SAnna Dabrowska { 7776a74c23SAnna Dabrowska // get tables and their SQL definitions 7876a74c23SAnna Dabrowska $sql = "SELECT sql, name FROM sqlite_master 7976a74c23SAnna Dabrowska WHERE type = 'table' 8076a74c23SAnna Dabrowska AND (name LIKE 'data_%' OR name LIKE 'multi_%')"; 8179b29326SAnna Dabrowska $tables = $sqlite->queryAll($sql); 8276a74c23SAnna Dabrowska 8376a74c23SAnna Dabrowska // get latest versions of schemas with islookup property 8476a74c23SAnna Dabrowska $sql = "SELECT MAX(id) AS id, tbl, islookup FROM schemas 8576a74c23SAnna Dabrowska GROUP BY tbl 8676a74c23SAnna Dabrowska "; 8779b29326SAnna Dabrowska $schemas = $sqlite->queryAll($sql); 8876a74c23SAnna Dabrowska 8976a74c23SAnna Dabrowska $ok = true; 9076a74c23SAnna Dabrowska 9176a74c23SAnna Dabrowska // Step 1: move original data to temporary tables and create new ones with modified schemas 9276a74c23SAnna Dabrowska foreach ($tables as $table) { 9376a74c23SAnna Dabrowska $name = $table['name']; 9476a74c23SAnna Dabrowska $sql = $table['sql']; 9576a74c23SAnna Dabrowska 9676a74c23SAnna Dabrowska // move original data to temp_* 9776a74c23SAnna Dabrowska $ok = $ok && $sqlite->query("ALTER TABLE $name RENAME TO temp_$name"); 9876a74c23SAnna Dabrowska 9976a74c23SAnna Dabrowska // update pid definitions 10076a74c23SAnna Dabrowska $sql = preg_replace('/pid (\w* ?NOT NULL|\w* ?PRIMARY KEY)/', 'pid TEXT DEFAULT ""', $sql); 10176a74c23SAnna Dabrowska 10276a74c23SAnna Dabrowska // add rid and new primary key to regular tables 10376a74c23SAnna Dabrowska $cnt = 0; 10476a74c23SAnna Dabrowska $sql = preg_replace('/(PRIMARY KEY ?\([^\)]+?)(\))/', ' rid INTEGER, $1, rid $2', $sql, -1, $cnt); 10576a74c23SAnna Dabrowska // add rid and new primary key to lookup tables 10676a74c23SAnna Dabrowska if (!$cnt) { 10776a74c23SAnna Dabrowska $sql = str_replace(')', ', rid INTEGER, PRIMARY KEY(pid,rid) )', $sql); 10876a74c23SAnna Dabrowska } 10976a74c23SAnna Dabrowska 11076a74c23SAnna Dabrowska // create the new table 11176a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($sql); 11276a74c23SAnna Dabrowska if (!$ok) return false; 11376a74c23SAnna Dabrowska } 11476a74c23SAnna Dabrowska 11576a74c23SAnna Dabrowska // Step 2: transfer data back from original tables (temp_*) 11676a74c23SAnna Dabrowska foreach ($schemas as $schema) { 11776a74c23SAnna Dabrowska $name = $schema['tbl']; 11876a74c23SAnna Dabrowska $sid = $schema['id']; 11976a74c23SAnna Dabrowska $isLookup = $schema['islookup']; 12076a74c23SAnna Dabrowska 12176a74c23SAnna Dabrowska if (!$isLookup) { 12276a74c23SAnna Dabrowska $s = sprintf('INSERT INTO data_%s SELECT *, 0 FROM temp_data_%s', $name, $name); 12376a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 12476a74c23SAnna Dabrowska if (!$ok) return false; 12576a74c23SAnna Dabrowska 12676a74c23SAnna Dabrowska $s = sprintf('INSERT INTO multi_%s SELECT *, 0 FROM temp_multi_%s', $name, $name); 12776a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 12876a74c23SAnna Dabrowska if (!$ok) return false; 12976a74c23SAnna Dabrowska } else { 13076a74c23SAnna Dabrowska // transfer pid to rid 13176a74c23SAnna Dabrowska $s = sprintf('INSERT INTO data_%s SELECT *, pid FROM temp_data_%s', $name, $name); 13276a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 13376a74c23SAnna Dabrowska if (!$ok) return false; 13476a74c23SAnna Dabrowska 13576a74c23SAnna Dabrowska $s = sprintf('INSERT INTO multi_%s SELECT *, pid FROM temp_multi_%s', $name, $name); 13676a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 13776a74c23SAnna Dabrowska if (!$ok) return false; 13876a74c23SAnna Dabrowska 13976a74c23SAnna Dabrowska // all lookup data has empty pids at this point 14076a74c23SAnna Dabrowska $s = "UPDATE data_$name SET pid = ''"; 14176a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 14276a74c23SAnna Dabrowska if (!$ok) return false; 14376a74c23SAnna Dabrowska 14476a74c23SAnna Dabrowska $s = "UPDATE multi_$name SET pid = ''"; 14576a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 14676a74c23SAnna Dabrowska if (!$ok) return false; 14776a74c23SAnna Dabrowska } 14876a74c23SAnna Dabrowska 14976a74c23SAnna Dabrowska // introduce composite ids in lookup columns 150544dca1bSAnna Dabrowska $s = $this->getLookupColsSql($sid); 15179b29326SAnna Dabrowska $cols = $sqlite->queryAll($s); 15276a74c23SAnna Dabrowska 15376a74c23SAnna Dabrowska if ($cols) { 15476a74c23SAnna Dabrowska foreach ($cols as $col) { 15576a74c23SAnna Dabrowska $colno = $col['COL']; 156e361da24SAnna Dabrowska $colname = "col$colno"; 157ef747633SAnna Dabrowska // lookup fields pointing to pages have to be migrated first! 158ef747633SAnna Dabrowska // they rely on a simplistic not-a-number check, and already migrated lookups pass the test! 15917a3a578SAndreas Gohr $f = 'UPDATE data_%s 16017a3a578SAndreas Gohr SET %s = \'["\'||%s||\'",0]\' 16117a3a578SAndreas Gohr WHERE %s != \'\' 16217a3a578SAndreas Gohr AND CAST(%s AS DECIMAL) != %s'; 163e361da24SAnna Dabrowska $s = sprintf($f, $name, $colname, $colname, $colname, $colname, $colname); 164e361da24SAnna Dabrowska $ok = $ok && $sqlite->query($s); 165e361da24SAnna Dabrowska if (!$ok) return false; 16676a74c23SAnna Dabrowska // multi_ 16717a3a578SAndreas Gohr $f = 'UPDATE multi_%s 16817a3a578SAndreas Gohr SET value = \'["\'||value||\'",0]\' 16917a3a578SAndreas Gohr WHERE colref = %s 17017a3a578SAndreas Gohr AND CAST(value AS DECIMAL) != value'; 171e361da24SAnna Dabrowska $s = sprintf($f, $name, $colno); 17276a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 17376a74c23SAnna Dabrowska if (!$ok) return false; 174ef747633SAnna Dabrowska 175ef747633SAnna Dabrowska // simple lookup fields 17617a3a578SAndreas Gohr $s = "UPDATE data_$name 17717a3a578SAndreas Gohr SET col$colno = '[" . '""' . ",'||col$colno||']' 17817a3a578SAndreas Gohr WHERE col$colno != '' 17917a3a578SAndreas Gohr AND CAST(col$colno AS DECIMAL) = col$colno"; 180ef747633SAnna Dabrowska $ok = $ok && $sqlite->query($s); 181ef747633SAnna Dabrowska if (!$ok) return false; 182ef747633SAnna Dabrowska // multi_ 18317a3a578SAndreas Gohr $s = "UPDATE multi_$name 18417a3a578SAndreas Gohr SET value = '[" . '""' . ",'||value||']' 18517a3a578SAndreas Gohr WHERE colref=$colno 18617a3a578SAndreas Gohr AND CAST(value AS DECIMAL) = value"; 187ef747633SAnna Dabrowska $ok = $ok && $sqlite->query($s); 188ef747633SAnna Dabrowska if (!$ok) return false; 18976a74c23SAnna Dabrowska } 19076a74c23SAnna Dabrowska } 19176a74c23SAnna Dabrowska } 19276a74c23SAnna Dabrowska 19376a74c23SAnna Dabrowska // Step 3: delete temp_* tables 19476a74c23SAnna Dabrowska foreach ($tables as $table) { 19576a74c23SAnna Dabrowska $name = $table['name']; 19676a74c23SAnna Dabrowska $s = "DROP TABLE temp_$name"; 19776a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 19876a74c23SAnna Dabrowska if (!$ok) return false; 19976a74c23SAnna Dabrowska } 20076a74c23SAnna Dabrowska 20176a74c23SAnna Dabrowska // Step 4: remove islookup in schemas table 20276a74c23SAnna Dabrowska $sql = "SELECT sql FROM sqlite_master 20376a74c23SAnna Dabrowska WHERE type = 'table' 20476a74c23SAnna Dabrowska AND name = 'schemas'"; 20579b29326SAnna Dabrowska $t = $sqlite->queryAll($sql); 20676a74c23SAnna Dabrowska $sql = $t[0]['sql']; 20776a74c23SAnna Dabrowska $sql = str_replace('islookup INTEGER,', '', $sql); 20876a74c23SAnna Dabrowska 20976a74c23SAnna Dabrowska $s = 'ALTER TABLE schemas RENAME TO temp_schemas'; 21076a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 21176a74c23SAnna Dabrowska if (!$ok) return false; 21276a74c23SAnna Dabrowska 21376a74c23SAnna Dabrowska // create a new table without islookup 21476a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($sql); 21576a74c23SAnna Dabrowska if (!$ok) return false; 21676a74c23SAnna Dabrowska 21776a74c23SAnna Dabrowska $s = 'INSERT INTO schemas SELECT id, tbl, ts, user, comment, config FROM temp_schemas'; 21876a74c23SAnna Dabrowska $ok = $ok && $sqlite->query($s); 21976a74c23SAnna Dabrowska 22079b29326SAnna Dabrowska return $ok; 22176a74c23SAnna Dabrowska } 222544dca1bSAnna Dabrowska 223544dca1bSAnna Dabrowska /** 224544dca1bSAnna Dabrowska * Executes Migration 17 225544dca1bSAnna Dabrowska * 226544dca1bSAnna Dabrowska * Fixes lookup data not correctly migrated by #16 227544dca1bSAnna Dabrowska * All lookups were presumed to reference lookup data, not pages, so the migrated value 228544dca1bSAnna Dabrowska * was always ["", <previous-pid-aka-new-rid>]. For page references it is ["<previous-pid>", 0] 229544dca1bSAnna Dabrowska * 23079b29326SAnna Dabrowska * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite 231544dca1bSAnna Dabrowska * @return bool 232544dca1bSAnna Dabrowska */ 23379b29326SAnna Dabrowska protected function migration17($sqlite) 234544dca1bSAnna Dabrowska { 235544dca1bSAnna Dabrowska $sql = "SELECT MAX(id) AS id, tbl FROM schemas 236544dca1bSAnna Dabrowska GROUP BY tbl 237544dca1bSAnna Dabrowska "; 23879b29326SAnna Dabrowska $schemas = $sqlite->queryAll($sql); 239544dca1bSAnna Dabrowska 240544dca1bSAnna Dabrowska $ok = true; 241544dca1bSAnna Dabrowska 242544dca1bSAnna Dabrowska foreach ($schemas as $schema) { 243544dca1bSAnna Dabrowska // find lookup columns 244544dca1bSAnna Dabrowska $name = $schema['tbl']; 245544dca1bSAnna Dabrowska $sid = $schema['id']; 246544dca1bSAnna Dabrowska $s = $this->getLookupColsSql($sid); 24779b29326SAnna Dabrowska $cols = $sqlite->queryAll($s); 248544dca1bSAnna Dabrowska 249544dca1bSAnna Dabrowska if ($cols) { 250544dca1bSAnna Dabrowska $colnames = array_map(function ($c) { 251544dca1bSAnna Dabrowska return 'col' . $c['COL']; 252544dca1bSAnna Dabrowska }, $cols); 253544dca1bSAnna Dabrowska 254544dca1bSAnna Dabrowska // data_ tables 255544dca1bSAnna Dabrowska $s = 'SELECT pid, rid, rev, ' . implode(', ', $colnames) . " FROM data_$name"; 25679b29326SAnna Dabrowska $allValues = $sqlite->queryAll($s); 257544dca1bSAnna Dabrowska 258544dca1bSAnna Dabrowska if (!empty($allValues)) { 259544dca1bSAnna Dabrowska foreach ($allValues as $row) { 260544dca1bSAnna Dabrowska list($pid, $rid, $rev, $colref, $rowno, $fixes) = $this->getFixedValues($row); 261544dca1bSAnna Dabrowska // now fix the values 262544dca1bSAnna Dabrowska if (!empty($fixes)) { 26317a3a578SAndreas Gohr $sql = "UPDATE data_$name 26417a3a578SAndreas Gohr SET " . implode(', ', $fixes) . " 26517a3a578SAndreas Gohr WHERE pid = ? 26617a3a578SAndreas Gohr AND rid = ? 26717a3a578SAndreas Gohr AND rev = ?"; 268544dca1bSAnna Dabrowska $params = [$pid, $rid, $rev]; 269544dca1bSAnna Dabrowska $ok = $ok && $sqlite->query($sql, $params); 270544dca1bSAnna Dabrowska } 271544dca1bSAnna Dabrowska } 272544dca1bSAnna Dabrowska } 273544dca1bSAnna Dabrowska 274544dca1bSAnna Dabrowska // multi_ tables 275544dca1bSAnna Dabrowska $s = "SELECT colref, pid, rid, rev, row, value FROM multi_$name"; 27679b29326SAnna Dabrowska $allValues = $sqlite->queryAll($s); 277544dca1bSAnna Dabrowska 278544dca1bSAnna Dabrowska if (!empty($allValues)) { 279544dca1bSAnna Dabrowska foreach ($allValues as $row) { 280544dca1bSAnna Dabrowska list($pid, $rid, $rev, $colref, $rowno, $fixes) = $this->getFixedValues($row); 281544dca1bSAnna Dabrowska // now fix the values 282544dca1bSAnna Dabrowska if (!empty($fixes)) { 28317a3a578SAndreas Gohr $sql = "UPDATE multi_$name 28417a3a578SAndreas Gohr SET " . implode(', ', $fixes) . " 28517a3a578SAndreas Gohr WHERE pid = ? 28617a3a578SAndreas Gohr AND rid = ? 28717a3a578SAndreas Gohr AND rev = ? 28817a3a578SAndreas Gohr AND colref = ? 28917a3a578SAndreas Gohr AND row = ?"; 290544dca1bSAnna Dabrowska $params = [$pid, $rid, $rev, $colref, $rowno]; 291544dca1bSAnna Dabrowska $ok = $ok && $sqlite->query($sql, $params); 292544dca1bSAnna Dabrowska } 293544dca1bSAnna Dabrowska } 294544dca1bSAnna Dabrowska } 295544dca1bSAnna Dabrowska } 296544dca1bSAnna Dabrowska } 297544dca1bSAnna Dabrowska 29879b29326SAnna Dabrowska return $ok; 299544dca1bSAnna Dabrowska } 300544dca1bSAnna Dabrowska 301544dca1bSAnna Dabrowska /** 302bbd79bccSAnna Dabrowska * Removes a temp table left over by migration 16 303bbd79bccSAnna Dabrowska * 30479b29326SAnna Dabrowska * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite 305bbd79bccSAnna Dabrowska * @return bool 306bbd79bccSAnna Dabrowska */ 30779b29326SAnna Dabrowska protected function migration18($sqlite) 308bbd79bccSAnna Dabrowska { 309bbd79bccSAnna Dabrowska $ok = true; 310bbd79bccSAnna Dabrowska 311bbd79bccSAnna Dabrowska $sql = 'DROP TABLE IF EXISTS temp_schemas'; 312bbd79bccSAnna Dabrowska $ok = $ok && $sqlite->query($sql); 313bbd79bccSAnna Dabrowska 31479b29326SAnna Dabrowska return $ok; 315bbd79bccSAnna Dabrowska } 316*66164365SAndreas Gohr 317fc6ac2e5SAnna Dabrowska /** 318fc6ac2e5SAnna Dabrowska * Executes Migration 19 319fc6ac2e5SAnna Dabrowska * 320fc6ac2e5SAnna Dabrowska * Add "published" column to all existing tables 321fc6ac2e5SAnna Dabrowska * 32279b29326SAnna Dabrowska * @param \dokuwiki\plugin\sqlite\SQLiteDB $sqlite 323fc6ac2e5SAnna Dabrowska * @return bool 324fc6ac2e5SAnna Dabrowska */ 32579b29326SAnna Dabrowska protected function migration19($sqlite) 326fc6ac2e5SAnna Dabrowska { 327fc6ac2e5SAnna Dabrowska $ok = true; 328fc6ac2e5SAnna Dabrowska 329fc6ac2e5SAnna Dabrowska /** @noinspection SqlResolve */ 330fc6ac2e5SAnna Dabrowska $sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND (name LIKE 'data_%' OR name LIKE 'multi_%')"; 33179b29326SAnna Dabrowska $tables = $sqlite->queryAll($sql); 332fc6ac2e5SAnna Dabrowska 333fc6ac2e5SAnna Dabrowska foreach ($tables as $row) { 334*66164365SAndreas Gohr $table = $row['name']; // no escaping needed, it's our own tables 335*66164365SAndreas Gohr $sql = "ALTER TABLE $table ADD COLUMN published INT DEFAULT NULL"; 336*66164365SAndreas Gohr $ok = $ok && $sqlite->query($sql); 337fc6ac2e5SAnna Dabrowska } 33879b29326SAnna Dabrowska return $ok; 339fc6ac2e5SAnna Dabrowska } 340fc6ac2e5SAnna Dabrowska 341bbd79bccSAnna Dabrowska 342bbd79bccSAnna Dabrowska /** 343544dca1bSAnna Dabrowska * Returns a select statement to fetch Lookup columns in the current schema 344544dca1bSAnna Dabrowska * 345544dca1bSAnna Dabrowska * @param int $sid Id of the schema 346544dca1bSAnna Dabrowska * @return string SQL statement 347544dca1bSAnna Dabrowska */ 348544dca1bSAnna Dabrowska protected function getLookupColsSql($sid) 349544dca1bSAnna Dabrowska { 350544dca1bSAnna Dabrowska return "SELECT C.colref AS COL, T.class AS TYPE 351544dca1bSAnna Dabrowska FROM schema_cols AS C 352544dca1bSAnna Dabrowska LEFT OUTER JOIN types AS T 353544dca1bSAnna Dabrowska ON C.tid = T.id 354544dca1bSAnna Dabrowska WHERE C.sid = $sid 355544dca1bSAnna Dabrowska AND TYPE LIKE '%Lookup' 356544dca1bSAnna Dabrowska "; 357544dca1bSAnna Dabrowska } 358544dca1bSAnna Dabrowska 359544dca1bSAnna Dabrowska /** 360544dca1bSAnna Dabrowska * Checks for improperly migrated values and returns an array with 361544dca1bSAnna Dabrowska * "<column> = <fixed-value>" fragments to be used in the UPDATE statement. 362544dca1bSAnna Dabrowska * 363544dca1bSAnna Dabrowska * @param array $row 364544dca1bSAnna Dabrowska * @return array 365544dca1bSAnna Dabrowska */ 366544dca1bSAnna Dabrowska protected function getFixedValues($row) 367544dca1bSAnna Dabrowska { 368544dca1bSAnna Dabrowska $pid = $row['pid']; 369544dca1bSAnna Dabrowska $rid = $row['rid']; 370544dca1bSAnna Dabrowska $rev = $row['rev']; 371544dca1bSAnna Dabrowska $colref = $row['colref']; 372544dca1bSAnna Dabrowska $rowno = $row['row']; 373544dca1bSAnna Dabrowska $fixes = []; 374544dca1bSAnna Dabrowska $matches = []; 375544dca1bSAnna Dabrowska 376544dca1bSAnna Dabrowska // check if anything needs to be fixed in data columns 377544dca1bSAnna Dabrowska foreach ($row as $col => $value) { 378544dca1bSAnna Dabrowska if (in_array($col, ['pid', 'rid', 'rev', 'colref', 'row'])) { 379544dca1bSAnna Dabrowska continue; 380544dca1bSAnna Dabrowska } 381544dca1bSAnna Dabrowska preg_match('/^\["",(?<pid>.*?\D+.*?)\]$/', $value, $matches); 382544dca1bSAnna Dabrowska if (!empty($matches['pid'])) { 383544dca1bSAnna Dabrowska $fixes[$col] = '["' . $matches['pid'] . '",0]'; 384544dca1bSAnna Dabrowska } 385544dca1bSAnna Dabrowska } 386544dca1bSAnna Dabrowska 387544dca1bSAnna Dabrowska if (!empty($fixes)) { 388544dca1bSAnna Dabrowska $fixes = array_map(function ($set, $key) { 389544dca1bSAnna Dabrowska return "$key = '$set'"; 390544dca1bSAnna Dabrowska }, $fixes, array_keys($fixes)); 391544dca1bSAnna Dabrowska } 392544dca1bSAnna Dabrowska 393544dca1bSAnna Dabrowska return [$pid, $rid, $rev, $colref, $rowno, $fixes]; 394544dca1bSAnna Dabrowska } 3958f259467SAndreas Gohr} 396