RendererProviderHTML::renderDoubleField()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 31
rs 9.424
cc 4
nc 8
nop 4
1
<?php
2
3
namespace Alpha\View\Renderer\Html;
4
5
use Alpha\View\Renderer\RendererProviderInterface;
6
use Alpha\View\Widget\Button;
7
use Alpha\View\Widget\TextBox;
8
use Alpha\View\Widget\SmallTextBox;
9
use Alpha\View\Widget\DateBox;
10
use Alpha\View\Widget\RecordSelector;
11
use Alpha\View\View;
12
use Alpha\View\ViewState;
13
use Alpha\Controller\Front\FrontController;
14
use Alpha\Controller\Controller;
15
use Alpha\Util\Logging\Logger;
16
use Alpha\Util\Security\SecurityUtils;
17
use Alpha\Util\Config\ConfigProvider;
18
use Alpha\Util\InputFilter;
19
use Alpha\Util\Service\ServiceFactory;
20
use Alpha\Util\Http\Request;
21
use Alpha\Model\Type\DEnum;
22
use Alpha\Model\Type\SmallText;
23
use Alpha\Model\Type\Text;
24
use Alpha\Model\Type\LargeText;
25
use Alpha\Model\ActiveRecord;
26
use Alpha\Exception\IllegalArguementException;
27
use Alpha\Exception\AlphaException;
28
use ReflectionClass;
29
30
/**
31
 * HTML renderer.  Will invoke widgets from the Alpha\View\Widgets package
32
 * automatically for the correct data type.  Templates from ./templates/html
33
 * will be loaded by default, but these can be overridden on a per-record level in
34
 * the application when required (consider the default ones to be scaffolding).
35
 *
36
 * @since 1.2
37
 *
38
 * @author John Collins <[email protected]>
39
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
40
 * @copyright Copyright (c) 2020, John Collins (founder of Alpha Framework).
41
 * All rights reserved.
42
 *
43
 * <pre>
44
 * Redistribution and use in source and binary forms, with or
45
 * without modification, are permitted provided that the
46
 * following conditions are met:
47
 *
48
 * * Redistributions of source code must retain the above
49
 *   copyright notice, this list of conditions and the
50
 *   following disclaimer.
51
 * * Redistributions in binary form must reproduce the above
52
 *   copyright notice, this list of conditions and the
53
 *   following disclaimer in the documentation and/or other
54
 *   materials provided with the distribution.
55
 * * Neither the name of the Alpha Framework nor the names
56
 *   of its contributors may be used to endorse or promote
57
 *   products derived from this software without specific
58
 *   prior written permission.
59
 *
60
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
61
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
62
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
63
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
65
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
66
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
67
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
68
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
70
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
71
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73
 * </pre>
74
 */
75
class RendererProviderHTML implements RendererProviderInterface
76
{
77
    /**
78
     * Trace logger.
79
     *
80
     * @var \Alpha\Util\Logging\Logger;
81
     *
82
     * @since 1.2
83
     */
84
    private static $logger = null;
85
86
    /**
87
     * The business object that we are renderering.
88
     *
89
     * @var \Alpha\Model\ActiveRecord
90
     *
91
     * @since 1.2
92
     */
93
    private $record;
94
95
    /**
96
     * The constructor.
97
     *
98
     * @since 1.2
99
     */
100
    public function __construct()
101
    {
102
        self::$logger = new Logger('RendererProviderHTML');
103
        self::$logger->debug('>>__construct()');
104
105
        self::$logger->debug('<<__construct');
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     */
111
    public function setRecord($record)
112
    {
113
        $this->record = $record;
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function createView($fields = array())
120
    {
121
        self::$logger->debug('>>createView(fields=['.var_export($fields, true).'])');
122
123
        // the form ID
124
        $fields['formID'] = stripslashes(get_class($this->record).'_'.$this->record->getID());
125
126
        // buffer form fields to $formFields
127
        $fields['formFields'] = $this->renderAllFields('create');
128
129
        // buffer HTML output for Create and Cancel buttons
130
        $button = new Button('submit', 'Create', 'createBut');
131
        $fields['createButton'] = $button->render();
132
133
        if (isset($fields['cancelButtonURL'])) {
134
            $button = new Button("document.location.replace('".$fields['cancelButtonURL']."')", 'Cancel', 'cancelBut');
135
        } else {
136
            $button = new Button("document.location.replace('".FrontController::generateSecureURL('act=Alpha\\Controller\\ListActiveRecordsController')."')", 'Cancel', 'cancelBut');
137
        }
138
        $fields['cancelButton'] = $button->render();
139
140
        // buffer security fields to $formSecurityFields variable
141
        $fields['formSecurityFields'] = self::renderSecurityFields();
142
143
        self::$logger->debug('<<createView [HTML]');
144
145
        return View::loadTemplate($this->record, 'create', $fields);
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function editView($fields = array())
152
    {
153
        self::$logger->debug('>>editView(fields=['.var_export($fields, true).'])');
154
155
        $config = ConfigProvider::getInstance();
156
157
        // the form ID
158
        $fields['formID'] = stripslashes(get_class($this->record).'_'.$this->record->getID());
159
160
        // buffer form fields to $formFields
161
        $fields['formFields'] = $this->renderAllFields('edit');
162
163
        // buffer HTML output for Create and Cancel buttons
164
        $button = new Button('submit', 'Save', 'saveBut');
165
        $fields['saveButton'] = $button->render();
166
167
        $formFieldId = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordID')) : 'ActiveRecordID');
168
            
169
        $js = View::loadTemplateFragment('html', 'bootstrapconfirmokay.phtml', array('prompt' => 'Are you sure you wish to delete this item?', 'formFieldId' => $formFieldId, 'formFieldValue' => $this->record->getID(), 'formId' => 'deleteForm'));
170
171
        $button = new Button($js, 'Delete', 'deleteBut');
172
        $fields['deleteButton'] = $button->render();
173
174
        $viewState = ViewState::getInstance();
175
        $start = $viewState->get('selectedStart');
176
177
        if (isset($fields['cancelButtonURL'])) {
178
            $button = new Button("document.location = '".$fields['cancelButtonURL']."'", 'Back to List', 'cancelBut');
179
        } else {
180
            $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->record).'&start='.$start.'&limit='.$config->get('app.list.page.amount'))."'", 'Back to List', 'cancelBut');
181
        }
182
        $fields['cancelButton'] = $button->render();
183
184
        // buffer security fields to $formSecurityFields variable
185
        $fields['formSecurityFields'] = self::renderSecurityFields();
186
187
        // ID will need to be posted for optimistic lock checking
188
        $fields['version_num'] = $this->record->getVersionNumber();
189
190
        self::$logger->debug('<<editView [HTML]');
191
192
        return View::loadTemplate($this->record, 'edit', $fields);
193
    }
194
195
    /**
196
     * {@inheritdoc}
197
     */
198
    public function listView($fields = array())
199
    {
200
        self::$logger->debug('>>listView(fields=['.var_export($fields, true).'])');
201
202
        $config = ConfigProvider::getInstance();
203
        $sessionProvider = $config->get('session.provider.name');
204
        $session = ServiceFactory::getInstance($sessionProvider, 'Alpha\Util\Http\Session\SessionProviderInterface');
205
206
        // work out how many columns will be in the table
207
        $reflection = new ReflectionClass(get_class($this->record));
208
        $properties = array_keys($reflection->getDefaultProperties());
209
        $fields['colCount'] = 1+count(array_diff($properties, $this->record->getDefaultAttributes(), $this->record->getTransientAttributes()));
210
211
        // get the class attributes
212
        $properties = $reflection->getProperties();
213
214
        $html = '';
215
216
        $html .= '<tr>';
217
        foreach ($properties as $propObj) {
218
            $propName = $propObj->name;
219
220
            // skip over password fields
221
            $property = $this->record->getPropObject($propName);
222
            if (!($property instanceof SmallText && $property->checkIsPassword())) {
223
                if (!in_array($propName, $this->record->getDefaultAttributes()) && !in_array($propName, $this->record->getTransientAttributes())) {
224
                    $html .= '  <th>'.$this->record->getDataLabel($propName).'</th>';
225
                }
226
                if ($propName == 'ID') {
227
                    $html .= '  <th>'.$this->record->getDataLabel($propName).'</th>';
228
                }
229
            } else {
230
                $fields['colCount'] = $fields['colCount']-1;
231
            }
232
        }
233
        $html .= '</tr><tr>';
234
235
        $fields['formHeadings'] = $html;
236
237
        $html = '';
238
239
        // and now the values
240
        foreach ($properties as $propObj) {
241
            $propName = $propObj->name;
242
243
            $property = $this->record->getPropObject($propName);
244
            if (!($property instanceof SmallText && $property->checkIsPassword())) {
245
                if (!in_array($propName, $this->record->getDefaultAttributes()) && !in_array($propName, $this->record->getTransientAttributes())) {
246
                    if ($property instanceof Text) {
247
                        $text = htmlentities($this->record->get($propName), ENT_COMPAT, 'utf-8');
248
                        if (mb_strlen($text) > 70) {
249
                            $html .= '  <td>&nbsp;'.mb_substr($text, 0, 70).'...</td>';
250
                        } else {
251
                            $html .= '  <td>&nbsp;'.$text.'</td>';
252
                        }
253
                    } elseif ($property instanceof DEnum) {
254
                        $html .= '  <td>&nbsp;'.$property->getDisplayValue().'</td>';
255
                    } else {
256
                        $html .= '  <td>&nbsp;'.$property->getValue().'</td>';
257
                    }
258
                }
259
                if ($propName == 'ID') {
260
                    $html .= '  <td>&nbsp;'.$this->record->getID().'</td>';
261
                }
262
            }
263
        }
264
        $html .= '</tr>';
265
266
        $fields['formFields'] = $html;
267
268
        $request = new Request(array('method' => 'GET'));
269
270
        // View button
271
        if (mb_strpos($request->getURI(), '/tk/') !== false) {
272
            if (isset($fields['viewButtonURL'])) {
273
                $button = new Button("document.location = '".$fields['viewButtonURL']."';", 'View', 'view'.$this->record->getID().'But');
274
            } else {
275
                $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->record).'&ActiveRecordID='.$this->record->getID())."';", 'View', 'view'.$this->record->getID().'But');
276
            }
277
            $fields['viewButton'] = $button->render();
278
        } else {
279
            if ($this->record->hasAttribute('URL')) {
280
                $button = new Button("document.location = '".$this->record->get('URL')."';", 'View', 'view'.$this->record->getID().'But');
281
            } else {
282
                $button = new Button("document.location = '".$config->get('app.url').'/record/'.urlencode(get_class($this->record)).'/'.$this->record->getID()."';", 'View', 'view'.$this->record->getID().'But');
283
            }
284
285
            $fields['viewButton'] = $button->render();
286
        }
287
288
        $html = '';
289
        // render edit and delete buttons for admins only
290
        if ($session->get('currentUser') && $session->get('currentUser')->inGroup('Admin')) {
291
            $html .= '&nbsp;&nbsp;';
292
            if (isset($fields['editButtonURL'])) {
293
                $button = new Button("document.location = '".$fields['editButtonURL']."'", 'Edit', 'edit'.$this->record->getID().'But');
294
            } else {
295
                $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->record).'&ActiveRecordID='.$this->record->getID().'&view=edit')."'", 'Edit', 'edit'.$this->record->getID().'But');
296
            }
297
298
            $html .= $button->render();
299
            $html .= '&nbsp;&nbsp;';
300
301
            $formFieldId = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordID')) : 'ActiveRecordID');
302
            
303
            $js = View::loadTemplateFragment('html', 'bootstrapconfirmokay.phtml', array('prompt' => 'Are you sure you wish to delete this item?', 'formFieldId' => $formFieldId, 'formFieldValue' => $this->record->getID(), 'formId' => 'deleteForm'));
304
305
            $button = new Button($js, 'Delete', 'delete'.$this->record->getID().'But');
306
            $html .= $button->render();
307
        }
308
        $fields['adminButtons'] = $html;
309
310
        // buffer security fields to $formSecurityFields variable
311
        $fields['formSecurityFields'] = self::renderSecurityFields();
312
313
        self::$logger->debug('<<listView [HTML]');
314
315
        return View::loadTemplate($this->record, 'list', $fields);
316
    }
317
318
    /**
319
     * {@inheritdoc}
320
     */
321
    public function detailedView($fields = array())
322
    {
323
        self::$logger->debug('>>detailedView(fields=['.var_export($fields, true).'])');
324
325
        $config = ConfigProvider::getInstance();
326
327
        $sessionProvider = $config->get('session.provider.name');
328
        $session = ServiceFactory::getInstance($sessionProvider, 'Alpha\Util\Http\Session\SessionProviderInterface');
329
330
        // we may want to display the ID regardless of class
331
        $fields['IDLabel'] = $this->record->getDataLabel('ID');
332
        $fields['ID'] = $this->record->getID();
333
334
        // buffer form fields to $formFields
335
        $fields['formFields'] = $this->renderAllFields('view');
336
337
        // Back button
338
        $button = new Button('history.back()', 'Back', 'backBut');
339
        $fields['backButton'] = $button->render();
340
341
        $html = '';
342
        // render edit and delete buttons for admins only
343
        if ($session->get('currentUser') !== false && $session->get('currentUser')->inGroup('Admin')) {
344
            if (isset($fields['editButtonURL'])) {
345
                $button = new Button("document.location = '".$fields['editButtonURL']."'", 'Edit', 'editBut');
346
            } else {
347
                $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->record).'&ActiveRecordID='.$this->record->getID().'&view=edit')."'", 'Edit', 'editBut');
348
            }
349
            $html .= $button->render();
350
351
            $formFieldId = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordID')) : 'ActiveRecordID');
352
            
353
            $js = View::loadTemplateFragment('html', 'bootstrapconfirmokay.phtml', array('prompt' => 'Are you sure you wish to delete this item?', 'formFieldId' => $formFieldId, 'formFieldValue' => $this->record->getID(), 'formId' => 'deleteForm'));
354
355
            $button = new Button($js, 'Delete', 'deleteBut');
356
            $html .= $button->render();
357
        }
358
        $fields['adminButtons'] = $html;
359
360
        self::$logger->debug('<<detailedView [HTML]');
361
362
        return View::loadTemplate($this->record, 'detail', $fields);
363
    }
364
365
    /**
366
     * {@inheritdoc}
367
     */
368
    public function adminView($fields = array())
369
    {
370
        self::$logger->debug('>>adminView(fields=['.var_export($fields, true).'])');
371
372
        $config = ConfigProvider::getInstance();
373
374
        // the class name of the record
375
        $fields['fullClassName'] = stripslashes(get_class($this->record));
376
377
        // the table name in the DB for the record
378
        $fields['tableName'] = $this->record->getTableName();
379
380
        // record count for the Record in the DB
381
        $fields['count'] = ($this->record->checkTableExists() ? $this->record->getCount() : '<span class="warning">unavailable</span>');
382
383
        // table exists in the DB?
384
        $fields['tableExists'] = ($this->record->checkTableExists() ? '<span class="success">Yes</span>' : '<span class="warning">No</span>');
385
386
        if ($this->record->getMaintainHistory()) {
387
            $fields['tableExists'] = ($this->record->checkTableExists(true) ? '<span class="success">Yes</span>' : '<span class="warning">No history table</span>');
388
        }
389
390
        // table schema needs to be updated in the DB?
391
        $fields['tableNeedsUpdate'] = ($this->record->checkTableNeedsUpdate() ? '<span class="warning">Yes</span>' : '<span class="success">No</span>');
392
393
        // create button
394
        if ($this->record->checkTableExists()) {
395
            if (isset($fields['createButtonURL'])) {
396
                $button = new Button("document.location = '".$fields['createButtonURL']."'", 'Create New', 'create'.stripslashes(get_class($this->record)).'But');
397
            } else {
398
                $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.get_class($this->record))."'", 'Create New', 'create'.stripslashes(get_class($this->record)).'But');
399
            }
400
            $fields['createButton'] = $button->render();
401
        } else {
402
            $fields['createButton'] = '';
403
        }
404
405
        // list all button
406
        if ($this->record->checkTableExists()) {
407
            $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.get_class($this->record).'&start=0&limit='.$config->get('app.list.page.amount'))."'", 'List All', 'list'.stripslashes(get_class($this->record)).'But');
408
            $fields['listButton'] = $button->render();
409
        } else {
410
            $fields['listButton'] = '';
411
        }
412
413
        // the create table button (if required)
414
        $html = '';
415
416
        if (!$this->record->checkTableExists()) {
417
            $button = new Button('submit', 'Create Table', 'createTableBut');
418
            $html .= $button->render();
419
            // hidden field so that we know which class to create the table for
420
            $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('createTableClass')) : 'createTableClass');
421
            $html .= '<input type="hidden" name="'.$fieldname.'" value="'.get_class($this->record).'"/>';
422
        }
423
424
        if ($html == '' && $this->record->getMaintainHistory() && !$this->record->checkTableExists(true)) {
425
            $button = new Button('submit', 'Create History Table', 'createHistoryTableBut');
426
            $html .= $button->render();
427
            // hidden field so that we know which class to create the table for
428
            $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('createTableClass')) : 'createTableClass');
429
            $html .= '<input type="hidden" name="'.$fieldname.'" value="'.get_class($this->record).'"/>';
430
        }
431
        $fields['createTableButton'] = $html;
432
433
        // recreate and update table buttons (if required)
434
        $html = '';
435
        if ($this->record->checkTableNeedsUpdate() && $this->record->checkTableExists()) {
436
            $formFieldId = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('admin_'.stripslashes(get_class($this->record)).'_button_pressed')) : 'admin_'.stripslashes(get_class($this->record)).'_button_pressed');
437
            
438
            $js = View::loadTemplateFragment('html', 'bootstrapconfirmokay.phtml', array('prompt' => 'Are you sure you wish to recreate this class table (all data will be lost)?', 'formFieldId' => $formFieldId, 'formFieldValue' => 'recreateTableBut', 'formId' => 'admin_'.stripslashes(get_class($this->record))));
439
440
            $button = new Button($js, 'Recreate Table', 'recreateTableBut');
441
            $html .= $button->render();
442
            // hidden field so that we know which class to recreate the table for
443
            $html .= '<input type="hidden" name="recreateTableClass" value="'.get_class($this->record).'"/>';
444
            $html .= '&nbsp;&nbsp;';
445
446
            $formFieldId = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('admin_'.stripslashes(get_class($this->record)).'_button_pressed')) : 'admin_'.stripslashes(get_class($this->record)).'_button_pressed');
447
            
448
            $js = View::loadTemplateFragment('html', 'bootstrapconfirmokay.phtml', array('prompt' => 'Are you sure you wish to attempt to modify this class table by adding new attributes?', 'formFieldId' => $formFieldId, 'formFieldValue' => 'updateTableBut', 'formId' => 'admin_'.stripslashes(get_class($this->record))));
449
450
            $button = new Button($js, 'Update Table', 'updateTableBut');
451
            $html .= $button->render();
452
            // hidden field so that we know which class to update the table for
453
            $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('updateTableClass')) : 'updateTableClass');
454
            $html .= '<input type="hidden" name="'.$fieldname.'" value="'.get_class($this->record).'"/>';
455
456
            // hidden field to tell us which button was pressed
457
            $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('admin_'.stripslashes(get_class($this->record)).'_button_pressed')) : 'admin_'.stripslashes(get_class($this->record)).'_button_pressed');
458
            $html .= '<input type="hidden" id="'.$fieldname.'" name="'.$fieldname.'" value=""/>';
459
        }
460
        $fields['recreateOrUpdateButtons'] = $html;
461
462
        // buffer security fields to $formSecurityFields variable
463
        $fields['formSecurityFields'] = self::renderSecurityFields();
464
465
        self::$logger->debug('<<adminView [HTML]');
466
467
        return View::loadTemplate($this->record, 'admin', $fields);
468
    }
469
470
    /**
471
     * {@inheritdoc}
472
     */
473
    public static function displayPageHead($controller)
474
    {
475
        if (self::$logger == null) {
476
            self::$logger = new Logger('RendererProviderHTML');
477
        }
478
479
        self::$logger->debug('>>displayPageHead(controller=['.var_export($controller, true).'])');
480
481
        $config = ConfigProvider::getInstance();
482
        $sessionProvider = $config->get('session.provider.name');
483
        $session = ServiceFactory::getInstance($sessionProvider, 'Alpha\Util\Http\Session\SessionProviderInterface');
484
485
        if (!class_exists(get_class($controller))) {
486
            throw new IllegalArguementException('The controller provided ['.get_class($controller).'] is not defined anywhere!');
487
        }
488
489
        $allowCSSOverrides = true;
490
491
        $request = new Request(array('method' => 'GET'));
492
493
        if ($session->get('currentUser') != null && ActiveRecord::isInstalled() && $session->get('currentUser')->inGroup('Admin') && mb_strpos($request->getURI(), '/tk/') !== false) {
494
            $allowCSSOverrides = false;
495
        }
496
497
        $duringCallbackOutput = '';
498
        if (method_exists($controller, 'during_displayPageHead_callback')) {
499
            $duringCallbackOutput = $controller->{'during_displayPageHead_callback'}();
500
        }
501
502
        $onloadEvent = '';
503
        if ($controller->getRecord() != null && $controller->getRecord()->hasAttribute('bodyOnload')) {
504
            $onloadEvent = $controller->getRecord()->get('bodyOnload');
505
        }
506
507
        $cmsCallbackOutput = '';
508
        if (method_exists($controller, 'insert_CMSDisplayStandardHeader_callback')) {
509
            $cmsCallbackOutput = $controller->{'insert_CMSDisplayStandardHeader_callback'}();
510
        }
511
512
        $html = View::loadTemplateFragment('html', 'head.phtml', array('title' => $controller->getTitle(), 'description' => $controller->getDescription(), 'allowCSSOverrides' => $allowCSSOverrides, 'duringCallbackOutput' => $duringCallbackOutput, 'cmsCallbackOutput' => $cmsCallbackOutput, 'onloadEvent' => $onloadEvent));
513
514
        self::$logger->debug('<<displayPageHead [HTML]');
515
516
        return $html;
517
    }
518
519
    /**
520
     * {@inheritdoc}
521
     */
522
    public static function displayPageFoot($controller)
523
    {
524
        if (self::$logger == null) {
525
            self::$logger = new Logger('RendererProviderHTML');
526
        }
527
528
        self::$logger->debug('>>displayPageFoot(controller=['.get_class($controller).'])');
529
530
        $html = View::loadTemplateFragment('html', 'footer.phtml', array());
531
532
        self::$logger->debug('<<displayPageFoot ['.$html.']');
533
534
        return $html;
535
    }
536
537
    /**
538
     * {@inheritdoc}
539
     */
540
    public static function displayUpdateMessage($message)
541
    {
542
        if (self::$logger == null) {
543
            self::$logger = new Logger('RendererProviderHTML');
544
        }
545
        self::$logger->debug('>>displayUpdateMessage(message=['.$message.'])');
546
547
        $html = '<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'.$message.'</div>';
548
549
        self::$logger->debug('<<displayUpdateMessage ['.$html.']');
550
551
        return $html;
552
    }
553
554
    /**
555
     * {@inheritdoc}
556
     */
557
    public static function displayErrorMessage($message)
558
    {
559
        if (self::$logger == null) {
560
            self::$logger = new Logger('RendererProviderHTML');
561
        }
562
        self::$logger->debug('>>displayErrorMessage(message=['.$message.'])');
563
564
        $html = '<div class="alert alert-danger">'.$message.'</div>';
565
566
        self::$logger->debug('<<displayErrorMessage ['.$html.']');
567
568
        return $html;
569
    }
570
571
    /**
572
     * {@inheritdoc}
573
     */
574
    public static function renderErrorPage($code, $message)
575
    {
576
        $config = ConfigProvider::getInstance();
577
578
        $html = View::loadTemplateFragment('html', 'head.phtml', array('title' => $code.' - '.$message, 'description' => $message, 'allowCSSOverrides' => false));
579
        $html .= '</head>';
580
        $html .= '<body>';
581
        $html .= '<div class="container">';
582
        $html .= self::displayErrorMessage('<strong>'.$code.':</strong> '.$message);
583
        $html .= '<div align="center"><a href="'.$config->get('app.url').'">Home Page</a></div>';
584
        $html .= '</div></body></html>';
585
586
        return $html;
587
    }
588
589
    /**
590
     * {@inheritdoc}
591
     */
592
    public static function renderDeleteForm($URI)
593
    {
594
        if (self::$logger == null) {
595
            self::$logger = new Logger('RendererProviderHTML');
596
        }
597
        self::$logger->debug('>>renderDeleteForm()');
598
599
        $config = ConfigProvider::getInstance();
600
601
        $html = '<form action="'.$URI.'" method="POST" id="deleteForm" accept-charset="UTF-8">';
602
        $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordID')) : 'ActiveRecordID');
603
        $html .= '<input type="hidden" name="'.$fieldname.'" id="'.$fieldname.'" value=""/>';
604
        $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('_METHOD')) : '_METHOD');
605
        $html .= '<input type="hidden" name="'.$fieldname.'" id="'.$fieldname.'" value="DELETE"/>';
606
        $html .= self::renderSecurityFields();
607
        $html .= '</form>';
608
609
        self::$logger->debug('<<renderDeleteForm ['.$html.']');
610
611
        return $html;
612
    }
613
614
    /**
615
     * {@inheritdoc}
616
     */
617
    public static function renderSecurityFields()
618
    {
619
        if (self::$logger == null) {
620
            self::$logger = new Logger('RendererProviderHTML');
621
        }
622
623
        self::$logger->debug('>>renderSecurityFields()');
624
625
        $config = ConfigProvider::getInstance();
626
627
        $html = '';
628
629
        $fields = Controller::generateSecurityFields();
630
631
        if ($config->get('security.encrypt.http.fieldnames')) {
632
            $fieldname = base64_encode(SecurityUtils::encrypt('var1'));
633
        } else {
634
            $fieldname = 'var1';
635
        }
636
637
        $html .= '<input type="hidden" name="'.$fieldname.'" value="'.$fields[0].'"/>';
638
639
        if ($config->get('security.encrypt.http.fieldnames')) {
640
            $fieldname = base64_encode(SecurityUtils::encrypt('var2'));
641
        } else {
642
            $fieldname = 'var2';
643
        }
644
645
        $html .= '<input type="hidden" name="'.$fieldname.'" value="'.$fields[1].'"/>';
646
647
        self::$logger->debug('<<renderSecurityFields ['.$html.']');
648
649
        return $html;
650
    }
651
652
    /**
653
     * {@inheritdoc}
654
     */
655
    public function renderIntegerField($name, $label, $mode, $value = '')
656
    {
657
        self::$logger->debug('>>renderIntegerField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
658
659
        $config = ConfigProvider::getInstance();
660
661
        if ($config->get('security.encrypt.http.fieldnames')) {
662
            $fieldname = base64_encode(SecurityUtils::encrypt($name));
663
        } else {
664
            $fieldname = $name;
665
        }
666
667
        $html = '<div class="form-group">';
668
        $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
669
670
        $request = new Request(array('method' => 'GET'));
671
672
        if ($mode == 'create') {
673
            $html .= '<input type="text" style="width:100%;" name="'.$fieldname.'" value="'.$request->getParam($name, '').'"/>';
674
        }
675
676
        if ($mode == 'edit') {
677
            $html .= '<input type="text" style="width:100%;" name="'.$fieldname.'" value="'.$value.'"/>';
678
        }
679
680
        $html .= '</div>';
681
682
        self::$logger->debug('<<renderIntegerField ['.$html.']');
683
684
        return $html;
685
    }
686
687
    /**
688
     * {@inheritdoc}
689
     */
690
    public function renderDoubleField($name, $label, $mode, $value = '')
691
    {
692
        self::$logger->debug('>>renderDoubleField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
693
694
        $config = ConfigProvider::getInstance();
695
696
        if ($config->get('security.encrypt.http.fieldnames')) {
697
            $fieldname = base64_encode(SecurityUtils::encrypt($name));
698
        } else {
699
            $fieldname = $name;
700
        }
701
702
        $html = '<div class="form-group">';
703
        $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
704
705
        $request = new Request(array('method' => 'GET'));
706
707
        if ($mode == 'create') {
708
            $html .= '<input type="text" size="13" name="'.$fieldname.'" value="'.$request->getParam($name, '').'"/>';
709
        }
710
711
        if ($mode == 'edit') {
712
            $html .= '<input type="text" size="13" name="'.$fieldname.'" value="'.$value.'"/>';
713
        }
714
715
        $html .= '</div>';
716
717
        self::$logger->debug('<<renderDoubleField ['.$html.']');
718
719
        return $html;
720
    }
721
722
    /**
723
     * {@inheritdoc}
724
     */
725
    public function renderBooleanField($name, $label, $mode, $value = '')
726
    {
727
        self::$logger->debug('>>renderBooleanField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
728
729
        $config = ConfigProvider::getInstance();
730
731
        if ($config->get('security.encrypt.http.fieldnames')) {
732
            $fieldname = base64_encode(SecurityUtils::encrypt($name));
733
        } else {
734
            $fieldname = $name;
735
        }
736
737
        $html = '<div class="checkbox">';
738
        $html .= '  <label>';
739
740
        if ($mode == 'create') {
741
            $html .= '      <input type="hidden" name="'.$fieldname.'" value="0">';
742
            $html .= '      <input type="checkbox" name="'.$fieldname.'" id="'.$fieldname.'">';
743
            $html .= '          '.$label;
744
        }
745
746
        if ($mode == 'edit') {
747
            $html .= '      <input type="hidden" name="'.$fieldname.'" value="0">';
748
            $html .= '      <input type="checkbox" name="'.$fieldname.'" id="'.$fieldname.'"'.($value == '1' ? ' checked' : '').' />';
749
            $html .= '          '.$label;
750
        }
751
752
        $html .= '  </label>';
753
        $html .= '</div>';
754
755
        self::$logger->debug('<<renderBooleanField ['.$html.']');
756
757
        return $html;
758
    }
759
760
    /**
761
     * {@inheritdoc}
762
     */
763
    public function renderEnumField($name, $label, $mode, $options, $value = '')
764
    {
765
        self::$logger->debug('>>renderEnumField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
766
767
        $config = ConfigProvider::getInstance();
768
769
        if ($config->get('security.encrypt.http.fieldnames')) {
770
            $fieldname = base64_encode(SecurityUtils::encrypt($name));
771
        } else {
772
            $fieldname = $name;
773
        }
774
775
        $html = '<div class="form-group">';
776
        $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
777
778
        if ($mode == 'create') {
779
            $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
780
            foreach ($options as $val) {
781
                $html .= '      <option value="'.$val.'">'.$val.'</option>';
782
            }
783
            $html .= '  </select>';
784
        }
785
786
        if ($mode == 'edit') {
787
            $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
788
            foreach ($options as $val) {
789
                if ($value == $val) {
790
                    $html .= '      <option value="'.$val.'" selected>'.$val.'</option>';
791
                } else {
792
                    $html .= '      <option value="'.$val.'">'.$val.'</option>';
793
                }
794
            }
795
            $html .= '  </select>';
796
        }
797
798
        $html .= '</div>';
799
800
        self::$logger->debug('<<renderEnumField ['.$html.']');
801
802
        return $html;
803
    }
804
805
    /**
806
     * {@inheritdoc}
807
     */
808
    public function renderDEnumField($name, $label, $mode, $options, $value = '')
809
    {
810
        self::$logger->debug('>>renderDEnumField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
811
812
        $config = ConfigProvider::getInstance();
813
814
        if ($config->get('security.encrypt.http.fieldnames')) {
815
            $fieldname = base64_encode(SecurityUtils::encrypt($name));
816
        } else {
817
            $fieldname = $name;
818
        }
819
820
        $html = '<div class="form-group">';
821
        $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
822
823
        if ($mode == 'create') {
824
            $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
825
            foreach (array_keys($options) as $index) {
826
                $html .= '<option value="'.$index.'">'.$options[$index].'</option>';
827
            }
828
            $html .= '  </select>';
829
        }
830
831
        if ($mode == 'edit') {
832
            $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
833
            foreach (array_keys($options) as $index) {
834
                if ($value == $index) {
835
                    $html .= '<option value="'.$index.'" selected>'.$options[$index].'</option>';
836
                } else {
837
                    $html .= '<option value="'.$index.'">'.$options[$index].'</option>';
838
                }
839
            }
840
            $html .= '  </select>';
841
        }
842
843
        $html .= '</div>';
844
845
        self::$logger->debug('<<renderDEnumField ['.$html.']');
846
847
        return $html;
848
    }
849
850
    /**
851
     * {@inheritdoc}
852
     */
853
    public function renderDefaultField($name, $label, $mode, $value = '')
854
    {
855
        self::$logger->debug('>>renderDefaultField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
856
857
        $config = ConfigProvider::getInstance();
858
859
        if ($config->get('security.encrypt.http.fieldnames')) {
860
            $fieldname = base64_encode(SecurityUtils::encrypt($name));
861
        } else {
862
            $fieldname = $name;
863
        }
864
865
        $html = '';
866
867
        $request = new Request(array('method' => 'GET'));
868
869
        if ($mode == 'create') {
870
            $html .= '<strong>'.$label.':</strong> <textarea cols="100" rows="3" name="'.$fieldname.'">'.$request->getParam($name, '').'</textarea>';
871
        }
872
873
        if ($mode == 'edit') {
874
            $html .= '<strong>'.$label.':</strong> <textarea cols="100" rows="3" name="'.$fieldname.'">'.$value.'</textarea>';
875
        }
876
877
        if ($mode == 'view') {
878
            $html .= '<p><strong>'.$label.':</strong> '.$value.'</p>';
879
        }
880
881
        self::$logger->debug('<<renderDefaultField ['.$html.']');
882
883
        return $html;
884
    }
885
886
    /**
887
     * {@inheritdoc}
888
     */
889
    public function renderTextField($name, $label, $mode, $value = '')
890
    {
891
        self::$logger->debug('>>renderTextField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
892
893
        $html = '';
894
895
        if ($mode == 'create') {
896
            // give 10 rows for content fields (other 5 by default)
897
            if ($name == 'content') {
898
                $text = new TextBox($this->record->getPropObject($name), $label, $name, 10);
0 ignored issues
show
Documentation introduced by
$this->record->getPropObject($name) is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Text>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
899
            } else {
900
                $text = new TextBox($this->record->getPropObject($name), $label, $name);
0 ignored issues
show
Documentation introduced by
$this->record->getPropObject($name) is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Text>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
901
            }
902
            $html .= $text->render();
903
        }
904
905
        if ($mode == 'edit') {
906
            // give 10 rows for content fields (other 5 by default)
907
            if ($name == 'content') {
908
                $viewState = ViewState::getInstance();
909
910
                if ($viewState->get('markdownTextBoxRows') == '') {
911
                    $text = new TextBox($this->record->getPropObject($name), $label, $name, 10);
0 ignored issues
show
Documentation introduced by
$this->record->getPropObject($name) is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Text>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
912
                } else {
913
                    $text = new TextBox($this->record->getPropObject($name), $label, $name, (integer)$viewState->get('markdownTextBoxRows'));
0 ignored issues
show
Documentation introduced by
$this->record->getPropObject($name) is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Text>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
914
                }
915
916
                $html .= $text->render();
917
            } else {
918
                $text = new TextBox($this->record->getPropObject($name), $label, $name);
0 ignored issues
show
Documentation introduced by
$this->record->getPropObject($name) is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Text>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
919
                $html .= $text->render();
920
            }
921
        }
922
923
        if ($mode == 'view') {
924
            $html .= '<p><strong>';
925
926
            $html .= $label;
927
928
            $html .= ':</strong>';
929
930
            // filter ouput to prevent malicious injection
931
            $value = InputFilter::encode($value);
932
933
            // ensures that line returns are rendered
934
            $value = str_replace("\n", '<br>', $value);
935
936
            $html .= '&nbsp;';
937
938
            $html .= $value;
939
940
            $html .= '</p>';
941
        }
942
943
        self::$logger->debug('<<renderTextField ['.$html.']');
944
945
        return $html;
946
    }
947
948
    /**
949
     * {@inheritdoc}
950
     */
951
    public function renderStringField($name, $label, $mode, $value = '')
952
    {
953
        self::$logger->debug('>>renderStringField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
954
955
        $html = '';
956
957
        if ($mode == 'create' || $mode == 'edit') {
958
            $string = new SmallTextBox($this->record->getPropObject($name), $label, $name);
0 ignored issues
show
Documentation introduced by
$this->record->getPropObject($name) is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\SmallText>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
959
            $html .= $string->render();
960
        }
961
962
        if ($mode == 'view') {
963
            $html .= '<p><strong>'.$label.':</strong> '.$value.'</p>';
964
        }
965
966
        self::$logger->debug('<<renderStringField ['.$html.']');
967
968
        return $html;
969
    }
970
971
    /**
972
     * {@inheritdoc}
973
     */
974
    public function renderRelationField($name, $label, $mode, $value = '', $expanded = false, $buttons = true)
975
    {
976
        self::$logger->debug('>>renderRelationField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'], expanded=['.$expanded.'], buttons=['.$buttons.'])');
977
978
        $html = '';
979
980
        $rel = $this->record->getPropObject($name);
981
982
        if ($mode == 'create' || $mode == 'edit') {
983
            if ($rel->getRelationType() == 'MANY-TO-MANY') {
984
                try {
985
                    // check to see if the rel is on this class
986
                    $rel->getSide(get_class($this->record));
987
                    $widget = new RecordSelector($rel, $label, $name, get_class($this->record));
0 ignored issues
show
Documentation introduced by
$rel is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Relation>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
988
                    $html .= $widget->render($expanded, $buttons);
989
                } catch (IllegalArguementException $iae) {
990
                    // the rel may be on a parent class
991
                    $widget = new RecordSelector($rel, $label, $name, get_parent_class($this->record));
0 ignored issues
show
Documentation introduced by
$rel is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Relation>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
992
                    $html .= $widget->render($expanded, $buttons);
993
                }
994
            } else {
995
                $rel = new RecordSelector($rel, $label, $name);
0 ignored issues
show
Documentation introduced by
$rel is of type object<Alpha\Model\Type\Type>|boolean, but the function expects a object<Alpha\Model\Type\Relation>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
996
                $html .= $rel->render($expanded, $buttons);
997
            }
998
        }
999
1000
        if ($mode == 'view') {
1001
            if ($rel->getRelationType() == 'MANY-TO-ONE') {
1002
                $html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue());
1003
            } elseif ($rel->getRelationType() == 'MANY-TO-MANY') {
1004
                try {
1005
                    // check to see if the rel is on this class
1006
                    $rel->getSide(get_class($this->record));
1007
                    $html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue(get_class($this->record)));
1008
                } catch (IllegalArguementException $iae) {
1009
                    // the rel may be on a parent class
1010
                    $html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue(get_parent_class($this->record)));
1011
                }
1012
            } else {
1013
                $rel = new RecordSelector($rel, $label, $name);
0 ignored issues
show
Documentation introduced by
$rel is of type object<Alpha\Model\Type\...\Widget\RecordSelector>, but the function expects a object<Alpha\Model\Type\Relation>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1014
                $html .= $rel->render($expanded, $buttons);
1015
            }
1016
        }
1017
1018
        self::$logger->debug('<<renderRelationField ['.$html.']');
1019
1020
        return $html;
1021
    }
1022
1023
    /**
1024
     * {@inheritdoc}
1025
     */
1026
    public function renderAllFields($mode, $filterFields = array(), $readOnlyFields = array())
1027
    {
1028
        self::$logger->debug('>>renderAllFields(mode=['.$mode.'], filterFields=['.var_export($filterFields, true).'], readOnlyFields=['.var_export($readOnlyFields, true).'])');
1029
1030
        $html = '';
1031
1032
        // get the class attributes
1033
        $properties = array_keys($this->record->getDataLabels());
1034
1035
        $orignalMode = $mode;
1036
1037
        foreach ($properties as $propName) {
1038
            if (!in_array($propName, $this->record->getDefaultAttributes()) && !in_array($propName, $filterFields)) {
1039
                // render readonly fields in the supplied array
1040
                if (in_array($propName, $readOnlyFields)) {
1041
                    $mode = 'view';
1042
                } else {
1043
                    $mode = $orignalMode;
1044
                }
1045
1046
                if (!is_object($this->record->getPropObject($propName))) {
1047
                    continue;
1048
                }
1049
1050
                $reflection = new ReflectionClass($this->record->getPropObject($propName));
1051
                $propClass = $reflection->getShortName();
1052
1053
                // exclude non-Relation transient attributes from create and edit screens
1054
                if ($propClass != 'Relation' && ($mode == 'edit' || $mode == 'create') && in_array($propName, $this->record->getTransientAttributes())) {
1055
                    continue;
1056
                }
1057
1058
                switch (mb_strtoupper($propClass)) {
1059
                    case 'INTEGER':
1060
                        if ($mode == 'view') {
1061
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $this->record->get($propName));
1062
                        } else {
1063
                            $html .= $this->renderIntegerField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1064
                        }
1065
                    break;
1066
                    case 'DOUBLE':
1067
                        if ($mode == 'view') {
1068
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $this->record->get($propName));
1069
                        } else {
1070
                            $html .= $this->renderDoubleField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1071
                        }
1072
                    break;
1073
                    case 'DATE':
1074
                        if ($mode == 'view') {
1075
                            $value = $this->record->get($propName);
1076
                            if ($value == '0000-00-00') {
1077
                                $value = '';
1078
                            }
1079
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $value);
1080
                        } else {
1081
                            $date = new DateBox($this->record->getPropObject($propName), $this->record->getDataLabel($propName), $propName);
1082
                            $html .= $date->render();
1083
                        }
1084
                    break;
1085
                    case 'TIMESTAMP':
1086
                        if ($mode == 'view') {
1087
                            $value = $this->record->get($propName);
1088
                            if ($value == '0000-00-00 00:00:00') {
1089
                                $value = '';
1090
                            }
1091
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $value);
1092
                        } else {
1093
                            $timestamp = new DateBox($this->record->getPropObject($propName), $this->record->getDataLabel($propName), $propName);
1094
                            $html .= $timestamp->render();
1095
                        }
1096
                    break;
1097
                    case 'SMALLTEXT':
1098
                        $html .= $this->renderStringField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1099
                    break;
1100
                    case 'TEXT':
1101
                        $html .= $this->renderTextField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1102
                    break;
1103
                    case 'LARGETEXT':
1104
                        $html .= $this->renderTextField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1105
                    break;
1106
                    case 'BOOLEAN':
1107
                        if ($mode == 'view') {
1108
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $this->record->get($propName));
1109
                        } else {
1110
                            $html .= $this->renderBooleanField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1111
                        }
1112
                    break;
1113
                    case 'ENUM':
1114
                        if ($mode == 'view') {
1115
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $this->record->get($propName));
1116
                        } else {
1117
                            $enum = $this->record->getPropObject($propName);
1118
                            $html .= $this->renderEnumField($propName, $this->record->getDataLabel($propName), $mode, $enum->getOptions(), $this->record->get($propName));
1119
                        }
1120
                    break;
1121
                    case 'DENUM':
1122
                        if ($mode == 'view') {
1123
                            $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), 'view', $this->record->getPropObject($propName)->getDisplayValue());
1124
                        } else {
1125
                            $denum = $this->record->getPropObject($propName);
1126
                            $html .= $this->renderDEnumField($propName, $this->record->getDataLabel($propName), $mode, $denum->getOptions(), $this->record->get($propName));
1127
                        }
1128
                    break;
1129
                    case 'RELATION':
1130
                        $html .= $this->renderRelationField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1131
                    break;
1132
                    default:
1133
                        $html .= $this->renderDefaultField($propName, $this->record->getDataLabel($propName), $mode, $this->record->get($propName));
1134
                    break;
1135
                }
1136
            }
1137
        }
1138
1139
        self::$logger->debug('<<renderAllFields ['.$html.']');
1140
1141
        return $html;
1142
    }
1143
}
1144