Completed
Push — master ( d689cc...634f91 )
by
unknown
02:42
created

CheckConstraintsRdf::requiresWrite()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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
	 * @see Action::requiresUnblock
83
	 *
84
	 * @return bool Always false.
85
	 */
86
	public function requiresUnblock() {
87
		return false;
88
	}
89
90
	/**
91
	 * Cleanup GUID string so it's OK for RDF.
92
	 * Should match what we're doing on RDF generation.
93
	 * @param string $guid
94
	 * @return string
95
	 */
96
	private function cleanupGuid( $guid ) {
97
		return preg_replace( '/[^\w-]/', '-', $guid );
98
	}
99
100
	/**
101
	 * Show something on GET request.
102
	 * @return string|null Will be added to the HTMLForm if present, or just added to the
103
	 *     output if not.  Return null to not add anything
104
	 */
105
	public function onView() {
106
		$response = $this->getRequest()->response();
107
		$this->getOutput()->disable();
108
109
		if ( !$this->resultsSource instanceof CachingResultsSource ) {
110
			// TODO: make configurable whether only cached results are returned
111
			$response->statusHeader( 501 ); // Not Implemented
112
			return null;
113
		}
114
115
		$entityId = $this->entityIdLookup->getEntityIdForTitle( $this->getTitle() );
116
		if ( $entityId === null ) {
117
			$response->statusHeader( 404 ); // Not Found
118
			return null;
119
		}
120
121
		$results = $this->resultsSource->getStoredResults( $entityId );
122
		if ( $results === null ) {
123
			$response->statusHeader( 204 ); // No Content
124
			return null;
125
		}
126
127
		$format = 'ttl'; // TODO: make format an option
128
129
		$writerFactory = new RdfWriterFactory();
130
		$formatName = $writerFactory->getFormatName( $format );
131
		$contentType = $writerFactory->getMimeTypes( $formatName )[0];
0 ignored issues
show
Security Bug introduced by
It seems like $formatName defined by $writerFactory->getFormatName($format) on line 130 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...
132
133
		$response->header( "Content-Type: $contentType; charset=UTF-8" );
134
135
		$writer = $writerFactory->getWriter( $formatName );
0 ignored issues
show
Security Bug introduced by
It seems like $formatName defined by $writerFactory->getFormatName($format) on line 130 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...
136
		foreach ( [ RdfVocabulary::NS_STATEMENT, RdfVocabulary::NS_ONTOLOGY ] as $ns ) {
137
			$writer->prefix( $ns, $this->rdfVocabulary->getNamespaceURI( $ns ) );
138
		}
139
		$writer->start();
140
141
		foreach ( $results->getArray() as $checkResult ) {
142
			if ( $checkResult instanceof NullResult ) {
143
				continue;
144
			}
145
			if ( $checkResult->getStatus() === CheckResult::STATUS_BAD_PARAMETERS ) {
146
				continue;
147
			}
148
149
			$writer->about( RdfVocabulary::NS_STATEMENT,
150
				$this->cleanupGuid( $checkResult->getContextCursor()->getStatementGuid() ) )
151
				->say( RdfVocabulary::NS_ONTOLOGY, 'hasViolationForConstraint' )
152
				->is( RdfVocabulary::NS_STATEMENT,
153
					$this->cleanupGuid( $checkResult->getConstraint()->getConstraintId() ) );
154
		}
155
		$writer->finish();
156
		echo $writer->drain();
157
		return null;
158
	}
159
160
}
161