common/ui/CorePage.php
<?php
/*******************************************************************************
Copyright 2012 Whole Foods Co-op
This file is part of CORE-POS.
IT CORE is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
IT CORE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
in the file license.txt along with IT CORE; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*********************************************************************************/
namespace COREPOS\common\ui;
/**
@class CorePage
Class for drawing screens
*/
class CorePage
{
public $description = "
Base class for creating HTML pages.
";
protected $onload_commands = array();
protected $scripts = array();
protected $css_files = array();
protected $error_text;
public $discoverable = true;
public $page_set = 'Misc';
public $doc_link = '';
protected $window_dressing = true;
public $has_unit_tests = false;
public $accepts = array();
/**
Instance of DB connection object
*/
protected $connection;
/**
Instance of logging object
*/
protected $logger;
/**
Instance of configuration object
*/
protected $config;
public function __construct()
{
$this->start_timestamp = microtime(true);
}
/**
DI Setter method for configuration
@param $fc [FannieConfig] configuration object
*/
public function setConfig($fc)
{
$this->config = $fc;
}
/**
DI Setter method for logging
@param $fl [FannieLogger] logging object
*/
public function setLogger($fl)
{
$this->logger = $fl;
}
/**
DI Setter method for database
@param $sql [SQLManager] database object
*/
public function setConnection($sql)
{
$this->connection = $sql;
}
/**
Toggle using menus
@param $menus boolean
*/
protected function hasMenus($menus)
{
$this->window_dressing = ($menus) ? true : false;
}
/**
preFlight is the very first method
called when drawing a page - even
prior to preprocess. Abstract children
i.e., child classes that act as parents
for grandchild classes, may use this method
to add functionality.
@return none
*/
protected function preFlight()
{
}
/**
postFlight is called very near the end of
execution. If the page was drawn, postFlight
is called prior to the closing body and HTML
tags. If the page was not drawn (preprocess
returned false), postFlight is called before
the script exits.
@return none
*/
protected function postFlight()
{
}
/**
Get the standard header
@return An HTML string
*/
protected function getHeader()
{
return '<!doctype html><html>';
}
/**
Get the standard footer
@return An HTML string
*/
protected function getFooter()
{
return '</html>';
}
/**
Handle pre-display tasks such as input processing
@return
- True if the page should be displayed
- False to stop here
Common uses include redirecting to a different module
and altering body content based on input
*/
public function preprocess()
{
return true;
}
/**
Define the main displayed content
@return An HTML string
*/
public function body_content()
{
}
public function bodyContent()
{
return $this->body_content();
}
public function errorContent()
{
return $this->error_text;
}
/**
Define any javascript needed
@return A javascript string
*/
protected function javascript_content()
{
}
protected function javascriptContent()
{
return $this->javascript_content();
}
/**
Add a script to the page using <script> tags
@param $file_url the script URL
@param $type the script type
*/
protected function addScript($file_url, $type='text/javascript')
{
$this->scripts[$file_url] = $type;
}
protected function addFirstScript($file_url, $type='text/javascript')
{
$new = array($file_url => $type);
foreach ($this->scripts as $url => $t) {
$new[$url] = $t;
}
$this->scripts = $new;
}
protected function addCssFile($file_url)
{
$this->css_files[] = $file_url;
}
/**
Define any CSS needed
@return A CSS string
*/
protected function css_content()
{
}
protected function cssContent()
{
return $this->css_content();
}
/**
Queue javascript commands to run on page load
*/
protected function add_onload_command($str)
{
$this->addOnloadCommand($str);
}
protected function addOnloadCommand($str)
{
$this->onload_commands[] = $str;
}
/**
Check if there are any problems
that might prevent the page from working
properly.
*/
protected function readinessCheck()
{
return true;
}
/**
Helper method
Check if a given table exists. Sets an appropriate message
in $error_text if the table is not present.
@param $database [string] database name
@param $table [string] table name
@return [boolean]
*/
protected function tableExistsReadinessCheck($database, $table)
{
$url = $this->config->get('URL');
$dbc = $this->connection;
$dbc->selectDB($database);
if (!$dbc->tableExists($table)) {
$this->error_text = "<p>Missing table {$database}.{$table}
<br /><a href=\"{$url}install/\">Click Here</a> to
create necessary tables.</p>";
return false;
}
return true;
}
/**
Helper method
Check if a given table has a specific column.
Sets an appropriate message
in $error_text if the column (or table) is not present.
@param $database [string] database name
@param $table [string] table name
@param $column [string] column name
@return [boolean]
*/
protected function tableHasColumnReadinessCheck($database, $table, $column)
{
$url = $this->config->get('URL');
if ($this->tableExistsReadinessCheck($database, $table) === false) {
return false;
}
$dbc = $this->connection;
$dbc->selectDB($database);
$definition = $dbc->tableDefinition($table);
if (!isset($definition[$column])) {
$this->error_text = "<p>Table {$database}.{$table} needs to be updated.
<br /><a href=\"{$url}install/InstallUpdatesPage.php\">Click Here</a> to
run updates.</p>";
return false;
}
return true;
}
public function unitTest($phpunit)
{
}
public function draw_page()
{
$this->drawPage();
}
/**
Check for input and display the page
*/
public function drawPage()
{
$this->preFlight();
if ($this->preprocess()) {
if ($this->window_dressing) {
echo $this->getHeader();
}
if ($this->readinessCheck() !== false) {
$body = $this->bodyContent();
} else {
$body = $this->errorContent();
}
if ($this->window_dressing) {
echo $body;
echo $this->getFooter();
} else {
$body = str_ireplace('</html>','',$body);
$body = str_ireplace('</body>','',$body);
echo $body;
}
$this->writeJS();
echo array_reduce($this->css_files,
function ($carry, $css_url) {
return $carry . sprintf('<link rel="stylesheet" type="text/css" href="%s">' . "\n",
$css_url);
},
''
);
$page_css = $this->css_content();
if (!empty($page_css)) {
echo '<style type="text/css">';
echo $page_css;
echo '</style>';
}
$this->postFlight();
echo '</body></html>';
} else {
$this->postFlight();
}
}
protected function writeJS()
{
foreach($this->scripts as $s_url => $s_type) {
printf('<script type="%s" src="%s"></script>',
$s_type, $s_url);
echo "\n";
}
$js_content = $this->javascriptContent();
if (!empty($js_content) || !empty($this->onload_commands)) {
echo '<script type="text/javascript">';
echo $js_content;
echo "\n\$(document).ready(function(){\n";
echo array_reduce($this->onload_commands, function($carry, $oc) { return $carry . $oc . "\n"; }, '');
echo "});\n";
echo '</script>';
}
}
public function baseTest($phpunit)
{
$phpunit->assertNotEquals(0, strlen($this->getHeader()));
$phpunit->assertNotEquals(0, strlen($this->getFooter()));
$this->addCssFile('/url.css');
$this->addScript('/url.css');
ob_start();
$this->drawPage();
$phpunit->assertNotEquals(0, strlen(ob_get_clean()));
include(dirname(__FILE__) . '/../../fannie/config.php');
$this->connection = new \COREPOS\common\SQLManager($FANNIE_SERVER, $FANNIE_SERVER_DBMS, $FANNIE_OP_DB, $FANNIE_SERVER_USER, $FANNIE_SERVER_PW, true);
$this->config = \FannieConfig::factory();
$phpunit->assertEquals(true, $this->tableExistsReadinessCheck($FANNIE_OP_DB, 'products'));
$phpunit->assertEquals(false, $this->tableExistsReadinessCheck($FANNIE_OP_DB, 'NOTproducts'));
$phpunit->assertEquals(true, $this->tableHasColumnReadinessCheck($FANNIE_OP_DB, 'products', 'upc'));
$phpunit->assertEquals(false, $this->tableHasColumnReadinessCheck($FANNIE_OP_DB, 'products', 'NOTupc'));
}
}