1<?php 2/** 3 * DokuWiki Plugin struct (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr, Michael Große <dokuwiki@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10use dokuwiki\plugin\struct\meta\Assignments; 11use dokuwiki\plugin\struct\meta\Schema; 12 13if(!defined('DOKU_INC')) die(); 14 15class action_plugin_struct_move extends DokuWiki_Action_Plugin { 16 17 /** 18 * Registers a callback function for a given event 19 * 20 * @param Doku_Event_Handler $controller DokuWiki's event controller object 21 * @return void 22 */ 23 public function register(Doku_Event_Handler $controller) { 24 $controller->register_hook('PLUGIN_MOVE_PAGE_RENAME', 'AFTER', $this, 'handle_move'); 25 } 26 27 /** 28 * Renames all occurances of a page ID in the database 29 * 30 * @param Doku_Event $event event object by reference 31 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 32 * handler was registered] 33 * @return bool 34 */ 35 public function handle_move(Doku_Event $event, $param) { 36 /** @var helper_plugin_struct_db $hlp */ 37 $hlp = plugin_load('helper', 'struct_db'); 38 $db = $hlp->getDB(false); 39 if(!$db) return false; 40 $old = $event->data['src_id']; 41 $new = $event->data['dst_id']; 42 43 // ALL data tables (we don't trust the assigments are still there) 44 foreach(Schema::getAll('page') as $tbl) { 45 /** @noinspection SqlResolve */ 46 $sql = "UPDATE data_$tbl SET pid = ? WHERE pid = ?"; 47 $db->query($sql, array($new, $old)); 48 49 /** @noinspection SqlResolve */ 50 $sql = "UPDATE multi_$tbl SET pid = ? WHERE pid = ?"; 51 $db->query($sql, array($new, $old)); 52 } 53 // assignments 54 $sql = "UPDATE schema_assignments SET pid = ? WHERE pid = ?"; 55 $db->query($sql, array($new, $old)); 56 // make sure assignments still match patterns; 57 $assignments = Assignments::getInstance(); 58 $assignments->reevaluatePageAssignments($new); 59 60 // titles 61 $sql = "UPDATE titles SET pid = ? WHERE pid = ?"; 62 $db->query($sql, array($new, $old)); 63 64 // Page Type references 65 $this->movePageLinks($db, $old, $new); 66 67 return true; 68 } 69 70 /** 71 * Handles current values for all Page type columns 72 * 73 * @param helper_plugin_sqlite $db 74 * @param string $old 75 * @param string $new 76 */ 77 protected function movePageLinks(helper_plugin_sqlite $db, $old, $new) { 78 $schemas = Schema::getAll(); 79 80 foreach($schemas as $table) { 81 $schema = new Schema($table); 82 foreach($schema->getColumns() as $col) { 83 if(!is_a($col->getType(), dokuwiki\plugin\struct\types\Page::class)) continue; 84 85 $colref = $col->getColref(); 86 if($col->isMulti()) { 87 /** @noinspection SqlResolve */ 88 $sql = "UPDATE multi_$table 89 SET value = REPLACE(value, ?, ?) 90 WHERE value LIKE ? 91 AND colref = $colref 92 AND latest = 1"; 93 94 } else { 95 /** @noinspection SqlResolve */ 96 $sql = "UPDATE data_$table 97 SET col$colref = REPLACE(col$colref, ?, ?) 98 WHERE col$colref LIKE ? 99 AND latest = 1"; 100 } 101 $db->query($sql, $old, $new, $old); // exact match 102 $db->query($sql, $old, $new, "$old#%"); // match with hashes 103 } 104 } 105 } 106} 107