Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 96 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
NewFilesPager | |
0.00% |
0 / 95 |
|
0.00% |
0 / 7 |
420 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
12 | |||
getQueryInfo | |
0.00% |
0 / 49 |
|
0.00% |
0 / 1 |
56 | |||
getIndexField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getStartBody | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
getEndBody | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
doBatchLookups | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
formatRow | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | * @ingroup Pager |
20 | */ |
21 | |
22 | namespace MediaWiki\Pager; |
23 | |
24 | use ImageGalleryBase; |
25 | use ImageGalleryClassNotFoundException; |
26 | use MediaWiki\Cache\LinkBatchFactory; |
27 | use MediaWiki\Context\IContextSource; |
28 | use MediaWiki\Html\FormOptions; |
29 | use MediaWiki\Linker\LinkRenderer; |
30 | use MediaWiki\Permissions\GroupPermissionsLookup; |
31 | use MediaWiki\Title\Title; |
32 | use MediaWiki\Title\TitleValue; |
33 | use MediaWiki\User\ExternalUserNames; |
34 | use RecentChange; |
35 | use Wikimedia\Rdbms\IConnectionProvider; |
36 | |
37 | /** |
38 | * @ingroup Pager |
39 | */ |
40 | class NewFilesPager extends RangeChronologicalPager { |
41 | |
42 | /** |
43 | * @var ImageGalleryBase |
44 | */ |
45 | protected $gallery; |
46 | |
47 | /** |
48 | * @var FormOptions |
49 | */ |
50 | protected $opts; |
51 | |
52 | private GroupPermissionsLookup $groupPermissionsLookup; |
53 | private LinkBatchFactory $linkBatchFactory; |
54 | |
55 | /** |
56 | * @param IContextSource $context |
57 | * @param GroupPermissionsLookup $groupPermissionsLookup |
58 | * @param LinkBatchFactory $linkBatchFactory |
59 | * @param LinkRenderer $linkRenderer |
60 | * @param IConnectionProvider $dbProvider |
61 | * @param FormOptions $opts |
62 | */ |
63 | public function __construct( |
64 | IContextSource $context, |
65 | GroupPermissionsLookup $groupPermissionsLookup, |
66 | LinkBatchFactory $linkBatchFactory, |
67 | LinkRenderer $linkRenderer, |
68 | IConnectionProvider $dbProvider, |
69 | FormOptions $opts |
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() { |
93 | $opts = $this->opts; |
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() ); |
173 | } catch ( ImageGalleryClassNotFoundException $e ) { |
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 | |
225 | /** |
226 | * Retain the old class name for backwards compatibility. |
227 | * @deprecated since 1.41 |
228 | */ |
229 | class_alias( NewFilesPager::class, 'NewFilesPager' ); |