From 212720fa28a66f9247ef94e9df0b1fb2bd80ddbb Mon Sep 17 00:00:00 2001 From: Roan Kattouw Date: Sat, 4 Oct 2008 14:58:13 +0000 Subject: [PATCH] API: * (bug 15785) Allow for different expiry times for different protections, like the UI does * BREAKING CHANGE: Alter action=protect output to display multiple expiry times * BREAKING CHANGE: Error messages invalidexpiry and pastexpiry now state the expiry they're about * Add ApiBase::PARAM_ALLOW_DUPLICATES and honor it in ApiBase::getParameterFromSettings() --- RELEASE-NOTES | 2 ++ includes/api/ApiBase.php | 13 +++++--- includes/api/ApiProtect.php | 61 +++++++++++++++++++++++-------------- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 32a847dbaf..496f6bfe0f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -293,6 +293,8 @@ The following extensions are migrated into MediaWiki 1.14: * (bug 15768) Add list=watchlistraw * (bug 15647) action=edit with basetimestamp fails if the page has been deleted and undeleted since the last edit +* (bug 15785) Allow for different expiry times for different protections in + action=protect === Languages updated in 1.14 === diff --git a/includes/api/ApiBase.php b/includes/api/ApiBase.php index 622b020bb6..8a4b34cae2 100644 --- a/includes/api/ApiBase.php +++ b/includes/api/ApiBase.php @@ -46,6 +46,7 @@ abstract class ApiBase { const PARAM_MAX = 3; const PARAM_MAX2 = 4; const PARAM_MIN = 5; + const PARAM_ALLOW_DUPLICATES = 6; const LIMIT_BIG1 = 500; // Fast query, std user limit const LIMIT_BIG2 = 5000; // Fast query, bot/sysop limit @@ -442,10 +443,12 @@ abstract class ApiBase { $default = $paramSettings; $multi = false; $type = gettype($paramSettings); + $dupes = false; } else { $default = isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null; $multi = isset ($paramSettings[self :: PARAM_ISMULTI]) ? $paramSettings[self :: PARAM_ISMULTI] : false; $type = isset ($paramSettings[self :: PARAM_TYPE]) ? $paramSettings[self :: PARAM_TYPE] : null; + $dupes = isset ($paramSettings[self:: PARAM_ALLOW_DUPLICATES]) ? $paramSettings[self :: PARAM_ALLOW_DUPLICATES] : false; // When type is not given, and no choices, the type is the same as $default if (!isset ($type)) { @@ -536,8 +539,8 @@ abstract class ApiBase { } } - // There should never be any duplicate values in a list - if (is_array($value)) + // Throw out duplicates if requested + if (is_array($value) && !$dupes) $value = array_unique($value); } @@ -686,8 +689,8 @@ abstract class ApiBase { 'missingparam' => array('code' => 'no$1', 'info' => "The \$1 parameter must be set"), 'invalidtitle' => array('code' => 'invalidtitle', 'info' => "Bad title ``\$1''"), 'invaliduser' => array('code' => 'invaliduser', 'info' => "Invalid username ``\$1''"), - 'invalidexpiry' => array('code' => 'invalidexpiry', 'info' => "Invalid expiry time"), - 'pastexpiry' => array('code' => 'pastexpiry', 'info' => "Expiry time is in the past"), + 'invalidexpiry' => array('code' => 'invalidexpiry', 'info' => "Invalid expiry time ``\$1''"), + 'pastexpiry' => array('code' => 'pastexpiry', 'info' => "Expiry time ``\$1'' is in the past"), 'create-titleexists' => array('code' => 'create-titleexists', 'info' => "Existing titles can't be protected with 'create'"), 'missingtitle-createonly' => array('code' => 'missingtitle-createonly', 'info' => "Missing titles can only be protected with 'create'"), 'cantblock' => array('code' => 'cantblock', 'info' => "You don't have permission to block users"), @@ -704,6 +707,8 @@ abstract class ApiBase { 'cantpurge' => array('code' => 'cantpurge', 'info' => "Only users with the 'purge' right can purge pages via the API"), 'protect-invalidaction' => array('code' => 'protect-invalidaction', 'info' => "Invalid protection type ``\$1''"), 'protect-invalidlevel' => array('code' => 'protect-invalidlevel', 'info' => "Invalid protection level ``\$1''"), + 'toofewexpiries' => array('code' => 'toofewexpiries', 'info' => "\$1 expiry timestamps were provided where \$2 were needed"), + // ApiEditPage messages 'noimageredirect-anon' => array('code' => 'noimageredirect-anon', 'info' => "Anonymous users can't create image redirects"), diff --git a/includes/api/ApiProtect.php b/includes/api/ApiProtect.php index 9b190e1ff4..f9b124c8de 100644 --- a/includes/api/ApiProtect.php +++ b/includes/api/ApiProtect.php @@ -61,22 +61,19 @@ class ApiProtect extends ApiBase { // We don't care about multiple errors, just report one of them $this->dieUsageMsg(current($errors)); - if(in_array($params['expiry'], array('infinite', 'indefinite', 'never'))) - $expiry = Block::infinity(); - else + $expiry = (array)$params['expiry']; + if(count($expiry) != count($params['protections'])) { - $expiry = strtotime($params['expiry']); - if($expiry < 0 || $expiry == false) - $this->dieUsageMsg(array('invalidexpiry')); - - $expiry = wfTimestamp(TS_MW, $expiry); - if($expiry < wfTimestampNow()) - $this->dieUsageMsg(array('pastexpiry')); + if(count($expiry) == 1) + $expiry = array_fill(0, count($params['protections']), $expiry[0]); + else + $this->dieUsageMsg(array('toofewexpiries', count($expiry), count($params['protections']))); } - + $protections = array(); $expiryarray = array(); - foreach($params['protections'] as $prot) + $resultProtections = array(); + foreach($params['protections'] as $i => $prot) { $p = explode('=', $prot); $protections[$p[0]] = ($p[1] == 'all' ? '' : $p[1]); @@ -88,7 +85,24 @@ class ApiProtect extends ApiBase { $this->dieUsageMsg(array('protect-invalidaction', $p[0])); if(!in_array($p[1], $wgRestrictionLevels) && $p[1] != 'all') $this->dieUsageMsg(array('protect-invalidlevel', $p[1])); - $expiryarray[$p[0]] = $expiry; + + if(in_array($expiry[$i], array('infinite', 'indefinite', 'never'))) + $expiryarray[$p[0]] = Block::infinity(); + else + { + $exp = strtotime($expiry[$i]); + if($exp < 0 || $exp == false) + $this->dieUsageMsg(array('invalidexpiry', $expiry[$i])); + + $exp = wfTimestamp(TS_MW, $exp); + if($exp < wfTimestampNow()) + $this->dieUsageMsg(array('pastexpiry', $expiry[$i])); + $expiryarray[$p[0]] = $exp; + } + $resultProtections[] = array($p[0] => $protections[$p[0]], + 'expiry' => ($expiryarray[$p[0]] == Block::infinity() ? + 'infinite' : + wfTimestamp(TS_ISO_8601, $expiryarray[$p[0]]))); } if($titleObj->exists()) { @@ -101,18 +115,14 @@ class ApiProtect extends ApiBase { // Just throw an unknown error in this case, as it's very likely to be a race condition $this->dieUsageMsg(array()); $res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason']); - if($expiry == Block::infinity()) - $res['expiry'] = 'infinity'; - else - $res['expiry'] = wfTimestamp(TS_ISO_8601, $expiry); - if($params['cascade']) $res['cascade'] = ''; - $res['protections'] = $protections; + $res['protections'] = $resultProtections; + $this->getResult()->setIndexedTagName($res['protections'], 'protection'); $this->getResult()->addValue(null, $this->getModuleName(), $res); } - public function mustBePosted() { return true; } + //public function mustBePosted() { return true; } public function getAllowedParams() { return array ( @@ -121,7 +131,11 @@ class ApiProtect extends ApiBase { 'protections' => array( ApiBase :: PARAM_ISMULTI => true ), - 'expiry' => 'infinite', + 'expiry' => array( + ApiBase :: PARAM_ISMULTI => true, + ApiBase :: PARAM_ALLOW_DUPLICATES => true, + ApiBase :: PARAM_DFLT => 'infinite', + ), 'reason' => '', 'cascade' => false ); @@ -132,7 +146,8 @@ class ApiProtect extends ApiBase { 'title' => 'Title of the page you want to (un)protect.', 'token' => 'A protect token previously retrieved through prop=info', 'protections' => 'Pipe-separated list of protection levels, formatted action=group (e.g. edit=sysop)', - 'expiry' => 'Expiry timestamp. If set to \'infinite\', \'indefinite\' or \'never\', the protection will never expire.', + 'expiry' => array('Expiry timestamps. If only one timestamp is set, it\'ll be used for all protections.', + 'Use \'infinite\', \'indefinite\' or \'never\', for a neverexpiring protection.'), 'reason' => 'Reason for (un)protecting (optional)', 'cascade' => 'Enable cascading protection (i.e. protect pages included in this page)' ); @@ -146,7 +161,7 @@ class ApiProtect extends ApiBase { protected function getExamples() { return array ( - 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=sysop|move=sysop&cascade&expiry=20070901163000', + 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=sysop|move=sysop&cascade&expiry=20070901163000|never', 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=all|move=all&reason=Lifting%20restrictions' ); } -- 2.20.1