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

SugarFieldBase::SugarFieldBase()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 2
Bugs 2 Features 1
Metric Value
cc 2
eloc 7
c 2
b 2
f 1
nc 2
nop 1
dl 0
loc 10
ccs 0
cts 7
cp 0
crap 6
rs 9.4285
1
<?php
2
/*********************************************************************************
3
 * SugarCRM Community Edition is a customer relationship management program developed by
4
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5
6
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
7
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
8
 *
9
 * This program is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU Affero General Public License version 3 as published by the
11
 * Free Software Foundation with the addition of the following permission added
12
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
13
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
14
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
15
 *
16
 * This program is distributed in the hope that it will be useful, but WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
19
 * details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License along with
22
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
23
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
 * 02110-1301 USA.
25
 *
26
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
27
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
28
 *
29
 * The interactive user interfaces in modified source and object code versions
30
 * of this program must display Appropriate Legal Notices, as required under
31
 * Section 5 of the GNU Affero General Public License version 3.
32
 *
33
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
34
 * these Appropriate Legal Notices must retain the display of the "Powered by
35
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
36
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
37
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
38
 ********************************************************************************/
39
40
/**
41
 * SugarFieldBase translates and displays fields from a vardef definition into different formats
42
 * including DetailView, ListView, EditView. It also provides Search Inputs and database queries
43
 * to handle searching
44
 *
45
 */
46
class SugarFieldBase {
47
    var $ss; // Sugar Smarty Object
48
    var $hasButton = false;
49 3
    function __construct($type) {
50 3
    	$this->type = $type;
51 3
        $this->ss = new Sugar_Smarty();
52 3
    }
53
54
    /**
55
     * @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
56
     */
57
    function SugarFieldBase($type){
58
        $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code';
59
        if(isset($GLOBALS['log'])) {
60
            $GLOBALS['log']->deprecated($deprecatedMessage);
61
        }
62
        else {
63
            trigger_error($deprecatedMessage, E_USER_DEPRECATED);
64
        }
65
        self::__construct($type);
66
    }
67
68 4
    function fetch($path){
69 4
    	$additional = '';
70 4
    	if(!$this->hasButton && !empty($this->button)){
71
    		$additional .= '<input type="button" class="button" ' . $this->button . '>';
72
    	}
73 4
        if(!empty($this->buttons)){
74
            foreach($this->buttons as $v){
75
                $additional .= ' <input type="button" class="button" ' . $v . '>';
76
            }
77
78
        }
79 4
        if(!empty($this->image)){
80
            $additional .= ' <img ' . $this->image . '>';
81
        }
82 4
    	return $this->ss->fetch($path) . $additional;
83
    }
84
85 4
    function findTemplate($view){
86 4
        static $tplCache = array();
87
88 4
        if ( isset($tplCache[$this->type][$view]) ) {
89 4
            return $tplCache[$this->type][$view];
90
        }
91
92 3
        $lastClass = get_class($this);
93 3
        $classList = array($this->type,str_replace('SugarField','',$lastClass));
94 3
        while ( $lastClass = get_parent_class($lastClass) ) {
95 3
            $classList[] = str_replace('SugarField','',$lastClass);
96
        }
97
98 3
        $tplName = '';
99 3
        foreach ( $classList as $className ) {
100 3
            global $current_language;
101 3
            if(isset($current_language)) {
102 3
                $tplName = 'include/SugarFields/Fields/'. $className .'/'. $current_language . '.' . $view .'.tpl';
103 3
                if ( file_exists('custom/'.$tplName) ) {
104
                    $tplName = 'custom/'.$tplName;
105
                    break;
106
                }
107 3
                if ( file_exists($tplName) ) {
108
                    break;
109
                }
110
            }
111 3
            $tplName = 'include/SugarFields/Fields/'. $className .'/'. $view .'.tpl';
112 3
            if ( file_exists('custom/'.$tplName) ) {
113
                $tplName = 'custom/'.$tplName;
114
                break;
115
            }
116 3
            if ( file_exists($tplName) ) {
117 3
                break;
118
            }
119
        }
120
121 3
        $tplCache[$this->type][$view] = $tplName;
122
123 3
        return $tplName;
124
    }
125
126
    public function formatField($rawField, $vardef){
127
        // The base field doesn't do any formatting, so override it in subclasses for more specific actions
128
        return $rawField;
129
    }
130
131
132
    public function unformatField($formattedField, $vardef){
133
        // The base field doesn't do any formatting, so override it in subclasses for more specific actions
134
        return $formattedField;
135
    }
136
137 4
    function getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex = -1, $view){
138 4
    	$this->setup($parentFieldArray, $vardef, $displayParams, $tabindex);
139
140
141 4
    	return $this->fetch($this->findTemplate($view));
142
    }
143
144
    function getListViewSmarty($parentFieldArray, $vardef, $displayParams, $col) {
145
        $tabindex = 1;
146
        //fixing bug #46666: don't need to format enum and radioenum fields
147
        //because they are already formated in SugarBean.php in the function get_list_view_array() as fix of bug #21672
148
        if ($this->type != 'Enum' && $this->type != 'Radioenum')
149
        {
150
            $parentFieldArray = $this->setupFieldArray($parentFieldArray, $vardef);
151
        }
152
		else
153
        {
154
        	$vardef['name'] = strtoupper($vardef['name']);
155
        }
156
157
    	$this->setup($parentFieldArray, $vardef, $displayParams, $tabindex, false);
158
159
        $this->ss->left_delimiter = '{';
160
        $this->ss->right_delimiter = '}';
161
        $this->ss->assign('col',$vardef['name']);
162
163
        return $this->fetch($this->findTemplate('ListView'));
164
    }
165
166
    /**
167
     * Returns a smarty template for the DetailViews
168
     *
169
     * @param parentFieldArray string name of the variable in the parent template for the bean's data
170
     * @param vardef vardef field defintion
171
     * @param displayParam parameters for display
172
     *      available paramters are:
173
     *      * labelSpan - column span for the label
174
     *      * fieldSpan - column span for the field
175
     */
176 1
    function getDetailViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
177 1
        return $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'DetailView');
178
    }
179
180
 	// 99% of all fields will just format like a listview, but just in case, it's here to override
181
    function getChangeLogSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
182
        return $this->formatField($parentFieldArray[$vardef['name']],$vardef);
183
    }
184
185
186 3
    function getEditViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
187 3
    	if(!empty($vardef['function']['returns']) && $vardef['function']['returns'] == 'html'){
188
    		$type = $this->type;
189
    		$this->type = 'Base';
190
    		$result= $this->getDetailViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex);
191
    		$this->type = $type;
192
    		return $result;
193
    	}
194
    	// jpereira@dri - #Bug49513 - Readonly type not working as expected
195
	// If readonly is set in displayParams, the vardef will be displayed as in DetailView.
196 3
	if (isset($displayParams['readonly']) && $displayParams['readonly']) {
197
		return $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'DetailView');
198
	}
199
	// ~ jpereira@dri - #Bug49513 - Readonly type not working as expected
200 3
       return $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'EditView');
201
    }
202
203
    function getImportViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex)
204
    {
205
        return $this->getEditViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex);
206
    }
207
208
209
210 1
    function getSearchViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex) {
211 1
		if(!empty($vardef['auto_increment']))$vardef['len']=255;
212 1
    	return $this->getSmartyView($parentFieldArray, $vardef, $displayParams, $tabindex, 'EditView');
213
    }
214
215 1
    function getPopupViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex){
216 1
    	 if (is_array($displayParams) && !isset($displayParams['formName']))
217 1
		     $displayParams['formName'] = 'popup_query_form';
218
	     else if (empty($displayParams))
219
		     $displayParams = array('formName' => 'popup_query_form');
220 1
		 return $this->getSearchViewSmarty($parentFieldArray, $vardef, $displayParams, $tabindex);
221
    }
222
223
    public function getEmailTemplateValue($inputField, $vardef, $context = null){
224
        // This does not return a smarty section, instead it returns a direct value
225
        return $this->formatField($inputField,$vardef);
226
    }
227
228 4
    function displayFromFunc( $displayType, $parentFieldArray, $vardef, $displayParams, $tabindex = 0 ) {
229
230 4
        if ( ! is_array($vardef['function']) ) {
231
            $funcName = $vardef['function'];
232
            $includeFile = '';
233
            $onListView = false;
234
            $returnsHtml = false;
235
        } else {
236 4
            $funcName = $vardef['function']['name'];
237 4
            $includeFile = '';
238 4
            if ( isset($vardef['function']['include']) ) {
239 2
                $includeFile = $vardef['function']['include'];
240
            }
241 4
            if ( isset($vardef['function']['onListView']) && $vardef['function']['onListView'] == true ) {
242
                $onListView = true;
243
            } else {
244 4
                $onListView = false;
245
            }
246 4
            if ( isset($vardef['function']['returns']) && $vardef['function']['returns'] == 'html' ) {
247 4
                $returnsHtml = true;
248
            } else {
249
                $returnsHtml = false;
250
            }
251
        }
252
253 4
        if ( $displayType == 'ListView'
254 4
                || $displayType == 'popupView'
255 4
                || $displayType == 'searchView'
256
                ) {
257
            // Traditionally, before 6.0, additional functions were never called, so this code doesn't get called unless the vardef forces it
258
            if ( $onListView ) {
259
                if ( !empty($includeFile) ) {
260
                    require_once($includeFile);
261
                }
262
263
                return $funcName($parentFieldArray, $vardef['name'], $parentFieldArray[strtoupper($vardef['name'])], $displayType);
264
            } else {
265
                $displayTypeFunc = 'get'.$displayType.'Smarty';
266
                return $this->$displayTypeFunc($parentFieldArray, $vardef, $displayParams, $tabindex);
267
            }
268
        } else {
269 4
            if ( !empty($displayParams['idName']) ) {
270
                $fieldName = $displayParams['idName'];
271
            } else {
272 4
                $fieldName = $vardef['name'];
273
            }
274 4
            if ( $returnsHtml ) {
275 4
                $this->setup($parentFieldArray, $vardef, $displayParams, $tabindex);
276 4
                $tpl = $this->findTemplate($displayType.'Function');
277 4
                if ( $tpl == '' ) {
278
                    // Can't find a function template, just use the base
279
                    $tpl = $this->findTemplate('DetailViewFunction');
280
                }
281 4
                return "<span id='{$vardef['name']}_span'>" . $this->fetch($tpl) . '</span>';
282
            } else {
283
                return '{sugar_run_helper include="'.$includeFile.'" func="'.$funcName.'" bean=$bean field="'.$fieldName.'" value=$fields.'.$fieldName.'.value displayType="'.$displayType.'"}';
284
            }
285
        }
286
    }
287
288
    function getEditView() {
289
    }
290
291
    /**
292
     * getSearchWhereValue
293
     *
294
     * Checks and returns a sane value based on the field type that can be used when building the where clause in a
295
     * search form.
296
     *
297
     * @param $value Mixed value being searched on
298
     * @return Mixed the value for the where clause used in search
299
     */
300
    function getSearchWhereValue($value) {
301
        return $value;
302
    }
303
304
    /**
305
     * getSearchInput
306
     *
307
     * This function allows the SugarFields to handle returning the search input value given arguments (typically from $_REQUEST/$_POST)
308
     * and a search string.
309
     *
310
     * @param $key String value of key to search for
311
     * @param $args Mixed value containing haystack to search for value in
312
     * @return $value Mixed value that the SugarField should return
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
313
     */
314
    function getSearchInput($key='', $args=array())
315
    {
316
    	//Nothing specified return empty string
317
    	if(empty($key) || empty($args))
318
    	{
319
    		return '';
320
    	}
321
322
    	return isset($args[$key]) ? $args[$key] : '';
323
    }
324
325
    function getQueryLike() {
326
327
    }
328
329
    function getQueryIn() {
330
    }
331
332
    /**
333
     * Setup function to assign values to the smarty template, should be called before every display function
334
     */
335 4
    function setup($parentFieldArray, $vardef, $displayParams, $tabindex, $twopass=true) {
336 4
    	$this->button = '';
337 4
    	$this->buttons = '';
338 4
    	$this->image = '';
339 4
        if ($twopass)
340
        {
341 4
            $this->ss->left_delimiter = '{{';
342 4
            $this->ss->right_delimiter = '}}';
343
        }
344
        else
345
        {
346
            $this->ss->left_delimiter = '{';
347
            $this->ss->right_delimiter = '}';
348
        }
349 4
        $this->ss->assign('parentFieldArray', $parentFieldArray);
350 4
        $this->ss->assign('vardef', $vardef);
351 4
        $this->ss->assign('tabindex', $tabindex);
352
353
        //for adding attributes to the field
354
355 4
        if(!empty($displayParams['field'])){
356
        	$plusField = '';
357
        	foreach($displayParams['field'] as $key=>$value){
358
        		$plusField .= ' ' . $key . '="' . $value . '"';//bug 27381
359
        	}
360
        	$displayParams['field'] = $plusField;
361
        }
362
        //for adding attributes to the button
363 4
    	if(!empty($displayParams['button'])){
364
        	$plusField = '';
365
        	foreach($displayParams['button'] as $key=>$value){
366
        		$plusField .= ' ' . $key . '="' . $value . '"';
367
        	}
368
        	$displayParams['button'] = $plusField;
369
        	$this->button = $displayParams['button'];
370
        }
371 4
        if(!empty($displayParams['buttons'])){
372
            $plusField = '';
373
            foreach($displayParams['buttons'] as $keys=>$values){
374
                foreach($values as $key=>$value){
375
                    $plusField[$keys] .= ' ' . $key . '="' . $value . '"';
376
                }
377
            }
378
            $displayParams['buttons'] = $plusField;
379
            $this->buttons = $displayParams['buttons'];
380
        }
381 4
        if(!empty($displayParams['image'])){
382
            $plusField = '';
383
            foreach($displayParams['image'] as $key=>$value){
384
                $plusField .= ' ' . $key . '="' . $value . '"';
385
            }
386
            $displayParams['image'] = $plusField;
387
            $this->image = $displayParams['image'];
388
        }
389 4
        $this->ss->assign('displayParams', $displayParams);
390
391
392 4
    }
393
394 3
    protected function getAccessKey($vardef, $fieldType = null, $module = null) {
395 3
        global $app_strings;
396
397
        $labelList = array(
398 3
            'accessKey' => array(),
399
            'accessKeySelect' => array(),
400
            'accessKeyClear' => array(),
401
        );
402
403
        // Labels are always in uppercase
404 3
        if ( isset($fieldType) ) {
405 3
            $fieldType = strtoupper($fieldType);
406
        }
407
408 3
        if ( isset($module) ) {
409 3
            $module = strtoupper($module);
410
        }
411
412
        // The vardef is the most specific, then the module + fieldType, then the module, then the fieldType
413 3
        if ( isset($vardef['accessKey']) ) {
414
            $labelList['accessKey'][] = $vardef['accessKey'];
415
        }
416 3
        if ( isset($vardef['accessKeySelect']) ) {
417
            $labelList['accessKeySelect'][] = $vardef['accessKeySelect'];
418
        }
419 3
        if ( isset($vardef['accessKeyClear']) ) {
420
            $labelList['accessKeyClear'][] = $vardef['accessKeyClear'];
421
        }
422
423 3
        if ( isset($fieldType) && isset($module) ) {
424 3
            $labelList['accessKey'][] = 'LBL_ACCESSKEY_'.$fieldType.'_'.$module;
425 3
            $labelList['accessKeySelect'][] = 'LBL_ACCESSKEY_SELECT_'.$fieldType.'_'.$module;
426 3
            $labelList['accessKeyClear'][] = 'LBL_ACCESSKEY_CLEAR_'.$fieldType.'_'.$module;
427
        }
428
429 3
        if ( isset($module) ) {
430 3
            $labelList['accessKey'][] = 'LBL_ACCESSKEY_'.$module;
431 3
            $labelList['accessKeySelect'][] = 'LBL_ACCESSKEY_SELECT_'.$module;
432 3
            $labelList['accessKeyClear'][] = 'LBL_ACCESSKEY_CLEAR_'.$module;
433
        }
434
435 3
        if ( isset($fieldType) ) {
436 3
            $labelList['accessKey'][] = 'LBL_ACCESSKEY_'.$fieldType;
437 3
            $labelList['accessKeySelect'][] = 'LBL_ACCESSKEY_SELECT_'.$fieldType;
438 3
            $labelList['accessKeyClear'][] = 'LBL_ACCESSKEY_CLEAR_'.$fieldType;
439
        }
440
441
        // Attach the defaults to the ends
442 3
        $labelList['accessKey'][] = 'LBL_ACCESSKEY';
443 3
        $labelList['accessKeySelect'][] = 'LBL_SELECT_BUTTON';
444 3
        $labelList['accessKeyClear'][] = 'LBL_CLEAR_BUTTON';
445
446
        // Figure out the label and the key for the button.
447
        // Later on we may attempt to make sure there are no two buttons with the same keys, but for now we will just use whatever is specified.
448 3
        $keyTypes = array('accessKey','accessKeySelect','accessKeyClear');
449
        $accessKeyList = array(
450 3
            'accessKey' => '',
451
            'accessKeyLabel' => '',
452
            'accessKeyTitle' => '',
453
            'accessKeySelect' => '',
454
            'accessKeySelectLabel' => '',
455
            'accessKeySelectTitle' => '',
456
            'accessKeyClear' => '',
457
            'accessKeyClearLabel' => '',
458
            'accessKeyClearTitle' => '',
459
        );
460 3
        foreach( $keyTypes as $type ) {
461 3
            foreach ( $labelList[$type] as $tryThis ) {
462 3
                if ( isset($app_strings[$tryThis.'_KEY']) && isset($app_strings[$tryThis.'_TITLE']) && isset($app_strings[$tryThis.'_LABEL']) ) {
463 3
                    $accessKeyList[$type] = $tryThis.'_KEY';
464 3
                    $accessKeyList[$type.'Title'] = $tryThis.'_TITLE';
465 3
                    $accessKeyList[$type.'Label'] = $tryThis.'_LABEL';
466 3
                    break;
467
                }
468
            }
469
        }
470
471 3
        return $accessKeyList;
472
    }
473
474
	/**
475
     * This should be called when the bean is saved. The bean itself will be passed by reference
476
     * @param SugarBean bean - the bean performing the save
477
     * @param array params - an array of paramester relevant to the save, most likely will be $_REQUEST
478
     */
479 1
    public function save(&$bean, $params, $field, $properties, $prefix = '') {
480 1
         if ( isset($params[$prefix.$field]) ) {
481
             if(isset($properties['len']) && isset($properties['type']) && $this->isTrimmable($properties['type'])){
482
                 $bean->$field = trim($this->unformatField($params[$prefix.$field], $properties));
483
             }
484
             else {
485
                 $bean->$field = $this->unformatField($params[$prefix.$field], $properties);
486
         	 }
487
         }
488 1
     }
489
490
     /**
491
      * Check if the field is allowed to be trimmed
492
      *
493
      * @param string $type
494
      * @return boolean
495
      */
496
     protected function isTrimmable($type) {
497
         return in_array($type, array('varchar', 'name'));
498
     }
499
500
    /**
501
     * Handles import field sanitizing for an field type
502
     *
503
     * @param  $value    string value to be sanitized
504
     * @param  $vardefs  array
505
     * @param  $focus    SugarBean object
506
     * @param  $settings ImportFieldSanitize object
507
     * @return string sanitized value or boolean false if there's a problem with the value
508
     */
509
    public function importSanitize(
510
        $value,
511
        $vardef,
512
        $focus,
513
        ImportFieldSanitize $settings
514
        )
515
    {
516
        if( isset($vardef['len']) ) {
517
            // check for field length
518
            $value = sugar_substr($value, $vardef['len']);
519
        }
520
521
        return $value;
522
    }
523
524
    /**
525
     * isRangeSearchView
526
     * This method helps determine whether or not to display the range search view code for the sugar field
527
     * @param array $vardef entry representing the sugar field's definition
528
     * @return boolean true if range search view should be displayed, false otherwise
529
     */
530
    protected function isRangeSearchView($vardef)
531
    {
532
     	return !empty($vardef['enable_range_search']) && !empty($_REQUEST['action']) && $_REQUEST['action']!='Popup';
533
    }
534
535
    /**
536
     * setupFieldArray
537
     * This method takes the $parentFieldArray mixed variable which may be an Array or object and attempts
538
     * to call any custom fieldSpecific formatting to the value depending on the field type.
539
     *
540
     * @see SugarFieldEnum.php, SugarFieldInt.php, SugarFieldFloat.php, SugarFieldRelate.php
541
     * @param	mixed	$parentFieldArray Array or Object of data where the field's value comes from
542
     * @param	array	$vardef The vardef entry linked to the SugarField instance
543
     * @return	array   $parentFieldArray The formatted $parentFieldArray with the formatField method possibly applied
544
     */
545
    protected function setupFieldArray($parentFieldArray, $vardef)
546
    {
547
        $fieldName = $vardef['name'];
548
        if ( is_array($parentFieldArray) )
549
        {
550
            $fieldNameUpper = strtoupper($fieldName);
551
            if ( isset($parentFieldArray[$fieldNameUpper]))
552
            {
553
                $parentFieldArray[$fieldName] = $this->formatField($parentFieldArray[$fieldNameUpper],$vardef);
554
            } else {
555
                $parentFieldArray[$fieldName] = '';
556
            }
557
        } elseif (is_object($parentFieldArray)) {
558
            if ( isset($parentFieldArray->$fieldName) )
559
            {
560
                $parentFieldArray->$fieldName = $this->formatField($parentFieldArray->$fieldName,$vardef);
561
            } else {
562
                $parentFieldArray->$fieldName = '';
563
            }
564
        }
565
        return $parentFieldArray;
566
    }
567
568
}
569
?>
570