Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
69.23% |
18 / 26 |
|
40.00% |
2 / 5 |
CRAP | |
0.00% |
0 / 1 |
ArchiveChangeListener | |
69.23% |
18 / 26 |
|
40.00% |
2 / 5 |
11.36 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
create | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isEnabled | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
onPageDeleteComplete | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
onPageUndeleteComplete | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace CirrusSearch; |
4 | |
5 | use CirrusSearch\Job\DeleteArchive; |
6 | use CirrusSearch\Job\IndexArchive; |
7 | use JobQueueGroup; |
8 | use ManualLogEntry; |
9 | use MediaWiki\Config\ConfigFactory; |
10 | use MediaWiki\Page\Hook\PageDeleteCompleteHook; |
11 | use MediaWiki\Page\Hook\PageUndeleteCompleteHook; |
12 | use MediaWiki\Page\ProperPageIdentity; |
13 | use MediaWiki\Permissions\Authority; |
14 | use MediaWiki\Revision\RevisionRecord; |
15 | use MediaWiki\Title\Title; |
16 | use MediaWiki\Utils\MWTimestamp; |
17 | use Wikimedia\Assert\Assert; |
18 | |
19 | /** |
20 | * Change listener responsible for writing to the archive index. |
21 | */ |
22 | class ArchiveChangeListener implements PageDeleteCompleteHook, PageUndeleteCompleteHook { |
23 | private JobQueueGroup $jobQueue; |
24 | private SearchConfig $searchConfig; |
25 | |
26 | public function __construct( JobQueueGroup $jobQueue, SearchConfig $searchConfig ) { |
27 | $this->jobQueue = $jobQueue; |
28 | $this->searchConfig = $searchConfig; |
29 | } |
30 | |
31 | public static function create( |
32 | JobQueueGroup $jobQueue, |
33 | ConfigFactory $configFactory |
34 | ): ArchiveChangeListener { |
35 | /** @phan-suppress-next-line PhanTypeMismatchArgumentSuperType $config is actually a SearchConfig */ |
36 | return new self( $jobQueue, $configFactory->makeConfig( "CirrusSearch" ) ); |
37 | } |
38 | |
39 | private function isEnabled(): bool { |
40 | if ( !$this->searchConfig->get( 'CirrusSearchIndexDeletes' ) ) { |
41 | return false; |
42 | } |
43 | return $this->searchConfig |
44 | ->getClusterAssignment() |
45 | ->getWritableClusters( UpdateGroup::ARCHIVE ) != []; |
46 | } |
47 | |
48 | /** |
49 | * @param ProperPageIdentity $page |
50 | * @param Authority $deleter |
51 | * @param string $reason |
52 | * @param int $pageID |
53 | * @param RevisionRecord $deletedRev |
54 | * @param ManualLogEntry $logEntry |
55 | * @param int $archivedRevisionCount |
56 | * @return void |
57 | */ |
58 | public function onPageDeleteComplete( ProperPageIdentity $page, Authority $deleter, |
59 | string $reason, int $pageID, RevisionRecord $deletedRev, ManualLogEntry $logEntry, |
60 | int $archivedRevisionCount |
61 | ) { |
62 | if ( !$this->isEnabled() ) { |
63 | // Not indexing, thus nothing to remove here. |
64 | return; |
65 | } |
66 | // Note that we must use the article id provided or it'll be lost in the ether. The job can't |
67 | // load it from the title because the page row has already been deleted. |
68 | $title = Title::castFromPageIdentity( $page ); |
69 | Assert::postcondition( $title !== null, '$page can be cast to a Title' ); |
70 | $this->jobQueue->lazyPush( |
71 | IndexArchive::build( |
72 | $title, |
73 | $this->searchConfig->makeId( $pageID ), |
74 | $logEntry->getTimestamp() !== false ? MWTimestamp::convert( TS_UNIX, $logEntry->getTimestamp() ) : MWTimestamp::time() |
75 | ) |
76 | ); |
77 | } |
78 | |
79 | /** |
80 | * When article is undeleted - check the archive for other instances of the title, |
81 | * if not there - drop it from the archive. |
82 | * @param ProperPageIdentity $page |
83 | * @param Authority $restorer |
84 | * @param string $reason |
85 | * @param RevisionRecord $restoredRev |
86 | * @param ManualLogEntry $logEntry |
87 | * @param int $restoredRevisionCount |
88 | * @param bool $created |
89 | * @param array $restoredPageIds |
90 | * @return void |
91 | */ |
92 | public function onPageUndeleteComplete( |
93 | ProperPageIdentity $page, |
94 | Authority $restorer, |
95 | string $reason, |
96 | RevisionRecord $restoredRev, |
97 | ManualLogEntry $logEntry, |
98 | int $restoredRevisionCount, |
99 | bool $created, |
100 | array $restoredPageIds |
101 | ): void { |
102 | if ( !$this->isEnabled() ) { |
103 | // Not indexing, thus nothing to remove here. |
104 | return; |
105 | } |
106 | $title = Title::castFromPageIdentity( $page ); |
107 | Assert::postcondition( $title !== null, '$page can be cast to a Title' ); |
108 | $this->jobQueue->lazyPush( |
109 | new DeleteArchive( $title, [ 'docIds' => $restoredPageIds ] ) |
110 | ); |
111 | } |
112 | } |