Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 259
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3namespace WikibaseQuality\ConstraintReport;
4
5use MediaWiki\Logger\LoggerFactory;
6use MediaWiki\MediaWikiServices;
7use MediaWiki\WikiMap\WikiMap;
8use ObjectCache;
9use RuntimeException;
10use Wikibase\DataModel\Entity\Property;
11use Wikibase\Repo\WikibaseRepo;
12use WikibaseQuality\ConstraintReport\Api\CachingResultsSource;
13use WikibaseQuality\ConstraintReport\Api\CheckingResultsSource;
14use WikibaseQuality\ConstraintReport\Api\ExpiryLock;
15use WikibaseQuality\ConstraintReport\Api\ResultsCache;
16use WikibaseQuality\ConstraintReport\Api\ResultsSource;
17use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ContextCursorDeserializer;
18use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ContextCursorSerializer;
19use WikibaseQuality\ConstraintReport\ConstraintCheck\DelegatingConstraintChecker;
20use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConnectionCheckerHelper;
21use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser;
22use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\DummySparqlHelper;
23use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\LoggingHelper;
24use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\RangeCheckerHelper;
25use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\SparqlHelper;
26use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\TypeCheckerHelper;
27use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageDeserializer;
28use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageRendererFactory;
29use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageSerializer;
30use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResultDeserializer;
31use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResultSerializer;
32
33return [
34    ConstraintsServices::EXPIRY_LOCK => static function ( MediaWikiServices $services ): ExpiryLock {
35        return new ExpiryLock( ObjectCache::getInstance( CACHE_ANYTHING ) );
36    },
37
38    ConstraintsServices::LOGGING_HELPER => static function ( MediaWikiServices $services ): LoggingHelper {
39        return new LoggingHelper(
40            $services->getStatsdDataFactory(),
41            LoggerFactory::getInstance( 'WikibaseQualityConstraints' ),
42            $services->getMainConfig()
43        );
44    },
45
46    ConstraintsServices::CONSTRAINT_STORE => static function ( MediaWikiServices $services ): ConstraintRepositoryStore {
47        $sourceDefinitions = WikibaseRepo::getEntitySourceDefinitions( $services );
48        $propertySource = $sourceDefinitions->getDatabaseSourceForEntityType( Property::ENTITY_TYPE );
49        if ( $propertySource === null ) {
50            throw new RuntimeException( 'Can\'t get a ConstraintStore for properties not stored in a database.' );
51        }
52
53        $localEntitySourceName = WikibaseRepo::getLocalEntitySource( $services )->getSourceName();
54        if ( $propertySource->getSourceName() !== $localEntitySourceName ) {
55            throw new RuntimeException( 'Can\'t get a ConstraintStore for a non local entity source.' );
56        }
57
58        $dbName = $propertySource->getDatabaseName();
59        return new ConstraintRepositoryStore(
60            $services->getDBLoadBalancerFactory()->getMainLB( $dbName ),
61            $dbName
62        );
63    },
64
65    ConstraintsServices::CONSTRAINT_LOOKUP => static function ( MediaWikiServices $services ): ConstraintLookup {
66        $sourceDefinitions = WikibaseRepo::getEntitySourceDefinitions( $services );
67        $propertySource = $sourceDefinitions->getDatabaseSourceForEntityType( Property::ENTITY_TYPE );
68        if ( $propertySource === null ) {
69            throw new RuntimeException( 'Can\'t get a ConstraintStore for properties not stored in a database.' );
70        }
71
72        $dbName = $propertySource->getDatabaseName();
73        $rawLookup = new ConstraintRepositoryLookup(
74            $services->getDBLoadBalancerFactory()->getMainLB( $dbName ),
75            $dbName
76        );
77        return new CachingConstraintLookup( $rawLookup );
78    },
79
80    ConstraintsServices::CHECK_RESULT_SERIALIZER => static function ( MediaWikiServices $services ): CheckResultSerializer {
81        return new CheckResultSerializer(
82            new ConstraintSerializer(
83                false // constraint parameters are not exposed
84            ),
85            new ContextCursorSerializer(),
86            new ViolationMessageSerializer(),
87            false // unnecessary to serialize individual result dependencies
88        );
89    },
90
91    ConstraintsServices::CHECK_RESULT_DESERIALIZER => static function ( MediaWikiServices $services ): CheckResultDeserializer {
92        $entityIdParser = WikibaseRepo::getEntityIdParser( $services );
93        $dataValueFactory = WikibaseRepo::getDataValueFactory( $services );
94
95        return new CheckResultDeserializer(
96            new ConstraintDeserializer(),
97            new ContextCursorDeserializer(),
98            new ViolationMessageDeserializer(
99                $entityIdParser,
100                $dataValueFactory
101            ),
102            $entityIdParser
103        );
104    },
105
106    ConstraintsServices::VIOLATION_MESSAGE_SERIALIZER => static function (
107        MediaWikiServices $services
108    ): ViolationMessageSerializer {
109        return new ViolationMessageSerializer();
110    },
111
112    ConstraintsServices::VIOLATION_MESSAGE_DESERIALIZER => static function (
113        MediaWikiServices $services
114    ): ViolationMessageDeserializer {
115        $entityIdParser = WikibaseRepo::getEntityIdParser( $services );
116        $dataValueFactory = WikibaseRepo::getDataValueFactory( $services );
117
118        return new ViolationMessageDeserializer(
119            $entityIdParser,
120            $dataValueFactory
121        );
122    },
123
124    ConstraintsServices::CONSTRAINT_PARAMETER_PARSER => static function (
125        MediaWikiServices $services
126    ): ConstraintParameterParser {
127        $deserializerFactory = WikibaseRepo::getBaseDataModelDeserializerFactory( $services );
128        $entitySourceDefinitions = WikibaseRepo::getEntitySourceDefinitions( $services );
129
130        return new ConstraintParameterParser(
131            $services->getMainConfig(),
132            $deserializerFactory,
133            $entitySourceDefinitions->getDatabaseSourceForEntityType( 'item' )->getConceptBaseUri()
134        );
135    },
136
137    ConstraintsServices::CONNECTION_CHECKER_HELPER => static function ( MediaWikiServices $services ): ConnectionCheckerHelper {
138        return new ConnectionCheckerHelper();
139    },
140
141    ConstraintsServices::RANGE_CHECKER_HELPER => static function ( MediaWikiServices $services ): RangeCheckerHelper {
142        return new RangeCheckerHelper(
143            $services->getMainConfig(),
144            WikibaseRepo::getUnitConverter( $services )
145        );
146    },
147
148    ConstraintsServices::SPARQL_HELPER => static function ( MediaWikiServices $services ): SparqlHelper {
149        $endpoint = $services->getMainConfig()->get( 'WBQualityConstraintsSparqlEndpoint' );
150        if ( $endpoint === '' ) {
151            return new DummySparqlHelper();
152        }
153
154        $rdfVocabulary = WikibaseRepo::getRdfVocabulary( $services );
155        $entityIdParser = WikibaseRepo::getEntityIdParser( $services );
156        $propertyDataTypeLookup = WikibaseRepo::getPropertyDataTypeLookup( $services );
157
158        return new SparqlHelper(
159            $services->getMainConfig(),
160            $rdfVocabulary,
161            $entityIdParser,
162            $propertyDataTypeLookup,
163            $services->getMainWANObjectCache(),
164            ConstraintsServices::getViolationMessageSerializer( $services ),
165            ConstraintsServices::getViolationMessageDeserializer( $services ),
166            $services->getStatsdDataFactory(),
167            ConstraintsServices::getExpiryLock( $services ),
168            ConstraintsServices::getLoggingHelper( $services ),
169            WikiMap::getCurrentWikiId() . ' WikibaseQualityConstraints ' . $services->getHttpRequestFactory()->getUserAgent(),
170            $services->getHttpRequestFactory()
171        );
172    },
173
174    ConstraintsServices::TYPE_CHECKER_HELPER => static function ( MediaWikiServices $services ): TypeCheckerHelper {
175        return new TypeCheckerHelper(
176            WikibaseServices::getEntityLookup( $services ),
177            $services->getMainConfig(),
178            ConstraintsServices::getSparqlHelper( $services ),
179            $services->getStatsFactory()->withComponent( 'WikibaseQualityConstraints' )
180        );
181    },
182
183    ConstraintsServices::DELEGATING_CONSTRAINT_CHECKER => static function (
184        MediaWikiServices $services
185    ): DelegatingConstraintChecker {
186        $statementGuidParser = WikibaseRepo::getStatementGuidParser( $services );
187
188        $config = $services->getMainConfig();
189        $checkerMap = [
190            $config->get( 'WBQualityConstraintsConflictsWithConstraintId' )
191                => ConstraintCheckerServices::getConflictsWithChecker( $services ),
192            $config->get( 'WBQualityConstraintsItemRequiresClaimConstraintId' )
193                => ConstraintCheckerServices::getItemChecker( $services ),
194            $config->get( 'WBQualityConstraintsValueRequiresClaimConstraintId' )
195                => ConstraintCheckerServices::getTargetRequiredClaimChecker( $services ),
196            $config->get( 'WBQualityConstraintsSymmetricConstraintId' )
197                => ConstraintCheckerServices::getSymmetricChecker( $services ),
198            $config->get( 'WBQualityConstraintsInverseConstraintId' )
199                => ConstraintCheckerServices::getInverseChecker( $services ),
200            $config->get( 'WBQualityConstraintsUsedAsQualifierConstraintId' )
201                => ConstraintCheckerServices::getQualifierChecker( $services ),
202            $config->get( 'WBQualityConstraintsAllowedQualifiersConstraintId' )
203                => ConstraintCheckerServices::getQualifiersChecker( $services ),
204            $config->get( 'WBQualityConstraintsMandatoryQualifierConstraintId' )
205                => ConstraintCheckerServices::getMandatoryQualifiersChecker( $services ),
206            $config->get( 'WBQualityConstraintsRangeConstraintId' )
207                => ConstraintCheckerServices::getRangeChecker( $services ),
208            $config->get( 'WBQualityConstraintsDifferenceWithinRangeConstraintId' )
209                => ConstraintCheckerServices::getDiffWithinRangeChecker( $services ),
210            $config->get( 'WBQualityConstraintsTypeConstraintId' )
211                => ConstraintCheckerServices::getTypeChecker( $services ),
212            $config->get( 'WBQualityConstraintsValueTypeConstraintId' )
213                => ConstraintCheckerServices::getValueTypeChecker( $services ),
214            $config->get( 'WBQualityConstraintsSingleValueConstraintId' )
215                => ConstraintCheckerServices::getSingleValueChecker( $services ),
216            $config->get( 'WBQualityConstraintsMultiValueConstraintId' )
217                => ConstraintCheckerServices::getMultiValueChecker( $services ),
218            $config->get( 'WBQualityConstraintsDistinctValuesConstraintId' )
219                => ConstraintCheckerServices::getUniqueValueChecker( $services ),
220            $config->get( 'WBQualityConstraintsFormatConstraintId' )
221                => ConstraintCheckerServices::getFormatChecker( $services ),
222            $config->get( 'WBQualityConstraintsCommonsLinkConstraintId' )
223                => ConstraintCheckerServices::getCommonsLinkChecker( $services ),
224            $config->get( 'WBQualityConstraintsOneOfConstraintId' )
225                => ConstraintCheckerServices::getOneOfChecker( $services ),
226            $config->get( 'WBQualityConstraintsUsedForValuesOnlyConstraintId' )
227                => ConstraintCheckerServices::getValueOnlyChecker( $services ),
228            $config->get( 'WBQualityConstraintsUsedAsReferenceConstraintId' )
229                => ConstraintCheckerServices::getReferenceChecker( $services ),
230            $config->get( 'WBQualityConstraintsNoBoundsConstraintId' )
231                => ConstraintCheckerServices::getNoBoundsChecker( $services ),
232            $config->get( 'WBQualityConstraintsAllowedUnitsConstraintId' )
233                => ConstraintCheckerServices::getAllowedUnitsChecker( $services ),
234            $config->get( 'WBQualityConstraintsSingleBestValueConstraintId' )
235                => ConstraintCheckerServices::getSingleBestValueChecker( $services ),
236            $config->get( 'WBQualityConstraintsAllowedEntityTypesConstraintId' )
237                => ConstraintCheckerServices::getEntityTypeChecker( $services ),
238            $config->get( 'WBQualityConstraintsNoneOfConstraintId' )
239                => ConstraintCheckerServices::getNoneOfChecker( $services ),
240            $config->get( 'WBQualityConstraintsIntegerConstraintId' )
241                => ConstraintCheckerServices::getIntegerChecker( $services ),
242            $config->get( 'WBQualityConstraintsCitationNeededConstraintId' )
243                => ConstraintCheckerServices::getCitationNeededChecker( $services ),
244            $config->get( 'WBQualityConstraintsPropertyScopeConstraintId' )
245                => ConstraintCheckerServices::getPropertyScopeChecker( $services ),
246            $config->get( 'WBQualityConstraintsContemporaryConstraintId' )
247                => ConstraintCheckerServices::getContemporaryChecker( $services ),
248            $config->get( 'WBQualityConstraintsLexemeLanguageConstraintId' )
249                => ConstraintCheckerServices::getLexemeLanguageChecker( $services ),
250            $config->get( 'WBQualityConstraintsLabelInLanguageConstraintId' )
251                => ConstraintCheckerServices::getLabelInLanguageChecker( $services ),
252        ];
253
254        return new DelegatingConstraintChecker(
255            WikibaseServices::getEntityLookup( $services ),
256            $checkerMap,
257            ConstraintsServices::getConstraintLookup( $services ),
258            ConstraintsServices::getConstraintParameterParser( $services ),
259            $statementGuidParser,
260            ConstraintsServices::getLoggingHelper( $services ),
261            $config->get( 'WBQualityConstraintsCheckQualifiers' ),
262            $config->get( 'WBQualityConstraintsCheckReferences' ),
263            $config->get( 'WBQualityConstraintsPropertiesWithViolatingQualifiers' )
264        );
265    },
266
267    ConstraintsServices::RESULTS_SOURCE => static function ( MediaWikiServices $services ): ResultsSource {
268        $config = $services->getMainConfig();
269        $resultsSource = new CheckingResultsSource(
270            ConstraintsServices::getDelegatingConstraintChecker( $services )
271        );
272
273        $cacheCheckConstraintsResults = false;
274
275        if ( $config->get( 'WBQualityConstraintsCacheCheckConstraintsResults' ) ) {
276            $cacheCheckConstraintsResults = true;
277            // check that we can use getLocalRepoWikiPageMetaDataAccessor()
278            // TODO we should always be able to cache constraint check results (T244726)
279            $entitySources = WikibaseRepo::getEntitySourceDefinitions( $services )->getSources();
280            $localEntitySourceName = WikibaseRepo::getLocalEntitySource( $services )->getSourceName();
281
282            foreach ( $entitySources as $entitySource ) {
283                if ( $entitySource->getSourceName() !== $localEntitySourceName ) {
284                    LoggerFactory::getInstance( 'WikibaseQualityConstraints' )->warning(
285                        'Cannot cache constraint check results for non-local source: ' .
286                        $entitySource->getSourceName()
287                    );
288                    $cacheCheckConstraintsResults = false;
289                    break;
290                }
291            }
292        }
293
294        if ( $cacheCheckConstraintsResults ) {
295            $possiblyStaleConstraintTypes = [
296                $config->get( 'WBQualityConstraintsCommonsLinkConstraintId' ),
297                $config->get( 'WBQualityConstraintsTypeConstraintId' ),
298                $config->get( 'WBQualityConstraintsValueTypeConstraintId' ),
299                $config->get( 'WBQualityConstraintsDistinctValuesConstraintId' ),
300            ];
301            $entityIdParser = WikibaseRepo::getEntityIdParser( $services );
302            $wikiPageEntityMetaDataAccessor = WikibaseRepo::getLocalRepoWikiPageMetaDataAccessor(
303                $services );
304
305            $resultsSource = new CachingResultsSource(
306                $resultsSource,
307                ResultsCache::getDefaultInstance(),
308                ConstraintsServices::getCheckResultSerializer( $services ),
309                ConstraintsServices::getCheckResultDeserializer( $services ),
310                $wikiPageEntityMetaDataAccessor,
311                $entityIdParser,
312                $config->get( 'WBQualityConstraintsCacheCheckConstraintsTTLSeconds' ),
313                $possiblyStaleConstraintTypes,
314                $config->get( 'WBQualityConstraintsCacheCheckConstraintsMaximumRevisionIds' ),
315                ConstraintsServices::getLoggingHelper( $services )
316            );
317        }
318
319        return $resultsSource;
320    },
321
322    ConstraintsServices::VIOLATION_MESSAGE_RENDERER_FACTORY => static function (
323        MediaWikiServices $services
324    ): ViolationMessageRendererFactory {
325        return new ViolationMessageRendererFactory(
326            $services->getMainConfig(),
327            $services->getLanguageNameUtils(),
328            WikibaseRepo::getEntityIdHtmlLinkFormatterFactory( $services ),
329            WikibaseRepo::getValueFormatterFactory( $services )
330        );
331    },
332];