MediaWiki  master
NewFilesPager.php
Go to the documentation of this file.
1 <?php
28 
33 
37  protected $gallery;
38 
42  protected $opts;
43 
45  private $groupPermissionsLookup;
46 
48  private $linkBatchFactory;
49 
58  public function __construct(
59  IContextSource $context,
60  GroupPermissionsLookup $groupPermissionsLookup,
61  LinkBatchFactory $linkBatchFactory,
62  LinkRenderer $linkRenderer,
63  ILoadBalancer $loadBalancer,
65  ) {
66  // Set database before parent constructor to avoid setting it there with wfGetDB
67  $this->mDb = $loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA );
68 
69  parent::__construct( $context, $linkRenderer );
70 
71  $this->opts = $opts;
72  $this->groupPermissionsLookup = $groupPermissionsLookup;
73  $this->linkBatchFactory = $linkBatchFactory;
74  $this->setLimit( $opts->getValue( 'limit' ) );
75 
76  $startTimestamp = '';
77  $endTimestamp = '';
78  if ( $opts->getValue( 'start' ) ) {
79  $startTimestamp = $opts->getValue( 'start' ) . ' 00:00:00';
80  }
81  if ( $opts->getValue( 'end' ) ) {
82  $endTimestamp = $opts->getValue( 'end' ) . ' 23:59:59';
83  }
84  $this->getDateRangeCond( $startTimestamp, $endTimestamp );
85  }
86 
87  public function getQueryInfo() {
89  $conds = [];
90  $dbr = $this->getDatabase();
91  $tables = [ 'image', 'actor' ];
92  $fields = [ 'img_name', 'img_timestamp', 'actor_user', 'actor_name' ];
93  $options = [];
94  $jconds = [ 'actor' => [ 'JOIN', 'actor_id=img_actor' ] ];
95 
96  $user = $opts->getValue( 'user' );
97  if ( $user !== '' ) {
98  $conds['actor_name'] = $user;
99  }
100 
101  if ( !$opts->getValue( 'showbots' ) ) {
102  $groupsWithBotPermission = $this->groupPermissionsLookup->getGroupsWithPermission( 'bot' );
103 
104  if ( count( $groupsWithBotPermission ) ) {
105  $tables[] = 'user_groups';
106  $conds[] = 'ug_group IS NULL';
107  $jconds['user_groups'] = [
108  'LEFT JOIN',
109  [
110  'ug_group' => $groupsWithBotPermission,
111  'ug_user = actor_user',
112  'ug_expiry IS NULL OR ug_expiry >= ' . $dbr->addQuotes( $dbr->timestamp() )
113  ]
114  ];
115  }
116  }
117 
118  if ( $opts->getValue( 'hidepatrolled' ) ) {
119  $tables[] = 'recentchanges';
120  $conds['rc_type'] = RC_LOG;
121  $conds['rc_log_type'] = 'upload';
122  $conds['rc_patrolled'] = RecentChange::PRC_UNPATROLLED;
123  $conds['rc_namespace'] = NS_FILE;
124 
125  $jconds['recentchanges'] = [
126  'JOIN',
127  [
128  'rc_title = img_name',
129  'rc_actor = img_actor',
130  'rc_timestamp = img_timestamp'
131  ]
132  ];
133  }
134 
135  if ( $opts->getValue( 'mediatype' ) ) {
136  $conds['img_media_type'] = $opts->getValue( 'mediatype' );
137  }
138 
139  // We're ordering by img_timestamp, but MariaDB sometimes likes to query other tables first
140  // and filesort the result set later.
141  // See T124205 / https://mariadb.atlassian.net/browse/MDEV-8880, and T244533
142  // Twist: This would cause issues if the user is set and we need to check user existence first
143  if ( $user === '' ) {
144  $options[] = 'STRAIGHT_JOIN';
145  }
146 
147  $query = [
148  'tables' => $tables,
149  'fields' => $fields,
150  'join_conds' => $jconds,
151  'conds' => $conds,
152  'options' => $options,
153  ];
154 
155  return $query;
156  }
157 
158  public function getIndexField() {
159  return [ [ 'img_timestamp', 'img_name' ] ];
160  }
161 
162  protected function getStartBody() {
163  if ( !$this->gallery ) {
164  // Note that null for mode is taken to mean use default.
165  $mode = $this->getRequest()->getVal( 'gallerymode', null );
166  try {
167  $this->gallery = ImageGalleryBase::factory( $mode, $this->getContext() );
168  } catch ( ImageGalleryClassNotFoundException $e ) {
169  // User specified something invalid, fallback to default.
170  $this->gallery = ImageGalleryBase::factory( false, $this->getContext() );
171  }
172  }
173 
174  return '';
175  }
176 
177  protected function getEndBody() {
178  return $this->gallery->toHTML();
179  }
180 
181  protected function doBatchLookups() {
182  $this->mResult->seek( 0 );
183  $lb = $this->linkBatchFactory->newLinkBatch();
184  foreach ( $this->mResult as $row ) {
185  if ( $row->actor_user ) {
186  $lb->add( NS_USER, $row->actor_name );
187  }
188  }
189  $lb->execute();
190  }
191 
192  public function formatRow( $row ) {
193  $username = $row->actor_name;
194 
195  if ( ExternalUserNames::isExternal( $username ) ) {
196  $ul = htmlspecialchars( $username );
197  } else {
198  $ul = $this->getLinkRenderer()->makeLink(
199  new TitleValue( NS_USER, $username ),
200  $username
201  );
202  }
203  $time = $this->getLanguage()->userTimeAndDate( $row->img_timestamp, $this->getUser() );
204 
205  $this->gallery->add(
206  Title::makeTitle( NS_FILE, $row->img_name ),
207  "$ul<br />\n<i>"
208  . htmlspecialchars( $time )
209  . "</i><br />\n",
210  '',
211  '',
212  [],
214  );
215 
216  return '';
217  }
218 }
const NS_USER
Definition: Defines.php:66
const NS_FILE
Definition: Defines.php:70
const RC_LOG
Definition: Defines.php:118
getContext()
Get the base IContextSource object.
static isExternal( $username)
Tells whether the username is external or not.
static factory( $mode=false, IContextSource $context=null)
Get a new image gallery.
Class for exceptions thrown by ImageGalleryBase::factory().
getDatabase()
Get the Database object in use.
Definition: IndexPager.php:248
setLimit( $limit)
Set the limit from an other source than the request.
Definition: IndexPager.php:335
Helper class to keep track of options when mixing links and form elements.
Definition: FormOptions.php:41
getValue( $name)
Get the value for the given option name.
Class that generates HTML for internal links.
Represents a title within MediaWiki.
Definition: Title.php:82
getIndexField()
Returns the name of the index field.
getQueryInfo()
Provides all parameters needed for the main paged query.
getEndBody()
Hook into getBody() for the end of the list.
__construct(IContextSource $context, GroupPermissionsLookup $groupPermissionsLookup, LinkBatchFactory $linkBatchFactory, LinkRenderer $linkRenderer, ILoadBalancer $loadBalancer, FormOptions $opts)
formatRow( $row)
Returns an HTML string representing the result row $row.
getStartBody()
Hook into getBody(), allows text to be inserted at the start.
doBatchLookups()
Called from getBody(), before getStartBody() is called and after doQuery() was called.
FormOptions $opts
ImageGalleryBase $gallery
Pager for filtering by a range of dates.
getDateRangeCond( $startTime, $endTime)
Set and return a date range condition using timestamps provided by the user.
const PRC_UNPATROLLED
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:40
Interface for objects which can provide a MediaWiki context on request.
This class is a delegate to ILBFactory for a given database cluster.
getConnectionRef( $i, $groups=[], $domain=false, $flags=0)
const DB_REPLICA
Definition: defines.php:26