Completed
Push — master ( 813ff2...07dd29 )
by mw
377:22 queued 342:34
created

getImportContents()   D

Complexity

Conditions 10
Paths 34

Size

Total Lines 44
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 44
c 0
b 0
f 0
cc 10
eloc 24
nc 34
nop 1
rs 4.8196

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 SMW\Importer;
4
5
use SMW\Utils\ErrorCodeFormatter;
6
use RuntimeException;
7
8
/**
9
 * @license GNU GPL v2+
10
 * @since 2.5
11
 *
12
 * @author mwjames
13
 */
14
class JsonImportContentsFileDirReader {
15
16
	/**
17
	 * @var array
18
	 */
19
	private static $contents = array();
0 ignored issues
show
Unused Code introduced by
The property $contents is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
20
21
	/**
22
	 * @var array
23
	 */
24
	private $errors = array();
25
26
	/**
27
	 * @var string
28
	 */
29
	private $importFileDir = '';
30
31
	/**
32
	 * @since 2.5
33
	 *
34
	 * @param string $importFileDir
35
	 */
36
	public function __construct( $importFileDir = '' ) {
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
37
		$this->importFileDir = $importFileDir;
38
39
		if ( $this->importFileDir === '' ) {
40
			$this->importFileDir = $GLOBALS['smwgImportFileDir'];
41
		}
42
	}
43
44
	/**
45
	 * @since 2.5
46
	 *
47
	 * @return array
48
	 */
49
	public function getErrors() {
50
		return $this->errors;
51
	}
52
53
	/**
54
	 * @since 2.5
55
	 *
56
	 * @return array
57
	 */
58
	public function getFiles() {
59
		return $this->getFilesFromLocation( $this->getImportFileDir(), 'json' );
60
	}
61
62
	/**
63
	 * @since 2.5
64
	 *
65
	 * @return ImportContents[]
66
	 * @throws RuntimeException
67
	 */
68
	public function getContentList() {
69
70
		$contents = array();
71
72
		try{
73
			$files = $this->getFiles();
74
		} catch( RuntimeException $e ) {
75
			$this->errors[] = $this->importFileDir . ' is not accessible.';
76
			$files = array();
77
		}
78
79
		foreach ( $files as $file => $path ) {
80
			$importContents = $this->getImportContents( $this->doFetchContentsFrom( $path ) );
81
82
			if ( $importContents === null ) {
83
				continue;
84
			}
85
86
			$contents[$file] = $importContents;
87
		}
88
89
		return $contents;
90
	}
91
92
	private function getImportContents( $fileContents ) {
93
94
		$contents = array();
95
96
		if ( !isset( $fileContents['import'] ) ) {
97
			return;
98
		}
99
100
		foreach ( $fileContents['import'] as $value ) {
101
			$importContents = new ImportContents();
102
103
			if ( isset( $value['page'] ) ) {
104
				$importContents->setName( $value['page'] );
105
			}
106
107
			if ( isset( $value['namespace'] ) ) {
108
				$importContents->setNamespace(
109
					defined( $value['namespace'] ) ? constant( $value['namespace'] ) : 0
110
				);
111
			}
112
113
			if ( !isset( $value['contents'] ) || $value['contents'] === '' ) {
114
				$importContents->addError( 'Missing, or has empty contents section' );
115
			} else {
116
				$this->fetchContents( $value['contents'], $importContents );
117
			}
118
119
			if ( !isset( $value['description'] ) ) {
120
				$importContents->setDescription( $fileContents['description'] );
121
			} else {
122
				$importContents->setDescription( $value['description'] );
123
			}
124
125
			$importContents->setVersion( $fileContents['meta']['version'] );
126
127
			if ( isset( $value['options'] ) ) {
128
				$importContents->setOptions( $value['options'] );
129
			}
130
131
			$contents[] = $importContents;
132
		}
133
134
		return $contents;
135
	}
136
137
	private function fetchContents( $contents, $importContents ) {
138
139
		$importContents->setContentType( ImportContents::CONTENT_TEXT );
140
141
		if ( !is_array( $contents ) || !isset( $contents['importFrom'] ) ) {
142
			return $importContents->setContents( $contents );
143
		}
144
145
		$file = $contents['importFrom'];
146
147
		$file = str_replace(
148
			array( '\\', '/' ),
149
			DIRECTORY_SEPARATOR,
150
			$this->importFileDir . ( $file{0} === '/' ? '' : '/' ) . $file
151
		);
152
153
		if ( !is_readable( $file ) ) {
154
			return $importContents->addError( $contents['importFrom'] . " wasn't accessible" );
155
		}
156
157
		$extension = pathinfo( $file, PATHINFO_EXTENSION );
158
159
		if ( $extension === 'xml' ) {
160
			$importContents->setContentType( ImportContents::CONTENT_XML );
161
		}
162
163
		$importContents->setContentsFile( $file );
164
	}
165
166
	private function doFetchContentsFrom( $file ) {
167
168
		$contents = json_decode(
169
			file_get_contents( $file ),
170
			true
171
		);
172
173
		if ( $contents !== null && json_last_error() === JSON_ERROR_NONE ) {
174
			return $contents;
175
		}
176
177
		throw new RuntimeException( ErrorCodeFormatter::getMessageFromJsonErrorCode( json_last_error() ) );
178
	}
179
180
	private function getImportFileDir() {
181
182
		$path = str_replace( array( '\\', '/' ), DIRECTORY_SEPARATOR, $this->importFileDir );
183
184
		if ( is_readable( $path ) ) {
185
			return $path;
186
		}
187
188
		throw new RuntimeException( "Expected an accessible {$path} path" );
189
	}
190
191
	private function getFilesFromLocation( $path, $extension ) {
192
193
		$files = array();
194
195
		$directoryIterator = new \RecursiveDirectoryIterator( $path );
196
197
		foreach ( new \RecursiveIteratorIterator( $directoryIterator ) as $fileInfo ) {
198
			if ( strtolower( substr( $fileInfo->getFilename(), -( strlen( $extension ) + 1 ) ) ) === ( '.' . $extension ) ) {
199
				$files[$fileInfo->getFilename()] = $fileInfo->getPathname();
200
			}
201
		}
202
203
		return $files;
204
	}
205
206
}
207