Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
15.25% covered (danger)
15.25%
9 / 59
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
WikibaseQualityConstraintsHooks
15.25% covered (danger)
15.25%
9 / 59
0.00% covered (danger)
0.00%
0 / 5
405.39
0.00% covered (danger)
0.00%
0 / 1
 onWikibaseChange
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
72
 isSelectedForJobRunBasedOnPercentage
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 isConstraintStatementsChange
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
5.03
 onArticlePurge
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 onBeforePageDisplay
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
72
1<?php
2
3namespace WikibaseQuality\ConstraintReport;
4
5use ExtensionRegistry;
6use JobSpecification;
7use MediaWiki\Config\Config;
8use MediaWiki\Hook\BeforePageDisplayHook;
9use MediaWiki\MediaWikiServices;
10use MediaWiki\Page\Hook\ArticlePurgeHook;
11use Wikibase\DataModel\Entity\NumericPropertyId;
12use Wikibase\Lib\Changes\Change;
13use Wikibase\Lib\Changes\EntityChange;
14use Wikibase\Lib\Changes\EntityDiffChangedAspects;
15use Wikibase\Repo\WikibaseRepo;
16use WikibaseQuality\ConstraintReport\Api\ResultsCache;
17use WikibaseQuality\ConstraintReport\Job\CheckConstraintsJob;
18
19/**
20 * Container for hook callbacks registered in extension.json.
21 *
22 * @license GPL-2.0-or-later
23 */
24final class WikibaseQualityConstraintsHooks implements
25    ArticlePurgeHook,
26    BeforePageDisplayHook
27{
28
29    public static function onWikibaseChange( Change $change ) {
30        if ( !( $change instanceof EntityChange ) ) {
31            return;
32        }
33        /** @var EntityChange $change */
34
35        $services = MediaWikiServices::getInstance();
36        $config = $services->getMainConfig();
37        $jobQueueGroup = $services->getJobQueueGroup();
38
39        // If jobs are enabled and the results would be stored in some way run a job.
40        if (
41            $config->get( 'WBQualityConstraintsEnableConstraintsCheckJobs' ) &&
42            $config->get( 'WBQualityConstraintsCacheCheckConstraintsResults' ) &&
43            self::isSelectedForJobRunBasedOnPercentage()
44        ) {
45            $params = [ 'entityId' => $change->getEntityId()->getSerialization() ];
46            $jobQueueGroup->lazyPush(
47                new JobSpecification( CheckConstraintsJob::COMMAND, $params )
48            );
49        }
50
51        if ( $config->get( 'WBQualityConstraintsEnableConstraintsImportFromStatements' ) &&
52            self::isConstraintStatementsChange( $config, $change )
53        ) {
54            $params = [ 'propertyId' => $change->getEntityId()->getSerialization() ];
55            $metadata = $change->getMetadata();
56            if ( array_key_exists( 'rev_id', $metadata ) ) {
57                $params['revisionId'] = $metadata['rev_id'];
58            }
59            $jobQueueGroup->push(
60                new JobSpecification( 'constraintsTableUpdate', $params )
61            );
62        }
63    }
64
65    private static function isSelectedForJobRunBasedOnPercentage() {
66        $config = MediaWikiServices::getInstance()->getMainConfig();
67        $percentage = $config->get( 'WBQualityConstraintsEnableConstraintsCheckJobsRatio' );
68
69        return mt_rand( 1, 100 ) <= $percentage;
70    }
71
72    public static function isConstraintStatementsChange( Config $config, Change $change ) {
73        if ( !( $change instanceof EntityChange ) ||
74             $change->getAction() !== EntityChange::UPDATE ||
75             !( $change->getEntityId() instanceof NumericPropertyId )
76        ) {
77            return false;
78        }
79
80        $info = $change->getInfo();
81
82        if ( !array_key_exists( 'compactDiff', $info ) ) {
83            // the non-compact diff ($info['diff']) does not contain statement diffs (T110996),
84            // so we only know that the change *might* affect the constraint statements
85            return true;
86        }
87
88        /** @var EntityDiffChangedAspects $aspects */
89        $aspects = $info['compactDiff'];
90
91        $propertyConstraintId = $config->get( 'WBQualityConstraintsPropertyConstraintId' );
92        return in_array( $propertyConstraintId, $aspects->getStatementChanges() );
93    }
94
95    public function onArticlePurge( $wikiPage ) {
96        $entityContentFactory = WikibaseRepo::getEntityContentFactory();
97        if ( $entityContentFactory->isEntityContentModel( $wikiPage->getContentModel() ) ) {
98            $entityIdLookup = WikibaseRepo::getEntityIdLookup();
99            $entityId = $entityIdLookup->getEntityIdForTitle( $wikiPage->getTitle() );
100            if ( $entityId !== null ) {
101                $resultsCache = ResultsCache::getDefaultInstance();
102                $resultsCache->delete( $entityId );
103            }
104        }
105    }
106
107    public function onBeforePageDisplay( $out, $skin ): void {
108        $lookup = WikibaseRepo::getEntityNamespaceLookup();
109        $title = $out->getTitle();
110        if ( $title === null ) {
111            return;
112        }
113
114        if ( !$lookup->isNamespaceWithEntities( $title->getNamespace() ) ) {
115            return;
116        }
117        if ( empty( $out->getJsConfigVars()['wbIsEditView'] ) ) {
118            return;
119        }
120
121        $services = MediaWikiServices::getInstance();
122        $config = $services->getMainConfig();
123
124        $isMobileView = ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) &&
125            $services->getService( 'MobileFrontend.Context' )->shouldDisplayMobileView();
126        if ( $isMobileView ) {
127            return;
128        }
129
130        $out->addModules( 'wikibase.quality.constraints.suggestions' );
131
132        if ( $config->get( 'WBQualityConstraintsShowConstraintViolationToNonLoggedInUsers' )
133            || $out->getUser()->isRegistered() ) {
134                $out->addModules( 'wikibase.quality.constraints.gadget' );
135        }
136    }
137
138}