xref: /plugin/approve/action/approve.php (revision af3e3cd8978d221000bc1a1e65ffc674af729866)
11aeb2b4dSghi<?php
21aeb2b4dSghi
31aeb2b4dSghiif(!defined('DOKU_INC')) die();
41aeb2b4dSghidefine(APPROVED, 'Approved');
51aeb2b4dSghi
6*af3e3cd8SSzymon Olewniczakdefine(METADATA_VERSION_KEY, 'plugin_approve_version');
7*af3e3cd8SSzymon Olewniczak
81aeb2b4dSghiclass action_plugin_approve_approve extends DokuWiki_Action_Plugin {
91aeb2b4dSghi
1050481663SSzymon Olewniczak    private $hlp;
1150481663SSzymon Olewniczak    function __construct(){
1250481663SSzymon Olewniczak        $this->hlp = plugin_load('helper', 'approve');
1350481663SSzymon Olewniczak    }
1450481663SSzymon Olewniczak
1550481663SSzymon Olewniczak    function register(Doku_Event_Handler $controller) {
1650481663SSzymon Olewniczak
171aeb2b4dSghi        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_approve, array());
1838d03fbdSghi        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_viewer, array());
191aeb2b4dSghi        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, handle_diff_accept, array());
201aeb2b4dSghi        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array());
211aeb2b4dSghi        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, handle_showrev, array());
22*af3e3cd8SSzymon Olewniczak        // ensure a page revision is created when summary changes:
23*af3e3cd8SSzymon Olewniczak        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before');
24*af3e3cd8SSzymon Olewniczak        $controller->register_hook('PARSER_METADATA_RENDER', 'AFTER', $this, 'handle_parser_metadata_render');
251aeb2b4dSghi    }
261aeb2b4dSghi
27d0c5854eSSzymon Olewniczak	function handle_diff_accept(Doku_Event $event, $param) {
2850481663SSzymon Olewniczak		global $ID;
2950481663SSzymon Olewniczak
3050481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
3150481663SSzymon Olewniczak
321aeb2b4dSghi		if ($event->data == 'diff' && isset($_GET['approve'])) {
331aeb2b4dSghi			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>');
341aeb2b4dSghi		}
351aeb2b4dSghi	}
361aeb2b4dSghi
37d0c5854eSSzymon Olewniczak	function handle_showrev(Doku_Event $event, $param) {
381aeb2b4dSghi		global $ID, $REV;
391aeb2b4dSghi
401aeb2b4dSghi		$last = $this->find_lastest_approved();
411aeb2b4dSghi		if ($last == $REV)
421aeb2b4dSghi			$event->preventDefault();
431aeb2b4dSghi	}
441aeb2b4dSghi
451aeb2b4dSghi	function can_approve() {
461aeb2b4dSghi		global $ID;
472cf0ddf9Sghi		return auth_quickaclcheck($ID) >= AUTH_DELETE;
481aeb2b4dSghi	}
491aeb2b4dSghi
50d0c5854eSSzymon Olewniczak	function handle_approve(Doku_Event $event, $param) {
51c7f8f6c0Sghi		global $ID, $REV, $INFO;
5250481663SSzymon Olewniczak
5350481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
5450481663SSzymon Olewniczak
551aeb2b4dSghi		if ($event->data == 'show' && isset($_GET['approve'])) {
5638d03fbdSghi		    if ( ! $this->can_approve()) return;
5738d03fbdSghi
58*af3e3cd8SSzymon Olewniczak		    //create new page revison
59*af3e3cd8SSzymon Olewniczak            saveWikiText($ID, rawWiki($ID), APPROVED);
601aeb2b4dSghi
611aeb2b4dSghi			header('Location: ?id='.$ID);
621aeb2b4dSghi		}
6338d03fbdSghi	}
64d0c5854eSSzymon Olewniczak    function handle_viewer(Doku_Event $event, $param) {
6538d03fbdSghi        global $REV, $ID;
6638d03fbdSghi        if ($event->data != 'show') return;
67a99f41c6SRuud Habing        if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return;
681aeb2b4dSghi
691aeb2b4dSghi	    $last = $this->find_lastest_approved();
7038d03fbdSghi	    //no page is approved
7138d03fbdSghi		if ($last == -1) return;
7238d03fbdSghi		//approved page is the newest page
7338d03fbdSghi		if ($last == 0) return;
7438d03fbdSghi
7538d03fbdSghi		//if we are viewing lastest revision, show last approved
7638d03fbdSghi		if ($REV == 0) header("Location: ?id=$ID&rev=$last");
771aeb2b4dSghi	}
781aeb2b4dSghi	function find_lastest_approved() {
791aeb2b4dSghi		global $ID;
801aeb2b4dSghi		$m = p_get_metadata($ID);
811aeb2b4dSghi		$sum = $m['last_change']['sum'];
821aeb2b4dSghi		if ($sum == APPROVED)
831aeb2b4dSghi			return 0;
841aeb2b4dSghi
851aeb2b4dSghi		$changelog = new PageChangeLog($ID);
861aeb2b4dSghi		//wyszukaj najnowszej zatwierdzonej
871aeb2b4dSghi		//poszukaj w dół
881aeb2b4dSghi		$chs = $changelog->getRevisions(0, 10000);
891aeb2b4dSghi		foreach ($chs as $rev) {
901aeb2b4dSghi			$ch = $changelog->getRevisionInfo($rev);
911aeb2b4dSghi			if ($ch['sum'] == APPROVED)
921aeb2b4dSghi				return $rev;
931aeb2b4dSghi		}
941aeb2b4dSghi		return -1;
951aeb2b4dSghi	}
961aeb2b4dSghi
97d0c5854eSSzymon Olewniczak    function handle_display_banner(Doku_Event $event, $param) {
981aeb2b4dSghi		global $ID, $REV, $INFO;
991aeb2b4dSghi
10050481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
1011aeb2b4dSghi        if ($event->data != 'show') return;
1021aeb2b4dSghi		if (!$INFO['exists']) return;
1031aeb2b4dSghi
104cf995419SSzymon Olewniczak		$sum = $this->hlp->page_sum($ID, $REV);
1051aeb2b4dSghi
1061aeb2b4dSghi		ptln('<div class="approval '.($sum == APPROVED ? 'approved_yes' : 'approved_no').'">');
1071aeb2b4dSghi
1081aeb2b4dSghi		tpl_pageinfo();
1091aeb2b4dSghi		ptln(' | ');
110274d699aSghi		$last_approved_rev = $this->find_lastest_approved();
1111aeb2b4dSghi		if ($sum == APPROVED) {
112*af3e3cd8SSzymon Olewniczak		    $version = p_get_metadata($ID, METADATA_VERSION_KEY);
113*af3e3cd8SSzymon Olewniczak
114*af3e3cd8SSzymon Olewniczak			ptln('<span>'.$this->getLang('approved').' (' . $this->getLang('version') .  ': ' . $version
115*af3e3cd8SSzymon Olewniczak                 . ')</span>');
1161aeb2b4dSghi			if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
1171aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
118*af3e3cd8SSzymon Olewniczak				ptln($this->getLang(p_get_metadata($ID, 'last_change sum') == APPROVED ? 'newest_approved' : 'newest_draft'));
1191aeb2b4dSghi				ptln('</a>');
1201aeb2b4dSghi			} else if ($REV != 0 && $REV != $last_approved_rev) {
1211aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
1221aeb2b4dSghi				ptln($this->getLang('newest_approved'));
1231aeb2b4dSghi				ptln('</a>');
1241aeb2b4dSghi			}
1251aeb2b4dSghi		} else {
1261aeb2b4dSghi			ptln('<span>'.$this->getLang('draft').'</span>');
1271aeb2b4dSghi
128274d699aSghi			if ($last_approved_rev == -1) {
129274d699aSghi			    if ($REV != 0) {
130274d699aSghi				    ptln('<a href="'.wl($ID).'">');
131274d699aSghi				    	ptln($this->getLang('newest_draft'));
132274d699aSghi				    ptln('</a>');
133274d699aSghi				}
134274d699aSghi			} else {
1351aeb2b4dSghi				if ($last_approved_rev != 0)
1361aeb2b4dSghi					ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">');
1371aeb2b4dSghi				else
1381aeb2b4dSghi					ptln('<a href="'.wl($ID).'">');
1391aeb2b4dSghi
1401aeb2b4dSghi					ptln($this->getLang('newest_approved'));
1411aeb2b4dSghi				ptln('</a>');
1421aeb2b4dSghi			}
1431aeb2b4dSghi
1441aeb2b4dSghi			//można zatwierdzać tylko najnowsze strony
1451aeb2b4dSghi			if ($REV == 0 && $this->can_approve()) {
1461aeb2b4dSghi				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
1471aeb2b4dSghi				'approve' => 'approve')).'">');
1481aeb2b4dSghi					ptln($this->getLang('approve'));
1491aeb2b4dSghi				ptln('</a>');
1501aeb2b4dSghi			}
1511aeb2b4dSghi		}
1521aeb2b4dSghi		ptln('</div>');
1531aeb2b4dSghi	}
1541aeb2b4dSghi
155*af3e3cd8SSzymon Olewniczak    /**
156*af3e3cd8SSzymon Olewniczak     * Check if the page has to be changed
157*af3e3cd8SSzymon Olewniczak     *
158*af3e3cd8SSzymon Olewniczak     * @param Doku_Event $event  event object by reference
159*af3e3cd8SSzymon Olewniczak     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
160*af3e3cd8SSzymon Olewniczak     *                           handler was registered]
161*af3e3cd8SSzymon Olewniczak     * @return void
162*af3e3cd8SSzymon Olewniczak     */
163*af3e3cd8SSzymon Olewniczak    public function handle_pagesave_before(Doku_Event $event, $param) {
164*af3e3cd8SSzymon Olewniczak        $id = $event->data['id'];
165*af3e3cd8SSzymon Olewniczak        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
166*af3e3cd8SSzymon Olewniczak
167*af3e3cd8SSzymon Olewniczak        //save page if summary is provided
168*af3e3cd8SSzymon Olewniczak        if($event->data['summary'] == APPROVED) {
169*af3e3cd8SSzymon Olewniczak            $event->data['contentChanged'] = true;
170*af3e3cd8SSzymon Olewniczak
171*af3e3cd8SSzymon Olewniczak            $version = p_get_metadata($id, METADATA_VERSION_KEY);
172*af3e3cd8SSzymon Olewniczak
173*af3e3cd8SSzymon Olewniczak            //calculate current version
174*af3e3cd8SSzymon Olewniczak            if (!$version) {
175*af3e3cd8SSzymon Olewniczak                $version = $this->calculateVersion($id);
176*af3e3cd8SSzymon Olewniczak            } else {
177*af3e3cd8SSzymon Olewniczak                $version += 1;
178*af3e3cd8SSzymon Olewniczak            }
179*af3e3cd8SSzymon Olewniczak
180*af3e3cd8SSzymon Olewniczak            p_set_metadata($id, array(METADATA_VERSION_KEY => $version));
181*af3e3cd8SSzymon Olewniczak        }
182*af3e3cd8SSzymon Olewniczak    }
183*af3e3cd8SSzymon Olewniczak
184*af3e3cd8SSzymon Olewniczak    /**
185*af3e3cd8SSzymon Olewniczak     * Check if the page has to be changed
186*af3e3cd8SSzymon Olewniczak     *
187*af3e3cd8SSzymon Olewniczak     * @param Doku_Event $event  event object by reference
188*af3e3cd8SSzymon Olewniczak     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
189*af3e3cd8SSzymon Olewniczak     *                           handler was registered]
190*af3e3cd8SSzymon Olewniczak     * @return void
191*af3e3cd8SSzymon Olewniczak     */
192*af3e3cd8SSzymon Olewniczak    public function handle_parser_metadata_render(Doku_Event $event, $param) {
193*af3e3cd8SSzymon Olewniczak        global $ID;
194*af3e3cd8SSzymon Olewniczak        $id = $ID;
195*af3e3cd8SSzymon Olewniczak        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
196*af3e3cd8SSzymon Olewniczak
197*af3e3cd8SSzymon Olewniczak        if (!isset($event->data['persistent'][METADATA_VERSION_KEY])) {
198*af3e3cd8SSzymon Olewniczak            $event->data['persistent'][METADATA_VERSION_KEY] = $this->calculateVersion($id);
199*af3e3cd8SSzymon Olewniczak        }
200*af3e3cd8SSzymon Olewniczak
201*af3e3cd8SSzymon Olewniczak
202*af3e3cd8SSzymon Olewniczak    }
203*af3e3cd8SSzymon Olewniczak
204*af3e3cd8SSzymon Olewniczak    /**
205*af3e3cd8SSzymon Olewniczak     * Calculate current version
206*af3e3cd8SSzymon Olewniczak     *
207*af3e3cd8SSzymon Olewniczak     * @param $id
208*af3e3cd8SSzymon Olewniczak     * @return int
209*af3e3cd8SSzymon Olewniczak     */
210*af3e3cd8SSzymon Olewniczak    protected function calculateVersion($id) {
211*af3e3cd8SSzymon Olewniczak        $version = 1;
212*af3e3cd8SSzymon Olewniczak
213*af3e3cd8SSzymon Olewniczak        $changelog = new PageChangeLog($id);
214*af3e3cd8SSzymon Olewniczak        $first = 0;
215*af3e3cd8SSzymon Olewniczak        $num = 100;
216*af3e3cd8SSzymon Olewniczak        while (count($revs = $changelog->getRevisions($first, $num)) > 0) {
217*af3e3cd8SSzymon Olewniczak            foreach ($revs as $rev) {
218*af3e3cd8SSzymon Olewniczak                $revInfo = $changelog->getRevisionInfo($rev);
219*af3e3cd8SSzymon Olewniczak                if ($revInfo['sum'] == APPROVED) {
220*af3e3cd8SSzymon Olewniczak                    $version += 1;
221*af3e3cd8SSzymon Olewniczak                }
222*af3e3cd8SSzymon Olewniczak            }
223*af3e3cd8SSzymon Olewniczak            $first += $num;
224*af3e3cd8SSzymon Olewniczak        }
225*af3e3cd8SSzymon Olewniczak
226*af3e3cd8SSzymon Olewniczak        return $version;
227*af3e3cd8SSzymon Olewniczak    }
228*af3e3cd8SSzymon Olewniczak
2291aeb2b4dSghi}
230