Source for file AlphaView.inc
Documentation is available at AlphaView.inc
require_once $config->get('sysRoot'). 'alpha/util/AlphaErrorHandlers.inc';
require_once $config->get('sysRoot'). 'alpha/util/Logger.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Date.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Timestamp.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Double.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Integer.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/String.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Text.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Enum.inc';
require_once $config->get('sysRoot'). 'alpha/model/types/Boolean.inc';
require_once $config->get('sysRoot'). 'alpha/view/widgets/Button.inc';
require_once $config->get('sysRoot'). 'alpha/view/widgets/StringBox.inc';
require_once $config->get('sysRoot'). 'alpha/view/widgets/DateBox.inc';
require_once $config->get('sysRoot'). 'alpha/view/widgets/TextBox.inc';
require_once $config->get('sysRoot'). 'alpha/view/widgets/RecordSelector.inc';
require_once $config->get('sysRoot'). 'alpha/model/AlphaDAO.inc';
require_once $config->get('sysRoot'). 'alpha/view/ViewState.inc';
* The master rendering view class for the Alpha Framework.
* @author John Collins <dev@alphaframework.org>
* @version $Id: AlphaView.inc 1347 2011-03-17 16:36:06Z johnc $
* @license http://www.opensource.org/licenses/bsd-license.php The BSD License
* @copyright Copyright (c) 2011, John Collins (founder of Alpha Framework).
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
* * Neither the name of the Alpha Framework nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The business object that will be rendered
private static $logger = null;
* Constructor for the AlphaView. As this is protected, use the AlphaView::getInstance method from a public scope.
* @throws IllegalArguementException
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>__construct(BO=['. var_export($BO, true). '])');
self::$logger->debug('<<__construct');
* Static method which returns a AlphaView object or a custom child view for the BO specified
* @param AlphaDAO $BO The main business object that this view is going to render
* @param boolean $returnParent Flag to enforce the return of this object instead of a child (defaults to false)
* @return AlphaView Returns a AlphaView object, or a child view object from the /view directory if one exists for this BO
public static function getInstance($BO, $returnParent= false) {
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>getInstance(BO=['. var_export($BO, true). '], returnParent=['. $returnParent. '])');
// remove the Object part
// replace _ with space, then uppercase words
$filename = ucwords($filename). 'View';
// finally, remove spaces
// Check to see if a custom view exists for this BO, and if it does return that view instead
if (file_exists($config->get('sysRoot'). 'view/'. $filename. '.inc')) {
require_once $config->get('sysRoot'). 'view/'. $filename. '.inc';
self::$logger->debug('<<getInstance [new '. $filename. '('. get_class($BO). ')]');
return new $filename($BO);
}elseif (file_exists($config->get('sysRoot'). 'alpha/view/'. $filename. '.inc')) {
require_once $config->get('sysRoot'). 'alpha/view/'. $filename. '.inc';
self::$logger->debug('<<getInstance [new '. $filename. '('. get_class($BO). ')]');
return new $filename($BO);
self::$logger->debug('<<getInstance [new AlphaView('. get_class($BO). ', true)]');
self::$logger->debug('<<getInstance [new AlphaView('. get_class($BO). ', true)]');
* Simple setter for the view business object
* @throws IllegalArguementException
public function setBO($BO) {
self::$logger->debug('>>setBO(BO=['. var_export($BO, true). '])');
self::$logger->debug('<<setBO');
* Gets the BO attached to this view (if any)
public function getBO() {
* Renders the default create view to standard output
* @param array $fields Hash array of HTML fields to pass to the template
self::$logger->debug('>>createView(fields=['. var_export($fields, true). '])');
$this->before_createView_callback();
$fields['formAction'] = $_SERVER['REQUEST_URI'];
$fields['formID'] = get_class($this->BO). '_'. $this->BO->getOID();
// buffer form fields to $formFields
// buffer HTML output for Create and Cancel buttons
$button = new Button('submit', 'Create', 'createBut');
$fields['createButton'] = $button->render();
$fields['cancelButton'] = $button->render();
// buffer security fields to $formSecurityFields variable
$this->after_createView_callback();
self::$logger->debug('<<createView');
* Renders a form to enable object editing to standard output
* @param array $fields Hash array of HTML fields to pass to the template
public function editView($fields= array()) {
self::$logger->debug('>>editView(fields=['. var_export($fields, true). '])');
$this->before_editView_callback();
$fields['formAction'] = $_SERVER['REQUEST_URI'];
$fields['formID'] = get_class($this->BO). '_'. $this->BO->getOID();
// buffer form fields to $formFields
// buffer HTML output for Create and Cancel buttons
$button = new Button('submit', 'Save', 'saveBut');
$fields['saveButton'] = $button->render();
$js = "$('#dialogDiv').text('Are you sure you wish to delete this item?');
'OK': function(event, ui) {
$('#deleteOID').attr('value', '". $this->BO->getOID(). "');
$('#deleteForm').submit();
'Cancel': function(event, ui) {
$('#dialogDiv').dialog('open');
$button = new Button($js, "Delete", "deleteBut");
$fields['deleteButton'] = $button->render();
$fields['cancelButton'] = $button->render();
// buffer security fields to $formSecurityFields variable
// OID will need to be posted for optimistic lock checking
$fields['version_num'] = $this->BO->getVersionNumber();
$this->after_editView_callback();
self::$logger->debug('<<editView');
* Renders the list view to standard output
* @param array $fields Hash array of HTML fields to pass to the template
public function listView($fields= array()) {
self::$logger->debug('>>listView(fields=['. var_export($fields, true). '])');
$this->before_listView_callback();
$fields['formAction'] = $_SERVER['REQUEST_URI'];
// work out how many columns will be in the table
$reflection = new ReflectionClass(get_class($this->BO));
$properties = array_keys($reflection->getDefaultProperties());
$fields['colCount'] = 1+ count(array_diff($properties, $this->BO->getDefaultAttributes(), $this->BO->getTransientAttributes()));
// get the class attributes
$properties = $reflection->getProperties();
foreach($properties as $propObj) {
$propName = $propObj->name;
// skip over password fields
$property = $this->BO->getPropObject($propName);
if(!($property instanceof String && $property->checkIsPassword())) {
if (!in_array($propName, $this->BO->getDefaultAttributes()) && !in_array($propName, $this->BO->getTransientAttributes())) {
$html .= ' <th>'. $this->BO->getDataLabel($propName). '</th>';
$html .= ' <th>'. $this->BO->getDataLabel($propName). '</th>';
$fields['colCount'] = $fields['colCount']- 1;
$fields['formHeadings'] = $html;
foreach($properties as $propObj) {
$propName = $propObj->name;
$property = $this->BO->getPropObject($propName);
if(!($property instanceof String && $property->checkIsPassword())) {
if (!in_array($propName, $this->BO->getDefaultAttributes()) && !in_array($propName, $this->BO->getTransientAttributes())) {
$propClass = get_class($this->BO->getPropObject($propName));
if ($propClass == 'Text') {
$html .= ' <td> '. substr($text, 0, 70). '...</td>';
$html .= ' <td> '. $text. '</td>';
}elseif($propClass == 'DEnum') {
$html .= ' <td> '. $this->BO->getPropObject($propName)->getDisplayValue(). '</td>';
$html .= ' <td> '. $this->BO->get($propName). '</td>';
$html .= ' <td> '. $this->BO->getOID(). '</td>';
$fields['formFields'] = $html;
if(strpos($_SERVER['REQUEST_URI'], '/tk/') !== false) {
$fields['viewButton'] = $button->render();
if($this->BO->hasAttribute('URL'))
$button = new Button("document.location = '". $this->BO->get('URL'). "';", 'View', 'viewBut');
$button = new Button("document.location = '". $config->get('sysURL'). "Detail/bo/". get_class($this->BO). "/oid/". $this->BO->getOID(). "';", 'View', 'viewBut');
$fields['viewButton'] = $button->render();
// render edit and delete buttons for admins only
if (isset ($_SESSION['currentUser']) && $_SESSION['currentUser']->inGroup('Admin')) {
$html .= $button->render();
$js = "$('#dialogDiv').text('Are you sure you wish to delete this item?');
'OK': function(event, ui) {
$('#deleteOID').attr('value', '". $this->BO->getOID(). "');
$('#deleteForm').submit();
'Cancel': function(event, ui) {
$('#dialogDiv').dialog('open');
$button = new Button($js, "Delete", "deleteBut");
$html .= $button->render();
$fields['adminButtons'] = $html;
// buffer security fields to $formSecurityFields variable
$this->after_listView_callback();
self::$logger->debug('<<listView');
* Displays a detailed view of the object (read-only) to standard output
* @param array $fields Hash array of HTML fields to pass to the template
self::$logger->debug('>>detailedView(fields=['. var_export($fields, true). '])');
$this->before_detailedView_callback();
// we may want to display the OID regardless of class
$fields['OIDLabel'] = $this->BO->getDataLabel('OID');
$fields['OID'] = $this->BO->getOID();
// buffer form fields to $formFields
$button = new Button('history.back()', 'Back', 'backBut');
$fields['backButton'] = $button->render();
// render edit and delete buttons for admins only
if (isset ($_SESSION['currentUser']) && $_SESSION['currentUser']->inGroup('Admin')) {
$html .= $button->render();
$js = "$('#dialogDiv').text('Are you sure you wish to delete this item?');
'OK': function(event, ui) {
$('#deleteOID').attr('value', '". $this->BO->getOID(). "');
$('#deleteForm').submit();
'Cancel': function(event, ui) {
$('#dialogDiv').dialog('open');
$button = new Button($js, "Delete", "deleteBut");
$html .= $button->render();
$fields['adminButtons'] = $html;
$this->after_detailedView_callback();
self::$logger->debug('<<detailedView');
* Renders the admin view for the business object screen to standard output
* @param array $fields Hash array of HTML fields to pass to the template
self::$logger->debug('>>adminView(fields=['. var_export($fields, true). '])');
$this->before_adminView_callback();
$fields['formAction'] = $_SERVER['REQUEST_URI'];
// the class name of the BO
// the table name in the DB for the BO
$fields['tableName'] = $this->BO->getTableName();
// record count for the BO in the DB
$fields['count'] = ($this->BO->checkTableExists() ? $this->BO->getCount() : '<span class="warning">unavailable</span>');
// table exists in the DB?
$fields['tableExists'] = ($this->BO->checkTableExists() ? '<span class="success">Yes</span>' : '<span class="warning">No</span>');
// table schema needs to be updated in the DB?
$fields['tableNeedsUpdate'] = ($this->BO->checkTableNeedsUpdate() ? '<span class="warning">Yes</span>' : '<span class="success">No</span>');
if($this->BO->checkTableExists()) {
$fields['createButton'] = $button->render();
$fields['createButton'] = '';
if($this->BO->checkTableExists()) {
$fields['listButton'] = $button->render();
$fields['listButton'] = '';
// the create table button (if required)
if (!$this->BO->checkTableExists()) {
$button = new Button("submit", "Create Table", "createTableBut");
$html .= $button->render();
// hidden field so that we know which class to create the table for
$html .= '<input type="hidden" name="createTableClass" value="'. get_class($this->BO). '"/>';
$fields['createTableButton'] = $html;
// recreate and update table buttons (if required)
if ($this->BO->checkTableNeedsUpdate() && $this->BO->checkTableExists()) {
$js = "$('#dialogDiv').text('Are you sure you wish to recreate this class table (all data will be lost)?');
'OK': function(event, ui) {
$('#admin_". get_class($this->BO). "_button_pressed').attr('value', 'recreateTableBut');
'Cancel': function(event, ui) {
$('#dialogDiv').dialog('open');
$button = new Button($js , "Recreate Table", "recreateTableBut");
$html .= $button->render();
// hidden field so that we know which class to recreate the table for
$html .= '<input type="hidden" name="recreateTableClass" value="'. get_class($this->BO). '"/>';
$js = "$('#dialogDiv').text('Are you sure you wish to attempt to modify this class table by adding new attributes?');
'OK': function(event, ui) {
$('#admin_". get_class($this->BO). "_button_pressed').attr('value', 'updateTableBut');
'Cancel': function(event, ui) {
$('#dialogDiv').dialog('open');
$button = new Button($js , "Update Table", "updateTableBut");
$html .= $button->render();
// hidden field so that we know which class to update the table for
$html .= '<input type="hidden" name="updateTableClass" value="'. get_class($this->BO). '"/>';
// hidden field to tell us which button was pressed
$html .= '<input type="hidden" id="admin_'. get_class($this->BO). '_button_pressed" name="admin_'. get_class($this->BO). '_button_pressed" value=""/>';
$fields['recreateOrUpdateButtons'] = $html;
// buffer security fields to $formSecurityFields variable
$this->after_adminView_callback();
self::$logger->debug('<<adminView');
* Method to render the page header HTML content
* @param AlphaController $controller
* @param bool $renderMenu Set to false to hide the default menu (default value is true)
* @throws IllegalArguementException
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>displayPageHead(controller=['. var_export($controller, true). '])');
if(method_exists($controller, 'before_displayPageHead_callback'))
$controller->before_displayPageHead_callback();
$html.= '<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">';
$html.= '<title>'. $controller->getTitle(). '</title>';
if($controller->getKeywords() != '')
$html.= '<meta name="Keywords" content="'. $controller->getKeywords(). '">';
if($controller->getDescription() != '')
$html.= '<meta name="Description" content="'. $controller->getDescription(). '">';
$html.= '<meta name="title" content="'. $controller->getTitle(). '">';
$html.= '<meta name="robots" content="index,follow,NOODP">';
if ($controller->getBO() != null && $controller->getBO()->hasAttribute('URL')) {
$URL = $controller->getBO()->get('URL');
$html.= '<link rel="canonical" href="'. $URL. '" />';
$html.= '<meta http-equiv="imagetoolbar" content="no">';
$html.= '<link rel="StyleSheet" type="text/css" href="'. $config->get('sysURL'). 'alpha/lib/jquery/ui/themes/'. $config->get('sysTheme'). '/ui.all.css">';
$html.= '<link rel="StyleSheet" type="text/css" href="'. $config->get('sysURL'). 'alpha/css/alpha.css">';
$html.= '<link rel="StyleSheet" type="text/css" href="'. $config->get('sysURL'). 'config/css/overrides.css">';
$html.= '<script language="JavaScript" src="'. $config->get('sysURL'). 'alpha/scripts/addOnloadEvent.js"></script>';
$html.= '<script type="text/javascript" src="'. $config->get('sysURL'). 'alpha/lib/jquery/jquery-1.3.2.min.js"></script>';
$html.= '<script language="JavaScript" src="'. $config->get('sysURL'). 'alpha/scripts/validation.js"></script>';
$html.= '<script type="text/javascript" src="'. $config->get('sysURL'). 'alpha/lib/jquery/contextMenu/jquery.contextMenu.js"></script>';
$html.= '<script type="text/javascript" src="'. $config->get('sysURL'). 'alpha/lib/jquery/ui/jquery.ui.potato.menu.js"></script>';
$html.= '<script type="text/javascript" src="'. $config->get('sysURL'). 'alpha/lib/jquery/ui/jquery-ui-1.7.2.custom.min.js"></script>';
$html.= '<script type="text/javascript" src="'. $config->get('sysURL'). 'alpha/lib/jquery/ui/ui.datepicker.js"></script>';
if($config->get('sysForceFrame')) {
// if no-forceframe=true or we are in the admin backend, don't force frame
if(!isset ($_GET['no-forceframe']) && strpos($_SERVER['REQUEST_URI'], '/tk/') === false) {
$html.= '<script type="text/javascript">';
$html.= 'pageLoc = self.location;';
$html.= 'pageAdd = top.location;';
$html.= 'if (pageLoc == pageAdd) {';
$html.= ' contentSrc = escape(pageLoc);';
$html.= ' contPage = \''. $config->get('sysURL'). '?\' + contentSrc;';
$html.= ' top.location.href = contPage;';
$html.= '<script type="text/javascript">';
if (isset ($_SESSION['currentUser']) && AlphaDAO::isInstalled() && $_SESSION['currentUser']->inGroup('Admin') && strpos($_SERVER['REQUEST_URI'], '/tk/') !== false) {
$html.= '<script type="text/javascript">';
$html.= ' (function($) {';
$html.= ' $(document).ready(function(){';
$html.= ' $("#adminmenu").ptMenu();';
// general dialog defaults
$html.= '<script type="text/javascript">';
$html.= ' (function($) {';
$html.= ' var dialogCoords = [(screen.width/2)-200, (screen.height/2)-200];';
$html.= ' $(document).ready(function(){';
$html.= ' $.extend($.ui.dialog.defaults, {';
$html.= ' resizable: false,';
$html.= ' draggable: false,';
$html.= ' autoOpen: false,';
$html.= ' position: dialogCoords,';
$html.= ' "Cancel": function() {';
$html.= ' $(this).dialog("close");';
$html.= '<script type="text/javascript">';
$html.= ' (function($) {';
$html.= ' $(document).ready(function(){';
$html.= ' var dialogOpts = {';
$html.= ' title: "Record selector",';
$html.= ' resizable: false,';
$html.= ' draggable: false,';
$html.= ' autoOpen: false,';
$html.= ' $("#recordSelector").dialog(dialogOpts);';
if(method_exists($controller, 'during_displayPageHead_callback'))
$html.= $controller->during_displayPageHead_callback();
if($controller->getBO() != null)
$html.= '<body'. ($controller->getBO()->get('bodyOnload') != '' ? ' onload="'. $controller->getBO()->get('bodyOnload'). '"' : ''). '>';
if(method_exists($controller, 'insert_CMSDisplayStandardHeader_callback'))
$html.= $controller->insert_CMSDisplayStandardHeader_callback();
$html .= '<div id="recordSelector"></div>';
if($controller->getTitle() != '')
$html.= '<h1>'. $controller->getTitle(). '</h1>';
if (isset ($_SESSION['currentUser'])) {
$html.= '<p>You are logged in as '. $_SESSION['currentUser']->getDisplayname(). '. <a href="'. FrontController::generateSecureURL('act=Logout'). '">Logout</a></p>';
if ($renderMenu && isset ($_SESSION['currentUser']) && AlphaDAO::isInstalled() && $_SESSION['currentUser']->inGroup('Admin') && strpos($_SERVER['REQUEST_URI'], '/tk/') !== false) {
$html .= '<ul id="adminmenu" class="potato-menu">
<li><a href="'. $config->get('sysURL'). '">Home</a></li>
<li><a href="#">Logs »</a>
$html.= $controller->after_displayPageHead_callback();
// render a status message if there is any
$message = $controller->getStatusMessage();
self::$logger->debug('<<displayPageHead ['. $html. ']');
* Method to render the page footer HTML
* @param AlphaController $controller
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>displayPageFoot(controller=['. get_class($controller). '])');
if(method_exists($controller, 'before_displayPageFoot_callback'))
$html .= $controller->before_displayPageFoot_callback();
$html .= '<div id="dialogDiv"></div>';
$this->after_displayPageFoot_callback();
self::$logger->debug('<<displayPageFoot ['. $html. ']');
* Renders the HTML for an update (e.g. successful save) message
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>displayUpdateMessage(message=['. $message. '])');
$html = '<div class="ui-state-highlight ui-corner-all" style="padding: 0pt 0.7em;">
<p><span class="ui-icon ui-icon-info" style="float: left; margin-right: 0.3em;"></span>
<strong>Update:</strong> '. $message. '</p></div>';
self::$logger->debug('<<displayUpdateMessage ['. $html. ']');
* Renders the HTML for an error (e.g. save failed) message
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>displayErrorMessage(message=['. $message. '])');
$html = '<div class="ui-state-error ui-corner-all" style="padding: 0pt 0.7em;">
<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: 0.3em;"></span>
<strong>Error:</strong> '. $message. '</p></div>';
self::$logger->debug('<<displayErrorMessage ['. $html. ']');
* Renders a HTML error page with the supplied error code (typlically a HTTP code) and a message
$html .= '<link rel="StyleSheet" type="text/css" href="'. $config->get('sysURL'). 'alpha/lib/jquery/ui/themes/'. $config->get('sysTheme'). '/ui.all.css">';
$html .= '<link rel="StyleSheet" type="text/css" href="'. $config->get('sysURL'). 'alpha/css/alpha.css">';
$html .= '<link rel="StyleSheet" type="text/css" href="'. $config->get('sysURL'). 'config/css/overrides.css">';
$html .= '<title>'. $code. ' - '. $message. '</title></head>';
$html .= '<div class="ui-state-error ui-corner-all" style="padding: 0pt 0.7em;">
<p><span class="ui-icon ui-icon-alert" style="float: left; margin-right: 0.3em;"></span>
<strong>'. $code. ':</strong> '. $message. '</p>
$html .= '</body></html>';
* Method to render a hidden form for posting the OID of an object to be deleted
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>renderDeleteForm()');
$html = '<form action="'. $_SERVER['REQUEST_URI']. '" method="POST" id="deleteForm">';
$html .= '<input type="hidden" name="deleteOID" id="deleteOID" value=""/>';
$html .= self::renderSecurityFields();
self::$logger->debug('<<renderDeleteForm ['. $html. ']');
* Method to render a HTML form with two hidden, hashed (MD5) form fields to be used as
* a check to ensure that a post to the controller is being sent from the same server
if(self::$logger == null)
self::$logger = new Logger('AlphaView');
self::$logger->debug('>>renderSecurityFields()');
$fields = AlphaController::generateSecurityFields();
$html .= '<input type="hidden" name="var1" value="'. $fields[0]. '"/>';
$html .= '<input type="hidden" name="var2" value="'. $fields[1]. '"/>';
self::$logger->debug('<<renderSecurityFields ['. $html. ']');
* Method to render the default Integer HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
self::$logger->debug('>>renderIntegerField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
$html .= '<tr><th style="width:25%;">';
$html .= '<input type="text" style="width:100%;" name="'. $name. '" value="'. (isset ($_POST[$name]) ? $_POST[$name] : ''). '"/><br>';
$html .= '<input type="text" style="width:100%;" name="'. $name. '" value="'. (isset ($_POST[$name]) ? $_POST[$name] : ''). '"/><br>';
$html .= '<tr><th style="width:25%;">';
$html .= '<input type="text" style="width:100%;" name="'. $name. '" value="'. $value. '"/><br>';
$html .= '<input type="text" style="width:100%;" name="'. $name. '" value="'. $value. '"/>';
self::$logger->debug('<<renderIntegerField ['. $html. ']');
* Method to render the default Double HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
public static function renderDoubleField($name, $label, $mode, $value= '', $tableTags= true) {
self::$logger->debug('>>renderDoubleField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
$html .= '<tr><th style="width:25%;">';
$html .= '<input type="text" size="13" name="'. $name. '" value="'. (isset ($_POST[$name]) ? $_POST[$name] : ''). '"/><br>';
$html .= '<input type="text" size="13" name="'. $name. '" value="'. (isset ($_POST[$name]) ? $_POST[$name] : ''). '"/>';
$html .= '<tr><th style="width:25%;">';
$html .= '<input type="text" size="13" name="'. $name. '" value="'. $value. '"/><br>';
$html .= '<input type="text" size="13" name="'. $name. '" value="'. $value. '"/>';
self::$logger->debug('<<renderDoubleField ['. $html. ']');
* Method to render the default Boolean HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
self::$logger->debug('>>renderBooleanField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
$html .= '<tr><th style="width:25%;">';
$html .= '<select size="1" name="'. $name. '"/>';
$html .= '<option value="0" selected>N</option>';
$html .= '<option value="1">Y</option>';
$html .= '</select><br>';
$html .= '<select size="1" name="'. $name. '"/>';
$html .= '<option value="0" selected>N</option>';
$html .= '<option value="1">Y</option>';
$html .= '<select size="1" name="'. $name. '"/>';
$html .= '<option value="0" '. ($value == '0'? 'selected': ''). '>N</option>';
$html .= '<option value="1" '. ($value == '1'? 'selected': ''). '>Y</option>';
$html .= '</select><br>';
$html .= '<select size="1" name="'. $name. '"/>';
$html .= '<option value="0" '. ($value == '0'? 'selected': ''). '>N</option>';
$html .= '<option value="1" '. ($value == '1'? 'selected': ''). '>Y</option>';
self::$logger->debug('<<renderBooleanField ['. $html. ']');
* Method to render the default Enum HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param array $options The Enum options
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
public function renderEnumField($name, $label, $mode, $options, $value= '', $tableTags= true) {
self::$logger->debug('>>renderEnumField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
$html .= '<tr><th style="width:25%;">';
$html .= '<select name="'. $name. '"/>';
foreach ($options as $val) {
$html .= '<option value="'. $val. '">'. $val. '</option>';
$html .= '</select><br>';
$html .= '<select name="'. $name. '"/>';
foreach ($options as $val) {
$html .= '<option value="'. $val. '">'. $val. '</option>';
$html .= '<tr><th style="width:25%;">';
$html .= '<select name="'. $name. '"/>';
foreach ($options as $val) {
$html .= '<option value="'. $val. '" selected>'. $val. '</option>';
$html .= '<option value="'. $val. '">'. $val. '</option>';
$html .= '</select><br>';
$html .= '<select name="'. $name. '"/>';
foreach ($options as $val) {
$html .= '<option value="'. $val. '" selected>'. $val. '</option>';
$html .= '<option value="'. $val. '">'. $val. '</option>';
self::$logger->debug('<<renderEnumField ['. $html. ']');
* Method to render the default DEnum HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param array $options The DEnum options
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
public function renderDEnumField($name, $label, $mode, $options, $value= '', $tableTags= true) {
self::$logger->debug('>>renderDEnumField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
$html .= '<tr><th style="width:25%;">';
$html .= '<select name="'. $name. '"/>';
foreach (array_keys($options) as $index) {
$html .= '<option value="'. $index. '">'. $options[$index]. '</option>';
$html .= '</select><br>';
$html .= '<select name="'. $name. '"/>';
$html .= '<option value="'. $index. '">'. $options[$index]. '</option>';
$html .= '<tr><th style="width:25%;">';
$html .= '<select name="'. $name. '"/>';
$html .= '<option value="'. $index. '" selected>'. $options[$index]. '</option>';
$html .= '<option value="'. $index. '">'. $options[$index]. '</option>';
$html .= '</select><br>';
$html .= '<select name="'. $name. '"/>';
$html .= '<option value="'. $index. '" selected>'. $options[$index]. '</option>';
$html .= '<option value="'. $index. '">'. $options[$index]. '</option>';
self::$logger->debug('<<renderDEnumField ['. $html. ']');
* Method to render the default field HTML when type is not known
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
self::$logger->debug('>>renderDefaultField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
$html .= '<tr><th colspan="2">';
$html .= '<tr><td colspan="2">';
$html .= '<textarea cols="100" rows="3" name="'. $name. '">'. (isset ($_POST[$name]) ? $_POST[$name] : ''). '</textarea><br>';
$html .= '<textarea cols="100" rows="3" name="'. $name. '">'. (isset ($_POST[$name]) ? $_POST[$name] : ''). '</textarea>';
$html .= '<tr><th colspan="2">';
$html .= '<tr><td colspan="2">';
$html .= '<textarea cols="100" rows="3" name="'. $name. '">'. $value. '</textarea><br>';
$html .= '<textarea cols="100" rows="3" name="'. $name. '">'. $value. '</textarea>';
if(method_exists($this, 'during_renderDefaultField_callback'))
$html .= $this->during_renderDefaultField_callback($name, $mode, $value);
self::$logger->debug('<<renderDefaultField ['. $html. ']');
* render the default Text HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
public function renderTextField($name, $label, $mode, $value= '', $tableTags= true) {
self::$logger->debug('>>renderTextField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '])');
// give 10 rows for content fields (other 5 by default)
$text = new TextBox($this->BO->getPropObject($name), $label, $name, 10);
$text = new TextBox($this->BO->getPropObject($name), $label, $name);
$html .= $text->render($tableTags);
// give 10 rows for content fields (other 5 by default)
if($viewState->get('markdownTextBoxRows') == '')
$text = new TextBox($this->BO->getPropObject($name), $label, $name, 10);
$text = new TextBox($this->BO->getPropObject($name), $label, $name, (integer) $viewState->get('markdownTextBoxRows'));
$html .= $text->render($tableTags, true);
$text = new TextBox($this->BO->getPropObject($name), $label, $name);
$html .= $text->render($tableTags);
// ensures that line returns are rendered
self::$logger->debug('<<renderTextField ['. $html. ']');
* render the default Relation HTML
* @param string $name The field name
* @param string $label The label to apply to the field
* @param string $mode The field mode (create/edit/view)
* @param string $value The field value (optional)
* @param bool $tableTags Include table tags and label (optional)
* @param bool $expanded Render the related fields in expanded format or not (optional)
* @param bool $buttons Render buttons for expanding/contacting the related fields (optional)
public function renderRelationField($name, $label, $mode, $value= '', $tableTags= true, $expanded= false, $buttons= true) {
self::$logger->debug('>>renderRelationField(name=['. $name. '], label=['. $label. '], mode=['. $mode. '], value=['. $value. '], tableTags=['. $tableTags. '], expanded=['. $expanded. '], buttons=['. $buttons. '])');
$rel = $this->BO->getPropObject($name);
if ($mode == 'create' || $mode == 'edit') {
if($rel->getRelationType() == 'MANY-TO-MANY') {
// check to see if the rel is on this class
$rel->getSide(get_class($this->BO));
$html .= $widget->render($tableTags, $expanded, $buttons);
// the rel may be on a parent class
$parentClassName = ucfirst($this->BO->getTableName()). 'Object';
$html .= $widget->render($tableTags, $expanded, $buttons);
$html .= $rel->render($tableTags, $expanded, $buttons);
if($rel->getRelationType() == 'MANY-TO-ONE') {
$html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue());
}elseif($rel->getRelationType() == 'MANY-TO-MANY') {
// check to see if the rel is on this class
// the rel may be on a parent class
$parentClassName = ucfirst($this->BO->getTableName()). 'Object';
$html .= $this->renderDefaultField($name, $label, 'view', $rel->getRelatedClassDisplayFieldValue($parentClassName));
$html .= $rel->render($tableTags, $expanded, $buttons);
self::$logger->debug('<<renderRelationField ['. $html. ']');
* Renders all fields for the current BO in edit/create/view mode
* @param string $mode (view|edit|create)
* @param array $filterFields Optional list of field names to exclude from rendering
* @param array $readOnlyFields Optional list of fields to render in a readonly fashion when rendering in create or edit mode
public function renderAllFields($mode, $filterFields= array(), $readOnlyFields= array()) {
self::$logger->debug('>>renderAllFields(mode=['. $mode. '], filterFields=['. var_export($filterFields, true). '], readOnlyFields=['. var_export($readOnlyFields, true). '])');
// get the class attributes
foreach($properties as $propName) {
if (!in_array($propName, $this->BO->getDefaultAttributes()) && !in_array($propName, $filterFields)) {
// render readonly fields in the supplied array
if(in_array($propName, $readOnlyFields))
$propClass = get_class($this->BO->getPropObject($propName));
// exclude non-Relation transient attributes from create and edit screens
if($propClass != 'Relation' && ($mode == 'edit' || $mode == 'create') && in_array($propName, $this->BO->getTransientAttributes())) {
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
$html .= $this->renderIntegerField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
$html .= $this->renderDoubleField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
$value = $this->BO->get($propName);
if ($value == '0000-00-00')
$date = new DateBox($this->BO->getPropObject($propName), $this->BO->getDataLabel($propName), $propName);
$html .= $date->render();
$value = $this->BO->get($propName);
if ($value == '0000-00-00 00:00:00')
$timestamp = new DateBox($this->BO->getPropObject($propName), $this->BO->getDataLabel($propName), $propName);
$html .= $timestamp->render();
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
$string = new StringBox($this->BO->getPropObject($propName), $this->BO->getDataLabel($propName), $propName);
$html .= $string->render();
$html .= $this->renderTextField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
$html .= $this->renderBooleanField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->get($propName));
$enum = $this->BO->getPropObject($propName);
$html .= $this->renderEnumField($propName, $this->BO->getDataLabel($propName), $mode, $enum->getOptions(), $this->BO->get($propName));
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), 'view', $this->BO->getPropObject($propName)->getDisplayValue());
$denum = $this->BO->getPropObject($propName);
$html .= $this->renderDEnumField($propName, $this->BO->getDataLabel($propName), $mode, $denum->getOptions(), $this->BO->get($propName));
$html .= $this->renderRelationField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
$html .= $this->renderDefaultField($propName, $this->BO->getDataLabel($propName), $mode, $this->BO->get($propName));
self::$logger->debug('<<renderAllFields ['. $html. ']');
* Loads a .phtml template for the BO specified if one exists. Lower level custom templates
* @throws IllegalArguementException
self::$logger->debug('>>loadTemplate(BO=['. var_export($BO, true). '], mode=['. $mode. '], fields=['. var_export($fields, true). '])');
// for each BO property, create a local variable holding its value
$reflection = new ReflectionClass(get_class($this->BO));
$properties = $reflection->getProperties();
foreach($properties as $propObj) {
$propName = $propObj->name;
if($propName != 'logger' && !$propObj->isPrivate()) {
if(get_class($BO->getPropObject($propName)) == 'DEnum') {
$ {$propName} = $BO->getPropObject($propName)->getDisplayValue();
$ {$propName} = $BO->get($propName);
// loop over the $fields array and create a local variable for each key value
$ {$fieldName} = $fields[$fieldName];
$filename = $mode. '.phtml';
$customPath = $config->get('sysRoot'). 'view/templates/'. $classTemplateDir. '/'. $filename;
$defaultPath1 = $config->get('sysRoot'). 'alpha/view/templates/'. $classTemplateDir. '/'. $filename;
$defaultPath2 = $config->get('sysRoot'). 'alpha/view/templates/'. $filename;
// Check to see if a custom template exists for this BO, and if it does load that
self::$logger->debug('Loading template ['. $customPath. ']');
}elseif (file_exists($defaultPath1)) {
self::$logger->debug('Loading template ['. $defaultPath1. ']');
}elseif (file_exists($defaultPath2)) {
self::$logger->debug('Loading template ['. $defaultPath2. ']');
throw new IllegalArguementException('No ['. $mode. '] HTML template found for class ['. get_class($BO). ']');
self::$logger->debug('<<loadTemplate');
|