xref: /plugin/struct/action/move.php (revision 07e481057ffda38c2a6654063f79614d606231f3)
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