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