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