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