Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 55 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
SignificantEditCreationHandler | |
0.00% |
0 / 55 |
|
0.00% |
0 / 2 |
56 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
onRevisionFromEditComplete | |
0.00% |
0 / 51 |
|
0.00% |
0 / 1 |
42 |
1 | <?php |
2 | |
3 | declare( strict_types=1 ); |
4 | |
5 | namespace ContentTranslation\HookHandler; |
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 DeferredUpdates; |
13 | use MediaWiki\Page\Hook\RevisionFromEditCompleteHook; |
14 | use MediaWiki\Revision\RevisionRecord; |
15 | use MediaWiki\Revision\RevisionStore; |
16 | use MediaWiki\User\UserIdentity; |
17 | use WikiPage; |
18 | |
19 | class SignificantEditCreationHandler implements RevisionFromEditCompleteHook { |
20 | |
21 | /** @var RevisionStore */ |
22 | private $revisionStore; |
23 | |
24 | /** @var RecentSignificantEditStore */ |
25 | private $significantEditStore; |
26 | |
27 | /** @var EditedSectionFinder */ |
28 | private $editedSectionFinder; |
29 | |
30 | /** @var WikidataIdFetcher */ |
31 | private $wikidataIdFetcher; |
32 | |
33 | public function __construct( |
34 | RevisionStore $revisionStore, |
35 | RecentSignificantEditStore $significantEditStore, |
36 | EditedSectionFinder $editedSectionFinder, |
37 | WikidataIdFetcher $wikidataIdFetcher |
38 | ) { |
39 | $this->revisionStore = $revisionStore; |
40 | $this->significantEditStore = $significantEditStore; |
41 | $this->editedSectionFinder = $editedSectionFinder; |
42 | $this->wikidataIdFetcher = $wikidataIdFetcher; |
43 | } |
44 | |
45 | /** |
46 | * This hook is registered for the "RevisionFromEditComplete" event. |
47 | * It adds a new row to the "cx_significant_edits" table, if the |
48 | * current revision fulfils some requirements. |
49 | * |
50 | * These requirements are: |
51 | * 1. This revision should be a significant contribution (size > 500 bytes) |
52 | * 2. This revision should affect at least one non-lead section |
53 | * |
54 | * @param WikiPage $wikiPage WikiPage edited |
55 | * @param RevisionRecord $rev New revision |
56 | * @param int|bool $originalRevId |
57 | * @param UserIdentity $user |
58 | * @param string[] &$tags |
59 | */ |
60 | public function onRevisionFromEditComplete( $wikiPage, $rev, $originalRevId, $user, &$tags ) { |
61 | $isSignificantEdit = $rev->getSize() > 500; |
62 | $significantEditStore = $this->significantEditStore; |
63 | // If edit is not of a significant size, |
64 | // or if current wiki family is not supported for this entrypoint |
65 | if ( !$isSignificantEdit || !$significantEditStore->isCurrentWikiFamilySupported() ) { |
66 | return; |
67 | } |
68 | |
69 | $currentLanguage = SiteMapper::getCurrentLanguageCode(); |
70 | $qid = $this->wikidataIdFetcher->getWikidataId( (string)$wikiPage->getTitle(), $currentLanguage ); |
71 | if ( !$qid ) { |
72 | wfDebugLog( 'cx-entrypoints-recent-edit', 'qid not found' ); |
73 | return; |
74 | } |
75 | |
76 | // get integer from Q id ("Q123") |
77 | $wikidataId = (int)filter_var( $qid, FILTER_SANITIZE_NUMBER_INT ); |
78 | $revisionStore = $this->revisionStore; |
79 | $editedSectionFinder = $this->editedSectionFinder; |
80 | |
81 | DeferredUpdates::addCallableUpdate( |
82 | static function () use ( |
83 | $rev, |
84 | $user, |
85 | $wikiPage, |
86 | $revisionStore, |
87 | $editedSectionFinder, |
88 | $significantEditStore, |
89 | $wikidataId |
90 | ) { |
91 | $previousRev = $revisionStore->getPreviousRevision( $rev ); |
92 | // Find all titles of non-lead sections that were edited in this revision |
93 | $editedSections = $editedSectionFinder->findEditedSectionsBetweenRevisions( $rev, $previousRev ); |
94 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Edited sections: ' . implode( ", ", $editedSections ) ); |
95 | |
96 | // If no non-lead section was edited, return |
97 | if ( !$editedSections ) { |
98 | return; |
99 | } |
100 | |
101 | $language = SiteMapper::getCurrentLanguageCode(); |
102 | |
103 | $userEdit = $significantEditStore->findExistingEdit( |
104 | $user->getId(), |
105 | $wikidataId, |
106 | $language |
107 | ); |
108 | |
109 | if ( $userEdit instanceof RecentSignificantEdit ) { |
110 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Recent edit already exists' ); |
111 | $userEdit->mergeSectionTitles( $editedSections ); |
112 | $significantEditStore->update( $userEdit ); |
113 | |
114 | return; |
115 | } |
116 | |
117 | $edit = new RecentSignificantEdit( |
118 | null, |
119 | $user->getId(), |
120 | $wikidataId, |
121 | $language, |
122 | (string)$wikiPage->getTitle(), |
123 | $editedSections, |
124 | null |
125 | ); |
126 | |
127 | $significantEditStore->insert( $edit ); |
128 | wfDebugLog( 'cx-entrypoints-recent-edit', 'Recent edit created' ); |
129 | } |
130 | ); |
131 | } |
132 | } |