summaryrefslogtreecommitdiff
path: root/includes/logging/LogEventsList.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/logging/LogEventsList.php')
-rw-r--r--includes/logging/LogEventsList.php235
1 files changed, 139 insertions, 96 deletions
diff --git a/includes/logging/LogEventsList.php b/includes/logging/LogEventsList.php
index c27b57af..4dc25ef3 100644
--- a/includes/logging/LogEventsList.php
+++ b/includes/logging/LogEventsList.php
@@ -3,7 +3,7 @@
* Contain classes to list log entries
*
* Copyright © 2004 Brion Vibber <brion@pobox.com>, 2008 Aaron Schulz
- * http://www.mediawiki.org/
+ * https://www.mediawiki.org/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@ class LogEventsList extends ContextSource {
public $flags;
/**
- * @var Array
+ * @var array
*/
protected $mDefaultQuery;
@@ -40,10 +40,11 @@ class LogEventsList extends ContextSource {
* The first two parameters used to be $skin and $out, but now only a context
* is needed, that's why there's a second unused parameter.
*
- * @param $context IContextSource Context to use; formerly it was Skin object.
- * @param $unused void Unused; used to be an OutputPage object.
- * @param int $flags flags; can be a combinaison of self::NO_ACTION_LINK,
- * self::NO_EXTRA_USER_LINKS or self::USE_REVDEL_CHECKBOXES.
+ * @param IContextSource|Skin $context Context to use; formerly it was
+ * a Skin object. Use of Skin is deprecated.
+ * @param null $unused Unused; used to be an OutputPage object.
+ * @param int $flags Can be a combination of self::NO_ACTION_LINK,
+ * self::NO_EXTRA_USER_LINKS or self::USE_REVDEL_CHECKBOXES.
*/
public function __construct( $context, $unused = null, $flags = 0 ) {
if ( $context instanceof IContextSource ) {
@@ -59,46 +60,29 @@ class LogEventsList extends ContextSource {
/**
* Deprecated alias for getTitle(); do not use.
*
- * @deprecated in 1.20; use getTitle() instead.
- * @return Title object
+ * @deprecated since 1.20; use getTitle() instead.
+ * @return Title
*/
public function getDisplayTitle() {
+ wfDeprecated( __METHOD__, '1.20' );
return $this->getTitle();
}
/**
- * Set page title and show header for this log type
- * @param $type Array
- * @deprecated in 1.19
- */
- public function showHeader( $type ) {
- wfDeprecated( __METHOD__, '1.19' );
- // If only one log type is used, then show a special message...
- $headerType = count( $type ) == 1 ? $type[0] : '';
- $out = $this->getOutput();
- if ( LogPage::isLogType( $headerType ) ) {
- $page = new LogPage( $headerType );
- $out->setPageTitle( $page->getName()->text() );
- $out->addHTML( $page->getDescription()->parseAsBlock() );
- } else {
- $out->addHTML( $this->msg( 'alllogstext' )->parse() );
- }
- }
-
- /**
* Show options for the log list
*
- * @param string $types or Array
- * @param $user String
- * @param $page String
- * @param $pattern String
- * @param $year Integer: year
- * @param $month Integer: month
- * @param $filter: array
- * @param $tagFilter: array?
+ * @param array|string $types
+ * @param string $user
+ * @param string $page
+ * @param string $pattern
+ * @param int $year Year
+ * @param int $month Month
+ * @param array $filter
+ * @param string $tagFilter Tag to select by default
*/
- public function showOptions( $types = array(), $user = '', $page = '', $pattern = '', $year = '',
- $month = '', $filter = null, $tagFilter = '' ) {
+ public function showOptions( $types = array(), $user = '', $page = '', $pattern = '', $year = 0,
+ $month = 0, $filter = null, $tagFilter = ''
+ ) {
global $wgScript, $wgMiserMode;
$title = SpecialPage::getTitleFor( 'Log' );
@@ -122,7 +106,7 @@ class LogEventsList extends ContextSource {
}
// date menu
- $html .= Xml::tags( 'p', null, Xml::dateMenu( $year, $month ) );
+ $html .= Xml::tags( 'p', null, Xml::dateMenu( (int)$year, (int)$month ) );
// Tag filter
if ( $tagSelector ) {
@@ -147,8 +131,8 @@ class LogEventsList extends ContextSource {
}
/**
- * @param $filter Array
- * @return String: Formatted HTML
+ * @param array $filter
+ * @return string Formatted HTML
*/
private function getFilterLinks( $filter ) {
// show/hide links
@@ -176,6 +160,7 @@ class LogEventsList extends ContextSource {
$links[$type] = $this->msg( "log-show-hide-{$type}" )->rawParams( $link )->escaped();
$hiddens .= Html::hidden( "hide_{$type}_log", $val ) . "\n";
}
+
// Build links
return '<small>' . $this->getLanguage()->pipeList( $links ) . '</small>' . $hiddens;
}
@@ -191,17 +176,19 @@ class LogEventsList extends ContextSource {
unset( $this->mDefaultQuery['month'] );
unset( $this->mDefaultQuery['year'] );
}
+
return $this->mDefaultQuery;
}
/**
- * @param $queryTypes Array
- * @return String: Formatted HTML
+ * @param array $queryTypes
+ * @return string Formatted HTML
*/
private function getTypeMenu( $queryTypes ) {
$queryType = count( $queryTypes ) == 1 ? $queryTypes[0] : '';
$selector = $this->getTypeSelector();
$selector->setDefault( $queryType );
+
return $selector->getHtml();
}
@@ -238,27 +225,39 @@ class LogEventsList extends ContextSource {
}
/**
- * @param $user String
- * @return String: Formatted HTML
+ * @param string $user
+ * @return string Formatted HTML
*/
private function getUserInput( $user ) {
- return '<span style="white-space: nowrap">' .
- Xml::inputLabel( $this->msg( 'specialloguserlabel' )->text(), 'user', 'mw-log-user', 15, $user ) .
- '</span>';
+ $label = Xml::inputLabel(
+ $this->msg( 'specialloguserlabel' )->text(),
+ 'user',
+ 'mw-log-user',
+ 15,
+ $user
+ );
+
+ return '<span style="white-space: nowrap">' . $label . '</span>';
}
/**
- * @param $title String
- * @return String: Formatted HTML
+ * @param string $title
+ * @return string Formatted HTML
*/
private function getTitleInput( $title ) {
- return '<span style="white-space: nowrap">' .
- Xml::inputLabel( $this->msg( 'speciallogtitlelabel' )->text(), 'page', 'mw-log-page', 20, $title ) .
- '</span>';
+ $label = Xml::inputLabel(
+ $this->msg( 'speciallogtitlelabel' )->text(),
+ 'page',
+ 'mw-log-page',
+ 20,
+ $title
+ );
+
+ return '<span style="white-space: nowrap">' . $label . '</span>';
}
/**
- * @param $pattern
+ * @param string $pattern
* @return string Checkbox
*/
private function getTitlePattern( $pattern ) {
@@ -268,7 +267,7 @@ class LogEventsList extends ContextSource {
}
/**
- * @param $types
+ * @param array $types
* @return string
*/
private function getExtraInputs( $types ) {
@@ -281,6 +280,7 @@ class LogEventsList extends ContextSource {
return Xml::inputLabel( $this->msg( 'revdelete-offender' )->text(), 'offender',
'mw-log-offender', 20, $offender );
}
+
return '';
}
@@ -299,8 +299,8 @@ class LogEventsList extends ContextSource {
}
/**
- * @param $row Row: a single row from the result set
- * @return String: Formatted HTML list item
+ * @param stdClass $row A single row from the result set
+ * @return string Formatted HTML list item
*/
public function logLine( $row ) {
$entry = DatabaseLogEntry::newFromRow( $row );
@@ -339,12 +339,15 @@ class LogEventsList extends ContextSource {
}
/**
- * @param $row Row
+ * @param stdClass $row Row
* @return string
*/
private function getShowHideLinks( $row ) {
- if ( ( $this->flags == self::NO_ACTION_LINK ) // we don't want to see the links
- || $row->log_type == 'suppress' ) { // no one can hide items from the suppress log
+ // We don't want to see the links and
+ // no one can hide items from the suppress log.
+ if ( ( $this->flags == self::NO_ACTION_LINK )
+ || $row->log_type == 'suppress'
+ ) {
return '';
}
$del = '';
@@ -352,15 +355,26 @@ class LogEventsList extends ContextSource {
// Don't show useless checkbox to people who cannot hide log entries
if ( $user->isAllowed( 'deletedhistory' ) ) {
$canHide = $user->isAllowed( 'deletelogentry' );
+ $canViewSuppressedOnly = $user->isAllowed( 'viewsuppressed' ) &&
+ !$user->isAllowed( 'suppressrevision' );
+ $entryIsSuppressed = self::isDeleted( $row, LogPage::DELETED_RESTRICTED );
+ $canViewThisSuppressedEntry = $canViewSuppressedOnly && $entryIsSuppressed;
if ( $row->log_deleted || $canHide ) {
- if ( $canHide && $this->flags & self::USE_REVDEL_CHECKBOXES ) { // Show checkboxes instead of links.
- if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $user ) ) { // If event was hidden from sysops
+ // Show checkboxes instead of links.
+ if ( $canHide && $this->flags & self::USE_REVDEL_CHECKBOXES && !$canViewThisSuppressedEntry ) {
+ // If event was hidden from sysops
+ if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $user ) ) {
$del = Xml::check( 'deleterevisions', false, array( 'disabled' => 'disabled' ) );
} else {
- $del = Xml::check( 'showhiderevisions', false, array( 'name' => 'ids[' . $row->log_id . ']' ) );
+ $del = Xml::check(
+ 'showhiderevisions',
+ false,
+ array( 'name' => 'ids[' . $row->log_id . ']' )
+ );
}
} else {
- if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $user ) ) { // If event was hidden from sysops
+ // If event was hidden from sysops
+ if ( !self::userCan( $row, LogPage::DELETED_RESTRICTED, $user ) ) {
$del = Linker::revDeleteLinkDisabled( $canHide );
} else {
$query = array(
@@ -368,20 +382,25 @@ class LogEventsList extends ContextSource {
'type' => 'logging',
'ids' => $row->log_id,
);
- $del = Linker::revDeleteLink( $query, self::isDeleted( $row, LogPage::DELETED_RESTRICTED ), $canHide );
+ $del = Linker::revDeleteLink(
+ $query,
+ $entryIsSuppressed,
+ $canHide && !$canViewThisSuppressedEntry
+ );
}
}
}
}
+
return $del;
}
/**
- * @param $row Row
- * @param $type Mixed: string/array
- * @param $action Mixed: string/array
- * @param $right string
- * @return Boolean
+ * @param stdClass $row Row
+ * @param string|array $type
+ * @param string|array $action
+ * @param string $right
+ * @return bool
*/
public static function typeAction( $row, $type, $action, $right = '' ) {
$match = is_array( $type ) ?
@@ -394,6 +413,7 @@ class LogEventsList extends ContextSource {
$match = $wgUser->isAllowed( $right );
}
}
+
return $match;
}
@@ -401,10 +421,10 @@ class LogEventsList extends ContextSource {
* Determine if the current user is allowed to view a particular
* field of this log row, if it's marked as deleted.
*
- * @param $row Row
- * @param $field Integer
- * @param $user User object to check, or null to use $wgUser
- * @return Boolean
+ * @param stdClass $row Row
+ * @param int $field
+ * @param User $user User to check, or null to use $wgUser
+ * @return bool
*/
public static function userCan( $row, $field, User $user = null ) {
return self::userCanBitfield( $row->log_deleted, $field, $user );
@@ -414,33 +434,33 @@ class LogEventsList extends ContextSource {
* Determine if the current user is allowed to view a particular
* field of this log row, if it's marked as deleted.
*
- * @param $bitfield Integer (current field)
- * @param $field Integer
- * @param $user User object to check, or null to use $wgUser
- * @return Boolean
+ * @param int $bitfield Current field
+ * @param int $field
+ * @param User $user User to check, or null to use $wgUser
+ * @return bool
*/
public static function userCanBitfield( $bitfield, $field, User $user = null ) {
if ( $bitfield & $field ) {
- if ( $bitfield & LogPage::DELETED_RESTRICTED ) {
- $permission = 'suppressrevision';
- } else {
- $permission = 'deletedhistory';
- }
- wfDebug( "Checking for $permission due to $field match on $bitfield\n" );
if ( $user === null ) {
global $wgUser;
$user = $wgUser;
}
- return $user->isAllowed( $permission );
- } else {
- return true;
+ if ( $bitfield & LogPage::DELETED_RESTRICTED ) {
+ $permissions = array( 'suppressrevision', 'viewsuppressed' );
+ } else {
+ $permissions = array( 'deletedhistory' );
+ }
+ $permissionlist = implode( ', ', $permissions );
+ wfDebug( "Checking for $permissionlist due to $field match on $bitfield\n" );
+ return call_user_func_array( array( $user, 'isAllowedAny' ), $permissions );
}
+ return true;
}
/**
- * @param $row Row
- * @param $field Integer: one of DELETED_* bitfield constants
- * @return Boolean
+ * @param stdClass $row Row
+ * @param int $field One of DELETED_* bitfield constants
+ * @return bool
*/
public static function isDeleted( $row, $field ) {
return ( $row->log_deleted & $field ) == $field;
@@ -449,7 +469,7 @@ class LogEventsList extends ContextSource {
/**
* Show log extract. Either with text and a box (set $msgKey) or without (don't set $msgKey)
*
- * @param $out OutputPage|String-by-reference
+ * @param OutputPage|string $out By-reference
* @param string|array $types Log types to show
* @param string|Title $page The page title to show log entries for
* @param string $user The user who made the log entries
@@ -466,7 +486,8 @@ class LogEventsList extends ContextSource {
* - wrap String Wrap the message in html (usually something like "<div ...>$1</div>").
* - flags Integer display flags (NO_ACTION_LINK,NO_EXTRA_USER_LINKS)
* - useRequestParams boolean Set true to use Pager-related parameters in the WebRequest
- * @return Integer Number of total log items (not limited by $lim)
+ * - useMaster boolean Use master DB
+ * @return int Number of total log items (not limited by $lim)
*/
public static function showLogExtract(
&$out, $types = array(), $page = '', $user = '', $param = array()
@@ -479,6 +500,7 @@ class LogEventsList extends ContextSource {
'wrap' => "$1",
'flags' => 0,
'useRequestParams' => false,
+ 'useMaster' => false,
);
# The + operator appends elements of remaining keys from the right
# handed array to the left handed, whereas duplicated keys are NOT overwritten.
@@ -511,17 +533,31 @@ class LogEventsList extends ContextSource {
$pager->mOffset = "";
$pager->mIsBackwards = false;
}
+
+ if ( $param['useMaster'] ) {
+ $pager->mDb = wfGetDB( DB_MASTER );
+ }
if ( isset( $param['offset'] ) ) { # Tell pager to ignore WebRequest offset
$pager->setOffset( $param['offset'] );
}
+
if ( $lim > 0 ) {
$pager->mLimit = $lim;
}
+
$logBody = $pager->getBody();
$s = '';
+
if ( $logBody ) {
if ( $msgKey[0] ) {
- $s = '<div class="mw-warning-with-logexcerpt">';
+ $dir = $context->getLanguage()->getDir();
+ $lang = $context->getLanguage()->getCode();
+
+ $s = Xml::openElement( 'div', array(
+ 'class' => "mw-warning-with-logexcerpt mw-content-$dir",
+ 'dir' => $dir,
+ 'lang' => $lang,
+ ) );
if ( count( $msgKey ) == 1 ) {
$s .= $context->msg( $msgKey[0] )->parseAsBlock();
@@ -538,6 +574,7 @@ class LogEventsList extends ContextSource {
$s = Html::rawElement( 'div', array( 'class' => 'mw-warning-logempty' ),
$context->msg( 'logempty' )->parse() );
}
+
if ( $pager->getNumRows() > $pager->mLimit ) { # Show "Full log" link
$urlParam = array();
if ( $page instanceof Title ) {
@@ -545,16 +582,20 @@ class LogEventsList extends ContextSource {
} elseif ( $page != '' ) {
$urlParam['page'] = $page;
}
+
if ( $user != '' ) {
$urlParam['user'] = $user;
}
+
if ( !is_array( $types ) ) { # Make it an array, if it isn't
$types = array( $types );
}
+
# If there is exactly one log type, we can link to Special:Log?type=foo
if ( count( $types ) == 1 ) {
$urlParam['type'] = $types[0];
}
+
$s .= Linker::link(
SpecialPage::getTitleFor( 'Log' ),
$context->msg( 'log-fulllog' )->escaped(),
@@ -562,6 +603,7 @@ class LogEventsList extends ContextSource {
$urlParam
);
}
+
if ( $logBody && $msgKey[0] ) {
$s .= '</div>';
}
@@ -586,10 +628,10 @@ class LogEventsList extends ContextSource {
/**
* SQL clause to skip forbidden log types for this user
*
- * @param $db DatabaseBase
- * @param $audience string, public/user
- * @param $user User object to check, or null to use $wgUser
- * @return Mixed: string or false
+ * @param DatabaseBase $db
+ * @param string $audience Public/user
+ * @param User $user User to check, or null to use $wgUser
+ * @return string|bool String on success, false on failure.
*/
public static function getExcludeClause( $db, $audience = 'public', User $user = null ) {
global $wgLogRestrictions;
@@ -613,6 +655,7 @@ class LogEventsList extends ContextSource {
} elseif ( $hiddenLogs ) {
return 'log_type NOT IN (' . $db->makeList( $hiddenLogs ) . ')';
}
+
return false;
}
}