xref: /plugin/approve/action/approve.php (revision bab7614807fca2209bc1b0be9a71e192a180a43a)
11aeb2b4dSghi<?php
21aeb2b4dSghi
3*bab76148SSzymon Olewniczakuse dokuwiki\plugin\approve\meta\ApproveConst;
41aeb2b4dSghi
51aeb2b4dSghiif(!defined('DOKU_INC')) die();
61aeb2b4dSghi
71aeb2b4dSghiclass action_plugin_approve_approve extends DokuWiki_Action_Plugin {
81aeb2b4dSghi
9*bab76148SSzymon Olewniczak    /** @var DokuWiki_PluginInterface */
10*bab76148SSzymon Olewniczak    protected $hlp;
11*bab76148SSzymon Olewniczak
1250481663SSzymon Olewniczak    function __construct(){
1350481663SSzymon Olewniczak        $this->hlp = plugin_load('helper', 'approve');
1450481663SSzymon Olewniczak    }
1550481663SSzymon Olewniczak
1650481663SSzymon Olewniczak    function register(Doku_Event_Handler $controller) {
1750481663SSzymon Olewniczak
1855f447f4SSzymon Olewniczak        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_approve', array());
1955f447f4SSzymon Olewniczak        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_viewer', array());
2055f447f4SSzymon Olewniczak        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, 'handle_diff_accept', array());
2155f447f4SSzymon Olewniczak        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'handle_display_banner', array());
2255f447f4SSzymon Olewniczak        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, 'handle_showrev', array());
23af3e3cd8SSzymon Olewniczak        // ensure a page revision is created when summary changes:
24af3e3cd8SSzymon Olewniczak        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before');
2555f447f4SSzymon Olewniczak        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handle_pagesave_after');
261aeb2b4dSghi    }
271aeb2b4dSghi
28d0c5854eSSzymon Olewniczak	function handle_diff_accept(Doku_Event $event, $param) {
2950481663SSzymon Olewniczak		global $ID;
3050481663SSzymon Olewniczak
3150481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
3250481663SSzymon Olewniczak
331aeb2b4dSghi		if ($event->data == 'diff' && isset($_GET['approve'])) {
341aeb2b4dSghi			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>');
351aeb2b4dSghi		}
3684047bdaSRuud
371173fda7SRuud        if ($event->data == 'diff' && isset($_GET['ready_for_approval']) && $this->getConf('ready_for_approval') === 1) {
3884047bdaSRuud			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&ready_for_approval=ready_for_approval">'.$this->getLang('approve_ready').'</a>');
3984047bdaSRuud		}
401aeb2b4dSghi	}
411aeb2b4dSghi
42d0c5854eSSzymon Olewniczak	function handle_showrev(Doku_Event $event, $param) {
4355f447f4SSzymon Olewniczak		global $REV;
441aeb2b4dSghi
451aeb2b4dSghi		$last = $this->find_lastest_approved();
461aeb2b4dSghi		if ($last == $REV)
471aeb2b4dSghi			$event->preventDefault();
481aeb2b4dSghi	}
491aeb2b4dSghi
501aeb2b4dSghi	function can_approve() {
511aeb2b4dSghi		global $ID;
522cf0ddf9Sghi		return auth_quickaclcheck($ID) >= AUTH_DELETE;
531aeb2b4dSghi	}
541aeb2b4dSghi
5584047bdaSRuud    function can_edit() {
5684047bdaSRuud		global $ID;
5784047bdaSRuud		return auth_quickaclcheck($ID) >= AUTH_EDIT;
5884047bdaSRuud	}
5984047bdaSRuud
60d0c5854eSSzymon Olewniczak	function handle_approve(Doku_Event $event, $param) {
6155f447f4SSzymon Olewniczak		global $ID;
6250481663SSzymon Olewniczak
6350481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
6450481663SSzymon Olewniczak
651aeb2b4dSghi		if ($event->data == 'show' && isset($_GET['approve'])) {
6638d03fbdSghi		    if ( ! $this->can_approve()) return;
6738d03fbdSghi
68af3e3cd8SSzymon Olewniczak		    //create new page revison
69*bab76148SSzymon Olewniczak            saveWikiText($ID, rawWiki($ID), ApproveConst::APPROVED);
701aeb2b4dSghi
711aeb2b4dSghi			header('Location: ?id='.$ID);
72*bab76148SSzymon Olewniczak		} elseif ($event->data == 'show' && isset($_GET['ready_for_approval'])) {
7384047bdaSRuud		    if ( ! $this->can_edit()) return;
7484047bdaSRuud
75*bab76148SSzymon Olewniczak            //create new page revison
76*bab76148SSzymon Olewniczak            saveWikiText($ID, rawWiki($ID), ApproveConst::READY_FOR_APPROVAL);
771aeb2b4dSghi
781aeb2b4dSghi            header('Location: ?id='.$ID);
791aeb2b4dSghi		}
8038d03fbdSghi	}
8155f447f4SSzymon Olewniczak
82d0c5854eSSzymon Olewniczak    function handle_viewer(Doku_Event $event, $param) {
8338d03fbdSghi        global $REV, $ID;
8438d03fbdSghi        if ($event->data != 'show') return;
85a99f41c6SRuud Habing        if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return;
861aeb2b4dSghi
871aeb2b4dSghi	    $last = $this->find_lastest_approved();
8838d03fbdSghi	    //no page is approved
8938d03fbdSghi		if ($last == -1) return;
9038d03fbdSghi		//approved page is the newest page
9138d03fbdSghi		if ($last == 0) return;
9238d03fbdSghi
9338d03fbdSghi		//if we are viewing lastest revision, show last approved
9438d03fbdSghi		if ($REV == 0) header("Location: ?id=$ID&rev=$last");
951aeb2b4dSghi	}
9655f447f4SSzymon Olewniczak
971aeb2b4dSghi	function find_lastest_approved() {
981aeb2b4dSghi		global $ID;
991aeb2b4dSghi		$m = p_get_metadata($ID);
1001aeb2b4dSghi		$sum = $m['last_change']['sum'];
101*bab76148SSzymon Olewniczak		if ($sum == ApproveConst::APPROVED)
1021aeb2b4dSghi			return 0;
1031aeb2b4dSghi
1041aeb2b4dSghi		$changelog = new PageChangeLog($ID);
105*bab76148SSzymon Olewniczak
1061aeb2b4dSghi		$chs = $changelog->getRevisions(0, 10000);
1071aeb2b4dSghi		foreach ($chs as $rev) {
1081aeb2b4dSghi			$ch = $changelog->getRevisionInfo($rev);
109*bab76148SSzymon Olewniczak			if ($ch['sum'] == ApproveConst::APPROVED)
1101aeb2b4dSghi				return $rev;
1111aeb2b4dSghi		}
1121aeb2b4dSghi		return -1;
1131aeb2b4dSghi	}
1141aeb2b4dSghi
115d0c5854eSSzymon Olewniczak    function handle_display_banner(Doku_Event $event, $param) {
1161aeb2b4dSghi		global $ID, $REV, $INFO;
1171aeb2b4dSghi
11850481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
1191aeb2b4dSghi        if ($event->data != 'show') return;
1201aeb2b4dSghi		if (!$INFO['exists']) return;
1211aeb2b4dSghi
122cf995419SSzymon Olewniczak		$sum = $this->hlp->page_sum($ID, $REV);
1231aeb2b4dSghi
12455f447f4SSzymon Olewniczak
12555f447f4SSzymon Olewniczak		$classes = array();
12655f447f4SSzymon Olewniczak		if ($this->getConf('prettyprint')) {
12755f447f4SSzymon Olewniczak		    $classes[] = 'plugin__approve_noprint';
12855f447f4SSzymon Olewniczak        }
12955f447f4SSzymon Olewniczak
130*bab76148SSzymon Olewniczak        if ($sum == ApproveConst::APPROVED) {
13155f447f4SSzymon Olewniczak		    $classes[] = 'plugin__approve_green';
132*bab76148SSzymon Olewniczak		} elseif ($sum == ApproveConst::READY_FOR_APPROVAL && $this->getConf('ready_for_approval')) {
133*bab76148SSzymon Olewniczak		    $classes[] = 'plugin__approve_ready';
13455f447f4SSzymon Olewniczak        } else {
13555f447f4SSzymon Olewniczak            $classes[] = 'plugin__approve_red';
13655f447f4SSzymon Olewniczak        }
13755f447f4SSzymon Olewniczak
13855f447f4SSzymon Olewniczak		ptln('<div id="plugin__approve" class="' . implode(' ', $classes) . '">');
1391aeb2b4dSghi
1401aeb2b4dSghi		tpl_pageinfo();
1411aeb2b4dSghi		ptln(' | ');
142274d699aSghi		$last_approved_rev = $this->find_lastest_approved();
143*bab76148SSzymon Olewniczak		if ($sum == ApproveConst::APPROVED) {
144*bab76148SSzymon Olewniczak		    $versions = p_get_metadata($ID, ApproveConst::METADATA_VERSIONS_KEY);
14555f447f4SSzymon Olewniczak		    if (!$versions) {
14655f447f4SSzymon Olewniczak                $versions = $this->render_metadata_for_approved_page($ID);
14755f447f4SSzymon Olewniczak            }
14855f447f4SSzymon Olewniczak            if (empty($REV)) {
14955f447f4SSzymon Olewniczak                $version = $versions[0];
15055f447f4SSzymon Olewniczak            } else {
15155f447f4SSzymon Olewniczak                $version = $versions[$REV];
15247b144feSSzymon Olewniczak            }
153af3e3cd8SSzymon Olewniczak
15455f447f4SSzymon Olewniczak			ptln('<strong>'.$this->getLang('approved').'</strong> (' . $this->getLang('version') .  ': ' . $version
15547b144feSSzymon Olewniczak                 . ')');
1561aeb2b4dSghi			if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
1571aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
158*bab76148SSzymon Olewniczak				ptln($this->getLang(p_get_metadata($ID, 'last_change sum') == ApproveConst::APPROVED ? 'newest_approved' : 'newest_draft'));
1591aeb2b4dSghi				ptln('</a>');
1601aeb2b4dSghi			} else if ($REV != 0 && $REV != $last_approved_rev) {
1611aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
1621aeb2b4dSghi				ptln($this->getLang('newest_approved'));
1631aeb2b4dSghi				ptln('</a>');
1641aeb2b4dSghi			}
1651aeb2b4dSghi		} else {
1661aeb2b4dSghi			ptln('<span>'.$this->getLang('draft').'</span>');
1671aeb2b4dSghi
168*bab76148SSzymon Olewniczak			if ($sum == ApproveConst::READY_FOR_APPROVAL && $this->getConf('ready_for_approval') === 1) {
16984047bdaSRuud				ptln('<span>| '.$this->getLang('marked_approve_ready').'</span>');
17084047bdaSRuud			}
17184047bdaSRuud
17284047bdaSRuud
173274d699aSghi			if ($last_approved_rev == -1) {
174274d699aSghi			    if ($REV != 0) {
175274d699aSghi				    ptln('<a href="'.wl($ID).'">');
176274d699aSghi				    	ptln($this->getLang('newest_draft'));
177274d699aSghi				    ptln('</a>');
178274d699aSghi				}
179274d699aSghi			} else {
1801aeb2b4dSghi				if ($last_approved_rev != 0)
1811aeb2b4dSghi					ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">');
1821aeb2b4dSghi				else
1831aeb2b4dSghi					ptln('<a href="'.wl($ID).'">');
1841aeb2b4dSghi
1851aeb2b4dSghi					ptln($this->getLang('newest_approved'));
1861aeb2b4dSghi				ptln('</a>');
1871aeb2b4dSghi			}
1881aeb2b4dSghi
189*bab76148SSzymon Olewniczak			if ($REV == 0 && $this->can_edit() && $sum != ApproveConst::READY_FOR_APPROVAL && $this->getConf('ready_for_approval') === 1) {
190*bab76148SSzymon Olewniczak				ptln(' | <a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
19184047bdaSRuud				'ready_for_approval' => 'ready_for_approval')).'">');
19284047bdaSRuud					ptln($this->getLang('approve_ready'));
19384047bdaSRuud				ptln('</a>');
19484047bdaSRuud			}
19584047bdaSRuud
1961aeb2b4dSghi			if ($REV == 0 && $this->can_approve()) {
197*bab76148SSzymon Olewniczak				ptln(' | <a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
1981aeb2b4dSghi				'approve' => 'approve')).'">');
1991aeb2b4dSghi					ptln($this->getLang('approve'));
2001aeb2b4dSghi				ptln('</a>');
2011aeb2b4dSghi			}
20284047bdaSRuud
20384047bdaSRuud
2041aeb2b4dSghi		}
2051aeb2b4dSghi		ptln('</div>');
2061aeb2b4dSghi	}
2071aeb2b4dSghi
208af3e3cd8SSzymon Olewniczak    /**
209af3e3cd8SSzymon Olewniczak     * Check if the page has to be changed
210af3e3cd8SSzymon Olewniczak     *
211af3e3cd8SSzymon Olewniczak     * @param Doku_Event $event  event object by reference
212af3e3cd8SSzymon Olewniczak     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
213af3e3cd8SSzymon Olewniczak     *                           handler was registered]
214af3e3cd8SSzymon Olewniczak     * @return void
215af3e3cd8SSzymon Olewniczak     */
216af3e3cd8SSzymon Olewniczak    public function handle_pagesave_before(Doku_Event $event, $param) {
21755f447f4SSzymon Olewniczak        global $REV;
218af3e3cd8SSzymon Olewniczak        $id = $event->data['id'];
219af3e3cd8SSzymon Olewniczak        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
220af3e3cd8SSzymon Olewniczak
221af3e3cd8SSzymon Olewniczak        //save page if summary is provided
222*bab76148SSzymon Olewniczak        if($event->data['summary'] == ApproveConst::APPROVED) {
223af3e3cd8SSzymon Olewniczak            $event->data['contentChanged'] = true;
22455f447f4SSzymon Olewniczak        }
22555f447f4SSzymon Olewniczak    }
226af3e3cd8SSzymon Olewniczak
22755f447f4SSzymon Olewniczak    /**
22855f447f4SSzymon Olewniczak     * @param Doku_Event $event
22955f447f4SSzymon Olewniczak     * @param            $param
23055f447f4SSzymon Olewniczak     */
23155f447f4SSzymon Olewniczak    public function handle_pagesave_after(Doku_Event $event, $param) {
23255f447f4SSzymon Olewniczak        global $REV;
23355f447f4SSzymon Olewniczak        $id = $event->data['id'];
23455f447f4SSzymon Olewniczak        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
235af3e3cd8SSzymon Olewniczak
23655f447f4SSzymon Olewniczak        //save page if summary is provided
237*bab76148SSzymon Olewniczak        if($event->data['summary'] == ApproveConst::APPROVED) {
23855f447f4SSzymon Olewniczak
239*bab76148SSzymon Olewniczak            $versions = p_get_metadata($id, ApproveConst::METADATA_VERSIONS_KEY);
24055f447f4SSzymon Olewniczak            //calculate versions
24155f447f4SSzymon Olewniczak            if (!$versions) {
24255f447f4SSzymon Olewniczak                $this->render_metadata_for_approved_page($id, $event->data['newRevision']);
243af3e3cd8SSzymon Olewniczak            } else {
24455f447f4SSzymon Olewniczak                $curver = $versions[0] + 1;
24555f447f4SSzymon Olewniczak                $versions[0] = $curver;
24655f447f4SSzymon Olewniczak                $versions[$event->data['newRevision']] = $curver;
247*bab76148SSzymon Olewniczak                p_set_metadata($id, array(ApproveConst::METADATA_VERSIONS_KEY => $versions));
24855f447f4SSzymon Olewniczak            }
24955f447f4SSzymon Olewniczak        }
250af3e3cd8SSzymon Olewniczak    }
251af3e3cd8SSzymon Olewniczak
252af3e3cd8SSzymon Olewniczak
253af3e3cd8SSzymon Olewniczak    /**
254af3e3cd8SSzymon Olewniczak     * Calculate current version
255af3e3cd8SSzymon Olewniczak     *
256af3e3cd8SSzymon Olewniczak     * @param $id
257*bab76148SSzymon Olewniczak     * @return array
258af3e3cd8SSzymon Olewniczak     */
25955f447f4SSzymon Olewniczak    protected function render_metadata_for_approved_page($id, $currev=false) {
26055f447f4SSzymon Olewniczak        if (!$currev) $currev = @filemtime(wikiFN($id));
26155f447f4SSzymon Olewniczak
26255f447f4SSzymon Olewniczak        $version = $this->approved($id);
26355f447f4SSzymon Olewniczak        //version for current page
26455f447f4SSzymon Olewniczak        $curver = $version + 1;
26555f447f4SSzymon Olewniczak        $versions = array(0 => $curver, $currev => $curver);
266af3e3cd8SSzymon Olewniczak
267af3e3cd8SSzymon Olewniczak        $changelog = new PageChangeLog($id);
268af3e3cd8SSzymon Olewniczak        $first = 0;
269af3e3cd8SSzymon Olewniczak        $num = 100;
270af3e3cd8SSzymon Olewniczak        while (count($revs = $changelog->getRevisions($first, $num)) > 0) {
271af3e3cd8SSzymon Olewniczak            foreach ($revs as $rev) {
272af3e3cd8SSzymon Olewniczak                $revInfo = $changelog->getRevisionInfo($rev);
273*bab76148SSzymon Olewniczak                if ($revInfo['sum'] == ApproveConst::APPROVED) {
27455f447f4SSzymon Olewniczak                    $versions[$rev] = $version;
27555f447f4SSzymon Olewniczak                    $version -= 1;
276af3e3cd8SSzymon Olewniczak                }
277af3e3cd8SSzymon Olewniczak            }
278af3e3cd8SSzymon Olewniczak            $first += $num;
279af3e3cd8SSzymon Olewniczak        }
280af3e3cd8SSzymon Olewniczak
281*bab76148SSzymon Olewniczak        p_set_metadata($id, array(ApproveConst::METADATA_VERSIONS_KEY => $versions));
28255f447f4SSzymon Olewniczak
28355f447f4SSzymon Olewniczak        return $versions;
284af3e3cd8SSzymon Olewniczak    }
285af3e3cd8SSzymon Olewniczak
28655f447f4SSzymon Olewniczak    /**
28755f447f4SSzymon Olewniczak     * Get the number of approved pages
28855f447f4SSzymon Olewniczak     * @param $id
28955f447f4SSzymon Olewniczak     * @return int
29055f447f4SSzymon Olewniczak     */
29155f447f4SSzymon Olewniczak    protected function approved($id) {
29255f447f4SSzymon Olewniczak        $count = 0;
29355f447f4SSzymon Olewniczak
29455f447f4SSzymon Olewniczak        $changelog = new PageChangeLog($id);
29555f447f4SSzymon Olewniczak        $first = 0;
29655f447f4SSzymon Olewniczak        $num = 100;
29755f447f4SSzymon Olewniczak        while (count($revs = $changelog->getRevisions($first, $num)) > 0) {
29855f447f4SSzymon Olewniczak            foreach ($revs as $rev) {
29955f447f4SSzymon Olewniczak                $revInfo = $changelog->getRevisionInfo($rev);
300*bab76148SSzymon Olewniczak                if ($revInfo['sum'] == ApproveConst::APPROVED) {
30155f447f4SSzymon Olewniczak                    $count += 1;
30255f447f4SSzymon Olewniczak                }
30355f447f4SSzymon Olewniczak            }
30455f447f4SSzymon Olewniczak            $first += $num;
30555f447f4SSzymon Olewniczak        }
30655f447f4SSzymon Olewniczak
30755f447f4SSzymon Olewniczak        return $count;
30855f447f4SSzymon Olewniczak    }
3091aeb2b4dSghi}
310