MediaWiki REL1_37
ContributionsLookup.php
Go to the documentation of this file.
1<?php
2
4
6use ChangeTags;
15use Message;
19
24
27
30
33
36
39
42
45
55 public function __construct(
63 ) {
64 $this->revisionStore = $revisionStore;
65 $this->linkRendererFactory = $linkRendererFactory;
66 $this->linkBatchFactory = $linkBatchFactory;
67 $this->hookContainer = $hookContainer;
68 $this->loadBalancer = $loadBalancer;
69 $this->actorMigration = $actorMigration;
70 $this->namespaceInfo = $namespaceInfo;
71 }
72
84 private function getPagerParams( int $limit, string $segment ): array {
85 $dir = 'next';
86 $seg = explode( '|', $segment, 2 );
87 if ( count( $seg ) > 1 ) {
88 if ( $seg[0] === 'after' ) {
89 $dir = 'prev';
90 $segment = $seg[1];
91 } elseif ( $seg[0] == 'before' ) {
92 $segment = $seg[1];
93 } else {
94 $dir = null;
95 $segment = null;
96 }
97 } else {
98 $segment = null;
99 }
100 return [
101 'limit' => $limit,
102 'offset' => $segment,
103 'dir' => $dir
104 ];
105 }
106
117 public function getContributions(
118 UserIdentity $target,
119 int $limit,
120 Authority $performer,
121 string $segment = '',
122 string $tag = null
124 $context = new RequestContext();
125 $context->setAuthority( $performer );
126
127 $paramArr = $this->getPagerParams( $limit, $segment );
128 $context->setRequest( new FauxRequest( $paramArr ) );
129
130 // TODO: explore moving this to factory method for testing
131 $pager = $this->getContribsPager( $context, $target, [
132 'tagfilter' => $tag,
133 'revisionsOnly' => true
134 ] );
135 $revisions = [];
136 $tags = [];
137 $count = 0;
138 if ( $pager->getNumRows() > 0 ) {
139 foreach ( $pager->mResult as $row ) {
140 // We retrieve and ignore one extra record to see if we are on the oldest segment.
141 if ( ++$count > $limit ) {
142 break;
143 }
144
145 // TODO: pre-load title batch?
146 $revision = $this->revisionStore->newRevisionFromRow( $row, 0 );
147 $revisions[] = $revision;
148 if ( $row->ts_tags ) {
149 $tagNames = explode( ',', $row->ts_tags );
150 $tags[ $row->rev_id ] = $this->getContributionTags( $tagNames );
151 }
152 }
153 }
154
155 $deltas = $this->getContributionDeltas( $revisions );
156
157 $flags = [
158 'newest' => $pager->mIsFirst,
159 'oldest' => $pager->mIsLast,
160 ];
161
162 // TODO: Make me an option in IndexPager
163 $pager->mIsFirst = false; // XXX: nasty...
164 $pagingQueries = $pager->getPagingQueries();
165
166 $prev = $pagingQueries['prev']['offset'] ?? null;
167 $next = $pagingQueries['next']['offset'] ?? null;
168
169 $after = $prev ? 'after|' . $prev : null; // later in time
170 $before = $next ? 'before|' . $next : null; // earlier in time
171
172 // TODO: Possibly return public $pager properties to segment for populating URLS ($mIsFirst, $mIsLast)
173 // HACK: Force result set order to be descending. Sorting logic in ContribsPager::reallyDoQuery is confusing.
174 if ( $paramArr['dir'] === 'prev' ) {
175 $revisions = array_reverse( $revisions );
176 }
177 return new ContributionsSegment( $revisions, $tags, $before, $after, $deltas, $flags );
178 }
179
184 private function getContributionTags( array $tagNames ): array {
185 $tagMetadata = [];
186 foreach ( $tagNames as $name ) {
187 $tagDisplay = ChangeTags::tagShortDescriptionMessage( $name, RequestContext::getMain() );
188 if ( $tagDisplay ) {
189 $tagMetadata[$name] = $tagDisplay;
190 }
191 }
192 return $tagMetadata;
193 }
194
202 private function getContributionDeltas( $revisions ): array {
203 // SpecialContributions uses the size of the revision if the parent revision is unknown. Cases include:
204 // - revision has been deleted
205 // - parent rev id has not been populated (this is the case for very old revisions)
206 $parentIds = [];
207 foreach ( $revisions as $revision ) {
208 $revId = $revision->getId();
209 $parentIds[$revId] = $revision->getParentId();
210 }
211 $parentSizes = $this->revisionStore->getRevisionSizes( $parentIds );
212 $deltas = [];
213 foreach ( $revisions as $revision ) {
214 $parentId = $revision->getParentId();
215 if ( $parentId === 0 ) { // first revision on a page
216 $delta = $revision->getSize();
217 } elseif ( !isset( $parentSizes[$parentId] ) ) { // parent revision is either deleted or untracked
218 $delta = null;
219 } else {
220 $delta = $revision->getSize() - $parentSizes[$parentId];
221 }
222 $deltas[ $revision->getId() ] = $delta;
223 }
224 return $deltas;
225 }
226
236 public function getContributionCount( UserIdentity $user, Authority $performer, $tag = null ): int {
237 $context = new RequestContext();
238 $context->setAuthority( $performer );
239 $context->setRequest( new FauxRequest( [] ) );
240
241 // TODO: explore moving this to factory method for testing
242 $pager = $this->getContribsPager( $context, $user, [
243 'tagfilter' => $tag,
244 ] );
245
246 $query = $pager->getQueryInfo();
247
248 $count = $pager->mDb->selectField(
249 $query['tables'],
250 'COUNT(*)',
251 $query['conds'],
252 __METHOD__,
253 [],
254 $query['join_conds']
255 );
256
257 return (int)$count;
258 }
259
260 private function getContribsPager(
261 IContextSource $context,
262 UserIdentity $targetUser,
263 array $options
264 ) {
265 return new ContribsPager(
266 $context,
267 $options,
268 $this->linkRendererFactory->create(),
269 $this->linkBatchFactory,
270 $this->hookContainer,
271 $this->loadBalancer,
272 $this->actorMigration,
273 $this->revisionStore,
274 $this->namespaceInfo,
275 $targetUser
276 );
277 }
278
279}
This is not intended to be a long-term part of MediaWiki; it will be deprecated and removed once acto...
static tagShortDescriptionMessage( $tag, MessageLocalizer $context)
Get the message object for the tag's short description.
Pager for Special:Contributions.
WebRequest clone which takes values from a provided array.
Factory to create LinkRender objects.
getContribsPager(IContextSource $context, UserIdentity $targetUser, array $options)
__construct(RevisionStore $revisionStore, LinkRendererFactory $linkRendererFactory, LinkBatchFactory $linkBatchFactory, HookContainer $hookContainer, ILoadBalancer $loadBalancer, ActorMigration $actorMigration, NamespaceInfo $namespaceInfo)
getContributions(UserIdentity $target, int $limit, Authority $performer, string $segment='', string $tag=null)
getPagerParams(int $limit, string $segment)
Constructs fake query parameters to be passed to ContribsPager.
getContributionCount(UserIdentity $user, Authority $performer, $tag=null)
Returns the number of edits by the given user.
getContributionDeltas( $revisions)
Gets size deltas of a revision and its parent revision.
Service for looking up page revisions.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:138
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Group all the pieces relevant to the context of a request into one instance @newable.
setAuthority(Authority $authority)
Interface for objects which can provide a MediaWiki context on request.
This interface represents the authority associated the current execution context, such as a web reque...
Definition Authority.php:37
Interface for objects representing user identity.
Database cluster connection, tracking, load balancing, and transaction manager interface.