Passed
Push — scrutinizer-code-quality ( 09f5a1...c4c5fb )
by Adam
56:05 queued 14:08
created

EditViewMetaParser::parse()   F

Complexity

Conditions 62
Paths > 20000

Size

Total Lines 274
Code Lines 166

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 3906
Metric Value
cc 62
eloc 166
nc 429496.7295
nop 5
dl 0
loc 274
ccs 0
cts 210
cp 0
crap 3906
rs 2

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
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3
/*********************************************************************************
4
 * SugarCRM Community Edition is a customer relationship management program developed by
5
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
6
7
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
8
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
9
 *
10
 * This program is free software; you can redistribute it and/or modify it under
11
 * the terms of the GNU Affero General Public License version 3 as published by the
12
 * Free Software Foundation with the addition of the following permission added
13
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
14
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
15
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
16
 *
17
 * This program is distributed in the hope that it will be useful, but WITHOUT
18
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
20
 * details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License along with
23
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
24
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25
 * 02110-1301 USA.
26
 *
27
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
28
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
29
 *
30
 * The interactive user interfaces in modified source and object code versions
31
 * of this program must display Appropriate Legal Notices, as required under
32
 * Section 5 of the GNU Affero General Public License version 3.
33
 *
34
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
35
 * these Appropriate Legal Notices must retain the display of the "Powered by
36
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
37
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
38
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
39
 ********************************************************************************/
40
41
42
/**
43
 * EdtiViewMetaParser.php
44
 * This is a utility file that attempts to provide support for parsing pre 5.0 SugarCRM
45
 * EditView.html files and produce a best guess editviewdefs.php file equivalent.
46
 *
47
 * @author Collin Lee
48
 */
49
50
require_once('include/SugarFields/Parsers/MetaParser.php');
51
52
class EditViewMetaParser extends MetaParser {
53
54
function __construct() {
55
   $this->mView = 'EditView';
56
}
57
58
    /**
59
     * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead
60
     */
61
    function EditViewMetaParser(){
62
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
63
        if(isset($GLOBALS['log'])) {
64
            $GLOBALS['log']->deprecated($deprecatedMessage);
65
        }
66
        else {
67
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
68
        }
69
        self::__construct();
70
    }
71
72
73
/**
74
 * parse
75
 *
76
 * @param $filePath The file path of the HTML file to parse
77
 * @param $vardefs The module's vardefs
78
 * @param $moduleDir The module's directory
79
 * @param $merge boolean value indicating whether or not to merge the parsed contents
80
 * @param $masterCopy The file path of the mater copy of the metadata file to merge against
81
 * @return String format of metadata contents
82
 **/
83
function parse($filePath, $vardefs = array(), $moduleDir = '', $merge=false, $masterCopy=null) {
84
85
   global $app_strings;
86
   $contents = file_get_contents($filePath);
87
   $contents = $this->trimHTML($contents);
88
   $contents = $this->stripFlavorTags($contents);
89
   $moduleName = '';
90
91
   $contents = $this->fixDuplicateTrTags($contents);
92
   $contents = $this->fixRowsWithMissingTr($contents);
93
94
   $tables = $this->getElementsByType("table", $contents);
95
   $formElements = $this->getFormElements($tables[0]);
96
   $hiddenInputs = array();
97
   foreach($formElements as $elem) {
98
   	      $type = $this->getTagAttribute("type", $elem);
99
   	      if(preg_match('/hidden/si',$type)) {
100
   	         $name = $this->getTagAttribute("name", $elem);
101
   	         $value = $this->getTagAttribute("value", $elem);
102
   	         $hiddenInputs[$name] = $value;
103
   	      }
104
   }
105
106
   // Get the second table in the page and onward
107
   $tables = array_slice($tables, 1);
108
   $panels = array();
109
   $tableCount = 0;
110
   $addedElements = array();
111
   $maxTableCountNum = 0;
112
   $tableCount = 0;
113
   foreach($tables as $table) {
114
   	      $table = $this->fixTablesWithMissingTr($table);
115
   	      $toptr = $this->getElementsByType("tr", $table);
116
          foreach($toptr as $tr) {
117
          	      $tabledata = $this->getElementsByType("table", $tr);
118
          	      $data = array();
119
          	      $panelKey = $tableCount == 0 ? "default" : '';
120
          	      foreach($tabledata as $t) {
121
          	      	      $vals = array_values($this->getElementsByType("tr", $t));
122
          	      	      if(preg_match_all('/<h4[^>]*?>.*?(\{MOD\.|\{APP\.)(LBL_[^\}]*?)[\}].*?<\/h4>/s', $vals[0], $matches, PREG_SET_ORDER)) {
123
          	      	      	array_shift($vals);
124
          	      	      	$panelKey = count($matches[0]) == 3 ? strtolower($matches[0][2]) : $panelKey;
125
          	      	      }
126
127
          	      	      //If $panelKey is empty use the maxTableCountNum value
128
          	      	      if(empty($panelKey)) {
129
          	      	      	$panels[$maxTableCountNum++] = $vals;
130
          	      	      } else {
131
          	      	        $panels[$panelKey] = $vals;
132
          	      	      }
133
   	              } //foreach
134
                  $tableCount++;
135
          } //foreach;
136
   } //foreach
137
138
   foreach($panels as $id=>$tablerows) {
139
140
       $metarow = array();
141
142
	   foreach($tablerows as $trow) {
143
144
	   	   $emptyCount = 0;
145
	   	   $tablecolumns = $this->getElementsByType("td", $trow);
146
	       $col = array();
147
	       $slot = 0;
148
149
		   foreach($tablecolumns as $tcols) {
150
		   	  $hasRequiredLabel = false;
151
152
		   	  //Get the sugar attribute value in the span elements of each table row
153
		   	  $sugarAttrLabel = $this->getTagAttribute("sugar", $tcols, "'^slot[^b]+$'");
154
155
		   	  //If there was no sugar attribute, try id (some versions of EditView.html used this instead)
156
		   	  if(empty($sugarAttrLabel)) {
157
		   	     $sugarAttrLabel = $this->getTagAttribute("id", $tcols, "'^slot[^b]+$'");
158
		   	  }
159
160
		   	  //Check if this field is required
161
		   	  if(!empty($sugarAttrLabel)) {
162
		   	  	 $hasRequiredLabel = $this->hasRequiredSpanLabel($tcols);
163
		   	  }
164
165
		   	  $sugarAttrValue = $this->getTagAttribute("sugar", $tcols, "'slot[0-9]+b$'");
166
167
		   	  //If there was no sugar attribute, try id (some versions of EditView.html used this instead)
168
              if(empty($sugarAttrValue)) {
169
              	 $sugarAttrValue = $this->getTagAttribute("id", $tcols, "'slot[0-9]+b$'");
170
              }
171
172
              // If there wasn't any slot numbering/lettering then just default to expect label->vallue pairs
173
	          $sugarAttrLabel = count($sugarAttrLabel) != 0 ? $sugarAttrLabel : ($slot % 2 == 0) ? true : false;
174
	          $sugarAttrValue = count($sugarAttrValue) != 0 ? $sugarAttrValue : ($slot % 2 == 1) ? true : false;
175
	          $slot++;
176
177
              if($sugarAttrValue) {
178
179
				   	  	 $spanValue = $this->getElementValue("span", $tcols);
180
181
				   	  	 if(empty($spanValue)) {
182
		                    $spanValue = $this->getElementValue("slot", $tcols);
183
		                 }
184
185
		                 if(empty($spanValue)) {
186
		                    $spanValue = $this->getElementValue("td", $tcols);
187
		                 }
188
189
		                 //Get all the editable form elements' names
190
				   	  	 $formElementNames = $this->getFormElementsNames($spanValue);
191
				   	  	 $customField = $this->getCustomField($formElementNames);
192
193
				   	  	 $name = '';
194
		                 $fields = null;
195
		                 $customCode = null;
196
197
		                 if(!empty($customField)) {
198
		                   // If it's a custom field we just set the name
199
		                   $name = $customField;
200
201
		                 } else if(empty($formElementNames) && preg_match_all('/[\{]([^\}]*?)[\}]/s', $spanValue, $matches, PREG_SET_ORDER)) {
202
				   	  	   // We are here if the $spanValue did not contain a form element for editing.
203
				   	  	   // We will assume that it is read only (since there were no edit form elements)
204
205
206
					           // If there is more than one matching {} value then try to find the right one to key off
207
					           // based on vardefs.php file.  Also, use the entire spanValue as customCode
208
					           	if(count($matches) > 1) {
209
							       $name = $matches[0][1];
210
							       $customCode = $spanValue;
211
							       foreach($matches as $pair) {
212
						   	  	 	   if(preg_match("/^(mod[\.]|app[\.]).*?/i", $pair[1])) {
213
						   	  	 	       $customCode = str_replace($pair[1], '$'.strtoupper($pair[1]), $customCode);
214
						   	  	 	   } else {
215
						   	  	 	       if(!empty($vardefs[$pair[1]])) {
216
						   	  	 	       	  $name = $pair[1];
217
						   	  	 	          $customCode = str_replace($pair[1], '$fields.'.strtolower($pair[1]).'.value', $customCode);
218
						   	  	 	       } else {
219
						   	  	 	       	  $phpName = $this->findAssignedVariableName($pair[1], $filePath);
220
						   	  	 	       	  $customCode = str_replace($pair[1], '$fields.'.strtolower($phpName).'.value', $customCode);
221
						   	  	 	       } //if-else
222
						   	  	 	   }
223
						           } //foreach
224
						       } else {
225
						       	   //If it is only a label, skip
226
						       	   if(preg_match("/^(mod[\.]|app[\.]).*?/i", $matches[0][1])) {
227
						       	   	  continue;
228
						       	   }
229
						   	  	   $name = strtolower($matches[0][1]);
230
						   	   }
231
232
				   	  	 } else if(is_array($formElementNames)) {
233
234
				   	  	      if(count($formElementNames) == 1) {
235
236
				   	  	      	 if(!empty($vardefs[$formElementNames[0]])) {
237
				   	  	            $name = $formElementNames[0];
238
				   	  	      	 } else {
239
				   	  	      	 	// Try to use the EdtiView.php file to find author's intent
240
				   	  	      	 	$name = $this->findAssignedVariableName($formElementNames[0], $filePath);
241
242
				   	  	      	 	//If it's still empty, just use the entire block as customCode
243
				   	  	      	 	if(empty($vardefs[$name])) {
244
				   	  	      	 	   //Replace any { characters just in case
245
				   	  	      	 	   $customCode = str_replace('{', '{$', $spanValue);
246
				   	  	      	 	}
247
				   	  	      	 } //if-else
248
				   	  	      } else {
249
				   	  	      	 //If it is an Array of form elements, it is likely the _id and _name relate field combo
250
		                         $relateName = $this->getRelateFieldName($formElementNames);
251
		                         if(!empty($relateName)) {
252
		                            $name = $relateName;
253
		                         } else {
254
		                         	 //One last attempt to scan $formElementNames for one vardef field only
255
		                         	 $name = $this->findSingleVardefElement($formElementNames, $vardefs);
256
		                         	 if(empty($name)) {
257
					   	  	      	 	 $fields = array();
258
			                         	 $name = $formElementNames[0];
259
						   	  	      	 foreach($formElementNames as $elementName) {
260
						   	  	      	 	if(isset($vardefs[$elementName])) {
261
						   	  	      	 	   $fields[] = $elementName;
262
						   	  	      	 	} else {
263
						   	  	      	 	   $fields[] = $this->findAssignedVariableName($elementName, $filePath);
264
						   	  	      	 	} //if-else
265
					   	  	      	 	} //foreach
266
		                         	} //if
267
		                         } //if-else
268
				   	  	      } //if-else
269
				   	  	 }
270
271
				   	  	 // Build the entry
272
				   	  	 if(preg_match("/<textarea/si", $spanValue)) {
273
				   	  	 	//special case for textarea form elements (add the displayParams)
274
				   	  	 	$displayParams = array();
275
				   	  	    $displayParams['rows'] = $this->getTagAttribute("rows", $spanValue);
276
				   	  	    $displayParams['cols'] = $this->getTagAttribute("cols", $spanValue);
277
278
				   	  	    if(!empty($displayParams['rows']) && !empty($displayParams['cols'])) {
279
					   	  	    $field = array();
280
					   	  	    $field['name'] = $name;
281
								$field['displayParams'] = $displayParams;
282
				   	  	    } else {
283
				   	  	        $field = $name;
284
				   	  	    }
285
				   	  	 } else {
286
287
				   	  	 	if(isset($fields) || isset($customCode)) {
288
				   	  	 	   $field = array();
289
				   	  	 	   $field['name'] = $name;
290
				   	  	 	   if(isset($fields)) {
291
				   	  	 	   	  $field['fields'] = $fields;
292
				   	  	 	   }
293
				   	  	 	   if(isset($customCode)) {
294
				   	  	 	   	  $field['customCode'] = $customCode;
295
				   	  	 	   	  $field['description'] = 'This field was auto generated';
296
				   	  	 	   }
297
				   	  	 	} else {
298
				   	  	 	   $emptyCount = $name == '' ? $emptyCount + 1 : $emptyCount;
299
				   	  	 	   $field = $name;
300
				   	  	 	}
301
				   	  	 } //if-else if-else block
302
303
				   	  	 $addedField = is_array($field) ? $field['name'] : $field;
304
				   	  	 if(empty($addedField) || empty($addedElements[$addedField])) {
305
				   	  	 	//Add the meta-data definition for required fields
306
				   	  	 	if($hasRequiredLabel) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $hasRequiredLabel of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
307
				   	  	 	   if(is_array($field)) {
308
				   	  	 	   	  if(isset($field['displayParams']) && is_array($field['displayParams'])) {
309
				   	  	 	   	  	 $field['displayParams']['required']=true;
310
				   	  	 	   	  } else {
311
				   	  	 	   	     $field['displayParams'] = array('required'=>true);
312
				   	  	 	   	  }
313
				   	  	 	   } else {
314
				   	  	 	   	  $field = array('name'=>strtolower($field), 'displayParams'=>array('required'=>true));
315
				   	  	 	   }
316
				   	  	 	}
317
				   	  	  	$col[] = is_array($field) ? $field : strtolower($field);
318
				   	  	  	$addedElements[$addedField] = $addedField;
319
				   	  	 }
320
		   	  } //if($sugarAttValue)
321
		   } //foreach
322
323
		   // One last final check.  If $emptyCount does not equal Array $col count, don't add
324
		   if($emptyCount != count($col)) {
325
326
			   	  if($hasRequiredLabel) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $hasRequiredLabel of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
327
			   	  	 if(is_array($col)) {
328
			   	  	    if(isset($col['displayParams'])) {
329
			   	  	       $col['displayParams']['required']=true;
330
			   	  	    } else {
331
			   	  	       $col['displayParams']=array('required'=>true);
332
			   	  	    }
333
			   	  	 } else {
334
			   	  	    $col = array('name'=>strtolower($col), 'displayParams'=>array('required'=>true));
335
			   	  	 }
336
			   	  }
337
338
	   	      $metarow[] = $col;
339
		   } //if
340
	   } //foreach
341
342
	   $panels[$id] = $metarow;
343
344
   } //foreach
345
346
   $this->mCustomPanels = $panels;
347
   $panels = $this->applyPreRules($moduleDir, $panels);
348
349
   $templateMeta = array();
350
   if($merge && !empty($masterCopy) && file_exists($masterCopy)) {
351
      $panels = $this->mergePanels($panels, $vardefs, $moduleDir, $masterCopy);
352
      $templateMeta = $this->mergeTemplateMeta($templateMeta, $moduleDir, $masterCopy);
353
   }
354
   $panels = $this->applyRules($moduleDir, $panels);
355
   return $this->createFileContents($moduleDir, $panels, $templateMeta, $filePath);
356
}
357
358
359
}
360
?>