xref: /plugin/approve/action/approve.php (revision 84047bda13dfe29d9312d3535347cddd33b24cb9)
11aeb2b4dSghi<?php
21aeb2b4dSghi
31aeb2b4dSghiif(!defined('DOKU_INC')) die();
41aeb2b4dSghidefine(APPROVED, 'Approved');
5*84047bdaSRuuddefine(READY_FOR_APPROVAL, 'Ready for approval');
61aeb2b4dSghi
71aeb2b4dSghiclass action_plugin_approve_approve extends DokuWiki_Action_Plugin {
81aeb2b4dSghi
950481663SSzymon Olewniczak    private $hlp;
1050481663SSzymon Olewniczak    function __construct(){
1150481663SSzymon Olewniczak        $this->hlp = plugin_load('helper', 'approve');
1250481663SSzymon Olewniczak    }
1350481663SSzymon Olewniczak
1450481663SSzymon Olewniczak    function register(Doku_Event_Handler $controller) {
1550481663SSzymon Olewniczak
161aeb2b4dSghi        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_approve, array());
1738d03fbdSghi        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_viewer, array());
181aeb2b4dSghi        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, handle_diff_accept, array());
191aeb2b4dSghi        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array());
201aeb2b4dSghi        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, handle_showrev, array());
211aeb2b4dSghi    }
221aeb2b4dSghi
23d0c5854eSSzymon Olewniczak	function handle_diff_accept(Doku_Event $event, $param) {
2450481663SSzymon Olewniczak		global $ID;
2550481663SSzymon Olewniczak
2650481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
2750481663SSzymon Olewniczak
281aeb2b4dSghi		if ($event->data == 'diff' && isset($_GET['approve'])) {
291aeb2b4dSghi			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>');
301aeb2b4dSghi		}
31*84047bdaSRuud
32*84047bdaSRuud		if ($event->data == 'diff' && isset($_GET['ready_for_approval'])) {
33*84047bdaSRuud			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&ready_for_approval=ready_for_approval">'.$this->getLang('approve_ready').'</a>');
34*84047bdaSRuud		}
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
50*84047bdaSRuud		function can_edit() {
51*84047bdaSRuud		global $ID;
52*84047bdaSRuud		return auth_quickaclcheck($ID) >= AUTH_EDIT;
53*84047bdaSRuud	}
54*84047bdaSRuud
55d0c5854eSSzymon Olewniczak	function handle_approve(Doku_Event $event, $param) {
56c7f8f6c0Sghi		global $ID, $REV, $INFO;
5750481663SSzymon Olewniczak
5850481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
5950481663SSzymon Olewniczak
601aeb2b4dSghi		if ($event->data == 'show' && isset($_GET['approve'])) {
6138d03fbdSghi		    if ( ! $this->can_approve()) return;
6238d03fbdSghi
63c7f8f6c0Sghi			//change last commit comment to Approved
64c7f8f6c0Sghi			$meta = p_read_metadata($ID);
65c7f8f6c0Sghi			$meta[current][last_change][sum] = $meta[persistent][last_change][sum] = APPROVED;
66c7f8f6c0Sghi			$meta[current][last_change][user] = $meta[persistent][last_change][user] = $INFO[client];
679f9f0967Sghi			if (!array_key_exists($INFO[client], $meta[current][contributor])) {
68c7f8f6c0Sghi			    $meta[current][contributor][$INFO[client]] = $INFO[userinfo][name];
69c7f8f6c0Sghi			    $meta[persistent][contributor][$INFO[client]] = $INFO[userinfo][name];
701aeb2b4dSghi			}
71c7f8f6c0Sghi			p_save_metadata($ID, $meta);
72c7f8f6c0Sghi			//update changelog
73c7f8f6c0Sghi			//remove last line from file
74c7f8f6c0Sghi			$changelog_file = metaFN($ID, '.changes');
75c7f8f6c0Sghi			$changes = file($changelog_file, FILE_SKIP_EMPTY_LINES);
76c7f8f6c0Sghi			$lastLogLine = array_pop($changes);
77c7f8f6c0Sghi			$info = parseChangelogLine($lastLogLine);
78c7f8f6c0Sghi
79c7f8f6c0Sghi			$info[user] = $INFO[client];
80c7f8f6c0Sghi			$info[sum] = APPROVED;
81c7f8f6c0Sghi
82c7f8f6c0Sghi			$logline = implode("\t", $info)."\n";
83c7f8f6c0Sghi			array_push($changes, $logline);
84c7f8f6c0Sghi
85c7f8f6c0Sghi			io_saveFile($changelog_file, implode('', $changes));
861aeb2b4dSghi
871aeb2b4dSghi			header('Location: ?id='.$ID);
881aeb2b4dSghi		}
89*84047bdaSRuud
90*84047bdaSRuud		if ($event->data == 'show' && isset($_GET['ready_for_approval'])) {
91*84047bdaSRuud		    if ( ! $this->can_edit()) return;
92*84047bdaSRuud
93*84047bdaSRuud			//change last commit comment to Approved
94*84047bdaSRuud			$meta = p_read_metadata($ID);
95*84047bdaSRuud			$meta[current][last_change][sum] = $meta[persistent][last_change][sum] = READY_FOR_APPROVAL;
96*84047bdaSRuud			$meta[current][last_change][user] = $meta[persistent][last_change][user] = $INFO[client];
97*84047bdaSRuud			if (!array_key_exists($INFO[client], $meta[current][contributor])) {
98*84047bdaSRuud			    $meta[current][contributor][$INFO[client]] = $INFO[userinfo][name];
99*84047bdaSRuud			    $meta[persistent][contributor][$INFO[client]] = $INFO[userinfo][name];
100*84047bdaSRuud			}
101*84047bdaSRuud			p_save_metadata($ID, $meta);
102*84047bdaSRuud			//update changelog
103*84047bdaSRuud			//remove last line from file
104*84047bdaSRuud			$changelog_file = metaFN($ID, '.changes');
105*84047bdaSRuud			$changes = file($changelog_file, FILE_SKIP_EMPTY_LINES);
106*84047bdaSRuud			$lastLogLine = array_pop($changes);
107*84047bdaSRuud			$info = parseChangelogLine($lastLogLine);
108*84047bdaSRuud
109*84047bdaSRuud			$info[user] = $INFO[client];
110*84047bdaSRuud			$info[sum] = APPROVED;
111*84047bdaSRuud
112*84047bdaSRuud			$logline = implode("\t", $info)."\n";
113*84047bdaSRuud			array_push($changes, $logline);
114*84047bdaSRuud
115*84047bdaSRuud			io_saveFile($changelog_file, implode('', $changes));
116*84047bdaSRuud
117*84047bdaSRuud			header('Location: ?id='.$ID);
118*84047bdaSRuud		}
11938d03fbdSghi	}
120d0c5854eSSzymon Olewniczak    function handle_viewer(Doku_Event $event, $param) {
12138d03fbdSghi        global $REV, $ID;
12238d03fbdSghi        if ($event->data != 'show') return;
123a99f41c6SRuud Habing        if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return;
1241aeb2b4dSghi
1251aeb2b4dSghi	    $last = $this->find_lastest_approved();
12638d03fbdSghi	    //no page is approved
12738d03fbdSghi		if ($last == -1) return;
12838d03fbdSghi		//approved page is the newest page
12938d03fbdSghi		if ($last == 0) return;
13038d03fbdSghi
13138d03fbdSghi		//if we are viewing lastest revision, show last approved
13238d03fbdSghi		if ($REV == 0) header("Location: ?id=$ID&rev=$last");
1331aeb2b4dSghi	}
1341aeb2b4dSghi	function find_lastest_approved() {
1351aeb2b4dSghi		global $ID;
1361aeb2b4dSghi		$m = p_get_metadata($ID);
1371aeb2b4dSghi		$sum = $m['last_change']['sum'];
1381aeb2b4dSghi		if ($sum == APPROVED)
1391aeb2b4dSghi			return 0;
1401aeb2b4dSghi
1411aeb2b4dSghi		$changelog = new PageChangeLog($ID);
1421aeb2b4dSghi		//wyszukaj najnowszej zatwierdzonej
1431aeb2b4dSghi		//poszukaj w dół
1441aeb2b4dSghi		$chs = $changelog->getRevisions(0, 10000);
1451aeb2b4dSghi		foreach ($chs as $rev) {
1461aeb2b4dSghi			$ch = $changelog->getRevisionInfo($rev);
1471aeb2b4dSghi			if ($ch['sum'] == APPROVED)
1481aeb2b4dSghi				return $rev;
1491aeb2b4dSghi		}
1501aeb2b4dSghi		return -1;
1511aeb2b4dSghi	}
1521aeb2b4dSghi
153d0c5854eSSzymon Olewniczak    function handle_display_banner(Doku_Event $event, $param) {
1541aeb2b4dSghi		global $ID, $REV, $INFO;
1551aeb2b4dSghi
15650481663SSzymon Olewniczak		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
1571aeb2b4dSghi        if ($event->data != 'show') return;
1581aeb2b4dSghi		if (!$INFO['exists']) return;
1591aeb2b4dSghi
160cf995419SSzymon Olewniczak		$sum = $this->hlp->page_sum($ID, $REV);
1611aeb2b4dSghi
162*84047bdaSRuud		ptln('<div class="approval '.($sum == APPROVED ? 'approved_yes' : ($sum == READY_FOR_APPROVAL ? 'approved_ready' :'approved_no')).'">');
1631aeb2b4dSghi
1641aeb2b4dSghi		tpl_pageinfo();
1651aeb2b4dSghi		ptln(' | ');
166274d699aSghi		$last_approved_rev = $this->find_lastest_approved();
1671aeb2b4dSghi		if ($sum == APPROVED) {
1681aeb2b4dSghi			ptln('<span>'.$this->getLang('approved').'</span>');
1691aeb2b4dSghi			if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
1701aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
1711aeb2b4dSghi				ptln($this->getLang($m['last_change']['sum'] == APPROVED ? 'newest_approved' : 'newest_draft'));
1721aeb2b4dSghi				ptln('</a>');
1731aeb2b4dSghi			} else if ($REV != 0 && $REV != $last_approved_rev) {
1741aeb2b4dSghi				ptln('<a href="'.wl($ID).'">');
1751aeb2b4dSghi				ptln($this->getLang('newest_approved'));
1761aeb2b4dSghi				ptln('</a>');
1771aeb2b4dSghi			}
1781aeb2b4dSghi		} else {
1791aeb2b4dSghi			ptln('<span>'.$this->getLang('draft').'</span>');
1801aeb2b4dSghi
181*84047bdaSRuud			if ($sum == READY_FOR_APPROVAL) {
182*84047bdaSRuud				ptln('<span>| '.$this->getLang('marked_approve_ready').'</span>');
183*84047bdaSRuud			}
184*84047bdaSRuud
185*84047bdaSRuud
186274d699aSghi			if ($last_approved_rev == -1) {
187274d699aSghi			    if ($REV != 0) {
188274d699aSghi				    ptln('<a href="'.wl($ID).'">');
189274d699aSghi				    	ptln($this->getLang('newest_draft'));
190274d699aSghi				    ptln('</a>');
191274d699aSghi				}
192274d699aSghi			} else {
1931aeb2b4dSghi				if ($last_approved_rev != 0)
1941aeb2b4dSghi					ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">');
1951aeb2b4dSghi				else
1961aeb2b4dSghi					ptln('<a href="'.wl($ID).'">');
1971aeb2b4dSghi
1981aeb2b4dSghi					ptln($this->getLang('newest_approved'));
1991aeb2b4dSghi				ptln('</a>');
2001aeb2b4dSghi			}
2011aeb2b4dSghi
202*84047bdaSRuud			if ($REV == 0 && $this->can_edit() && $sum != READY_FOR_APPROVAL) {
203*84047bdaSRuud				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
204*84047bdaSRuud				'ready_for_approval' => 'ready_for_approval')).'">');
205*84047bdaSRuud					ptln($this->getLang('approve_ready'));
206*84047bdaSRuud				ptln('</a>');
207*84047bdaSRuud			}
208*84047bdaSRuud
2091aeb2b4dSghi			//można zatwierdzać tylko najnowsze strony
2101aeb2b4dSghi			if ($REV == 0 && $this->can_approve()) {
2111aeb2b4dSghi				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
2121aeb2b4dSghi				'approve' => 'approve')).'">');
2131aeb2b4dSghi					ptln($this->getLang('approve'));
2141aeb2b4dSghi				ptln('</a>');
2151aeb2b4dSghi			}
216*84047bdaSRuud
217*84047bdaSRuud
2181aeb2b4dSghi		}
2191aeb2b4dSghi		ptln('</div>');
2201aeb2b4dSghi	}
2211aeb2b4dSghi
2221aeb2b4dSghi}
223