Test Failed
Push — CI ( 0f01dd...c95a04 )
by Adam
55:13
created

GridLayoutMetaDataParser::_populateFromRequest()   F

Complexity

Conditions 21
Paths 2688

Size

Total Lines 115
Code Lines 48

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 115
rs 2
cc 21
eloc 48
nc 2688
nop 1

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)
3
    die ( 'Not A Valid Entry Point' ) ;
4
/*********************************************************************************
5
 * SugarCRM Community Edition is a customer relationship management program developed by
6
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
7
8
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
9
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
10
 *
11
 * This program is free software; you can redistribute it and/or modify it under
12
 * the terms of the GNU Affero General Public License version 3 as published by the
13
 * Free Software Foundation with the addition of the following permission added
14
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
15
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
16
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
17
 *
18
 * This program is distributed in the hope that it will be useful, but WITHOUT
19
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
21
 * details.
22
 *
23
 * You should have received a copy of the GNU Affero General Public License along with
24
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
25
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26
 * 02110-1301 USA.
27
 *
28
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
29
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
30
 *
31
 * The interactive user interfaces in modified source and object code versions
32
 * of this program must display Appropriate Legal Notices, as required under
33
 * Section 5 of the GNU Affero General Public License version 3.
34
 *
35
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
36
 * these Appropriate Legal Notices must retain the display of the "Powered by
37
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
38
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
39
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
40
 ********************************************************************************/
41
42
43
require_once 'modules/ModuleBuilder/parsers/views/AbstractMetaDataParser.php' ;
44
require_once 'modules/ModuleBuilder/parsers/views/MetaDataParserInterface.php' ;
45
require_once 'modules/ModuleBuilder/parsers/constants.php' ;
46
47
class GridLayoutMetaDataParser extends AbstractMetaDataParser implements MetaDataParserInterface
48
{
49
50
    static $variableMap = array (
51
    	MB_EDITVIEW => 'EditView' ,
52
    	MB_DETAILVIEW => 'DetailView' ,
53
    	MB_QUICKCREATE => 'QuickCreate',
54
    	) ;
55
56
	protected $FILLER ;
57
58
    /*
59
     * Constructor
60
     * @param string view           The view type, that is, editview, searchview etc
61
     * @param string moduleName     The name of the module to which this view belongs
62
     * @param string packageName    If not empty, the name of the package to which this view belongs
63
     */
64
    function __construct ($view , $moduleName , $packageName = '')
65
    {
66
        $GLOBALS [ 'log' ]->debug ( get_class ( $this ) . "->__construct( {$view} , {$moduleName} , {$packageName} )" ) ;
67
68
        $view = strtolower ( $view ) ;
69
70
		$this->FILLER = array ( 'name' => MBConstants::$FILLER['name'] , 'label' => translate ( MBConstants::$FILLER['label'] ) ) ;
71
72
        $this->_moduleName = $moduleName ;
73
        $this->_view = $view ;
74
75
        if (empty ( $packageName ))
76
        {
77
            require_once 'modules/ModuleBuilder/parsers/views/DeployedMetaDataImplementation.php' ;
78
            $this->implementation = new DeployedMetaDataImplementation ( $view, $moduleName, self::$variableMap ) ;
0 ignored issues
show
Unused Code introduced by
The call to DeployedMetaDataImplementation::__construct() has too many arguments starting with self::$variableMap.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
79
        } else
80
        {
81
            require_once 'modules/ModuleBuilder/parsers/views/UndeployedMetaDataImplementation.php' ;
82
            $this->implementation = new UndeployedMetaDataImplementation ( $view, $moduleName, $packageName ) ;
83
        }
84
85
        $viewdefs = $this->implementation->getViewdefs () ;
86
        if (!isset(self::$variableMap [ $view ]))
87
            self::$variableMap [ $view ] = $view;
88
89
        if (!isset($viewdefs [ self::$variableMap [ $view ]])){
90
            sugar_die ( get_class ( $this ) . ": incorrect view variable for $view" ) ;
91
        }
92
93
        $viewdefs = $viewdefs [ self::$variableMap [ $view ] ] ;
94
        if (! isset ( $viewdefs [ 'templateMeta' ] ))
95
            sugar_die ( get_class ( $this ) . ": missing templateMeta section in layout definition (case sensitive)" ) ;
96
97
        if (! isset ( $viewdefs [ 'panels' ] ))
98
            sugar_die ( get_class ( $this ) . ": missing panels section in layout definition (case sensitive)" ) ;
99
100
        $this->_viewdefs = $viewdefs ;
101
        if ($this->getMaxColumns () < 1)
102
            sugar_die ( get_class ( $this ) . ": maxColumns=" . $this->getMaxColumns () . " - must be greater than 0!" ) ;
103
104
        $this->_fielddefs =  $this->implementation->getFielddefs() ;
105
        $this->_standardizeFieldLabels( $this->_fielddefs );
106
        $this->_viewdefs [ 'panels' ] = $this->_convertFromCanonicalForm ( $this->_viewdefs [ 'panels' ] , $this->_fielddefs ) ; // put into our internal format
107
        $this->_originalViewDef = $this->getFieldsFromLayout($this->implementation->getOriginalViewdefs ());
108
    }
109
110
    /*
111
     * Save a draft layout
112
     */
113
    function writeWorkingFile ($populate = true)
114
    {
115
        if ($populate)
116
            $this->_populateFromRequest ( $this->_fielddefs ) ;
117
        
118
        $viewdefs = $this->_viewdefs ;
119
        $viewdefs [ 'panels' ] = $this->_convertToCanonicalForm ( $this->_viewdefs [ 'panels' ] , $this->_fielddefs ) ;
120
        $this->implementation->save ( array ( self::$variableMap [ $this->_view ] => $viewdefs ) ) ;
0 ignored issues
show
Bug introduced by
The method save does only exist in DeployedMetaDataImplementation, but not in DeployedSubpanelImplemen...dSubpanelImplementation.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
121
    }
122
123
    /*
124
     * Deploy the layout
125
     * @param boolean $populate If true (default), then update the layout first with new layout information from the $_REQUEST array
126
     */
127
    function handleSave ($populate = true)
128
    {
129
    	$GLOBALS [ 'log' ]->info ( get_class ( $this ) . "->handleSave()" ) ;
130
131
        if ($populate)
132
            $this->_populateFromRequest ( $this->_fielddefs ) ;
133
134
        $viewdefs = $this->_viewdefs ;
135
        $viewdefs [ 'panels' ] = $this->_convertToCanonicalForm ( $this->_viewdefs [ 'panels' ] , $this->_fielddefs ) ;
136
        $this->implementation->deploy ( array ( self::$variableMap [ $this->_view ] => $viewdefs ) ) ;
137
    }
138
139
    /*
140
     * Return the layout, padded out with (empty) and (filler) fields ready for display
141
     */
142
    function getLayout ()
143
    {
144
    	$viewdefs = array () ;
145
    	$fielddefs = $this->_fielddefs;
146
    	$fielddefs [ $this->FILLER [ 'name' ] ] = $this->FILLER ;
147
    	$fielddefs [ MBConstants::$EMPTY [ 'name' ] ] = MBConstants::$EMPTY ;
148
    	
149
		foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel )
150
        {
151
            foreach ( $panel as $rowID => $row )
152
            {
153
                foreach ( $row as $colID => $fieldname )
154
                {
155
                	if (isset ($this->_fielddefs [ $fieldname ]))
156
					{
157
						$viewdefs [ $panelID ] [ $rowID ] [ $colID ] = self::_trimFieldDefs( $this->_fielddefs [ $fieldname ] ) ;
158
					} 
159
					else if (isset($this->_originalViewDef [ $fieldname ]) && is_array($this->_originalViewDef [ $fieldname ]))
160
					{
161
						$viewdefs [ $panelID ] [ $rowID ] [ $colID ] = self::_trimFieldDefs( $this->_originalViewDef [ $fieldname ] ) ;
162
					} 
163
					else 
164
					{
165
						$viewdefs [ $panelID ] [ $rowID ] [ $colID ] = array("name" => $fieldname, "label" => $fieldname);
166
					}
167
                }
168
            }
169
        }
170
        return $viewdefs ;
171
    }
172
173
    /*
174
    * Return the tab definitions for tab/panel combo
175
    */
176
    function getTabDefs ()
177
    {
178
      $tabDefs = array();
179
      $this->setUseTabs( false );
180
      foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel )
181
      {
182
183
        $tabDefs [ strtoupper($panelID) ] = array();
184
185
        // panel or tab setting
186
        if ( isset($this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'newTab' ])
187
        && is_bool($this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'newTab' ]))
188
        {
189
          $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = $this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'newTab' ];
190
          if ($tabDefs [ strtoupper($panelID) ] [ 'newTab' ] == true)
191
              $this->setUseTabs( true );
192
        }
193
        else
194
        {
195
          $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = false;
196
        }
197
198
        // collapsed panels
199
        if ( isset($this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'panelDefault' ])
200
        && $this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] [ strtoupper($panelID) ] [ 'panelDefault' ] == 'collapsed' )
201
        {
202
          $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = 'collapsed';
203
        }
204
        else
205
        {
206
          $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = 'expanded';
207
        }
208
      }
209
      return $tabDefs;
210
    }
211
212
    /*
213
     * Set tab definitions
214
     */
215
    function setTabDefs($tabDefs) {
216
      $this->_viewdefs [ 'templateMeta' ] [ 'tabDefs' ] = $tabDefs;
217
    }
218
219
    function getMaxColumns ()
220
    {
221
        if (!empty( $this->_viewdefs) && isset($this->_viewdefs [ 'templateMeta' ] [ 'maxColumns' ]))
222
		{
223
			return $this->_viewdefs [ 'templateMeta' ] [ 'maxColumns' ] ;
224
		}else
225
		{
226
			return 2;
227
		}
228
    }
229
230
    function getAvailableFields ()
231
    {
232
233
    	// Obtain the full list of valid fields in this module
234
    	$availableFields = array () ;
235
        foreach ( $this->_fielddefs as $key => $def )
236
        {
237
            if ( GridLayoutMetaDataParser::validField ( $def,  $this->_view ) || isset($this->_originalViewDef[$key]) )
238
            {
239
                //If the field original label existing, we should use the original label instead the label in its fielddefs.
240
            	if(isset($this->_originalViewDef[$key]) && is_array($this->_originalViewDef[$key]) && isset($this->_originalViewDef[$key]['label'])){
241
                    $availableFields [ $key ] = array ( 'name' => $key , 'label' => $this->_originalViewDef[$key]['label']) ; 
242
                }else{
243
                    $availableFields [ $key ] = array ( 'name' => $key , 'label' => isset($def [ 'label' ]) ? $def [ 'label' ] : $def['vname'] ) ; // layouts use 'label' not 'vname' for the label entry
244
                }
245
246
                $availableFields[$key]['translatedLabel'] = translate( isset($def [ 'label' ]) ? $def [ 'label' ] : $def['vname'], $this->_moduleName);
247
            }
248
			
249
        }
250
251
		// Available fields are those that are in the Model and the original layout definition, but not already shown in the View
252
        // So, because the formats of the two are different we brute force loop through View and unset the fields we find in a copy of Model
253
        if (! empty ( $this->_viewdefs ))
254
        {
255
            foreach ( $this->_viewdefs [ 'panels' ] as $panel )
256
            {
257
                foreach ( $panel as $row )
258
                {
259
                    foreach ( $row as $field )
260
                    {
261
                    	unset ( $availableFields [ $field ] ) ;
262
                    }
263
                }
264
            }
265
        }
266
        
267
        //eggsurplus: Bug 10329 - sort on intuitive display labels
268
        //sort by translatedLabel
269
        function cmpLabel($a, $b) 
270
        {
271
            return strcmp($a["translatedLabel"], $b["translatedLabel"]);
272
        }
273
        usort($availableFields , 'cmpLabel');
274
275
        return $availableFields ;
276
    }
277
278
    function getPanelDependency ( $panelID )
279
    {
280
    	if ( ! isset ( $this->_viewdefs [ 'templateMeta' ][ 'dependency' ] ) && ! isset ( $this->_viewdefs [ 'templateMeta' ][ 'dependency' ] [ $panelID ] ) )
281
    		return false;
282
283
    	return $this->_viewdefs  [ 'templateMeta' ][ 'dependency' ] [ $panelID ] ;
284
    }
285
286
    /*
287
     * Add a new field to the layout
288
     * If $panelID is passed in, attempt to add to that panel, otherwise add to the first panel
289
     * The field is added in place of the first empty (not filler) slot after the last field in the panel; if that row is full, then a new row will be added to the end of the panel
290
     * and the field added to the start of it.
291
     * @param array $def Set of properties for the field, in same format as in the viewdefs
292
     * @param string $panelID Identifier of the panel to add the field to; empty or false if we should use the first panel
293
     */
294
    function addField ( $def , $panelID = FALSE)
295
    {
296
297
        if (count ( $this->_viewdefs [ 'panels' ] ) == 0)
298
        {
299
            $GLOBALS [ 'log' ]->error ( get_class ( $this ) . "->addField(): _viewdefs empty for module {$this->_moduleName} and view {$this->_view}" ) ;
300
        }
301
302
        // if a panelID was not provided, use the first available panel in the list
303
        if (! $panelID)
304
        {
305
            $panels = array_keys ( $this->_viewdefs [ 'panels' ] ) ;
306
            list ( $dummy, $panelID ) = each ( $panels ) ;
0 ignored issues
show
Unused Code introduced by
The assignment to $dummy is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
307
        }
308
309
        if (isset ( $this->_viewdefs [ 'panels' ] [ $panelID ] ))
310
        {
311
312
            $panel = $this->_viewdefs [ 'panels' ] [ $panelID ] ;
313
            $lastrow = count ( $panel ) - 1 ; // index starts at 0
314
            $maxColumns = $this->getMaxColumns () ;
315
            $lastRowDef = $this->_viewdefs [ 'panels' ] [ $panelID ] [ $lastrow ];
316
            for ( $column = 0 ; $column < $maxColumns ; $column ++ )
317
            {
318
                if (! isset ( $lastRowDef [ $column ] )
319
                        || (is_array( $lastRowDef [ $column ]) && $lastRowDef [ $column ][ 'name' ] == '(empty)')
320
                        || (is_string( $lastRowDef [ $column ]) && $lastRowDef [ $column ] == '(empty)')
321
                ){
322
                    break ;
323
                }
324
            }
325
326
            // if we're on the last column of the last row, start a new row
327
            if ($column >= $maxColumns)
328
            {
329
                $lastrow ++ ;
330
                $this->_viewdefs [ 'panels' ] [ $panelID ] [ $lastrow ] = array ( ) ;
331
                $column = 0 ;
332
            }
333
334
            $this->_viewdefs [ 'panels' ] [ $panelID ] [ $lastrow ] [ $column ] = $def [ 'name' ] ;
335
            // now update the fielddefs
336
            if (isset($this->_fielddefs [ $def [ 'name' ] ]))
337
            {
338
                $this->_fielddefs [ $def [ 'name' ] ] = array_merge ( $this->_fielddefs [ $def [ 'name' ] ] , $def ) ;
339
            } else
340
            {
341
            	$this->_fielddefs [ $def [ 'name' ] ] = $def;
342
            }
343
        }
344
        return true ;
345
    }
346
347
    /*
348
     * Remove all instances of a field from the layout, and replace by (filler)
349
     * Filler because we attempt to preserve the customized layout as much as possible - replacing by (empty) would mean that the positions or sizes of adjacent fields may change
350
     * If the last row of a panel only consists of (filler) after removing the fields, then remove the row also. This undoes the standard addField() scenario;
351
     * If the fields had been moved around in the layout however then this will not completely undo any addField()
352
     * @param string $fieldName Name of the field to remove
353
     * @return boolean True if the field was removed; false otherwise
354
     */
355
    function removeField ($fieldName)
356
    {
357
        $GLOBALS [ 'log' ]->info ( get_class ( $this ) . "->removeField($fieldName)" ) ;
358
359
        $result = false ;
360
        reset ( $this->_viewdefs ) ;
361
        $firstPanel = each ( $this->_viewdefs [ 'panels' ] ) ;
362
        $firstPanelID = $firstPanel [ 'key' ] ;
363
364
        foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel )
365
        {
366
            $lastRowTouched = false ;
367
            $lastRowID = count ( $this->_viewdefs [ 'panels' ] [ $panelID ] ) - 1 ; // zero offset
368
369
            foreach ( $panel as $rowID => $row )
370
            {
371
372
                foreach ( $row as $colID => $field )
373
                    if ($field == $fieldName)
374
                    {
375
                        $lastRowTouched = $rowID ;
376
                        $this->_viewdefs [ 'panels' ] [ $panelID ] [ $rowID ] [ $colID ] = $this->FILLER [ 'name' ];
377
                    }
378
379
            }
380
381
            // if we removed a field from the last row of this panel, tidy up if the last row now consists only of (empty) or (filler)
382
383
            if ( $lastRowTouched ==  $lastRowID )
384
            {
385
                $lastRow = $this->_viewdefs [ 'panels' ] [ $panelID ] [ $lastRowID ] ; // can't use 'end' for this as we need the key as well as the value...
386
387
                $empty = true ;
388
389
                foreach ( $lastRow as $colID => $field )
390
                    $empty &=  $field == MBConstants::$EMPTY ['name' ] || $field == $this->FILLER [ 'name' ]  ;
391
392
                if ($empty)
393
                {
394
                    unset ( $this->_viewdefs [ 'panels' ] [ $panelID ] [ $lastRowID ] ) ;
395
                    // if the row was the only one in the panel, and the panel is not the first (default) panel, then remove the panel also
396
					if ( count ( $this->_viewdefs [ 'panels' ] [ $panelID ] ) == 0 && $panelID != $firstPanelID )
397
						unset ( $this->_viewdefs [ 'panels' ] [ $panelID ] ) ;
398
                }
399
400
            }
401
402
            $result |= ($lastRowTouched !== false ); // explicitly compare to false as row 0 will otherwise evaluate as false
403
        }
404
405
        return $result ;
406
407
    }
408
409
    function setPanelDependency ( $panelID , $dependency )
410
    {
411
    	// only accept dependencies for pre-existing panels
412
    	if ( ! isset ( $this->_viewdefs [ 'panels' ] [ $panelID ] ) )
413
    		return false;
414
415
    	$this->_viewdefs  [ 'templateMeta' ] [ 'dependency' ] [ $panelID ] = $dependency ;
416
    	return true ;
417
    }
418
419
    /*
420
     * Return an integer value for the next unused panel identifier, such that it and any larger numbers are guaranteed to be unused already in the layout
421
     * Necessary when adding new panels to a layout
422
     * @return integer First unique panel ID suffix
423
     */
424
    function getFirstNewPanelId ()
425
    {
426
        $firstNewPanelId = 0 ;
427
        foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel )
428
        {
429
            // strip out all but the numerics from the panelID - can't just use a cast as numbers may not be first in the string
430
            for ( $i = 0, $result = '' ; $i < strlen ( $panelID ) ; $i ++ )
431
            {
432
                if (is_numeric ( $panelID [ $i ] ))
433
                {
434
                    $result .= $panelID [ $i ] ;
435
                }
436
            }
437
438
            $firstNewPanelId = max ( ( int ) $result, $firstNewPanelId ) ;
439
        }
440
        return $firstNewPanelId + 1 ;
441
    }
442
443
    /*
444
     * Load the panel layout from the submitted form and update the _viewdefs
445
     */
446
    protected function _populateFromRequest ( &$fielddefs )
447
    {
448
        $GLOBALS [ 'log' ]->debug ( get_class ( $this ) . "->populateFromRequest()" ) ;
449
        $i = 1 ;
450
451
        // set up the map of panel# (as provided in the _REQUEST) to panel ID (as used in $this->_viewdefs['panels'])
452
        $i = 1 ;
453
        foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel )
454
        {
455
            $panelMap [ $i ++ ] = $panelID ;
456
        }
457
458
        foreach ( $_REQUEST as $key => $displayLabel )
459
        {
460
            $components = explode ( '-', $key ) ;
461
            if ($components [ 0 ] == 'panel' && $components [ 2 ] == 'label')
462
            {
463
                $panelMap [ $components [ '1' ] ] = $displayLabel ;
464
            }
465
        }
466
467
        $this->_viewdefs [ 'panels' ] = array () ; // because the new field properties should replace the old fields, not be merged
468
469
        // run through the $_REQUEST twice - first to obtain the fieldnames, the second to update the field properties
470
        for ( $pass=1 ; $pass<=2 ; $pass++ )
471
        {
472
        	foreach ( $_REQUEST as $slot => $value )
473
        	{
474
            	$slotComponents = explode ( '-', $slot ) ; // [0] = 'slot', [1] = panel #, [2] = slot #, [3] = property name
475
476
            	if ($slotComponents [ 0 ] == 'slot')
477
            	{
478
                	$slotNumber = $slotComponents [ '2' ] ;
479
                	$panelID = $panelMap [ $slotComponents [ '1' ] ] ;
480
                	$rowID = floor ( $slotNumber / $this->getMaxColumns () ) ;
481
                	$colID = $slotNumber - ($rowID * $this->getMaxColumns ()) ;
482
                	$property = $slotComponents [ '3' ] ;
483
484
                	//If this field has a custom definition, copy that over
485
                	if ( $pass == 1 )
486
                	{
487
                		if ( $property == 'name' )
488
                    		$this->_viewdefs [ 'panels' ] [ $panelID ] [ $rowID ] [ $colID ] = $value ;
489
                	} else
490
                	{
491
                		// update fielddefs for this property in the provided position
492
                		if ( isset ( $this->_viewdefs [ 'panels' ] [ $panelID ] [ $rowID ] [ $colID ] ) )
493
                		{
494
                			$fieldname = $this->_viewdefs [ 'panels' ] [ $panelID ] [ $rowID ] [ $colID ] ;
495
							$fielddefs [ $fieldname ] [ $property ] = $value ;
496
                		}
497
                	}
498
            	}
499
500
        	}
501
        }
502
503
/*
504
        //Set the tabs setting
505
        if (isset($_REQUEST['panels_as_tabs']))
506
        {
507
        	if ($_REQUEST['panels_as_tabs'] == false || $_REQUEST['panels_as_tabs'] == "false")
508
        	   $this->setUseTabs( false );
509
        	else
510
        	   $this->setUseTabs( true );
511
        }
512
*/
513
514
        //Set the tab definitions
515
        $tabDefs = array();
516
        $this->setUseTabs( false );
517
        foreach ( $this->_viewdefs [ 'panels' ] as $panelID => $panel )
518
        {
519
          // panel or tab setting
520
          $tabDefs [ strtoupper($panelID) ] = array();
521
          if ( isset($_REQUEST['tabDefs_'.$panelID.'_newTab']) )
522
          {
523
            $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = ( $_REQUEST['tabDefs_'.$panelID.'_newTab'] == '1' ) ? true : false;
524
            if ($tabDefs [ strtoupper($panelID) ] [ 'newTab' ] == true)
525
                $this->setUseTabs( true );
526
          }
527
          else
528
          {
529
            $tabDefs [ strtoupper($panelID) ] [ 'newTab' ] = false;
530
          }
531
532
          // collapse panel
533
          if ( isset($_REQUEST['tabDefs_'.$panelID.'_panelDefault']) )
534
          {
535
            $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = ( $_REQUEST['tabDefs_'.$panelID.'_panelDefault'] == 'collapsed' ) ? 'collapsed' : 'expanded';
536
          }
537
          else
538
          {
539
            $tabDefs [ strtoupper($panelID) ] [ 'panelDefault' ] = 'expanded';
540
          }
541
542
        }
543
        $this->setTabDefs($tabDefs);
544
545
    	//bug: 38232 - Set the sync detail and editview settings
546
        if (isset($_REQUEST['sync_detail_and_edit']))
547
        {
548
        	if ($_REQUEST['sync_detail_and_edit'] === false || $_REQUEST['sync_detail_and_edit'] === "false")
549
            {
550
        	   $this->setSyncDetailEditViews( false );
551
            }
552
            elseif(!empty($_REQUEST['sync_detail_and_edit']))
553
            {
554
        	   $this->setSyncDetailEditViews( true );
555
            }
556
        }
557
558
        $GLOBALS [ 'log' ]->debug ( print_r ( $this->_viewdefs [ 'panels' ], true ) ) ;
559
560
    }
561
562
    /*  Convert our internal format back to the standard Canonical MetaData layout
563
     *  First non-(empty) field goes in at column 0; all other (empty)'s removed
564
     *  Studio required fields are also added to the layout.
565
     *  Do this AFTER reading in all the $_REQUEST parameters as can't guarantee the order of those, and we need to operate on complete rows
566
     */
567
    protected function _convertToCanonicalForm ( $panels , $fielddefs )
568
    {
569
        $previousViewDef = $this->getFieldsFromLayout($this->implementation->getViewdefs ());
570
        $oldDefs = $this->implementation->getViewdefs ();
571
        $currentFields = $this->getFieldsFromLayout($this->_viewdefs);
572
        foreach($fielddefs as $field => $def)
573
        {
574
        	if (self::fieldIsRequired($def) && !isset($currentFields[$field]))
575
        	{
576
                //Use the previous viewdef if this field was on it.
577
                if (isset($previousViewDef[$field]))
578
                {
579
                    $def = $previousViewDef[$field];
580
                }
581
                //next see if the field was on the original layout.
582
                else if (isset ($this->_originalViewDef [ $field ]))
583
                {
584
                    $def = $this->_originalViewDef [ $field ] ;   
585
                }
586
                //Otherwise make up a viewdef for it from field_defs
587
                else
588
                {
589
                    $def =  self::_trimFieldDefs( $def ) ;
590
                }
591
                $this->addField($def);
592
        	}
593
        }
594
        
595
        foreach ( $panels as $panelID => $panel )
596
        {
597
            // remove all (empty)s
598
            foreach ( $panel as $rowID => $row )
599
            {
600
                $startOfRow = true ;
601
                $offset = 0 ;
602
                foreach ( $row as $colID => $fieldname )
603
                {
604
                    if ($fieldname == MBConstants::$EMPTY[ 'name' ])
605
                    {
606
                        // if a leading (empty) then remove (by noting that remaining fields need to be shuffled along)
607
                        if ($startOfRow)
608
                        {
609
                            $offset ++ ;
610
                        }
611
                        unset ( $row [ $colID ] ) ;
612
                    } else
613
                    {
614
                        $startOfRow = false ;
615
                    }
616
                }
617
618
                // reindex to remove leading (empty)s and replace fieldnames by full definition from fielddefs
619
                $newRow = array ( ) ;
620
                foreach ( $row as $colID => $fieldname )
621
                {
622
                	if ($fieldname == null )
623
                	   continue;
624
                    //Backwards compatibility and a safeguard against multiple calls to _convertToCanonicalForm
625
                    if(is_array($fieldname))
626
                    {
627
628
                    	$newRow [ $colID - $offset ] = $fieldname;
629
                    	continue;
630
                    }else if(!isset($fielddefs[$fieldname])){
631
                       continue;
632
                     }
633
634
                	//Replace (filler) with the empty string
635
                	if ($fieldname == $this->FILLER[ 'name' ]) {
636
                        $newRow [ $colID - $offset ] = '' ;
637
                    }
638
                    //Use the previous viewdef if this field was on it.
639
					else if (isset($previousViewDef[$fieldname]))
640
                	{
641
                        $newRow[$colID - $offset] = $this->getNewRowItem($previousViewDef[$fieldname], $fielddefs[$fieldname]);
642
                	}
643
                    //next see if the field was on the original layout.
644
                    else if (isset ($this->_originalViewDef [ $fieldname ]))
645
                    {
646
                        $newRow[$colID - $offset] = $this->getNewRowItem($this->_originalViewDef[$fieldname], $fielddefs[$fieldname]);  
647
                    }
648
                	//Otherwise make up a viewdef for it from field_defs
649
                	else if (isset ($fielddefs [ $fieldname ]))
650
                	{
651
                		$newRow [ $colID - $offset ] =  self::_trimFieldDefs( $fielddefs [ $fieldname ] ) ;
652
                		
653
                	}
654
                	//No additional info on this field can be found, jsut use the name;
655
                	else 
656
                	{
657
                        $newRow [ $colID - $offset ] = $fieldname;
658
                	}
659
                }
660
                $panels [ $panelID ] [ $rowID ] = $newRow ;
661
            }
662
        }
663
        
664
        return $panels ;
665
    }
666
667
    /*
668
     * fixing bug #44428: Studio | Tab Order causes layout errors
669
     * @param string|array $source it can be a string which contain just a name of field 
670
     *                                  or an array with field attributes including name
671
     * @param array $fielddef stores field defs from request
672
     * @return string|array definition of new row item
673
     */
674
    function getNewRowItem($source, $fielddef)
675
    {
676
        //We should copy over the tabindex if it is set.
677
        $newRow = array();
678
        if (isset ($fielddef) && !empty($fielddef['tabindex']))
679
        {
680
            if (is_array($source))
681
            {
682
                $newRow = $source;
683
            }
684
            else
685
            {
686
                $newRow['name'] = $source;
687
            }
688
            $newRow['tabindex'] = $fielddef['tabindex'];
689
        }
690
        else
691
        {
692
            $newRow = $source;
693
        }
694
        return $newRow;
695
    }
696
697
    /*
698
     * Convert from the standard MetaData format to our internal format
699
     * Replace NULL with (filler) and missing entries with (empty)
700
     */
701
    protected function _convertFromCanonicalForm ( $panels , $fielddefs )
702
    {
703
        if (empty ( $panels ))
704
            return ;
705
706
        // Fix for a flexibility in the format of the panel sections - if only one panel, then we don't have a panel level defined,
707
		// it goes straight into rows
708
        // See EditView2 for similar treatment
709
        if (! empty ( $panels ) && count ( $panels ) > 0)
710
        {
711
            $keys = array_keys ( $panels ) ;
712
            if (is_numeric ( $keys [ 0 ] ))
713
            {
714
                $defaultPanel = $panels ;
715
                unset ( $panels ) ; //blow away current value
716
                $panels [ 'default' ] = $defaultPanel ;
717
            }
718
        }
719
720
        $newPanels = array ( ) ;
721
722
        // replace '' with (filler)
723
        foreach ( $panels as $panelID => $panel )
724
        {
725
            foreach ( $panel as $rowID => $row )
726
            {
727
                $cols = 0;
728
            	foreach ( $row as $colID => $col )
729
                {
730
                    if ( ! empty ( $col ) )
731
                    {
732
                        if ( is_string ( $col ))
733
                        {
734
                            $fieldname = $col ;
735
                        } else if (! empty ( $col [ 'name' ] ))
736
                        {
737
                            $fieldname = $col [ 'name' ] ;
738
                        }
739
                    } else
740
                    {
741
                    	$fieldname = $this->FILLER['name'] ;
742
                    }
743
744
                    $newPanels [ $panelID ] [ $rowID ] [ $cols ] = $fieldname ;
745
                    $cols++;
746
                }
747
            }
748
        }
749
750
        // replace missing fields with (empty)
751
        foreach ( $newPanels as $panelID => $panel )
752
        {
753
            $column = 0 ;
754
            foreach ( $panel as $rowID => $row )
755
            {
756
                // pad between fields on a row
757
                foreach ( $row as $colID => $col )
758
                {
759
                    for ( $i = $column + 1 ; $i < $colID ; $i ++ )
760
                    {
761
                        $row [ $i ] = MBConstants::$EMPTY ['name'];
762
                    }
763
                    $column = $colID ;
764
                }
765
                // now pad out to the end of the row
766
                if (($column + 1) < $this->getMaxColumns ())
767
                { // last column is maxColumns-1
768
                    for ( $i = $column + 1 ; $i < $this->getMaxColumns () ; $i ++ )
769
                    {
770
                        $row [ $i ] = MBConstants::$EMPTY ['name'] ;
771
                    }
772
                }
773
                ksort ( $row ) ;
774
                $newPanels [ $panelID ] [ $rowID ] = $row ;
775
            }
776
        }
777
778
        return $newPanels ;
779
    }
780
    
781
    protected function getFieldsFromLayout($viewdef) {
782
    	if (isset($viewdef['panels']))
783
    	{
784
    		$panels = $viewdef['panels']; 
785
    	} else {
786
    	    $panels = $viewdef[self::$variableMap [ $this->_view ] ]['panels'];
787
    	}
788
    	
789
        $ret = array();
790
        if (is_array($panels)) 
791
        {       
792
	        foreach ( $panels as $rows) {
793
	            foreach ($rows as $fields) {
794
	                if (!is_array($fields)) {
795
	                	$ret[$fields] = $fields;
796
	                	continue;
797
	                }
798
	            	foreach ($fields as $field) {
799
	                    if (is_array($field) && !empty($field['name']))
800
	                    {
801
	                        $ret[$field['name']] = $field;  
802
	                    }
803
	            	    else if(!is_array($field)){
804
                            $ret[$field] = $field;
805
                        }	                    
806
	                }
807
	            }
808
	        }
809
        }
810
        return $ret;
811
    }
812
    
813
    protected function fieldIsRequired($def)
814
    {
815
    	if (isset($def['studio']))
816
    	{ 
817
    		if (is_array($def['studio']))
818
    		{
819
    			if (!empty($def['studio'][$this->_view]) && $def['studio'][$this->_view] == "required")
820
    			{
821
    				return true;
822
    }
823
    			else if (!empty($def['studio']['required']) && $def['studio']['required'] == true)
824
    			{
825
    				return true;
826
    			}
827
    		}
828
    		else if ($def['studio'] == "required" ){
829
    		  return true;
830
    		}
831
    }
832
        return false;
833
    }
834
835
    static function _trimFieldDefs ( $def )
836
	{
837
		$ret = array_intersect_key ( $def , 
838
            array ( 'studio' => true , 'name' => true , 'label' => true , 'displayParams' => true , 'comment' => true , 
839
                    'customCode' => true , 'customLabel' => true , 'tabindex' => true , 'hideLabel' => true) ) ;
840
        if (!empty($def['vname']) && empty($def['label']))
841
            $ret['label'] = $def['vname'];
842
		return $ret;
843
	}
844
	
845
	public function getUseTabs(){
846
        if (isset($this->_viewdefs  [ 'templateMeta' ]['useTabs']))
847
           return $this->_viewdefs  [ 'templateMeta' ]['useTabs'];
848
           
849
        return false;
850
    }
851
    
852
    public function setUseTabs($useTabs){
853
        $this->_viewdefs  [ 'templateMeta' ]['useTabs'] = $useTabs;
854
    }
855
    
856
    /**
857
     * Return whether the Detail & EditView should be in sync.
858
     */
859
	public function getSyncDetailEditViews(){
860
        if (isset($this->_viewdefs  [ 'templateMeta' ]['syncDetailEditViews']))
861
           return $this->_viewdefs  [ 'templateMeta' ]['syncDetailEditViews'];
862
           
863
        return false;
864
    }
865
    
866
    /**
867
     * Sync DetailView & EditView. This should only be set on the EditView
868
     * @param bool $syncViews
0 ignored issues
show
Bug introduced by
There is no parameter named $syncViews. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
869
     */
870
    public function setSyncDetailEditViews($syncDetailEditViews){
871
        $this->_viewdefs  [ 'templateMeta' ]['syncDetailEditViews'] = $syncDetailEditViews;
872
    }
873
874
    /**
875
     * Getter function to get the implementation method which is a private variable
876
     * @return DeployedMetaDataImplementation
877
     */
878
    public function getImplementation(){
879
        return $this->implementation;
880
    }
881
882
    /**
883
     * Public access to _convertFromCanonicalForm
884
     * @param  $panels
885
     * @param  $fielddefs
886
     * @return array
887
     */
888
    public function convertFromCanonicalForm ( $panels , $fielddefs )
889
    {
890
        return $this->_convertFromCanonicalForm ( $panels , $fielddefs );
891
    }
892
893
     /**
894
     * Public access to _convertToCanonicalForm
895
     * @param  $panels
896
     * @param  $fielddefs
897
     * @return array
898
     */
899
    public function convertToCanonicalForm ( $panels , $fielddefs )
900
    {
901
        return $this->_convertToCanonicalForm ( $panels , $fielddefs );
902
    }
903
904
    
905
    /**
906
     * @return Array list of fields in this module that have the calculated property
907
     */
908
    public function getCalculatedFields() {
909
        $ret = array();
910
        foreach ($this->_fielddefs as $field => $def)
911
        {
912
            if(!empty($def['calculated']) && !empty($def['formula']))
913
            {
914
                $ret[] = $field;
915
            }
916
        }
917
        
918
        return $ret;
919
    }
920
921
    /**
922
     * @return Array fields in the given panel
923
     */
924
    public function getFieldsInPanel($targetPanel) {
925
        return iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($this->_viewdefs['panels'][$targetPanel])));
926
    }
927
}
928
929
?>
930