Completed
Push — master ( 59f8d5...8ba3ac )
by
unknown
09:44
created

CheckConstraintsRdf   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 8
dl 0
loc 132
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A newFromGlobalState() 0 12 1
A getName() 0 3 1
A requiresWrite() 0 3 1
A cleanupGuid() 0 3 1
B onView() 0 54 8
1
<?php
2
3
namespace WikibaseQuality\ConstraintReport\Api;
4
5
use FormlessAction;
6
use IContextSource;
7
use Page;
8
use Wikibase\Rdf\RdfVocabulary;
9
use Wikibase\Repo\WikibaseRepo;
10
use Wikibase\Store\EntityIdLookup;
11
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult;
12
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\NullResult;
13
use WikibaseQuality\ConstraintReport\ConstraintReportFactory;
14
use Wikimedia\Purtle\RdfWriterFactory;
15
16
/**
17
 * Produce constraint check results in RDF.
18
 * Only returns cached constraint check results for now.
19
 */
20
class CheckConstraintsRdf extends FormlessAction {
21
22
	/**
23
	 * @var EntityIdLookup
24
	 */
25
	private $entityIdLookup;
26
	/**
27
	 * @var ResultsSource
28
	 */
29
	private $resultsSource;
30
	/**
31
	 * @var RdfVocabulary
32
	 */
33
	private $rdfVocabulary;
34
35
	public function __construct(
36
		Page $page,
37
		IContextSource $context,
38
		ResultsSource $resultsSource,
39
		EntityIdLookup $entityIdLookup,
40
		RdfVocabulary $rdfVocabulary
41
	) {
42
		parent::__construct( $page, $context );
43
		$this->resultsSource = $resultsSource;
44
		$this->entityIdLookup = $entityIdLookup;
45
		$this->rdfVocabulary = $rdfVocabulary;
46
	}
47
48
	public static function newFromGlobalState( Page $page, IContextSource $context = null ) {
49
		$repo = WikibaseRepo::getDefaultInstance();
50
		$constraintReportFactory = ConstraintReportFactory::getDefaultInstance();
51
52
		return new static(
53
			$page,
54
			$context,
55
			$constraintReportFactory->getResultsSource(),
56
			$repo->getEntityIdLookup(),
57
			$repo->getRdfVocabulary()
58
		);
59
	}
60
61
	/**
62
	 * Return the name of the action this object responds to
63
	 * @since 1.17
64
	 *
65
	 * @return string Lowercase name
66
	 */
67
	public function getName() {
68
		return 'constraintsrdf';
69
	}
70
71
	/**
72
	 * Whether this action requires the wiki not to be locked
73
	 * @since 1.17
74
	 *
75
	 * @return bool
76
	 */
77
	public function requiresWrite() {
78
		return false;
79
	}
80
81
	/**
82
	 * Cleanup GUID string so it's OK for RDF.
83
	 * Should match what we're doing on RDF generation.
84
	 * @param string $guid
85
	 * @return string
86
	 */
87
	private function cleanupGuid( $guid ) {
88
		return preg_replace( '/[^\w-]/', '-', $guid );
89
	}
90
91
	/**
92
	 * Show something on GET request.
93
	 * @return string|null Will be added to the HTMLForm if present, or just added to the
94
	 *     output if not.  Return null to not add anything
95
	 */
96
	public function onView() {
97
		$response = $this->getRequest()->response();
98
		$this->getOutput()->disable();
99
100
		if ( !$this->resultsSource instanceof CachingResultsSource ) {
101
			// TODO: make configurable whether only cached results are returned
102
			$response->statusHeader( 501 ); // Not Implemented
103
			return null;
104
		}
105
106
		$entityId = $this->entityIdLookup->getEntityIdForTitle( $this->getTitle() );
107
		if ( $entityId === null ) {
108
			$response->statusHeader( 404 ); // Not Found
109
			return null;
110
		}
111
112
		$results = $this->resultsSource->getStoredResults( $entityId );
113
		if ( $results === null ) {
114
			$response->statusHeader( 204 ); // No Content
115
			return null;
116
		}
117
118
		$format = 'ttl'; // TODO: make format an option
119
120
		$writerFactory = new RdfWriterFactory();
121
		$formatName = $writerFactory->getFormatName( $format );
122
		$contentType = $writerFactory->getMimeTypes( $formatName )[0];
0 ignored issues
show
Security Bug introduced by
It seems like $formatName defined by $writerFactory->getFormatName($format) on line 121 can also be of type false; however, Wikimedia\Purtle\RdfWriterFactory::getMimeTypes() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
123
124
		$response->header( "Content-Type: $contentType; charset=UTF-8" );
125
126
		$writer = $writerFactory->getWriter( $formatName );
0 ignored issues
show
Security Bug introduced by
It seems like $formatName defined by $writerFactory->getFormatName($format) on line 121 can also be of type false; however, Wikimedia\Purtle\RdfWriterFactory::getWriter() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
127
		foreach ( [ RdfVocabulary::NS_STATEMENT, RdfVocabulary::NS_ONTOLOGY ] as $ns ) {
128
			$writer->prefix( $ns, $this->rdfVocabulary->getNamespaceURI( $ns ) );
129
		}
130
		$writer->start();
131
132
		foreach ( $results->getArray() as $checkResult ) {
133
			if ( $checkResult instanceof NullResult ) {
134
				continue;
135
			}
136
			if ( $checkResult->getStatus() === CheckResult::STATUS_BAD_PARAMETERS ) {
137
				continue;
138
			}
139
140
			$writer->about( RdfVocabulary::NS_STATEMENT,
141
				$this->cleanupGuid( $checkResult->getContextCursor()->getStatementGuid() ) )
142
				->say( RdfVocabulary::NS_ONTOLOGY, 'hasViolationForConstraint' )
143
				->is( RdfVocabulary::NS_STATEMENT,
144
					$this->cleanupGuid( $checkResult->getConstraint()->getConstraintId() ) );
145
		}
146
		$writer->finish();
147
		echo $writer->drain();
148
		return null;
149
	}
150
151
}
152