IncrementalXmlDumpReader::next()   C
last analyzed

Complexity

Conditions 11
Paths 10

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 11.6893

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 39
ccs 23
cts 28
cp 0.8214
rs 5.2653
cc 11
eloc 26
nc 10
nop 0
crap 11.6893

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Wikibase\EntityStore\Internal;
4
5
use Deserializers\Deserializer;
6
use Deserializers\Exceptions\DeserializationException;
7
use Iterator;
8
use Psr\Log\LoggerInterface;
9
use Wikibase\DataModel\Entity\EntityDocument;
10
11
/**
12
 * Internal class
13
14
 * @licence GPLv2+
15
 * @author Thomas Pellissier Tanon
16
 */
17
class IncrementalXmlDumpReader implements Iterator {
18
19
	/**
20
	 * @var resource
21
	 */
22
	private $fileStream;
23
24
	/**
25
	 * @var Deserializer
26
	 */
27
	private $entityDeserializer;
28
29
	/**
30
	 * @var EntityDocument|null
31
	 */
32
	private $currentEntity = null;
33
34
	/**
35
	 * @var LoggerInterface
36
	 */
37
	private $logger;
38
39
	/**
40
	 * @param string $fileName
41
	 * @param Deserializer $entityDeserializer
42
	 * @param LoggerInterface $logger
43
	 */
44 2
	public function __construct( $fileName, Deserializer $entityDeserializer, LoggerInterface $logger ) {
45 2
		$this->fileStream = fopen( $fileName, 'r' );
46 2
		$this->entityDeserializer = $entityDeserializer;
47 2
		$this->logger = $logger;
48 2
	}
49
50 2
	public function __destruct() {
51 2
		fclose( $this->fileStream );
52 2
	}
53
54
	/**
55
	 * @see Iterator::current
56
	 */
57 2
	public function current() {
58 2
		return $this->currentEntity;
59
	}
60
61
	/**
62
	 * @see Iterator::next
63
	 */
64 2
	public function next() {
65 2
		$this->currentEntity = null;
66
67 2
		$isEntity = false;
68 2
		$text = '';
69 2
		while( true ) {
70 2
			$line = fgets( $this->fileStream );
71
72 2
			if( $line === false ) {
73 2
				return;
74
			}
75
76 2
			if( preg_match( '/<model>wikibase-[a-z]+<\/model>/', $line ) ) {
77 2
				$isEntity = true;
78 2
			} elseif( preg_match( '/<text.*>(.*)<\/text>/', $line, $m ) ) {
79 2
				$text = $m[1];
80 2
			} elseif( preg_match( '/<\/page>/', $line, $m ) && $isEntity ) {
81
82 2
				$json = json_decode( html_entity_decode( $text ), true );
83 2
				if( $json === null ) {
84 2
					$this->logger->error( 'The serialization is not a valid JSON document.' );
85 2
					continue;
86
				}
87
88 2
				if( array_key_exists( 'redirect', $json ) ) {
89 2
					$this->logger->info( 'Entity redirection not supported.' );
90 2
					continue;
91
				}
92
93
				try {
94 2
					$this->currentEntity = $this->entityDeserializer->deserialize( $json );
95 2
					return;
96
				} catch( DeserializationException $e ) {
97
					$id = array_key_exists( 'id', $json ) ? $json['id'] : '';
98
					$this->logger->error( 'Deserialization of entity ' . $id . ' failed: ' . $e->getMessage() );
99
				}
100
			}
101 2
		}
102
	}
103
104
	/**
105
	 * @see Iterator::key
106
	 */
107
	public function key() {
108
		if ( $this->currentEntity === null ) {
109
			return null;
110
		}
111
112
		return $this->currentEntity->getId()->getSerialization();
113
	}
114
115
	/**
116
	 * @see Iterator::valid
117
	 */
118 2
	public function valid() {
119 2
		return $this->currentEntity !== null;
120
	}
121
122
	/**
123
	 * @see Iterator::rewind
124
	 */
125 2
	public function rewind() {
126 2
		fseek( $this->fileStream, 0 );
127 2
		$this->next();
128 2
	}
129
}
130