SDImportDataParser::processData()   F
last analyzed

Complexity

Conditions 18
Paths 30

Size

Total Lines 108

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 18
nc 30
nop 4
dl 0
loc 108
rs 3.8933
c 0
b 0
f 0

How to fix   Long Method    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
if ( !defined( 'MEDIAWIKI' ) ) {
4
	echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
5
}
6
7
/** In this class we store things related to data processing **/
8
9
class SDImportDataParser {
10
11
	/**
12
	* @param $input string
13
	* @param $args array
14
	* @param $parser Parser
15
	* @param $frame Frame
16
	* @return string
17
	*/
18
	public static function processData( $input, $args, $parser, $frame ) {
0 ignored issues
show
Unused Code introduced by
The parameter $frame is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
19
	
20
		global $wgSDImportDataPage;
21
		$pageTitle = $parser->getTitle();
22
		$output = "";
23
24
		$separator="\t";
25
		$delimiter='"';
26
		$fields = array();
27
28
		if ( is_object( $pageTitle ) ) {
29
30
			$ns = $pageTitle->getNamespace();
31
32
			if ( key_exists( $ns, $wgSDImportDataPage ) ) {
33
34
				$nsRepo = $wgSDImportDataPage[$ns];
35
				
36
				$separator = SDImportData::getSelector( $args, $nsRepo, "separator" ); // String
37
				$delimiter = SDImportData::getSelector( $args, $nsRepo, "delimiter" ); // String
38
				$object = SDImportData::getSelector( $args, $nsRepo, "rowobject" ); // String
39
				$fields = SDImportData::getSelector( $args, $nsRepo, "rowfields" ); // Array
40
				$props = SDImportData::getSelector( $args, $nsRepo, "typefields" ); // Array
0 ignored issues
show
Unused Code introduced by
$props is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
41
				$refs = SDImportData::getSelector( $args, $nsRepo, "ref" ); // Hash
42
				$pre = SDImportData::getSelector( $args, $nsRepo, "prefields" ); // Array
43
				$post = SDImportData::getSelector( $args, $nsRepo, "postfields" ); // Array
44
				$editable = SDImportData::getSelector( $args, $nsRepo, "edit" ); // Boolean
45
				// TODO: Add single option here maybe?
46
47
				// TODO: Should we add props here if they don't exist?
48
				
49
50
				$dprops = array();
51
52
				if ( $refs ) {
53
					foreach ( $refs as $key => $val ) {
54
						$dprops[ $key ] = SDImportData::processWikiText( $val, $pageTitle );
55
					}
56
				}
57
				
58
				// Empty array
59
				$table = array();
60
				// We not assume preprocessing here
61
				$checkstr = trim( $input );
62
				if ( !empty( $checkstr ) ) {
63
					$table = self::getCSVData( $input, $separator, $delimiter );
64
				}
65
66
				// wfErrorLog( "SELF: ".print_r($table), '/tmp/my-custom-debug.log' );
67
68
69
				foreach ( $table as $row ) {
70
					$fieldcount = 0;
71
					$struct = array();
72
					foreach ( $row as $field ) {
73
74
						$field = trim( $field );
75
						
76
						if ( ! empty( $field ) ) {
77
							$pretxt = "";
78
							if ( isset( $pre[ $fieldcount ] ) && !empty( $pre[ $fieldcount ] ) ) {
79
								$pretxt = $pre[ $fieldcount ].":"; // : for pre
80
							}
81
							$postxt = "";
82
							if ( isset( $post[ $fieldcount ] ) && !empty( $post[ $fieldcount ] ) ) {
83
								$postxt = "@".$post[ $fieldcount ]; // @ for post
84
							}
85
							if ( array_key_exists( $fieldcount, $fields ) ) {
86
								$struct[ $fields[ $fieldcount ] ] =  $pretxt.$field.$postxt;
87
							}
88
						}
89
						$fieldcount++;
90
					}
91
					foreach ( $dprops as $dpropk => $dpropv ) {
92
						$struct[ $dpropk ] = $dpropv;
93
					}
94
					
95
					SDImportData::insertInternalObject( $parser, $pageTitle, $object, $struct );
0 ignored issues
show
Documentation introduced by
$struct is of type array, but the function expects a object.

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...
96
				}
97
98
			}
99
100
		}
101
		
102
		if ( !empty( $input ) ) {
103
			$wgOut = $parser->getOutput();
104
105
			// TODO: Revisit if this still needs handled this way
106
			global $wgScriptPath;
107
			$handsonpath = $wgScriptPath."/extensions/SemanticDataImport/libs/handsontable/handsontable.full.js";
108
			$wgOut->addHeadItem( '<script src="'.$handsonpath.'"></script>' ); //Hack because of handsontable for last versions :/
109
			$wgOut->addModules( 'ext.sdimport' );
110
111
			$fieldList = "";
112
			if ( sizeof( $fields ) > 0 ) {
113
				$fieldList = " data-cols='".implode(",", $fields)."' ";
114
			}
115
			
116
			$dataedit = "";
117
			if ( $editable ) {
0 ignored issues
show
Bug introduced by
The variable $editable does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
118
				$dataedit = "data-edit='data-edit'";
119
			}
120
121
			$output = "<div class='smwdata' data-delimiter='".$delimiter."' data-separator=\"".$separator."\"".$fieldList." ".$dataedit.">".$input."</div>";
122
		}
123
124
		return array( $output, 'noparse' => true, 'isHTML' => true );
125
	}
126
127
128
129
	/**
130
	* @param $input string
131
	* @param $args array
132
	* @param $parser Parser
133
	* @param $frame Frame
134
	* @return string
135
	*/
136
	public static function prepareLink( $parser, $frame, $args ) {
137
138
		global $wgSDImportDataPage;
139
140
		$wgOut = $parser->getOutput();
141
		$wgOut->addModules( 'ext.sdimport' );
142
		
143
		$attrs_allowed = array( "title", "model", "readonly", "ref", "readOnlyfields" );
144
		
145
		$attrs = array();
146
		$output = "";
147
		$model = "json"; // Let's use by default JSON model
148
		$pagetitle = null; // No page default. Do nothing
149
		$ref = null; // No ref hash by default
150
		$readOnlyfields = null; // No readonlyfields by default
151
		
152
		foreach ( $args as $arg ) {
153
			$arg_clean = trim( $frame->expand( $arg ) );
154
			$arg_proc = explode( "=", $arg_clean, 2 );
155
			
156
			if ( count( $arg_proc ) == 1 ){
157
				$pagetitle = trim( $arg_proc[0] );
158
			} else {
159
			
160
				if ( in_array( trim( $arg_proc[0] ), $attrs_allowed ) ) {
161
					$attrs[ trim( $arg_proc[0] ) ] = trim( $arg_proc[1] );
162
				}
163
			}
164
		}
165
		
166
		// TODO: Parse more parameters from function
167
		if ( array_key_exists( "title", $attrs ) ) {
168
			$pagetitle = $attrs['title'];
169
		}
170
		if ( array_key_exists( "model", $attrs ) ) {
171
			$model = $attrs['model'];
172
		}
173
		if ( array_key_exists( "ref", $attrs ) ) {
174
			$ref = str_replace( "[", "{", $attrs['ref'] );
175
			$ref = str_replace( "]", "}", $ref );
176
		}
177
178
		if ( array_key_exists( "readOnlyfields", $attrs ) ) {
179
			$readOnlyfields = str_replace( "[", "{", $attrs['readOnlyfields'] );
180
			$readOnlyfields = str_replace( "]", "}", $readOnlyfields );
181
		}
182
		
183
		if ( $pagetitle ) {
184
			
185
			$dataAttrsStr = "";
186
			
187
			if ( $pagetitle ) {
188
				$dataAttrsStr.= "data-title='$pagetitle'";
189
			}
190
			
191
			if ( $ref ) {
192
				$dataAttrsStr.= " data-ref='$ref'";
193
			}
194
			
195
			if ( $readOnlyfields ) {
196
				$dataAttrsStr.= " data-readOnlyfields='$readOnlyfields'";
197
			}
198
			
199
			$dataAttrsStr.= " data-model='$model'";
200
201
			if ( array_key_exists( "readonly", $attrs ) ) {
202
				$dataAttrsStr.= " data-readonly='true'";
203
			}
204
			
205
			$output = "<div class='smwdata-link' ".$dataAttrsStr."></div>";
206
		
207
		}
208
		
209
		return array( $output, 'noparse' => true, 'isHTML' => true );
210
		
211
	}
212
213
	private static function getCSVData( $text, $separator="\t", $delimiter='"' ) {
214
215
		$table = array();
216
217
		if ( empty( $text ) ) {
218
			return $table;
219
		}
220
221
		$linesCSV = explode( "\n", $text );
222
223
		foreach ( $linesCSV as $lineCSV ) {
224
			if ( !empty( $lineCSV ) ) {
225
				array_push( $table, str_getcsv( $lineCSV, $separator, $delimiter ) );
226
			}
227
		}
228
229
		return $table;
230
231
	}
232
233
234
235
}
236