10173e75dSAndreas Gohr<?php 20173e75dSAndreas Gohr/** 30173e75dSAndreas Gohr * DokuWiki Plugin struct (Action Component) 40173e75dSAndreas Gohr * 50173e75dSAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 60173e75dSAndreas Gohr * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 70173e75dSAndreas Gohr */ 80173e75dSAndreas Gohr 90173e75dSAndreas Gohr// must be run within Dokuwiki 10ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Assignments; 11*5a1a3bb1SAndreas Gohruse dokuwiki\plugin\struct\meta\Column; 12ba766201SAndreas Gohruse dokuwiki\plugin\struct\meta\Schema; 13*5a1a3bb1SAndreas Gohruse dokuwiki\plugin\struct\types\Lookup; 14*5a1a3bb1SAndreas Gohruse dokuwiki\plugin\struct\types\Page; 150173e75dSAndreas Gohr 160173e75dSAndreas Gohrif(!defined('DOKU_INC')) die(); 170173e75dSAndreas Gohr 180173e75dSAndreas Gohrclass action_plugin_struct_move extends DokuWiki_Action_Plugin { 190173e75dSAndreas Gohr 20*5a1a3bb1SAndreas Gohr /** @var helper_plugin_sqlite */ 21*5a1a3bb1SAndreas Gohr protected $db = null; 22*5a1a3bb1SAndreas Gohr 230173e75dSAndreas Gohr /** 240173e75dSAndreas Gohr * Registers a callback function for a given event 250173e75dSAndreas Gohr * 260173e75dSAndreas Gohr * @param Doku_Event_Handler $controller DokuWiki's event controller object 270173e75dSAndreas Gohr * @return void 280173e75dSAndreas Gohr */ 290173e75dSAndreas Gohr public function register(Doku_Event_Handler $controller) { 300173e75dSAndreas Gohr $controller->register_hook('PLUGIN_MOVE_PAGE_RENAME', 'AFTER', $this, 'handle_move'); 310173e75dSAndreas Gohr } 320173e75dSAndreas Gohr 330173e75dSAndreas Gohr /** 340173e75dSAndreas Gohr * Renames all occurances of a page ID in the database 350173e75dSAndreas Gohr * 360173e75dSAndreas Gohr * @param Doku_Event $event event object by reference 370173e75dSAndreas Gohr * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 380173e75dSAndreas Gohr * handler was registered] 390173e75dSAndreas Gohr * @return bool 400173e75dSAndreas Gohr */ 410173e75dSAndreas Gohr public function handle_move(Doku_Event $event, $param) { 420173e75dSAndreas Gohr /** @var helper_plugin_struct_db $hlp */ 430173e75dSAndreas Gohr $hlp = plugin_load('helper', 'struct_db'); 44*5a1a3bb1SAndreas Gohr $this->db = $hlp->getDB(false); 45*5a1a3bb1SAndreas Gohr if(!$this->db) return false; 460173e75dSAndreas Gohr $old = $event->data['src_id']; 470173e75dSAndreas Gohr $new = $event->data['dst_id']; 480173e75dSAndreas Gohr 49*5a1a3bb1SAndreas Gohr // general update of our meta tables 50*5a1a3bb1SAndreas Gohr $this->updateDataTablePIDs($old, $new); 51*5a1a3bb1SAndreas Gohr $this->updateAssignments($old, $new); 52*5a1a3bb1SAndreas Gohr $this->updateTitles($old, $new); 5307e48105SAndreas Gohr 54*5a1a3bb1SAndreas Gohr // apply updates to all columns in all schemas depending on type 55*5a1a3bb1SAndreas Gohr $schemas = Schema::getAll(); 56*5a1a3bb1SAndreas Gohr foreach($schemas as $table) { 57*5a1a3bb1SAndreas Gohr $schema = new Schema($table); 58*5a1a3bb1SAndreas Gohr foreach($schema->getColumns() as $col) { 59*5a1a3bb1SAndreas Gohr switch(get_class($col->getType())) { 60*5a1a3bb1SAndreas Gohr case Page::class: 61*5a1a3bb1SAndreas Gohr $this->updateColumnPage($schema, $col, $old, $new); 62*5a1a3bb1SAndreas Gohr break; 63*5a1a3bb1SAndreas Gohr case Lookup::class: 64*5a1a3bb1SAndreas Gohr $this->updateColumnLookup($schema, $col, $old, $new); 65*5a1a3bb1SAndreas Gohr break; 660173e75dSAndreas Gohr } 67*5a1a3bb1SAndreas Gohr } 68*5a1a3bb1SAndreas Gohr } 690173e75dSAndreas Gohr 70*5a1a3bb1SAndreas Gohr // FIXME we need to update Media Type fields on media move 71*5a1a3bb1SAndreas Gohr // FIXME we should wrap all this in a transaction 7207e48105SAndreas Gohr 730173e75dSAndreas Gohr return true; 740173e75dSAndreas Gohr } 7507e48105SAndreas Gohr 7607e48105SAndreas Gohr /** 77*5a1a3bb1SAndreas Gohr * Update the pid column of ALL data tables 7807e48105SAndreas Gohr * 79*5a1a3bb1SAndreas Gohr * (we don't trust the assigments are still there) 80*5a1a3bb1SAndreas Gohr * 81*5a1a3bb1SAndreas Gohr * @param string $old old page id 82*5a1a3bb1SAndreas Gohr * @param string $new new page id 8307e48105SAndreas Gohr */ 84*5a1a3bb1SAndreas Gohr protected function updateDataTablePIDs($old, $new) { 85*5a1a3bb1SAndreas Gohr foreach(Schema::getAll('page') as $tbl) { 86*5a1a3bb1SAndreas Gohr /** @noinspection SqlResolve */ 87*5a1a3bb1SAndreas Gohr $sql = "UPDATE data_$tbl SET pid = ? WHERE pid = ?"; 88*5a1a3bb1SAndreas Gohr $this->db->query($sql, array($new, $old)); 8907e48105SAndreas Gohr 90*5a1a3bb1SAndreas Gohr /** @noinspection SqlResolve */ 91*5a1a3bb1SAndreas Gohr $sql = "UPDATE multi_$tbl SET pid = ? WHERE pid = ?"; 92*5a1a3bb1SAndreas Gohr $this->db->query($sql, array($new, $old)); 93*5a1a3bb1SAndreas Gohr } 94*5a1a3bb1SAndreas Gohr } 9507e48105SAndreas Gohr 96*5a1a3bb1SAndreas Gohr /** 97*5a1a3bb1SAndreas Gohr * Update the page-schema assignments 98*5a1a3bb1SAndreas Gohr * 99*5a1a3bb1SAndreas Gohr * @param string $old old page id 100*5a1a3bb1SAndreas Gohr * @param string $new new page id 101*5a1a3bb1SAndreas Gohr */ 102*5a1a3bb1SAndreas Gohr protected function updateAssignments($old, $new) { 103*5a1a3bb1SAndreas Gohr // assignments 104*5a1a3bb1SAndreas Gohr $sql = "UPDATE schema_assignments SET pid = ? WHERE pid = ?"; 105*5a1a3bb1SAndreas Gohr $this->db->query($sql, array($new, $old)); 106*5a1a3bb1SAndreas Gohr // make sure assignments still match patterns; 107*5a1a3bb1SAndreas Gohr $assignments = Assignments::getInstance(); 108*5a1a3bb1SAndreas Gohr $assignments->reevaluatePageAssignments($new); 109*5a1a3bb1SAndreas Gohr } 110*5a1a3bb1SAndreas Gohr 111*5a1a3bb1SAndreas Gohr /** 112*5a1a3bb1SAndreas Gohr * Update the Title information for the moved page 113*5a1a3bb1SAndreas Gohr * 114*5a1a3bb1SAndreas Gohr * @param string $old old page id 115*5a1a3bb1SAndreas Gohr * @param string $new new page id 116*5a1a3bb1SAndreas Gohr */ 117*5a1a3bb1SAndreas Gohr protected function updateTitles($old, $new) { 118*5a1a3bb1SAndreas Gohr $sql = "UPDATE titles SET pid = ? WHERE pid = ?"; 119*5a1a3bb1SAndreas Gohr $this->db->query($sql, array($new, $old)); 120*5a1a3bb1SAndreas Gohr } 121*5a1a3bb1SAndreas Gohr 122*5a1a3bb1SAndreas Gohr /** 123*5a1a3bb1SAndreas Gohr * Update a Page type column 124*5a1a3bb1SAndreas Gohr * 125*5a1a3bb1SAndreas Gohr * @param Schema $schema 126*5a1a3bb1SAndreas Gohr * @param Column $col 127*5a1a3bb1SAndreas Gohr * @param string $old old page id 128*5a1a3bb1SAndreas Gohr * @param string $new new page id 129*5a1a3bb1SAndreas Gohr */ 130*5a1a3bb1SAndreas Gohr protected function updateColumnPage(Schema $schema, Column $col, $old, $new) { 13107e48105SAndreas Gohr $colref = $col->getColref(); 132*5a1a3bb1SAndreas Gohr $table = $schema->getTable(); 133*5a1a3bb1SAndreas Gohr 13407e48105SAndreas Gohr if($col->isMulti()) { 13507e48105SAndreas Gohr /** @noinspection SqlResolve */ 13607e48105SAndreas Gohr $sql = "UPDATE multi_$table 13707e48105SAndreas Gohr SET value = REPLACE(value, ?, ?) 13807e48105SAndreas Gohr WHERE value LIKE ? 13907e48105SAndreas Gohr AND colref = $colref 14007e48105SAndreas Gohr AND latest = 1"; 14107e48105SAndreas Gohr 14207e48105SAndreas Gohr } else { 14307e48105SAndreas Gohr /** @noinspection SqlResolve */ 14407e48105SAndreas Gohr $sql = "UPDATE data_$table 14507e48105SAndreas Gohr SET col$colref = REPLACE(col$colref, ?, ?) 14607e48105SAndreas Gohr WHERE col$colref LIKE ? 14707e48105SAndreas Gohr AND latest = 1"; 14807e48105SAndreas Gohr } 149*5a1a3bb1SAndreas Gohr $this->db->query($sql, $old, $new, $old); // exact match 150*5a1a3bb1SAndreas Gohr $this->db->query($sql, $old, $new, "$old#%"); // match with hashes 15107e48105SAndreas Gohr } 152*5a1a3bb1SAndreas Gohr 153*5a1a3bb1SAndreas Gohr /** 154*5a1a3bb1SAndreas Gohr * Update a Lookup type column 155*5a1a3bb1SAndreas Gohr * 156*5a1a3bb1SAndreas Gohr * Lookups contain a page id when the referenced schema is a data schema 157*5a1a3bb1SAndreas Gohr * 158*5a1a3bb1SAndreas Gohr * @param Schema $schema 159*5a1a3bb1SAndreas Gohr * @param Column $col 160*5a1a3bb1SAndreas Gohr * @param string $old old page id 161*5a1a3bb1SAndreas Gohr * @param string $new new page id 162*5a1a3bb1SAndreas Gohr */ 163*5a1a3bb1SAndreas Gohr protected function updateColumnLookup(Schema $schema, Column $col, $old, $new) { 164*5a1a3bb1SAndreas Gohr $tconf = $col->getType()->getConfig(); 165*5a1a3bb1SAndreas Gohr $ref = new Schema($tconf['schema']); 166*5a1a3bb1SAndreas Gohr if(!$ref->getId()) return; // this schema does not exist 167*5a1a3bb1SAndreas Gohr if($ref->isLookup()) return; // a lookup is referenced, nothing to do 168*5a1a3bb1SAndreas Gohr 169*5a1a3bb1SAndreas Gohr // after the checks it's basically the same as a Page type column 170*5a1a3bb1SAndreas Gohr $this->updateColumnPage($schema, $col, $old, $new); 17107e48105SAndreas Gohr } 1720173e75dSAndreas Gohr} 173