From fd6ae6f62c38f0dbe1eb1a01ca43b057f2c634c0 Mon Sep 17 00:00:00 2001 From: Viktor Date: Sun, 24 Feb 2019 07:16:52 +0200 Subject: [PATCH 1/4] Add the "approving_weights" option --- conf/default.php | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/default.php b/conf/default.php index 8d52fae..723ad09 100644 --- a/conf/default.php +++ b/conf/default.php @@ -3,6 +3,7 @@ $conf['apr_namespaces'] = ''; $conf['no_apr_namespaces'] = ''; $conf['number_of_approved'] = 1; +$conf['approving_weights'] = ''; $conf['hidereaderbanner'] = 0; $conf['hide drafts'] = 0; $conf['hide_approved_banner'] = 0; From 150dc8609d689adb8c401327fa422b4a956a524e Mon Sep 17 00:00:00 2001 From: Viktor Date: Sun, 24 Feb 2019 07:18:52 +0200 Subject: [PATCH 2/4] Add the "approving_weights" metadata --- conf/metadata.php | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/metadata.php b/conf/metadata.php index cb9ea4b..e475937 100644 --- a/conf/metadata.php +++ b/conf/metadata.php @@ -3,6 +3,7 @@ $meta['apr_namespaces'] = array('string'); $meta['no_apr_namespaces'] = array('string'); $meta['number_of_approved'] = array('numeric', '_min' => 1); +$meta['approving_weights'] = array('string', '_pattern' => '#^(\w+=\d+&?)*$#'); $meta['hide drafts'] = array('onoff'); $meta['hidereaderbanner'] = array('onoff'); $meta['hide_approved_banner'] = array('onoff'); From 3ce767b2b3740da155432e2ef1d1fc47bbfedf03 Mon Sep 17 00:00:00 2001 From: Viktor Date: Sun, 24 Feb 2019 07:20:07 +0200 Subject: [PATCH 3/4] Add the "approving_weights" description --- lang/en/settings.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lang/en/settings.php b/lang/en/settings.php index 9f25083..9f31ed6 100644 --- a/lang/en/settings.php +++ b/lang/en/settings.php @@ -3,6 +3,7 @@ $lang['apr_namespaces'] = 'Namespaces this plugin applies to (space separated list).'; $lang['no_apr_namespaces'] = 'Namespaces this plugin does not apply to (space separated list).'; $lang['number_of_approved'] = 'Number of users needed to approve a page.'; +$lang['approving_weights'] = 'Groups and the number of approvals required to approve a page (for example, if number_of_approved=10 and this option is defined as admin=10&moderator=5&user=1, then a page can be approved by one admin, two moderators, ten users, or one moderator and five users)'; $lang['hidereaderbanner'] = 'Hide banner to read only users'; $lang['hide drafts'] = 'Hide drafts to read only users'; $lang['hide_approved_banner'] = 'Hide banner on approved pages'; From 491eb0a4dc07d265bec1877cd6962a77b0893942 Mon Sep 17 00:00:00 2001 From: Viktor Date: Sun, 24 Feb 2019 07:23:45 +0200 Subject: [PATCH 4/4] Implement the "approving_weights" feature --- helper.php | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/helper.php b/helper.php index ea8ba15..59c5354 100644 --- a/helper.php +++ b/helper.php @@ -99,7 +99,21 @@ function canApprove() { return false; } - return ($INFO['perm'] >= AUTH_DELETE); + if ($INFO['perm'] >= AUTH_DELETE) { + return true; + } + + if (empty($INFO['userinfo']['grps'])) { + return false; + } + + $approving_weights = $this->getApprovingWeights(); + if ($approving_weights) { + $approving_groups = array_keys($approving_weights); + return !!array_intersect($approving_groups, $INFO['userinfo']['grps']); + } + + return false; } function getRevision($id = null) { @@ -207,7 +221,52 @@ function isRevisionApproved($revision, $id = null) { if (!isset($approvals[$revision])) { return false; } - return (count($approvals[$revision]) >= $this->getConf('number_of_approved')); + + $number_of_approved = $this->getConf('number_of_approved'); + if (count($approvals[$revision]) >= $number_of_approved) { + return true; + } + + $approving_weights = $this->getApprovingWeights(); + if (!$approving_weights) { + return false; + } + + global $auth; + foreach ($approvals[$revision] as $username => $approver) { + $userdata = $auth->getUserData($username); + if (empty($userdata['grps'])) { + continue; + } + + foreach ($approving_weights as $approving_group => $approving_weight) { + if (in_array($approving_group, $userdata['grps'], true)) { + $number_of_approved -= $approving_weight; + if ($number_of_approved <= 0) { + return true; + } + } + } + } + return false; + } + + /** + * @staticvar array $weights + * @return array + */ + private function getApprovingWeights() { + static $weights = null; + if ($weights === null) { + $qs = $this->getConf('approving_weights'); + if ($qs) { + parse_str($qs, $weights); + $weights = array_filter(array_map('intval', $weights)); + } else { + $weights = []; + } + } + return $weights; } function isCurrentRevisionApproved($id = null) {