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