1<?php
2/**
3 * Move Plugin Page Rename Functionality
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <gohr@cosmocode.de>
7 */
8// must be run within Dokuwiki
9if(!defined('DOKU_INC')) die();
10
11/**
12 * Class action_plugin_move_rename
13 */
14class action_plugin_move_rename extends DokuWiki_Action_Plugin {
15
16    /**
17     * Register event handlers.
18     *
19     * @param Doku_Event_Handler $controller The plugin controller
20     */
21    public function register(Doku_Event_Handler $controller) {
22        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'handle_init');
23
24        // TODO: DEPRECATED JAN 2018
25        $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'handle_pagetools');
26
27        $controller->register_hook('MENU_ITEMS_ASSEMBLY', 'AFTER', $this, 'addsvgbutton', array());
28        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax');
29    }
30
31    /**
32     * set JavaScript info if renaming of current page is possible
33     */
34    public function handle_init() {
35        global $JSINFO;
36        global $INFO;
37        $JSINFO['move_renameokay'] = $this->renameOkay($INFO['id']);
38    }
39
40    /**
41     * Adds a button to the default template
42     *
43     * TODO: DEPRECATED JAN 2018
44     *
45     * @param Doku_Event $event
46     */
47    public function handle_pagetools(Doku_Event $event) {
48        if($event->data['view'] != 'main') return;
49        if (!$this->getConf('pagetools_integration')) {
50            return;
51        }
52
53        $newitem = '<li class="plugin_move_page"><a href=""><span>' . $this->getLang('renamepage') . '</span></a></li>';
54        $offset = count($event->data['items']) - 1;
55        $event->data['items'] =
56            array_slice($event->data['items'], 0, $offset, true) +
57            array('plugin_move' => $newitem) +
58            array_slice($event->data['items'], $offset, null, true);
59    }
60
61    /**
62     * Add 'rename' button to page tools, new SVG based mechanism
63     *
64     * @param Doku_Event $event
65     */
66    public function addsvgbutton(Doku_Event $event) {
67        global $INFO, $JSINFO;
68        if(
69            $event->data['view'] !== 'page' ||
70            !$this->getConf('pagetools_integration') ||
71            !$JSINFO['move_renameokay']
72        ) {
73            return;
74        }
75        if(!$INFO['exists']) {
76            return;
77        }
78        array_splice($event->data['items'], -1, 0, array(new \dokuwiki\plugin\move\MenuItem()));
79    }
80
81    /**
82     * Rename a single page
83     */
84    public function handle_ajax(Doku_Event $event) {
85        if($event->data != 'plugin_move_rename') return;
86        $event->preventDefault();
87        $event->stopPropagation();
88
89        global $MSG;
90        global $INPUT;
91
92        $src = cleanID($INPUT->str('id'));
93        $dst = cleanID($INPUT->str('newid'));
94
95        /** @var helper_plugin_move_op $MoveOperator */
96        $MoveOperator = plugin_load('helper', 'move_op');
97
98        $JSON = new JSON();
99
100        header('Content-Type: application/json');
101
102        if($this->renameOkay($src) && $MoveOperator->movePage($src, $dst)) {
103            // all went well, redirect
104            echo $JSON->encode(array('redirect_url' => wl($dst, '', true, '&')));
105        } else {
106            if(isset($MSG[0])) {
107                $error = $MSG[0]; // first error
108            } else {
109                $error = $this->getLang('cantrename');
110            }
111            echo $JSON->encode(array('error' => $error));
112        }
113    }
114
115    /**
116     * Determines if it would be okay to show a rename page button for the given page and current user
117     *
118     * @param $id
119     * @return bool
120     */
121    public function renameOkay($id) {
122        global $ACT;
123        global $USERINFO;
124        if(!($ACT == 'show' || empty($ACT))) return false;
125        if(!page_exists($id)) return false;
126        if(auth_quickaclcheck($id) < AUTH_EDIT) return false;
127        if(checklock($id) !== false || @file_exists(wikiLockFN($id))) return false;
128        if(!isset($_SERVER['REMOTE_USER'])) return false;
129        if(!auth_isMember($this->getConf('allowrename'), $_SERVER['REMOTE_USER'], (array) $USERINFO['grps'])) return false;
130
131        return true;
132    }
133
134    /**
135     * Use this in your template to add a simple "move this page" link
136     *
137     * Alternatively give anything the class "plugin_move_page" - it will automatically be hidden and shown and
138     * trigger the page move dialog.
139     */
140    public function tpl() {
141        echo '<a href="" class="plugin_move_page">';
142        echo $this->getLang('renamepage');
143        echo '</a>';
144    }
145
146}
147