Overview

Namespaces

  • Alpha
    • Controller
      • Front
    • Exception
    • Model
      • Type
    • Task
    • Util
      • Backup
      • Cache
      • Code
        • Highlight
        • Metric
      • Config
      • Convertor
      • Email
      • Extension
      • Feed
      • File
      • Graph
      • Helper
      • Http
        • Filter
        • Session
      • Image
      • Logging
      • Search
      • Security
    • View
      • Renderer
        • Html
        • Json
      • Widget

Classes

  • RendererProviderHTML
  • Overview
  • Namespace
  • Class
  • Tree
   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\StringBox;
   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\Http\Session\SessionProviderFactory;
  20: use Alpha\Util\Http\Request;
  21: use Alpha\Model\Type\String;
  22: use Alpha\Model\ActiveRecord;
  23: use Alpha\Exception\IllegalArguementException;
  24: use Alpha\Exception\AlphaException;
  25: use ReflectionClass;
  26: 
  27: /**
  28:  * HTML renderer.  Will invoke widgets from the Alpha\View\Widgets package
  29:  * automatically for the correct data type.  Templates from ./templates/html
  30:  * will be loaded by default, but these can be overridden on a per-BO level in
  31:  * the application when required (consider the default ones to be scaffolding).
  32:  *
  33:  * @since 1.2
  34:  *
  35:  * @author John Collins <dev@alphaframework.org>
  36:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
  37:  * @copyright Copyright (c) 2015, John Collins (founder of Alpha Framework).
  38:  * All rights reserved.
  39:  *
  40:  * <pre>
  41:  * Redistribution and use in source and binary forms, with or
  42:  * without modification, are permitted provided that the
  43:  * following conditions are met:
  44:  *
  45:  * * Redistributions of source code must retain the above
  46:  *   copyright notice, this list of conditions and the
  47:  *   following disclaimer.
  48:  * * Redistributions in binary form must reproduce the above
  49:  *   copyright notice, this list of conditions and the
  50:  *   following disclaimer in the documentation and/or other
  51:  *   materials provided with the distribution.
  52:  * * Neither the name of the Alpha Framework nor the names
  53:  *   of its contributors may be used to endorse or promote
  54:  *   products derived from this software without specific
  55:  *   prior written permission.
  56:  *
  57:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  58:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  59:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  60:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  61:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  62:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  63:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  64:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  66:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  67:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  68:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70:  * </pre>
  71:  */
  72: class RendererProviderHTML implements RendererProviderInterface
  73: {
  74:     /**
  75:      * Trace logger.
  76:      *
  77:      * @var Alpha\Util\Logging\Logger;
  78:      *
  79:      * @since 1.2
  80:      */
  81:     private static $logger = null;
  82: 
  83:     /**
  84:      * The business object that we are renderering.
  85:      *
  86:      * @var Alpha\Model\ActiveRecord
  87:      *
  88:      * @since 1.2
  89:      */
  90:     private $BO;
  91: 
  92:     /**
  93:      * The constructor.
  94:      *
  95:      * @since 1.2
  96:      */
  97:     public function __construct()
  98:     {
  99:         self::$logger = new Logger('RendererProviderHTML');
 100:         self::$logger->debug('>>__construct()');
 101: 
 102:         self::$logger->debug('<<__construct');
 103:     }
 104: 
 105:     /**
 106:      * {@inheritdoc}
 107:      */
 108:     public function setBO($BO)
 109:     {
 110:         $this->BO = $BO;
 111:     }
 112: 
 113:     /**
 114:      * {@inheritdoc}
 115:      */
 116:     public function createView($fields = array())
 117:     {
 118:         self::$logger->debug('>>createView(fields=['.var_export($fields, true).'])');
 119: 
 120:         $config = ConfigProvider::getInstance();
 121: 
 122:         // the form ID
 123:         $fields['formID'] = stripslashes(get_class($this->BO).'_'.$this->BO->getOID());
 124: 
 125:         // buffer form fields to $formFields
 126:         $fields['formFields'] = $this->renderAllFields('create');
 127: 
 128:         // buffer HTML output for Create and Cancel buttons
 129:         $button = new Button('submit', 'Create', 'createBut');
 130:         $fields['createButton'] = $button->render();
 131: 
 132:         if (isset($fields['cancelButtonURL'])) {
 133:             $button = new Button("document.location.replace('".$fields['cancelButtonURL']."')", 'Cancel', 'cancelBut');
 134:         } else {
 135:             $button = new Button("document.location.replace('".FrontController::generateSecureURL('act=Alpha\\Controller\\ListActiveRecordsController')."')", 'Cancel', 'cancelBut');
 136:         }
 137:         $fields['cancelButton'] = $button->render();
 138: 
 139:         // buffer security fields to $formSecurityFields variable
 140:         $fields['formSecurityFields'] = self::renderSecurityFields();
 141: 
 142:         self::$logger->debug('<<createView [HTML]');
 143: 
 144:         return View::loadTemplate($this->BO, 'create', $fields);
 145:     }
 146: 
 147:     /**
 148:      * {@inheritdoc}
 149:      */
 150:     public function editView($fields = array())
 151:     {
 152:         self::$logger->debug('>>editView(fields=['.var_export($fields, true).'])');
 153: 
 154:         $config = ConfigProvider::getInstance();
 155: 
 156:         // the form ID
 157:         $fields['formID'] = stripslashes(get_class($this->BO).'_'.$this->BO->getOID());
 158: 
 159:         // buffer form fields to $formFields
 160:         $fields['formFields'] = $this->renderAllFields('edit');
 161: 
 162:         // buffer HTML output for Create and Cancel buttons
 163:         $button = new Button('submit', 'Save', 'saveBut');
 164:         $fields['saveButton'] = $button->render();
 165: 
 166:         $js = "if(window.jQuery) {
 167:                     BootstrapDialog.show({
 168:                         title: 'Confirmation',
 169:                         message: 'Are you sure you wish to delete this item?',
 170:                         buttons: [
 171:                             {
 172:                                 icon: 'glyphicon glyphicon-remove',
 173:                                 label: 'Cancel',
 174:                                 cssClass: 'btn btn-default btn-xs',
 175:                                 action: function(dialogItself){
 176:                                     dialogItself.close();
 177:                                 }
 178:                             },
 179:                             {
 180:                                 icon: 'glyphicon glyphicon-ok',
 181:                                 label: 'Okay',
 182:                                 cssClass: 'btn btn-default btn-xs',
 183:                                 action: function(dialogItself) {
 184:                                     $('[id=\"".($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordOID')) : 'ActiveRecordOID')."\"]').attr('value', '".$this->BO->getOID()."');
 185:                                     $('#deleteForm').submit();
 186:                                     dialogItself.close();
 187:                                 }
 188:                             }
 189:                         ]
 190:                     });
 191:                 }";
 192:         $button = new Button($js, 'Delete', 'deleteBut');
 193:         $fields['deleteButton'] = $button->render();
 194: 
 195:         $viewState = ViewState::getInstance();
 196:         $start = $viewState->get('selectedStart');
 197: 
 198:         if (isset($fields['cancelButtonURL'])) {
 199:             $button = new Button("document.location = '".$fields['cancelButtonURL']."'", 'Back to List', 'cancelBut');
 200:         } else {
 201:             $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->BO).'&start='.$start.'&limit='.$config->get('app.list.page.amount'))."'", 'Back to List', 'cancelBut');
 202:         }
 203:         $fields['cancelButton'] = $button->render();
 204: 
 205:         // buffer security fields to $formSecurityFields variable
 206:         $fields['formSecurityFields'] = self::renderSecurityFields();
 207: 
 208:         // OID will need to be posted for optimistic lock checking
 209:         $fields['version_num'] = $this->BO->getVersionNumber();
 210: 
 211:         self::$logger->debug('<<editView [HTML]');
 212: 
 213:         return View::loadTemplate($this->BO, 'edit', $fields);
 214:     }
 215: 
 216:     /**
 217:      * {@inheritdoc}
 218:      */
 219:     public function listView($fields = array())
 220:     {
 221:         self::$logger->debug('>>listView(fields=['.var_export($fields, true).'])');
 222: 
 223:         $config = ConfigProvider::getInstance();
 224:         $sessionProvider = $config->get('session.provider.name');
 225:         $session = SessionProviderFactory::getInstance($sessionProvider);
 226: 
 227:         // work out how many columns will be in the table
 228:         $reflection = new ReflectionClass(get_class($this->BO));
 229:         $properties = array_keys($reflection->getDefaultProperties());
 230:         $fields['colCount'] = 1 + count(array_diff($properties, $this->BO->getDefaultAttributes(), $this->BO->getTransientAttributes()));
 231: 
 232:         // get the class attributes
 233:         $properties = $reflection->getProperties();
 234: 
 235:         $html = '';
 236: 
 237:         $html .= '<tr>';
 238:         foreach ($properties as $propObj) {
 239:             $propName = $propObj->name;
 240: 
 241:             // skip over password fields
 242:             $property = $this->BO->getPropObject($propName);
 243:             if (!($property instanceof String && $property->checkIsPassword())) {
 244:                 if (!in_array($propName, $this->BO->getDefaultAttributes()) && !in_array($propName, $this->BO->getTransientAttributes())) {
 245:                     $html .= '  <th>'.$this->BO->getDataLabel($propName).'</th>';
 246:                 }
 247:                 if ($propName == 'OID') {
 248:                     $html .= '  <th>'.$this->BO->getDataLabel($propName).'</th>';
 249:                 }
 250:             } else {
 251:                 $fields['colCount'] = $fields['colCount'] - 1;
 252:             }
 253:         }
 254:         $html .= '</tr><tr>';
 255: 
 256:         $fields['formHeadings'] = $html;
 257: 
 258:         $html = '';
 259: 
 260:         // and now the values
 261:         foreach ($properties as $propObj) {
 262:             $propName = $propObj->name;
 263: 
 264:             $property = $this->BO->getPropObject($propName);
 265:             if (!($property instanceof String && $property->checkIsPassword())) {
 266:                 if (!in_array($propName, $this->BO->getDefaultAttributes()) && !in_array($propName, $this->BO->getTransientAttributes())) {
 267:                     $propClass = get_class($this->BO->getPropObject($propName));
 268: 
 269:                     if ($propClass == 'Text') {
 270:                         $text = htmlentities($this->BO->get($propName), ENT_COMPAT, 'utf-8');
 271:                         if (mb_strlen($text) > 70) {
 272:                             $html .= '  <td>&nbsp;'.mb_substr($text, 0, 70).'...</td>';
 273:                         } else {
 274:                             $html .= '  <td>&nbsp;'.$text.'</td>';
 275:                         }
 276:                     } elseif ($propClass == 'DEnum') {
 277:                         $html .= '  <td>&nbsp;'.$this->BO->getPropObject($propName)->getDisplayValue().'</td>';
 278:                     } else {
 279:                         $html .= '  <td>&nbsp;'.$this->BO->get($propName).'</td>';
 280:                     }
 281:                 }
 282:                 if ($propName == 'OID') {
 283:                     $html .= '  <td>&nbsp;'.$this->BO->getOID().'</td>';
 284:                 }
 285:             }
 286:         }
 287:         $html .= '</tr>';
 288: 
 289:         $fields['formFields'] = $html;
 290: 
 291:         $request = new Request(array('method' => 'GET'));
 292: 
 293:         // View button
 294:         if (mb_strpos($request->getURI(), '/tk/') !== false) {
 295:             if (isset($fields['viewButtonURL'])) {
 296:                 $button = new Button("document.location = '".$fields['viewButtonURL']."';", 'View', 'view'.$this->BO->getOID().'But');
 297:             } else {
 298:                 $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->BO).'&ActiveRecordOID='.$this->BO->getOID())."';", 'View', 'view'.$this->BO->getOID().'But');
 299:             }
 300:             $fields['viewButton'] = $button->render();
 301:         } else {
 302:             if ($this->BO->hasAttribute('URL')) {
 303:                 $button = new Button("document.location = '".$this->BO->get('URL')."';", 'View', 'view'.$this->BO->getOID().'But');
 304:             } else {
 305:                 $button = new Button("document.location = '".$config->get('app.url').'/record/'.urlencode(get_class($this->BO)).'/'.$this->BO->getOID()."';", 'View', 'view'.$this->BO->getOID().'But');
 306:             }
 307: 
 308:             $fields['viewButton'] = $button->render();
 309:         }
 310: 
 311:         $html = '';
 312:         // render edit and delete buttons for admins only
 313:         if ($session->get('currentUser') && $session->get('currentUser')->inGroup('Admin')) {
 314:             $html .= '&nbsp;&nbsp;';
 315:             if (isset($fields['editButtonURL'])) {
 316:                 $button = new Button("document.location = '".$fields['editButtonURL']."'", 'Edit', 'edit'.$this->BO->getOID().'But');
 317:             } else {
 318:                 $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->BO).'&ActiveRecordOID='.$this->BO->getOID().'&view=edit')."'", 'Edit', 'edit'.$this->BO->getOID().'But');
 319:             }
 320: 
 321:             $html .= $button->render();
 322:             $html .= '&nbsp;&nbsp;';
 323: 
 324:             $js = "if(window.jQuery) {
 325:                     BootstrapDialog.show({
 326:                         title: 'Confirmation',
 327:                         message: 'Are you sure you wish to delete this item?',
 328:                         buttons: [
 329:                             {
 330:                                 icon: 'glyphicon glyphicon-remove',
 331:                                 label: 'Cancel',
 332:                                 cssClass: 'btn btn-default btn-xs',
 333:                                 action: function(dialogItself){
 334:                                     dialogItself.close();
 335:                                 }
 336:                             },
 337:                             {
 338:                                 icon: 'glyphicon glyphicon-ok',
 339:                                 label: 'Okay',
 340:                                 cssClass: 'btn btn-default btn-xs',
 341:                                 action: function(dialogItself) {
 342:                                     $('[id=\"".($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordOID')) : 'ActiveRecordOID')."\"]').attr('value', '".$this->BO->getOID()."');
 343:                                     $('#deleteForm').submit();
 344:                                     dialogItself.close();
 345:                                 }
 346:                             }
 347:                         ]
 348:                     });
 349:                 }";
 350: 
 351:             $button = new Button($js, 'Delete', 'delete'.$this->BO->getOID().'But');
 352:             $html .= $button->render();
 353:         }
 354:         $fields['adminButtons'] = $html;
 355: 
 356:         // buffer security fields to $formSecurityFields variable
 357:         $fields['formSecurityFields'] = self::renderSecurityFields();
 358: 
 359:         self::$logger->debug('<<listView [HTML]');
 360: 
 361:         return View::loadTemplate($this->BO, 'list', $fields);
 362:     }
 363: 
 364:     /**
 365:      * {@inheritdoc}
 366:      */
 367:     public function detailedView($fields = array())
 368:     {
 369:         self::$logger->debug('>>detailedView(fields=['.var_export($fields, true).'])');
 370: 
 371:         $config = ConfigProvider::getInstance();
 372: 
 373:         $sessionProvider = $config->get('session.provider.name');
 374:         $session = SessionProviderFactory::getInstance($sessionProvider);
 375: 
 376:         // we may want to display the OID regardless of class
 377:         $fields['OIDLabel'] = $this->BO->getDataLabel('OID');
 378:         $fields['OID'] = $this->BO->getOID();
 379: 
 380:         // buffer form fields to $formFields
 381:         $fields['formFields'] = $this->renderAllFields('view');
 382: 
 383:         // Back button
 384:         $button = new Button('history.back()', 'Back', 'backBut');
 385:         $fields['backButton'] = $button->render();
 386: 
 387:         $html = '';
 388:         // render edit and delete buttons for admins only
 389:         if ($session->get('currentUser') !== false && $session->get('currentUser')->inGroup('Admin')) {
 390:             if (isset($fields['editButtonURL'])) {
 391:                 $button = new Button("document.location = '".$fields['editButtonURL']."'", 'Edit', 'editBut');
 392:             } else {
 393:                 $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\Controller\ActiveRecordController&ActiveRecordType='.get_class($this->BO).'&ActiveRecordOID='.$this->BO->getOID().'&view=edit')."'", 'Edit', 'editBut');
 394:             }
 395:             $html .= $button->render();
 396: 
 397:             $js = "if(window.jQuery) {
 398:                     BootstrapDialog.show({
 399:                         title: 'Confirmation',
 400:                         message: 'Are you sure you wish to delete this item?',
 401:                         buttons: [
 402:                             {
 403:                                 icon: 'glyphicon glyphicon-remove',
 404:                                 label: 'Cancel',
 405:                                 cssClass: 'btn btn-default btn-xs',
 406:                                 action: function(dialogItself){
 407:                                     dialogItself.close();
 408:                                 }
 409:                             },
 410:                             {
 411:                                 icon: 'glyphicon glyphicon-ok',
 412:                                 label: 'Okay',
 413:                                 cssClass: 'btn btn-default btn-xs',
 414:                                 action: function(dialogItself) {
 415:                                     $('[id=\"".($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordOID')) : 'ActiveRecordOID')."\"]').attr('value', '".$this->BO->getOID()."');
 416:                                     $('#deleteForm').submit();
 417:                                     dialogItself.close();
 418:                                 }
 419:                             }
 420:                         ]
 421:                     });
 422:                 }";
 423: 
 424:             $button = new Button($js, 'Delete', 'deleteBut');
 425:             $html .= $button->render();
 426:         }
 427:         $fields['adminButtons'] = $html;
 428: 
 429:         self::$logger->debug('<<detailedView [HTML]');
 430: 
 431:         return View::loadTemplate($this->BO, 'detail', $fields);
 432:     }
 433: 
 434:     /**
 435:      * {@inheritdoc}
 436:      */
 437:     public function adminView($fields = array())
 438:     {
 439:         self::$logger->debug('>>adminView(fields=['.var_export($fields, true).'])');
 440: 
 441:         $config = ConfigProvider::getInstance();
 442: 
 443:         // the class name of the BO
 444:         $fields['fullClassName'] = stripslashes(get_class($this->BO));
 445: 
 446:         // the table name in the DB for the BO
 447:         $fields['tableName'] = $this->BO->getTableName();
 448: 
 449:         // record count for the BO in the DB
 450:         $fields['count'] = ($this->BO->checkTableExists() ? $this->BO->getCount() : '<span class="warning">unavailable</span>');
 451: 
 452:         // table exists in the DB?
 453:         $fields['tableExists'] = ($this->BO->checkTableExists() ? '<span class="success">Yes</span>' : '<span class="warning">No</span>');
 454: 
 455:         if ($this->BO->getMaintainHistory()) {
 456:             $fields['tableExists'] = ($this->BO->checkTableExists(true) ? '<span class="success">Yes</span>' : '<span class="warning">No history table</span>');
 457:         }
 458: 
 459:         // table schema needs to be updated in the DB?
 460:         $fields['tableNeedsUpdate'] = ($this->BO->checkTableNeedsUpdate() ? '<span class="warning">Yes</span>' : '<span class="success">No</span>');
 461: 
 462:         // create button
 463:         if ($this->BO->checkTableExists()) {
 464:             if (isset($fields['createButtonURL'])) {
 465:                 $button = new Button("document.location = '".$fields['createButtonURL']."'", 'Create New', 'create'.stripslashes(get_class($this->BO)).'But');
 466:             } else {
 467:                 $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.get_class($this->BO))."'", 'Create New', 'create'.stripslashes(get_class($this->BO)).'But');
 468:             }
 469:             $fields['createButton'] = $button->render();
 470:         } else {
 471:             $fields['createButton'] = '';
 472:         }
 473: 
 474:         // list all button
 475:         if ($this->BO->checkTableExists()) {
 476:             $button = new Button("document.location = '".FrontController::generateSecureURL('act=Alpha\\Controller\\ActiveRecordController&ActiveRecordType='.get_class($this->BO).'&start=0&limit='.$config->get('app.list.page.amount'))."'", 'List All', 'list'.stripslashes(get_class($this->BO)).'But');
 477:             $fields['listButton'] = $button->render();
 478:         } else {
 479:             $fields['listButton'] = '';
 480:         }
 481: 
 482:         // the create table button (if required)
 483:         $html = '';
 484: 
 485:         if (!$this->BO->checkTableExists()) {
 486:             $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('createTableBut')) : 'createTableBut');
 487:             $button = new Button('submit', 'Create Table', $fieldname);
 488:             $html .= $button->render();
 489:             // hidden field so that we know which class to create the table for
 490:             $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('createTableClass')) : 'createTableClass');
 491:             $html .= '<input type="hidden" name="'.$fieldname.'" value="'.get_class($this->BO).'"/>';
 492:         }
 493: 
 494:         if ($html == '' && $this->BO->getMaintainHistory() && !$this->BO->checkTableExists(true)) {
 495:             $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('createHistoryTableBut')) : 'createHistoryTableBut');
 496:             $button = new Button('submit', 'Create History Table', $fieldname);
 497:             $html .= $button->render();
 498:             // hidden field so that we know which class to create the table for
 499:             $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('createTableClass')) : 'createTableClass');
 500:             $html .= '<input type="hidden" name="'.$fieldname.'" value="'.get_class($this->BO).'"/>';
 501:         }
 502:         $fields['createTableButton'] = $html;
 503: 
 504:         // recreate and update table buttons (if required)
 505:         $html = '';
 506:         if ($this->BO->checkTableNeedsUpdate() && $this->BO->checkTableExists()) {
 507:             $js = "if(window.jQuery) {
 508:                     BootstrapDialog.show({
 509:                         title: 'Confirmation',
 510:                         message: 'Are you sure you wish to recreate this class table (all data will be lost)?',
 511:                         buttons: [
 512:                             {
 513:                                 icon: 'glyphicon glyphicon-remove',
 514:                                 label: 'Cancel',
 515:                                 cssClass: 'btn btn-default btn-xs',
 516:                                 action: function(dialogItself){
 517:                                     dialogItself.close();
 518:                                 }
 519:                             },
 520:                             {
 521:                                 icon: 'glyphicon glyphicon-ok',
 522:                                 label: 'Okay',
 523:                                 cssClass: 'btn btn-default btn-xs',
 524:                                 action: function(dialogItself) {
 525:                                     $('[Id=\"".($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('admin_'.stripslashes(get_class($this->BO)).'_button_pressed')) : 'admin_'.stripslashes(get_class($this->BO)).'_button_pressed')."\"]').attr('value', 'recreateTableBut');
 526:                                     $('#admin_".stripslashes(get_class($this->BO))."').submit();
 527:                                     dialogItself.close();
 528:                                 }
 529:                             }
 530:                         ]
 531:                     });
 532:                 }";
 533: 
 534:             $button = new Button($js, 'Recreate Table', 'recreateTableBut');
 535:             $html .= $button->render();
 536:             // hidden field so that we know which class to recreate the table for
 537:             $html .= '<input type="hidden" name="recreateTableClass" value="'.get_class($this->BO).'"/>';
 538:             $html .= '&nbsp;&nbsp;';
 539: 
 540:             $js = "if(window.jQuery) {
 541:                     BootstrapDialog.show({
 542:                         title: 'Confirmation',
 543:                         message: 'Are you sure you wish to attempt to modify this class table by adding new attributes?',
 544:                         buttons: [
 545:                             {
 546:                                 icon: 'glyphicon glyphicon-remove',
 547:                                 label: 'Cancel',
 548:                                 cssClass: 'btn btn-default btn-xs',
 549:                                 action: function(dialogItself){
 550:                                     dialogItself.close();
 551:                                 }
 552:                             },
 553:                             {
 554:                                 icon: 'glyphicon glyphicon-ok',
 555:                                 label: 'Okay',
 556:                                 cssClass: 'btn btn-default btn-xs',
 557:                                 action: function(dialogItself) {
 558:                                     $('[Id=\"".($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('admin_'.stripslashes(get_class($this->BO)).'_button_pressed')) : 'admin_'.stripslashes(get_class($this->BO)).'_button_pressed')."\"]').attr('value', 'updateTableBut');
 559:                                     $('#admin_".stripslashes(get_class($this->BO))."').submit();
 560:                                     dialogItself.close();
 561:                                 }
 562:                             }
 563:                         ]
 564:                     });
 565:                 }";
 566: 
 567:             $button = new Button($js, 'Update Table', 'updateTableBut');
 568:             $html .= $button->render();
 569:             // hidden field so that we know which class to update the table for
 570:             $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('updateTableClass')) : 'updateTableClass');
 571:             $html .= '<input type="hidden" name="'.$fieldname.'" value="'.get_class($this->BO).'"/>';
 572:             // hidden field to tell us which button was pressed
 573:             $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('admin_'.stripslashes(get_class($this->BO)).'_button_pressed')) : 'admin_'.stripslashes(get_class($this->BO)).'_button_pressed');
 574:             $html .= '<input type="hidden" id="'.$fieldname.'" name="'.$fieldname.'" value=""/>';
 575:         }
 576:         $fields['recreateOrUpdateButtons'] = $html;
 577: 
 578:         // buffer security fields to $formSecurityFields variable
 579:         $fields['formSecurityFields'] = self::renderSecurityFields();
 580: 
 581:         self::$logger->debug('<<adminView [HTML]');
 582: 
 583:         return View::loadTemplate($this->BO, 'admin', $fields);
 584:     }
 585: 
 586:     /**
 587:      * {@inheritdoc}
 588:      */
 589:     public static function displayPageHead($controller)
 590:     {
 591:         if (self::$logger == null) {
 592:             self::$logger = new Logger('RendererProviderHTML');
 593:         }
 594: 
 595:         self::$logger->debug('>>displayPageHead(controller=['.var_export($controller, true).'])');
 596: 
 597:         $config = ConfigProvider::getInstance();
 598:         $sessionProvider = $config->get('session.provider.name');
 599:         $session = SessionProviderFactory::getInstance($sessionProvider);
 600: 
 601:         if (!class_exists(get_class($controller))) {
 602:             throw new IllegalArguementException('The controller provided ['.get_class($controller).'] is not defined anywhere!');
 603:         }
 604: 
 605:         $allowCSSOverrides = true;
 606: 
 607:         $request = new Request(array('method' => 'GET'));
 608: 
 609:         if ($session->get('currentUser') != null && ActiveRecord::isInstalled() && $session->get('currentUser')->inGroup('Admin') && mb_strpos($request->getURI(), '/tk/') !== false) {
 610:             $allowCSSOverrides = false;
 611:         }
 612: 
 613:         $html = View::loadTemplateFragment('html', 'head.phtml', array('title' => $controller->getTitle(), 'description' => $controller->getDescription(), 'allowCSSOverrides' => $allowCSSOverrides));
 614: 
 615:         if (method_exists($controller, 'during_displayPageHead_callback')) {
 616:             $html .= $controller->during_displayPageHead_callback();
 617:         }
 618: 
 619:         $html .= '</head>';
 620: 
 621:         try {
 622:             if ($controller->getRecord() != null) {
 623:                 $html .= '<body'.($controller->getRecord()->get('bodyOnload') != '' ? ' onload="'.$controller->getRecord()->get('bodyOnload').'"' : '').'>';
 624:             } else {
 625:                 $html .= '<body>';
 626:             }
 627:         } catch (AlphaException $e) {
 628:             $html .= '<body>';
 629:         }
 630: 
 631:         $html .= '<div class="container">';
 632: 
 633:         if (method_exists($controller, 'insert_CMSDisplayStandardHeader_callback')) {
 634:             $html .= $controller->insert_CMSDisplayStandardHeader_callback();
 635:         }
 636: 
 637:         self::$logger->debug('<<displayPageHead [HTML]');
 638: 
 639:         return $html;
 640:     }
 641: 
 642:     /**
 643:      * {@inheritdoc}
 644:      */
 645:     public static function displayPageFoot($controller)
 646:     {
 647:         if (self::$logger == null) {
 648:             self::$logger = new Logger('RendererProviderHTML');
 649:         }
 650: 
 651:         self::$logger->debug('>>displayPageFoot(controller=['.get_class($controller).'])');
 652: 
 653:         $html = View::loadTemplateFragment('html', 'footer.phtml', array());
 654: 
 655:         self::$logger->debug('<<displayPageFoot ['.$html.']');
 656: 
 657:         return $html;
 658:     }
 659: 
 660:     /**
 661:      * {@inheritdoc}
 662:      */
 663:     public static function displayUpdateMessage($message)
 664:     {
 665:         if (self::$logger == null) {
 666:             self::$logger = new Logger('RendererProviderHTML');
 667:         }
 668:         self::$logger->debug('>>displayUpdateMessage(message=['.$message.'])');
 669: 
 670:         $html = '<div class="alert alert-success alert-dismissable"><button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>'.$message.'</div>';
 671: 
 672:         self::$logger->debug('<<displayUpdateMessage ['.$html.']');
 673: 
 674:         return $html;
 675:     }
 676: 
 677:     /**
 678:      * {@inheritdoc}
 679:      */
 680:     public static function displayErrorMessage($message)
 681:     {
 682:         if (self::$logger == null) {
 683:             self::$logger = new Logger('RendererProviderHTML');
 684:         }
 685:         self::$logger->debug('>>displayErrorMessage(message=['.$message.'])');
 686: 
 687:         $html = '<div class="alert alert-danger">'.$message.'</div>';
 688: 
 689:         self::$logger->debug('<<displayErrorMessage ['.$html.']');
 690: 
 691:         return $html;
 692:     }
 693: 
 694:     /**
 695:      * {@inheritdoc}
 696:      */
 697:     public static function renderErrorPage($code, $message)
 698:     {
 699:         $config = ConfigProvider::getInstance();
 700: 
 701:         $html = View::loadTemplateFragment('html', 'head.phtml', array('title' => $code.' - '.$message, 'description' => $message, 'allowCSSOverrides' => false));
 702:         $html .= '</head>';
 703:         $html .= '<body>';
 704:         $html .= '<div class="container">';
 705:         $html .= self::displayErrorMessage('<strong>'.$code.':</strong> '.$message);
 706:         $html .= '<div align="center"><a href="'.$config->get('app.url').'">Home Page</a></div>';
 707:         $html .= '</div></body></html>';
 708: 
 709:         return $html;
 710:     }
 711: 
 712:     /**
 713:      * {@inheritdoc}
 714:      */
 715:     public static function renderDeleteForm($URI)
 716:     {
 717:         if (self::$logger == null) {
 718:             self::$logger = new Logger('RendererProviderHTML');
 719:         }
 720:         self::$logger->debug('>>renderDeleteForm()');
 721: 
 722:         $config = ConfigProvider::getInstance();
 723: 
 724:         $html = '<form action="'.$URI.'" method="POST" id="deleteForm" accept-charset="UTF-8">';
 725:         $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('ActiveRecordOID')) : 'ActiveRecordOID');
 726:         $html .= '<input type="hidden" name="'.$fieldname.'" id="'.$fieldname.'" value=""/>';
 727:         $fieldname = ($config->get('security.encrypt.http.fieldnames') ? base64_encode(SecurityUtils::encrypt('_METHOD')) : '_METHOD');
 728:         $html .= '<input type="hidden" name="'.$fieldname.'" id="'.$fieldname.'" value="DELETE"/>';
 729:         $html .= self::renderSecurityFields();
 730:         $html .= '</form>';
 731: 
 732:         self::$logger->debug('<<renderDeleteForm ['.$html.']');
 733: 
 734:         return $html;
 735:     }
 736: 
 737:     /**
 738:      * {@inheritdoc}
 739:      */
 740:     public static function renderSecurityFields()
 741:     {
 742:         if (self::$logger == null) {
 743:             self::$logger = new Logger('RendererProviderHTML');
 744:         }
 745: 
 746:         self::$logger->debug('>>renderSecurityFields()');
 747: 
 748:         $config = ConfigProvider::getInstance();
 749: 
 750:         $html = '';
 751: 
 752:         $fields = Controller::generateSecurityFields();
 753: 
 754:         if ($config->get('security.encrypt.http.fieldnames')) {
 755:             $fieldname = base64_encode(SecurityUtils::encrypt('var1'));
 756:         } else {
 757:             $fieldname = 'var1';
 758:         }
 759: 
 760:         $html .= '<input type="hidden" name="'.$fieldname.'" value="'.$fields[0].'"/>';
 761: 
 762:         if ($config->get('security.encrypt.http.fieldnames')) {
 763:             $fieldname = base64_encode(SecurityUtils::encrypt('var2'));
 764:         } else {
 765:             $fieldname = 'var2';
 766:         }
 767: 
 768:         $html .= '<input type="hidden" name="'.$fieldname.'" value="'.$fields[1].'"/>';
 769: 
 770:         self::$logger->debug('<<renderSecurityFields ['.$html.']');
 771: 
 772:         return $html;
 773:     }
 774: 
 775:     /**
 776:      * {@inheritdoc}
 777:      */
 778:     public function renderIntegerField($name, $label, $mode, $value = '')
 779:     {
 780:         self::$logger->debug('>>renderIntegerField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
 781: 
 782:         $config = ConfigProvider::getInstance();
 783: 
 784:         if ($config->get('security.encrypt.http.fieldnames')) {
 785:             $fieldname = base64_encode(SecurityUtils::encrypt($name));
 786:         } else {
 787:             $fieldname = $name;
 788:         }
 789: 
 790:         $html = '<div class="form-group">';
 791:         $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
 792: 
 793:         $request = new Request(array('method' => 'GET'));
 794: 
 795:         if ($mode == 'create') {
 796:             $html .= '<input type="text" style="width:100%;" name="'.$fieldname.'" value="'.$request->getParam($name, '').'"/>';
 797:         }
 798: 
 799:         if ($mode == 'edit') {
 800:             $html .= '<input type="text" style="width:100%;" name="'.$fieldname.'" value="'.$value.'"/>';
 801:         }
 802: 
 803:         $html .= '</div>';
 804: 
 805:         self::$logger->debug('<<renderIntegerField ['.$html.']');
 806: 
 807:         return $html;
 808:     }
 809: 
 810:     /**
 811:      * {@inheritdoc}
 812:      */
 813:     public function renderDoubleField($name, $label, $mode, $value = '')
 814:     {
 815:         self::$logger->debug('>>renderDoubleField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
 816: 
 817:         $config = ConfigProvider::getInstance();
 818: 
 819:         if ($config->get('security.encrypt.http.fieldnames')) {
 820:             $fieldname = base64_encode(SecurityUtils::encrypt($name));
 821:         } else {
 822:             $fieldname = $name;
 823:         }
 824: 
 825:         $html = '<div class="form-group">';
 826:         $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
 827: 
 828:         $request = new Request(array('method' => 'GET'));
 829: 
 830:         if ($mode == 'create') {
 831:             $html .= '<input type="text" size="13" name="'.$fieldname.'" value="'.$request->getParam($name, '').'"/>';
 832:         }
 833: 
 834:         if ($mode == 'edit') {
 835:             $html .= '<input type="text" size="13" name="'.$fieldname.'" value="'.$value.'"/>';
 836:         }
 837: 
 838:         $html .= '</div>';
 839: 
 840:         self::$logger->debug('<<renderDoubleField ['.$html.']');
 841: 
 842:         return $html;
 843:     }
 844: 
 845:     /**
 846:      * {@inheritdoc}
 847:      */
 848:     public function renderBooleanField($name, $label, $mode, $value = '')
 849:     {
 850:         self::$logger->debug('>>renderBooleanField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
 851: 
 852:         $config = ConfigProvider::getInstance();
 853: 
 854:         if ($config->get('security.encrypt.http.fieldnames')) {
 855:             $fieldname = base64_encode(SecurityUtils::encrypt($name));
 856:         } else {
 857:             $fieldname = $name;
 858:         }
 859: 
 860:         $html = '<div class="checkbox">';
 861:         $html .= '  <label>';
 862: 
 863:         if ($mode == 'create') {
 864:             $html .= '      <input type="hidden" name="'.$fieldname.'" value="0">';
 865:             $html .= '      <input type="checkbox" name="'.$fieldname.'" id="'.$fieldname.'">';
 866:             $html .= '          '.$label;
 867:         }
 868: 
 869:         if ($mode == 'edit') {
 870:             $html .= '      <input type="hidden" name="'.$fieldname.'" value="0">';
 871:             $html .= '      <input type="checkbox" name="'.$fieldname.'" id="'.$fieldname.'"'.($value == '1' ? ' checked' : '').' />';
 872:             $html .= '          '.$label;
 873:         }
 874: 
 875:         $html .= '  </label>';
 876:         $html .= '</div>';
 877: 
 878:         self::$logger->debug('<<renderBooleanField ['.$html.']');
 879: 
 880:         return $html;
 881:     }
 882: 
 883:     /**
 884:      * {@inheritdoc}
 885:      */
 886:     public function renderEnumField($name, $label, $mode, $options, $value = '')
 887:     {
 888:         self::$logger->debug('>>renderEnumField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
 889: 
 890:         $config = ConfigProvider::getInstance();
 891: 
 892:         if ($config->get('security.encrypt.http.fieldnames')) {
 893:             $fieldname = base64_encode(SecurityUtils::encrypt($name));
 894:         } else {
 895:             $fieldname = $name;
 896:         }
 897: 
 898:         $html = '<div class="form-group">';
 899:         $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
 900: 
 901:         if ($mode == 'create') {
 902:             $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
 903:             foreach ($options as $val) {
 904:                 $html .= '      <option value="'.$val.'">'.$val.'</option>';
 905:             }
 906:             $html .= '  </select>';
 907:         }
 908: 
 909:         if ($mode == 'edit') {
 910:             $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
 911:             foreach ($options as $val) {
 912:                 if ($value == $val) {
 913:                     $html .= '      <option value="'.$val.'" selected>'.$val.'</option>';
 914:                 } else {
 915:                     $html .= '      <option value="'.$val.'">'.$val.'</option>';
 916:                 }
 917:             }
 918:             $html .= '  </select>';
 919:         }
 920: 
 921:         $html .= '</div>';
 922: 
 923:         self::$logger->debug('<<renderEnumField ['.$html.']');
 924: 
 925:         return $html;
 926:     }
 927: 
 928:     /**
 929:      * {@inheritdoc}
 930:      */
 931:     public function renderDEnumField($name, $label, $mode, $options, $value = '')
 932:     {
 933:         self::$logger->debug('>>renderDEnumField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
 934: 
 935:         $config = ConfigProvider::getInstance();
 936: 
 937:         if ($config->get('security.encrypt.http.fieldnames')) {
 938:             $fieldname = base64_encode(SecurityUtils::encrypt($name));
 939:         } else {
 940:             $fieldname = $name;
 941:         }
 942: 
 943:         $html = '<div class="form-group">';
 944:         $html .= '  <label for="'.$fieldname.'">'.$label.'</label>';
 945: 
 946:         if ($mode == 'create') {
 947:             $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
 948:             foreach (array_keys($options) as $index) {
 949:                 $html .= '<option value="'.$index.'">'.$options[$index].'</option>';
 950:             }
 951:             $html .= '  </select>';
 952:         }
 953: 
 954:         if ($mode == 'edit') {
 955:             $html .= '  <select name="'.$fieldname.'" id="'.$fieldname.'" class="form-control"/>';
 956:             foreach (array_keys($options) as $index) {
 957:                 if ($value == $index) {
 958:                     $html .= '<option value="'.$index.'" selected>'.$options[$index].'</option>';
 959:                 } else {
 960:                     $html .= '<option value="'.$index.'">'.$options[$index].'</option>';
 961:                 }
 962:             }
 963:             $html .= '  </select>';
 964:         }
 965: 
 966:         $html .= '</div>';
 967: 
 968:         self::$logger->debug('<<renderDEnumField ['.$html.']');
 969: 
 970:         return $html;
 971:     }
 972: 
 973:     /**
 974:      * {@inheritdoc}
 975:      */
 976:     public function renderDefaultField($name, $label, $mode, $value = '')
 977:     {
 978:         self::$logger->debug('>>renderDefaultField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
 979: 
 980:         $config = ConfigProvider::getInstance();
 981: 
 982:         if ($config->get('security.encrypt.http.fieldnames')) {
 983:             $fieldname = base64_encode(SecurityUtils::encrypt($name));
 984:         } else {
 985:             $fieldname = $name;
 986:         }
 987: 
 988:         $html = '';
 989: 
 990:         $request = new Request(array('method' => 'GET'));
 991: 
 992:         if ($mode == 'create') {
 993:             $html .= '<textarea cols="100" rows="3" name="'.$fieldname.'">'.$request->getParam($name, '').'</textarea>';
 994:         }
 995: 
 996:         if ($mode == 'edit') {
 997:             $html .= '<textarea cols="100" rows="3" name="'.$fieldname.'">'.$value.'</textarea>';
 998:         }
 999: 
1000:         if ($mode == 'view') {
1001:             $html .= '<p><strong>'.$label.':</strong> '.$value.'</p>';
1002:         }
1003: 
1004:         self::$logger->debug('<<renderDefaultField ['.$html.']');
1005: 
1006:         return $html;
1007:     }
1008: 
1009:     /**
1010:      * {@inheritdoc}
1011:      */
1012:     public function renderTextField($name, $label, $mode, $value = '')
1013:     {
1014:         self::$logger->debug('>>renderTextField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
1015: 
1016:         $config = ConfigProvider::getInstance();
1017: 
1018:         $html = '';
1019: 
1020:         if ($mode == 'create') {
1021:             // give 10 rows for content fields (other 5 by default)
1022:             if ($name == 'content') {
1023:                 $text = new TextBox($this->BO->getPropObject($name), $label, $name, 10);
1024:             } else {
1025:                 $text = new TextBox($this->BO->getPropObject($name), $label, $name);
1026:             }
1027:             $html .= $text->render();
1028:         }
1029: 
1030:         if ($mode == 'edit') {
1031:             // give 10 rows for content fields (other 5 by default)
1032:             if ($name == 'content') {
1033:                 $viewState = ViewState::getInstance();
1034: 
1035:                 if ($viewState->get('markdownTextBoxRows') == '') {
1036:                     $text = new TextBox($this->BO->getPropObject($name), $label, $name, 10);
1037:                 } else {
1038:                     $text = new TextBox($this->BO->getPropObject($name), $label, $name, (integer) $viewState->get('markdownTextBoxRows'));
1039:                 }
1040: 
1041:                 $html .= $text->render();
1042:             } else {
1043:                 $text = new TextBox($this->BO->getPropObject($name), $label, $name);
1044:                 $html .= $text->render();
1045:             }
1046:         }
1047: 
1048:         if ($mode == 'view') {
1049:             $html .= '<p><strong>';
1050: 
1051:             $html .= $label;
1052: 
1053:             $html .= ':</strong>';
1054: 
1055:             // filter ouput to prevent malicious injection
1056:             $value = InputFilter::encode($value);
1057: 
1058:             // ensures that line returns are rendered
1059:             $value = str_replace("\n", '<br>', $value);
1060: 
1061:             $html .= '&nbsp;';
1062: 
1063:             $html .= $value;
1064: 
1065:             $html .= '</p>';
1066:         }
1067: 
1068:         self::$logger->debug('<<renderTextField ['.$html.']');
1069: 
1070:         return $html;
1071:     }
1072: 
1073:     /**
1074:      * {@inheritdoc}
1075:      */
1076:     public function renderStringField($name, $label, $mode, $value = '')
1077:     {
1078:         self::$logger->debug('>>renderStringField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'])');
1079: 
1080:         $config = ConfigProvider::getInstance();
1081: 
1082:         $html = '';
1083: 
1084:         if ($mode == 'create' || $mode == 'edit') {
1085:             $string = new StringBox($this->BO->getPropObject($name), $label, $name);
1086:             $html .= $string->render();
1087:         }
1088: 
1089:         if ($mode == 'view') {
1090:             $html .= '<p><strong>'.$label.':</strong> '.$value.'</p>';
1091:         }
1092: 
1093:         self::$logger->debug('<<renderStringField ['.$html.']');
1094: 
1095:         return $html;
1096:     }
1097: 
1098:     /**
1099:      * {@inheritdoc}
1100:      */
1101:     public function renderRelationField($name, $label, $mode, $value = '', $expanded = false, $buttons = true)
1102:     {
1103:         self::$logger->debug('>>renderRelationField(name=['.$name.'], label=['.$label.'], mode=['.$mode.'], value=['.$value.'], expanded=['.$expanded.'], buttons=['.$buttons.'])');
1104: 
1105:         $config = ConfigProvider::getInstance();
1106: 
1107:         $html = '';
1108: 
1109:         $rel = $this->BO->getPropObject($name);
1110: 
1111:         if ($mode == 'create' || $mode == 'edit') {
1112:             if ($rel->getRelationType() == 'MANY-TO-MANY') {
1113:                 try {
1114:                     // check to see if the rel is on this class
1115:                     $rel->getSide(get_class($this->BO));
1116:                     $widget = new RecordSelector($rel, $label, $name, get_class($this->BO));
1117:                     $html .= $widget->render($expanded, $buttons);
1118:                 } catch (IllegalArguementException $iae) {
1119:                     // the rel may be on a parent class
1120:                     $widget = new RecordSelector($rel, $label, $name, get_parent_class($this->BO));
1121:                     $html .= $widget->render($expanded, $buttons);
1122:                 }
1123:             } else {
1124:                 $rel = new RecordSelector($rel, $label, $name);
1125:                 $html .= $rel->render($expanded, $buttons);
1126:             }
1127:         }
1128: 
1129:         if ($mode == 'view') {
1130:             if ($rel->getRelationType() == 'MANY-TO-ONE') {
1131:                 $html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue());
1132:             } elseif ($rel->getRelationType() == 'MANY-TO-MANY') {
1133:                 try {
1134:                     // check to see if the rel is on this class
1135:                     $rel->getSide(get_class($this->BO));
1136:                     $html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue(get_class($this->BO)));
1137:                 } catch (IllegalArguementException $iae) {
1138:                     // the rel may be on a parent class
1139:                     $html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue(get_parent_class($this->BO)));
1140:                 }
1141:             } else {
1142:                 $rel = new RecordSelector($rel, $label, $name);
1143:                 $html .= $rel->render($expanded, $buttons);
1144:             }
1145:         }
1146: 
1147:         self::$logger->debug('<<renderRelationField ['.$html.']');
1148: 
1149:         return $html;
1150:     }
1151: 
1152:     /**
1153:      * {@inheritdoc}
1154:      */
1155:     public function renderAllFields($mode, $filterFields = array(), $readOnlyFields = array())
1156:     {
1157:         self::$logger->debug('>>renderAllFields(mode=['.$mode.'], filterFields=['.var_export($filterFields, true).'], readOnlyFields=['.var_export($readOnlyFields, true).'])');
1158: 
1159:         $html = '';
1160: 
1161:         // get the class attributes
1162:         $properties = array_keys($this->BO->getDataLabels());
1163: 
1164:         $orignalMode = $mode;
1165: 
1166:         foreach ($properties as $propName) {
1167:             if (!in_array($propName, $this->BO->getDefaultAttributes()) && !in_array($propName, $filterFields)) {
1168:                 // render readonly fields in the supplied array
1169:                 if (in_array($propName, $readOnlyFields)) {
1170:                     $mode = 'view';
1171:                 } else {
1172:                     $mode = $orignalMode;
1173:                 }
1174: 
1175:                 if (!is_object($this->BO->getPropObject($propName))) {
1176:                     continue;
1177:                 }
1178: 
1179:                 $reflection = new ReflectionClass($this->BO->getPropObject($propName));
1180:                 $propClass = $reflection->getShortName();
1181: 
1182:                 // exclude non-Relation transient attributes from create and edit screens
1183:                 if ($propClass != 'Relation' && ($mode == 'edit' || $mode == 'create') && in_array($propName, $this->BO->getTransientAttributes())) {
1184:                     continue;
1185:                 }
1186: 
1187:                 switch (mb_strtoupper($propClass)) {
1188:                     case 'INTEGER' :
1189:                         if ($mode == 'view') {
1190:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
1191:                         } else {
1192:                             $html .= $this->renderIntegerField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1193:                         }
1194:                     break;
1195:                     case 'DOUBLE' :
1196:                         if ($mode == 'view') {
1197:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
1198:                         } else {
1199:                             $html .= $this->renderDoubleField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1200:                         }
1201:                     break;
1202:                     case 'DATE' :
1203:                         if ($mode == 'view') {
1204:                             $value = $this->BO->get($propName);
1205:                             if ($value == '0000-00-00') {
1206:                                 $value = '';
1207:                             }
1208:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $value);
1209:                         } else {
1210:                             $date = new DateBox($this->BO->getPropObject($propName), $this->BO->getDataLabel($propName), $propName);
1211:                             $html .= $date->render();
1212:                         }
1213:                     break;
1214:                     case 'TIMESTAMP' :
1215:                         if ($mode == 'view') {
1216:                             $value = $this->BO->get($propName);
1217:                             if ($value == '0000-00-00 00:00:00') {
1218:                                 $value = '';
1219:                             }
1220:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $value);
1221:                         } else {
1222:                             $timestamp = new DateBox($this->BO->getPropObject($propName), $this->BO->getDataLabel($propName), $propName);
1223:                             $html .= $timestamp->render();
1224:                         }
1225:                     break;
1226:                     case 'STRING' :
1227:                         $html .= $this->renderStringField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1228:                     break;
1229:                     case 'TEXT' :
1230:                         $html .= $this->renderTextField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1231:                     break;
1232:                     case 'BOOLEAN' :
1233:                         if ($mode == 'view') {
1234:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
1235:                         } else {
1236:                             $html .= $this->renderBooleanField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1237:                         }
1238:                     break;
1239:                     case 'ENUM' :
1240:                         if ($mode == 'view') {
1241:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
1242:                         } else {
1243:                             $enum = $this->BO->getPropObject($propName);
1244:                             $html .= $this->renderEnumField($propName, $this->BO->getDataLabel($propName), $mode, $enum->getOptions(), $this->BO->get($propName));
1245:                         }
1246:                     break;
1247:                     case 'DENUM' :
1248:                         if ($mode == 'view') {
1249:                             $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->getPropObject($propName)->getDisplayValue());
1250:                         } else {
1251:                             $denum = $this->BO->getPropObject($propName);
1252:                             $html .= $this->renderDEnumField($propName, $this->BO->getDataLabel($propName), $mode, $denum->getOptions(), $this->BO->get($propName));
1253:                         }
1254:                     break;
1255:                     case 'RELATION' :
1256:                         $html .= $this->renderRelationField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1257:                     break;
1258:                     default :
1259:                         $html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
1260:                     break;
1261:                 }
1262:             }
1263:         }
1264: 
1265:         self::$logger->debug('<<renderAllFields ['.$html.']');
1266: 
1267:         return $html;
1268:     }
1269: }
1270: 
Alpha Framework 2.0.4 API Documentation API documentation generated by ApiGen 2.8.0