Changed the app controller jqGrid virtual functions for getting the tables for both count and the full query. The ExtraTables bit was too confusing, and was only intended to allow the user to specify a subset for count and augment it for full query. This is easily accomplished by having DataTables just call DataCountTables first... one line solution ends the confusion.
Modified linkable behavior to support a %{MODEL_ALIAS} tag, which is replaced in the relationship conditions at runtime with the actual model alias. This is experimental at best, and certainly will create a problem for any model that ends up using the conditions in 'contain' instead of 'link'.
Broke the LedgerEntry->findInLedgerContext function out into multiple pieces, so those same pieces could be used in the LedgerEntries controller to populate jqGrid.
Changed the ledger_entries element, as a special case, to also allow listing control from ledger_id and account_type, instead of idlist as a mechanism for populating the grid.
Changed the infobox summary css, which will break several pages until I rework them.
Some next steps include fixing the broken infoboxes, and changing the transactions view to use the ledger_entries element. This also means the ledger_entries element will need to add support for idlist, or if we have any credit/debit issues, perhaps another custom transaction_id instead.
git-svn-id: file:///svn-source/pmgr/branches/ledger_transactions_20090605@134 97e9348a-65ac-dc4b-aefc-98561f571b83
371 lines
12 KiB
PHP
371 lines
12 KiB
PHP
<?php
|
|
/* SVN FILE: $Id: app_controller.php 7945 2008-12-19 02:16:01Z gwoo $ */
|
|
/**
|
|
* Short description for file.
|
|
*
|
|
* This file is application-wide controller file. You can put all
|
|
* application-wide controller-related methods here.
|
|
*
|
|
* PHP versions 4 and 5
|
|
*
|
|
* CakePHP(tm) : Rapid Development Framework (http://www.cakephp.org)
|
|
* Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
*
|
|
* Licensed under The MIT License
|
|
* Redistributions of files must retain the above copyright notice.
|
|
*
|
|
* @filesource
|
|
* @copyright Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
|
|
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
|
|
* @package cake
|
|
* @subpackage cake.app
|
|
* @since CakePHP(tm) v 0.2.9
|
|
* @version $Revision: 7945 $
|
|
* @modifiedby $LastChangedBy: gwoo $
|
|
* @lastmodified $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
|
|
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
|
*/
|
|
/**
|
|
* Short description for class.
|
|
*
|
|
* Add your application-wide methods in the class below, your controllers
|
|
* will inherit them.
|
|
*
|
|
* @package cake
|
|
* @subpackage cake.app
|
|
*/
|
|
class AppController extends Controller {
|
|
var $helpers = array('Html', 'Form', 'Javascript', 'Format', 'Time');
|
|
var $components = array('DebugKit.Toolbar');
|
|
|
|
function sideMenuLinks() {
|
|
return array(
|
|
array('name' => 'Common', 'header' => true),
|
|
array('name' => 'Site Map', 'url' => array('controller' => 'maps', 'action' => 'view', 1)),
|
|
array('name' => 'Units', 'url' => array('controller' => 'units', 'action' => 'index')),
|
|
array('name' => 'Leases', 'url' => array('controller' => 'leases', 'action' => 'index')),
|
|
array('name' => 'Customers', 'url' => array('controller' => 'customers', 'action' => 'index')),
|
|
array('name' => 'Contacts', 'url' => array('controller' => 'contacts', 'action' => 'index')),
|
|
array('name' => 'Accounts', 'url' => array('controller' => 'accounts', 'action' => 'index')),
|
|
array('name' => 'Ledgers', 'url' => array('controller' => 'ledgers', 'action' => 'index')),
|
|
);
|
|
}
|
|
|
|
function beforeRender() {
|
|
$this->set('sidemenu', $this->sideMenuLinks());
|
|
}
|
|
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* helper: jqGridView
|
|
* - called by function to create an index listing
|
|
*/
|
|
|
|
function jqGridView($title, $action = null) {
|
|
$this->set('title', $title);
|
|
// The resulting page will contain a jqGrid, which will
|
|
// use ajax to obtain the actual data for this action
|
|
$this->set('action', $action ? $action : $this->params['action']);
|
|
$this->render('/elements/' . $this->params['controller']);
|
|
}
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* action: jqGridData
|
|
* - Fetches the actual data requested by jqGrid as XML
|
|
*/
|
|
|
|
function jqGridData() {
|
|
// 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->jqGridDataSetup($params);
|
|
|
|
// Get the top level model for this grid
|
|
$model = $this->jqGridDataModel($params);
|
|
|
|
// Establish the basic query and conditions
|
|
$query = array_intersect_key($this->jqGridDataCountTables($params, $model),
|
|
array('link'=>1, 'contain'=>1));
|
|
$query['conditions'] = $this->jqGridDataConditions($params, $model);
|
|
|
|
// Get the number of records prior to pagination
|
|
$count = $this->jqGridDataRecordCount($params, $model, $query);
|
|
|
|
// Start the query over, this time getting the actual set
|
|
// of tables needed, not just those needed for counting.
|
|
$query = array_intersect_key($this->jqGridDataTables($params, $model),
|
|
array('link'=>1, 'contain'=>1));
|
|
$query['conditions'] = $this->jqGridDataConditions($params, $model);
|
|
|
|
// Verify a few parameters and determine our starting row
|
|
$limit = $params['rows'];
|
|
$total = ($count < 0) ? 0 : ceil($count/$limit);
|
|
$page = ($params['page'] <= 1) ? 1 : (($params['page'] > $total) ? $total : $params['page']);
|
|
$start = $limit*$page - $limit;
|
|
|
|
// Grab the actual records taking pagination into account
|
|
$query['group'] = $model->alias.'.'.$model->primaryKey;
|
|
$query['order'] = $this->jqGridDataOrder($params, $model,
|
|
isset($params['sidx']) ? $params['sidx'] : null,
|
|
isset($params['sord']) ? $params['sord'] : null);
|
|
$query['limit'] = $this->jqGridDataLimit($params, $model, $start, $limit);
|
|
$query['fields'] = $this->jqGridDataFields($params, $model);
|
|
$results = $this->jqGridDataRecords($params, $model, $query);
|
|
|
|
// Post process the records
|
|
$this->jqGridRecordsPostProcess($params, $model, $results);
|
|
|
|
// Add in any needed hyperlinks
|
|
$this->jqGridRecordLinks($params, $model, $results, array());
|
|
|
|
// DEBUG PURPOSES ONLY!
|
|
$params['query'] = $query;
|
|
|
|
// Finally, dump out the data
|
|
$this->jqGridDataOutputHeader($params, $model);
|
|
echo "<?xml version='1.0' encoding='utf-8'?>\n";
|
|
echo "<rows>\n";
|
|
$this->jqGridDataOutputSummary($params, $model, $page, $total, $count);
|
|
$this->jqGridDataOutputRecords($params, $model, $results);
|
|
echo "</rows>\n";
|
|
|
|
// Call out to finalize everything
|
|
$this->jqGridDataFinalize($params);
|
|
}
|
|
|
|
/**************************************************************************
|
|
**************************************************************************
|
|
**************************************************************************
|
|
* virtual: jqGridData* functions
|
|
* - These set up the context for the jqGrid data, and will
|
|
* need to be overridden in the derived class for anything
|
|
* other than the most basic of grids.
|
|
*/
|
|
|
|
function jqGridDataSetup(&$params) {
|
|
// Assume we're debugging.
|
|
// The actual jqGrid request will set this to false
|
|
$debug = true;
|
|
|
|
if (isset($this->passedArgs['debug']))
|
|
$debug = $this->passedArgs['debug'];
|
|
|
|
$params['debug'] = $debug;
|
|
|
|
if (!$debug) {
|
|
$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 fields
|
|
// This SHOULD always be set, except when debugging
|
|
if (isset($params['fields']))
|
|
$params['fields'] = unserialize($params['fields']);
|
|
else
|
|
$params['fields'] = array($this->{$this->modelClass}->alias
|
|
.'.'.
|
|
$this->{$this->modelClass}->primarKey);
|
|
|
|
// Unserialize the list of ids, if present.
|
|
if (isset($params['custom']))
|
|
$params['custom'] = unserialize($params['custom']);
|
|
else
|
|
$params['custom'] = null;
|
|
|
|
// Unserialize the list of ids, if present.
|
|
if (isset($params['idlist']))
|
|
$params['idlist'] = unserialize($params['idlist']);
|
|
|
|
}
|
|
|
|
function jqGridDataModel(&$params) {
|
|
return $this->{$this->modelClass};
|
|
}
|
|
|
|
function jqGridDataCountTables(&$params, &$model) {
|
|
// If not overridden, we use the same tables to
|
|
// perform our count as we do to for the actual query
|
|
return $this->jqGridDataTables($params, $model);
|
|
}
|
|
|
|
function jqGridDataTables(&$params, &$model) {
|
|
return array('contain' => false);
|
|
}
|
|
|
|
function jqGridDataConditions(&$params, &$model) {
|
|
$searches = array();
|
|
|
|
if (isset($params['_search']) && $params['_search'] === 'true') {
|
|
if (isset($params['searchOper'])) {
|
|
$searches[] = array('op' => $params['searchOper'],
|
|
'field' => $params['searchField'],
|
|
'value' => $params['searchString']);
|
|
}
|
|
else {
|
|
// DOH! Crappy mechanism puts toolbar search terms
|
|
// directly into params as name/value pairs. No
|
|
// way to know which elements of params are search
|
|
// terms, so skipping this at the moment.
|
|
}
|
|
}
|
|
elseif (isset($params['filt']) && $params['filt']) {
|
|
$searches[] = array('op' => 'bw',
|
|
'field' => $params['filtField'],
|
|
'value' => $params['filtValue']);
|
|
}
|
|
|
|
$ops = array('eq' => array('op' => null, 'pre' => '', 'post' => ''),
|
|
'ne' => array('op' => '<>', 'pre' => '', 'post' => ''),
|
|
'lt' => array('op' => '<', 'pre' => '', 'post' => ''),
|
|
'le' => array('op' => '<=', 'pre' => '', 'post' => ''),
|
|
'gt' => array('op' => '>', 'pre' => '', 'post' => ''),
|
|
'ge' => array('op' => '>=', 'pre' => '', 'post' => ''),
|
|
'bw' => array('op' => 'LIKE', 'pre' => '', 'post' => '%'),
|
|
'ew' => array('op' => 'LIKE', 'pre' => '%', 'post' => ''),
|
|
'cn' => array('op' => 'LIKE', 'pre' => '%', 'post' => '%'),
|
|
);
|
|
|
|
$conditions = array();
|
|
foreach ($searches AS $search) {
|
|
$op = $ops[$search['op']];
|
|
$field = $search['field'] . ($op['op'] ? ' '.$op['op'] : '');
|
|
$value = $op['pre'] . $search['value']. $op['post'];
|
|
$conditions[] = array($field => $value);
|
|
}
|
|
|
|
if (isset($params['action']) && $params['action'] === 'idlist') {
|
|
$conditions[] = array($model->alias.'.'.$model->primaryKey => $params['idlist']);
|
|
}
|
|
|
|
return $conditions;
|
|
}
|
|
|
|
function jqGridDataFields(&$params, &$model) {
|
|
return null;
|
|
}
|
|
|
|
function jqGridDataOrder(&$params, &$model, $index, $direction) {
|
|
return $index ? array($index .' '. $direction) : null;
|
|
}
|
|
|
|
function jqGridDataLimit(&$params, &$model, $start, $limit) {
|
|
return $start . ', ' . $limit;
|
|
}
|
|
|
|
function jqGridDataRecordCount(&$params, &$model, $query) {
|
|
return $model->find('count', $query);
|
|
}
|
|
|
|
function jqGridDataRecords(&$params, &$model, $query) {
|
|
return $model->find('all', $query);
|
|
}
|
|
|
|
function jqGridRecordsPostProcess(&$params, &$model, &$records) {
|
|
$model_alias = $model->alias;
|
|
$id = $model->primaryKey;
|
|
|
|
foreach ($records AS &$record) {
|
|
$record['jqGrid_id'] = $record[$model_alias][$id];
|
|
// Add the calculated fields (if any), to the model fields
|
|
if (isset($record[0])) {
|
|
$record[$model_alias] += $record[0];
|
|
unset($record[0]);
|
|
}
|
|
}
|
|
|
|
// DEBUG PURPOSES ONLY!
|
|
//$params['records'] = $records;
|
|
}
|
|
|
|
function jqGridRecordLinks(&$params, &$model, &$records, $links) {
|
|
foreach ($links AS $table => $fields) {
|
|
$controller = Inflector::pluralize(Inflector::underscore($table));
|
|
$id = 'id';
|
|
if (isset($fields['id']))
|
|
$id = $fields['id'];
|
|
foreach ($records AS &$record) {
|
|
foreach (array_diff_key($fields, array('id'=>1)) AS $field) {
|
|
// DEBUG PURPOSES ONLY!
|
|
//$params['linkrecord'][] = compact('table', 'field', 'id', 'controller', 'record');
|
|
$record[$table][$field] =
|
|
'<A HREF="' .
|
|
Router::url(array('controller' => $controller,
|
|
'action' => 'view',
|
|
$record[$table][$id])) .
|
|
'">' .
|
|
$record[$table][$field] .
|
|
'</A>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function jqGridDataOutputHeader(&$params, &$model) {
|
|
if ($params['debug']) {
|
|
ob_start();
|
|
}
|
|
else {
|
|
header("Content-type: text/xml;charset=utf-8");
|
|
}
|
|
}
|
|
|
|
function jqGridDataOutputSummary(&$params, &$model, $page, $total, $records) {
|
|
echo " <params><![CDATA[\n" . print_r($params, true) . "\n]]></params>\n";
|
|
echo " <page>$page</page>\n";
|
|
echo " <total>$total</total>\n";
|
|
echo " <records>$records</records>\n";
|
|
}
|
|
|
|
function jqGridDataOutputRecords(&$params, &$model, &$records) {
|
|
$model_alias = $model->alias;
|
|
$id = 'jqGrid_id';
|
|
|
|
foreach ($records AS $record) {
|
|
echo " <row id='{$record[$id]}'>\n";
|
|
foreach ($params['fields'] AS $field) {
|
|
if (preg_match("/\./", $field)) {
|
|
list($tbl, $col) = explode(".", $field);
|
|
$data = $record[$tbl][$col];
|
|
}
|
|
else {
|
|
$data = $record[$model_alias][$field];
|
|
}
|
|
|
|
// be sure to put text data in CDATA
|
|
if (preg_match("/^\d*$/", $data))
|
|
echo " <cell>$data</cell>\n";
|
|
else
|
|
echo " <cell><![CDATA[$data]]></cell>\n";
|
|
}
|
|
echo " </row>\n";
|
|
}
|
|
}
|
|
|
|
function jqGridDataFinalize(&$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<PRE>\n$xml\n</PRE>\n");
|
|
}
|
|
}
|
|
}
|
|
?>
|