xref: /plugin/approve/action/approve.php (revision 84047bda13dfe29d9312d3535347cddd33b24cb9)
1<?php
2
3if(!defined('DOKU_INC')) die();
4define(APPROVED, 'Approved');
5define(READY_FOR_APPROVAL, 'Ready for approval');
6
7class action_plugin_approve_approve extends DokuWiki_Action_Plugin {
8
9    private $hlp;
10    function __construct(){
11        $this->hlp = plugin_load('helper', 'approve');
12    }
13
14    function register(Doku_Event_Handler $controller) {
15
16        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_approve, array());
17        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_viewer, array());
18        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, handle_diff_accept, array());
19        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array());
20        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, handle_showrev, array());
21    }
22
23	function handle_diff_accept(Doku_Event $event, $param) {
24		global $ID;
25
26		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
27
28		if ($event->data == 'diff' && isset($_GET['approve'])) {
29			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>');
30		}
31
32		if ($event->data == 'diff' && isset($_GET['ready_for_approval'])) {
33			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&ready_for_approval=ready_for_approval">'.$this->getLang('approve_ready').'</a>');
34		}
35	}
36
37	function handle_showrev(Doku_Event $event, $param) {
38		global $ID, $REV;
39
40		$last = $this->find_lastest_approved();
41		if ($last == $REV)
42			$event->preventDefault();
43	}
44
45	function can_approve() {
46		global $ID;
47		return auth_quickaclcheck($ID) >= AUTH_DELETE;
48	}
49
50		function can_edit() {
51		global $ID;
52		return auth_quickaclcheck($ID) >= AUTH_EDIT;
53	}
54
55	function handle_approve(Doku_Event $event, $param) {
56		global $ID, $REV, $INFO;
57
58		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
59
60		if ($event->data == 'show' && isset($_GET['approve'])) {
61		    if ( ! $this->can_approve()) return;
62
63			//change last commit comment to Approved
64			$meta = p_read_metadata($ID);
65			$meta[current][last_change][sum] = $meta[persistent][last_change][sum] = APPROVED;
66			$meta[current][last_change][user] = $meta[persistent][last_change][user] = $INFO[client];
67			if (!array_key_exists($INFO[client], $meta[current][contributor])) {
68			    $meta[current][contributor][$INFO[client]] = $INFO[userinfo][name];
69			    $meta[persistent][contributor][$INFO[client]] = $INFO[userinfo][name];
70			}
71			p_save_metadata($ID, $meta);
72			//update changelog
73			//remove last line from file
74			$changelog_file = metaFN($ID, '.changes');
75			$changes = file($changelog_file, FILE_SKIP_EMPTY_LINES);
76			$lastLogLine = array_pop($changes);
77			$info = parseChangelogLine($lastLogLine);
78
79			$info[user] = $INFO[client];
80			$info[sum] = APPROVED;
81
82			$logline = implode("\t", $info)."\n";
83			array_push($changes, $logline);
84
85			io_saveFile($changelog_file, implode('', $changes));
86
87			header('Location: ?id='.$ID);
88		}
89
90		if ($event->data == 'show' && isset($_GET['ready_for_approval'])) {
91		    if ( ! $this->can_edit()) return;
92
93			//change last commit comment to Approved
94			$meta = p_read_metadata($ID);
95			$meta[current][last_change][sum] = $meta[persistent][last_change][sum] = READY_FOR_APPROVAL;
96			$meta[current][last_change][user] = $meta[persistent][last_change][user] = $INFO[client];
97			if (!array_key_exists($INFO[client], $meta[current][contributor])) {
98			    $meta[current][contributor][$INFO[client]] = $INFO[userinfo][name];
99			    $meta[persistent][contributor][$INFO[client]] = $INFO[userinfo][name];
100			}
101			p_save_metadata($ID, $meta);
102			//update changelog
103			//remove last line from file
104			$changelog_file = metaFN($ID, '.changes');
105			$changes = file($changelog_file, FILE_SKIP_EMPTY_LINES);
106			$lastLogLine = array_pop($changes);
107			$info = parseChangelogLine($lastLogLine);
108
109			$info[user] = $INFO[client];
110			$info[sum] = APPROVED;
111
112			$logline = implode("\t", $info)."\n";
113			array_push($changes, $logline);
114
115			io_saveFile($changelog_file, implode('', $changes));
116
117			header('Location: ?id='.$ID);
118		}
119	}
120    function handle_viewer(Doku_Event $event, $param) {
121        global $REV, $ID;
122        if ($event->data != 'show') return;
123        if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return;
124
125	    $last = $this->find_lastest_approved();
126	    //no page is approved
127		if ($last == -1) return;
128		//approved page is the newest page
129		if ($last == 0) return;
130
131		//if we are viewing lastest revision, show last approved
132		if ($REV == 0) header("Location: ?id=$ID&rev=$last");
133	}
134	function find_lastest_approved() {
135		global $ID;
136		$m = p_get_metadata($ID);
137		$sum = $m['last_change']['sum'];
138		if ($sum == APPROVED)
139			return 0;
140
141		$changelog = new PageChangeLog($ID);
142		//wyszukaj najnowszej zatwierdzonej
143		//poszukaj w dół
144		$chs = $changelog->getRevisions(0, 10000);
145		foreach ($chs as $rev) {
146			$ch = $changelog->getRevisionInfo($rev);
147			if ($ch['sum'] == APPROVED)
148				return $rev;
149		}
150		return -1;
151	}
152
153    function handle_display_banner(Doku_Event $event, $param) {
154		global $ID, $REV, $INFO;
155
156		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
157        if ($event->data != 'show') return;
158		if (!$INFO['exists']) return;
159
160		$sum = $this->hlp->page_sum($ID, $REV);
161
162		ptln('<div class="approval '.($sum == APPROVED ? 'approved_yes' : ($sum == READY_FOR_APPROVAL ? 'approved_ready' :'approved_no')).'">');
163
164		tpl_pageinfo();
165		ptln(' | ');
166		$last_approved_rev = $this->find_lastest_approved();
167		if ($sum == APPROVED) {
168			ptln('<span>'.$this->getLang('approved').'</span>');
169			if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
170				ptln('<a href="'.wl($ID).'">');
171				ptln($this->getLang($m['last_change']['sum'] == APPROVED ? 'newest_approved' : 'newest_draft'));
172				ptln('</a>');
173			} else if ($REV != 0 && $REV != $last_approved_rev) {
174				ptln('<a href="'.wl($ID).'">');
175				ptln($this->getLang('newest_approved'));
176				ptln('</a>');
177			}
178		} else {
179			ptln('<span>'.$this->getLang('draft').'</span>');
180
181			if ($sum == READY_FOR_APPROVAL) {
182				ptln('<span>| '.$this->getLang('marked_approve_ready').'</span>');
183			}
184
185
186			if ($last_approved_rev == -1) {
187			    if ($REV != 0) {
188				    ptln('<a href="'.wl($ID).'">');
189				    	ptln($this->getLang('newest_draft'));
190				    ptln('</a>');
191				}
192			} else {
193				if ($last_approved_rev != 0)
194					ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">');
195				else
196					ptln('<a href="'.wl($ID).'">');
197
198					ptln($this->getLang('newest_approved'));
199				ptln('</a>');
200			}
201
202			if ($REV == 0 && $this->can_edit() && $sum != READY_FOR_APPROVAL) {
203				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
204				'ready_for_approval' => 'ready_for_approval')).'">');
205					ptln($this->getLang('approve_ready'));
206				ptln('</a>');
207			}
208
209			//można zatwierdzać tylko najnowsze strony
210			if ($REV == 0 && $this->can_approve()) {
211				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
212				'approve' => 'approve')).'">');
213					ptln($this->getLang('approve'));
214				ptln('</a>');
215			}
216
217
218		}
219		ptln('</div>');
220	}
221
222}
223