1<?php
2
3if(!defined('DOKU_INC')) die();
4
5use dokuwiki\Extension\Event;
6
7class action_plugin_publish_approve extends DokuWiki_Action_Plugin {
8
9    /**
10     * @var helper_plugin_publish
11     */
12    private $helper;
13
14    function __construct() {
15        $this->helper = plugin_load('helper', 'publish');
16    }
17
18    function register(Doku_Event_Handler $controller) {
19        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_io_write', array());
20        $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'approveNS', array());
21    }
22
23    function approveNS(Doku_Event &$event, $param) {
24        if ($event->data !== 'plugin_publish_approveNS') {
25            return;
26        }
27        //no other ajax call handlers needed
28        $event->stopPropagation();
29        $event->preventDefault();
30
31        //e.g. access additional request variables
32        global $INPUT; //available since release 2012-10-13 "Adora Belle"
33        $namespace = $INPUT->str('namespace');
34        $pages = $this->helper->getPagesFromNamespace($namespace);
35        $pages = $this->helper->removeSubnamespacePages($pages, $namespace);
36
37        global $ID, $INFO;
38        $original_id = $ID;
39        foreach ($pages as $page) {
40            $ID = $page[0];
41            $INFO = pageinfo();
42            if (!$this->helper->canApprove()) {
43                continue;
44            }
45            $this->addApproval();
46        }
47        $ID = $original_id;
48    }
49
50    function handle_io_write(Doku_Event &$event, $param) {
51        # This is the only hook I could find which runs on save,
52        # but late enough to have lastmod set (ACTION_ACT_PREPROCESS
53        # is too early)
54        global $ACT;
55        global $INPUT;
56        global $ID;
57
58        if ($ACT != 'show') {
59            return;
60        }
61
62        if (!$INPUT->has('publish_approve')) {
63            return;
64        }
65
66        if (!$this->helper->canApprove()) {
67            msg($this->getLang('wrong permissions to approve'), -1);
68            return;
69        }
70
71        $this->addApproval();
72        send_redirect(wl($ID, array('rev' => $this->helper->getRevision()), true, '&'));
73    }
74
75    function addApproval() {
76        global $USERINFO;
77        global $ID;
78        global $INFO;
79
80        if (!$INFO['exists']) {
81            msg($this->getLang('cannot approve a non-existing revision'), -1);
82            return;
83        }
84
85        $approvalRevision = $this->helper->getRevision();
86        $approvals = $this->helper->getApprovals();
87
88        if (!isset($approvals[$approvalRevision])) {
89            $approvals[$approvalRevision] = array();
90        }
91
92        $approvals[$approvalRevision][$INFO['client']] = array(
93            $INFO['client'],
94            $_SERVER['REMOTE_USER'],
95            $USERINFO['mail'],
96            time()
97        );
98
99        $success = p_set_metadata($ID, array('approval' => $approvals), true, true);
100        if ($success) {
101            msg($this->getLang('version approved'), 1);
102
103            $data = array();
104            $data['rev'] = $approvalRevision;
105            $data['id'] = $ID;
106            $data['approver'] = $_SERVER['REMOTE_USER'];
107            $data['approver_info'] = $USERINFO;
108            if ($this->getConf('send_mail_on_approve') && $this->helper->isRevisionApproved($approvalRevision)) {
109                /** @var action_plugin_publish_mail $mail */
110                $mail = plugin_load('action','publish_mail');
111                $mail->send_approve_mail();
112            }
113            Event::createAndTrigger('PLUGIN_PUBLISH_APPROVE', $data);
114        } else {
115            msg($this->getLang('cannot approve error'), -1);
116        }
117
118    }
119
120}
121