Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
29 / 29 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
ProtectionFilter | |
100.00% |
29 / 29 |
|
100.00% |
2 / 2 |
6 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
filter | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
5 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments\NewcomerTasks; |
4 | |
5 | use GrowthExperiments\NewcomerTasks\Task\TaskSet; |
6 | use MediaWiki\Cache\LinkBatchFactory; |
7 | use MediaWiki\Title\TitleFactory; |
8 | use Wikimedia\Rdbms\IConnectionProvider; |
9 | |
10 | /** |
11 | * Filter out protected items from a small resultset. |
12 | */ |
13 | class ProtectionFilter extends AbstractTaskSetFilter implements TaskSetFilter { |
14 | |
15 | /** @var TitleFactory */ |
16 | private $titleFactory; |
17 | |
18 | /** @var LinkBatchFactory */ |
19 | private $linkBatchFactory; |
20 | |
21 | private IConnectionProvider $connectionProvider; |
22 | |
23 | /** |
24 | * @param TitleFactory $titleFactory |
25 | * @param LinkBatchFactory $linkBatchFactory |
26 | * @param IConnectionProvider $connectionProvider |
27 | */ |
28 | public function __construct( |
29 | TitleFactory $titleFactory, |
30 | LinkBatchFactory $linkBatchFactory, |
31 | IConnectionProvider $connectionProvider |
32 | ) { |
33 | $this->titleFactory = $titleFactory; |
34 | $this->linkBatchFactory = $linkBatchFactory; |
35 | $this->connectionProvider = $connectionProvider; |
36 | } |
37 | |
38 | /** @inheritDoc */ |
39 | public function filter( TaskSet $taskSet, int $maxLength = PHP_INT_MAX ): TaskSet { |
40 | // Warm title cache for fetching the IDs. |
41 | $linkBatch = $this->linkBatchFactory->newLinkBatch(); |
42 | $linkBatch->setCaller( __METHOD__ ); |
43 | foreach ( $taskSet as $task ) { |
44 | $linkBatch->addObj( $task->getTitle() ); |
45 | } |
46 | $linkBatch->execute(); |
47 | |
48 | $invalidTasks = []; |
49 | $validTasks = []; |
50 | |
51 | foreach ( $taskSet as $task ) { |
52 | $title = $this->titleFactory->newFromLinkTarget( $task->getTitle() ); |
53 | $validTasks[ $title->getArticleID() ] = $task; |
54 | } |
55 | // Do a single batch query instead of several individual queries with RestrictionStore. |
56 | // In the longer run, adding batch querying to RestrictionStore itself would be nice. |
57 | $results = []; |
58 | if ( $validTasks ) { |
59 | $results = $this->connectionProvider->getReplicaDatabase()->newSelectQueryBuilder() |
60 | ->select( [ 'pr_page' ] ) |
61 | ->from( 'page_restrictions' ) |
62 | ->where( [ |
63 | 'pr_page' => array_keys( $validTasks ), |
64 | 'pr_type' => 'edit' |
65 | ] ) |
66 | ->caller( __METHOD__ ) |
67 | ->fetchResultSet(); |
68 | } |
69 | |
70 | foreach ( $results as $item ) { |
71 | // We found restrictions, so add the task to the invalid task list, and |
72 | // unset it from the valid task list. |
73 | $invalidTasks[$item->pr_page] = $validTasks[$item->pr_page]; |
74 | unset( $validTasks[$item->pr_page] ); |
75 | } |
76 | |
77 | $validTasks = array_slice( $validTasks, 0, $maxLength, true ); |
78 | |
79 | return $this->copyValidAndInvalidTasksToNewTaskSet( $taskSet, $validTasks, $invalidTasks ); |
80 | } |
81 | |
82 | } |