11aeb2b4dSghi<?php 21aeb2b4dSghi 3*bab76148SSzymon Olewniczakuse dokuwiki\plugin\approve\meta\ApproveConst; 41aeb2b4dSghi 51aeb2b4dSghiif(!defined('DOKU_INC')) die(); 61aeb2b4dSghi 71aeb2b4dSghiclass action_plugin_approve_approve extends DokuWiki_Action_Plugin { 81aeb2b4dSghi 9*bab76148SSzymon Olewniczak /** @var DokuWiki_PluginInterface */ 10*bab76148SSzymon Olewniczak protected $hlp; 11*bab76148SSzymon Olewniczak 1250481663SSzymon Olewniczak function __construct(){ 1350481663SSzymon Olewniczak $this->hlp = plugin_load('helper', 'approve'); 1450481663SSzymon Olewniczak } 1550481663SSzymon Olewniczak 1650481663SSzymon Olewniczak function register(Doku_Event_Handler $controller) { 1750481663SSzymon Olewniczak 1855f447f4SSzymon Olewniczak $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_approve', array()); 1955f447f4SSzymon Olewniczak $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_viewer', array()); 2055f447f4SSzymon Olewniczak $controller->register_hook('TPL_ACT_RENDER', 'AFTER', $this, 'handle_diff_accept', array()); 2155f447f4SSzymon Olewniczak $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'handle_display_banner', array()); 2255f447f4SSzymon Olewniczak $controller->register_hook('HTML_SHOWREV_OUTPUT', 'BEFORE', $this, 'handle_showrev', array()); 23af3e3cd8SSzymon Olewniczak // ensure a page revision is created when summary changes: 24af3e3cd8SSzymon Olewniczak $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_pagesave_before'); 2555f447f4SSzymon Olewniczak $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'handle_pagesave_after'); 261aeb2b4dSghi } 271aeb2b4dSghi 28d0c5854eSSzymon Olewniczak function handle_diff_accept(Doku_Event $event, $param) { 2950481663SSzymon Olewniczak global $ID; 3050481663SSzymon Olewniczak 3150481663SSzymon Olewniczak if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 3250481663SSzymon Olewniczak 331aeb2b4dSghi if ($event->data == 'diff' && isset($_GET['approve'])) { 341aeb2b4dSghi ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&approve=approve">'.$this->getLang('approve').'</a>'); 351aeb2b4dSghi } 3684047bdaSRuud 371173fda7SRuud if ($event->data == 'diff' && isset($_GET['ready_for_approval']) && $this->getConf('ready_for_approval') === 1) { 3884047bdaSRuud ptln('<a href="'.DOKU_URL.'doku.php?id='.$_GET['id'].'&ready_for_approval=ready_for_approval">'.$this->getLang('approve_ready').'</a>'); 3984047bdaSRuud } 401aeb2b4dSghi } 411aeb2b4dSghi 42d0c5854eSSzymon Olewniczak function handle_showrev(Doku_Event $event, $param) { 4355f447f4SSzymon Olewniczak global $REV; 441aeb2b4dSghi 451aeb2b4dSghi $last = $this->find_lastest_approved(); 461aeb2b4dSghi if ($last == $REV) 471aeb2b4dSghi $event->preventDefault(); 481aeb2b4dSghi } 491aeb2b4dSghi 501aeb2b4dSghi function can_approve() { 511aeb2b4dSghi global $ID; 522cf0ddf9Sghi return auth_quickaclcheck($ID) >= AUTH_DELETE; 531aeb2b4dSghi } 541aeb2b4dSghi 5584047bdaSRuud function can_edit() { 5684047bdaSRuud global $ID; 5784047bdaSRuud return auth_quickaclcheck($ID) >= AUTH_EDIT; 5884047bdaSRuud } 5984047bdaSRuud 60d0c5854eSSzymon Olewniczak function handle_approve(Doku_Event $event, $param) { 6155f447f4SSzymon Olewniczak global $ID; 6250481663SSzymon Olewniczak 6350481663SSzymon Olewniczak if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 6450481663SSzymon Olewniczak 651aeb2b4dSghi if ($event->data == 'show' && isset($_GET['approve'])) { 6638d03fbdSghi if ( ! $this->can_approve()) return; 6738d03fbdSghi 68af3e3cd8SSzymon Olewniczak //create new page revison 69*bab76148SSzymon Olewniczak saveWikiText($ID, rawWiki($ID), ApproveConst::APPROVED); 701aeb2b4dSghi 711aeb2b4dSghi header('Location: ?id='.$ID); 72*bab76148SSzymon Olewniczak } elseif ($event->data == 'show' && isset($_GET['ready_for_approval'])) { 7384047bdaSRuud if ( ! $this->can_edit()) return; 7484047bdaSRuud 75*bab76148SSzymon Olewniczak //create new page revison 76*bab76148SSzymon Olewniczak saveWikiText($ID, rawWiki($ID), ApproveConst::READY_FOR_APPROVAL); 771aeb2b4dSghi 781aeb2b4dSghi header('Location: ?id='.$ID); 791aeb2b4dSghi } 8038d03fbdSghi } 8155f447f4SSzymon Olewniczak 82d0c5854eSSzymon Olewniczak function handle_viewer(Doku_Event $event, $param) { 8338d03fbdSghi global $REV, $ID; 8438d03fbdSghi if ($event->data != 'show') return; 85a99f41c6SRuud Habing if (auth_quickaclcheck($ID) > AUTH_READ || ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID))) return; 861aeb2b4dSghi 871aeb2b4dSghi $last = $this->find_lastest_approved(); 8838d03fbdSghi //no page is approved 8938d03fbdSghi if ($last == -1) return; 9038d03fbdSghi //approved page is the newest page 9138d03fbdSghi if ($last == 0) return; 9238d03fbdSghi 9338d03fbdSghi //if we are viewing lastest revision, show last approved 9438d03fbdSghi if ($REV == 0) header("Location: ?id=$ID&rev=$last"); 951aeb2b4dSghi } 9655f447f4SSzymon Olewniczak 971aeb2b4dSghi function find_lastest_approved() { 981aeb2b4dSghi global $ID; 991aeb2b4dSghi $m = p_get_metadata($ID); 1001aeb2b4dSghi $sum = $m['last_change']['sum']; 101*bab76148SSzymon Olewniczak if ($sum == ApproveConst::APPROVED) 1021aeb2b4dSghi return 0; 1031aeb2b4dSghi 1041aeb2b4dSghi $changelog = new PageChangeLog($ID); 105*bab76148SSzymon Olewniczak 1061aeb2b4dSghi $chs = $changelog->getRevisions(0, 10000); 1071aeb2b4dSghi foreach ($chs as $rev) { 1081aeb2b4dSghi $ch = $changelog->getRevisionInfo($rev); 109*bab76148SSzymon Olewniczak if ($ch['sum'] == ApproveConst::APPROVED) 1101aeb2b4dSghi return $rev; 1111aeb2b4dSghi } 1121aeb2b4dSghi return -1; 1131aeb2b4dSghi } 1141aeb2b4dSghi 115d0c5854eSSzymon Olewniczak function handle_display_banner(Doku_Event $event, $param) { 1161aeb2b4dSghi global $ID, $REV, $INFO; 1171aeb2b4dSghi 11850481663SSzymon Olewniczak if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $ID)) return; 1191aeb2b4dSghi if ($event->data != 'show') return; 1201aeb2b4dSghi if (!$INFO['exists']) return; 1211aeb2b4dSghi 122cf995419SSzymon Olewniczak $sum = $this->hlp->page_sum($ID, $REV); 1231aeb2b4dSghi 12455f447f4SSzymon Olewniczak 12555f447f4SSzymon Olewniczak $classes = array(); 12655f447f4SSzymon Olewniczak if ($this->getConf('prettyprint')) { 12755f447f4SSzymon Olewniczak $classes[] = 'plugin__approve_noprint'; 12855f447f4SSzymon Olewniczak } 12955f447f4SSzymon Olewniczak 130*bab76148SSzymon Olewniczak if ($sum == ApproveConst::APPROVED) { 13155f447f4SSzymon Olewniczak $classes[] = 'plugin__approve_green'; 132*bab76148SSzymon Olewniczak } elseif ($sum == ApproveConst::READY_FOR_APPROVAL && $this->getConf('ready_for_approval')) { 133*bab76148SSzymon Olewniczak $classes[] = 'plugin__approve_ready'; 13455f447f4SSzymon Olewniczak } else { 13555f447f4SSzymon Olewniczak $classes[] = 'plugin__approve_red'; 13655f447f4SSzymon Olewniczak } 13755f447f4SSzymon Olewniczak 13855f447f4SSzymon Olewniczak ptln('<div id="plugin__approve" class="' . implode(' ', $classes) . '">'); 1391aeb2b4dSghi 1401aeb2b4dSghi tpl_pageinfo(); 1411aeb2b4dSghi ptln(' | '); 142274d699aSghi $last_approved_rev = $this->find_lastest_approved(); 143*bab76148SSzymon Olewniczak if ($sum == ApproveConst::APPROVED) { 144*bab76148SSzymon Olewniczak $versions = p_get_metadata($ID, ApproveConst::METADATA_VERSIONS_KEY); 14555f447f4SSzymon Olewniczak if (!$versions) { 14655f447f4SSzymon Olewniczak $versions = $this->render_metadata_for_approved_page($ID); 14755f447f4SSzymon Olewniczak } 14855f447f4SSzymon Olewniczak if (empty($REV)) { 14955f447f4SSzymon Olewniczak $version = $versions[0]; 15055f447f4SSzymon Olewniczak } else { 15155f447f4SSzymon Olewniczak $version = $versions[$REV]; 15247b144feSSzymon Olewniczak } 153af3e3cd8SSzymon Olewniczak 15455f447f4SSzymon Olewniczak ptln('<strong>'.$this->getLang('approved').'</strong> (' . $this->getLang('version') . ': ' . $version 15547b144feSSzymon Olewniczak . ')'); 1561aeb2b4dSghi if ($REV != 0 && auth_quickaclcheck($ID) > AUTH_READ) { 1571aeb2b4dSghi ptln('<a href="'.wl($ID).'">'); 158*bab76148SSzymon Olewniczak ptln($this->getLang(p_get_metadata($ID, 'last_change sum') == ApproveConst::APPROVED ? 'newest_approved' : 'newest_draft')); 1591aeb2b4dSghi ptln('</a>'); 1601aeb2b4dSghi } else if ($REV != 0 && $REV != $last_approved_rev) { 1611aeb2b4dSghi ptln('<a href="'.wl($ID).'">'); 1621aeb2b4dSghi ptln($this->getLang('newest_approved')); 1631aeb2b4dSghi ptln('</a>'); 1641aeb2b4dSghi } 1651aeb2b4dSghi } else { 1661aeb2b4dSghi ptln('<span>'.$this->getLang('draft').'</span>'); 1671aeb2b4dSghi 168*bab76148SSzymon Olewniczak if ($sum == ApproveConst::READY_FOR_APPROVAL && $this->getConf('ready_for_approval') === 1) { 16984047bdaSRuud ptln('<span>| '.$this->getLang('marked_approve_ready').'</span>'); 17084047bdaSRuud } 17184047bdaSRuud 17284047bdaSRuud 173274d699aSghi if ($last_approved_rev == -1) { 174274d699aSghi if ($REV != 0) { 175274d699aSghi ptln('<a href="'.wl($ID).'">'); 176274d699aSghi ptln($this->getLang('newest_draft')); 177274d699aSghi ptln('</a>'); 178274d699aSghi } 179274d699aSghi } else { 1801aeb2b4dSghi if ($last_approved_rev != 0) 1811aeb2b4dSghi ptln('<a href="'.wl($ID, array('rev' => $last_approved_rev)).'">'); 1821aeb2b4dSghi else 1831aeb2b4dSghi ptln('<a href="'.wl($ID).'">'); 1841aeb2b4dSghi 1851aeb2b4dSghi ptln($this->getLang('newest_approved')); 1861aeb2b4dSghi ptln('</a>'); 1871aeb2b4dSghi } 1881aeb2b4dSghi 189*bab76148SSzymon Olewniczak if ($REV == 0 && $this->can_edit() && $sum != ApproveConst::READY_FOR_APPROVAL && $this->getConf('ready_for_approval') === 1) { 190*bab76148SSzymon Olewniczak ptln(' | <a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff', 19184047bdaSRuud 'ready_for_approval' => 'ready_for_approval')).'">'); 19284047bdaSRuud ptln($this->getLang('approve_ready')); 19384047bdaSRuud ptln('</a>'); 19484047bdaSRuud } 19584047bdaSRuud 1961aeb2b4dSghi if ($REV == 0 && $this->can_approve()) { 197*bab76148SSzymon Olewniczak ptln(' | <a href="'.wl($ID, array('rev' => $last_approved_rev, 'do' => 'diff', 1981aeb2b4dSghi 'approve' => 'approve')).'">'); 1991aeb2b4dSghi ptln($this->getLang('approve')); 2001aeb2b4dSghi ptln('</a>'); 2011aeb2b4dSghi } 20284047bdaSRuud 20384047bdaSRuud 2041aeb2b4dSghi } 2051aeb2b4dSghi ptln('</div>'); 2061aeb2b4dSghi } 2071aeb2b4dSghi 208af3e3cd8SSzymon Olewniczak /** 209af3e3cd8SSzymon Olewniczak * Check if the page has to be changed 210af3e3cd8SSzymon Olewniczak * 211af3e3cd8SSzymon Olewniczak * @param Doku_Event $event event object by reference 212af3e3cd8SSzymon Olewniczak * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 213af3e3cd8SSzymon Olewniczak * handler was registered] 214af3e3cd8SSzymon Olewniczak * @return void 215af3e3cd8SSzymon Olewniczak */ 216af3e3cd8SSzymon Olewniczak public function handle_pagesave_before(Doku_Event $event, $param) { 21755f447f4SSzymon Olewniczak global $REV; 218af3e3cd8SSzymon Olewniczak $id = $event->data['id']; 219af3e3cd8SSzymon Olewniczak if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return; 220af3e3cd8SSzymon Olewniczak 221af3e3cd8SSzymon Olewniczak //save page if summary is provided 222*bab76148SSzymon Olewniczak if($event->data['summary'] == ApproveConst::APPROVED) { 223af3e3cd8SSzymon Olewniczak $event->data['contentChanged'] = true; 22455f447f4SSzymon Olewniczak } 22555f447f4SSzymon Olewniczak } 226af3e3cd8SSzymon Olewniczak 22755f447f4SSzymon Olewniczak /** 22855f447f4SSzymon Olewniczak * @param Doku_Event $event 22955f447f4SSzymon Olewniczak * @param $param 23055f447f4SSzymon Olewniczak */ 23155f447f4SSzymon Olewniczak public function handle_pagesave_after(Doku_Event $event, $param) { 23255f447f4SSzymon Olewniczak global $REV; 23355f447f4SSzymon Olewniczak $id = $event->data['id']; 23455f447f4SSzymon Olewniczak if ($this->hlp->in_namespace($this->getConf('no_apr_namespaces'), $id)) return; 235af3e3cd8SSzymon Olewniczak 23655f447f4SSzymon Olewniczak //save page if summary is provided 237*bab76148SSzymon Olewniczak if($event->data['summary'] == ApproveConst::APPROVED) { 23855f447f4SSzymon Olewniczak 239*bab76148SSzymon Olewniczak $versions = p_get_metadata($id, ApproveConst::METADATA_VERSIONS_KEY); 24055f447f4SSzymon Olewniczak //calculate versions 24155f447f4SSzymon Olewniczak if (!$versions) { 24255f447f4SSzymon Olewniczak $this->render_metadata_for_approved_page($id, $event->data['newRevision']); 243af3e3cd8SSzymon Olewniczak } else { 24455f447f4SSzymon Olewniczak $curver = $versions[0] + 1; 24555f447f4SSzymon Olewniczak $versions[0] = $curver; 24655f447f4SSzymon Olewniczak $versions[$event->data['newRevision']] = $curver; 247*bab76148SSzymon Olewniczak p_set_metadata($id, array(ApproveConst::METADATA_VERSIONS_KEY => $versions)); 24855f447f4SSzymon Olewniczak } 24955f447f4SSzymon Olewniczak } 250af3e3cd8SSzymon Olewniczak } 251af3e3cd8SSzymon Olewniczak 252af3e3cd8SSzymon Olewniczak 253af3e3cd8SSzymon Olewniczak /** 254af3e3cd8SSzymon Olewniczak * Calculate current version 255af3e3cd8SSzymon Olewniczak * 256af3e3cd8SSzymon Olewniczak * @param $id 257*bab76148SSzymon Olewniczak * @return array 258af3e3cd8SSzymon Olewniczak */ 25955f447f4SSzymon Olewniczak protected function render_metadata_for_approved_page($id, $currev=false) { 26055f447f4SSzymon Olewniczak if (!$currev) $currev = @filemtime(wikiFN($id)); 26155f447f4SSzymon Olewniczak 26255f447f4SSzymon Olewniczak $version = $this->approved($id); 26355f447f4SSzymon Olewniczak //version for current page 26455f447f4SSzymon Olewniczak $curver = $version + 1; 26555f447f4SSzymon Olewniczak $versions = array(0 => $curver, $currev => $curver); 266af3e3cd8SSzymon Olewniczak 267af3e3cd8SSzymon Olewniczak $changelog = new PageChangeLog($id); 268af3e3cd8SSzymon Olewniczak $first = 0; 269af3e3cd8SSzymon Olewniczak $num = 100; 270af3e3cd8SSzymon Olewniczak while (count($revs = $changelog->getRevisions($first, $num)) > 0) { 271af3e3cd8SSzymon Olewniczak foreach ($revs as $rev) { 272af3e3cd8SSzymon Olewniczak $revInfo = $changelog->getRevisionInfo($rev); 273*bab76148SSzymon Olewniczak if ($revInfo['sum'] == ApproveConst::APPROVED) { 27455f447f4SSzymon Olewniczak $versions[$rev] = $version; 27555f447f4SSzymon Olewniczak $version -= 1; 276af3e3cd8SSzymon Olewniczak } 277af3e3cd8SSzymon Olewniczak } 278af3e3cd8SSzymon Olewniczak $first += $num; 279af3e3cd8SSzymon Olewniczak } 280af3e3cd8SSzymon Olewniczak 281*bab76148SSzymon Olewniczak p_set_metadata($id, array(ApproveConst::METADATA_VERSIONS_KEY => $versions)); 28255f447f4SSzymon Olewniczak 28355f447f4SSzymon Olewniczak return $versions; 284af3e3cd8SSzymon Olewniczak } 285af3e3cd8SSzymon Olewniczak 28655f447f4SSzymon Olewniczak /** 28755f447f4SSzymon Olewniczak * Get the number of approved pages 28855f447f4SSzymon Olewniczak * @param $id 28955f447f4SSzymon Olewniczak * @return int 29055f447f4SSzymon Olewniczak */ 29155f447f4SSzymon Olewniczak protected function approved($id) { 29255f447f4SSzymon Olewniczak $count = 0; 29355f447f4SSzymon Olewniczak 29455f447f4SSzymon Olewniczak $changelog = new PageChangeLog($id); 29555f447f4SSzymon Olewniczak $first = 0; 29655f447f4SSzymon Olewniczak $num = 100; 29755f447f4SSzymon Olewniczak while (count($revs = $changelog->getRevisions($first, $num)) > 0) { 29855f447f4SSzymon Olewniczak foreach ($revs as $rev) { 29955f447f4SSzymon Olewniczak $revInfo = $changelog->getRevisionInfo($rev); 300*bab76148SSzymon Olewniczak if ($revInfo['sum'] == ApproveConst::APPROVED) { 30155f447f4SSzymon Olewniczak $count += 1; 30255f447f4SSzymon Olewniczak } 30355f447f4SSzymon Olewniczak } 30455f447f4SSzymon Olewniczak $first += $num; 30555f447f4SSzymon Olewniczak } 30655f447f4SSzymon Olewniczak 30755f447f4SSzymon Olewniczak return $count; 30855f447f4SSzymon Olewniczak } 3091aeb2b4dSghi} 310