xref: /plugin/approve/action/approve.php (revision 47b144fe96061c8ddca9ab7457b43d7cf2a79279)
1<?php
2
3if(!defined('DOKU_INC')) die();
4define(APPROVED, 'Approved');
5
6define(METADATA_VERSION_KEY, 'plugin_approve_version');
7
8class action_plugin_approve_approve extends DokuWiki_Action_Plugin {
9
10    private $hlp;
11    function __construct(){
12        $this->hlp = plugin_load('helper', 'approve');
13    }
14
15    function register(Doku_Event_Handler $controller) {
16
17        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_approve, array());
18        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, handle_viewer, array());
19        $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, handle_diff_accept, array());
20        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, handle_display_banner, array());
21        $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, handle_showrev, array());
22        // ensure a page revision is created when summary changes:
23        $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before');
24    }
25
26	function handle_diff_accept(Doku_Event $event, $param) {
27		global $ID;
28
29		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
30
31		if ($event->data == 'diff' && isset($_GET['approve'])) {
32			ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>');
33		}
34	}
35
36	function handle_showrev(Doku_Event $event, $param) {
37		global $ID, $REV;
38
39		$last = $this->find_lastest_approved();
40		if ($last == $REV)
41			$event->preventDefault();
42	}
43
44	function can_approve() {
45		global $ID;
46		return auth_quickaclcheck($ID) >= AUTH_DELETE;
47	}
48
49	function handle_approve(Doku_Event $event, $param) {
50		global $ID, $REV, $INFO;
51
52		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
53
54		if ($event->data == 'show' && isset($_GET['approve'])) {
55		    if ( ! $this->can_approve()) return;
56
57		    //create new page revison
58            saveWikiText($ID, rawWiki($ID), APPROVED);
59
60			header('Location: ?id='.$ID);
61		}
62	}
63    function handle_viewer(Doku_Event $event, $param) {
64        global $REV, $ID;
65        if ($event->data != 'show') return;
66        if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return;
67
68	    $last = $this->find_lastest_approved();
69	    //no page is approved
70		if ($last == -1) return;
71		//approved page is the newest page
72		if ($last == 0) return;
73
74		//if we are viewing lastest revision, show last approved
75		if ($REV == 0) header("Location: ?id=$ID&rev=$last");
76	}
77	function find_lastest_approved() {
78		global $ID;
79		$m = p_get_metadata($ID);
80		$sum = $m['last_change']['sum'];
81		if ($sum == APPROVED)
82			return 0;
83
84		$changelog = new PageChangeLog($ID);
85		//wyszukaj najnowszej zatwierdzonej
86		//poszukaj w dół
87		$chs = $changelog->getRevisions(0, 10000);
88		foreach ($chs as $rev) {
89			$ch = $changelog->getRevisionInfo($rev);
90			if ($ch['sum'] == APPROVED)
91				return $rev;
92		}
93		return -1;
94	}
95
96    function handle_display_banner(Doku_Event $event, $param) {
97		global $ID, $REV, $INFO;
98
99		if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return;
100        if ($event->data != 'show') return;
101		if (!$INFO['exists']) return;
102
103		$sum = $this->hlp->page_sum($ID, $REV);
104
105		ptln('<div class="approval '.($sum == APPROVED ? 'approved_yes' : 'approved_no').'">');
106
107		tpl_pageinfo();
108		ptln(' | ');
109		$last_approved_rev = $this->find_lastest_approved();
110		if ($sum == APPROVED) {
111		    $version = p_get_metadata($ID, METADATA_VERSION_KEY);
112		    if (!$version) {
113		        $version = $this->calculateVersion($ID);
114		        p_set_metadata($ID, array(METADATA_VERSION_KEY => $version));
115            }
116
117			ptln('<span>'.$this->getLang('approved').'</span> (' . $this->getLang('version') .  ': ' . $version
118                 . ')');
119			if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) {
120				ptln('<a href="'.wl($ID).'">');
121				ptln($this->getLang(p_get_metadata($ID, 'last_change sum') == APPROVED ? 'newest_approved' : 'newest_draft'));
122				ptln('</a>');
123			} else if ($REV != 0 && $REV != $last_approved_rev) {
124				ptln('<a href="'.wl($ID).'">');
125				ptln($this->getLang('newest_approved'));
126				ptln('</a>');
127			}
128		} else {
129			ptln('<span>'.$this->getLang('draft').'</span>');
130
131			if ($last_approved_rev == -1) {
132			    if ($REV != 0) {
133				    ptln('<a href="'.wl($ID).'">');
134				    	ptln($this->getLang('newest_draft'));
135				    ptln('</a>');
136				}
137			} else {
138				if ($last_approved_rev != 0)
139					ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">');
140				else
141					ptln('<a href="'.wl($ID).'">');
142
143					ptln($this->getLang('newest_approved'));
144				ptln('</a>');
145			}
146
147			//można zatwierdzać tylko najnowsze strony
148			if ($REV == 0 && $this->can_approve()) {
149				ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff',
150				'approve' => 'approve')).'">');
151					ptln($this->getLang('approve'));
152				ptln('</a>');
153			}
154		}
155		ptln('</div>');
156	}
157
158    /**
159     * Check if the page has to be changed
160     *
161     * @param Doku_Event $event  event object by reference
162     * @param mixed      $param  [the parameters passed as fifth argument to register_hook() when this
163     *                           handler was registered]
164     * @return void
165     */
166    public function handle_pagesave_before(Doku_Event $event, $param) {
167        $id = $event->data['id'];
168        if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return;
169
170        //save page if summary is provided
171        if($event->data['summary'] == APPROVED) {
172            $event->data['contentChanged'] = true;
173
174            $version = p_get_metadata($id, METADATA_VERSION_KEY);
175
176            //calculate current version
177            if (!$version) {
178                $version = $this->calculateVersion($id);
179            } else {
180                $version += 1;
181            }
182
183            p_set_metadata($id, array(METADATA_VERSION_KEY => $version));
184        }
185    }
186
187    /**
188     * Calculate current version
189     *
190     * @param $id
191     * @return int
192     */
193    protected function calculateVersion($id) {
194        $version = 1;
195
196        $changelog = new PageChangeLog($id);
197        $first = 0;
198        $num = 100;
199        while (count($revs = $changelog->getRevisions($first, $num)) > 0) {
200            foreach ($revs as $rev) {
201                $revInfo = $changelog->getRevisionInfo($rev);
202                if ($revInfo['sum'] == APPROVED) {
203                    $version += 1;
204                }
205            }
206            $first += $num;
207        }
208
209        return $version;
210    }
211
212}
213