array('SITE' => false, 'CONTROLLER' => false, 'ACTION' => false)); var $std_area = 10; var $new_area = 20; var $op_area = 30; var $admin_area = 40; var $dev_area = 50; function __construct() { $this->params['dev'] = false; $this->params['admin'] = false; parent::__construct(); } /************************************************************************** ************************************************************************** ************************************************************************** * function: sideMenuAreaVerify * - Verifies the validity of the sidemenu area/subarea/priority, * and ensures the class member is set to appropriately handle it. */ function sideMenuAreaVerify(&$area, $subarea, $priority = null) { $area = strtoupper($area); if (!array_key_exists($area, $this->sidemenu['areas'])) $this->INTERNAL_ERROR("Sidemenu link '{$area}': Unknown"); if ($area == 'SITE') $name = 'Navigation'; elseif ($area == 'CONTROLLER') $name = Inflector::humanize($this->params['controller']); elseif ($area == 'ACTION') $name = Inflector::humanize(Inflector::singularize($this->params['controller'])); if (empty($this->sidemenu['areas'][$area])) $this->sidemenu['areas'][$area] = array('enable' => true, 'name' => $name, 'subareas' => array()); if (empty($subarea)) return; $subname = $name; if ($subarea == $this->std_area) $subname .= ''; elseif ($subarea == $this->op_area) //$subname .= '-Ops'; $subname = 'Operations'; elseif ($subarea == $this->new_area) //$subname .= '-New'; $subname = 'Creation'; elseif ($subarea == $this->admin_area) $subname .= '-Admin'; elseif ($subarea == $this->dev_area) $subname .= '-Dev'; else $subname .= '-' . $subarea; if (empty($this->sidemenu['areas'][$area]['subareas'][$subarea])) $this->sidemenu['areas'][$area]['subareas'][$subarea] = array('enable' => true, 'name' => $subname, 'priorities' => array()); if (empty($priority)) return; if (empty($this->sidemenu['areas'][$area]['subareas'][$subarea]['priorities'][$priority])) $this->sidemenu['areas'][$area]['subareas'][$subarea]['priorities'][$priority] = array(); } /************************************************************************** ************************************************************************** ************************************************************************** * function: sideMenuAreaName * - Sets the name of the sidemenu area/subarea */ function sideMenuAreaName($name, $area, $subarea = null) { $this->sideMenuAreaVerify($area, $subarea); if (empty($subarea)) $this->sidemenu['areas'][$area]['name'] = $name; else $this->sidemenu['areas'][$area]['subareas'][$subarea]['name'] = $name; } /************************************************************************** ************************************************************************** ************************************************************************** * function: sideMenuAreaActivate * - Sets the selected area/subarea to be active when the * page is first loaded. */ function sideMenuAreaActivate($area, $subarea = null) { $this->sidemenu['active'] = compact('area', 'subarea'); } /************************************************************************** ************************************************************************** ************************************************************************** * function: sideMenuEnable * - Enables/Disables an area or subarea of the sidemenu */ function sideMenuEnable($area, $subarea = null, $enable = true) { $this->sideMenuAreaVerify($area, $subarea); if (isset($subarea)) $this->sidemenu['areas'][$area]['subareas'][$subarea]['enable'] = $enable; else $this->sidemenu['areas'][$area]['enable'] = $enable; } /************************************************************************** ************************************************************************** ************************************************************************** * function: addSideMenuLink * - Adds another link to the sidemenu area/subarea/priority */ function addSideMenuLink($name, $url, $extra, $area, $subarea = null, $priority = 10) { if (empty($subarea)) $subarea = $this->std_area; $this->sideMenuAreaVerify($area, $subarea); $this->sidemenu['areas'][$area]['subareas'][$subarea]['priorities'][$priority][] = array('name' => $name, 'url' => $url) + (empty($extra) ? array() : $extra); } /************************************************************************** ************************************************************************** ************************************************************************** * function: addDefaultSideMenuLinks * - Adds the standard links present on all generated pages */ function addDefaultSideMenuLinks() { $this->addSideMenuLink('Site Map', array('controller' => 'maps', 'action' => 'view', 1), null, 'SITE'); $this->addSideMenuLink('Units', array('controller' => 'units', 'action' => 'index'), null, 'SITE'); $this->addSideMenuLink('Leases', array('controller' => 'leases', 'action' => 'index'), null, 'SITE'); $this->addSideMenuLink('Customers', array('controller' => 'customers', 'action' => 'index'), null, 'SITE'); $this->addSideMenuLink('Deposits', array('controller' => 'transactions', 'action' => 'deposit'), null, 'SITE'); /* $this->addSideMenuLink('Move-In', */ /* array('controller' => 'customers', 'action' => 'move_in'), null, */ /* 'SITE', $this->op_area); */ /* $this->addSideMenuLink('Move-Out', */ /* array('controller' => 'customers', 'action' => 'move_out'), null, */ /* 'SITE', $this->op_area); */ /* $this->addSideMenuLink('New Receipt', */ /* array('controller' => 'customers', 'action' => 'receipt'), null, */ /* 'SITE', $this->op_area); */ /* $this->addSideMenuLink('New Customer', */ /* array('controller' => 'customers', 'action' => 'add'), null, */ /* 'SITE', $this->op_area); */ /* $this->addSideMenuLink('New Deposit', */ /* array('controller' => 'tenders', 'action' => 'deposit'), null, */ /* 'SITE', $this->op_area); */ $this->addSideMenuLink('Accounts', array('controller' => 'accounts', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Contacts', array('controller' => 'contacts', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Ledgers', array('controller' => 'ledgers', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Tenders', array('controller' => 'tenders', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Transactions', array('controller' => 'transactions', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Ldgr Entries', array('controller' => 'ledger_entries', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Stmt Entries', array('controller' => 'statement_entries', 'action' => 'index'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Assess Charges', array('controller' => 'leases', 'action' => 'assess_all'), null, 'SITE', $this->admin_area); $this->addSideMenuLink('Un-Nuke', '#', array('htmlAttributes' => array('onclick' => '$(".pr-section").show(); return false;')), 'SITE', $this->dev_area); $this->addSideMenuLink('New Ledgers', array('controller' => 'accounts', 'action' => 'newledger'), null, 'SITE', $this->dev_area); //array('name' => 'RESET DATA', array('controller' => 'accounts', 'action' => 'reset_data')); $this->sideMenuAreaName('Operations', 'SITE', $this->op_area); } /************************************************************************** ************************************************************************** ************************************************************************** * hook: beforeFilter * - Called just before the action function */ function beforeFilter() { $this->params['dev'] = (!empty($this->params['dev_route'])); $this->params['admin'] = (!empty($this->params['admin_route']) || !empty($this->params['dev_route'])); if (!$this->params['dev']) Configure::write('debug', '0'); $this->addDefaultSideMenuLinks(); $this->sideMenuEnable('SITE', $this->op_area, false); foreach ($this->sidemenu['areas'] AS $area_name => $area) { if (empty($this->params['dev'])) $this->sideMenuEnable($area_name, $this->dev_area, false); if (empty($this->params['admin'])) $this->sideMenuEnable($area_name, $this->admin_area, false); } } /************************************************************************** ************************************************************************** ************************************************************************** * hook: beforeRender * - Called just before rendering the page */ function beforeRender() { // Stupid Cake... our constructor sets admin/dev, // but cake stomps it somewhere along the way // after constructing the CakeError controller. if ($this->name === 'CakeError') { $this->params['dev'] = false; $this->params['admin'] = false; } foreach ($this->sidemenu['areas'] AS &$area) { if (empty($area['enable'])) $area = array(); if (empty($area['subareas'])) continue; ksort($area['subareas']); foreach ($area['subareas'] AS &$subarea) { if (empty($subarea['enable'])) $subarea = array(); if (empty($subarea['priorities'])) continue; ksort($subarea['priorities']); } unset($subarea); } unset($area); // Activate a default section (unless already specified) foreach (array_reverse($this->sidemenu['areas']) AS $area_name => $area) { if (empty($area)) continue; if (empty($this->sidemenu['active']) || empty($this->sidemenu['areas'][$this->sidemenu['active']['area']])) $this->sideMenuAreaActivate($area_name); } //pr($this->sidemenu); $this->set('sidemenu', $this->sidemenu); } /************************************************************************** ************************************************************************** ************************************************************************** * override: redirect */ function redirect($url, $status = null, $exit = true) { // OK, since the controller will not be able to // utilize our overriden url function in AppHelper, // we'll have to do it manually here. App::import('Helper', 'Html'); $url = HtmlHelper::url($url, true); if (headers_sent()) { // If we've already sent the headers, it's because // we're debugging, and our debug output has gotten // out before the redirect. That's probably a good // thing, as we don't typically want pages to be // jerked out from under us while trying to read // the debug output. So, since we can't redirect // anyway, we may as well go with the flow and just // render this page instead, using an empty template $this->set('message', ("Intended redirect:
" .
''.$url.''));
echo $this->render('/empty');
if ($exit)
$this->_stop();
}
return parent::redirect($url, $status, $exit);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* function: reset_data
* - Development function. TO BE DELETED
*/
function reset_data() {
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
Configure::write('debug', '0');
$script = $_SERVER['DOCUMENT_ROOT'] . '/pmgr/build.cmd';
echo "
" . date('r') . "\n"; //echo "
Script: $script" . "\n"; $db = & $this->Account->getDataSource(); $script .= ' "' . $db->config['database'] . '"'; $script .= ' "' . $db->config['login'] . '"'; $script .= ' "' . $db->config['password'] . '"'; $handle = popen($script . ' 2>&1', 'r'); //echo "
Handle: $handle; " . gettype($handle) . "\n"; echo "
\n";
while (($read = fread($handle, 2096))) {
echo $read;
}
echo "\n";
pclose($handle);
}
/**************************************************************************
**************************************************************************
**************************************************************************
* helper: gridView
* - called by derived controllers to create an index listing
*/
function gridView($title, $action = null, $element = null) {
$this->sideMenuEnable('SITE', $this->op_area);
$this->sideMenuAreaActivate('CONTROLLER');
$this->set('title', $title);
// The resulting page will contain a grid, which will
// use ajax to obtain the actual data for this action
$this->set('action', $action ? $action : $this->params['action']);
$this->render('/elements/' . ($element ? $element : $this->params['controller']));
}
/**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
* action: gridData
* - Fetches the actual data requested by grid as XML
*/
function gridData() {
// Grab a copy of the parameters that control this request
$params = array();
if (isset($this->params['url']) && is_array($this->params['url']))
$params = $this->params['url'];
// Do any preliminary setup necessary
$this->gridDataSetup($params);
// Get the top level model for this grid
$model = $this->gridDataModel($params);
// Get the number of records prior to pagination
$count = $this->gridDataCount($params, $model);
// Determine pagination configuration (and save to $params)
$pagination = $this->gridDataPagination($params, $model, $count);
// Retreive the appropriate subset of data
$records = $this->gridDataRecords($params, $model, $pagination);
// Post process the records
$this->gridDataPostProcess($params, $model, $records);
// Output the resulting record set
$this->gridDataOutput($params, $model, $records, $pagination);
// Call out to finalize everything
$this->gridDataFinalize($params);
}
/**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
**************************************************************************
* virtual: gridData* functions
* - These set up the context for the grid data, and will
* need to be overridden in the derived class for anything
* other than the most basic of grids.
*/
/**************************************************************************
**************************************************************************
**************************************************************************
* gridData SETUP / CLEANUP
*/
function gridDataModel(&$params) {
return $this->{$this->modelClass};
}
function gridDataSetup(&$params) {
// Debug only if requested
$params['debug'] = !empty($this->passedArgs['debug']);
if ($params['debug']) {
ob_start();
}
else {
$this->layout = null;
$this->autoLayout = false;
$this->autoRender = false;
Configure::write('debug', '0');
}
// Establish some defaults (except for serialized items)
$params = array_merge(array('page' => 1,
'rows' => 20),
$params);
// Unserialize our complex structure of post data.
// This SHOULD always be set, except when debugging
if (isset($params['post']))
$params['post'] = unserialize($params['post']);
else
$params['post'] = array();
// Unserialize our complex structure of dynamic post data
if (isset($params['dynamic_post']))
$params['dynamic_post'] = unserialize($params['dynamic_post']);
else
$params['dynamic_post'] = null;
// Unserialize our complex structure of dynamic post data
if (isset($params['dynamic_post_replace']))
$params['dynamic_post_replace'] = unserialize($params['dynamic_post_replace']);
else
$params['dynamic_post_replace'] = null;
// Merge the static and dynamic post data
if (!empty($params['dynamic_post']))
$params['post'] = array_merge_recursive($params['post'], $params['dynamic_post']);
if (!empty($params['dynamic_post_replace']))
$params['post'] = array_merge($params['post'], $params['dynamic_post_replace']);
// This SHOULD always be set, except when debugging
if (!isset($params['post']['fields']))
$params['post']['fields'] = array($this->{$this->modelClass}->alias
.'.'.
$this->{$this->modelClass}->primaryKey);
// Make sure the action parameter at least exists, and
// promote it to the top level (since it drives the operation).
if (isset($params['post']['action']))
$params['action'] = $params['post']['action'];
else
$params['action'] = null;
}
function gridDataFinalize(&$params) {
if ($params['debug']) {
$xml = ob_get_contents();
ob_end_clean();
$xml = preg_replace("/&/", "&", $xml);
$xml = preg_replace("/", "<", $xml);
$xml = preg_replace("/>/", ">", $xml);
echo ("\n\n$xml\n\n"); $this->render_empty(); } } /************************************************************************** ************************************************************************** ************************************************************************** * gridData COUNTING */ function gridDataCount(&$params, &$model) { // Establish the tables and conditions for counting $query = array_intersect_key($this->gridDataCountTableSet($params, $model), array('link'=>1, 'contain'=>1)); // Conditions for the count $query['conditions'] = $this->gridDataCountConditionSet($params, $model); // Grouping (which would not be typical) $query['group'] = $this->gridDataCountGroup($params, $model); // DEBUG PURPOSES ONLY! $params['count_query'] = $query; // Get the number of records prior to pagination return $this->gridDataCountExecute($params, $model, $query); } function gridDataCountExecute(&$params, &$model, $query) { return $model->find('count', $query); } function gridDataCountTables(&$params, &$model) { // Same tables for counting as for retreiving return $this->gridDataTables($params, $model); } function gridDataCountTableSet(&$params, &$model) { // Preliminary set of tables $query = array_intersect_key($this->gridDataCountTables($params, $model), array('link'=>1, 'contain'=>1)); // Perform filtering based on user request: $params['post']['filter'] return array_intersect_key($this->gridDataFilterTables($params, $model, $query), array('link'=>1, 'contain'=>1)); } function gridDataCountConditions(&$params, &$model) { // Same conditions for counting as for retreiving return $this->gridDataConditions($params, $model); } function gridDataCountConditionSet(&$params, &$model) { // Conditions for the count $conditions = $this->gridDataCountConditions($params, $model); // Perform filtering based on user request: $params['post']['filter'] return $this->gridDataFilterConditions($params, $model, $conditions); } function gridDataCountGroup(&$params, &$model) { // Grouping will screw up the count, since it // causes the results to be split into chunks // based on the GROUP BY clause. We can't have // more than one row of data in the count query, // just a _single_ row with the actual count. return null; } /************************************************************************** ************************************************************************** ************************************************************************** * gridData FILTERING */ function gridDataFilterTables(&$params, &$model, $query) { if (isset($query['contain'])) $link = 'contain'; else $link = 'link'; if (empty($params['post']['filter'])) return $query; foreach ($params['post']['filter'] AS $filter => $filter_value) { $split = $this->gridDataFilterSplit($params, $model, $filter, $filter_value); /* pr(array('AppController::gridDataFilterTable' => */ /* array('checkpoint' => "Filter split") */ /* + compact('split'))); */ $table = $this->gridDataFilterTablesTable($params, $model, $split['table']); if (!$table) continue; $config = $this->gridDataFilterTablesConfig($params, $model, $split['table']); /* pr(array('AppController::gridDataFilterTable' => */ /* array('checkpoint' => "Add filter config to query") */ /* + array('query[link]' => $query[$link]) */ /* + compact('config'))); */ // If the table is already part of the query, append to it if ($table == $model->alias) { $query[$link] = array_merge_recursive(array_diff_key($config, array('fields'=>1)), $query[$link]); } elseif (isset($query[$link][$table])) { $query[$link][$table] = array_merge_recursive($config, $query[$link][$table]); } elseif (in_array($table, $query[$link])) { // REVISIT