This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
khosb/modules/module.inc.php
2011-05-03 09:49:04 +10:00

573 lines
15 KiB
PHP

<?php
/**
* osBilling - Open Billing Software
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Originally authored by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
* @license http://www.gnu.org/licenses/
* @package AgileBill
* @subpackage Modules
*/
require_once(PATH_CORE.'xml.inc.php');
/**
* Module Abstract Class
* This abstract class provides the basic variables and methods for all modules.
*
* @package AgileBill
* @subpackage Modules
*/
abstract class OSB_module {
# Validation error array
public $val_error = array();
# Debug output to STDOUT
protected $debug = false;
# Inbound VAR value
protected $VAR = array();
# Object database ID & Record
private $record = array();
# Last Record ID read from DB
private $record_id = null;
/**
* Initialise the module
*/
public function __construct($id=null) {
global $VAR;
$this->VAR = $VAR;
if (isset($this->VAR['debug']) && $this->VAR['debug'])
$this->debug = true;
$f = sprintf('%s%s/%s_construct.xml',PATH_MODULES,get_class($this),get_class($this));
if (is_file($f)) {
# Open the construct file for parsing
$C_xml = new CORE_xml;
$construct = $C_xml->xml_to_array($f);
# Required attributes of the construct file.
foreach (array('module','table','field') as $index) {
if (! isset($construct['construct'][$index]))
printf('ERROR: Missing [%s] for [%s]',$index,$f);
else
$this->{$index} = $construct['construct'][$index];
}
# Optional attributes of the construct file.
foreach (array('method','trigger','cache','order_by','limit','title','tpl') as $index)
if (isset($construct['construct'][$index]))
$this->{$index} = $construct['construct'][$index];
# Bind our language translation path
bindtextdomain($this->module,PATH_LANGUAGE);
bind_textdomain_codeset($this->module,'UTF-8');
}
$this->sql_LoadRecord($id);
}
/**
* Return this record from the database
*/
protected function getRecord() {
return isset($this->record) ? $this->record : null;
}
protected function clearRecord() {
$this->record = array();
}
protected function delRecordAttr($attr) {
if (isset($this->record[$attr]))
unset($this->record[$attr]);
}
/**
* Return a field from the database record
*/
protected function getRecordAttr($attr) {
return isset($this->record[$attr]) ? $this->record[$attr] : null;
}
protected function setRecordAttr($attr,$value) {
$this->record[$attr] = $value;
return $value;
}
public function getlist() {
# Open the construct file for parsing
$C_xml = new CORE_xml;
$dh = opendir(PATH_MODULES);
$modules = array();
while ($module=readdir($dh))
if (! in_array($module,array('.','..')) && is_dir(PATH_MODULES.$module) && is_file($f=sprintf('%s/%s/%s_install.xml',PATH_MODULES,$module,$module))) {
$install = $C_xml->xml_to_array($f);
# Determine the type
if (! isset($install['install']['module_properties']['type']))
$type = 'plugin';
else
$type = $install['install']['module_properties']['type'];
# Store the data
foreach (array('parent','name','notes','sub_modules','dependancy','type','table-only','method-only') as $index)
if (isset($install['install']['module_properties'][$index]))
$modules[$type][$module][$index] = $install['install']['module_properties'][$index];
}
return $modules;
}
/**
* Basic module helper when interacting with the database.
*/
private function database($type,$VAR,$method=null) {
if ($type && ! is_array($this->method[$type]))
$this->method[$type] = explode(',',$this->method[$type]);
if (is_null($method) && $type)
$method = $type;
$db = new CORE_database;
if (method_exists($db,$method))
return $db->$method($VAR,$this,$type);
else {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,sprintf('Method doesnt exist'));
}
}
/**
* Export module helper
*/
private function export($type,$VAR,$method=null) {
# Require the export class
require_once(PATH_CORE.'export.inc.php');
$this->method[$type] = explode(',',$this->method[$type]);
if (is_null($method) && $type)
$method = $type;
$export = new CORE_export;
if (method_exists($export,$method))
$export->$method($VAR,$this,$type);
else {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,sprintf('Method doesnt exist'));
}
}
/** ADMIN INTERFACE METHODS **/
/**
* Add Records to the database
*/
public function add($VAR) {
if ($id = $this->database('add',$VAR))
return $id;
global $VAR;
# If update fails, return to the add page.
if (isset($VAR['_page']) && $VAR['_page'] == sprintf('%s:%s',$this->module,'view'))
$VAR['_page'] = sprintf('%s:%s',$this->module,'add');
return false;
}
/**
* Delete Records in the database
*/
public function delete($VAR) {
return $this->database('',$VAR,'mass_delete');
}
/**
* Search for Records in the database
*/
public function search($VAR) {
$this->database('search',$VAR);
}
/**
* Export Records from the database
*/
public function search_export($VAR) {
switch ($VAR['format']) {
case 'csv':
$this->export('export_csv',$VAR,'search_csv');
break;
case 'excel':
$this->export('export_excel',$VAR,'search_excel');
break;
case 'pdf':
$this->export('export_pdf',$VAR,'pdf_invoice');
break;
case 'tab':
$this->export('export_tab',$VAR,'search_tab');
break;
case 'xml':
$this->export('export_xml',$VAR,'search_xml');
break;
default:
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,sprintf('Export method doesnt exist'));
}
}
/**
* Search for Records in the database
*/
public function search_form($VAR) {
$this->database('search',$VAR,'search_form');
}
/**
* Show the Records from a Search in the database
*/
public function search_show($VAR) {
return $this->database('search',$VAR,'search_show');
}
/**
* Update Records in the database
*/
public function update($VAR) {
return $this->database('update',$VAR);
}
/**
* View a Record in the database
*/
public function view($VAR) {
#@todo implement showing the modified attributes if a update fails.
return $this->database('view',$VAR);
}
/** USER INTERFACE METHODS **/
/**
* Add Records to the database
*/
public function user_add($VAR) {
return $this->database('user_add',$VAR,'add');
}
/**
* Search for Records in the database
*/
public function user_search($VAR) {
if (! SESS_LOGGED) return false;
if (get_class($this) == 'discount')
$VAR[$this->module.'_avail_account_id'] = SESS_ACCOUNT;
else
$VAR[$this->module.'_account_id'] = SESS_ACCOUNT;
$this->database('search',$VAR);
}
/**
* Show the Records from a Search in the database
*/
public function user_search_show($VAR) {
if (! SESS_LOGGED) return false;
return $this->database('search',$VAR,'search_show');
}
/**
* Static Vars
*/
public function static_var($VAR) {
global $smarty;
require_once(PATH_CORE.'static_var.inc.php');
$static_var = new CORE_static_var;
if (preg_match('/search/',$VAR['_page']))
$arr = $static_var->generate_form($this->module,'add','search');
else
$arr = $static_var->generate_form($this->module,'add','update');
if (gettype($arr) == 'array') {
# Set everything as a smarty array, and return
$smarty->assign('show_static_var',true);
$smarty->assign('static_var',$arr);
return true;
} else {
# Or if no results
$smarty->assign('show_static_var',false);
return false;
}
}
/**
* Render the results of a search
*
* This function can also be used to only render the headers, and the tpl file can be responsible for rendering the data
*
* If $args is null, we only render the header
*/
public function tpl_search_show($VAR,$object,$args) {
global $C_list;
require_once(PATH_CORE.'translate.inc.php');
$C_translate = new CORE_translate;
list($class,$method) = explode(':',$VAR['_page']);
$method = strtolower($method);
if (! isset($this->tpl[$method]))
return;
# If we are only rendering the headers, then skip the table definitions
if (! is_null($args)) {
echo '<table width="100%" border="0" cellspacing="0" cellpadding="0" class="table_background"><tr><td>';
echo '<table width="100%" border="0" cellspacing="1" cellpadding="3">';
}
# Display the search heading
echo '<tr valign="middle" align="center" class="table_heading">';
foreach ($this->tpl[$method] as $index => $details) {
switch ($index) {
case 'blank':
case 'checkbox':
case 'icon':
case 'last':
printf('<td class="table_heading"%s>&nbsp;</td>',isset($details['width']) ? sprintf(' style="width: %s;"',$details['width']) : '');
break;
default:
printf('<td class="table_heading"%s>',isset($details['width']) ? sprintf(' style="width: %s;"',$details['width']) : '');
printf('<script type="text/javascript">document.write(search_heading(\'%s\',\'%s\'));</script>',
isset($details['translate'])
? $C_translate->translate($details['translate'],$this->module)
: $C_translate->tf(array('module'=>$this->module,'field'=>$details['field']),null),
$details['field']);
echo '</td>';
}
}
echo '</tr>';
# Loop through each record
if (is_array($args) && count($args[0])) {
foreach ($args[0] as $key => $values) {
printf('<tr id="row%s" onclick="row_sel(\'%s\',1);" ondblclick="window.location=\'?_page=%s:view&amp;id=%s\';" onmouseover="row_mouseover(\'%s\',\'row_mouse_over_select\',\'row_mouse_over\');" onmouseout="row_mouseout(\'%s\',\'%s\',\'row_select\');" class="%s">',
$values['id'],$values['id'],$this->module,$values['id'],$values['id'],$values['id'],$values['_C'],$values['_C']);
foreach ($this->tpl[$method] as $index => $details) {
switch ($details['type']) {
case 'bool':
printf('<td>%s</td>',$values[$details['field']] ? $C_translate->translate('true') : $C_translate->translate('false'));
break;
case 'bool_icon':
echo '<td>';
if ($values[$details['field']])
printf('<img src="themes/%s/images/icons/%s" alt="True" width="16" height="16" style="border: 0px;"/>',DEFAULT_THEME,isset($details['true']) ? $details['true'] : 'go_16.gif');
else
printf('<img src="themes/%s/images/icons/%s" alt="False" width="16" height="16" style="border: 0px;"/>',DEFAULT_THEME,isset($details['false']) ? $details['false'] : 'stop_16.gif');
echo '</td>';
break;
case 'checkbox':
echo '<td style="text-align: center">';
printf('<input type="checkbox" id="record%s" name="record%s" value="%s" onclick="row_sel(\'%s\',1,\'%s\');"/>',
$values['id'],$values['id'],$values['id'],$values['id'],$values['_C']);
printf('<script type="text/javascript">row_sel(\'%s\',0,\'%s\'); record_arr[i] = \'%s\'; i++;</script>',$values['id'],$values['_C'],$values['id']);
echo '</td>';
break;
case 'currency':
printf('<td>%s</td>',$C_list->format_currency($values[$details['field']],DEFAULT_CURRENCY));
break;
case 'date':
printf('<td>%s %s</td>',date(UNIX_DATE_FORMAT,$values[$details['field']]),date(DEFAULT_TIME_FORMAT,$values[$details['field']]));
break;
case 'literal':
printf('<td>%s</td>',str_replace('%%id%%',$values['id'],$details['data']));
break;
default:
printf('<td>&nbsp;%s</td>',$values[$details['field']]);
}
}
echo '</tr>';
}
}
if (! is_null($args)) {
echo '</table>';
echo '</td></tr></table>';
}
}
/**
* Get a record from the table by ID
*/
protected function getID($id) {
$db = &DB();
$record = $db->Execute(sqlSelect($db,$this->table,'*',array('id'=>$id)));
if ($record && $record->RecordCount() == 1)
return $record->fields;
else
return array();
}
/**
* Get a record from the table by Name
*/
protected function getName($name) {
$db = &DB();
$record = $db->Execute(sqlSelect($db,$this->table,'*',array('name'=>$name)));
if ($record && $record->RecordCount() == 1)
return $record->fields;
else
return array();
}
/**
* Graph Statistics
*/
public function graph($start,$end,$constraint,$default) {
global $C_translate;
$db = &DB();
$result = $db->Execute(sqlSelect($db,$this->table,sprintf('date_orig>=%s AND date_orig<=',$start,$end)));
if ($result->RecordCount() == 0) {
$arr['title'] = $C_translate->translate('search_no_results','','');
$arr['results'] = $default;
return $arr;
}
while (! $result->EOF) {
$d = $result->fields['date_orig'];
for ($i=0; $i<count($constraint); $i++) {
if ($d >= $constraint[$i]['start'] && $d < $constraint[$i]['end'])
$default[$i]++;
}
$result->MoveNext();
}
$C_translate->value[$this->table]['count'] = $result->RecordCount();
$title = $C_translate->translate('statistics',$this->table,'');
$arr['title'] = $title;
$arr['results'] = $default;
return $arr;
}
protected function sql_SaveRecord($noconvert=false,$ignoreval=false) {
global $VAR;
$lVAR = array();
if (is_array($VAR))
$lVAR = array_merge($VAR);
foreach ($this->record as $k => $v)
$lVAR[sprintf('%s_%s',$this->table,$k)] = $v;
$lVAR['_noredirect'] = true;
if ($noconvert)
$lVAR['_noconvert'] = true;
if ($ignoreval)
$lVAR['_ignoreval'] = true;
# Adding record
if (! isset($this->record['id']) || $this->record['id'] != $this->record_id)
return $this->add($lVAR);
else
return $this->update($lVAR);
}
protected function sql_LoadRecord($id) {
$record = $this->sql_GetRecords(array('where'=>array('id'=>$id)));
if (count($record) == 1) {
$this->record = array_pop($record);
$this->record_id = $id;
} else {
$this->record = null;
$this->record_id = null;
}
}
/**
* Get Data out of the tables for the module
*
* @return array Table records
*/
protected function sql_GetRecords($opt=array()) {
$db = &DB();
$data = array();
$result = $db->Execute(sqlSelect($this->table,'*',$opt));
if ($result && $result->RecordCount())
while (! $result->EOF) {
array_push($data,$result->fields);
$result->MoveNext();
}
return $data;
}
}
?>