Completed
Push — master ( dd8aad...6526e1 )
by mw
04:06
created

src/DataValueDeserializer.php (1 issue)

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
12
/**
13
 * @license GNU GPL v2+
14
 * @since 1.0
15
 *
16
 * @author mwjames
17
 */
18
class DataValueDeserializer {
19
20
	/**
21
	 * @var string
22
	 */
23
	private $querySource;
24
25
	/**
26
	 * @since 1.0
27
	 *
28
	 * @param string $querySource
29
	 */
30 9
	public function __construct( $querySource ) {
31 9
		$this->querySource = $querySource;
32 9
	}
33
34
	/**
35
	 * @since 1.0
36
	 *
37
	 * @return string
38
	 */
39 5
	public function getQuerySource() {
40 5
		return $this->querySource;
41
	}
42
43
	/**
44
	 * @since 1.0
45
	 *
46
	 * @param DIProperty $property
47
	 * @param array|string $value
48
	 *
49
	 * @return DataValue
50
	 */
51 7
	public function newDataValueFrom( DIProperty $property, $value ) {
52
53 7
		$dv = null;
54 7
		$propertyList = array();
55
56 7
		if ( $property->findPropertyTypeId() === '_wpg' || isset( $value['fulltext'] ) ) {
57 1
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiWikiPage( $value ) );
58 7
		} elseif ( $property->findPropertyTypeId() === '_rec' ) {
59 1
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiContainerOnRecordType( $value, $propertyList ) );
60 1
			$dv->setFieldProperties( $propertyList );
61 6
		} elseif ( $property->findPropertyTypeId() === '_dat' ) {
62 4
			$dv = $this->newDataValueFromDataItem( $property, $this->newDiTime( $value ) );
0 ignored issues
show
It seems like $this->newDiTime($value) targeting SEQL\DataValueDeserializer::newDiTime() can also be of type object<SMWDITime>; however, SEQL\DataValueDeserializ...DataValueFromDataItem() does only seem to accept boolean, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
63 6
		} elseif ( $property->findPropertyTypeId() === '_qty' ) {
64 1
			$dv = $this->newDataValueFromPropertyObject( $property, $value['value'] . ' ' . $value['unit']  );
65 1
		}
66
67 7
		if ( $dv === null ) {
68 1
			$dv = $this->newDataValueFromPropertyObject( $property, $value );
69 1
		}
70
71 7
		return $dv;
72
	}
73
74
	/**
75
	 * @since 1.0
76
	 *
77
	 * @param array $value
78
	 *
79
	 * @return DIWikiPage
80
	 */
81 6
	public function newDiWikiPage( array $value ) {
82
83 6
		$ns = (int)$value['namespace'] === NS_CATEGORY ? NS_CATEGORY : NS_MAIN;
84
85 6
		if ( $ns === NS_CATEGORY ) {
86 1
			$value['fulltext'] = substr( $value['fulltext'], ($pos = strpos( $value['fulltext'], ':') ) !== false ? $pos + 1 : 0 );
87 1
		}
88
89 6
		$title = \Title::newFromText( $this->querySource . ':' . str_replace(" ", "_", $value['fulltext'] ), $ns );
90
91 6
		return DIWikiPage::newFromTitle( $title );
92
	}
93
94 4
	private function newDiTime( $value ) {
95
96 4
		if ( isset( $value['raw'] ) ) {
97 3
			return DITime::doUnserialize( $value['raw'] );
98
		}
99
100
		// < 0.7 API format
101
		// Avoid something like "Part of the date is out of bounds" where the API
102
		// doesn't sent a raw format
103
		// return 9999 BC to indicate that we hit a bounds with the timespamp
104
		try{
105 1
			$dataItem = DITime::newFromTimestamp( $value );
106 1
		} catch ( \Exception $e ) {
107
			$dataItem = DITime::doUnserialize( '2/-9999' );
108
		}
109
110 1
		return $dataItem;
111
	}
112
113 2
	private function newDataValueFromPropertyObject( $property, $value ) {
114
115
		try{
116 2
			$dv = DataValueFactory::newPropertyObjectValue( $property, $value );
117 2
		} catch ( \Exception $e ) {
118
			$dv = false;
119
		}
120
121 2
		return $dv;
122
	}
123
124 6
	private function newDataValueFromDataItem( $property, $dataItem = false ) {
125
126 6
		if ( $dataItem === false ) {
127 1
			return false;
128
		}
129
130
		try{
131 5
			$dv = DataValueFactory::newDataItemValue( $dataItem, $property );
132 5
		} catch ( \Exception $e ) {
133
			$dv = false;
134
		}
135
136 5
		return $dv;
137
	}
138
139 1
	private function newDiContainerOnRecordType( array $value, &$propertyList ) {
140
141
		// Remote container to use an anonymous
142 1
		$semanticData = ContainerSemanticData::makeAnonymousContainer();
143
144 1
		foreach ( $value as $recValue ) {
145 1
			$recordProperty = DIProperty::newFromUserLabel( $recValue['label'] );
146 1
			$recordProperty->setInterwiki( $this->querySource );
147 1
			$recordProperty->setPropertyTypeId( $recValue['typeid'] );
148 1
			$propertyList[] = $recordProperty;
149
150 1
			foreach ( $recValue['item'] as $item ) {
151 1
				$dataValue = $this->newDataValueFrom( $recordProperty, $item );
152
153 1
				if ( $dataValue === false ) {
154
					continue;
155
				}
156
157 1
				$semanticData->addPropertyObjectValue( $recordProperty, $dataValue->getDataItem() );
158 1
			}
159 1
		}
160
161 1
		return new DIContainer( $semanticData );
162
	}
163
164
}
165