Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 259 |
n/a |
0 / 0 |
CRAP | n/a |
0 / 0 |
1 | <?php |
2 | |
3 | namespace WikibaseQuality\ConstraintReport; |
4 | |
5 | use MediaWiki\Logger\LoggerFactory; |
6 | use MediaWiki\MediaWikiServices; |
7 | use MediaWiki\WikiMap\WikiMap; |
8 | use ObjectCache; |
9 | use RuntimeException; |
10 | use Wikibase\DataModel\Entity\Property; |
11 | use Wikibase\Repo\WikibaseRepo; |
12 | use WikibaseQuality\ConstraintReport\Api\CachingResultsSource; |
13 | use WikibaseQuality\ConstraintReport\Api\CheckingResultsSource; |
14 | use WikibaseQuality\ConstraintReport\Api\ExpiryLock; |
15 | use WikibaseQuality\ConstraintReport\Api\ResultsCache; |
16 | use WikibaseQuality\ConstraintReport\Api\ResultsSource; |
17 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ContextCursorDeserializer; |
18 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ContextCursorSerializer; |
19 | use WikibaseQuality\ConstraintReport\ConstraintCheck\DelegatingConstraintChecker; |
20 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConnectionCheckerHelper; |
21 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser; |
22 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\DummySparqlHelper; |
23 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\LoggingHelper; |
24 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\RangeCheckerHelper; |
25 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\SparqlHelper; |
26 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\TypeCheckerHelper; |
27 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageDeserializer; |
28 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageRendererFactory; |
29 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageSerializer; |
30 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResultDeserializer; |
31 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResultSerializer; |
32 | |
33 | return [ |
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 | ]; |