Completed
Push — master ( aad109...a11cd2 )
by mw
02:20
created

CannedResultArray::loadContent()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 7.0161

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 37
ccs 27
cts 29
cp 0.931
rs 6.7273
cc 7
eloc 24
nc 7
nop 0
crap 7.0161
1
<?php
2
3
namespace SEQL\ByHttpRequest;
4
5
use SMW\DataValueFactory;
6
use SMW\DIProperty;
7
use SMW\DIWikiPage;
8
use SMW\Query\PrintRequest;
9
use SMWDataValue as DataValue;
10
use SMWResultArray as ResultArray;
11
12
/**
13
 * @license GNU GPL v2+
14
 * @since 1.0
15
 *
16
 * @author mwjames
17
 */
18
class CannedResultArray extends ResultArray {
19
20
	/**
21
	 * @var PrintRequest
22
	 */
23
	private $mPrintRequest;
0 ignored issues
show
Comprehensibility introduced by mwjames
Consider using a different property name as you override a private property of the parent class.
Loading history...
24
25
	/**
26
	 * @var DIWikiPage
27
	 */
28
	private $mResult;
0 ignored issues
show
Comprehensibility introduced by mwjames
Consider using a different property name as you override a private property of the parent class.
Loading history...
29
30
	/**
31
	 * @var JsonResponseParser
32
	 */
33
	private $jsonResponseParser;
34
35
	/**
36
	 * @var DataValue[]|false
37
	 */
38
	private $mContent;
0 ignored issues
show
Comprehensibility introduced by mwjames
Consider using a different property name as you override a private property of the parent class.
Loading history...
39
40
	/**
41
	 * @since 1.0
42
	 *
43
	 * @param DIWikiPage $resultPage
44
	 * @param PrintRequest $printRequest
45
	 * @param JsonResponseParser $jsonResponseParser
46
	 */
47 6
	public function __construct( DIWikiPage $resultPage, PrintRequest $printRequest, JsonResponseParser $jsonResponseParser ) {
48 6
		$this->mResult = $resultPage;
49 6
		$this->mPrintRequest = $printRequest;
50 6
		$this->jsonResponseParser = $jsonResponseParser;
51 6
		$this->mContent = false;
52 6
	}
53
54
	/**
55
	 * @see ResultArray::getResultSubject
56
	 *
57
	 * @return DIWikiPage
58
	 */
59 1
	public function getResultSubject() {
60 1
		return $this->mResult;
61
	}
62
63
	/**
64
	 * @see ResultArray::getContent
65
	 *
66
	 * @return SMWDataItem[]|false
67
	 */
68 4
	public function getContent() {
69 4
		$this->loadContent();
70
71 4
		if ( !$this->mContent ) {
72
			return $this->mContent;
73
		}
74
75 4
		$content = array();
76
77 4
		foreach ( $this->mContent as $value ) {
78 4
			$content[] = $value instanceof DataValue ? $value->getDataItem() : $value;
79 4
		}
80
81 4
		return $content;
82
	}
83
84
	/**
85
	 * @see ResultArray::getPrintRequest
86
	 *
87
	 * @return PrintRequest
88
	 */
89
	public function getPrintRequest() {
90
		return $this->mPrintRequest;
91
	}
92
93
	/**
94
	 * @see ResultArray::getNextDataItem
95
	 *
96
	 * @since 1.6
97
	 *
98
	 * @return SMWDataItem|false
99
	 */
100 4
	public function getNextDataItem() {
101
102 4
		$this->loadContent();
103 4
		$result = current( $this->mContent );
104 4
		next( $this->mContent );
105
106 4
		return $result instanceof DataValue ? $result->getDataItem() : $result;
107
	}
108
109
	/**
110
	 * @see ResultArray::reset
111
	 *
112
	 * @since 1.7.1
113
	 *
114
	 * @return SMWDataItem|false
115
	 */
116 4
	public function reset() {
117
118 4
		$this->loadContent();
119 4
		$result = reset( $this->mContent );
120
121 4
		return $result instanceof DataValue ? $result->getDataItem() : $result;
122
	}
123
124
	/**
125
	 * @see ResultArray::getNextDataValue
126
	 *
127
	 * @since 1.6
128
	 *
129
	 * @return SMWDataValue|false
130
	 */
131 4
	public function getNextDataValue() {
132
133 4
		$this->loadContent();
134 4
		$content = current( $this->mContent );
135 4
		next( $this->mContent );
136
137 4
		if ( $content === false ) {
138
			return false;
139
		}
140
141 4
		$property = $this->getMatchablePropertyFromPrintRequest();
142
143
		// Units of measurement can not be assumed to be declared on a wiki
144
		// therefore don't try to recreate a DataValue and use the DV created
145
		// from the raw API response
146 4
		if ( $this->mPrintRequest->getMode() === PrintRequest::PRINT_PROP &&
147 4
		    $property->findPropertyTypeId() === '_qty' ) {
148 1
			return $content;
149
		}
150
151 3
		if ( $this->mPrintRequest->getMode() === PrintRequest::PRINT_PROP &&
152 3
		    strpos( $property->findPropertyTypeId(), '_rec' ) !== false ) {
153
154
			if ( $this->mPrintRequest->getParameter( 'index' ) === false ) {
155
				return $content;
156
			}
157
158
			$pos = $this->mPrintRequest->getParameter( 'index' ) - 1;
159
			$dataItems = $content->getDataItems();
0 ignored issues
show
Bug introduced by mwjames
The method getDataItems() does not exist on SMWDataValue. Did you maybe mean getDataItem()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
160
161
			if ( !array_key_exists( $pos, $dataItems ) ) {
162
				return $content;
163
			}
164
165
			$diProperties = $content->getPropertyDataItems();
0 ignored issues
show
Bug introduced by mwjames
The method getPropertyDataItems() does not exist on SMWDataValue. Did you maybe mean getProperty()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
166
			$content = $dataItems[$pos];
167
168
			if ( array_key_exists( $pos, $diProperties ) &&
169
				!is_null( $diProperties[$pos] ) ) {
170
				$diProperty = $diProperties[$pos];
171
			} else {
172
				$diProperty = null;
173
			}
174
175 3
		} elseif ( $this->mPrintRequest->getMode() == PrintRequest::PRINT_PROP ) {
176 1
			$diProperty = $property;
177 1
		} else {
178 2
			$diProperty = null;
179
		}
180
181 3
		if ( $content instanceof DataValue ) {
182 1
			$content = $content->getDataItem();
183 1
		}
184
185 3
		$dataValue = DataValueFactory::getInstance()->newDataItemValue( $content, $diProperty );
186
187 3
		if ( $this->mPrintRequest->getOutputFormat() ) {
188
			$dataValue->setOutputFormat( $this->mPrintRequest->getOutputFormat() );
189
		}
190
191 3
		return $dataValue;
192
	}
193
194
	/**
195
	 * Load results of the given print request and result subject. This is only
196
	 * done when needed.
197
	 */
198 4
	protected function loadContent() {
199 4
		if ( $this->mContent !== false ) {
200 4
			return;
201
		}
202
203 4
		$this->mContent = array();
204
205 4
		switch ( $this->mPrintRequest->getMode() ) {
206 4
			case PrintRequest::PRINT_THIS:
207 1
				$this->mContent = array( $this->mResult );
0 ignored issues
show
Documentation Bug introduced by mwjames
It seems like array($this->mResult) of type array<integer,object<SMW...ect<SMW\\DIWikiPage>"}> is incompatible with the declared type array<integer,object<SMWDataValue>>|false of property $mContent.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
208 1
			break;
209 3
			case PrintRequest::PRINT_CCAT:
210 3
			case PrintRequest::PRINT_CATS:
211
212 1
				$this->mContent = $this->jsonResponseParser->getPropertyValuesFor(
213 1
					$this->mResult,
214 1
					new DIProperty( '_INST' )
215 1
				);
216
217 1
			break;
218 2
			case PrintRequest::PRINT_PROP:
219 2
				$propertyValue = $this->mPrintRequest->getData();
220
221 2
				if ( $propertyValue->isValid() ) {
222 2
					$this->mContent = $this->jsonResponseParser->getPropertyValuesFor(
223 2
						$this->mResult,
224 2
						$this->getMatchablePropertyFromPrintRequest()
0 ignored issues
show
Bug introduced by mwjames
It seems like $this->getMatchablePropertyFromPrintRequest() can be null; however, getPropertyValuesFor() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
225 2
					);
226 2
				}
227
228 2
			break;
229
			default:
230
				$this->mContent = array(); // Unknown print request.
231 4
		}
232
233 4
		reset( $this->mContent );
234 4
	}
235
236 4
	private function getMatchablePropertyFromPrintRequest() {
237
238 4
		if ( $this->mPrintRequest->getMode() !== PrintRequest::PRINT_PROP ) {
239 2
			return null;
240
		}
241
242 2
		$property = $this->mPrintRequest->getData()->getDataItem();
243
244
		// The API may not deploy the natural property key (until 0.8+) hence something
245
		// like |?Has population=Population (in K) does not return a valid result from
246
		// the parser because "Has population" cannot be connected to "Population (in K)"
247
		// without the extra "key" field therefore construct a new property to match the
248
		// label
249 2
		if ( $this->mPrintRequest->getLabel() !== '' && $this->mPrintRequest->getLabel() !== $property->getLabel() ) {
250 1
			return $this->jsonResponseParser->findPropertyFromInMemoryExternalRepositoryCache(
251 1
				DIProperty::newFromUserLabel( $this->mPrintRequest->getLabel() )
252 1
			);
253
		}
254
255 1
		return $this->jsonResponseParser->findPropertyFromInMemoryExternalRepositoryCache(
256
			$property
257 1
		);
258
	}
259
260
}
261