/** * Update the article's restriction field, and leave a log entry. * * @param $limit Array: set of restriction keys * @param $reason String * @param &$cascade Integer. Set to false if cascading protection isn't allowed. * @param $expiry Array: per restriction type expiration * @return bool true on success */ public function updateRestrictions($limit = array(), $reason = '', &$cascade = 0, $expiry = array()) { global $wgUser, $wgContLang; $restrictionTypes = $this->mTitle->getRestrictionTypes(); $id = $this->mTitle->getArticleID(); if ($id <= 0) { wfDebug("updateRestrictions failed: article id {$id} <= 0\n"); return false; } if (wfReadOnly()) { wfDebug("updateRestrictions failed: read-only\n"); return false; } if (!$this->mTitle->userCan('protect')) { wfDebug("updateRestrictions failed: insufficient permissions\n"); return false; } if (!$cascade) { $cascade = false; } // Take this opportunity to purge out expired restrictions Title::purgeExpiredRestrictions(); # FIXME: Same limitations as described in ProtectionForm.php (line 37); # we expect a single selection, but the schema allows otherwise. $current = array(); $updated = Article::flattenRestrictions($limit); $changed = false; foreach ($restrictionTypes as $action) { if (isset($expiry[$action])) { # Get current restrictions on $action $aLimits = $this->mTitle->getRestrictions($action); $current[$action] = implode('', $aLimits); # Are any actual restrictions being dealt with here? $aRChanged = count($aLimits) || !empty($limit[$action]); # If something changed, we need to log it. Checking $aRChanged # assures that "unprotecting" a page that is not protected does # not log just because the expiry was "changed". if ($aRChanged && $this->mTitle->mRestrictionsExpiry[$action] != $expiry[$action]) { $changed = true; } } } $current = Article::flattenRestrictions($current); $changed = $changed || $current != $updated; $changed = $changed || $updated && $this->mTitle->areRestrictionsCascading() != $cascade; $protect = $updated != ''; # If nothing's changed, do nothing if ($changed) { if (wfRunHooks('ArticleProtect', array(&$this, &$wgUser, $limit, $reason))) { $dbw = wfGetDB(DB_MASTER); # Prepare a null revision to be added to the history $modified = $current != '' && $protect; if ($protect) { $comment_type = $modified ? 'modifiedarticleprotection' : 'protectedarticle'; } else { $comment_type = 'unprotectedarticle'; } $comment = $wgContLang->ucfirst(wfMsgForContent($comment_type, $this->mTitle->getPrefixedText())); # Only restrictions with the 'protect' right can cascade... # Otherwise, people who cannot normally protect can "protect" pages via transclusion $editrestriction = isset($limit['edit']) ? array($limit['edit']) : $this->mTitle->getRestrictions('edit'); # The schema allows multiple restrictions if (!in_array('protect', $editrestriction) && !in_array('sysop', $editrestriction)) { $cascade = false; } $cascade_description = ''; if ($cascade) { $cascade_description = ' [' . wfMsgForContent('protect-summary-cascade') . ']'; } if ($reason) { $comment .= ": {$reason}"; } $editComment = $comment; $encodedExpiry = array(); $protect_description = ''; foreach ($limit as $action => $restrictions) { if (!isset($expiry[$action])) { $expiry[$action] = Block::infinity(); } $encodedExpiry[$action] = Block::encodeExpiry($expiry[$action], $dbw); if ($restrictions != '') { $protect_description .= "[{$action}={$restrictions}] ("; if ($encodedExpiry[$action] != 'infinity') { $protect_description .= wfMsgForContent('protect-expiring', $wgContLang->timeanddate($expiry[$action], false, false), $wgContLang->date($expiry[$action], false, false), $wgContLang->time($expiry[$action], false, false)); } else { $protect_description .= wfMsgForContent('protect-expiry-indefinite'); } $protect_description .= ') '; } } $protect_description = trim($protect_description); if ($protect_description && $protect) { $editComment .= " ({$protect_description})"; } if ($cascade) { $editComment .= "{$cascade_description}"; } # Update restrictions table foreach ($limit as $action => $restrictions) { if ($restrictions != '') { $dbw->replace('page_restrictions', array(array('pr_page', 'pr_type')), array('pr_page' => $id, 'pr_type' => $action, 'pr_level' => $restrictions, 'pr_cascade' => $cascade && $action == 'edit' ? 1 : 0, 'pr_expiry' => $encodedExpiry[$action]), __METHOD__); } else { $dbw->delete('page_restrictions', array('pr_page' => $id, 'pr_type' => $action), __METHOD__); } } # Insert a null revision $nullRevision = Revision::newNullRevision($dbw, $id, $editComment, true); $nullRevId = $nullRevision->insertOn($dbw); $latest = $this->getLatest(); # Update page record $dbw->update('page', array('page_touched' => $dbw->timestamp(), 'page_restrictions' => '', 'page_latest' => $nullRevId), array('page_id' => $id), 'Article::protect'); wfRunHooks('NewRevisionFromEditComplete', array($this, $nullRevision, $latest, $wgUser)); wfRunHooks('ArticleProtectComplete', array(&$this, &$wgUser, $limit, $reason)); # Update the protection log $log = new LogPage('protect'); if ($protect) { $params = array($protect_description, $cascade ? 'cascade' : ''); $log->addEntry($modified ? 'modify' : 'protect', $this->mTitle, trim($reason), $params); } else { $log->addEntry('unprotect', $this->mTitle, $reason); } } # End hook } # End "changed" check return true; }
function doProtect($limit = array(), $reason = '', &$expiry = '') { global $wgUser, $wgRestrictionTypes, $wgContLang, $wgTitle; $id = $wgTitle->getArticleID(); if (wfReadOnly() || $id == 0) { return false; } if (strlen($expiry) == 0) { $expiry = 'infinite'; } if ($expiry == 'infinite' || $expiry == 'indefinite') { $expiry = Block::infinity(); } else { # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1 $expiry = strtotime($expiry); if ($expiry < 0 || $expiry === false) { //invalid expiry, rewrite to infinity $expiry = Block::infinity(); } else { // Fixme: non-qualified absolute times are not in users specified timezone // and there isn't notice about it in the ui $expiry = wfTimestamp(TS_MW, $expiry); } } // Take this opportunity to purge out expired restrictions Title::purgeExpiredRestrictions(); # FIXME: Same limitations as described in ProtectionForm.php (line 37); # we expect a single selection, but the schema allows otherwise. $current = array(); foreach ($wgRestrictionTypes as $action) { $current[$action] = implode('', $wgTitle->getRestrictions($action)); } $current = Article::flattenRestrictions($current); $updated = Article::flattenRestrictions($limit); $changed = $current != $updated; $changed = $changed || $wgTitle->mRestrictionsExpiry != $expiry; $protect = $updated != ''; # If nothing's changed, do nothing if ($changed) { global $wgGroupPermissions; $dbw = wfGetDB(DB_MASTER); $encodedExpiry = Block::encodeExpiry($expiry, $dbw); $expiry_description = ''; if ($encodedExpiry != 'infinity') { $expiry_description = ' (' . wfMsgForContent('protect-expiring', $wgContLang->timeanddate($expiry, false, false)) . ')'; } # Prepare a null revision to be added to the history $modified = $current != '' && $protect; if ($protect) { $comment_type = $modified ? 'modifiedarticleprotection' : 'protectedarticle'; } else { $comment_type = 'unprotectedarticle'; } $comment = $wgContLang->ucfirst(wfMsgForContent($comment_type, $wgTitle->getPrefixedText())); if ($reason) { $comment .= ": {$reason}"; } if ($protect) { $comment .= " [{$updated}]"; } if ($expiry_description && $protect) { $comment .= "{$expiry_description}"; } # Update restrictions table foreach ($limit as $action => $restrictions) { if ($restrictions != '') { $dbw->replace('page_restrictions', array(array('pr_page', 'pr_type')), array('pr_page' => $id, 'pr_type' => $action, 'pr_level' => $restrictions, 'pr_cascade' => 0, 'pr_expiry' => $encodedExpiry), __METHOD__); } else { $dbw->delete('page_restrictions', array('pr_page' => $id, 'pr_type' => $action), __METHOD__); } } # Insert a null revision $nullRevision = Revision::newNullRevision($dbw, $id, $comment, true); $nullRevId = $nullRevision->insertOn($dbw); # Update page record $dbw->update('page', array('page_touched' => $dbw->timestamp(), 'page_restrictions' => '', 'page_latest' => $nullRevId), array('page_id' => $id), 'Article::protect'); # Update the protection log $log = new LogPage('protect'); if ($protect) { $log->addEntry($modified ? 'modify' : 'protect', $wgTitle, trim($reason . " [{$updated}]{$expiry_description}")); } else { $log->addEntry('unprotect', $wgTitle, $reason); } } # End "changed" check return true; }
/** * Update the article's restriction field, and leave a log entry. * * @param array $limit set of restriction keys * @param string $reason * @return bool true on success */ function updateRestrictions($limit = array(), $reason = '') { global $wgUser, $wgRestrictionTypes, $wgContLang; $id = $this->mTitle->getArticleID(); if (!$wgUser->isAllowed('protect') || wfReadOnly() || $id == 0) { return false; } # FIXME: Same limitations as described in ProtectionForm.php (line 37); # we expect a single selection, but the schema allows otherwise. $current = array(); foreach ($wgRestrictionTypes as $action) { $current[$action] = implode('', $this->mTitle->getRestrictions($action)); } $current = Article::flattenRestrictions($current); $updated = Article::flattenRestrictions($limit); $changed = $current != $updated; $protect = $updated != ''; # If nothing's changed, do nothing if ($changed) { if (wfRunHooks('ArticleProtect', array(&$this, &$wgUser, $limit, $reason))) { $dbw =& wfGetDB(DB_MASTER); # Prepare a null revision to be added to the history $comment = $wgContLang->ucfirst(wfMsgForContent($protect ? 'protectedarticle' : 'unprotectedarticle', $this->mTitle->getPrefixedText())); if ($reason) { $comment .= ": {$reason}"; } if ($protect) { $comment .= " [{$updated}]"; } $nullRevision = Revision::newNullRevision($dbw, $id, $comment, true); $nullRevId = $nullRevision->insertOn($dbw); # Update page record $dbw->update('page', array('page_touched' => $dbw->timestamp(), 'page_restrictions' => $updated, 'page_latest' => $nullRevId), array('page_id' => $id), 'Article::protect'); wfRunHooks('ArticleProtectComplete', array(&$this, &$wgUser, $limit, $reason)); # Update the protection log $log = new LogPage('protect'); if ($protect) { $log->addEntry('protect', $this->mTitle, trim($reason . " [{$updated}]")); } else { $log->addEntry('unprotect', $this->mTitle, $reason); } } # End hook } # End "changed" check return true; }
/** * Update the article's restriction field, and leave a log entry. * * @param array $limit set of restriction keys * @param string $reason * @return bool true on success */ function updateRestrictions($limit = array(), $reason = '', $cascade = 0, $expiry = null) { global $wgUser, $wgRestrictionTypes, $wgContLang; $id = $this->mTitle->getArticleID(); if (array() != $this->mTitle->getUserPermissionsErrors('protect', $wgUser) || wfReadOnly() || $id == 0) { return false; } if (!$cascade) { $cascade = false; } // Take this opportunity to purge out expired restrictions Title::purgeExpiredRestrictions(); # FIXME: Same limitations as described in ProtectionForm.php (line 37); # we expect a single selection, but the schema allows otherwise. $current = array(); foreach ($wgRestrictionTypes as $action) { $current[$action] = implode('', $this->mTitle->getRestrictions($action)); } $current = Article::flattenRestrictions($current); $updated = Article::flattenRestrictions($limit); $changed = $current != $updated; $changed = $changed || $this->mTitle->areRestrictionsCascading() != $cascade; $changed = $changed || $this->mTitle->mRestrictionsExpiry != $expiry; $protect = $updated != ''; # If nothing's changed, do nothing if ($changed) { global $wgGroupPermissions; if (wfRunHooks('ArticleProtect', array(&$this, &$wgUser, $limit, $reason))) { $dbw = wfGetDB(DB_MASTER); $encodedExpiry = Block::encodeExpiry($expiry, $dbw); $expiry_description = ''; if ($encodedExpiry != 'infinity') { $expiry_description = ' (' . wfMsgForContent('protect-expiring', $wgContLang->timeanddate($expiry, false, false)) . ')'; } # Prepare a null revision to be added to the history $modified = $current != '' && $protect; if ($protect) { $comment_type = $modified ? 'modifiedarticleprotection' : 'protectedarticle'; } else { $comment_type = 'unprotectedarticle'; } $comment = $wgContLang->ucfirst(wfMsgForContent($comment_type, $this->mTitle->getPrefixedText())); foreach ($limit as $action => $restrictions) { # Check if the group level required to edit also can protect pages # Otherwise, people who cannot normally protect can "protect" pages via transclusion $cascade = $cascade && isset($wgGroupPermissions[$restrictions]['protect']) && $wgGroupPermissions[$restrictions]['protect']; } $cascade_description = ''; if ($cascade) { $cascade_description = ' [' . wfMsg('protect-summary-cascade') . ']'; } if ($reason) { $comment .= ": {$reason}"; } if ($protect) { $comment .= " [{$updated}]"; } if ($expiry_description && $protect) { $comment .= "{$expiry_description}"; } if ($cascade) { $comment .= "{$cascade_description}"; } $rowsAffected = false; # Update restrictions table foreach ($limit as $action => $restrictions) { if ($restrictions != '') { $dbw->replace('page_restrictions', array(array('pr_page', 'pr_type')), array('pr_page' => $id, 'pr_type' => $action, 'pr_level' => $restrictions, 'pr_cascade' => $cascade ? 1 : 0, 'pr_expiry' => $encodedExpiry), __METHOD__); if ($dbw->affectedRows() != 0) { $rowsAffected = true; } } else { $dbw->delete('page_restrictions', array('pr_page' => $id, 'pr_type' => $action), __METHOD__); if ($dbw->affectedRows() != 0) { $rowsAffected = true; } } } if (!$rowsAffected) { // No change return true; } # Insert a null revision $nullRevision = Revision::newNullRevision($dbw, $id, $comment, true); $nullRevId = $nullRevision->insertOn($dbw); # Update page record $dbw->update('page', array('page_touched' => $dbw->timestamp(), 'page_restrictions' => '', 'page_catinfo' => $this->mTitle->getCategoryMask(), 'page_latest' => $nullRevId), array('page_id' => $id), 'Article::protect'); wfRunHooks('ArticleProtectComplete', array(&$this, &$wgUser, $limit, $reason)); # Update the protection log $log = new LogPage('protect'); if ($protect) { $log->addEntry($modified ? 'modify' : 'protect', $this->mTitle, trim($reason . " [{$updated}]{$cascade_description}{$expiry_description}")); } else { $log->addEntry('unprotect', $this->mTitle, $reason); } } # End hook } # End "changed" check return true; }