xref: /plugin/approve/action/approve.php (revision 55f447f4b2c788699fdccdbce99e3ff91d5d0e1c)
11aeb2b4dSghi<?php
21aeb2b4dSghi
31aeb2b4dSghiif(!defined('DOKU_INC')) die();
41aeb2b4dSghidefine(APPROVED, 'Approved');
51aeb2b4dSghi
6*55f447f4SSzymon Olewniczakdefine(METADATA_VERSIONS_KEY, 'plugin_approve_versions');
7af3e3cd8SSzymon 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
17*55f447f4SSzymon Olewniczak        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_approve', array());
18*55f447f4SSzymon Olewniczak        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_viewer', array());
19*55f447f4SSzymon Olewniczak        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, 'handle_diff_accept', array());
20*55f447f4SSzymon Olewniczak        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'handle_display_banner', array());
21*55f447f4SSzymon Olewniczak        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, 'handle_showrev', array());
22af3e3cd8SSzymon Olewniczak        // ensure a page revision is created when summary changes:
23af3e3cd8SSzymon Olewniczak        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before');
24*55f447f4SSzymon Olewniczak        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handle_pagesave_after');
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) {
38*55f447f4SSzymon Olewniczak		global $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) {
51*55f447f4SSzymon Olewniczak		global $ID;
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
58af3e3cd8SSzymon Olewniczak		    //create new page revison
59af3e3cd8SSzymon Olewniczak            saveWikiText($ID, rawWiki($ID), APPROVED);
601aeb2b4dSghi
611aeb2b4dSghi			header('Location: ?id='.$ID);
621aeb2b4dSghi		}
6338d03fbdSghi	}
64*55f447f4SSzymon Olewniczak
65d0c5854eSSzymon Olewniczak    function handle_viewer(Doku_Event $event, $param) {
6638d03fbdSghi        global $REV, $ID;
6738d03fbdSghi        if ($event->data != 'show') return;
68a99f41c6SRuud Habing        if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return;
691aeb2b4dSghi
701aeb2b4dSghi	    $last = $this->find_lastest_approved();
7138d03fbdSghi	    //no page is approved
7238d03fbdSghi		if ($last == -1) return;
7338d03fbdSghi		//approved page is the newest page
7438d03fbdSghi		if ($last == 0) return;
7538d03fbdSghi
7638d03fbdSghi		//if we are viewing lastest revision, show last approved
7738d03fbdSghi		if ($REV == 0) header("Location: ?id=$ID&rev=$last");
781aeb2b4dSghi	}
79*55f447f4SSzymon Olewniczak
801aeb2b4dSghi	function find_lastest_approved() {
811aeb2b4dSghi		global $ID;
821aeb2b4dSghi		$m = p_get_metadata($ID);
831aeb2b4dSghi		$sum = $m['last_change']['sum'];
841aeb2b4dSghi		if ($sum == APPROVED)
851aeb2b4dSghi			return 0;
861aeb2b4dSghi
871aeb2b4dSghi		$changelog = new PageChangeLog($ID);
881aeb2b4dSghi		//wyszukaj najnowszej zatwierdzonej
891aeb2b4dSghi		//poszukaj w dół
901aeb2b4dSghi		$chs = $changelog->getRevisions(0, 10000);
911aeb2b4dSghi		foreach ($chs as $rev) {
921aeb2b4dSghi			$ch = $changelog->getRevisionInfo($rev);
931aeb2b4dSghi			if ($ch['sum'] == APPROVED)
941aeb2b4dSghi				return $rev;
951aeb2b4dSghi		}
961aeb2b4dSghi		return -1;
971aeb2b4dSghi	}
981aeb2b4dSghi
99d0c5854eSSzymon Olewniczak    function handle_display_banner(Doku_Event $event, $param) {
1001aeb2b4dSghi		global $ID, $REV, $INFO;
1011aeb2b4dSghi
10250481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
1031aeb2b4dSghi        if ($event->data != 'show') return;
1041aeb2b4dSghi		if (!$INFO['exists']) return;
1051aeb2b4dSghi
106cf995419SSzymon Olewniczak		$sum = $this->hlp->page_sum($ID, $REV);
1071aeb2b4dSghi
108*55f447f4SSzymon Olewniczak
109*55f447f4SSzymon Olewniczak		$classes = array();
110*55f447f4SSzymon Olewniczak		if ($this->getConf('prettyprint')) {
111*55f447f4SSzymon Olewniczak		    $classes[] = 'plugin__approve_noprint';
112*55f447f4SSzymon Olewniczak        }
113*55f447f4SSzymon Olewniczak
114*55f447f4SSzymon Olewniczak        if ($sum == APPROVED) {
115*55f447f4SSzymon Olewniczak		    $classes[] = 'plugin__approve_green';
116*55f447f4SSzymon Olewniczak        } else {
117*55f447f4SSzymon Olewniczak            $classes[] = 'plugin__approve_red';
118*55f447f4SSzymon Olewniczak        }
119*55f447f4SSzymon Olewniczak
120*55f447f4SSzymon Olewniczak		ptln('<div id="plugin__approve" class="' . implode(' ', $classes) . '">');
1211aeb2b4dSghi
1221aeb2b4dSghi		tpl_pageinfo();
1231aeb2b4dSghi		ptln(' | ');
124274d699aSghi		$last_approved_rev = $this->find_lastest_approved();
1251aeb2b4dSghi		if ($sum == APPROVED) {
126*55f447f4SSzymon Olewniczak		    $versions = p_get_metadata($ID, METADATA_VERSIONS_KEY);
127*55f447f4SSzymon Olewniczak		    if (!$versions) {
128*55f447f4SSzymon Olewniczak                $versions = $this->render_metadata_for_approved_page($ID);
129*55f447f4SSzymon Olewniczak            }
130*55f447f4SSzymon Olewniczak            if (empty($REV)) {
131*55f447f4SSzymon Olewniczak                $version = $versions[0];
132*55f447f4SSzymon Olewniczak            } else {
133*55f447f4SSzymon Olewniczak                $version = $versions[$REV];
13447b144feSSzymon Olewniczak            }
135af3e3cd8SSzymon Olewniczak
136*55f447f4SSzymon Olewniczak			ptln('<strong>'.$this->getLang('approved').'</strong> (' . $this->getLang('version') .  ': ' . $version
13747b144feSSzymon Olewniczak                 . ')');
1381aeb2b4dSghi			if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
1391aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
140af3e3cd8SSzymon Olewniczak				ptln($this->getLang(p_get_metadata($ID, 'last_change sum') == APPROVED ? 'newest_approved' : 'newest_draft'));
1411aeb2b4dSghi				ptln('</a>');
1421aeb2b4dSghi			} else if ($REV != 0 && $REV != $last_approved_rev) {
1431aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
1441aeb2b4dSghi				ptln($this->getLang('newest_approved'));
1451aeb2b4dSghi				ptln('</a>');
1461aeb2b4dSghi			}
1471aeb2b4dSghi		} else {
1481aeb2b4dSghi			ptln('<span>'.$this->getLang('draft').'</span>');
1491aeb2b4dSghi
150274d699aSghi			if ($last_approved_rev == -1) {
151274d699aSghi			    if ($REV != 0) {
152274d699aSghi				    ptln('<a href="'.wl($ID).'">');
153274d699aSghi				    	ptln($this->getLang('newest_draft'));
154274d699aSghi				    ptln('</a>');
155274d699aSghi				}
156274d699aSghi			} else {
1571aeb2b4dSghi				if ($last_approved_rev != 0)
1581aeb2b4dSghi					ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">');
1591aeb2b4dSghi				else
1601aeb2b4dSghi					ptln('<a href="'.wl($ID).'">');
1611aeb2b4dSghi
1621aeb2b4dSghi					ptln($this->getLang('newest_approved'));
1631aeb2b4dSghi				ptln('</a>');
1641aeb2b4dSghi			}
1651aeb2b4dSghi
1661aeb2b4dSghi			//można zatwierdzać tylko najnowsze strony
1671aeb2b4dSghi			if ($REV == 0 && $this->can_approve()) {
1681aeb2b4dSghi				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
1691aeb2b4dSghi				'approve' => 'approve')).'">');
1701aeb2b4dSghi					ptln($this->getLang('approve'));
1711aeb2b4dSghi				ptln('</a>');
1721aeb2b4dSghi			}
1731aeb2b4dSghi		}
1741aeb2b4dSghi		ptln('</div>');
1751aeb2b4dSghi	}
1761aeb2b4dSghi
177af3e3cd8SSzymon Olewniczak    /**
178af3e3cd8SSzymon Olewniczak     * Check if the page has to be changed
179af3e3cd8SSzymon Olewniczak     *
180af3e3cd8SSzymon Olewniczak     * @param Doku_Event $event  event object by reference
181af3e3cd8SSzymon Olewniczak     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
182af3e3cd8SSzymon Olewniczak     *                           handler was registered]
183af3e3cd8SSzymon Olewniczak     * @return void
184af3e3cd8SSzymon Olewniczak     */
185af3e3cd8SSzymon Olewniczak    public function handle_pagesave_before(Doku_Event $event, $param) {
186*55f447f4SSzymon Olewniczak        global $REV;
187af3e3cd8SSzymon Olewniczak        $id = $event->data['id'];
188af3e3cd8SSzymon Olewniczak        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
189af3e3cd8SSzymon Olewniczak
190af3e3cd8SSzymon Olewniczak        //save page if summary is provided
191af3e3cd8SSzymon Olewniczak        if($event->data['summary'] == APPROVED) {
192af3e3cd8SSzymon Olewniczak            $event->data['contentChanged'] = true;
193*55f447f4SSzymon Olewniczak        }
194*55f447f4SSzymon Olewniczak    }
195af3e3cd8SSzymon Olewniczak
196*55f447f4SSzymon Olewniczak    /**
197*55f447f4SSzymon Olewniczak     * @param Doku_Event $event
198*55f447f4SSzymon Olewniczak     * @param            $param
199*55f447f4SSzymon Olewniczak     */
200*55f447f4SSzymon Olewniczak    public function handle_pagesave_after(Doku_Event $event, $param) {
201*55f447f4SSzymon Olewniczak        global $REV;
202*55f447f4SSzymon Olewniczak        $id = $event->data['id'];
203*55f447f4SSzymon Olewniczak        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
204af3e3cd8SSzymon Olewniczak
205*55f447f4SSzymon Olewniczak        //save page if summary is provided
206*55f447f4SSzymon Olewniczak        if($event->data['summary'] == APPROVED) {
207*55f447f4SSzymon Olewniczak
208*55f447f4SSzymon Olewniczak            $versions = p_get_metadata($id, METADATA_VERSIONS_KEY);
209*55f447f4SSzymon Olewniczak            //calculate versions
210*55f447f4SSzymon Olewniczak            if (!$versions) {
211*55f447f4SSzymon Olewniczak                $this->render_metadata_for_approved_page($id, $event->data['newRevision']);
212af3e3cd8SSzymon Olewniczak            } else {
213*55f447f4SSzymon Olewniczak                $curver = $versions[0] + 1;
214*55f447f4SSzymon Olewniczak                $versions[0] = $curver;
215*55f447f4SSzymon Olewniczak                $versions[$event->data['newRevision']] = $curver;
216*55f447f4SSzymon Olewniczak                p_set_metadata($id, array(METADATA_VERSIONS_KEY => $versions));
217*55f447f4SSzymon Olewniczak            }
218*55f447f4SSzymon Olewniczak        }
219af3e3cd8SSzymon Olewniczak    }
220af3e3cd8SSzymon Olewniczak
221af3e3cd8SSzymon Olewniczak
222af3e3cd8SSzymon Olewniczak    /**
223af3e3cd8SSzymon Olewniczak     * Calculate current version
224af3e3cd8SSzymon Olewniczak     *
225af3e3cd8SSzymon Olewniczak     * @param $id
226af3e3cd8SSzymon Olewniczak     * @return int
227af3e3cd8SSzymon Olewniczak     */
228*55f447f4SSzymon Olewniczak    protected function render_metadata_for_approved_page($id, $currev=false) {
229*55f447f4SSzymon Olewniczak        if (!$currev) $currev = @filemtime(wikiFN($id));
230*55f447f4SSzymon Olewniczak
231*55f447f4SSzymon Olewniczak        $version = $this->approved($id);
232*55f447f4SSzymon Olewniczak        //version for current page
233*55f447f4SSzymon Olewniczak        $curver = $version + 1;
234*55f447f4SSzymon Olewniczak        $versions = array(0 => $curver, $currev => $curver);
235af3e3cd8SSzymon Olewniczak
236af3e3cd8SSzymon Olewniczak        $changelog = new PageChangeLog($id);
237af3e3cd8SSzymon Olewniczak        $first = 0;
238af3e3cd8SSzymon Olewniczak        $num = 100;
239af3e3cd8SSzymon Olewniczak        while (count($revs = $changelog->getRevisions($first, $num)) > 0) {
240af3e3cd8SSzymon Olewniczak            foreach ($revs as $rev) {
241af3e3cd8SSzymon Olewniczak                $revInfo = $changelog->getRevisionInfo($rev);
242af3e3cd8SSzymon Olewniczak                if ($revInfo['sum'] == APPROVED) {
243*55f447f4SSzymon Olewniczak                    $versions[$rev] = $version;
244*55f447f4SSzymon Olewniczak                    $version -= 1;
245af3e3cd8SSzymon Olewniczak                }
246af3e3cd8SSzymon Olewniczak            }
247af3e3cd8SSzymon Olewniczak            $first += $num;
248af3e3cd8SSzymon Olewniczak        }
249af3e3cd8SSzymon Olewniczak
250*55f447f4SSzymon Olewniczak        p_set_metadata($id, array(METADATA_VERSIONS_KEY => $versions));
251*55f447f4SSzymon Olewniczak
252*55f447f4SSzymon Olewniczak        return $versions;
253af3e3cd8SSzymon Olewniczak    }
254af3e3cd8SSzymon Olewniczak
255*55f447f4SSzymon Olewniczak    /**
256*55f447f4SSzymon Olewniczak     * Get the number of approved pages
257*55f447f4SSzymon Olewniczak     * @param $id
258*55f447f4SSzymon Olewniczak     * @return int
259*55f447f4SSzymon Olewniczak     */
260*55f447f4SSzymon Olewniczak    protected function approved($id) {
261*55f447f4SSzymon Olewniczak        $count = 0;
262*55f447f4SSzymon Olewniczak
263*55f447f4SSzymon Olewniczak        $changelog = new PageChangeLog($id);
264*55f447f4SSzymon Olewniczak        $first = 0;
265*55f447f4SSzymon Olewniczak        $num = 100;
266*55f447f4SSzymon Olewniczak        while (count($revs = $changelog->getRevisions($first, $num)) > 0) {
267*55f447f4SSzymon Olewniczak            foreach ($revs as $rev) {
268*55f447f4SSzymon Olewniczak                $revInfo = $changelog->getRevisionInfo($rev);
269*55f447f4SSzymon Olewniczak                if ($revInfo['sum'] == APPROVED) {
270*55f447f4SSzymon Olewniczak                    $count += 1;
271*55f447f4SSzymon Olewniczak                }
272*55f447f4SSzymon Olewniczak            }
273*55f447f4SSzymon Olewniczak            $first += $num;
274*55f447f4SSzymon Olewniczak        }
275*55f447f4SSzymon Olewniczak
276*55f447f4SSzymon Olewniczak        return $count;
277*55f447f4SSzymon Olewniczak    }
2781aeb2b4dSghi}
279