Completed
Push — master ( 3e30e6...aad109 )
by mw
02:31
created

src/DataValueDeserializer.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SEQL;
4
5
use SMW\DataValueFactory;
6
use SMW\DIProperty;
7
use SMW\DIWikiPage;
8
use SMWContainerSemanticData as ContainerSemanticData;
9
use SMWDIContainer as DIContainer;
10
use SMWDITime as DITime;
11
use SMWDIBlob as DIBlob;
12
13
/**
14
 * @license GNU GPL v2+
15
 * @since 1.0
16
 *
17
 * @author mwjames
18
 */
19
class DataValueDeserializer {
20
21
	/**
22
	 * @var string
23
	 */
24
	private $querySource;
25
26
	/**
27
	 * @var EmbeddedLinksReplacer
28
	 */
29
	private $embeddedLinksReplacer;
30
31
	/**
32
	 * @since 1.0
33
	 *
34
	 * @param string $querySource
35
	 */
36 15
	public function __construct( $querySource ) {
37 15
		$this->querySource = $querySource;
38 15
		$this->embeddedLinksReplacer = new EmbeddedLinksReplacer( $querySource );
39 15
	}
40
41
	/**
42
	 * @since 1.0
43
	 *
44
	 * @return string
45
	 */
46 8
	public function getQuerySource() {
47 8
		return $this->querySource;
48
	}
49
50
	/**
51
	 * @since 1.0
52
	 *
53
	 * @param DIProperty $property
54
	 * @param array|string $value
55
	 *
56
	 * @return DataValue
57
	 */
58 12
	public function newDataValueFrom( DIProperty $property, $value ) {
59
60 12
		$dv = null;
61 12
		$propertyList = array();
62
63 12
		if ( $property->findPropertyTypeId() === '_wpg' || isset( $value['fulltext'] ) ) {
64 2
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiWikiPage( $value ) );
65 12
		} elseif ( strpos( $property->findPropertyTypeId(), '_rec' ) !== false ) {
66 2
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiContainerOnRecordType( $value, $propertyList ) );
0 ignored issues
show
$this->newDiContainerOnR...($value, $propertyList) is of type object<SMWDIContainer>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
67 2
			$dv->setFieldProperties( $propertyList );
68 11
		} elseif ( $property->findPropertyTypeId() === '_dat' ) {
69 4
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiTime( $value ) );
70 10
		} elseif ( strpos( $property->findPropertyTypeId(), '_txt' ) !== false ) {
71 2
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiBlob( $value ) );
0 ignored issues
show
$this->newDiBlob($value) is of type object<SMWDIBlob>, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
72 6
		} elseif ( $property->findPropertyTypeId() === '_qty' ) {
73 1
			$dv = $this->newDataValueFromPropertyObject( $property, $value['value'] . ' ' . $value['unit']  );
74 1
		}
75
76 12
		if ( $dv === null ) {
77 3
			$dv = $this->newDataValueFromPropertyObject( $property, $value );
78 3
		}
79
80 12
		return $dv;
81
	}
82
83
	/**
84
	 * @since 1.0
85
	 *
86
	 * @param array $value
87
	 *
88
	 * @return DIWikiPage|false
89
	 */
90 11
	public function newDiWikiPage( array $value ) {
91
92 11
		if ( !isset( $value['namespace'] ) || !isset( $value['fulltext'] ) ) {
93 1
			return false;
94
		}
95
96 10
		$ns = (int)$value['namespace'] === NS_CATEGORY ? NS_CATEGORY : NS_MAIN;
97
98 10
		if ( $ns === NS_CATEGORY ) {
99 1
			$value['fulltext'] = substr( $value['fulltext'], ($pos = strpos( $value['fulltext'], ':') ) !== false ? $pos + 1 : 0 );
100 1
		}
101
102 10
		$title = \Title::newFromText( $this->querySource . ':' . str_replace(" ", "_", $value['fulltext'] ), $ns );
103
104 10
		return DIWikiPage::newFromTitle( $title );
105
	}
106
107 4
	private function newDiTime( $value ) {
108
109 4
		if ( isset( $value['raw'] ) ) {
110 3
			return DITime::doUnserialize( $value['raw'] );
111
		}
112
113
		// < 0.7 API format
114
		// Avoid something like "Part of the date is out of bounds" where the API
115
		// doesn't sent a raw format
116
		// return 9999 BC to indicate that we hit a bounds with the timespamp
117
		try{
118 1
			$dataItem = DITime::newFromTimestamp( $value );
119 1
		} catch ( \Exception $e ) {
120
			$dataItem = DITime::doUnserialize( '2/-9999' );
121
		}
122
123 1
		return $dataItem;
124
	}
125
126 2
	private function newDiBlob( $value ) {
127 2
		return new DIBlob( $this->embeddedLinksReplacer->replace( $value ) );
128
	}
129
130 4
	private function newDataValueFromPropertyObject( $property, $value ) {
131
132
		try{
133 4
			$dv = DataValueFactory::newPropertyObjectValue( $property, $value );
134 4
		} catch ( \Exception $e ) {
135
			$dv = false;
136
		}
137
138 4
		return $dv;
139
	}
140
141 8
	private function newDataValueFromDataItem( $property, $dataItem = false ) {
142
143 8
		if ( $dataItem === false ) {
144 1
			return false;
145
		}
146
147
		try{
148 7
			$dv = DataValueFactory::newDataItemValue( $dataItem, $property );
0 ignored issues
show
$dataItem is of type boolean, but the function expects a object<SMWDataItem>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
149 7
		} catch ( \Exception $e ) {
150
			$dv = false;
151
		}
152
153 7
		return $dv;
154
	}
155
156 2
	private function newDiContainerOnRecordType( array $value, &$propertyList ) {
157
158
		// Remote container to use an anonymous
159 2
		$semanticData = ContainerSemanticData::makeAnonymousContainer();
160
161 2
		foreach ( $value as $recValue ) {
162 2
			$recordProperty = DIProperty::newFromUserLabel( $recValue['label'] );
163 2
			$recordProperty->setInterwiki( $this->querySource );
164 2
			$recordProperty->setPropertyTypeId( $recValue['typeid'] );
165 2
			$propertyList[] = $recordProperty;
166
167 2
			foreach ( $recValue['item'] as $item ) {
168 2
				$dataValue = $this->newDataValueFrom( $recordProperty, $item );
169
170 2
				if ( $dataValue === false ) {
171
					continue;
172
				}
173
174 2
				$semanticData->addPropertyObjectValue( $recordProperty, $dataValue->getDataItem() );
175 2
			}
176 2
		}
177
178 2
		return new DIContainer( $semanticData );
179
	}
180
181
}
182