Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 44 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
SignificantEditSubscriber | |
0.00% |
0 / 44 |
|
0.00% |
0 / 2 |
56 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
handlePageUpdatedEventAfterCommit | |
0.00% |
0 / 40 |
|
0.00% |
0 / 1 |
42 |
1 | <?php |
2 | |
3 | declare( strict_types=1 ); |
4 | |
5 | namespace ContentTranslation\Events; |
6 | |
7 | use ContentTranslation\Entity\RecentSignificantEdit; |
8 | use ContentTranslation\Service\EditedSectionFinder; |
9 | use ContentTranslation\Service\WikidataIdFetcher; |
10 | use ContentTranslation\SiteMapper; |
11 | use ContentTranslation\Store\RecentSignificantEditStore; |
12 | use MediaWiki\DomainEvent\EventSubscriberBase; |
13 | use MediaWiki\Revision\RevisionStore; |
14 | use MediaWiki\Storage\PageUpdatedEvent; |
15 | |
16 | /** |
17 | * Event subscriber for significant edits. |
18 | * |
19 | * Subscribes to PageUpdatedEventAfterCommit events and stores significant edits |
20 | * in the cx_significant_edits table. |
21 | * |
22 | * @copyright See AUTHORS.txt |
23 | * @license GPL-2.0-or-later |
24 | */ |
25 | class SignificantEditSubscriber extends EventSubscriberBase { |
26 | private RevisionStore $revisionStore; |
27 | private RecentSignificantEditStore $significantEditStore; |
28 | private EditedSectionFinder $editedSectionFinder; |
29 | private WikidataIdFetcher $wikidataIdFetcher; |
30 | private const MINIMUM_MODIFIED_BYTES = 500; |
31 | |
32 | public function __construct( |
33 | RevisionStore $revisionStore, |
34 | RecentSignificantEditStore $significantEditStore, |
35 | EditedSectionFinder $editedSectionFinder, |
36 | WikidataIdFetcher $wikidataIdFetcher |
37 | ) { |
38 | $this->revisionStore = $revisionStore; |
39 | $this->significantEditStore = $significantEditStore; |
40 | $this->editedSectionFinder = $editedSectionFinder; |
41 | $this->wikidataIdFetcher = $wikidataIdFetcher; |
42 | } |
43 | |
44 | /** |
45 | * Handler for "PageUpdatedEventAfterCommit" events. |
46 | * It adds a new row to the "cx_significant_edits" table, if the |
47 | * current revision fulfils some requirements. |
48 | * |
49 | * These requirements are: |
50 | * 1. The changes in the revision should modify at least MINIMUM_MODIFIED_BYTES bytes |
51 | * 2. This change should affect at least one non-lead section |
52 | * |
53 | * @noinspection PhpUnused |
54 | * @param PageUpdatedEvent $event |
55 | * @return void |
56 | */ |
57 | public function handlePageUpdatedEventAfterCommit( PageUpdatedEvent $event ): void { |
58 | $pageIdentity = $event->getPage(); |
59 | $rev = $event->getNewRevision(); |
60 | $user = $event->getAuthor(); |
61 | |
62 | $isSignificantEdit = $rev->getSize() > self::MINIMUM_MODIFIED_BYTES; |
63 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Edit size: ' . $rev->getSize() ); |
64 | // If edit is not of a significant size, |
65 | // or if current wiki family is not supported for this entrypoint |
66 | if ( !$isSignificantEdit || !$this->significantEditStore->isCurrentWikiFamilySupported() ) { |
67 | return; |
68 | } |
69 | |
70 | $currentLanguage = SiteMapper::getCurrentLanguageCode(); |
71 | $qid = $this->wikidataIdFetcher->getWikidataId( (string)$pageIdentity, $currentLanguage ); |
72 | if ( !$qid ) { |
73 | wfDebugLog( 'cx-entrypoints-recent-edit', 'qid not found' ); |
74 | return; |
75 | } |
76 | |
77 | // get integer from Q id ("Q123") |
78 | $wikidataId = (int)filter_var( $qid, FILTER_SANITIZE_NUMBER_INT ); |
79 | |
80 | $previousRev = $this->revisionStore->getPreviousRevision( $rev ); |
81 | // Find all titles of non-lead sections that were edited in this revision |
82 | $editedSections = $this->editedSectionFinder->findEditedSectionsBetweenRevisions( $rev, $previousRev ); |
83 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Edited sections: ' . implode( ", ", $editedSections ) ); |
84 | |
85 | // If no non-lead section was edited, return |
86 | if ( !$editedSections ) { |
87 | return; |
88 | } |
89 | |
90 | $language = SiteMapper::getCurrentLanguageCode(); |
91 | |
92 | $userEdit = $this->significantEditStore->findExistingEdit( |
93 | $user->getId(), |
94 | $wikidataId, |
95 | $language |
96 | ); |
97 | |
98 | if ( $userEdit instanceof RecentSignificantEdit ) { |
99 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Recent edit already exists' ); |
100 | $userEdit->mergeSectionTitles( $editedSections ); |
101 | $this->significantEditStore->update( $userEdit ); |
102 | |
103 | return; |
104 | } |
105 | |
106 | $edit = new RecentSignificantEdit( |
107 | null, |
108 | $user->getId(), |
109 | $wikidataId, |
110 | $language, |
111 | (string)$pageIdentity, |
112 | $editedSections, |
113 | null |
114 | ); |
115 | |
116 | $this->significantEditStore->insert( $edit ); |
117 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Recent edit created' ); |
118 | } |
119 | } |