OSB enhancements to date

This commit is contained in:
Deon George
2010-11-30 09:41:08 +11:00
parent 8715a2059b
commit ec6a542bc3
478 changed files with 23423 additions and 9309 deletions

View File

@@ -92,8 +92,30 @@ class account extends OSB_module {
/** SMARTY METHODS **/
/**
* Get authorized groups
* Get a list of groups to which an account is a member of
*
* Accounts are always a member of group 0/2 (All Un & Registered Users)
*/
public function sAccountGroups($account_id) {
static $CACHE = array();
if (! isset($CACHE[$account_id])) {
$db = &DB();
$rs = $db->Execute(sqlSelect($db,'account_group','group_id',sprintf('group_id>2 AND active=1 AND account_id=%s',$account_id)));
$CACHE[$account_id] = array(0,2);
if ($rs && $rs->RecordCount()) {
while (! $rs->EOF) {
array_push($CACHE[$account_id],$rs->fields['group_id']);
$rs->MoveNext();
}
}
}
return $CACHE[$account_id];
}
// @todo Use sAccountGroups() in this method
public function user_get_auth_groups($VAR) {
global $smarty,$C_auth;
@@ -103,16 +125,17 @@ class account extends OSB_module {
# Get groups for this account
$authgrp = array();
if (! empty($VAR['id'])) {
$grs = $db->Execute(sqlSelect($db,'account_group','group_id',sprintf('group_id>2 AND active=1 AND account_id=%s',$VAR['id'])));
if ($grs && $grs->RecordCount()) {
while (! $grs->EOF) {
$authgrp[$grs->fields['group_id']] = true;
$grs->MoveNext();
$rs = $db->Execute(sqlSelect($db,'account_group','group_id',sprintf('group_id>2 AND active=1 AND account_id=%s',$VAR['id'])));
if ($rs && $rs->RecordCount()) {
while (! $rs->EOF) {
$authgrp[$rs->fields['group_id']] = true;
$rs->MoveNext();
}
}
}
$rs = $db->Execute(sqlSelect($db,'group','id,name',sprintf('id IN (%s) AND id > 2',implode(',',$C_auth->group))));
if ($rs && $rs->RecordCount()) {
while (! $rs->EOF) {
$gid = $rs->fields['id'];
@@ -609,9 +632,7 @@ class account extends OSB_module {
$limit = $result->fields['date_orig']+$LIMIT_SECONDS;
if ($limit>time()) {
$error1 = $C_translate->translate('password_reset_spam_limit',$this->module,'');
$error = str_replace('%limit%',$LIMIT_SECONDS,$error1);
$C_debug->alert($error);
$C_debug->alert(sprintf(_('You have already submitted the password reset request for this account within the past %s seconds, please wait to try again'),$LIMIT_SECONDS));
return;
@@ -640,7 +661,7 @@ class account extends OSB_module {
$my->send('account_reset_password',$account,'','',$now,false);
# ALERT: we have sent an email to you....
$C_debug->alert($C_translate->translate('password_reset_sent',$this->module,''));
$C_debug->alert(_('Thank you, we have sent an email to your email address on file with a link for changing your password. The link is valid for 15 minutes only, so be sure to check your email right away.'));
}
/**
@@ -914,9 +935,9 @@ class account extends OSB_module {
}
}
public function __construct() {
public function __construct($id=null) {
if (! defined('AJAX'))
parent::__construct();
parent::__construct($id);
}
/**
@@ -1084,6 +1105,8 @@ class account extends OSB_module {
$where = sprintf('(username LIKE "%s%%" OR first_name LIKE "%s%%" OR last_name LIKE "%s%%" OR company LIKE "%s%%")',
$VAR[$field],$VAR[$field],$VAR[$field],$VAR[$field]);
$where .= 'AND status=1';
if (! preg_match("/{$return}/",$fieldlist))
$fieldlist .= ','.$return;
@@ -1095,8 +1118,8 @@ class account extends OSB_module {
if ($result->RecordCount() > 0) {
while (! $result->EOF) {
printf('<li><div class="name"><b>%s %s</b></div><div class="email"><span class="informal">%s</span></div><div class="index" style="display:none">%s</div></li>',
$result->fields['first_name'],$result->fields['last_name'],$result->fields['email'],$result->fields[$return]);
printf('<li><div class="name"><b>%s %s (%s)</b></div><div class="email"><span class="informal">%s</span></div><div class="index" style="display:none">%s</div></li>',
$result->fields['first_name'],$result->fields['last_name'],$result->fields['username'],$result->fields['email'],$result->fields[$return]);
$result->MoveNext();
}
@@ -1774,13 +1797,13 @@ class account extends OSB_module {
}
# Get invoice details for this account
$view = $db->SelectLimit(sqlSelect($db,'invoice','id,date_orig,total_amt,billed_amt,process_status',array('account_id'=>$VAR['id']),'id DESC'),10);
$view = $db->SelectLimit(sqlSelect($db,'invoice','id,date_orig,total_amt,IFNULL(credit_amt,0) as credit_amt,status,billed_amt,process_status',array('account_id'=>$VAR['id']),'id DESC'),10);
if ($view && $view->RecordCount() > 0) {
$smart['invoice'] = array();
while (! $view->EOF) {
if ($view->fields['total_amt'] > $view->fields['billed_amt'] && $view->fields['suspend_billing'] != 1)
$view->fields['due'] = $view->fields['total_amt']-$view->fields['billed_amt'];
$view->fields['due'] = round($view->fields['total_amt']-$view->fields['billed_amt']-$view->fields['credit_amt'],2);
array_push($smart['invoice'],$view->fields);
$view->MoveNext();
@@ -1798,6 +1821,18 @@ class account extends OSB_module {
}
}
# Get payment details for this account
$rs = $db->SelectLimit(sqlSelect($db,array('payment','payment_item'),'A.id,A.date_payment,A.total_amt,SUM(B.alloc_amt) AS alloc_amt',
sprintf('A.account_id=%s AND B.payment_id=A.id',$VAR['id']),'A.date_payment DESC','','','B.payment_id'),10);
if ($rs && $rs->RecordCount() > 0) {
$smart['payment'] = array();
while (! $rs->EOF) {
array_push($smart['payment'],$rs->fields);
$rs->MoveNext();
}
}
# Get invoices to be generated for this account
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$invoice = new invoice;

View File

@@ -108,9 +108,6 @@
<convert>md5</convert>
<display>Password</display>
</password>
<inherit_group>
<type>L</type>
</inherit_group>
<!-- @unknown? -->
<misc>
<type>C2(128)</type>
@@ -233,10 +230,10 @@
<user_view>id,parent_id,date_last,language_id,country_id,affiliate_id,reseller_id,currency_id,theme_id,username,password,status,first_name,middle_name,last_name,title,email,company,address1,address2,city,state,zip,email_type,tax_id,max_child</user_view>
<delete>id</delete>
<add>search,date_expire,language_id,country_id,currency_id,theme_id,username,password,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip</add>
<update>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,inherit_group,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,invoice_delivery,invoice_show_itemized,invoice_grace,invoice_advance_gen,tax_id,max_child</update>
<view>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,inherit_group,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,invoice_delivery,invoice_show_itemized,invoice_grace,invoice_advance_gen,tax_id,max_child</view>
<update>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,invoice_delivery,invoice_show_itemized,invoice_grace,invoice_advance_gen,tax_id,max_child</update>
<view>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,invoice_delivery,invoice_show_itemized,invoice_grace,invoice_advance_gen,tax_id,max_child</view>
<search>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,invoice_delivery,invoice_show_itemized,invoice_grace,invoice_advance_gen,tax_id,max_child</search>
<search_export>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,inherit_group,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,tax_id,max_child</search_export>
<search_export>id,date_orig,date_last,date_expire,parent_id,language_id,country_id,affiliate_id,campaign_id,reseller_id,currency_id,theme_id,username,password,misc,status,first_name,middle_name,last_name,title,email,email_type,company,address1,address2,city,state,zip,tax_id,max_child</search_export>
<export_excel>language_id,country_id,affiliate_id,campaign_id,currency_id,username,password,misc,status,first_name,middle_name,last_name,title,email,company,address1,address2,city,state,zip,tax_id</export_excel>
<export_xml>language_id,country_id,affiliate_id,campaign_id,currency_id,username,password,misc,status,first_name,middle_name,last_name,title,email,company,address1,address2,city,state,zip,tax_id</export_xml>
<export_csv>language_id,country_id,affiliate_id,campaign_id,currency_id,username,password,misc,status,first_name,middle_name,last_name,title,email,company,address1,address2,city,state,zip,tax_id</export_csv>

View File

@@ -7,7 +7,7 @@
<date_last>1112335769</date_last>
<date_expire>0</date_expire>
<parent_id>0</parent_id>
<language_id>english</language_id>
<language_id>en</language_id>
<country_id>840</country_id>
<reseller_id>0</reseller_id>
<currency_id>1</currency_id>

View File

@@ -0,0 +1,289 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Auth driver.
*
* @package OSB
* @subpackage Account
* @category Auth
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Auth_OSB extends Auth_ORM {
/**
* OSB authentication is controlled via database queries.
*
* This method can be used to test two situations:
* 1) Is the user logged in? ($role == FALSE)
* 2) Can the user run the current controller->action ($role == TRUE)
*
* @param boolean If authentication should be done for this module:method (ie: controller:action).
* @return boolean
*/
public function logged_in($role = NULL, $debug = NULL) {
$status = FALSE;
// Get the user from the session
$user = $this->get_user(FALSE);
// If we are not a valid user object, then we are not logged in
if (is_object($user) AND $user instanceof Model_Account AND $user->loaded()) {
if (Config::sitemode() == Kohana::DEVELOPMENT && Kohana::config('config.site_debug'))
SystemMessage::add(array('title'=>'Debug','type'=>'debug','body'=>Kohana::debug(array('user'=>$user->username,'r'=>$role))));
if (! empty($role)) {
// Get the module details
$module = ORM::factory('module',array('name'=>Request::instance()->controller));
if (! $module->loaded() OR ! $module->status) {
SystemMessage::add(array(
'title'=>'Module is not defined or active in the Database',
'type'=>'warning',
'body'=>sprintf('Module not defined: %s',Request::instance()->controller),
));
} else {
if (Request::instance()->directory)
$method_name = sprintf('%s_%s',Request::instance()->directory,Request::instance()->action);
else
$method_name = Request::instance()->action;
// Get the method number
$method = ORM::factory('module_method',array('module_id'=>$module->id,'name'=>$method_name));
if (! $method->loaded()) {
SystemMessage::add(array(
'title'=>'Method is not defined or active in the Database',
'type'=>'warning',
'body'=>sprintf('Method not defined: %s for %s',Request::instance()->action,$module->name),
));
} else {
// If the role has the authorisation to run the method
$group_method = ORM::factory('group_method')
->where('method_id','=',$method->id);
$roles = '';
foreach ($group_method->find_all() as $gm) {
$roles .= ($roles ? '|' : '').$gm->group->name;
$ro = ORM::factory('group', array('name' => $gm->group->name));
// $ro->id == 0 means all users.
if ($ro->id == 0 OR $user->has('group', $ro)) {
$status = TRUE;
$roles = '';
break;
}
}
if (! $status) {
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array(
'title'=>'User is not authorised in Database',
'type'=>'debug',
'body'=>sprintf('Role(s) checked: %s<br/>User: %s</br>Module: %s<br/>Method: %s',$roles,$user->username,$module->name,$method->name),
));
}
}
}
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array(
'title'=>'Debug',
'type'=>'debug',
'body'=>sprintf('A-User: <b>%s</b>, Module: <b>%s</b>, Method: <b>%s</b>, Role: <b>%s</b>, Status: <b>%s</b>, Data: <b>%s</b>',
$user->username,Request::instance()->controller,Request::instance()->action,$role,$status,$debug)));
// There is no role, so the method should be allowed to run as anonymous
} else {
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array(
'title'=>'Debug',
'type'=>'debug',
'body'=>sprintf('B-User: <b>%s</b>, Module: <b>%s</b>, Method: <b>%s</b>, Status: <b>%s</b>, Data: <b>%s</b>',
$user->username,Request::instance()->controller,Request::instance()->action,'No Role Default Access',$debug)));
$status = TRUE;
}
// Check and see if we have a token to login and run the method
} elseif ((! empty($_REQUEST['token']) AND $token = $_REQUEST['token']) OR $token=Session::instance()->get('token')) {
if ($user=$this->_get_token_user($token) AND $user !== FALSE)
$status = TRUE;
} else {
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array('title'=>'Debug','type'=>'debug','body'=>'No user logged in'));
}
return $status;
}
/**
* Gets the currently logged in user from the session.
* Returns FALSE if no user is currently logged in.
*
* @param boolean Check token users too
* @return mixed
*/
public function get_user($tokenuser=TRUE) {
$user = parent::get_user();
// If we are not logged in, see if there is token for the usre
if ($tokenuser AND $user === FALSE AND $token=Session::instance()->get('token')) {
$user = $this->_get_token_user($token);
}
return $user;
}
/**
* Get the user that a token applies to
*
* This will check that the token is valid (not expired and for the request)
*
* @param $token The token
* @return mixed The user
*/
private function _get_token_user($token) {
$mmto = ORM::factory('module_method_token',array('token'=>$token));
$request = Request::instance();
$user = FALSE;
if ($mmto->loaded()) {
if ($mmto->date_expire < time()) {
SystemMessage::add(array(
'title'=>_('Token Not Valid'),
'type'=>'warning',
'body'=>_('Token expired')));
Session::instance()->delete('token');
$mmto->delete();
} else {
// Check that the token is for this URI
$mo = ORM::factory('module',array('name'=>$request->controller));
$mmo = ORM::factory('module_method',
array('name'=>$request->directory ? sprintf('%s_%s',$request->directory,$request->action) : $request->action));
// Ignore the token if this is not the right method.
if ($mmo->id == $mmto->method_id) {
// @todo Implement single use tokens
Session::instance()->set('token',$token);
$user = ORM::factory('account',$mmto->account_id);
}
}
}
return $user;
}
/**
* Logs a user in.
*
* @param string username
* @param string password
* @param boolean enable autologin
* @return boolean
*/
protected function _login($user, $password, $remember)
{
if ( ! is_object($user))
{
$username = $user;
// Load the user
$user = ORM::factory('user');
$user->where($user->unique_key($username), '=', $username)->find();
}
// If the passwords match, perform a login
if ($user->has('group', ORM::factory('group', array('name' => 'Registered Users'))) AND $user->password === $password)
{
if ($remember === TRUE)
{
// Create a new autologin token
$token = ORM::factory('user_token');
// Set token data
$token->user_id = $user->id;
$token->expires = time() + $this->_config['lifetime'];
$token->save();
// Set the autologin cookie
Cookie::set('authautologin', $token->token, $this->_config['lifetime']);
}
// Record our session ID, we may need to update our DB when we get a new ID
$oldsess = session_id();
// Finish the login
$this->complete_login($user);
// Do we need to update databases with our new sesion ID
// @todo figure out where this is best to go
$session_change_trigger = array('cart'=>'session_id');
if (count($session_change_trigger) AND (session_id() != $oldsess)) {
foreach ($session_change_trigger as $t => $c) {
$orm = ORM::factory($t)
->where($c,'=',$oldsess);
$orm->session_id = session_id();
$orm->save_all();
}
}
return TRUE;
}
// Login failed
return FALSE;
}
/**
* Override the supplied find_salt() to enable disabling salt keys
*/
public function find_salt($password) {
$salt = '';
foreach ($this->_config['salt_pattern'] as $i => $offset) {
// Find salt characters, take a good long look...
if (is_numeric($offset))
$salt .= substr($password, $offset + $i, 1);
}
return $salt;
}
/**
* Determine if a user is authorised to view an account
*
* @param integer Account ID
*
* @return boolean TRUE if authorised, FALSE if not.
*/
public function authorised($aid) {
if (! $this->get_user())
return FALSE;
// @todo Consider caching this.
$ao = ORM::factory('account',$this->get_user()->id);
if (! $ao->loaded() OR ($aid != $ao->id AND ! $ao->admin()))
return FALSE;
return TRUE;
}
/**
* Disable KO3 hash_password function
*/
public function hash_password($password,$salt = FALSE) {
return md5($password);
}
}
?>

View File

@@ -0,0 +1,16 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides account management
*
* @package lnApp
* @subpackage Page/Account
* @category Controllers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
* @also [logout]
*/
class Controller_Account extends Controller_TemplateDefault {
}
?>

View File

@@ -0,0 +1,115 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides User Account Update functions
*
* @package OSB
* @subpackage Account
* @category Controllers/User
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Controller_User_Account extends Controller_TemplateDefault {
public $secure_actions = array(
'edit'=>TRUE,
'resetpassword'=>TRUE,
);
public function action_resetpassword() {
$ao = Auth::instance()->get_user();
if (! $ao->loaded())
throw new Kohana_Exception('Account doesnt exist :account ?',array(':account'=>$ao->id));
// @todo Fix this next logic, since matches_ifset is not being called when the value is on the form, but empty
if (empty($_POST['password_confirm']))
$_POST['password_confirm'] = ' ';
// Store our new values
$ao->values($_POST);
// Run validation and save
if ($ao->changed())
if ($ao->check()) {
SystemMessage::add(array(
'title'=>_('Record updated'),
'type'=>'info',
'body'=>_('Your account record has been updated.')
));
$ao->save();
Request::instance()->redirect('login');
} else {
SystemMessage::add(array(
'title'=>_('Record NOT updated'),
'type'=>'error',
'body'=>_('Your updates didnt pass validation.')
));
foreach ($ao->validate()->errors('form_errors') as $field => $error)
SystemMessage::add(array(
'title'=>$field,
'type'=>'error',
'body'=>$error,
));
}
Block::add(array(
'title'=>_('Password Reset'),
'body'=>View::factory('account/password_reset')
->set('record',$ao),
));
$this->template->content = Block::factory();
}
/**
* Show a product
*/
public function action_edit() {
$ao = Auth::instance()->get_user();
if (! $ao->loaded())
throw new Kohana_Exception('Account doesnt exist :account ?',array(':account'=>$ao->id));
// Store our new values
$ao->values($_POST);
// Run validation and save
if ($ao->changed())
if ($ao->check()) {
SystemMessage::add(array(
'title'=>_('Record updated'),
'type'=>'info',
'body'=>_('Your account record has been updated.')
));
$ao->save();
} else {
SystemMessage::add(array(
'title'=>_('Record NOT updated'),
'type'=>'error',
'body'=>_('Your updates didnt pass validation.')
));
foreach ($ao->validate()->errors('form_errors') as $field => $error)
SystemMessage::add(array(
'title'=>$field,
'type'=>'error',
'body'=>$error,
));
}
Block::add(array(
'title'=>sprintf('%s: %s - %s',_('Account Edit'),$ao->accnum(),$ao->name(TRUE)),
'body'=>View::factory('account/edit')
->set('record',$ao),
));
$this->template->content = Block::factory();
}
}
?>

View File

@@ -0,0 +1,76 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Account extends Model_Auth_UserDefault {
// Relationships
protected $_has_many = array(
'user_tokens' => array('model' => 'user_token'),
'group' => array('through' => 'account_group'),
'invoice' => array(),
'payment'=>array(),
'service' => array(),
);
// Complete our login
public function complete_login() {}
/**
* Return an account name
*/
public function name($withcompany=FALSE) {
if ($withcompany)
return sprintf('%s %s (%s)',$this->first_name,$this->last_name,$this->company);
else
return sprintf('%s %s',$this->first_name,$this->last_name);
}
public function accnum() {
return sprintf('%02s-%06s',Config::siteid(),$this->id);
}
public function date_last() {
return Config::date($this->date_last);
}
public function title($name) {
return StaticList_Title::form($name,$this->title);
}
public function currency($name) {
return StaticListModule::form($name,'currency',$this->currency_id,'id','name',array());
}
public function country($name) {
return StaticListModule::form($name,'country',$this->country_id,'id','name',array());
}
public function language($name) {
// @todo To setup
return 'en';
}
/**
* Get the groups that an account belongs to
*/
public function groups() {
return $this->group->find_all()->as_array();
}
public function admin() {
// @todo Define admins in the config file or DB
$admins = array('Root');
foreach ($this->groups() as $go)
if (in_array($go->name,$admins))
return TRUE;
return FALSE;
}
}

View File

@@ -0,0 +1,54 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Auth_RoleDefault extends Model_Auth_Role {
protected $_table_names_plural = false;
protected $_object_formated = array();
protected $_formated = FALSE;
protected $_formats = array();
/**
* Format fields for display purposes
*
* @param string column name
* @return mixed
*/
protected function _format() {
$format = Validate::factory($this->_object);
foreach ($this->_formats as $column => $formats)
$format->filters($column,$formats);
if ($format->check())
foreach ($format as $column => $value)
$this->_object_formated[$column] = $value;
$this->_formated = TRUE;
}
/**
* Return a formated columns, as per the model definition
*/
public function display($column) {
// Trigger a load of the record.
$value = $this->__get($column);
// If some of our fields need to be formated for display purposes.
if ($this->_loaded AND ! $this->_formated AND $this->_formats)
$this->_format();
if (isset($this->_object_formated[$column]))
return $this->_object_formated[$column];
else
return $value;
}
}
?>

View File

@@ -0,0 +1,77 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Auth_UserDefault extends Model_Auth_User {
protected $_table_names_plural = false;
// Validation rules
protected $_rules = array(
'username' => array(
'not_empty' => NULL,
'min_length' => array(4),
'max_length' => array(32),
),
'password' => array(
'not_empty' => NULL,
'min_length' => array(5),
'max_length' => array(42),
),
'password_confirm' => array(
'matches_ifset' => array('password'),
),
'email' => array(
'not_empty' => NULL,
'min_length' => array(4),
'max_length' => array(127),
'email' => NULL,
),
);
// Validation callbacks
protected $_callbacks = array(
'username' => array('username_available'),
'email' => array('email_available'),
);
// Columns to ignore
protected $_ignored_columns = array('password_confirm');
/*
* Complete our login
*
* For some database logins, we may not want to record the user last login
* details in the repository, so we just override that parent function
* here.
*
* We can also do some other post-login actions here.
*/
public function complete_login() {}
/**
* Test to see if a record has been changed
*/
public function changed() {
return ! (empty($this->_changed));
}
/**
* Debug function to see that has() finds
* @todo This function could be removed
*/
public function has_list($alias, $model) {
// Return list of matches
return DB::select()
->from($this->_has_many[$alias]['through'])
->where($this->_has_many[$alias]['foreign_key'], '=', $this->pk())
->where($this->_has_many[$alias]['far_key'], '=', $model->pk())
->execute($this->_db)
->as_array();
}
}

View File

@@ -0,0 +1,84 @@
<!-- @todo NEEDS TO BE TRANSLATED -->
<?php echo Form::open(); ?>
<table class="box-center">
<tr>
<td class="head">Last Updated</td>
<td><?php echo $record->date_last(); ?></td>
</tr>
<tr>
<td class="head">User Name</td>
<td><b><?php echo $record->username; ?></b></td>
</tr>
<!-- //@todo This needs to be done somewhere else
<tr>
<td class="head">Password</td>
<td><input type="password" name="password" value=""/></td>
</tr>
<tr>
<td class="head">Confirm Password</td>
<td><input type="password" name="confirm_password" value=""/></td>
</tr>
-->
<tr>
<td class="head">Email</td>
<td><input type="text" name="email" value="<?php echo $record->email; ?>"/></td>
</tr>
<tr>
<td class="head">Company</td>
<td><input type="text" name="company" value="<?php echo $record->company; ?>"/></td>
</tr>
<tr>
<td class="head">First Name</td>
<td><input type="text" name="first_name" value="<?php echo $record->first_name; ?>"/></td>
</tr>
<tr>
<td class="head">Last Name</td>
<td><input type="text" name="last_name" value="<?php echo $record->last_name; ?>"/></td>
</tr>
<tr>
<td class="head">Title</td>
<td><?php echo $record->title('title'); ?></td>
</tr>
<tr>
<td class="head">Address</td>
<td><input type="text" name="address1" value="<?php echo $record->address1; ?>"/></td>
</tr>
<tr>
<td class="head">&nbsp;</td>
<td><input type="text" name="address2" value="<?php echo $record->address2; ?>"/></td>
</tr>
<tr>
<td class="head">City</td>
<td><input type="text" name="city" value="<?php echo $record->city; ?>"/></td>
</tr>
<tr>
<td class="head">State</td>
<td><input type="text" name="state" value="<?php echo $record->state; ?>"/></td>
</tr>
<tr>
<td class="head">Postal Code</td>
<td><input type="text" name="zip" value="<?php echo $record->zip; ?>"/></td>
</tr>
<tr>
<td class="head">Country</td>
<td><?php echo $record->country('country'); ?></td>
</tr>
<tr>
<td class="head">Language</td>
<td><?php echo $record->language('language_id'); ?></td>
</tr>
<tr>
<td class="head">Currency</td>
<td><?php echo $record->currency('currency_id'); ?></td>
</tr>
<tr>
<!-- @todo NEEDS TO BE CONFIGURABLE -->
<td class="head">HTML Email</td>
<td>Yes</td>
</tr>
<!-- @todo OTHER STATIC VARS -->
<tr>
<td colspan="2" style="text-align: center;"><?php echo Form::submit('update','Update'); ?></td>
</tr>
</table>
<?php echo Form::close(); ?>

View File

@@ -0,0 +1,16 @@
<!-- @todo NEEDS TO BE TRANSLATED -->
<?php echo Form::open(); ?>
<table class="box-center">
<tr>
<td class="head">Password</td>
<td><input type="password" name="password" value=""/></td>
</tr>
<tr>
<td class="head">Confirm Password</td>
<td><input type="password" name="password_confirm" value=""/></td>
</tr>
<tr>
<td colspan="2" style="text-align: center;"><?php echo Form::submit('update','Update'); ?></td>
</tr>
</table>
<?php echo Form::close(); ?>

View File

@@ -0,0 +1,135 @@
<br/>
<?php echo Form::open(); ?>
<table class="login">
<tr>
<td>User Name</td>
<td><?php echo Form::input('username',$account->username,
array('id'=>'login-uid','size'=>40,'class'=>(array_key_exists('username',$errors) ? 'error' : 'ok'))); ?></td>
</tr>
<tr>
<td>Password</td>
<td><?php echo Form::password('password',null,array('id'=>'login-pwd','size'=>16));?></td>
</tr>
<tr>
<td>Confirm Password</td>
<td><?php echo Form::password('password_confirm',null,array('id'=>'login-pwd-confirm','size'=>16));?></td>
</tr>
<tr>
<td>Email Address</td>
<td><?php echo Form::input('email',$account->email,array('size'=>40));?></td>
</tr>
<tr>
<td>Company</td>
<td><?php echo Form::input('company',$account->company,array('size'=>40));?></td>
</tr>
<tr>
<td>First Name</td>
<td><?php echo Form::input('first_name',$account->first_name,array('size'=>40));?></td>
</tr>
<tr>
<td>Last Name</td>
<td><?php echo Form::input('last_name',$account->last_name,array('size'=>40));?></td>
</tr>
<tr>
<td>Title</td>
<td><?php echo StaticList_Title::form('title',$account->title);?></td>
</tr>
<tr>
<td>Address Line 1</td>
<td><?php echo Form::input('address1',$account->address1,array('size'=>40));?></td>
</tr>
<tr>
<td>Address Line 2</td>
<td><?php echo Form::input('address2',$account->address2,array('size'=>40));?></td>
</tr>
<tr>
<td>City</td>
<td><?php echo Form::input('city',$account->city,array('size'=>40));?></td>
</tr>
<tr>
<td>State</td>
<td><?php echo Form::input('state',$account->state,array('size'=>20));?></td>
</tr>
<tr>
<td>Post Code</td>
<td><?php echo Form::input('zip',$account->zip,array('size'=>20));?></td>
</tr>
<tr>
<td>Country</td>
<!-- @todo - our default currency should be defined in a config -->
<td><?php echo StaticList_Module::form('country_id','country',61,'id','name',array());?></td>
<!--
{if $VAR.account_country_id != ''}
{$list->menu('no','account_country_id','country','name',$VAR.account_country_id,'form_field" onchange="taxIdsDisplay(this.value)',true)}
{else}
{$list->menu('no','account_country_id','country','name',$smarty.const.DEFAULT_COUNTRY,'form_field" onchange="taxIdsDisplay(this.value)',true)}
{/if}
{$method->exe_noauth('tax','get_tax_ids')}
{if $tax_ids}
<script type="text/javascript" language="javascript">
{if $VAR.account_country_id != ""}
var countryId='{$VAR.account_country_id}';
{else}
var countryId='{$smarty.const.DEFAULT_COUNTRY}';
{/if}
{literal}
function taxIdsDisplay(id) {
try{ document.getElementById('tax_country_id_'+id).style.display='block'; } catch(e) {}
try{ document.getElementById('tax_country_id_'+countryId).style.display='none'; } catch(e) {}
countryId=id;
}
{/literal}
</script>
</td>
</tr>
{foreach from=$tax_ids item=tax}
<tr valign="top" id="tax_country_id_{$tax.country_id}" {if $VAR.account_country_id !=''}{if $VAR.account_country_id!=$tax.country_id}{osb f=style_hide}{/if}{else}{if $smarty.const.DEFAULT_COUNTRY!=$tax.country_id}{osb f=style_hide}{/if}{/if}>
<td width="29%">{$tax.tax_id_name}</td>
<td width="71%">
<input type="text" name="account_tax_id[{$tax.country_id}]" value="{$VAR.account_tax_id[$tax.country_id]}" {if $account_tax_id == true}class="form_field_error"{/if}/>
<!-* {if $tax.tax_id_exempt}
(or) exempt
<input type="checkbox" name="account_tax_id_exempt[{$tax.country_id}]" value="1"/>
{/if} -*>
{/foreach}
{/if}
</td>
-->
</tr>
<!--
{$method->exe('account','static_var')}
{foreach from=$static_var item=record}
<tr valign="top">
<td>{$record.name}</td>
<td>{$record.html}</td>
</tr>
{/foreach}
-->
<!--
{if $smarty.const.NEWSLETTER_REGISTRATION == "1"}
<tr valign="top">
<td>{t module=account}subscribe_newsletters{/t}</td>
<td>{$method->exe('newsletter','check_list_registration')}</td>
</tr>
{/if}
-->
<tr>
<td>Use HTML for Email</td>
<!-- // @todo default should be specified in a global confi -->
<td><?php echo StaticList_YesNo::form('email_type',true); ?></td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr><td colspan="2" style="text-align: center;"><?php echo Form::submit('submit',_('Register'));?></td></tr>
</table>
<?php echo Form::close(); ?>
<!-- @todo The following focus() is not ajax/jscript friendly -->
<!-- @todo Provide field validation highlighting -->
<!-- @todo Add javascript to stop submission when password fields dont match -->
<script type="text/javascript">document.getElementById('login-uid').focus();</script>

View File

@@ -1,7 +1,7 @@
<install>
<module_properties>
<name>account_billing</name>
<parent>account_admin</parent>
<parent>account</parent>
<notes><![CDATA[This module contains the encrypted billing data.]]></notes>
</module_properties>
<sql_inserts>
@@ -31,4 +31,4 @@
</search_show>
</module_method>
</sql_inserts>
</install>
</install>

View File

@@ -0,0 +1,71 @@
<?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:Payment
*/
/**
* The main AgileBill Account Fee Class
*
* @package AgileBill
* @subpackage Modules:AccountFee
*/
class account_fee extends OSB_module {
/**
* Calculate the account fee for an account
*
* @param $account_id The account ID to calculate
* @param $period Invoice period being calculated
* @uses account
*/
public function sAccountFee($account_id,$period) {
static $CACHE = array();
if (! isset($CACHE[$account_id][$period])) {
$db = &DB();
include_once(PATH_MODULES.'account/account.inc.php');
$ao = new account;
# Load the account fees
$rs = $db->Execute(sqlSelect('account_fee','*',array('where'=>array('active=1'))));
if ($rs && $rs->RecordCount()) {
while (! $rs->EOF) {
$gf = unserialize($rs->fields['groups_fee']);
if (isset($gf[$period]) && $gf[$period]['show'])
foreach ($ao->sAccountGroups($account_id) as $gid)
if (isset($gf[$period]['group'][$gid])
&& (! isset($CACHE[$account_id][$period]) || $CACHE[$account_id][$period] > $gf[$period]['group'][$gid]['fee']))
$CACHE[$account_id][$period] = $gf[$period]['group'][$gid]['fee'];
$rs->MoveNext();
}
}
}
return $CACHE[$account_id][$period];
}
}
?>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<construct>
<!-- Module name -->
<module>account_fee</module>
<!-- Module supporting database table -->
<table>account_fee</table>
<!-- Module dependancy(s) (module wont install if these modules are not yet installed) -->
<dependancy>account</dependancy>
<!-- DB cache in seconds -->
<cache>0</cache>
<!-- Default order_by field for SQL queries -->
<order_by>name</order_by>
<!-- Default SQL limit for SQL queries -->
<limit>25</limit>
<!-- Schema version (used to determine if the schema has change during upgrades) -->
<version>1</version>
<!-- Database indexes -->
<index>
</index>
<!-- Database fields -->
<field>
<!-- Record ID -->
<id>
<index>1</index>
<type>I4</type>
<unique>1</unique>
</id>
<!-- Site ID -->
<site_id>
<index>1</index>
<type>I4</type>
</site_id>
<!-- Date record created -->
<date_orig>
<convert>date-now</convert>
<display>Date Created</display>
<type>I8</type>
</date_orig>
<!-- Date record updated -->
<date_last>
<convert>date-now</convert>
<display>Date Updated</display>
<type>I8</type>
</date_last>
<!-- Record active (BOOL)-->
<status>
<display>Active</display>
<type>L</type>
</status>
<name>
<type>C(32)</type>
<validate>any</validate>
</name>
<groups_fee>
<convert>array</convert>
<type>X2</type>
</groups_fee>
</field>
<!-- Methods for this class, and the fields they have access to, if applicable -->
<method>
<add>name,groups_fee</add>
<search>name</search>
<update>name,groups_fee</update>
<view>id,name,groups_fee</view>
</method>
<!-- Method triggers -->
<trigger></trigger>
<!-- Template page display titles -->
<title>
<add>Add Account Fee</add>
</title>
<!-- Template helpers -->
<tpl>
<search_show>
<checkbox>
<field>id</field>
<type>checkbox</type>
<width>25px</width>
</checkbox>
<name>
<field>name</field>
</name>
</search_show>
</tpl>
</construct>

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<install>
<!-- Tree Menu Module Properties -->
<module_properties>
<!-- MODULE Dependancy, this module wont be installed if the dependant modules dont exist -->
<dependancy>account</dependancy>
<!-- Translated display to use on the tree -->
<display>Account Fees</display>
<!-- Display a module in the menu tree -->
<menu_display>1</menu_display>
<!-- MODULE Name -->
<name>account_fee</name>
<!-- MODULE Notes, these notes show up in the modules table, as a description of the module -->
<notes><![CDATA[Add account fees to accounts.]]></notes>
<!-- MODULE Parent, the parent node in the tree -->
<parent>account</parent>
<!-- SUB Modules to install with this one -->
<sub_modules></sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->
<module_method>
<add>
<display>Add</display>
<menu_display>1</menu_display>
<name>add</name>
<notes><![CDATA[Add records]]></notes>
</add>
<delete>
<name>delete</name>
<notes><![CDATA[Delete records]]></notes>
</delete>
<search>
<display>List</display>
<menu_display>1</menu_display>
<name>search</name>
<notes><![CDATA[List records]]></notes>
<page><![CDATA[core:search&module=%%&_next_page_one=view]]></page>
</search>
<search_form>
<name>search_form</name>
<notes><![CDATA[Search for records]]></notes>
</search_form>
<search_show>
<name>search_show</name>
<notes><![CDATA[Show the results of a search]]></notes>
</search_show>
<update>
<name>update</name>
<notes><![CDATA[Update a record]]></notes>
</update>
<view>
<name>view</name>
<notes><![CDATA[View a record]]></notes>
</view>
</module_method>
</install>

View File

@@ -0,0 +1,39 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Group extends Model_Auth_RoleDefault {
protected $_object_formated = array();
// Relationships
protected $_has_many = array(
'account'=>array('through'=>'account_group'),
);
protected $_sorting = array(
'name'=>'ASC',
);
protected $_formats = array(
'status'=>array('StaticList_YesNo::display'=>array()),
);
// Validation rules
protected $_rules = array(
'name' => array(
'not_empty' => NULL,
'min_length' => array(4),
'max_length' => array(32),
),
'description' => array(
'max_length' => array(255),
),
);
}
?>

View File

@@ -66,7 +66,7 @@
<!-- define all the methods for this class, and the fields they have access to, if applicable. -->
<method>
<add>date_orig,staff_id,account_id,type,memo</add>
<add>staff_id,account_id,type,memo</add>
<update>id,site_id,date_orig,staff_id,account_id,type,memo</update>
<delete>id,site_id,date_orig,staff_id,account_id,type,memo</delete>
<view>id,site_id,date_orig,staff_id,account_id,type,memo</view>

36
modules/adsl/adsl.inc.php Normal file
View File

@@ -0,0 +1,36 @@
<?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:ADSL
*/
/**
* This class provides the ability to define ADSL Supplier Products.
*
* @package osBilling
* @subpackage Modules:ADSL
*/
class adsl extends OSB_module {
}
?>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<construct>
<module>adsl</module>
<table>adsl</table>
<dependancy></dependancy>
<cache>0</cache>
<order_by>product_desc</order_by>
<limit>35</limit>
<!-- Page Display Titles -->
<title>
<add>Add ADSL</add>
<view>ADSL</view>
</title>
<field>
<id>
<type>I8</type>
<unique>1</unique>
</id>
<site_id>
<type>I4</type>
</site_id>
<date_orig>
<type>I8</type>
<convert>date-now</convert>
</date_orig>
<date_last>
<type>I8</type>
<convert>date-now</convert>
</date_last>
<status>
<display>Active</display>
<type>L</type>
</status>
<supplier_id>
<display>Supplier</display>
<type>I4</type>
<asso_table>adsl_supplier</asso_table>
<asso_field>name</asso_field>
<validate>any</validate>
</supplier_id>
<product_id>
<display>Product ID</display>
<type>C(16)</type>
<min_len>1</min_len>
<max_len>16</max_len>
</product_id>
<product_desc>
<display>Product Description</display>
<type>C(128)</type>
<min_len>1</min_len>
<max_len>128</max_len>
</product_desc>
<base_cost>
<display>Base Cost</display>
<type>F</type>
</base_cost>
<contract_term>
<description>Contract Term in Months</description>
<display>Contract Term</display>
<type>I4</type>
</contract_term>
<base_down_peak>
<display>Peak Downloads (MB)</display>
<type>F</type>
</base_down_peak>
<base_up_peak>
<display>Peak Uploads (MB)</display>
<type>F</type>
</base_up_peak>
<base_down_offpeak>
<display>OffPeak Downloads (MB)</display>
<type>F</type>
</base_down_offpeak>
<base_up_offpeak>
<display>OffPeak Uploads (MB)</display>
<type>F</type>
</base_up_offpeak>
<extra_charged>
<display>Charge Extra Traffic</display>
<type>L</type>
</extra_charged>
<extra_shaped>
<display>Shaping speed for extra traffic</display>
<type>C(8)</type>
</extra_shaped>
<offpeak_start>
<display>Offpeak Start</display>
<type>I8</type>
<convert>time</convert>
</offpeak_start>
<offpeak_end>
<display>Offpeak End</display>
<type>I8</type>
<convert>time</convert>
</offpeak_end>
<extra_down_peak>
<display>Peak Downloads Rate ($/MB)</display>
<type>F</type>
</extra_down_peak>
<extra_up_peak>
<display>Peak Uploads Rate ($/MB)</display>
<type>F</type>
</extra_up_peak>
<extra_down_offpeak>
<display>OffPeak Downloads Rate ($/MB)</display>
<type>F</type>
</extra_down_offpeak>
<extra_up_offpeak>
<display>OffPeak Uploads Rate ($/MB)</display>
<type>F</type>
</extra_up_offpeak>
</field>
<method>
<add>supplier_id,product_id,product_desc</add>
<update>id,date_last,status,product_id,product_desc,base_cost,contract_term,base_down_peak,base_up_peak,base_down_offpeak,base_up_offpeak,extra_charged,extra_shaped,offpeak_start,offpeak_end,extra_down_peak,extra_up_peak,extra_down_offpeak,extra_up_offpeak</update>
<delete>id</delete>
<view>id,status,supplier_id,product_id,product_desc,base_cost,contract_term,base_down_peak,base_up_peak,base_down_offpeak,base_up_offpeak,extra_charged,extra_shaped,offpeak_start,offpeak_end,extra_down_peak,extra_up_peak,extra_down_offpeak,extra_up_offpeak</view>
<search>id,date_orig,date_last,status,supplier_id,product_id,product_desc,base_cost</search>
</method>
<index>
<adsls>id,site_id</adsls>
<asso>supplier_id</asso>
<service>service_id</service>
<adsl>product</adsl>
</index>
<trigger>0</trigger>
<!-- Template Helpers -->
<tpl>
<search_show>
<checkbox>
<field>id</field>
<type>checkbox</type>
<width>25px</width>
</checkbox>
<supplier_id>
<field>supplier_id</field>
</supplier_id>
<product_id>
<field>product_id</field>
</product_id>
<base_cost>
<field>base_cost</field>
<type>currency</type>
</base_cost>
</search_show>
</tpl>
</construct>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<install>
<!-- Tree Menu Module Properties -->
<module_properties>
<!-- MODULE Dependancy, this module wont be installed if the dependant modules dont exist -->
<dependancy></dependancy>
<!-- Translated display to use on the tree -->
<display>ADSL</display>
<!-- Display a module in the menu tree -->
<menu_display>1</menu_display>
<!-- MODULE Name -->
<name>adsl</name>
<!-- MODULE Notes, these notes show up in the modules table, as a description of the module -->
<notes><![CDATA[This module records the ADSL supplier products]]></notes>
<!-- MODULE Parent, the parent node in the tree -->
<parent>adsl</parent>
<!-- SUB Modules to install with this one -->
<sub_modules>adsl_supplier</sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->
<module_method>
<add>
<display>Add</display>
<menu_display>1</menu_display>
<name>add</name>
<notes><![CDATA[Add records]]></notes>
</add>
<delete>
<name>delete</name>
<notes><![CDATA[Delete records]]></notes>
</delete>
<search>
<display>Search</display>
<menu_display>1</menu_display>
<name>search</name>
<notes><![CDATA[List records]]></notes>
<page><![CDATA[core:search&module=%%&_next_page_one=view]]></page>
</search>
<search_show>
<name>search_show</name>
<notes><![CDATA[Show the results of a search]]></notes>
</search_show>
<update>
<name>update</name>
<notes><![CDATA[Update a record]]></notes>
</update>
<view>
<name>view</name>
<notes><![CDATA[View a record]]></notes>
</view>
</module_method>
</install>

View File

@@ -0,0 +1,151 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class looks after ADSL products
*
* @package OSB
* @subpackage Product
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class ADSL {
// Map the table fields
static $map = array(
'base_up_offpeak'=>'extra_up_offpeak',
'base_down_offpeak'=>'extra_down_offpeak',
'base_up_peak'=>'extra_up_peak',
'base_down_peak'=>'extra_down_peak',
);
/**
* Return an instance of this class
*
* @return ADSL
*/
public static function instance() {
return new ADSL;
}
/**
* Return the additional information used by product_view
*/
public function product_view($data) {
// @todo - this test shouldnt be required
if (preg_match('/^a:/',$data))
throw new Kohana_Exception('Data shouldnt be a serialized array');
$ao = ORM::factory('adsl_plan',$data);
$output = View::factory('adsl/product_view')
->set('record',$ao);
return $output;
}
public function contract_view($data,$price_base,$price_setup) {
// @todo - this test shouldnt be required
if (preg_match('/^a:/',$data))
throw new Kohana_Exception('Data shouldnt be a serialized array');
$ao = ORM::factory('adsl_plan',$data);
$output = View::factory('adsl/contract_view')
->set('record',$ao)
->set('price_base',$price_base)
->set('price_setup',$price_setup);
return $output;
}
/**
* Collect information for the cart
*/
public function product_cart() {
}
/**
* Map the metric fields to their excess rate
*/
public static function map($metric) {
return ADSL::$map[$metric];
}
/**
* Calculate the allowance array or traffic used array
*
* If:
* + UPLOADS are charged and there are no PEAK/OFFPEAK periods (therefore all
* traffic is charged), the allowance will be shown as 1 metric - TRAFFIC.
* + UPLOADS are charged and there are PEAK/OFFPEAK periods the allowance
* will be shown as 2 metrics - PEAK/OFFPEAK.
* + UPLOADS are NOT charged and there are no PEAK/OFFPEAK periods the allowance
* will be shown as 1 metrics - TRAFFIC.
* + UPLOADS are NOT charged and there are PEAK/OFFPEAK periods the allowance
* will be shown as 2 metrics - PEAK/OFFPEAK.
*
* Thus:
* + If base_x_Y is NULL, all Y traffic is FREE (ignore respective extra_x_Y setting).
* + If base_x_Y is a number, all Y traffic is FREE up to the number (evaluate extra_x_Y setting).
* + If extra_x_Y is a number, charge this amount for traffic over base_x_Y.
* + If extra_down_peak is NULL this is invalid, treat base_down_peak as NULL
* + If extra_down_offpeak is NULL add traffic_down_offpeak to traffic_down_peak
* + If extra_up_peak is NULL add traffic_up_peak to traffic_down_peak
* + If extra_up_offpeak is NULL add traffic_up_offpeak to traffic_down_offpeak
*
* @param array $plan - the allowance plan
*/
public static function allowance($plan) {
// Map the NULL relationships
$extras = array(
'extra_up_offpeak'=>'base_down_offpeak',
'extra_down_offpeak'=>'base_down_peak',
'extra_up_peak'=>'base_down_peak',
'extra_down_peak'=>'base_down_peak',
);
// Work out if we charge each period
$a = array();
if (! isset($plan['extra_down_peak']) OR is_null($plan['extra_down_peak']))
$a['base_down_peak'] = 0;
foreach (ADSL::$map as $k => $v) {
// Work through attributes we count.
if (isset($plan[$k]) AND ! is_null($plan[$k])) {
// Work through attributes that are merged
if (! isset($plan[$v]) OR is_null($plan[$v])) {
if (isset($a[$k])) {
if (isset($a[$extras[$v]]))
$a[$extras[$v]] += $a[$k];
else
$a[$extras[$v]] = $a[$k];
unset($a[$k]);
}
if (isset($a[$extras[$v]]))
$a[$extras[$v]] += $plan[$k];
else
$a[$extras[$v]] = $plan[$k];
} else {
if (isset($a[$k]))
$a[$k] += $plan[$k];
else
$a[$k] = $plan[$k];
}
}
}
// Return the output sorted
$return = array();
foreach (array('base_down_peak','base_down_offpeak','base_up_peak','base_up_offpeak') as $k)
if (isset($a[$k]))
$return[$k] = $a[$k];
return $return;
}
}
?>

View File

@@ -0,0 +1,59 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class supports ADSL Plans
*
* @package OSB
* @subpackage ADSL
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_ADSL_Plan extends ORMOSB {
// Relationships
protected $_belongs_to = array(
'adsl_supplier_plan'=>array(),
);
protected $_has_many = array(
'service'=>array('through'=>'service__adsl'),
);
protected $_formats = array(
'extra_down_peak'=>array(
'Tax::add'=>array(),
'Currency::display'=>array(),
),
'extra_down_offpeak'=>array(
'Tax::add'=>array(),
'Currency::display'=>array(),
),
'extra_up_peak'=>array(
'Tax::add'=>array(),
'Currency::display'=>array(),
),
'extra_up_offpeak'=>array(
'Tax::add'=>array(),
'Currency::display'=>array(),
),
);
/**
* Show the ADSL allowance as a peak/offpeak metric
*/
public function allowance($string=TRUE) {
$output = ADSL::allowance(array(
'base_down_peak'=>$this->base_down_peak,
'base_down_offpeak'=>$this->base_down_offpeak,
'base_up_peak'=>$this->base_up_peak,
'base_up_offpeak'=>$this->base_up_offpeak,
'extra_down_peak'=>$this->extra_down_peak,
'extra_down_offpeak'=>$this->extra_down_offpeak,
'extra_up_peak'=>$this->extra_up_peak,
'extra_up_offpeak'=>$this->extra_up_offpeak,
));
return $string ? implode('/',$output) : $output;
}
}
?>

View File

@@ -0,0 +1,40 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class supports ADSL Suppliers
*
* @package OSB
* @subpackage ADSL
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_ADSL_Supplier extends ORMOSB {
// Relationships
protected $_has_many = array(
'adsl_supplier_plan'=>array('foreign_key'=>'supplier_id'),
);
protected $_updated_column = FALSE;
/**
* Return a list of services for this supplier
*
* @param boolean $active TRUE List only active Services|False List all services
*/
public function services($active=TRUE) {
$services = array();
// Get a list of plans made for this supplier
foreach ($this->adsl_supplier_plan->find_all() as $aspo)
// Find all the plan who use this supplier plan
foreach ($aspo->adsl_plan->find_all() as $apo)
// Find all the services who use this plan
foreach ($apo->service->find_all() as $so)
array_push($services,$so);
return $services;
}
}
?>

View File

@@ -0,0 +1,39 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class supports ADSL Plans
*
* @package OSB
* @subpackage ADSL
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_ADSL_Supplier_Plan extends ORMOSB {
// Relationships
protected $_has_many = array(
'adsl_plan'=>array(),
);
protected $_belongs_to = array(
'adsl_supplier'=>array('foreign_key'=>'supplier_id'),
);
/**
* Show the ADSL allowance as a peak/offpeak metric
*/
public function allowance() {
return sprintf('%s/%s',$this->base_down_peak+$this->base_up_peak,$this->base_down_offpeak+$this->base_up_offpeak);
}
public function tax() {
// @todo This should be taken from the users session
// @todo rounding should be a system default
return round($this->base_cost*.1,2);
}
public function name() {
return $this->product_id;
}
}
?>

View File

@@ -0,0 +1,12 @@
<!-- //@todo To translate -->
<table class="box-full">
<tr>
<td style="width: 60%;">Contract Term</td>
<td class="head" colspan="2"><?php echo $record->display('contract_term'); ?></td>
</tr>
<tr>
<!-- @todo This should get tax settings from the session -->
<td>Minimum Cost</td>
<td class="head" colspan="2"><?php echo Currency::display(Tax::add($record->contract_term*$price_base+$price_setup)); ?> <span style="font-size: 80%; font-weight:normal;"><?php printf('(%s * %s + %s)',$record->contract_term,Tax::add($price_base),Tax::add($price_setup)); ?></span></td>
</tr>
</table>

View File

@@ -0,0 +1,26 @@
<!-- //@todo To translate -->
<table class="box-full">
<tr>
<td style="width: 60%;">Speed</td>
<td class="head" colspan="2"><?php echo $record->display('speed'); ?></td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>Peak</td>
<td>Off Peak</td>
</tr>
<tr>
<td>Included Download Traffic</td>
<!-- // @todo Since price is stored in the DB in GB, so should the traffic. -->
<td class="head"><?php echo $record->base_down_peak/1000; ?> GB</td>
<td class="head"><?php echo $record->base_down_offpeak/1000; ?> GB</td>
</tr>
<tr>
<td>Extra Download Traffic</td>
<td class="head"><?php echo $record->display('extra_down_peak'); ?>/GB</td>
<td class="head"><?php echo $record->display('extra_down_offpeak'); ?>/GB</td>
</tr>
</table>

View File

@@ -0,0 +1,22 @@
<?php
/**
* osBilling - Open Billing Software
*
* Originally authored by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
* @package osBilling
* @subpackage Modules:ADSL
*/
/**
* This class provides the ability to define ADSL Suppliers.
*
* @package osBilling
* @subpackage Modules:ADSL
*/
class adsl_supplier extends OSB_module {
}
?>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<construct>
<!-- define the module name -->
<module>adsl_supplier</module>
<!-- define the module table name -->
<table>adsl_supplier</table>
<!-- define the module dependancy(s) -->
<dependancy/>
<!-- define the DB cache in seconds -->
<cache>0</cache>
<!-- define the default order_by field for SQL queries -->
<order_by>name</order_by>
<!-- define the methods -->
<limit>25</limit>
<!-- define the fields -->
<field>
<id>
<type>I4</type>
<unique>1</unique>
<index>1</index>
</id>
<site_id>
<type>I4</type>
</site_id>
<status>
<display>Active</display>
<type>L</type>
</status>
<debug>
<type>L</type>
</debug>
<name>
<display>Supplier</display>
<type>C(128)</type>
<min_len>1</min_len>
<max_len>128</max_len>
<validate>any</validate>
</name>
<notes>
<type>C(255)</type>
</notes>
<provision_plugin>
<type>C(128)</type>
<min_len>1</min_len>
<max_len>128</max_len>
</provision_plugin>
<provision_plugin_data>
<type>X2</type>
<convert>array</convert>
</provision_plugin_data>
<max_accounts>
<type>I4</type>
</max_accounts>
</field>
<!-- define all the methods for this class, and the fields they have access to, if applicable. -->
<method>
<add>name</add>
<update>id,status,debug,name,notes,provision_plugin,provision_plugin_data,max_accounts</update>
<delete>id</delete>
<view>id,status,debug,name,notes,provision_plugin,provision_plugin_data,max_accounts</view>
<search>id,status,debug,name,notes,provision_plugin,provision_plugin_data,max_accounts</search>
</method>
<!-- define the method triggers -->
<trigger>0</trigger>
<!-- Template Helpers -->
<tpl>
<search_show>
<checkbox>
<field>id</field>
<type>checkbox</type>
<width>25px</width>
</checkbox>
<supplier_id>
<field>name</field>
</supplier_id>
</search_show>
</tpl>
</construct>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<install>
<module_properties>
<display>ADSL Suppliers</display>
<name>adsl_supplier</name>
<table>adsl_supplier</table>
<parent>adsl</parent>
<notes><![CDATA[This module records the ADSL suppliers]]></notes>
<dependancy>adsl</dependancy>
<sub_modules></sub_modules>
<menu_display>1</menu_display>
</module_properties>
<sql_inserts>
<module_method>
<add>
<display>Add</display>
<name>add</name>
<page><![CDATA[%%:add]]></page>
<menu_display>1</menu_display>
</add>
<delete>
<name>delete</name>
</delete>
<search>
<name>search</name>
</search>
<search_show>
<display>Search</display>
<name>search_show</name>
<notes><![CDATA[Allow users to view the search results]]></notes>
</search_show>
<update>
<name>update</name>
</update>
<view>
<display>List</display>
<name>view</name>
<page><![CDATA[core:search&module=%%&_escape=1]]></page>
<menu_display>1</menu_display>
</view>
</module_method>
</sql_inserts>
</install>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<install>
<adsl_supplier>
<id>1</id>
<site_id>1</site_id>
<status>1</status>
<debug></debug>
<name>Exetel</name>
<notes></notes>
<provision_plugin></provision_plugin>
<provision_plugin_data><![CDATA[a:1:{i:0;s:0:"";}]]></provision_plugin_data>
<max_accounts></max_accounts>
</adsl_supplier>
<adsl_supplier>
<id>2</id>
<site_id>1</site_id>
<status>0</status>
<debug></debug>
<name>People</name>
<notes></notes>
<provision_plugin></provision_plugin>
<provision_plugin_data></provision_plugin_data>
<max_accounts></max_accounts>
</adsl_supplier>
<adsl_supplier_id>
<id>3</id>
</adsl_supplier_id>
</install>

View File

@@ -1,27 +1,34 @@
<?php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software; you can redistribute it and/or
* modify it under the terms of the Open AgileBill License
* License as published at http://www.agileco.com/agilebill/license1-4.txt
*
* For questions, help, comments, discussion, etc., please join the
* Agileco community forums at http://forum.agileco.com/
*
* Originally authored by Tony Landis, AgileBill LLC
*
* Recent modifications by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
*
* @link http://www.agileco.com/
* @copyright 2004-2008 Agileco, LLC.
* @license http://www.agileco.com/agilebill/license1-4.txt
* @author Tony Landis <tony@agileco.com>
* @author Tony Landis <tony@agileco.com>
* @package AgileBill
* @version 1.4.93
* @subpackage Module:Asset
*/
class asset
{
var $module = "asset";
/**
* The main AgileBill Asset Class
*
* @package AgileBill
* @subpackage Module:Asset
*/
class asset extends OSB_module {
/* check availibility */
function available($assetPoolId, $qty=1) {
$db=&DB();
@@ -110,73 +117,5 @@ class asset
$C_debug->alert('Unable to process the uploaded file.');
}
}
function construct() {
$this->xml_construct = PATH_MODULES . $this->module . "/" . $this->module . "_construct.xml";
$C_xml = new CORE_xml;
$construct = $C_xml->xml_to_array($this->xml_construct);
$this->method = $construct["construct"]["method"];
$this->trigger = $construct["construct"]["trigger"];
$this->field = $construct["construct"]["field"];
$this->table = $construct["construct"]["table"];
$this->module = $construct["construct"]["module"];
$this->cache = $construct["construct"]["cache"];
$this->order_by = $construct["construct"]["order_by"];
$this->limit = $construct["construct"]["limit"];
}
function add($VAR) {
$this->construct();
$type = "add";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->add($VAR, $this, $type);
}
function view($VAR) {
$this->construct();
$type = "view";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->view($VAR, $this, $type);
}
function update($VAR) {
$this->construct();
$type = "update";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->update($VAR, $this, $type);
}
function delete($VAR) {
$this->construct();
$db = new CORE_database;
$db->mass_delete($VAR, $this, "");
}
function search_form($VAR) {
$this->construct();
$type = "search";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->search_form($VAR, $this, $type);
}
function search($VAR) {
$this->construct();
$type = "search";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->search($VAR, $this, $type);
}
function search_show($VAR) {
$this->construct();
$type = "search";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->search_show($VAR, $this, $type);
}
}
?>
?>

View File

@@ -1,64 +1,121 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<construct>
<module>asset</module>
<table>asset</table>
<dependancy></dependancy>
<cache>0</cache>
<order_by>asset</order_by>
<limit>35</limit>
<field>
<id>
<type>I8</type>
<unique>1</unique>
</id>
<site_id>
<type>I4</type>
</site_id>
<date_orig>
<type>I8</type>
<convert>date-now</convert>
</date_orig>
<date_last>
<type>I8</type>
<convert>date-now</convert>
</date_last>
<status>
<type>L</type>
</status>
<service_id>
<type>I8</type>
</service_id>
<pool_id>
<type>I4</type>
<asso_table>asset_pool</asso_table>
<asso_field>name</asso_field>
<validate>any</validate>
</pool_id>
<asset>
<type>C(128)</type>
<min_len>1</min_len>
<max_len>128</max_len>
</asset>
<misc>
<type>C(255)</type>
</misc>
</field>
<method>
<add>id,site_id,date_orig,date_last,status,service_id,pool_id,asset,misc</add>
<update>id,site_id,date_last,status,service_id,pool_id,asset,misc</update>
<delete>id,site_id,date_orig,date_last,status,service_id,pool_id,asset,misc</delete>
<view>id,site_id,date_orig,date_last,status,service_id,pool_id,asset,misc</view>
<search>id,site_id,date_orig,date_last,status,service_id,pool_id,asset,misc</search>
</method>
<index>
<assets>id,site_id</assets>
<asso>pool_id</asso>
<service>service_id</service>
<asset>asset</asset>
</index>
<trigger>0</trigger>
</construct>
<!-- Module name -->
<module>asset</module>
<!-- Module supporting database table -->
<table>asset</table>
<!-- Module dependancy(s) (module wont install if these modules are not yet installed) -->
<dependancy></dependancy>
<!-- DB cache in seconds -->
<cache>0</cache>
<!-- Default order_by field for SQL queries -->
<order_by>asset</order_by>
<!-- Default SQL limit for SQL queries -->
<limit>25</limit>
<!-- Schema version (used to determine if the schema has change during upgrades) -->
<version>0</version>
<!-- Database indexes -->
<index>
<assets>id,site_id</assets>
<asso>pool_id</asso>
<service>service_id</service>
<asset>asset</asset>
</index>
<!-- Database fields -->
<field>
<!-- Record ID -->
<id>
<index>1</index>
<type>I8</type>
<unique>1</unique>
</id>
<!-- Site ID -->
<site_id>
<index>1</index>
<type>I4</type>
</site_id>
<!-- Date record created -->
<date_orig>
<convert>date-now</convert>
<display>Date Created</display>
<type>I8</type>
</date_orig>
<!-- Date record updated -->
<date_last>
<convert>date-now</convert>
<display>Date Updated</display>
<type>I8</type>
</date_last>
<!-- Record active (BOOL)-->
<status>
<display>Active</display>
<type>L</type>
</status>
<service_id>
<display>Service ID</display>
<type>I8</type>
</service_id>
<pool_id>
<display>Pool</display>
<asso_table>asset_pool</asso_table>
<asso_field>name</asso_field>
<type>I4</type>
<validate>any</validate>
</pool_id>
<asset>
<display>Asset</display>
<min_len>1</min_len>
<max_len>128</max_len>
<type>C(128)</type>
</asset>
<misc>
<display>Notes</display>
<type>C(255)</type>
</misc>
</field>
<!-- Methods for this class, and the fields they have access to, if applicable -->
<method>
<add>status,pool_id,asset,misc</add>
<update>id,status,service_id,pool_id,asset,misc</update>
<delete>id</delete>
<view>id,date_orig,date_last,status,service_id,pool_id,asset,misc</view>
<search>id,date_orig,date_last,status,service_id,pool_id,asset,misc</search>
</method>
<!-- Method triggers -->
<trigger></trigger>
<!-- Template page display titles -->
<title>
<add>Add Asset</add>
<view>View Asset</view>
</title>
<!-- Template helpers -->
<tpl>
<search_show>
<checkbox>
<field>id</field>
<type>checkbox</type>
<width>25px</width>
</checkbox>
<date_last>
<field>date_last</field>
<type>date</type>
</date_last>
<status>
<field>status</field>
<type>bool_icon</type>
</status>
<pool_id>
<field>pool_id</field>
</pool_id>
<asset>
<field>asset</field>
</asset>
</search_show>
</tpl>
</construct>

View File

@@ -1,47 +1,64 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<install>
<module_properties>
<name>asset</name>
<parent>asset</parent>
<notes>Manage assets that can be assigned to services and maintain their availibility status</notes>
<menu_display>1</menu_display>
<dependancy></dependancy>
<sub_modules>asset_pool</sub_modules>
</module_properties>
<sql_inserts>
<module_method>
<add>
<name>add</name>
<page>%%:add</page>
<menu_display>1</menu_display>
</add>
<update>
<name>update</name>
</update>
<delete>
<name>delete</name>
</delete>
<view>
<name>view</name>
<page>core:search&amp;module=%%&amp;_escape=1</page>
<menu_display>1</menu_display>
</view>
<search>
<name>search</name>
<page>%%:search_form</page>
<menu_display>1</menu_display>
</search>
<search_form>
<name>search_form</name>
</search_form>
<search_show>
<name>search_show</name>
</search_show>
<import>
<name>import</name>
<page>%%:import</page>
<menu_display>1</menu_display>
</import>
</module_method>
</sql_inserts>
</install>
<install>
<!-- Tree Menu Module Properties -->
<module_properties>
<!-- MODULE Dependancy, this module wont be installed if the dependant modules dont exist -->
<dependancy></dependancy>
<!-- Translated display to use on the tree -->
<display>Asset</display>
<!-- Display a module in the menu tree -->
<menu_display>1</menu_display>
<!-- MODULE Name -->
<name>asset</name>
<!-- MODULE Notes, these notes show up in the modules table, as a description of the module -->
<notes><![CDATA[Manage assets that can be assigned to services and maintain their availibility status.]]></notes>
<!-- MODULE Parent, the parent node in the tree -->
<parent></parent>
<!-- SUB Modules to install with this one -->
<sub_modules>asset_pool</sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->
<module_method>
<add>
<display>Add</display>
<menu_display>1</menu_display>
<name>add</name>
<notes><![CDATA[Add records]]></notes>
</add>
<delete>
<name>delete</name>
<notes><![CDATA[Delete records]]></notes>
</delete>
<search>
<display>List</display>
<name>search</name>
<menu_display>1</menu_display>
<notes><![CDATA[List records]]></notes>
<page><![CDATA[core:search&module=%%&_next_page_one=view]]></page>
</search>
<search_form>
<name>search_form</name>
<notes><![CDATA[Search for records]]></notes>
</search_form>
<search_show>
<name>search_show</name>
<notes><![CDATA[Show the results of a search]]></notes>
</search_show>
<update>
<name>update</name>
<notes><![CDATA[Update a record]]></notes>
</update>
<view>
<name>view</name>
<notes><![CDATA[View a record]]></notes>
</view>
<import>
<display>Import</display>
<menu_display>1</menu_display>
<name>import</name>
</import>
</module_method>
</install>

View File

@@ -1,91 +1,33 @@
<?php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software; you can redistribute it and/or
* modify it under the terms of the Open AgileBill License
* License as published at http://www.agileco.com/agilebill/license1-4.txt
*
* For questions, help, comments, discussion, etc., please join the
* Agileco community forums at http://forum.agileco.com/
*
* Originally authored by Tony Landis, AgileBill LLC
*
* Recent modifications by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
*
* @link http://www.agileco.com/
* @copyright 2004-2008 Agileco, LLC.
* @license http://www.agileco.com/agilebill/license1-4.txt
* @author Tony Landis <tony@agileco.com>
* @author Tony Landis <tony@agileco.com>
* @package AgileBill
* @version 1.4.93
* @subpackage Module:AssetPool
*/
class asset_pool
{
# Open the constructor for this mod
function construct()
{
$this->table = 'asset_pool';
$this->module = 'asset_pool';
$this->xml_construct = PATH_MODULES . $this->module . "/" . $this->module . "_construct.xml";
$C_xml = new CORE_xml;
$construct = $C_xml->xml_to_array($this->xml_construct);
$this->method = $construct["construct"]["method"];
$this->trigger = $construct["construct"]["trigger"];
$this->field = $construct["construct"]["field"];
$this->cache = $construct["construct"]["cache"];
$this->order_by = $construct["construct"]["order_by"];
$this->limit = $construct["construct"]["limit"];
}
function add($VAR)
{
$this->construct();
$type = "add";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->add($VAR, $this, $type);
}
function view($VAR)
{
$this->construct();
$type = "view";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->view($VAR, $this, $type);
}
function update($VAR)
{
$this->construct();
$type = "update";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->update($VAR, $this, $type);
}
function delete($VAR)
{
$this->construct();
$db = new CORE_database;
$db->mass_delete($VAR, $this, "");
}
function search($VAR)
{
$this->construct();
$type = "search";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->search($VAR, $this, $type);
}
function search_show($VAR)
{
$this->construct();
$type = "search";
$this->method["$type"] = explode(",", $this->method["$type"]);
$db = new CORE_database;
$db->search_show($VAR, $this, $type);
}
/**
* The main AgileBill Asset Pool Class
*
* @package AgileBill
* @subpackage Module:AssetPool
*/
class asset_pool extends OSB_module {
}
?>
?>

View File

@@ -1,33 +1,73 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<construct>
<module>asset_pool</module>
<name>asset_pool</name>
<table>asset_pool</table>
<dependancy>asset</dependancy>
<cache>0</cache>
<order_by>name</order_by>
<limit>35</limit>
<index>
<main>id,site_id</main>
</index>
<field>
<id>
<type>I4</type>
<unique>1</unique>
</id>
<site_id>
<type>I4</type>
</site_id>
<name>
<type>C(32)</type>
</name>
</field>
<method>
<add>id,site_id,name</add>
<update>id,site_id,name</update>
<delete>id,site_id,name</delete>
<view>id,site_id,name</view>
<search>id,site_id,name</search>
</method>
<trigger>0</trigger>
</construct>
<construct>
<!-- Module name -->
<module>asset_pool</module>
<!-- Module supporting database table -->
<table>asset_pool</table>
<!-- Module dependancy(s) (module wont install if these modules are not yet installed) -->
<dependancy>asset</dependancy>
<!-- DB cache in seconds -->
<cache>0</cache>
<!-- Default order_by field for SQL queries -->
<order_by>NAME</order_by>
<!-- Default SQL limit for SQL queries -->
<limit>25</limit>
<!-- Schema version (used to determine if the schema has change during upgrades) -->
<version>0</version>
<!-- Database indexes -->
<index>
<main>id,site_id</main>
</index>
<!-- Database fields -->
<field>
<!-- Record ID -->
<id>
<index>1</index>
<type>I4</type>
<unique>1</unique>
</id>
<!-- Site ID -->
<site_id>
<index>1</index>
<type>I4</type>
</site_id>
<name>
<display>Name</display>
<type>C(32)</type>
</name>
</field>
<!-- Methods for this class, and the fields they have access to, if applicable -->
<method>
<add>name</add>
<update>id,name</update>
<delete>id</delete>
<view>id,name</view>
<search>id,name</search>
</method>
<!-- Method triggers -->
<trigger></trigger>
<!-- Template page display titles -->
<title>
<add>Add Asset Pool</add>
<view>View Asset Pool</view>
</title>
<!-- Template helpers -->
<tpl>
<search_show>
<checkbox>
<field>id</field>
<type>checkbox</type>
<width>25px</width>
</checkbox>
<name>
<field>name</field>
</name>
</search_show>
</tpl>
</construct>

View File

@@ -1,38 +1,57 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<install>
<module_properties>
<name>asset_pool</name>
<table>asset_pool</table>
<parent>asset</parent>
<notes>Manage multiple pools of assets</notes>
<menu_display>1</menu_display>
<dependancy>asset</dependancy>
<sub_modules></sub_modules>
</module_properties>
<sql_inserts>
<module_method>
<add>
<name>add</name>
<page>%%:add</page>
<menu_display>1</menu_display>
</add>
<update>
<name>update</name>
</update>
<search>
<name>search</name>
</search>
<search_show>
<name>search_show</name>
</search_show>
<delete>
<name>delete</name>
</delete>
<view>
<name>view</name>
<page>core:search&amp;module=%%&amp;_escape=1</page>
<menu_display>1</menu_display>
</view>
</module_method>
</sql_inserts>
</install>
<install>
<!-- Tree Menu Module Properties -->
<module_properties>
<!-- MODULE Dependancy, this module wont be installed if the dependant modules dont exist -->
<dependancy>asset</dependancy>
<!-- Translated display to use on the tree -->
<display>Asset Pool</display>
<!-- Display a module in the menu tree -->
<menu_display>1</menu_display>
<!-- MODULE Name -->
<name>asset_pool</name>
<!-- MODULE Notes, these notes show up in the modules table, as a description of the module -->
<notes><![CDATA[Manage multiple pools of assets.]]></notes>
<!-- MODULE Parent, the parent node in the tree -->
<parent>asset</parent>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->
<module_method>
<add>
<display>Add</display>
<menu_display>1</menu_display>
<name>add</name>
<notes><![CDATA[Add records]]></notes>
</add>
<delete>
<name>delete</name>
<notes><![CDATA[Delete records]]></notes>
</delete>
<search>
<display>List</display>
<menu_display>1</menu_display>
<name>search</name>
<notes><![CDATA[List records]]></notes>
<page><![CDATA[core:search&module=%%&_next_page_one=view]]></page>
</search>
<search_form>
<name>search_form</name>
<notes><![CDATA[Search for records]]></notes>
</search_form>
<search_show>
<name>search_show</name>
<notes><![CDATA[Show the results of a search]]></notes>
</search_show>
<update>
<name>update</name>
<notes><![CDATA[Update a record]]></notes>
</update>
<view>
<name>view</name>
<notes><![CDATA[View a record]]></notes>
</view>
</module_method>
</install>

View File

@@ -17,7 +17,7 @@
<!-- SUB Modules to install with this one -->
<sub_modules></sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type>base</type>
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->

View File

@@ -17,7 +17,7 @@
<!-- SUB Modules to install with this one -->
<sub_modules></sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type>base</type>
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->

View File

@@ -17,7 +17,7 @@
<!-- SUB Modules to install with this one -->
<sub_modules></sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type>base</type>
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->

View File

@@ -29,16 +29,6 @@
* @subpackage Module:Cart
*/
class cart extends OSB_module {
var $account_id;
var $session_id;
/**
* How many associated product levels to check for products to grant?
*
* @var int
*/
var $module='cart';
/**
* Admin View Cart Contents
*/
@@ -188,148 +178,49 @@ class cart extends OSB_module {
/**
* Get cart contents and return adodb rs
*/
public function get_contents() {
$db = &DB();
$sql = sprintf('SELECT DISTINCT c.* FROM %scart as c',AGILE_DB_PREFIX);
if (! empty($this->account_id)) {
$sql .= sprintf(' LEFT JOIN %ssession AS s ON (s.site_id=%s AND s.account_id=%s) WHERE (c.account_id=%s OR c.session_id=s.id) ',
AGILE_DB_PREFIX,DEFAULT_SITE,$this->account_id,$this->account_id);
} else {
$sql .= sprintf(' WHERE c.session_id=%s',$db->qstr(SESS));
$this->account_id = SESS_ACCOUNT;
}
$sql .= sprintf(' AND c.site_id=%s AND (c.cart_parent_id=0 OR c.cart_parent_id IS NULL) ORDER BY c.cart_type,c.date_orig',DEFAULT_SITE);
$result = $db->Execute($sql);
return $result;
}
/**
* Convert cart contents into invoice object & get smarty data
*/
public function put_contents_invoice(&$result,&$invoice) {
$db = &DB();
# get parent cart items
$i = 0;
$smart = array();
while (! $result->EOF) {
$id = $result->fields['id'];
$this->addInvoiceItem($id,$result,$invoice,$smart,$i);
switch ($result->fields['cart_type']) {
# AD HOC
case 3:
$smart[$i]['price'] = $invoice->invoice_item[$id]['total_amt'];
break;
# Domain
case 2:
$smart[$i]['price'] = $invoice->invoice_item[$id]['total_amt'];
$smart[$i]['tld_arr'] = $invoice->tld_arr[$id];
$smart[$i]['sku'] = sprintf('DOMAIN-%s',strtoupper($result->fields['host_type']));
break;
# Product
default:
@$smart[$i]['price'] = $invoice->price_arr[$id];
}
# Get the product attributes
$smart[$i]['attr'] = '';
if (! empty($invoice->invoice_item[$id]['product_attr_cart'])) {
@$attrib = explode("\r\n",$invoice->invoice_item[$id]['product_attr_cart']);
foreach($attrib as $attr) {
$attributei = explode('==',$attr);
if (! empty($attributei[0]) && !empty($attributei[1]))
$smart[$i]['attr'] .= sprintf('<span style="text-decoration: underline;">%s</span> : %s<br/>',$attributei[0],$attributei[1]);
}
}
# Get all children of this item
$ii = 0;
$resultassoc = $db->Execute(sqlSelect($db,'cart','*',sprintf('cart_parent_id=%s AND id !=%s',$result->fields['id'],$result->fields['id'])));
if ($resultassoc && $resultassoc->RecordCount()) {
while (!$resultassoc->EOF) {
$id = $resultassoc->fields['id'];
$this->addInvoiceItem($id,$resultassoc,$invoice,$smart,$i,$ii,true);
# Domain
if ($resultassoc->fields['cart_type'] == 2 ) {
$smart[$i]['assoc'][$ii]['price'] = $invoice->invoice_item[$id]['total_amt'];
$smart[$i]['assoc'][$ii]['tld_arr'] = $invoice->tld_arr[$id];
$smart[$i]['assoc'][$ii]['sku'] = sprintf('DOMAIN-%s',strtoupper($result->fields['host_type']));
}
$resultassoc->MoveNext();
}
}
$result->MoveNext();
$i++;
}
return $smart;
public function sGetContents() {
return $this->sql_GetRecords(array('where'=>array('session_id'=>SESS)));
}
/**
* View Cart Contents
*
* @uses invoice
*/
public function user_view($VAR) {
global $smarty;
# Get cart contents RS
$result = $this->get_contents();
if (! $result || $result->RecordCount() == 0) {
# Get cart contents
if (! count($results = $this->sGetContents())) {
$smarty->assign('result','0');
return false;
}
// init invoice object
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$invoice = new invoice;
$invoice->initNew(0);
$invoice->taxable=false;
$invoice->discount=false;
$invoice->setRecordAttr('account_id',SESS_ACCOUNT);
$smart = $this->put_contents_invoice($result,$invoice);
$smarty->assign('results',count($invoice->invoice_item));
$smarty->assign('cart',$smart);
}
/**
* Run a cart item through the invoice class to retrieve totals, discounts, taxes, attributes, etc.
*
* @param int $id
* @param array $result
* @param object $invoice
* @param array $smart
* @param int $i
* @param int $assoc
*/
private function addInvoiceItem($id,&$result,&$invoice,&$smart,$i,$ii=false,$assoc=false) {
$invoice->addItem(
$id,
$result
);
if (! $assoc) {
@$smart[$i] = $result->fields;
@$smart[$i]['product'] = $invoice->product[$id];
@$smart[$i]['price_base'] = $invoice->invoice_item[$id]['price_base'];
@$smart[$i]['price_setup'] = $invoice->invoice_item[$id]['price_setup'];
} else {
@$smart[$i]['assoc'][$ii] = $result->fields;
@$smart[$i]['assoc'][$ii]['product'] = $invoice->product[$id];
@$smart[$i]['assoc'][$ii]['price_base'] = $invoice->invoice_item[$id]['price_base'];
@$smart[$i]['assoc'][$ii]['price_setup'] = $invoice->invoice_item[$id]['price_setup'];
foreach ($results as $result) {
$invoice->aaddItem(array(
'cart_id'=>$result['id'],
'domain_name'=>$result['domain_name'],
'domain_term'=>$result['domain_term'],
'domain_tld'=>$result['domain_tld'],
'domain_type'=>$result['domain_type'],
'item_type'=>0,
'product_id'=>$result['product_id'],
'quantity'=>$result['quantity'],
'recurr_schedule'=>$result['recurr_schedule'],
'product_attr'=>$result['product_attr'],
'product_attr_cart'=>$result['product_attr'],
'host_type'=>$result['host_type'],
'type'=>in_array($result['host_type'],array('register')) ? 'domain' : null
));
}
$smarty->assign('results',$invoice->sCountItems());
$smarty->assign('cart',$invoice->getItems());
}
/**
@@ -761,7 +652,6 @@ class cart extends OSB_module {
# Make sure this service is not in the cart
$sql = 'DELETE FROM ' . AGILE_DB_PREFIX . 'cart WHERE site_id='.$db->qstr(DEFAULT_SITE).' AND service_id='.$db->qstr($VAR['service_id']) ;
echo '<PRE>';print_r(array($sql=>$sql,'q'=>sqlDelete($db,'cart',array('service_id'=>$VAR['service_id']))));die();
$rs = $db->Execute($sql);
# Make sure this service has no outstanding invoices:

View File

@@ -17,7 +17,7 @@
<!-- SUB Modules to install with this one -->
<sub_modules></sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type>base</type>
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->

View File

@@ -0,0 +1,105 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides a order cart
*
* @package OSB
* @subpackage Cart
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Cart {
public static function instance() {
return new Cart;
}
/**
* Return a list of items in the cart
*/
public function contents() {
return ORM::factory('cart')
->where('session_id','=',Session::instance()->id());
}
/**
* Print an HTML cart list
*
* @param bool $detail List a detailed cart or a summary cart
*/
public function cart_block() {
// If the cart is empty, we'll return here.
if (! $this->contents()->count_all())
return 'The cart is empty.';
Style::add(array(
'type'=>'file',
'data'=>'css/cart_blocklist.css',
));
$output = '<table class="cart_blocklist" border="0">';
foreach ($this->contents()->find_all() as $item) {
$ppa = $item->product->get_price_array();
$pdata = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
$output .= View::factory('cart/block_list')
->set('item',$item)
->set('price_setup',$item->quantity*$ppa[$item->recurr_schedule]['price_setup'])
->set('price_firstinvoice',$item->quantity*$ppa[$item->recurr_schedule]['price_base']*$pdata['prorata']);
}
$output .= '<tr class="submit">';
$output .= sprintf('<td colspan="3">%s&nbsp;%s</td>',
Form::button('checkout','Checkout',array('type' => 'submit')),
Form::button('empty','Empty',array('type' => 'submit')));
$output .= '</tr>';
$output .= '</table>';
return $output;
}
/**
* Test to see if the cart has some trial options
*
* @return boolean
*/
public function has_trial() {
foreach ($this->contents()->find_all() as $item)
if ($item->product->is_trial())
return TRUE;
return FALSE;
}
public function subtotal() {
$total = 0;
foreach ($this->contents()->find_all() as $item) {
$ppa = $item->product->get_price_array();
$period = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
$total += $item->quantity*$ppa[$item->recurr_schedule]['price_base']*$period['prorata'];
$total += $item->quantity*$ppa[$item->recurr_schedule]['price_setup'];
}
return $total;
}
/**
* Calculate Tax for the cart items
*
* @return unknown_type
* @uses Tax
*/
public function tax() {
// @todo Tax zone should come from somewhere else
return Tax::detail(61,NULL,$this->subtotal());
}
public function total() {
// @todo Tax zone should come from somewhere else
return $this->subtotal()+Tax::total(61,NULL,$this->subtotal());
}
}
?>

View File

@@ -0,0 +1,116 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides a order cart
*
* @package OSB
* @subpackage Cart
* @category Controllers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Controller_Cart extends Controller_TemplateDefault {
/**
* Default action when called
*/
public function action_index() {
return $this->action_list();
}
/**
* List items in the cart
*/
public function action_list() {
// @todo - this should be a global config item
$mediapath = Route::get('default/media');
$block = new block;
// If the cart is empty, we'll return here.
if (! Cart::instance()->contents()->count_all())
$block->add(array(
'title'=>_('Empty Cart'),
'body'=>_('The cart is empty')
));
else {
Style::add(array(
'type'=>'file',
'data'=>'css/cart_contents.css',
));
$output = Form::open('checkout/noready');
foreach (Cart::instance()->contents()->find_all() as $item) {
$ppa = $item->product->get_price_array();
$pdata = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
$price_box = View::factory('cart/list_pricebox')
->set('price_recurring',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_base']))
->set('price_firstinvoice',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_base']*$pdata['prorata']))
->set('price_setup',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_setup']))
->set('item',$item)
->set('mediapath',$mediapath);
$output .= View::factory('cart/list_item')
->set('price_box',$price_box)
->set('service_start',$pdata['date'])
->set('service_end',$pdata['end'])
->set('price_recurring',Currency::display($item->quantity*$ppa[$item->recurr_schedule]['price_base']))
->set('item',$item)
->set('mediapath',$mediapath);
// If we are a plugin product, we might need more information
if ($item->product->prod_plugin AND method_exists($item->product->prod_plugin_file,'product_cart')) {
$output .= View::factory(sprintf('%s/cart_info',strtolower($item->product->prod_plugin_file)));
// @todo JS validation will need to verify data before submission
}
}
$output .= '<div>'.Form::submit('submit',_('Checkout')).'</div>';
$output .= Form::close();
$block->add(array(
'title'=>_('Your Items'),
'body'=>$output,
));
}
$this->template->content = $block;
// Suppress our right hand tab
$this->template->right = ' ';
}
/**
* Add an item to the cart
*/
public function action_add() {
$cart = ORM::factory('cart');
$cart->session_id = Session::instance()->id();
if (Auth::instance()->logged_in())
$cart->account_id = Auth::instance()->get_user()->id;
if ($cart->values($_POST)->check())
$cart->save();
else
echo Kohana::debug($cart->validate()->errors());
if ($cart->saved())
Request::instance()->redirect('cart/index');
else
throw new Kohana_Exception(_('There was a problem adding the item to the cart.'));
}
public function action_empty() {
$cart = ORM::factory('cart')
->where('session_id','=',session_id());
$cart->delete_all();
$this->template->content = _('Cart Emptied');
}
}
?>

View File

@@ -0,0 +1,25 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class supports a product cart
*
* @package OSB
* @subpackage Cart
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Cart extends ORMOSB {
protected $_belongs_to = array(
'product'=>array(),
);
protected $_formats = array(
'recurr_schedule'=>array('StaticList_RecurSchedule::display'=>array()),
);
// Cart doesnt use the update column
protected $_updated_column = FALSE;
}
?>

View File

@@ -0,0 +1,32 @@
/** Cart Block Contents Style Sheet **/
table.cart_blocklist {
/* margin-left: auto; */
/* margin-right: auto; */
width: 100%;
background-color: #F9F9FA;
border: 0px solid #AAAACC;
padding: 2px;
}
table.cart_blocklist tr td.sku {
color: #000000;
font-size: 75%;
}
table.cart_blocklist tr td.price {
font-weight: bold;
text-align: right;
}
table.cart_blocklist tr td.schedule {
font-size: 60%;
}
table.cart_blocklist tr.submit td {
text-align: center;
}
table.cart_blocklist tr.submit td button {
font-size: 60%;
font-weight: bold;
}

View File

@@ -0,0 +1,46 @@
/** Cart Contents Style Sheet **/
table.cart_contents {
/* margin-left: auto; */
/* margin-right: auto; */
width: 100%;
background-color: #F9F9FA;
border: 0px solid #AAAACC;
padding: 2px;
}
table.cart_contents tr td.title {
color: #000000;
font-size: 125%;
}
table.cart_contents tr td.title a {
text-decoration: none;
color: #0000AA;
}
table.cart_contents tr td {
vertical-align: top;
}
table.cart_contents tr td.icon {
width: 22px;
}
table.cart_contents tr td.price_box {
width: 20%;
}
table.cart_contents tr td.price_box table.cart_detail_pricebox {
width: 100%;
background-color: #FAFAFB;
}
table.cart_contents tr td.price_box table.cart_detail_pricebox td.head {
text-align: left;
}
table.cart_contents tr td.price_box table.cart_detail_pricebox td.value {
font-weight: bold;
text-align: right;
}

View File

@@ -0,0 +1,34 @@
/** Checkout Cart Style Sheet **/
table.checkout_cartlist {
/* margin-left: auto; */
/* margin-right: auto; */
width: 100%;
background-color: #F9F9FA;
border: 0px solid #AAAACC;
padding: 2px;
}
table.checkout_cartlist tr td.title {
color: #000000;
font-size: 125%;
}
table.checkout_cartlist tr td.title a {
text-decoration: none;
color: #0000AA;
}
table.checkout_cartlist tr td {
vertical-align: top;
}
table.checkout_cartlist tr td.icon {
width: 22px;
}
table.checkout_cartlist tr td.value {
font-weight: bold;
font-size: 120%;
text-align: right;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,5 @@
<tr>
<td class="sku"><?php echo $item->product->sku; ?></td>
<td class="schedule"><?php echo $item->display('recurr_schedule');?></td>
<td class="price"><?php echo Currency::display($price_firstinvoice+$price_setup); ?></td>
</tr>

View File

@@ -0,0 +1,11 @@
<!-- @todo Translation required -->
<tr>
<td colspan="3" class="title"><b><?php echo HTML::anchor(sprintf('product/view/%s',$item->product->id),$item->product->product_translate->find()->name); ?></b></td>
<td class="value"><?php echo Currency::display($price_firstinvoice+$price_setup); ?></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>Current Service Period:</td>
<td><b><?php printf('%s -> %s',$service_start,$service_end);?></b></td>
<td>&nbsp;</td>
</tr>

View File

@@ -0,0 +1,25 @@
<table>
<!-- @todo This rounding should be a global configuration item -->
<tr>
<td><?php echo Country::icon($country); ?></td>
<td>Cart Sub-Total:</td>
<td><?php echo Currency::display($cart->subtotal()); ?></td>
</tr>
<?php if ($cart->tax()) { ?>
<?php foreach ($cart->tax() as $tax) { ?>
<!-- @todo This rounding should be a global configuration item -->
<!-- @todo Tax details should come from central configuration -->
<tr>
<td>&nbsp;</td>
<td>Tax (<?php echo $tax['description']; ?>):</td>
<td><?php echo Currency::display($tax['amount']); ?></td>
</tr>
<?php } ?>
<?php } ?>
<!-- @todo This rounding should be a global configuration item -->
<tr>
<td>&nbsp;</td>
<td>Cart Total:</td>
<td><?php echo Currency::display($cart->total()); ?></td>
</tr>
</table>

View File

@@ -0,0 +1,17 @@
<!-- @todo Translation required -->
<table class="cart_contents" border="0">
<tr>
<td colspan="3" class="title"><b><?php echo HTML::anchor(sprintf('product/view/%s',$item->product->id),$item->product->product_translate->find()->name); ?></b></td>
<td class="icon"><?php echo HTML::image($mediapath->uri(array('file'=>'img/edit-delete.png')),array('alt'=>_('Remove'))); ?></td>
<td rowspan="4" class="price_box"><?php echo $price_box; ?></td>
</tr>
<tr>
<td>&nbsp;</td><td>Pricing Structure:</td><td colspan="2"><b><?php echo $item->product->display('price_type'); ?></b></td>
</tr>
<tr>
<td>&nbsp;</td><td>Invoice Frequency:</td><td colspan="2"><b><?php echo $item->display('recurr_schedule'); ?> (<?php echo $price_recurring; ?>)</b></td>
</tr>
<tr>
<td>&nbsp;</td><td>Current Service Period:</td><td><b><?php printf('%s -> %s',$service_start,$service_end); ?></b></td>
</tr>
</table>

View File

@@ -0,0 +1,27 @@
<!-- @todo translation needed -->
<table class="cart_detail_pricebox" border="0">
<tr>
<td class="head">Re-Occuring Price</td>
<td class="value"><?php echo $price_recurring; ?></td>
<td>&nbsp;</td>
</tr>
<tr>
<td colspan="2">&nbsp;</td></tr>
<tr>
<td class="head">First Invoice</td>
<td class="value"><?php echo $price_firstinvoice; ?></td>
<td>&nbsp;</td>
</tr>
<?php if ($price_setup) { ?>
<tr>
<td class="head">Setup</td>
<td class="value"><?php echo $price_setup; ?></td>
<td>&nbsp;</td>
</tr>
<?php } ?>
<tr>
<td class="head">Quantity</td><!-- // @todo Quantity cannot be changed -->
<td class="value"><?php echo Form::input('quantity',$item->quantity,array('size'=>2,'disabled'=>'disabled')); ?></td>
<td class="icon"><?php echo HTML::image($mediapath->uri(array('file'=>'img/accessories-calculator-small.png')),array('alt'=>_('Re-Calc'))); ?></td>
</tr>
</table>

View File

@@ -29,322 +29,172 @@
* @subpackage Module:Charge
*/
class charge extends OSB_module {
var $xmlrpc=false;
private $xmlrpc = false;
function sweep_daily() {
$this->sweep('0');
public function task_SweepDaily() {
$this->sweep(0);
}
function sweep_weekly() {
$this->sweep('1');
public function task_SweepWeekly() {
$this->sweep(1);
}
function sweep_monthly() {
$this->sweep('2');
public function task_SweepMonthly() {
$this->sweep(2);
}
function sweep_quarterly() {
$this->sweep('3');
public function task_SweepQuarterly() {
$this->sweep(3);
}
function sweep_semi_annually() {
$this->sweep('4');
public function task_SweepSemiAnnually() {
$this->sweep(4);
}
function sweep_annually() {
$this->sweep('5');
public function task_SweepAnnually() {
$this->sweep(5);
}
function sweep($type) {
include_once(PATH_MODULES.'account_billing/account_billing.inc.php');
$account_billing = new account_billing;
private function sweep($type) {
global $C_list;
include_once(PATH_MODULES.'tax/tax.inc.php');
$taxObj = new tax;
# Load required elements
include_once(PATH_MODULES.'invoice/invoice.inc.php');
include_once(PATH_MODULES.'account/account.inc.php');
include_once(PATH_MODULES.'discount/discount.inc.php');
$account_billing = false;
if ($C_list->is_installed('account_billing')) {
include_once(PATH_MODULES.'account_billing/account_billing.inc.php');
$abo = new account_billing;
}
$charges = $this->sql_GetRecords(array('where'=>array('status'=>0,'sweep_type'=>$type),'orderby'=>'account_id,date_orig'));
# No charges
if (! count($charges))
return true;
# Start a transaction
$db = &DB();
$sql = "SELECT DISTINCT
".AGILE_DB_PREFIX."charge.id,
".AGILE_DB_PREFIX."charge.account_id,
".AGILE_DB_PREFIX."charge.service_id,
".AGILE_DB_PREFIX."charge.amount,
".AGILE_DB_PREFIX."charge.taxable,
".AGILE_DB_PREFIX."charge.attributes,
".AGILE_DB_PREFIX."charge.quantity,
".AGILE_DB_PREFIX."charge.product_id,
".AGILE_DB_PREFIX."charge.description,
".AGILE_DB_PREFIX."account.affiliate_id,
".AGILE_DB_PREFIX."account.reseller_id,
".AGILE_DB_PREFIX."account.country_id,
".AGILE_DB_PREFIX."account.currency_id,
".AGILE_DB_PREFIX."account.state
FROM
".AGILE_DB_PREFIX."charge
LEFT JOIN
".AGILE_DB_PREFIX."account
ON
".AGILE_DB_PREFIX."account.id = " . AGILE_DB_PREFIX."charge.account_id
WHERE
".AGILE_DB_PREFIX."charge.site_id = " . $db->qstr(DEFAULT_SITE) . "
AND
".AGILE_DB_PREFIX."account.site_id = " . $db->qstr(DEFAULT_SITE) . "
AND
".AGILE_DB_PREFIX."charge.status = " . $db->qstr('0') ."
AND
".AGILE_DB_PREFIX."charge.sweep_type = " . $db->qstr($type) ."
ORDER BY
".AGILE_DB_PREFIX."charge.account_id";
$rs = $db->Execute($sql);
if ($rs === false) {
global $C_debug;
$C_debug->error('charge.inc.php','charge :: sweep()', $db->ErrorMsg(). "\r\n\r\n". $sql);
return false;
if (AGILE_DB_TYPE == 'mysqlt') {
$db->StartTrans();
if (! $db->hasTransactions) {
global $C_debug;
$msg = "Transactions not supported in 'mysql' driver. Use 'mysqlt' or 'mysqli' driver";
$C_debug->alert($msg);
$C_debug->error(__FILE__,__METHOD__,$msg);
return false;
}
}
$account_id = false;
$invoice_id = false;
$i = false;
$i_total = false;
$invoice_count = 0;
$sweep_count = 0;
while(!$rs->EOF)
{
if( $rs->fields['account_id'] != $account_id )
{
$account_id = $rs->fields['account_id'];
$i=0;
$i_total = $this->count_account_charges($account_id, $rs->CurrentRow(), $rs);
$sub_total = 0;
$taxable_amount = 0;
$this_discount_total = 0;
$tax_amt = 0;
$discount_amt = 0;
# Start a new transaction
$trans = &DB();
$trans->StartTrans();
# Start a new invoice
$invoice_id = $db->GenID(AGILE_DB_PREFIX . 'invoice_id');
# check for any discounts for the parent invoice or account_id (applied at checkout and should continue to be applied if recurring type discount)
$discountObj = new discount;
# get parent invoice id if service specified (for discount checking)
$parent_invoice_id = false;
if($rs->fields['service_id']) {
$parentinv = $db->Execute(sqlSelect($db,"service","invoice_id","id={$rs->fields['service_id']}"));
if($parentinv && $parentinv->RecordCount()) {
$parent_invoice_id = $parentinv->fields['invoice_id'];
}
}
# get available discounts to this account/service
$discountObj->available_discounts($account_id, 1, $parent_invoice_id);
$ao = false;
$io = false;
foreach ($charges as $charge) {
# First Run
if (! $ao) {
$ao = new account($charge['account_id']);
}
# Next run, are we onto a new account?
if ($ao->getRecordAttr('id') != $charge['account_id']) {
$rs = $io->sql_SaveRecord(true);
if (! $rs) {
global $C_debug;
###########################
##### LINE ITEM ACTIONS ###
###########################
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
$db->FailTrans();
if( !empty($account_id) )
{
### Get the line item id
$invoice_item_id = $db->GenID(AGILE_DB_PREFIX . 'invoice_item_id');
### Set the invoice item details:
$product_id = $rs->fields['product_id'];
if(!empty($product_id) && empty($this->product["$product_id"]))
{
$sql = "SELECT sku FROM ".AGILE_DB_PREFIX."product WHERE
id = " . $db->qstr($product_id) . " AND
site_id = " . $db->qstr(DEFAULT_SITE);
$prod = $db->Execute($sql);
if($prod->RecordCount() > 0)
{
$sku = $prod->fields['sku'];
$this->product["$product_id"] = $sku;
$product_attr = '';
if(!empty($rs->fields['description']))
$product_attr = "Description=={$rs->fields['description']}\r\n";
$product_attr .= $rs->fields['attributes'];
}
else
{
$sku = $rs->fields['description'];
$this->product["$product_id"] = $sku;
$product_attr = $rs->fields['attributes'];
}
} elseif (!empty($this->product["$product_id"])) {
$sku = $this->product["$product_id"];
$product_attr = $rs->fields['attributes'];
} else {
$sku = $rs->fields['description'];
$product_attr = $rs->fields['attributes'];
return false;
}
$quantity = $rs->fields['quantity'];
$price_base = $rs->fields['amount'];
$item_total_amt = ($price_base * $quantity);
if (AGILE_DB_TYPE == 'mysqlt')
$db->CompleteTrans();
// Calculate any recurring discounts for this account
$item_discount_amt = $discountObj->calc_all_discounts(1, $invoice_item_id, $rs->fields['product_id'], $item_total_amt, $account_id, $sub_total+$item_total_amt);
$item_total_amt -= $item_discount_amt;
$sub_total += $item_total_amt;
$discount_amt += $item_discount_amt;
# Start next invoice
$io = false;
# calculate any taxes for this item
$item_tax_amt=0;
if($rs->fields['taxable']) {
$item_tax_arr = $taxObj->calculate($item_total_amt, $rs->fields['country_id'], $rs->fields['state']);
if(is_array($item_tax_arr)) foreach($item_tax_arr as $tx) $item_tax_amt += $tx['rate'];
$tax_amt += $item_tax_amt;
}
### Add line item to new invoice
$sql = "INSERT INTO ".AGILE_DB_PREFIX."invoice_item SET
id = ".$db->qstr( $invoice_item_id ) .",
site_id = ".$db->qstr( DEFAULT_SITE ).",
invoice_id = ".$db->qstr( $invoice_id ).",
account_id = ".$db->qstr( $account_id ).",
date_orig = ".$db->qstr( time() ).",
product_id = ".$db->qstr( $product_id ).",
sku = ".$db->qstr( $sku ).",
quantity = ".$db->qstr( $quantity ).",
item_type = ".$db->qstr( '0' ).",
product_attr = ".$db->qstr( $product_attr ).",
price_type = ".$db->qstr( '0' ).",
price_base = ".$db->qstr( $price_base ).",
price_setup = ".$db->qstr( 0 ) .",
tax_amt = ".$db->qstr($item_tax_amt) . ",
total_amt = ".$db->qstr($item_total_amt) . ",
discount_amt = ".$db->qstr($item_discount_amt);
$trans->Execute($sql);
# Insert tax records
$taxObj->invoice_item($invoice_id, $invoice_item_id, $account_id, @$item_tax_arr);
# Insert discount records
$discountObj->invoice_item($invoice_id, $invoice_item_id, $account_id);
### Update this charge status to billed
$sql = "UPDATE ".AGILE_DB_PREFIX."charge SET
status = ".$db->qstr( '1' ) ."
WHERE
site_id = ".$db->qstr( DEFAULT_SITE )." AND
id = ".$db->qstr( $rs->fields['id'] ) ;
$trans->Execute($sql);
$i++;
$sweep_count++;
# Load our new account object
$ao = new account($charge['account_id']);
}
if (! $io) {
# Generate an invoice id
$io = new invoice();
$io->setRecordAttr('id',sqlGenID($db,'invoice'));
$io->setRecordAttr('account_id',$charge['account_id']);
$io->setRecordAttr('billed_currency_id',$ao->getRecordAttr('currency_id'));
$io->setRecordAttr('actual_billed_currency_id',DEFAULT_CURRENCY);
$io->setRecordAttr('reseller_id',$ao->getRecordAttr('reseller_id'));
$io->setRecordAttr('checkout_plugin_id',$ao->getRecordAttr('checkout_plugin_id'));
$io->setRecordAttr('checkout_plugin_data',$ao->getRecordAttr('checkout_plugin_data'));
$io->setRecordAttr('grace_period',$ao->getRecordAttr('invoice_grace'));
$io->setRecordAttr('affiliate_id',$ao->getRecordAttr('affiliate_id'));
$io->setRecordAttr('campaign_id',null);
$io->setRecordAttr('notice_next_date',time());
$io->setRecordAttr('billing_status',0);
$io->setRecordAttr('print_status',0);
$io->setRecordAttr('process_status',0);
$io->setRecordAttr('status',1);
// $io->setRecordAttr('suspend_billing',0);
$io->setRecordAttr('billed_amt',0);
$io->setRecordAttr('actual_billed_amt',0);
$io->setRecordAttr('notice_count',0);
$io->setRecordAttr('type',1);
$io->setRecordAttr('notice_max',MAX_BILLING_NOTICE);
$io->setRecordAttr('account_billing_id',null);
#######################
### INVOICE ACTIONS ###
#######################
if($i_total == $i || $i == $rs->RecordCount())
{
if( $invoice_id )
{
### Get the most recent billing id for this client:
if(!isset($billing_id["$account_id"]))
{
$billing_arr = $account_billing->default_billing($account_id);
$billing_id["$account_id"] = $billing_arr['billing_id'];
$checkout_plugin_id["$account_id"] = $billing_arr['checkout_plugin_id'];
}
### Affiliate & Reseller info:
$affiliate_id = $rs->fields['affiliate_id'];
$reseller_id = $rs->fields['reseller_id'];
$actual_billed_currency_id = $rs->fields['currency_id'];
# calculate any taxes
@$total = $sub_total + $tax_amt;
if($total <= 0) {
$process_status = 1;
$billing_status = 1;
} else {
$process_status = 0;
$billing_status = 0;
}
### Generate the invoice insert SQL:
$sql = "INSERT INTO ".AGILE_DB_PREFIX."invoice SET
id = ".$db->qstr($invoice_id).",
site_id = ".$db->qstr(DEFAULT_SITE).",
date_orig = ".$db->qstr(time()).",
date_last = ".$db->qstr(time()).",
process_status = ".$db->qstr($process_status).",
billing_status = ".$db->qstr($billing_status).",
print_status = ".$db->qstr('0').",
account_id = ".$db->qstr($account_id).",
account_billing_id = ".$db->qstr($billing_id["$account_id"]).",
affiliate_id = ".$db->qstr($affiliate_id).",
reseller_id = ".$db->qstr($reseller_id).",
checkout_plugin_id = ".$db->qstr($checkout_plugin_id["$account_id"]).",
tax_amt = ".$db->qstr($tax_amt).",
discount_amt = ".$db->qstr($discount_amt).",
actual_billed_currency_id = ".$db->qstr($actual_billed_currency_id).",
actual_billed_amt = ".$db->qstr('0').",
billed_currency_id = ".$db->qstr(DEFAULT_CURRENCY).",
billed_amt = ".$db->qstr('0').",
total_amt = ".$db->qstr($total).",
notice_count = ".$db->qstr('0').",
notice_max = ".$db->qstr(MAX_BILLING_NOTICE).",
notice_next_date = ".$db->qstr(time()).",
grace_period = ".$db->qstr(GRACE_PERIOD).",
due_date = ".$db->qstr(time());
$trans->Execute($sql);
### Close this transaction
$trans->CompleteTrans();
$i_total = false;
$i = false;
$account_id = false;
$invoice_id = false;
$discount = false;
$cookie = false;
$invoice_count++;
}
# @todo this should be a system default
$io->setRecordAttr('due_date',time()+7*86400);
}
$rs->MoveNext();
$io->aaddItem(array(
'charge_id'=>$charge['id'],
'date_start'=>$charge['date_orig'],
'date_stop'=>$charge['date_orig'],
'domain_name'=>null,
'domain_tld'=>null,
'domain_type'=>null,
'domain_term'=>null,
'item_type'=>5,
'price_setup'=>0,
'price_base'=>$charge['amount'],
'price_type'=>3,
'product_id'=>$charge['product_id'],
'product_name'=>$charge['description'],
'product_attr'=>$charge['attributes'],
'product_attr_cart'=>null,
'quantity'=>$charge['quantity'],
'recurring_schedule'=>null,
'service_id'=>$charge['service_id'],
'sku'=>null
));
# @todo Move this update, need to incase the charge add fails.
$db->Execute(sqlUpdate($db,'charge',array('status'=>1),array('id'=>$charge['id'])));
}
global $C_debug;
$C_debug->alert("Swept $sweep_count Charge(s) into $invoice_count Invoice(s).");
return true;
# Save invoice
if ($io) {
$rs = $io->sql_SaveRecord(true);
if (! $rs) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
$db->FailTrans();
return false;
}
if (AGILE_DB_TYPE == 'mysqlt')
$db->CompleteTrans();
}
}
### Get total charges for an account
function count_account_charges($account, $start_pos, &$rs) {
$rs->Move($start_pos);
$i = 0;
while(!$rs->EOF) {
if($rs->fields['account_id'] != $account) {
$rs->Move($start_pos);
return $i;
}
$i++;
$rs->MoveNext();
}
$rs->Move($start_pos);
return $i;
}
##############################
## API ##
##############################
function api($VAR) {
$db = &DB();
@@ -368,8 +218,7 @@ class charge extends OSB_module {
} else {
# check the account id
if(!empty($VAR['account_id']))
{
if(!empty($VAR['account_id'])) {
$sql = "SELECT * FROM ".AGILE_DB_PREFIX."account WHERE
id = " . $db->qstr($VAR['account_id']) . " OR
username = " . $db->qstr($VAR['account_id']) . " AND
@@ -379,19 +228,14 @@ class charge extends OSB_module {
global $C_debug;
$C_debug->error('charge.inc.php','charge :: api()', $db->ErrorMsg(). "\r\n\r\n". $sql);
}
if($rs->RecordCount() == 1)
{
if($rs->RecordCount() == 1) {
$account_id = $rs->fields['id'];
}
else
{
} else {
return $this->api_return(0,'','The \'account_id\' value provided does not exist');
}
}
# check the service id
elseif(!empty($VAR['service_id']))
{
} elseif(!empty($VAR['service_id'])) {
$sql = "SELECT id,account_id FROM ".AGILE_DB_PREFIX."service WHERE
site_id = " . $db->qstr(DEFAULT_SITE) . " AND
id = " . $db->qstr($VAR['service_id']);
@@ -400,8 +244,7 @@ class charge extends OSB_module {
global $C_debug;
$C_debug->error('charge.inc.php','charge :: api()', $db->ErrorMsg(). "\r\n\r\n". $sql);
}
if($rs->RecordCount() == 1)
{
if($rs->RecordCount() == 1) {
$service_id = $VAR['service_id'];
$account_id = $rs->fields['account_id'];
} else {
@@ -468,15 +311,12 @@ class charge extends OSB_module {
global $C_debug;
$C_debug->error('charge.inc.php','charge :: api()', $db->ErrorMsg(). "\r\n\r\n". $sql);
return $this->api_return(0,'','The SQL insert failed!');
}
else
{
} else {
return $this->api_return(1,$id,'');
}
return true;
}
function api_return($status=0,$id='',$error='') {
if (! $this->xmlrpc) {
echo "status=={$status}++charge_id={$id}++error=={$error}";
@@ -489,7 +329,7 @@ class charge extends OSB_module {
/**
* Add a record
*/
function add($VAR) {
public function add($VAR) {
if (! empty($VAR['attributes'])) {
$attr = '';
@@ -500,7 +340,7 @@ class charge extends OSB_module {
$VAR['charge_attributes'] = $attr;
}
return $this->add($VAR);
return parent::add($VAR);
}
/**

View File

@@ -88,22 +88,23 @@
<type>X2</type>
</attributes>
<description>
<display>Description</display>
<type>C(32)</type>
</description>
</field>
<!-- Methods for this class, and the fields they have access to, if applicable -->
<method>
<add>status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</add>
<search_export>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</search_export>
<update>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</update>
<export_excel>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_excel>
<delete>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</delete>
<export_xml>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_xml>
<view>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</view>
<export_tab>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_tab>
<search>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</search>
<export_csv>id,site_id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_csv>
<add>status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes,description</add>
<delete>id</delete>
<update>id,status,sweep_type,amount,quantity,taxable,attributes,description</update>
<search_export>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</search_export>
<search>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</search>
<view>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes,description</view>
<export_excel>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_excel>
<export_xml>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_xml>
<export_tab>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_tab>
<export_csv>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</export_csv>
<import>id,date_orig,status,sweep_type,account_id,product_id,service_id,amount,quantity,taxable,attributes</import>
</method>

View File

@@ -17,7 +17,7 @@
<!-- SUB Modules to install with this one -->
<sub_modules></sub_modules>
<!-- MODULE Type (core|base), core modules cannot be deleted, unrecognised types are ignored. -->
<type>base</type>
<type></type>
</module_properties>
<!-- Tree Menu & Module Methods to load, they will be assigned the group permissions on install time, as selected by the user. -->

View File

@@ -0,0 +1,24 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides charge item capabilities.
*
* @package OSB
* @subpackage Charge
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Charge extends ORMOSB {
protected $_formats = array(
'amount'=>array('Currency::display'=>array()),
);
// Show our description on the invoice.
public function invoice_display() {
// @todo The rounding should be a global config
return sprintf('%s: %2s x %s (%s)',Config::date($this->date_orig),$this->quantity,$this->description,$this->display('amount'));
}
}
?>

View File

@@ -2,8 +2,7 @@
$auth_methods = Array
(
Array ('module' => 'checkout', 'method' => 'preview'),
Array ('module' => 'checkout', 'method' => 'adddiscount'),
Array ('module' => 'checkout', 'method' => 'checkoutoption'),
Array ('module' => 'checkout', 'method' => 'checkoutnow')
);
?>
?>

View File

@@ -71,6 +71,10 @@ class base_checkout_plugin
}
}
public function getName() {
return $this->name;
}
/**
* Get country name,
*

View File

@@ -29,11 +29,6 @@
* @subpackage Module:Checkout
*/
class checkout extends OSB_module {
var $account_id;
var $session_id;
var $affiliate_id;
var $campaign_id;
var $admin_view=false;
var $admin_checkout=false;
var $admin_checkout_option=false;
@@ -50,16 +45,6 @@ class checkout extends OSB_module {
return true;
}
/**
* Add Discount Code to Sess
*/
function adddiscount($VAR)
{
include_once(PATH_MODULES.'discount/discount.inc.php');
$dsc=new discount();
$dsc->add_cart_discount($VAR);
}
/**
* Admin Create the Invoice Record
*/
@@ -130,20 +115,30 @@ class checkout extends OSB_module {
* @param int $account_id
* @param float $total
* @param array $product_arr Array of product_ids being purchased
* @param int $country_id
* @param bool $any_new
* @param bool $any_trial
* @param bool $any_recurring
* @return array
* @uses account
*/
function get_checkout_options($account_id,$total=0,$product_arr=false,$country_id=1,$any_new=false,$any_trial=false,$any_recurring=false) {
$options=false;
if($any_trial) $options .= " AND allow_trial=1 ";
if($any_recurring) $options .= " AND allow_recurring=1 ";
if($any_new) $options .= " AND allow_new=1 ";
if(!$options) return false;
$db=&DB();
$chopt = $db->Execute(sqlSelect($db,"checkout","*","active=1 $options"));
function get_checkout_options($account_id,$total=0,$product_arr=false,$any_new=false,$any_trial=false,$any_recurring=false) {
$options = '';
if ($any_trial)
$options .= ' AND allow_trial=1';
if ($any_recurring)
$options .= ' AND allow_recurring=1';
if ($any_new)
$options .= ' AND allow_new=1';
if (! $options)
return false;
include_once(PATH_MODULES.'account/account.inc.php');
$ao = new account($account_id);
$country_id = $ao->getRecordAttr('country_id');
$db = &DB();
$chopt = $db->Execute(sqlSelect($db,'checkout','*',sprintf('active=1 %s',$options)));
if($chopt && $chopt->RecordCount()) {
while( !$chopt->EOF ) {
$show = true;
@@ -240,57 +235,72 @@ class checkout extends OSB_module {
/**
* Preview / Confirm prior to checkout
*
* @uses account
* @uses cart
*/
public function preview($VAR) {
public function preview($VAR,$object,$returnInvoice=false) {
if (! SESS_LOGGED)
return false;
$db = &DB();
if (empty($this->session_id))
$this->session_id = SESS;
if (empty($this->account_id))
$this->account_id = SESS_ACCOUNT;
# Load the cart
include_once(PATH_MODULES.'/cart/cart.inc.php');
$cartObj = new cart;
$co = new cart();
$cartObj->account_id = $this->account_id;
$cartObj->session_id = $this->session_id;
$result = $cartObj->get_contents();
if (! $result || $result->RecordCount() == 0)
if (! $results = $co->sGetContents())
return false;
# Load invoice object
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$invoice = new invoice;
$invoice = new invoice();
$invoice->initNew(0);
$invoice->account_id = $this->account_id;
$invoice->setRecordAttr('account_id',$this->account_id);
# Get the account details:
$account = $db->Execute(sqlSelect($db,'account','*',array('id'=>$this->account_id)));
$invoice->country_id = $account->fields['country_id'];
$invoice->state = $account->fields['state'];
# Put the cart items into an invoice
foreach ($results as $result) {
$invoice->aaddItem(array(
'charge_id'=>null,
'domain_name'=>$result['domain_name'],
'domain_term'=>$result['domain_term'],
'domain_type'=>$result['domain_type'],
'domain_tld'=>$result['domain_tld'],
'host_type'=>$result['host_type'],
'item_type'=>0,
'service_id'=>null,
'cart_id'=>$result['id'],
'product_id'=>$result['product_id'],
'quantity'=>isset($result['quantity']) ? $result['quantity'] : 1,
'recurr_schedule'=>$result['recurr_schedule'],
'product_attr'=>$result['product_attr'],
'product_attr_cart'=>$result['product_attr'],
'type'=>in_array($result['host_type'],array('register')) ? 'domain' : null
));
}
# Put cart contents into invoice format
$smart = $cartObj->put_contents_invoice($result,$invoice);
# Get available checkout options
$product_arr = array();
foreach ($invoice->invoice_item as $item)
if (! empty($item['product_id']))
array_push($product_arr,$item['product_id']);
$checkout_options = $this->get_checkout_options($this->account_id,$invoice->total_amt,$product_arr,$invoice->country_id,$invoice->any_new,$invoice->any_trial,$invoice->any_recurring);
$checkout_c = count($checkout_options);
# If we are being called by checkout, then we use the preview code to build our invoice.
if ($returnInvoice)
return $invoice;
global $smarty;
$smarty->assign('results',count($invoice->invoice_item));
$smarty->assign('cart',$smart);
$smarty->assign('sub_total',($invoice->total_amt+$invoice->discount_amt)-$invoice->tax_amt);
$smarty->assign('total',$invoice->total_amt);
$smarty->assign('discount',$invoice->group_discounts());
$smarty->assign('tax',$invoice->group_taxes());
$smarty->assign('results',$invoice->sCountItems());
$smarty->assign('cart',$invoice->getItems());
$smarty->assign('sub_total',$invoice->sSubTotal());
$smarty->assign('discounttotal',$invoice->sTotalDiscount(true));
$smarty->assign('discount',$invoice->getDiscountDetails(true));
$smarty->assign('taxtotal',$invoice->sTotalTax(true));
$smarty->assign('tax',$invoice->getTaxDetails());
$smarty->assign('total',$invoice->sTotal(true));
# Get our checkout options
$checkout_options = $this->get_checkout_options($this->account_id,$invoice->sTotal(),$invoice->getProductItems(),
(is_null($invoice->getRecordAttr('id'))),
in_array(2,$invoice->getProductItemTypes()),(! is_null($invoice->getRecordAttr('id'))));
$checkout_c = count($checkout_options);
$smarty->assign('checkout',$checkout_options);
$smarty->assign('checkout_c',$checkout_c);
$checkout_c--;
@@ -299,10 +309,12 @@ class checkout extends OSB_module {
/**
* Create the Invoice Record and send user to checkout
*
* @uses account
* @uses currency
*/
public function checkoutnow($VAR) {
global $C_translate,$C_list,$smarty;
$db = &DB();
# Validate user is logged in:
if (! SESS_LOGGED) {
@@ -312,6 +324,8 @@ class checkout extends OSB_module {
return false;
}
$db = &DB();
# Check for admin
if (! $this->admin_checkout && ! empty($VAR['account_id'])) {
global $C_auth;
@@ -325,34 +339,28 @@ class checkout extends OSB_module {
}
}
if (empty($this->session_id))
$this->session_id = SESS;
if (empty($this->account_id))
$this->account_id = SESS_ACCOUNT;
$invoice = $this->preview($VAR,null,true);
include_once(PATH_MODULES.'/cart/cart.inc.php');
$cartObj = new cart;
# Set some defaults
$invoice->setRecordAttr('actual_billed_amt',0);
$invoice->setRecordAttr('billed_amt',0);
$invoice->setRecordAttr('billing_status',0);
$invoice->setRecordAttr('due_date',time());
$invoice->setRecordAttr('grace_period',0);
$invoice->setRecordAttr('notice_count',0);
$invoice->setRecordAttr('notice_max',0);
$invoice->setRecordAttr('notice_next_date',null);
$invoice->setRecordAttr('print_status',0);
$invoice->setRecordAttr('process_status',0);
$invoice->setRecordAttr('status',1);
$invoice->setRecordAttr('suspend_billing',0);
$invoice->setRecordAttr('reseller_id',0);
$invoice->setRecordAttr('type',0);
$cartObj->account_id = $this->account_id;
$cartObj->session_id = $this->session_id;
$result = $cartObj->get_contents();
if (! $result || $result->RecordCount() == 0)
return false;
# Load invoice object
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$invoice = new invoice;
$invoice->initNew(0);
$invoice->account_id = $this->account_id;
# Get the account details:
$account = $db->Execute(sqlSelect($db,'account','*',array('id'=>$this->account_id)));
$invoice->country_id = $account->fields['country_id'];
$invoice->state = $account->fields['state'];
# Put cart contents into invoice format
$cartObj->put_contents_invoice($result,$invoice);
# (Re)Calculate our discounts and taxes
$invoice->setRecordAttr('discount_amt',$invoice->sTotalDiscount(true));
$invoice->setRecordAttr('tax_amt',$invoice->sTotalTax(true));
$invoice->setRecordAttr('total_amt',$invoice->sTotal(true));
// Validate and init a checkout plugin
$checkout = false;
@@ -362,24 +370,22 @@ class checkout extends OSB_module {
$PLG = new checkout_admin;
$checkout = true;
$invoice->checkout_plugin_id = false;
$invoice->setRecordAttr('checkout_plugin_id',false);
} else {
// Get available checkout options and check against the one provided
$invoice->checkout_plugin_id = $VAR['option'];
$product_arr = array();
foreach ($invoice->invoice_item as $item)
if (! empty($item['product_id']))
array_push($product_arr,$item['product_id']);
# Get available checkout options and check against the one provided
$invoice->setRecordAttr('checkout_plugin_id',$VAR['option']);
$checkout_options = $this->get_checkout_options($this->account_id,$invoice->total_amt,$product_arr,$invoice->country_id,$invoice->any_new,$invoice->any_trial,$invoice->any_recurring);
$checkout_options = $this->get_checkout_options($this->account_id,$invoice->sTotal(),$invoice->getProductItems(),
(is_null($invoice->getRecordAttr('id'))),
in_array(2,$invoice->getProductItemTypes()),in_array(1,$invoice->getProductItemTypes()));
if ($checkout_options) {
foreach ($checkout_options as $a) {
if ($a['fields']['id'] == $invoice->checkout_plugin_id) {
if ($a['fields']['id'] == $invoice->getRecordAttr('checkout_plugin_id')) {
# Load the selected checkout plugin and run pre-validation
$checkout_plugin = $a['fields']['checkout_plugin'];
include_once(sprintf('%scheckout/%s.php',PATH_PLUGINS,$checkout_plugin));
eval ('$PLG = new plg_chout_'.$checkout_plugin.'("'.$invoice->checkout_plugin_id.'");');
eval (sprintf('$PLG = new plg_chout_%s("%s");',$checkout_plugin,$invoice->getRecordAttr('checkout_plugin_id')));
$plugin_validate = $PLG->validate($VAR,$this);
if ($plugin_validate != true) {
@@ -394,17 +400,19 @@ class checkout extends OSB_module {
}
}
# If we werent able to checkout, then return here
if (! $checkout) {
echo '<script language=Javascript> alert("Unable to checkout with the selected method, please select another."); </script> ';
echo '<script type="text/javascript">alert("Unable to checkout with the selected method, please select another.");</script>';
return false;
}
// validate credit card on file details
global $VAR;
if (! empty($VAR['account_billing_id']) && @$VAR['new_card']==2) {
$invoice->account_billing_id=$VAR['account_billing_id'];
$invoice->setRecordAttr('account_billing_id',$VAR['account_billing_id']);
/* validate credit card on file details */
if(!$PLG->setBillingFromDB($this->account_id, $invoice->account_billing_id, $invoice->checkout_plugin_id)) {
if(!$PLG->setBillingFromDB($this->account_id,$VAR['account_billing_id'],$invoice->checkout_plugin_id)) {
global $C_debug;
$C_debug->alert("Sorry, we cannot use that billing record for this purchase.");
return false;
@@ -442,86 +450,102 @@ class checkout extends OSB_module {
}
}
# Load account object
include_once(PATH_MODULES.'account/account.inc.php');
$ao = new account($this->account_id);
# Affiliate
if(empty($this->affiliate_id)) {
if(!empty($account->fields['affiliate_id']))
$invoice->affiliate_id = $account->fields['affiliate_id'];
else
$invoice->affiliate_id = SESS_AFFILIATE;
}
if (is_null($invoice->getRecordAttr('affiliate_id')))
$invoice->setRecordAttr('affiliate_id',
(! is_null($ao->getRecordAttr('affiliate_id'))) ? $ao->getRecordAttr('affiliate_id') : SESS_AFFILIATE);
# Campaign
if(empty($this->campaign_id)) {
if(!empty($account->fields['campaign_id']))
$invoice->campaign_id = $account->fields['campaign_id'];
else
$invoice->campaign_id = SESS_CAMPAIGN;
}
if (is_null($invoice->getRecordAttr('campaign_id')))
$invoice->setRecordAttr('campaign_id',
(! is_null($ao->getRecordAttr('campaign_id'))) ? $ao->getRecordAttr('campaign_id') : SESS_CAMPAIGN);
$invoice->record_id = sqlGenID($db,"invoice");
$invoice->actual_billed_currency_id = SESS_CURRENCY;
$invoice->billed_currency_id = DEFAULT_CURRENCY;
$invoice->setRecordAttr('actual_billed_currency_id',SESS_CURRENCY);
$invoice->setRecordAttr('billed_currency_id',DEFAULT_CURRENCY);
$invoice->checkout_type = $PLG->type;
$invoice->setRecordAttr('id',sqlGenID($db,'invoice'));
// initial invoice status
if( $invoice->total_amt == 0 || $PLG->type == 'gateway') {
$invoice->billing_status = 1;
$invoice->actual_billed_amt = $C_list->format_currency_decimal($invoice->total_amt, SESS_CURRENCY);
$invoice->billed_amt = $invoice->total_amt;
# Initial invoice status
if ($invoice->sTotal() == 0 || $PLG->type == 'gateway') {
$invoice->setRecordAttr('billing_status',1);
$invoice->actual_billed_amt = $C_list->format_currency_decimal($invoice->sTotal(),SESS_CURRENCY);
$invoice->billed_amt = $invoice->sTotal();
}
// Currency conversion:
# Currency conversion
if (SESS_CURRENCY != DEFAULT_CURRENCY) {
$bill_amt = $C_list->format_currency_decimal ($invoice->total_amt, SESS_CURRENCY);
$recur_amt = $C_list->format_currency_decimal ($invoice->recur_amt, SESS_CURRENCY);
$bill_amt = $C_list->format_currency_decimal($invoice->sTotal(),SESS_CURRENCY);
$recur_amt = is_null($invoice->sRecurAmt()) ? null : $C_list->format_currency_decimal($invoice->sRecurAmt(),SESS_CURRENCY);
} else {
$bill_amt = round($invoice->total_amt,2);
$recur_amt = round($invoice->recur_amt,2);
$bill_amt = round($invoice->sTotal(),2);
$recur_amt = is_null($invoice->sRecurAmt()) ? null : round($invoice->sRecurAmt(),2);
}
// Get currency ISO (three_digit) for checkout plugin
$currrs = $db->Execute(sqlSelect($db,"currency","three_digit","id=".SESS_CURRENCY));
if($currrs && $currrs->RecordCount()) $currency_iso = $currrs->fields['three_digit'];
# Get currency ISO (three_digit) for checkout plugin
include_once(PATH_MODULES.'currency/currency.inc.php');
$cuo = new currency();
$currencies = $cuo->sql_GetRecords(array('where'=>array('id'=>SESS_CURRENCY)));
if ($currencies)
$currency_iso = $currencies[0]['three_digit'];
else
$currency_iso = $C_list->currency_iso(SESS_CURRENCY);
# Run the plugin bill_checkout() method:
$invoice->setRecordAttr('checkout_plugin_data',
$PLG->bill_checkout($bill_amt,$invoice->getRecordAttr('id'),$currency_iso,$ao->getRecord(),$recur_amt,$invoice->recur_arr));
if ($invoice->getRecordAttr('checkout_plugin_data') === false || $invoice->getRecordAttr('checkout_plugin_data') == '' ) {
if (! empty($PLG->redirect))
echo $PLG->redirect;
// Run the plugin bill_checkout() method:
$currency_iso = $C_list->currency_iso(SESS_CURRENCY);
$invoice->checkout_plugin_data = $PLG->bill_checkout($bill_amt, $invoice->record_id, $currency_iso, $account->fields, $recur_amt, $invoice->recur_arr);
if($invoice->checkout_plugin_data === false || $invoice->checkout_plugin_data == '' ) {
if(!empty($PLG->redirect)) echo $PLG->redirect;
return false;
} elseif ($PLG->type == "gateway" || empty($PLG->redirect)) {
$VAR['id'] = $invoice->record_id;
if(!$this->admin_checkout) $VAR['_page'] = "invoice:thankyou";
$invoice->checkout_plugin_data=false;
} elseif(!$this->admin_checkout) {
echo "<html><head></head><body><center>
Please wait while we redirect you to the secure payment site....
{$PLG->redirect}</center></body></html>";
} elseif ($PLG->type == 'gateway' || empty($PLG->redirect)) {
$VAR['id'] = $invoice->getRecordAttr('id');
if (! $this->admin_checkout)
$VAR['_page'] = 'invoice:thankyou';
$invoice->setRecordAttr('checkout_plugin_data',false);
} elseif (! $this->admin_checkout) {
echo "<html><head></head><body><center>Please wait while we redirect you to the secure payment site.... {$PLG->redirect}</center></body></html>";
}
// Call the Plugin method for storing the checkout data:
$invoice->account_billing_id = $PLG->store_billing($VAR, $invoice->account_id);
# Call the Plugin method for storing the checkout data:
$invoice->setRecordAttr('account_billing_id',$PLG->store_billing($VAR,$invoice->account_id));
// clear user discounts
$fields=Array('discounts'=>"");
$db->Execute(sqlUpdate($db,"session",$fields,"id = ::".SESS."::"));
# Clear user discounts
$db->Execute(sqlUpdate($db,'session',array('discounts'=>null),array('id'=>SESS)));
// admin options
$email=true;
if($this->admin_checkout) {
if(empty($VAR['send_email']) || $VAR['send_email']=='false') $email=false; else $email=true;
if(!empty($VAR['due_date'])) $invoice->due_date=$this->getInputDate($VAR['due_date']);
if(!empty($VAR['grace_period'])) $invoice->grace_period=$VAR['grace_period'];
if(!empty($VAR['notice_max'])) $invoice->notice_max=$VAR['notice_max'];
# admin options
$email = true;
if ($this->admin_checkout) {
if (empty($VAR['send_email']) || $VAR['send_email']=='false')
$email=false;
else
$email=true;
if (! empty($VAR['due_date']))
$invoice->due_date=$this->getInputDate($VAR['due_date']);
if (! empty($VAR['grace_period']))
$invoice->grace_period=$VAR['grace_period'];
if (! empty($VAR['notice_max']))
$invoice->notice_max=$VAR['notice_max'];
}
if ($invoice->commitNew($taxObj,$discountObj,$email)) {
if ($invoice->sql_SaveRecord(true)) {
# Delete all cart items
$db->Execute(sqlDelete($db,'cart',sprintf('(session_id=::%s:: OR account_id=%s)',SESS,$invoice->account_id)));
$db->Execute(sqlDelete($db,'cart',sprintf('(session_id=::%s:: OR account_id=%s)',SESS,$invoice->getRecordAttr('account_id'))));
# Admin redirect
if ($this->admin_checkout)
printf('<script language="javascript">parent.location.href=\'%sadmin.php?_page=invoice:view&id=%s\';</script>',URL,$invoice->record_id);
printf('<script language="javascript">parent.location.href=\'%sadmin.php?_page=invoice:view&id=%s\';</script>',URL,$invoice->getRecordAttr('id'));
}
return false;
@@ -564,7 +588,7 @@ class checkout extends OSB_module {
if($amt > 0)
{
// get total due for this invoice:
$rs=sqlSelect($db, "invoice","SUM(total_amt-billed_amt) as total","id=$id");
$rs=sqlSelect($db, "invoice","SUM(total_amt-billed_amt-IFNULL(credit_amt,0)) as total","id=$id");
if($rs && $rs->RecordCount()) {
$thisamt = $rs->fields["total"];
@@ -582,235 +606,248 @@ class checkout extends OSB_module {
}
/**
* Postback for Redirect Pay
* Postback Payment Processing
* This function will handle the postback processing from a payment processor
*
* @param array $arr Incoming payment information
* @uses invoice
* @uses invoice_item
*/
function postback($arr)
{
global $C_debug;
public function postback($arr) {
global $C_debug,$C_list;
if(empty($arr['invoice_id'])) return false;
if(empty($arr['transaction_id'])) return false;
if(empty($arr['amount'])) return false;
# Minimum incoming values to continue
if (empty($arr['invoice_id']))
return false;
if (empty($arr['transaction_id']))
return false;
if (empty($arr['amount']))
return false;
if(eregi("MULTI-", $arr['invoice_id'])) {
$this->postback_multiple($arr);
return;
}
# Does this postback pay multiple invoices?
if (preg_match('/^MULTI-/',$arr['invoice_id']))
return $this->postback_multiple($arr);
# Get the latest invoice info:
$db = &DB();
$sql1 ="";
if(!empty($arr['subscription_id']))
$sql1 = "checkout_plugin_data = ".$db->qstr( trim($arr['subscription_id']) )." OR ";
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$io = new invoice();
$q = "SELECT * FROM ".AGILE_DB_PREFIX."invoice WHERE
(
$sql1
parent_id = ".$db->qstr(@$arr['invoice_id'])."
OR
id = ".$db->qstr(@$arr['invoice_id'])."
)
AND
billing_status != 1
AND
site_id = ".$db->qstr(DEFAULT_SITE)."
ORDER BY date_orig
LIMIT 0,1";
$invoice = $db->Execute($q);
# Get the latest invoice information
$invoices = $io->sql_GetRecords(array(
'where'=>sprintf('(parent_id=%s OR id=%s%s)',$arr['invoice_id'],$arr['invoice_id'],
(! empty($arr['subscription_id']) && trim($arr['subscription_id'])) ? sprintf(' OR checkout_plugin_data=%s',trim($arr['subscription_id'])) : ''),
'limit'=>'0,1'));
if ($invoice === false || $invoice->RecordCount()==0)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
if (! count($invoices)) {
$C_debug->error(__FILE__,__METHOD__,sprintf('No invoice records, unable to process payment for: %s',$arr['invoice_id']));
if($invoice->RecordCount() == 0)
return false;
$invoice_id = $invoice->fields['id'];
# Validate the currency
$billed_currency_id = $invoice->fields['billed_currency_id'];
$total_amt = $invoice->fields['total_amt'];
$billed_amt = $invoice->fields['billed_amt'];
$actual_billed_amt = $invoice->fields['actual_billed_amt'];
$currency_iso = @$arr['currency'];
if(empty($currency_iso) || !$currency_iso)
{
# same as billed_currency_id
$this->billed_amt = $arr['amount'] + $billed_amt;
$this->actual_billed_amt = $arr['amount'] + $billed_amt;
$this->actual_billed_currency_id = $billed_currency_id;
}
else
{
# Get the actual billed currency id currency info:
$q = "SELECT * FROM ".AGILE_DB_PREFIX."currency WHERE
three_digit = ".$db->qstr($currency_iso)." AND
site_id = ".$db->qstr(DEFAULT_SITE);
$result = $db->Execute($q);
if ($result === false)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
$actual_billed_currency_id = $result->fields['id'];
if(is_string($result->fields["convert_array"]))
$convert = unserialize($result->fields["convert_array"]);
else
$convert = false;
$this->format_currency[$actual_billed_currency_id] = Array (
'symbol' => $result->fields["symbol"],
'convert' => $convert,
'iso' => $result->fields["three_digit"]);
if($result->RecordCount() == 0 || $actual_billed_currency_id == $billed_currency_id)
{
# same as billed_currency_id
$this->billed_amt = $arr['amount'] + $billed_amt;
$this->actual_billed_amt = $arr['amount'] + $billed_amt;
$this->actual_billed_currency_id = $actual_billed_currency_id;
}
else
{
# Get the billed currency id currency info:
$q = "SELECT * FROM ".AGILE_DB_PREFIX."currency WHERE
id = ".$db->qstr($billed_currency_id)." AND
site_id = ".$db->qstr(DEFAULT_SITE);
$result = $db->Execute($q);
if ($result === false)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
$this->format_currency[$billed_currency_id] = Array (
'symbol' => $result->fields["symbol"],
'convert' => unserialize($result->fields["convert_array"]),
'iso' => $result->fields["three_digit"]);
# Convert the invoice amount to the actual billed currency amount
$due_amount = $invoice->fields['total_amt'] - $invoice->fields['billed_amt'];
$conversion = $this->format_currency[$billed_currency_id]["convert"][$actual_billed_currency_id]["rate"];
$this->billed_amt = $billed_amt + ($arr['amount'] /= $conversion);
$this->actual_billed_amt = $actual_billed_amt + $arr['amount'];
$this->actual_billed_currency_id = $actual_billed_currency_id;
}
return false;
}
# Get our invoice object, that this payment is for.
$invoice = array_pop($invoices);
# If we are not passed a currency, we can only assume it is the same as that used to bill the invoice.
if (! isset($arr['currency']) || ! trim($arr['currency'])) {
$this->billed_amt = $arr['amount']+$invoice['billed_amt'];
$this->actual_billed_amt = $arr['amount']+$invoice['billed_amt'];
$this->actual_billed_currency_id = $invoice['billed_currency_id'];
# Check for any subscription_id
if(!empty($arr['subscription_id'])) {
$this->subscription_id = trim($arr['subscription_id']);
} else {
$this->subscription_id = trim($invoice->fields['checkout_plugin_data']);
}
# Get the actual billed currency id currency info
$rs = $db->Execute(sqlSelect('currency','*',array('where'=>array('three_digit'=>$arr['currency']))));
# Check for the checkout_id
if(!empty($arr['checkout_id'])) {
$this->checkout_id = $arr['checkout_id'];
} else {
$this->checkout_id = $invoice->fields['checkout_plugin_id'];
}
if (! $rs)
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
# Check for the billing status:
if($this->billed_amt >= $invoice->fields['total_amt']) {
$this->billing_status = '1';
} else {
$this->billing_status = '0';
}
# No currency information, assume the currency of the invoice
elseif (! $rs->RecordCount()) {
$C_debug->error(__FILE__,__METHOD__,sprintf('No currency: %s?',$arr['currency']));
# Check if this transaction_id has already been processed:
$q = "SELECT id FROM ".AGILE_DB_PREFIX."invoice_memo WHERE
invoice_id = ".$db->qstr($invoice_id)." AND
type = ".$db->qstr('postback')." AND
memo = ".$db->qstr($arr['transaction_id'])." AND
site_id = ".$db->qstr(DEFAULT_SITE);
$memo = $db->Execute($q);
if ($memo === false)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
if ($memo->RecordCount() > 0) {
# duplicate post:
$C_debug->error('Duplicate Postback','checkout.inc.php :: postback()', "Duplicate postback for invoice {$arr['invoice_id']} & transaction id {$arr['transaction_id']}");
} else {
# Create the invoice memo:
$memo_id = $db->GenID(AGILE_DB_PREFIX . 'invoice_memo_id');
$q = "INSERT INTO
".AGILE_DB_PREFIX."invoice_memo
SET
id = ".$db->qstr($memo_id).",
site_id = ".$db->qstr(DEFAULT_SITE).",
date_orig = ".$db->qstr(time()).",
invoice_id = ".$db->qstr($invoice_id).",
account_id = ".$db->qstr(0).",
type = ".$db->qstr('postback').",
memo = ".$db->qstr($arr['transaction_id']) ;
$memosql = $db->Execute($q);
if ($memosql === false)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
# Update the invoice billing info:
$q = "UPDATE
".AGILE_DB_PREFIX."invoice
SET
date_last = ".$db->qstr(time()).",
billing_status = ".$db->qstr($this->billing_status).",
checkout_plugin_id = ".$db->qstr($this->checkout_id).",
checkout_plugin_data = ".$db->qstr($this->subscription_id).",
billed_amt = ".$db->qstr($this->billed_amt).",
actual_billed_amt = ".$db->qstr($this->actual_billed_amt).",
actual_billed_currency_id = ".$db->qstr($this->actual_billed_currency_id)."
WHERE
id = ".$db->qstr($invoice_id)." AND
site_id = ".$db->qstr(DEFAULT_SITE);
$memosql = $db->Execute($q);
if ($memosql === false)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
# Update the invoice approval status
$VAR['id'] = $invoice_id;
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$inv = new invoice;
if(!$arr['status'])
{
# void
$inv->voidInvoice($VAR);
# create a record of the viod in an invoice memo:
$memo_id = $db->GenID(AGILE_DB_PREFIX . 'invoice_memo_id');
$q = "INSERT INTO
".AGILE_DB_PREFIX."invoice_memo
SET
id = ".$db->qstr($memo_id).",
site_id = ".$db->qstr(DEFAULT_SITE).",
date_orig = ".$db->qstr(time()).",
invoice_id = ".$db->qstr($invoice_id).",
account_id = ".$db->qstr(0).",
type = ".$db->qstr('void').",
memo = ".$db->qstr("Voided due to postback: ".$arr['transaction_id']) ;
$rsql = $db->Execute($q);
if ($rsql === false)
$C_debug->error('checkout.inc.php','postback', $q . " | " . @$db->ErrorMsg());
$this->billed_amt = $arr['amount']+$invoice['billed_amt'];
$this->actual_billed_amt = $arr['amount']+$invoice['billed_amt'];
$this->actual_billed_currency_id = $invoice['billed_currency_id'];
} else {
$this->actual_billed_currency_id = $rs->fields['id'];
# approve
$inv->autoApproveInvoice($invoice_id);
if (is_string($rs->fields['convert_array']))
$convert = unserialize($rs->fields['convert_array']);
else
$convert = false;
$this->format_currency[$this->actual_billed_currency_id] = array(
'symbol'=>$rs->fields['symbol'],
'convert'=>$convert,
'iso'=>$rs->fields['three_digit']);
# Get the billed currency id currency info:
$rs = $db->Execute(sqlSelect('currency','*',array('where'=>array('id'=>$invoice['billed_currency_id']))));
if (! $rs)
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
$this->format_currency[$invoice['billed_currency_id']] = array(
'symbol'=>$rs->fields['symbol'],
'convert'=>unserialize($rs->fields['convert_array']),
'iso'=>$rs->fields['three_digit']);
# Convert the invoice amount to the actual billed currency amount
$conversion = $this->format_currency[$invoice['billed_currency_id']]['convert'][$this->actual_billed_currency_id]['rate'];
$this->billed_amt = $invoice['billed_amt']+($arr['amount']/$conversion);
$this->actual_billed_amt = $invoice['actual_billed_amt']+$arr['amount'];
}
}
# Check for any subscription_id
if (! empty($arr['subscription_id']))
$this->subscription_id = trim($arr['subscription_id']);
else
$this->subscription_id = trim($invoice['checkout_plugin_data']);
$this->checkout_id = $this->getRecordAttr('id');
# Check for the billing status:
if ($this->billed_amt >= $invoice['total_amt'])
$this->billing_status = '1';
else
$this->billing_status = '0';
# Check if this transaction_id has already been processed:
$rs = $db->Execute(
sqlSelect('invoice_memo','id',
array('where'=>array('invoice_id'=>$invoice['id'],'type'=>'postback','memo'=>sprintf('%s-%s',$this->getRecordAttr('id'),$arr['transaction_id'])))));
if (! $rs)
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
# Transaction ID already exists
elseif ($rs->RecordCount()) {
# Duplicate post:
$C_debug->error(__FILE__,__METHOD__,
sprintf('Duplicate postback for invoice %s & transaction id %s-%s',$arr['invoice_id'],$this->getRecordAttr('id'),$arr['transaction_id']));
# Record new transaction ID
} else {
# Create the invoice memo
# @todo should get the account_id
$rs = $db->Execute(
sqlInsert($db,'invoice_memo',
array('date_orig'=>time(),'invoice_id'=>$invoice['id'],'account_id'=>null,
'type'=>'postback','memo'=>sprintf('%s-%s',$this->getRecordAttr('id'),$arr['transaction_id']))));
if (! $rs)
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
$io = new invoice($invoice['id']);
# Update the invoice approval status
if (! isset($arr['status']) || ! $arr['status']) {
$rs = $db->Execute(
sqlInsert($db,'invoice_memo',
array('date_orig'=>time(),'invoice_id'=>$invoice['id'],
'account_id'=>null,'type'=>'void','memo'=>sprintf('%s: %s-%s',_('Voided due to postback'),$this->getRecordAttr('id'),$arr['transaction_id']))));
if (! $rs)
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
# Void
$io->voidInvoice(array('id'=>$invoice['id']));
} else {
# Check the items, see if there is a payment fee to add to the invoice
if (isset($arr['items']) && is_array($arr['items'])) {
include_once(PATH_MODULES.'invoice_item/invoice_item.inc.php');
foreach ($arr['items'] as $k => $v) {
if (isset($v['item_number']) && $v['item_number'] == 'PAYFEE') {
$ito = new invoice_item();
$ito->setRecordAttr('invoice_id',$invoice['id']);
$ito->setRecordAttr('account_id',0);
$ito->setRecordAttr('service_id',null);
$ito->setRecordAttr('charge_id',null);
$ito->setRecordAttr('product_name',sprintf('Payment Fee: %s',$this->getRecordAttr('name')));
$ito->setRecordAttr('product_id',null);
$ito->setRecordAttr('product_attr',null);
$ito->setRecordAttr('product_attr_cart',null);
$ito->setRecordAttr('sku','PAYFEE');
$ito->setRecordAttr('quantity',1);
$ito->setRecordAttr('item_type',0);
$ito->setRecordAttr('price_setup',0);
$ito->setRecordAttr('domain_name',null);
$ito->setRecordAttr('domain_tld',null);
$ito->setRecordAttr('domain_type',null);
$ito->setRecordAttr('domain_term',null);
$ito->setRecordAttr('price_type',null);
$ito->setRecordAttr('recurring_schedule',null);
$ito->setRecordAttr('date_start',null);
$ito->setRecordAttr('date_stop',null);
$ito->setRecordAttr('price_base',$v['mc_gross_']);
# @todo need to retro work out the tax amount.
$ito->setRecordAttr('tax_amt',0);
$item = $ito->sql_SaveRecord();
$io->setRecordAttr('total_amt',$io->getRecordAttr('total_amt')+$ito->getRecordAttr('total_amt'));
$io->setRecordAttr('tax_amt',$io->getRecordAttr('tax_amt')+$ito->getRecordAttr('tax_amt'));
}
}
}
$io->setRecordAttr('billing_status',$this->billing_status);
$io->setRecordAttr('checkout_plugin_id',$this->getRecordAttr('id'));
$io->setRecordAttr('checkout_plugin_data',$this->subscription_id);
$io->setRecordAttr('billed_amt',$this->billed_amt);
$io->setRecordAttr('actual_billed_amt',$this->actual_billed_amt);
$io->setRecordAttr('actual_billed_currency_id',$this->actual_billed_currency_id);
$rs = $io->sql_SaveRecord();
# If the payment module is installed, record the payment item.
if ($C_list->is_installed('payment')) {
include_once(PATH_MODULES.'payment/payment.inc.php');
include_once(PATH_MODULES.'payment_item/payment_item.inc.php');
$po = new payment();
$po->setRecordAttr('account_id',$io->getRecordAttr('account_id'));
$po->setRecordAttr('date_payment',time());
$po->setRecordAttr('checkout_plugin_id',$this->getRecordAttr('id'));
$po->setRecordAttr('total_amt',$arr['amount']);
$po->setRecordAttr('fees_amt',(isset($arr['fee']) ? $arr['fee'] : 0));
$po->setRecordAttr('notes',print_r($_POST,true));
$po->setRecordAttr('source_id',$io->getRecordAttr('account_id'));
$pid = $po->sql_SaveRecord(true);
$po->sql_LoadRecord($pid);
# Mark this payment pending
# @todo Make this a global configuration option to auto mark payments as pending, so they can be reviewed.
$po->setRecordAttr('pending_status',1);
$po->sql_SaveRecord();
$pio = new payment_item();
$pio->setRecordAttr('payment_id',$pid);
$pio->setRecordAttr('invoice_id',$io->getRecordAttr('id'));
$pio->setRecordAttr('alloc_amt',$arr['amount']);
$pio->sql_SaveRecord();
}
# Approve
$io->autoApproveInvoice($invoice['id']);
# User invoice payment confirmation
include_once(PATH_MODULES.'email_template/email_template.inc.php');
$email = new email_template;
$email->send('invoice_paid_user', $invoice->fields['account_id'], $invoice_id, DEFAULT_CURRENCY, '');
$email->send('invoice_paid_user',$invoice['account_id'],$invoice['id'],DEFAULT_CURRENCY,'');
# Admin alert of payment processed
$email = new email_template;
$email->send('admin->invoice_paid_admin', $invoice->fields['account_id'], $invoice_id, DEFAULT_CURRENCY, '');
$email->send('admin->invoice_paid_admin',$invoice['account_id'],$invoice['id'],DEFAULT_CURRENCY,'');
}
}
return true;
}

View File

@@ -141,11 +141,11 @@
<!-- Methods for this class, and the fields they have access to, if applicable -->
<method>
<add>id,site_id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups,graphic_url</add>
<update>id,site_id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups,graphic_url</update>
<delete>id,site_id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,excluded_products,required_groups</delete>
<view>id,site_id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups,graphic_url</view>
<search>id,site_id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups</search>
<add>name,description,active,checkout_plugin,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_amount,default_when_amount,allowed_currencies,email_template,required_groups,graphic_url</add>
<delete>id</delete>
<search>id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups</search>
<update>id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups,graphic_url</update>
<view>id,name,description,active,checkout_plugin,plugin_data,allow_recurring,allow_new,allow_trial,total_minimum,total_maximum,max_decline_attempts,manual_approval_all,manual_approval_recur,manual_approval_country,manual_approval_group,manual_approval_amount,manual_approval_currency,default_when_currency,default_when_country,default_when_group,default_when_amount,allowed_currencies,email_template,excluded_products,required_groups,graphic_url</view>
</method>
<!-- Method triggers -->

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides checkout capabilities.
*
* @package OSB
* @subpackage Checkout
* @category Controllers
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Controller_Checkout extends Controller_TemplateDefault {
protected $auth_required = TRUE;
protected $noauth_redirect = 'login/register';
/**
* This is the main call to export, providing a list of items to export and
* setting up the page to call the export plugin when submitted.
*/
public function action_index() {
if ($_POST)
return $this->checkout();
// @todo - this should be a global config item
$mediapath = Route::get('default/media');
$block = new block;
// @todo Items in the cart dont have account_id if they were put in the cart when the user was not logged in
// If the cart is empty, we'll return here.
if (! Cart::instance()->contents()->count_all())
$block->add(array(
'title'=>_('Empty Cart'),
'body'=>_('The cart is empty')
));
else {
Style::add(array(
'type'=>'file',
'data'=>'css/checkout_cartlist.css',
));
// Show a list of items in the cart
$output = '<table class="checkout_cartlist" border="0">';
foreach (Cart::instance()->contents()->find_all() as $item) {
$ppa = $item->product->get_price_array();
$pdata = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
$output .= View::factory('cart/checkout_list')
->set('price_firstinvoice',$item->quantity*$ppa[$item->recurr_schedule]['price_base']*$pdata['prorata'])
->set('price_setup',$item->quantity*$ppa[$item->recurr_schedule]['price_setup'])
->set('service_start',$pdata['date'])
->set('service_end',$pdata['end'])
->set('price_recurring',$item->quantity*$ppa[$item->recurr_schedule]['price_base'])
->set('item',$item)
->set('mediapath',$mediapath);
}
$output .= '</table>';
$block->add(array(
'title'=>_('Your Items'),
'body'=>$output,
));
$po = ORM::factory('checkout')
->payment_options_cart();
// @todo Country value should come from somewhere?
$block->add(array(
'title'=>_('Order Total'),
'body'=>View::factory('cart/checkout_total')
->set('cart',Cart::instance())
->set('country',61),
));
$output = Form::open();
$output .= '<table class="payment_options_box" border="0">';
foreach ($po as $payment) {
$output .= View::factory('checkout/payment_option')
->set('payment',$payment);
}
// @todo Add Javascript to stop submission if something not selected
$output .= '<tr><td>&nbsp;</td></tr>';
$output .= '<tr>';
$output .= sprintf('<td>%s</td>',Form::submit('submit',_('Submit Order')));
$output .= '</tr>';
$output .= '</table>';
$output .= Form::close();
$block->add(array(
'title'=>_('Available Payment Methods'),
'body'=>$output,
));
}
$this->template->content = $block;
// Suppress our right hand tab
$this->template->right = ' ';
}
/**
* Process checkout
*/
private function checkout() {
$invoice = ORM::factory('invoice');
// Add our individual items to the invoice
foreach (Cart::instance()->contents()->find_all() as $item) {
$invoice_item = $invoice->add_item();
$invoice_item->product_id = $item->product_id;
$invoice_item->product_attr = $item->product_attr;
$invoice_item->product_attr_cart = $item->product_attr;
$invoice_item->quantity = $item->quantity;
$invoice_item->recurring_schedule = $item->recurr_schedule;
$ppa = $item->product->get_price_array();
$period = Period::details($item->recurr_schedule,$item->product->price_recurr_weekday,time(),TRUE);
// @todo rounding should be a global config
$invoice_item->price_base = round($item->quantity*$ppa[$item->recurr_schedule]['price_base']*$period['prorata'],2);
$invoice_item->price_setup = round($item->quantity*$ppa[$item->recurr_schedule]['price_setup'],2);
}
$invoice->account_id = Auth::instance()->get_user()->id;
$invoice->type = 2; // INVOICED VIA CHECKOUT
$invoice->status = 1; // INVOICE IS NOT CANCELLED
$invoice->due_date = time(); // DATE INVOICE MUST BE PAID
$invoice->billed_currency_id = 6; // @todo This should come from the site config or the currency selected
/*
$invoice->process_status = NULL; // TO BE PROCESSED
$invoice->billing_status = NULL; // UNPAID
$invoice->refund_status = NULL; // NOT REFUNDED
$invoice->print_status = NULL; // NOT YET PRINTED
$invoice->discount_amt = NULL; // @todo CALCULATE DISCOUNTS
$invoice->checkout_plugin_id = NULL; // @todo Update the selected checkout plugin
$invoice->checkout_plugin_data = NULL; // @todo Data required for the checkout plugin
*/
if ($invoice->check())
$invoice->save();
else
throw new Kohana_Exception('Problem saving invoice - Failed check()');
}
}
?>

View File

@@ -0,0 +1,67 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides checkout capabilities.
*
* @package OSB
* @subpackage Checkout
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Checkout extends ORMOSB {
protected $_has_many = array(
'payment' => array()
);
/**
* Give a cart, this will present the available checkout options
*
* Trial Products are NEW products
* Cart items are NEW products
* Invoice items are RE-OCCURING items (ie: carts are not re-occuring)
*
*/
public function payment_options_cart() {
$cart = Cart::instance();
$available_payments = array();
if ($cart->has_trial())
$this->and_where('allow_trial','=',TRUE);
$this->and_where('allow_new','=',TRUE);
foreach ($this->where('active','=',TRUE)->find_all() as $item) {
// Check that the cart total meets the minimum requirement
if ($item->total_minimum AND $cart->total() < $item->total_minimum)
continue;
// Check the cart total meets the maximum requirement
if (($item->total_maximum AND $cart->total() > $item->total_maximum) OR ($item->total_maximum == '0' AND $cart->total()))
continue;
// Check that the payment option is available to this client based on groups
// @todo Enable this test
// Check that the payment option is not prohibited by an SKU item
// @todo Enable this test
// Check if this payment method is a default payment method
// @todo Enable this test
// By Amount
// By Currency
// By Group
// By Country
// This payment option is valid
array_push($available_payments,$item);
// Sort the checkout options
// @todo Is this required?
}
return $available_payments;
}
}
?>

View File

@@ -0,0 +1,3 @@
<tr>
<td class="icon"><label for="payment_<?php echo $payment->id; ?>"><?php echo FORM::radio('payment',$payment->id,0,array('id'=>'payment_'.$payment->id)); ?> <?php echo HTML::image($payment->graphic_url,array('alt'=>'')); ?> <?php echo $payment->name; ?></label></td>
</tr>

View File

@@ -338,6 +338,9 @@ function sqlSelect($TableList,$FieldList,$sql=array()) {
$fields = $FieldList;
# Condition(s)
# @todo to remove sqlConditions() doesnt need $db
if (! isset($db))
$db = &DB();
$where = sqlConditions($db,$sql['where'],$TableList);
$line = '';
@@ -351,7 +354,7 @@ function sqlSelect($TableList,$FieldList,$sql=array()) {
# Limit
if (isset($sql['limit']) && $sql['limit'])
$line .= 'LIMIT '.$sql['limit'];
$line .= ' LIMIT '.$sql['limit'];
$SQL = sprintf('SELECT %s FROM %s %s %s',$fields,$table,$where,$line);

View File

@@ -171,7 +171,7 @@ function CORE_database_add($VAR,$construct,$type) {
$insert_value = $VAR[$field_var];
# Perform data conversions
if (isset($construct->field[$field_name]['convert']))
if (isset($construct->field[$field_name]['convert']) && ! isset($VAR['_noconvert']))
$insert_value = $validate->convert($field_name,$insert_value,$construct->field[$field_name]['convert']);
# Create the sql statement
@@ -185,17 +185,14 @@ function CORE_database_add($VAR,$construct,$type) {
$field_var = sprintf('%s_%s',$construct->module,$field_name);
if (isset($construct->field[$field_name]) && ! isset($VAR[$field_var]))
if (isset($construct->field[$field_name]['convert']))
if (isset($construct->field[$field_name]['convert']) && ! isset($VAR['_noconvert']))
$field_list[$field_name] = $validate->convert($field_name,time(),$construct->field[$field_name]['convert']);
else
$field_list[$field_name] = time();
}
# Determine the record id
$construct->record_id = $db->GenID(AGILE_DB_PREFIX.$construct->table.'_id');
# Define the new ID as a constant
define(strtoupper(sprintf('NEW_RECORD_%s_ID',$construct->table)),$construct->record_id);
$construct->record_id = isset($field_list['id']) ? $field_list['id'] : $db->GenID(AGILE_DB_PREFIX.$construct->table.'_id');
# Execute the query
$result = $db->Execute(sqlInsert($db,$construct->table,$field_list,$construct->record_id));

View File

@@ -45,15 +45,16 @@ function CORE_database_update($VAR,$construct,$type) {
$construct->validated = true;
# Quick Validation to see if we have too many variables.
foreach ($VAR as $field_name => $value)
if (preg_match("/^{$construct->module}_/",$field_name))
if (! in_array(preg_replace("/^{$construct->module}_/",'',$field_name),$arr))
array_push($construct->val_error,array(
'field'=>sprintf('%s_%s',$construct->table,$field_name),
'field_trans'=>$field_name,
'error'=>sprintf('WARNING: Variable passed to %s but it will be ignored.',__METHOD__),
'method'=>sprintf('%s:%s(%s)',__FILE__,__METHOD__,__LINE__)
));
if (! isset($VAR['_ignoreval']))
foreach ($VAR as $field_name => $value)
if (preg_match("/^{$construct->module}_/",$field_name))
if (! in_array(preg_replace("/^{$construct->module}_/",'',$field_name),$arr))
array_push($construct->val_error,array(
'field'=>sprintf('%s_%s',$construct->table,$field_name),
'field_trans'=>$field_name,
'error'=>sprintf('WARNING: Variable passed to %s but it will be ignored.',__METHOD__),
'method'=>sprintf('%s:%s(%s)',__FILE__,__METHOD__,__LINE__)
));
# Define this record id
$id = $VAR[$construct->module.'_id'];
@@ -67,7 +68,7 @@ function CORE_database_update($VAR,$construct,$type) {
$ignore_con = false;
$ignore_convert = array('sha','md5','rc5','crypt');
for ($ic=0; $ic<count($ignore_convert); $ic++)
if (isset($construct->field[$field_name]['convert']))
if (isset($construct->field[$field_name]['convert']) && ! isset($VAR['_noconvert']))
if ($construct->field[$field_name]['convert'] == $ignore_convert[$ic])
$ignore_con = true;
@@ -105,10 +106,11 @@ function CORE_database_update($VAR,$construct,$type) {
array_push($construct->val_error,array(
'field'=>sprintf('%s_%s',$construct->module,$field_name),
'field_trans'=>$C_translate->translate('field_'.$field_name,$construct->module,''),
'field_trans'=>$C_translate->translate('field_'.$field_name,$construct->module,'') ? $C_translate->translate('field_'.$field_name,$construct->module,'') : $field_name,
'error'=>$C_translate->translate('validate_any','',''),
'method'=>sprintf('%s:%s(%s)',__FILE__,__METHOD__,__LINE__)
));
}
}
}
@@ -158,7 +160,7 @@ function CORE_database_update($VAR,$construct,$type) {
$insert_value = $VAR[$field_var];
# Perform data conversions
if (isset($construct->field[$field_name]['convert']) && trim($construct->field[$field_name]['convert']))
if (isset($construct->field[$field_name]['convert']) && trim($construct->field[$field_name]['convert']) && ! isset($VAR['_noconvert']))
$insert_value = $validate->convert($field_name,$insert_value,$construct->field[$field_name]['convert']);
$field_list[$field_name] = $insert_value;

View File

@@ -37,7 +37,6 @@ class CORE_list {
public function menu($input_id,$name,$table,$field,$default,$class,$all=false) {
$this->mmenu($input_id,$name,$table,$field,$default,'',$class,$all);
}
/**
* Generate a select list, using the values in a table
*
@@ -83,7 +82,8 @@ class CORE_list {
$i = 0;
while (! $result->EOF) {
$return .= sprintf('<option value="%s"%s>%s</option>',$result->fields['id'],($default == $result->fields['id']) ? ' selected="selected"' : '',$result->fields[$field]);
$return .= sprintf('<option value="%s"%s>%s</option>',
$result->fields['id'],($default == $result->fields['id']) ? ' selected="selected"' : '',$result->fields[$field]);
$result->MoveNext();
$i++;
@@ -95,7 +95,7 @@ class CORE_list {
$return = $C_translate->translate('lists_none_defined');
if ($i > 0 && ! $noicon)
$return .= sprintf('&nbsp;<img src="themes/%s/images/icons/zoomi_16.gif" alt="Zoom" width="16" height="16" style="border: 0px;" onclick="menu_item_view(\'%s\',\'%s\');"/>',THEME_NAME,$table,$input_id);
$return .= sprintf('&nbsp;<img src="themes/%s/images/icons/zoomi_16.gif" alt="Zoom" width="16" height="16" style="border: 0px;" onclick="menu_item_view(\'%s\',\'%s\');"/>',THEME_NAME,$table,$input_id);
echo $return;
}
@@ -103,23 +103,27 @@ class CORE_list {
function decrypt($data) {
include_once(PATH_CORE.'crypt.inc.php');
return CORE_decrypt($data);
}
function menu_cc_admin($field, $account, $default, $class, $user=false) {
include_once(PATH_MODULES . 'account_billing/account_billing.inc.php');
$acct_bill = new account_billing;
echo $acct_bill->menu_admin($field, $account, $default, $class, $user);
function menu_cc_admin($field,$account,$default,$class,$user=false) {
include_once(PATH_MODULES.'account_billing/account_billing.inc.php');
$abo = new account_billing;
echo $abo->menu_admin($field,$account,$default,$class,$user);
}
function menu_multi($default, $name, $table, $field, $id, $max, $class) {
function menu_multi($default,$name,$table,$field,$id,$max,$class) {
include_once(PATH_CORE.'list_menu_multi.inc.php');
echo list_menu_multi($default, $name, $table, $field, $id, $max, $class);
echo list_menu_multi($default,$name,$table,$field,$id,$max,$class);
}
function menu_files($id, $name, $default, $path, $pre, $ext, $class) {
function menu_files($id,$name,$default,$path,$pre,$ext,$class) {
include_once(PATH_CORE.'list_menu_files.inc.php');
echo list_menu_files($id, $name, $default, $path, $pre, $ext, $class);
echo list_menu_files($id,$name,$default,$path,$pre,$ext,$class);
}
/**
@@ -133,249 +137,111 @@ class CORE_list {
* @param bool $all If true, then a blank item will be included.
*/
public function menu_staticlist($type,$input_id,$name,$default,$class,$all=false) {
global $C_list;
# Whether the values are also keys.
$nokeys = false;
$list = array();
switch ($type) {
case 'assoc_grant_type':
$list = array(0=>_('Grant access for specified amount of days'),1=>_('Grant access while associated subscription is active'),2=>_('Grant access forerver'));
break;
case 'assoc_prod_type':
$list = array(0=>_('Require All Selected Products'),1=>_('Require Any One Selected Product'));
break;
case 'charge_sweep':
$list = array(0=>_('Daily'),1=>_('Weekly'),2=>_('Monthly'),3=>_('Quarterly'),4=>_('Semi-Annually'),5=>_('Annually'),6=>_('Service Rebill'));
break;
case 'commissiontype':
$list = array(0=>_('None'),1=>_('Percentage Based'),2=>('Flat Rate'));
break;
# @todo To deprecate this and standardise with commissiontype
case 'discounttype':
$list = array(0=>_('Percentage Based'),1=>('Flat Rate'));
break;
case 'copluginmode':
$list = array(0=>_('Test'),1=>_('Live'));
break;
case 'domaintype':
$list = array(
'register'=>_('Register'),
'transfer'=>_('Transfer'),
'park'=>_('Park')
);
break;
case 'email_piping':
$list = array(0=>'&nbsp;',1=>'POP',2=>'IMAP');
break;
case 'email_piping_action':
$list = array(0=>_('Leave message in mailbox'),1=>_('Delete message from mailbox'));
break;
case 'invoice_delivery':
$list = array(0=>_('None'),1=>_('E-Mail'),2=>_('Print'));
break;
case 'invoice_show_itemized':
$list = array(0=>_('Overview Only'),1=>_('Full Detail'));
break;
case 'nametitle':
$list = array(_('Mr'),_('Ms'),_('Mrs'),_('Miss'),_('Dr'),_('Prof'));
$nokeys = true;
break;
case 'os':
$list = array(0=>'Linux',1=>'Windows');
break;
case 'recur_schedule':
$list = array(0=>_('Weekly'),1=>_('Monthly'),2=>_('Quarterly'),3=>_('Semi-Annually'),4=>_('Annually'),5=>_('Two years'),6=>_('Three Years'));
break;
case 'recur_type':
$list = array(0=>_('Bill on Aniversary Date of Subscription'),1=>_('Bill on Fixed Schedule'));
break;
case 'pricetype':
$list = array(0=>_('One-time Charge'),1=>_('Recurring Membership/Subscription'),2=>_('Trial for Membership/Subscription'));
break;
case 'servicetype':
if ($C_list->is_installed('host_server')) {
$list['host'] = _('Hosting');
$list['host_group'] = _('Hosting & Group Access');
$list['domain'] = _('Domain Name');
}
$list['none'] = _('Recurring Only');
break;
case 'servicequeue':
$list = array(
'new'=>_('Add New'),
'active'=>_('Activate'),
'inactive'=>_('Deactivate'),
'delete'=>_('Delete'),
'edit'=>_('Edit/Update'),
'queue_none'=>_('None')
);
break;
case 'statictype':
$list = array(
'small_text'=>_('Small Text'),
'medium_text'=>_('Medium Text'),
'large_text'=>_('Large Text'),
'dropdown_list'=>_('Dropdown List'),
'calendar'=>_('Calendar'),
'file_upload'=>_('File Upload'),
'status'=>_('Status'),
'checkbox'=>_('Checkbox'),
'hidden'=>_('Hidden')
);
break;
case 'tasktype':
$list = array(0=>_('Internal Method'),1=>_('System Call'));
break;
case 'trial_length':
$list = array(0=>_('Days'),1=>_('Weeks'),2=>_('Months'));
break;
default: return sprintf('Unknown staticlist: %s',$type);
}
# If id is blank, we'll just return the value
if (! $input_id)
return $list[$default];
$return = sprintf('<select id="%s" name="%s" class="%s">',$input_id,$name,$class);
if ($all)
$return .= '<option value="">&nbsp;</option>';
foreach ($list as $element => $details) {
$selected = '';
if ($nokeys) {
if ($default == $details)
$selected = ' selected="selected"';
} else {
if ($default == $element)
$selected = ' selected="selected"';
}
$return .= sprintf('<option value="%s"%s>%s</option>',$nokeys ? $details : $element,$selected,$details);
}
$return .= '</select>';
return $return;
include_once(PATH_CORE.'list_staticlist.inc.php');
return list_menu_staticlist($type,$input_id,$name,$default,$class,$all);
}
function format_currency ($number, $currency_id) {
if(empty($number)) $number = 0;
if(empty($currency_id)) $currency_id = DEFAULT_CURRENCY;
if(!isset($this->format_currency[$currency_id])) $this->currency($currency_id);
if($currency_id != DEFAULT_CURRENCY)
if(!isset($this->format_currency[DEFAULT_CURRENCY]))
$this->currency(DEFAULT_CURRENCY);
$number *= $this->format_currency[DEFAULT_CURRENCY]["convert"][$currency_id]["rate"];
if($number > .05 || $number == 0 || $number < -1)
return $this->format_currency[$currency_id]["symbol"]
. "" . number_format($number, DEFAULT_DECIMAL_PLACE) . " "
. $this->format_currency[$currency_id]["iso"];
else
return $this->format_currency[$currency_id]["symbol"]
. "" . number_format($number, 3) . " "
. $this->format_currency[$currency_id]["iso"];
public function format_currency($number,$currency_id=DEFAULT_CURRENCY) {
$number = $this->format_currency_decimal($number,$currency_id);
if (! $currency_id)
$currency_id = DEFAULT_CURRENCY;
return sprintf('%s%s %s',
$this->format_currency[$currency_id]['symbol'],
($number > .05 || $number == 0 || $number < -1 || DEFAULT_DECIMAL_PLACE == 2)
? number_format($number,DEFAULT_DECIMAL_PLACE)
: number_format($this->format_currency_decimal($number,$currency_id,2)),
$this->currency_iso($currency_id));
}
function format_currency_num ($number, $currency_id) {
if(empty($number)) $number = 0;
if(empty($currency_id)) $currency_id = DEFAULT_CURRENCY;
if(!isset($this->format_currency[$currency_id])) $this->currency($currency_id);
if(!isset($this->format_currency[DEFAULT_CURRENCY])) $this->currency(DEFAULT_CURRENCY);
$number *= $this->format_currency[DEFAULT_CURRENCY]["convert"][$currency_id]["rate"];
if($number > .05 || $number == 0 || $number < -1)
return $this->format_currency[$currency_id]["symbol"] . number_format($number, DEFAULT_DECIMAL_PLACE);
else
return $this->format_currency[$currency_id]["symbol"] . number_format($number, 2);
public function format_currency_num($number,$currency_id=DEFAULT_CURRENCY) {
$number = $this->format_currency_decimal($number,$currency_id);
if (! $currency_id)
$currency_id = DEFAULT_CURRENCY;
return sprintf('%s%s',
$this->format_currency[$currency_id]['symbol'],
($number > .05 || $number == 0 || $number < -1 || DEFAULT_DECIMAL_PLACE == 2)
? number_format($number,DEFAULT_DECIMAL_PLACE)
: number_format($this->format_currency_decimal($number,$currency_id),2));
}
function format_currency_decimal ($number, $currency_id) {
if(empty($number)) return 0;
if(empty($currency_id)) $currency_id = DEFAULT_CURRENCY;
if(!isset($this->format_currency[$currency_id])) $this->currency($currency_id);
if(!isset($this->format_currency[DEFAULT_CURRENCY])) $this->currency(DEFAULT_CURRENCY);
return round($number *= $this->format_currency[DEFAULT_CURRENCY]["convert"][$currency_id]["rate"], 2);
public function format_currency_decimal($number,$currency_id,$decimals=DEFAULT_DECIMAL_PLACE) {
if (empty($number))
return 0;
if (empty($currency_id))
$currency_id = DEFAULT_CURRENCY;
if (! isset($this->format_currency[$currency_id]))
$this->currency($currency_id);
if (! isset($this->format_currency[DEFAULT_CURRENCY]))
$this->currency(DEFAULT_CURRENCY);
return round($number*=$this->format_currency[DEFAULT_CURRENCY]['convert'][$currency_id]['rate'],$decimals);
}
function currency_list($ret) {
if(!isset($this->format_currency[$currency_id])) $this->currency(DEFAULT_CURRENCY);
public function currency_list($ret,$currency_id=DEFAULT_CURRENCY) {
global $smarty;
$smarty->assign("$ret", $this->format_currency[DEFAULT_CURRENCY]["convert"]);
if (! isset($this->format_currency[$currency_id]))
$this->currency(DEFAULT_CURRENCY);
$smarty->assign($ret,$this->format_currency[DEFAULT_CURRENCY]['convert']);
}
function currency_iso ($currency_id) {
if(empty($currency_id)) $currency_id = DEFAULT_CURRENCY;
if(!isset($this->format_currency[$currency_id])) $this->currency($currency_id);
return $this->format_currency[$currency_id]["iso"];
public function currency_iso($currency_id=DEFAULT_CURRENCY) {
if (! isset($this->format_currency[$currency_id]))
$this->currency(DEFAULT_CURRENCY);
return $this->format_currency[$currency_id]['iso'];
}
function currency($currency_id) {
public function currency($currency_id) {
static $CACHE = array();
$db = &DB();
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . 'currency WHERE
site_id = ' . $db->qstr(DEFAULT_SITE) . ' AND
id = ' . $db->qstr($currency_id);
$result = $db->Execute($sql);
if($result->RecordCount() > 0) {
$this->format_currency[$currency_id] = Array (
'symbol' => $result->fields["symbol"],
'convert' => unserialize($result->fields["convert_array"]),
'iso' => $result->fields["three_digit"]);
return true;
} else {
return false;
if (! isset($CACHE[$currency_id])) {
$rs = $db->Execute(sqlSelect('currency','*',array('where'=>array('id'=>$currency_id))));
if ($rs && $rs->RecordCount())
$this->format_currency[$currency_id] = array(
'symbol' => $rs->fields['symbol'],
'convert' => unserialize($rs->fields['convert_array']),
'iso' => $rs->fields['three_digit']);
else
return false;
}
return true;
}
function radio($input_id, $name, $table, $field, $id, $class) {
include_once(PATH_CORE . 'list_radio.inc.php');
echo list_radio($input_id, $name, $table, $field, $id, $class);
public function radio($input_id,$name,$table,$field,$id,$class) {
include_once(PATH_CORE.'list_radio.inc.php');
echo list_radio($input_id,$name,$table,$field,$id,$class);
}
function check($input_id, $name, $table, $field, $default, $class) {
include_once(PATH_CORE . 'list_check.inc.php');
echo list_check($input_id, $name, $table, $field, $default, $class);
public function check($input_id,$name,$table,$field,$default,$class) {
include_once(PATH_CORE.'list_check.inc.php');
echo list_check($input_id,$name,$table,$field,$default,$class);
}
function select_groups($default, $field_name, $class, $size, $own_account) {
include_once(PATH_CORE . 'list_select_groups.inc.php');
return list_select_groups($default, $field_name, $class, $size, $own_account);
public function select_groups($default,$field_name,$class,$size,$own_account) {
include_once(PATH_CORE.'list_select_groups.inc.php');
return list_select_groups($default,$field_name,$class,$size,$own_account);
}
function calender_view($field, $default, $css, $id) {
if(isset($default) && $default != '' && $default != '0')
$default = date(UNIX_DATE_FORMAT, $default);
else
$default = '';
public function calender_view($field,$default,$css,$id) {
include_once(PATH_CORE.'list_calendar.inc.php');
echo list_calender_add($field, $default, $css,$id);
if (isset($default) && $default != '' && $default != '0')
$default = date(UNIX_DATE_FORMAT,$default);
else
$default = '';
echo list_calender_add($field,$default,$css,$id);
}
public function calender_add($field,$default,$css,$id='') {
@@ -387,90 +253,94 @@ class CORE_list {
}
# @todo Remove?
function calender_add_static_var($field, $default, $css) {
if($default == 'now') $default = date(UNIX_DATE_FORMAT, time());
public function calender_add_static_var($field,$default,$css) {
include_once(PATH_CORE.'list_calendar.inc.php');
echo list_calender_add_static($field, $default, $css);
}
function calender_search($field, $default, $css) {
if ($default == 'now')
$default = date(UNIX_DATE_FORMAT, time());
$default = date(UNIX_DATE_FORMAT,time());
echo '
<select name="field_option['.$field.'][0]">
<option value=">">></option>
<option value="<"><</option>
<option value="<="><=</option>
<option value=">=">>=</option>
<option value="!=">!=</option>
</select>&nbsp;&nbsp;';
$this->calender_view($field,$default,$css,0);
echo '<br/>
<select name="field_option['.$field.'][1]">
<option value="<"><</option>
<option value=">">></option>
<option value="<="><=</option>
<option value=">=">>=</option>
<option value="!=">!=</option>
</select>&nbsp;&nbsp;';
$this->calender_view($field,$default,$css,1);
echo list_calender_add_static($field,$default,$css);
}
function setup_default_date($default, $css) {
include_once(PATH_CORE . 'list_setup_default_date.inc.php');
echo list_setup_default_date($default, $css);
public function calender_search($field,$default,$css) {
if ($default == 'now')
$default = date(UNIX_DATE_FORMAT,time());
foreach (array(0,1) as $id) {
printf('<select name="field_option[%s][%s]"><option value=">">></option><option value="<"><</option><option value="<="><=</option><option value=">=">>=</option><option value="!=">!=</option></select>&nbsp;&nbsp;',$field,$id);
$this->calender_view($field,$default,$css,$id);
echo '<br/>';
}
}
function card_type_menu($default_selected, $checkout_id, $field='checkout_plugin_data[card_type]', $class,$all=false) {
include_once(PATH_CORE . 'list_card_type_menu.inc.php');
echo list_card_type_menu($default_selected, $checkout_id, $field, $class,$all);
public function setup_default_date($default,$css) {
include_once(PATH_CORE.'list_setup_default_date.inc.php');
echo list_setup_default_date($default,$css);
}
function date($date) {
if($date == '') $date = time();
return date(UNIX_DATE_FORMAT, $date);
public function card_type_menu($default_selected,$checkout_id,$field='checkout_plugin_data[card_type]',$class,$all=false) {
include_once(PATH_CORE.'list_card_type_menu.inc.php');
echo list_card_type_menu($default_selected,$checkout_id,$field,$class,$all);
}
function date_time($date) {
if ($date == '')
return 'UNKNOWN';
$ret = date(UNIX_DATE_FORMAT, $date);
$ret .= " ".date(DEFAULT_TIME_FORMAT, $date);
return $ret;
public function time($date) {
if ($date == '')
$date = time();
return date(DEFAULT_TIME_FORMAT,$date);
}
function unserial ($data, $var) {
public function date($date) {
if ($date == '')
$date = time();
return date(UNIX_DATE_FORMAT,$date);
}
public function date_time($date) {
if ($date == '')
return 'UNKNOWN';
return sprintf('%s %s',$this->date($date),$this->time($date));
}
public function unserial($data,$var) {
global $smarty;
if(is_string($data)) $array = unserialize($data);
if(is_array($array)) $smarty->assign($var, $array);
return;
if (is_string($data))
$array = unserialize($data);
if (is_array($array))
$smarty->assign($var,$array);
}
function smarty_array($table, $field, $sql, $return) {
public function smarty_array($table,$field,$sql,$return) { return $this->tmSmartyArray($table,$field,$sql,$return); }
public function tmSmartyArray($table,$field,$sql,$return) {
$db = &DB();
$sql= "SELECT id, $field FROM ".AGILE_DB_PREFIX."$table
WHERE site_id = '" . DEFAULT_SITE . "'" . $sql . "
ORDER BY $field";
$result = $db->Execute($sql);
if ($result === false)
{
$smart = array();
# @todo this sqlSelect() is using a call for DEFAULT_SITE until all calls to smarty_array() dont start $sql with 'AND'
$result = $db->Execute($s=sqlSelect($table,sprintf('id,%s',$field),array('where'=>sprintf('site_id=%s %s',DEFAULT_SITE,$sql),'orderby'=>$field)));
if (! $result) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
}
while (!$result->EOF)
{
$smart[] = $result->fields;
while (! $result->EOF) {
array_push($smart,$result->fields);
$result->MoveNext();
}
global $smarty;
$smarty->assign("$return", $smart);
$smarty->assign($return,$smart);
return true;
}
function translate($table, $field1, $field2, $id, $var) {
function translate($table,$field1,$field2,$id,$var) {
global $smarty;
$db = &DB();
$sql= "SELECT id, $field1 FROM ".AGILE_DB_PREFIX."$table
@@ -484,7 +354,7 @@ class CORE_list {
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
} else if($result->RecordCount() > 0) {
$smarty->assign("$var", $result->fields);
$smarty->assign("$var",$result->fields);
return $result->fields;
} else {
if (SESS_LANGUAGE == DEFAULT_LANGUAGE) {
@@ -500,7 +370,7 @@ class CORE_list {
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
} else if($result->RecordCount() > 0) {
$smarty->assign("$var", $result->fields);
$smarty->assign("$var",$result->fields);
return $result->fields;
} else {
return false;
@@ -510,11 +380,9 @@ class CORE_list {
}
public function bool($field,$curr_value,$class='form_menu',$extra='') {
global $C_translate;
# If the field is blank, we'll just return true/false
if (! $field)
return $curr_value ? $C_translate->translate('true') : $C_translate->translate('false');
return $curr_value ? _('Yes') : _('No');
if ($curr_value == 'all') {
$true = '';
@@ -529,47 +397,25 @@ class CORE_list {
$false= ' selected="selected"';
}
$return = sprintf('<select id="%s" name="%s" class="%s" %s>',$field,$field,$class,$extra);
$return = sprintf('<select id="%s" name="%s" class="%s" %s>',preg_replace('/[\[\]]/','_',$field),$field,$class,$extra);
if ($curr_value == 'all')
$return .= '<option value="" selected="selected">&nbsp;</option>';
$return .= sprintf('<option value="1"%s>%s</option>',$true,$C_translate->translate('true'));
$return .= sprintf('<option value="0"%s>%s</option>',$false,$C_translate->translate('false'));
$return .= sprintf('<option value="1"%s>%s</option>',$true,_('Yes'));
$return .= sprintf('<option value="0"%s>%s</option>',$false,_('No'));
$return .= '</select>';
echo $return;
}
// @todo this looks the same as bool()
function bool_static_var($field, $curr_value, $class) {
global $C_translate;
if ($curr_value == 'all') {
$true = '';
$false= '';
} else if ($curr_value == 0) {
$true = '';
$false= ' selected';
} else {
$true = ' selected';
$false= '';
}
$return = '<select id="'.$field.'" name="'. $field .'">';
if($curr_value == 'all')
$return .= '<option value="" selected>&nbsp;</option>';
$return .= '<option value="1"' . $true . '>'. $C_translate->translate('true', 'CORE','') . '</option>';
$return .= '<option value="0"' . $false . '>'. $C_translate->translate('false','CORE','') . '</option>';
$return .= '</select>';
return $return;
}
function graphview() {
global $VAR, $C_method;
$auth = Array('product:top', 'account_admin:top', 'affiliate:top', 'invoice:compare');
global $VAR,$C_method;
$auth = Array('product:top','account_admin:top','affiliate:top','invoice:compare');
for($i=0; $i<count($auth); $i++) {
if($auth[$i] == $VAR['graph']) {
$m = explode(':', $VAR['graph']);
$C_method->exe_noauth($m[0], $m[1]);
$m = explode(':',$VAR['graph']);
$C_method->exe_noauth($m[0],$m[1]);
exit;
}
}
@@ -583,7 +429,7 @@ class CORE_list {
@$range = $VAR['graph_range'];
@$start = $VAR['graph_start'];
@$extra = $VAR['graph_extra'];
$graph->BAR_graph($module, $range, $start, $extra);
$graph->BAR_graph($module,$range,$start,$extra);
}
function pie_graph() {
@@ -595,35 +441,45 @@ class CORE_list {
@$range = $VAR['graph_range'];
@$start = $VAR['graph_start'];
@$extra = $VAR['graph_extra'];
$graph->PIE_graph($module, $method, $range, $start, $extra);
$graph->PIE_graph($module,$method,$range,$start,$extra);
}
# @todo consider changing this so that it returns the .inc file if the module is installed
# so that $a = x->is_installed('y'); require_once $a can be used
function is_installed($module) {
if(@$this->is_installed[$module] == true) return true;
if($this->auth_method_by_name($module, 'search')) {
/**
* Check if a module is installed
*
* @param string Name of Module to check
* @return string include path to module, if installed, otherwise false
*/
public function is_installed($module) {
$file = sprintf('%s%s/%s.inc.php',PATH_MODULES,$module,$module);
# If we have already checked, then return the file.
if (isset($this->is_installed[$module]) && $this->is_installed[$module])
return $file;
if (file_exists($file) && $this->auth_method_by_name($module,'search')) {
$this->is_installed[$module] = true;
return true;
return $file;
}
$db = &DB();
$sql = 'SELECT id FROM ' . AGILE_DB_PREFIX . 'module WHERE
site_id = ' . $db->qstr(DEFAULT_SITE) . ' AND
name = ' . $db->qstr($module) . ' AND
status = ' . $db->qstr("1");
$result = $db->Execute($sql);
if($result->RecordCount() > 0) {
$result = $db->Execute(sqlSelect('module','id',array('where'=>array('name'=>$module,'status'=>1))));
if ($result && $result->RecordCount() && file_exists($file)) {
$this->is_installed[$module] = true;
return true;
return $file;
} else {
return false;
}
}
function auth_method_by_name($module, $method) {
# @todo this should probably be private?
public function auth_method_by_name($module,$method) {
global $C_auth;
if (!is_object($C_auth))
if (! is_object($C_auth))
return false;
return $C_auth->auth_method_by_name($module,$method);
@@ -638,7 +494,8 @@ class CORE_list {
echo $C_auth->generate_admin_menu();
}
function account($field) {
# @todo to deprecate
private function account($field) {
if (empty($this->account) && SESS_LOGGED) {
$db = &DB();
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . 'account WHERE
@@ -651,7 +508,9 @@ class CORE_list {
}
# Get the AgileBill version info
function version() {
# @todo to deprecate
private function version() {
die();
require_once(PATH_CORE.'version.inc.php');
}
}

View File

@@ -68,7 +68,7 @@ function list_menu_files($id,$name,$default,$path,$pre,$ext,$class) {
asort($arr);
$return = sprintf('<select id="%s_%s" name="%s">',$name,$id,$name);
$return = sprintf('<select id="%s%s" name="%s" class="%s">',$id ? $name.'_' : $name,$id,$name,$class);
if ($id == 'all' || $default == 'all')
$return .= '<option value="" selected="selected">&nbsp;</option>';

View File

@@ -0,0 +1,288 @@
<?php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software; you can redistribute it and/or
* modify it under the terms of the Open AgileBill License
* License as published at http://www.agileco.com/agilebill/license1-4.txt
*
* Originally authored by Tony Landis, AgileBill LLC
*
* Recent modifications by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
*
* @link http://www.agileco.com/
* @copyright 2004-2008 Agileco, LLC.
* @license http://www.agileco.com/agilebill/license1-4.txt
* @author Tony Landis <tony@agileco.com>
* @package AgileBill
* @subpackage Core
*/
/**
* The main AgileBill Static Lists Method
*
* @package AgileBill
* @subpackage List
*/
/**
* Generate a list of frequently used selections in OSB
*
* @param string $type List type
* @param string $input_id HTML id="" value.
* @param string $name HTML name="" value.
* @param string $default Default Value to pre-select (if it exists)
* @param string $class CSS class for the select list
* @param bool $all If true, then a blank item will be included.
*/
function list_menu_staticlist($type,$input_id,$name,$default,$class,$all=false) {
global $C_list;
# Whether the values are also keys.
$nokeys = false;
$list = array();
switch ($type) {
case 'assoc_grant_type':
$list = array(
0=>_('Grant access for specified amount of days'),
1=>_('Grant access while associated subscription is active'),
2=>_('Grant access forerver')
);
break;
case 'assoc_prod_type':
$list = array(
0=>_('Require All Selected Products'),
1=>_('Require Any One Selected Product')
);
break;
case 'charge_sweep':
$list = array(
0=>_('Daily'),
1=>_('Weekly'),
2=>_('Monthly'),
3=>_('Quarterly'),
4=>_('Semi-Annually'),
5=>_('Annually'),
6=>_('Service Rebill')
);
break;
case 'commissiontype':
$list = array(
0=>_('None'),
1=>_('Percentage Based'),
2=>('Flat Rate')
);
break;
# @todo To deprecate this and standardise with commissiontype
case 'discounttype':
$list = array(
0=>_('Percentage Based'),
1=>_('Flat Rate')
);
break;
case 'copluginmode':
$list = array(
0=>_('Test'),
1=>_('Live')
);
break;
case 'domaintype':
$list = array(
'register'=>_('Register'),
'transfer'=>_('Transfer'),
'park'=>_('Park')
);
break;
case 'email_piping':
$list = array(
0=>'&nbsp;',
1=>'POP',
2=>'IMAP'
);
break;
case 'email_piping_action':
$list = array(
0=>_('Leave message in mailbox'),
1=>_('Delete message from mailbox')
);
break;
case 'invoice_delivery':
$list = array(
0=>_('None'),
1=>_('E-Mail'),
2=>_('Print')
);
break;
case 'invoice_show_itemized':
$list = array(
0=>_('Overview Only'),
1=>_('Full Detail')
);
break;
case 'nametitle':
$list = array(
_('Mr'),
_('Ms'),
_('Mrs'),
_('Miss'),
_('Dr'),
_('Prof')
);
$nokeys = true;
break;
case 'os':
$list = array(
0=>'Linux',
1=>'Windows'
);
break;
case 'recur_schedule':
$list = array(
0=>_('Weekly'),
1=>_('Monthly'),
2=>_('Quarterly'),
3=>_('Semi-Annually'),
4=>_('Annually'),
5=>_('Two years'),
6=>_('Three Years')
);
break;
case 'recur_type':
$list = array(
0=>_('Bill on Aniversary Date of Subscription'),
1=>_('Bill on Fixed Schedule')
);
break;
case 'pricetype':
$list = array(
0=>_('One-time Charge'),
1=>_('Recurring Membership/Subscription'),
2=>_('Trial for Membership/Subscription')
);
break;
case 'servicetype':
if ($C_list->is_installed('host_server')) {
$list['host'] = _('Hosting');
$list['host_group'] = _('Hosting & Group Access');
$list['domain'] = _('Domain Name');
}
$list['none'] = _('Recurring Only');
break;
case 'servicequeue':
$list = array(
'new'=>_('Add New'),
'active'=>_('Activate'),
'inactive'=>_('Deactivate'),
'delete'=>_('Delete'),
'edit'=>_('Edit/Update'),
'queue_none'=>_('None')
);
break;
case 'statictype':
$list = array(
'small_text'=>_('Small Text'),
'medium_text'=>_('Medium Text'),
'large_text'=>_('Large Text'),
'dropdown_list'=>_('Dropdown List'),
'calendar'=>_('Calendar'),
'file_upload'=>_('File Upload'),
'status'=>_('Status'),
'checkbox'=>_('Checkbox'),
'hidden'=>_('Hidden')
);
break;
case 'tasktype':
$list = array(
0=>_('Internal Method'),
1=>_('System Call')
);
break;
case 'trial_length':
$list = array(
0=>_('Days'),
1=>_('Weeks'),
2=>_('Months')
);
break;
default: return sprintf('Unknown staticlist: %s',$type);
}
# If ID is blank, we'll just return the value
if (! $input_id)
return $list[$default];
# If the NAME is blank, we'll return the list itself
if (! $name)
return $list;
$return = sprintf('<select id="%s" name="%s" class="%s">',$input_id,$name,$class);
if ($all)
$return .= '<option value="">&nbsp;</option>';
foreach ($list as $element => $details) {
$selected = '';
if ($nokeys) {
if ($default == $details)
$selected = ' selected="selected"';
} else {
if ($default == $element)
$selected = ' selected="selected"';
}
$return .= sprintf('<option value="%s"%s>%s</option>',$nokeys ? $details : $element,$selected,$details);
}
$return .= '</select>';
return $return;
}

View File

@@ -1,327 +1,207 @@
<?php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software; you can redistribute it and/or
* modify it under the terms of the Open AgileBill License
* License as published at http://www.agileco.com/agilebill/license1-4.txt
*
* For questions, help, comments, discussion, etc., please join the
* Agileco community forums at http://forum.agileco.com/
*
* Originally authored by Tony Landis, AgileBill LLC
*
* Recent modifications by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
*
* @link http://www.agileco.com/
* @copyright 2004-2008 Agileco, LLC.
* @license http://www.agileco.com/agilebill/license1-4.txt
* @author Tony Landis <tony@agileco.com>
* @author Tony Landis <tony@agileco.com>
* @package AgileBill
* @version 1.4.93
* @subpackage Core:Login
*/
class CORE_login_handler
{
function login($VAR, $md5=true)
{
global $C_translate, $C_debug;
/**
* The main AgileBill Login Class
*
* @package AgileBill
* @subpackage Core:Login
*/
class CORE_login_handler {
/**
* Login to OSB
*/
public function login($VAR,$md5=true) {
global $C_translate, $C_debug;
$db = &DB();
# check that the username/password are both set
if(($VAR['_username'] == '') || ($VAR['_password'] == ''))
{
if ((! $VAR['_username']) || (! $VAR['_password'])) {
$C_debug->alert($C_translate->translate('login_enter_both','',''));
return;
return false;
}
# md5 the password
if($md5)
$pass = md5($VAR['_password']);
else
$pass = $VAR['_password'];
$pass = $md5 ? md5($VAR['_password']) : $VAR['_password'];
# check the database for a match
$db = &DB();
$q = "SELECT id,status,username,password,date_expire FROM " . AGILE_DB_PREFIX . "account WHERE
password = '$pass' AND
username = '".$VAR['_username']."' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# Check the database for a match
$rs = $db->Execute(
sqlSelect('account','id,status,username,password,date_expire',
array('where'=>array('username'=>$VAR['_username'],'password'=>$pass))));
# get the account id
$id = $result->fields['id'];
# check that their is no lock on this account id or IP address:
if($this->locked ($id))
{
$C_debug->alert($C_translate->translate('login_locked','',''));
return;
}
# verify the username/password match.
if($result->fields['username'] == $VAR['_username'])
{
if (($result->fields['password'] !== $VAR['_password']) && ($result->fields['password'] != $pass))
{
# no match
$C_debug->alert($C_translate->translate('login_pw_failed','',''));
# log as a failed login
$this->lock_check($VAR,"0",$id);
return;
}
}
else
{
# no username match
if (! $rs || ! $rs->RecordCount() == 1) {
$C_debug->alert($C_translate->translate('login_un_pw_failed','',''));
# reload the login page
$VAR["_page"] = 'account:user_login';
# Log as a failed login
$this->lock_check($VAR,0,$VAR['_username']);
return false;
}
# Get the account id
$id = $rs->fields['id'];
# Check that their is no lock on this account id or IP address:
if ($this->locked($id)) {
$C_debug->alert($C_translate->translate('login_locked','',''));
# log as a failed login
$this->lock_check($VAR,"0",$VAR['_username']);
return;
}
if($result->fields['date_expire'] == "0" || $result->fields['date_expire'] == "")
$date_expire = time()+99;
if ($rs->fields['date_expire'] == 0 || ! $rs->fields['date_expire'])
$date_expire = time()+99;
else
$date_expire = $result->fields['date_expire'];
$date_expire = $rs->fields['date_expire'];
# Check that it is an active account
if ($rs->fields['status'] != 1 || $date_expire <= time()) {
# Inactive account
$C_debug->alert($C_translate->translate('login_inactive','',''));
# check that it is an active account
if($result->fields['status'] != "1" || $date_expire <= time())
{
# inactive account
$C_debug->alert($C_translate->translate('login_inactive','',''));
# Log as failed login
$this->lock_check($VAR,0,$id);
# log as failed login
$this->lock_check($VAR,"0",$id);
return;
}
else
{
# active account - check for password sharing if login_share module is installed
} else {
# Active account - check for password sharing if login_share module is installed
include_once(PATH_CORE.'list.inc.php');
$C_list = new CORE_list;
if($C_list->is_installed('login_share'))
{
$C_list = new CORE_list;
if ($C_list->is_installed('login_share')) {
include_once(PATH_MODULES.'login_share/login_share.inc.php');
$share = new login_share;
if(!$share->login($id, $VAR['_username']))
{
# shared account alert
if (! $share->login($id,$VAR['_username'])) {
# Shared account alert
$C_debug->alert($C_translate->translate('shared_account','login_share',''));
# log as failed login
$this->lock_check($VAR,"0",$id);
# Log as failed login
$this->lock_check($VAR,0,$id);
return;
}
}
return;
}
}
}
# set the expiry date of the login session
$date_expire = (time() + (SESSION_EXPIRE * 60));
# Set the expiry date of the login session
$date_expire = time()+(SESSION_EXPIRE*60);
# update the DB
$db = &DB();
$q = "UPDATE " . AGILE_DB_PREFIX . "session
SET
ip= '". USER_IP ."',
date_expire = '$date_expire',
logged = '1',
account_id = '$id'
WHERE
id = '" . SESS . "'
AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# Update the DB
$rs = $db->Execute(
sqlUpdate($db,'session',array('ip'=>USER_IP,'date_expire'=>$date_expire,'logged'=>1,'account_id'=>$id),array('id'=>SESS)));
# delete any old sessions for this account
$db = &DB();
$q = "DELETE FROM " . AGILE_DB_PREFIX . "session WHERE
account_id = '$id' AND
id != '" . SESS . "' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# Delete any old sessions for this account
$rs = $db->Execute(sqlDelete($db,'session',sprintf('account_id=%s AND id!="%s"',$id,SESS)));
#return logged in message
# Return logged in message
$C_debug->alert($C_translate->translate('login_success','',''));
# Get the last successful login:
$db = &DB();
$q = "SELECT * FROM " . AGILE_DB_PREFIX . "login_log WHERE
account_id = ". $db->qstr($id)." AND
status = ". $db->qstr(1)." AND
site_id = ". $db->qstr(DEFAULT_SITE) . "
ORDER BY date_orig DESC LIMIT 1";
$result = $db->Execute($q);
if($result->RecordCount() != 0)
{
$ip = $result->fields["ip"];
$date = $result->fields["date_orig"];
$date1 = date(UNIX_DATE_FORMAT, $date);
$date1.= " ".date(DEFAULT_TIME_FORMAT, $date);
$rs = $db->Execute(
sqlSelect('login_log','ip,date_orig',array('where'=>array('account_id'=>$id,'status'=>1),'orderby'=>'date_orig DESC','limit'=>1)));
$message = $C_translate->translate('login_log_success','','');
$message = ereg_replace('%date%', $date1, $message);
$message = ereg_replace('%ip%', $ip, $message);
$C_debug->alert($message);
}
if ($rs && $rs->RecordCount())
$C_debug->alert(
str_replace('%DATE%',
sprintf('<b>%s %s</b>',date(UNIX_DATE_FORMAT,$rs->fields['date_orig']),date(DEFAULT_TIME_FORMAT,$rs->fields['date_orig'])),
str_replace('%IP%',sprintf('<b>%s</b>',$rs->fields['ip']),_('Last successful login was on %DATE% from %IP%'))));
# log the successful login
$this->lock_check($VAR,"1",$id);
# Log the successful login
$this->lock_check($VAR,1,$id);
}
public function logout($VAR) {
global $C_debug,$C_translate;
function logout ($VAR)
{
global $C_debug, $C_translate;
$db = &DB();
# logout the current session by editing the database record
$q = "UPDATE ". AGILE_DB_PREFIX ."session SET logged='0'
WHERE id = '" . SESS . "' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# Logout the current session by editing the database record
$db->Execute(sqlUpdate($db,'session',array('logged'=>0),array('id'=>SESS)));
# delete any session caches!
$q = 'DELETE FROM '.AGILE_DB_PREFIX.'session_auth_cache WHERE
session_id = '. $db->qstr(SESS) .' AND
site_id = '. $db->qstr(DEFAULT_SITE);
$db->Execute($q);
# Delete any session caches!
$db->Execute(sqlDelete($db,'session_auth_cache',array('session_id'=>SESS)));
# logout success:
$C_debug->alert($C_translate->translate('logout_success','',''));
}
function locked ($account_id)
{
# @todo this should move to login_lock.inc.php
private function locked($account_id) {
global $C_list;
include_once(PATH_CORE.'list.inc.php');
$C_list = new CORE_list;
$C_list = new CORE_list;
if (! $C_list->is_installed('login_lock'))
return false;
if($account_id != '')
$sql = " OR account_id = '$account_id' AND ";
else
$sql = " AND ";
# check by IP & USER
$db = &DB();
$q = "SELECT id FROM " . AGILE_DB_PREFIX . "login_lock WHERE
ip = '" . USER_IP . "'";
$q .= $sql;
$q .= " date_expire >= '" . time() . "' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
$i = 0;
$rs = $db->Execute(
sqlSelect('login_lock','id',
array('where'=>
sprintf('ip=::%s:: AND date_expire>=%s %s',USER_IP,time(),$account_id ? sprintf('AND account_id=%s',$account_id) : ''))));
while (!$result->EOF)
{
$i++;
$result->MoveNext();
}
# return the results
if ($i > 0)
if ($rs && $rs->RecordCount())
return true;
else
return false;
}
# @todo this should move to login_lock.inc.php
private function lock_check($VAR,$status,$account_id) {
global $C_list;
include_once(PATH_CORE.'list.inc.php');
$C_list = new CORE_list;
function lock_check ($VAR,$status,$account_id)
{
# if this is a success, delete all login old login records..
/*
if($status == 1)
{
# delete all login attempts for this account
# (to clean the slate after the account login lock expires)
$db = &DB();
$q = "DELETE FROM " . AGILE_DB_PREFIX . "login_log WHERE
account_id = '$account_id' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
}
*/
# create the appropriate login attempt record.
$db = &DB();
$login_id = $db->GenID(AGILE_DB_PREFIX . 'login_log_id');
$q = "INSERT INTO " . AGILE_DB_PREFIX . "login_log SET
id = " . $db->qstr($login_id) . ",
ip = " . $db->qstr( USER_IP ) . ",
account_id = " . $db->qstr($account_id ) . ",
date_orig = " . $db->qstr(time()) . ",
status = " . $db->qstr($status ) . ",
site_id = " . $db->qstr(DEFAULT_SITE);
$result = $db->Execute($q);
# Create the appropriate login attempt record.
$db->Execute(sqlInsert($db,'login_log',array('ip'=>USER_IP,'account_id'=>$account_id,'date_orig'=>time(),'status'=>$status)));
# if this is a successfull login, we can now exit...
if($status == 1) return;
if ($status == 1 || ! $C_list->is_installed('login_lock'))
return true;
# determine the time period to check for login attempts after:
$date_orig = (time() - (LOGIN_ATTEMPT_TIME*60));
# Determine the time period to check for login attempts after:
$date_orig = time()-(LOGIN_ATTEMPT_TIME*60);
# check the database for all the failed login attempts from
# this IP withing the time period defined in the setup.
$q = "SELECT id FROM " . AGILE_DB_PREFIX . "login_log WHERE
ip = '" . USER_IP . "' AND
date_orig >= '$date_orig' AND
status = '0' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
$i = 0;
while (!$result->EOF)
{
$i++;
$result->MoveNext();
}
# Check the database for all the failed login attempts from this IP withing the time period defined in the setup.
$rs = $db->Execute(sqlSelect('login_log','COUNT(id) as id',array('where'=>sprintf('ip=::%s:: AND date_orig>=%s AND status=0',USER_IP,$date_orig))));
# Check that it does not exceed the allowed failed login attempts
if ($rs && $rs->fields['id']>=LOGIN_ATTEMPT_TRY) {
# Get the time this login block will expire:
$date_expire = time()+(LOGIN_ATTEMPT_LOCK*60);
# check that it does not exceed the allowed failed login attempts
if($i >= LOGIN_ATTEMPT_TRY)
{
# get the time this login block will expire:
$date_expire = (time() + (LOGIN_ATTEMPT_LOCK * 60));
# Delete all old blocks for this ip
$result = $db->Execute(sqlDelete($db,'login_lock',array('ip'=>USER_IP)));
# delete all old blocks for this ip
$q = "DELETE FROM " . AGILE_DB_PREFIX . "login_lock WHERE
ip = '" . USER_IP . "' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# create a block on this login
$q = "INSERT INTO " . AGILE_DB_PREFIX . "login_lock SET
ip = '" . USER_IP . "',
date_orig = '".time()."',
date_expire = '$date_expire',
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# delete all login attempts for this account
# (to clean the slate after the account login lock expires)
$q = "DELETE FROM " . AGILE_DB_PREFIX . "login_log WHERE
ip = '" . USER_IP . "' AND
status = '0' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
# Create a block on this login
$result = $db->Execute(sqlInsert($db,'login_lock',array('ip'=>USER_IP,'date_orig'=>time(),'date_expire'=>$date_expire)));
}
}
}

View File

@@ -52,7 +52,8 @@ class CORE_method {
include_once($file);
if (class_exists($module) && method_exists($module,$method)) {
eval (sprintf('$%s = new %s();$%s->%s($VAR,$%s);',$module,$module,$module,$method,$module));
eval(sprintf('$%s = new %s(%s);$%s->%s($VAR,$%s);',
$module,$module,isset($VAR['id']) ? $VAR['id'] : 'null',$module,$method,$module));
} else {
$C_debug->alert($C_translate->translate('method_non_existant','core',''));
@@ -76,6 +77,13 @@ class CORE_method {
}
}
/**
* Execute a method that supports output for a template
*/
public function exetm($module,$method) {
return $this->exe($module,'tm'.$method);
}
/**
* Execute a modules method
*/
@@ -120,7 +128,8 @@ class CORE_method {
include_once($file);
if (class_exists($module) && method_exists($module,$method)) {
eval (sprintf('$%s = new %s();$%s->%s($VAR,$%s,$args);',$module,$module,$module,$method,$module));
eval(sprintf('$%s = new %s(%s);$%s->%s($VAR,$%s,$args);',
$module,$module,(isset($VAR['id']) ? $VAR['id'] : 'null'),$module,$method,$module));
global $smarty;

View File

@@ -61,7 +61,7 @@ class CORE_search {
),$this->id));
# Error reporting
if ($result === false) {
if (! $result) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
@@ -80,10 +80,10 @@ class CORE_search {
# Get the details for this search
$db = &DB();
$result = $db->Execute(sqlSelect($db,'search','*',sprintf('id=%s',$id)));
$result = $db->Execute(sqlSelect('search','*',array('where'=>array('id'=>$id))));
# Error reporting
if ($result === false) {
if (! $result) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
@@ -100,7 +100,7 @@ class CORE_search {
$this->limit = $result->fields['limit_no'];
# Check if this search has expired:
if($this->date_expire <= time()) {
if ($this->date_expire <= time()) {
# Refresh the search
# $this->results = $this->refresh($id);
# echo "<BR> this search has expired! Refreshing.... <BR>";
@@ -137,7 +137,7 @@ class CORE_search {
* @param int Contians the Search Id to be saved
* @param string Contains the name of the Module this search was for
*/
public function save($search_id,$module,$name) {
public function save($search_id,$module,$name) {
# Save the search
$db = &DB();
@@ -156,12 +156,12 @@ class CORE_search {
),$this->id));
# Error reporting
if ($result === false) {
if (! $result) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
}
}
}
/**
* Build the recent search menu and JavaScript

View File

@@ -1,416 +1,409 @@
<?php
/**
* AgileBill - Open Billing Software
*
* This body of work is free software; you can redistribute it and/or
* modify it under the terms of the Open AgileBill License
* License as published at http://www.agileco.com/agilebill/license1-4.txt
*
* For questions, help, comments, discussion, etc., please join the
* Agileco community forums at http://forum.agileco.com/
*
* Originally authored by Tony Landis, AgileBill LLC
*
* Recent modifications by Deon George
*
* @author Deon George <deonATleenooksDOTnet>
* @copyright 2009 Deon George
* @link http://osb.leenooks.net
*
* @link http://www.agileco.com/
* @copyright 2004-2008 Agileco, LLC.
* @license http://www.agileco.com/agilebill/license1-4.txt
* @author Tony Landis <tony@agileco.com>
* @author Tony Landis <tony@agileco.com>
* @package AgileBill
* @version 1.4.93
* @subpackage Core:Session
*/
class CORE_session
{
var $id;
function CORE_session()
{
global $C_debug, $_GET, $_POST,$_COOKIE, $HTTP_COOKIE_VARS, $VAR;
/**
* The main AgileBill Session Class
*
* @package AgileBill
* @subpackage Core:Session
*/
class CORE_session {
# Our session ID
private $id = '';
# The time our session expires
private $sess_date_expire = 0;
if (isset($_GET['s']))
$session_arr[] = $_GET['s'];
else if (isset($_POST['s']))
$session_arr[] = $_POST['s'];
else if(isset($_COOKIE[COOKIE_NAME]))
$session_arr[] = $_COOKIE[COOKIE_NAME];
else if (isset($HTTP_COOKIE_VARS[COOKIE_NAME]))
$session_arr[] = $HTTP_COOKIE_VARS[COOKIE_NAME];
public function __construct() {
global $C_debug,$VAR;
if(isset($session_arr)) {
for($i=0; $i<count($session_arr); $i++) {
if($session_arr[$i] != '') {
$validate = $this->validate($session_arr[$i]);
if($validate != FALSE) {
$this->id = $session_arr[$i];
$i = count($session_arr);
}
}
}
}
$session_arr = array();
@$this->sess_date_expire = time() + (SESSION_EXPIRE*60);
if(!isset($this->id))
{
empty($VAR['tid']) ? $this->sess_theme_id = DEFAULT_THEME : $this->sess_theme_id = $VAR['tid'];
empty($VAR['lid']) ? $this->sess_language_id = DEFAULT_LANGUAGE : $this->sess_language_id = $VAR['lid'];
empty($VAR['cid']) ? $this->sess_country_id = DEFAULT_COUNTRY : $this->sess_country_id = $VAR['cid'];
empty($VAR['cyid']) ? $this->sess_currency_id = DEFAULT_CURRENCY : $this->sess_currency_id = $this->get_currency($VAR['cyid']);
empty($VAR['wid']) ? $this->sess_weight_id = DEFAULT_WEIGHT : $this->sess_weight_id = $VAR['wid'];
@$this->sess_reseller_id = $VAR['rid'];
@$this->sess_affiliate_id = $this->get_affiliate(0);
@$this->sess_campaign_id = $this->get_campaign(0);
$this->sess_logged = false;
$this->sess_account_id = false;
$this->session();
# Get our SESSION ID, either as a GET/POST or COOKIE
if (isset($_GET['s']) && trim($_GET['s']))
array_push($session_arr,$_GET['s']);
elseif (isset($_POST['s']) && trim($_POST['s']))
array_push($session_arr,$_POST['s']);
elseif(isset($_COOKIE[COOKIE_NAME]) && trim($_COOKIE[COOKIE_NAME])) {
array_push($session_arr,$_COOKIE[COOKIE_NAME]);
# Clear the cookie, as we'll validate it
$this->id = $_COOKIE[COOKIE_NAME];
$this->setcookies(true);
$this->id = '';
}
else
{
empty($VAR['tid']) ? $this->sess_theme_id = $validate['theme_id'] : $this->sess_theme_id = $VAR['tid'];
empty($VAR['lid']) ? $this->sess_language_id = $validate['language_id'] : $this->sess_language_id = $VAR['lid'];
empty($VAR['cid']) ? $this->sess_country_id = $validate['country_id'] : $this->sess_country_id = $VAR['cid'];
empty($VAR['cyid']) ? $this->sess_currency_id = $validate['currency_id'] : $this->sess_currency_id = $this->get_currency($VAR['cyid']);
empty($VAR['wid']) ? $this->sess_weight_id = $validate['weight_id'] : $this->sess_weight_id = $VAR['wid'];
empty($VAR['rid']) ? $this->sess_reseller_id = $validate['reseller_id'] : $this->sess_reseller_id = $VAR['rid'];
empty($VAR['aid']) ? $this->sess_affiliate_id = $validate['affiliate_id'] : $this->sess_affiliate_id = $this->get_affiliate($validate['affiliate_id']);
empty($VAR['caid']) ? $this->sess_campaign_id = $validate['campaign_id'] : $this->sess_campaign_id = $this->get_campaign($validate['campaign_id']);
$this->sess_account_id = $validate['account_id'];
$this->sess_logged = $validate['logged'];
foreach ($session_arr as $s)
if ($validate = $this->validate($s))
$this->id = $s;
$this->sess_date_expire = time()+(SESSION_EXPIRE*60);
if (! $this->id) {
$this->tid = empty($VAR['tid']) ? DEFAULT_THEME : $VAR['tid'];
$this->lid = empty($VAR['lid']) ? DEFAULT_LANGUAGE : $VAR['lid'];
$this->cid = empty($VAR['cid']) ? DEFAULT_COUNTRY : $VAR['cid'];
$this->cyid = empty($VAR['cyid']) ? DEFAULT_CURRENCY : $this->get_currency($VAR['cyid']);
$this->wid = empty($VAR['wid']) ? DEFAULT_WEIGHT : $VAR['wid'];
$this->rid = empty($VAR['rid']) ? null : $VAR['rid'];
$this->aid = $this->get_session_link(0,'affiliate');
$this->caid = $this->get_session_link(0,'campaign');
$this->sess_logged = false;
$this->sess_account_id = false;
$this->session();
} else {
$this->tid = empty($VAR['tid']) ? $validate['theme_id'] : $VAR['tid'];
$this->lid = empty($VAR['lid']) ? $validate['language_id'] : $VAR['lid'];
$this->cid = empty($VAR['cid']) ? $validate['country_id'] : $VAR['cid'];
$this->cyid = empty($VAR['cyid']) ? $validate['currency_id'] : $this->get_currency($VAR['cyid']);
$this->wid = empty($VAR['wid']) ? $validate['weight_id'] : $VAR['wid'];
$this->rid = empty($VAR['rid']) ? $validate['reseller_id'] : $VAR['rid'];
$this->aid = empty($VAR['aid']) ? $validate['affiliate_id'] : $this->get_session_link($validate['affiliate_id'],'affiliate');
$this->caid = empty($VAR['caid']) ? $validate['campaign_id'] : $this->get_session_link($validate['campaign_id'],'campaign');
$this->sess_logged = $validate['logged'];
$this->sess_account_id = $validate['account_id'];
$db = &DB();
$q = "UPDATE " . AGILE_DB_PREFIX . "session SET
date_last = " . $db->qstr(time()) . ",
date_expire = " . $db->qstr($this->sess_date_expire) . ",
ip = " . $db->qstr(USER_IP) . ",
theme_id = " . $db->qstr($this->sess_theme_id) . ",
country_id = " . $db->qstr($this->sess_country_id) . ",
language_id = " . $db->qstr($this->sess_language_id) . ",
currency_id = " . $db->qstr($this->sess_currency_id) . ",
weight_id = " . $db->qstr($this->sess_weight_id) . ",
reseller_id = " . $db->qstr($this->sess_reseller_id) . ",
affiliate_id = " . $db->qstr($this->sess_affiliate_id). ",
campaign_id = " . $db->qstr($this->sess_campaign_id) . "
WHERE
id = " . $db->qstr($this->id) . "
AND
site_id = " . $db->qstr(DEFAULT_SITE);
// update the old session ONLY if info has changed or expires/no update in the past 5 minutes.
if (!empty($VAR['tid']) || !empty($VAR['lid']) || !empty($VAR['cid']) || !empty($VAR['cyid']) ||
!empty($VAR['wid']) || !empty($VAR['rid']) || !empty($VAR['aid']) || !empty($VAR['caid']) ) {
$result = $db->Execute($q);
} else if ($validate['logged'] == '0' && !empty($this->sess_date_expire) && $this->sess_date_expire+60*5 < time()) {
$result = $db->Execute($q);
} else if (!empty($validate['date_last']) && $validate['date_last']+60*5 < time()) {
$result = $db->Execute($q);
}
# Only update the session (every 5 mins) if we are logged in
if ($validate['logged'] && $this->sess_date_expire+60*5 < time())
$db->Execute(
sqlUpdate($db,'session',array(
'date_last'=>time(),
'date_expire'=>$this->sess_date_expire,
'ip'=>USER_IP,
'theme_id'=>$this->tid,
'country_id'=>$this->cid,
'language_id'=>$this->lid,
'currency_id'=>$this->cyid,
'weight_id'=>$this->wid,
'reseller_id'=>$this->rid,
'affiliate_id'=>$this->aid,
'campaign_id'=>$this->caid,
),array('id'=>$this->id)));
}
if(!defined("SESS")) define ('SESS', $this->id);
$this->setcookies();
if (! defined('SESS'))
define('SESS',$this->id);
$this->setcookies();
}
function validate($session_id) {
private function validate($session_id) {
global $C_debug;
$db = &DB();
$q = "SELECT
" . AGILE_DB_PREFIX . "session.*,
" . AGILE_DB_PREFIX . "account.id AS acct_id,
" . AGILE_DB_PREFIX . "account.status,
" . AGILE_DB_PREFIX . "account.date_expire AS account_date_expire,
" . AGILE_DB_PREFIX . "session_auth_cache.date_expire AS sess_auth_date_expire,
" . AGILE_DB_PREFIX . "session_auth_cache.group_arr,
" . AGILE_DB_PREFIX . "session_auth_cache.module_arr
FROM
" . AGILE_DB_PREFIX . "session
LEFT JOIN " . AGILE_DB_PREFIX . "account ON ".AGILE_DB_PREFIX."account.id = ".AGILE_DB_PREFIX."session.account_id
LEFT JOIN " . AGILE_DB_PREFIX . "session_auth_cache ON " . AGILE_DB_PREFIX . "session.id = " . AGILE_DB_PREFIX . "session_auth_cache.session_id
WHERE
" . AGILE_DB_PREFIX . "session.id = " . $db->qstr($session_id) . "
AND
" . AGILE_DB_PREFIX . "session.site_id = " . $db->qstr(DEFAULT_SITE) . "
AND ((
" . AGILE_DB_PREFIX . "account.site_id = " . $db->qstr(DEFAULT_SITE) . "
AND
" . AGILE_DB_PREFIX . "session.account_id IS NOT NULL
) OR (
" . AGILE_DB_PREFIX . "account.site_id IS NULL
AND
" . AGILE_DB_PREFIX . "session.account_id IS NULL
))
AND
" . AGILE_DB_PREFIX . "session_auth_cache.site_id = " . $db->qstr(DEFAULT_SITE);
$result = $db->Execute($q);
if ($result === false) {
$C_debug->error('session.inc.php','validate', $db->ErrorMsg());
echo '<BR>Unable to start session: Database Error: ' . $db->ErrorMsg();
return;
} else if ($result->RecordCount() == 0) {
return FALSE;
}
// Set the auth caching for use in the auth module to save a query there:
$this->auth_cache['date_expire'] = $result->fields["sess_auth_date_expire"];
$this->auth_cache['group_arr'] = $result->fields["group_arr"];
$this->auth_cache['module_arr'] = $result->fields["module_arr"];
$q = str_replace('{p}',AGILE_DB_PREFIX,str_replace('{s}',DEFAULT_SITE,sprintf(
'SELECT A.*,B.id AS acct_id,B.status,B.date_expire AS account_date_expire,C.date_expire AS sess_auth_date_expire,C.group_arr,C.module_arr
FROM {p}session AS A
LEFT JOIN {p}account AS B ON B.id=A.account_id LEFT JOIN {p}session_auth_cache AS C ON A.id=C.session_id
WHERE A.id=%s AND A.site_id={s} AND ((B.site_id={s} AND A.account_id IS NOT NULL) OR (B.site_id IS NULL AND A.account_id IS NULL)) AND C.site_id={s}',$db->qstr($session_id)
)));
if($result->fields['id'] == $session_id) {
if($result->fields["logged"] == "1") {
if($result->fields['status'] != "1") {
return FALSE;
} else if(!empty($result->fields['account_date_expire']) && $result->fields['account_date_expire'] < time()) {
return FALSE;
} else if(SESSION_EXPIRE != 0 && $result->fields['date_expire'] <= time()) {
$this->logout($session_id);
return FALSE;
}
}
$rs = $db->Execute($q);
if (! $rs) {
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
printf('Unable to start session: Database Error: %s',$db->ErrorMsg());
if(SESSION_IP_MATCH) {
if($result->fields['ip'] != USER_IP) {
$this->delete($session_id);
return FALSE;
}
}
return false;
} else {
return FALSE;
} elseif ($rs->RecordCount() == 0) {
return false;
}
return $result->fields;
# Set the auth caching for use in the auth module to save a query there:
$this->auth_cache['date_expire'] = $rs->fields['sess_auth_date_expire'];
$this->auth_cache['group_arr'] = $rs->fields['group_arr'];
$this->auth_cache['module_arr'] = $rs->fields['module_arr'];
if ($rs->fields['logged'] == 1) {
if ($rs->fields['status'] != 1)
return false;
elseif (! empty($rs->fields['account_date_expire']) && $rs->fields['account_date_expire'] < time())
return false;
elseif (SESSION_EXPIRE != 0 && $rs->fields['date_expire'] <= time()) {
$this->logout($session_id);
return false;
}
}
if (SESSION_IP_MATCH && ($rs->fields['ip'] != USER_IP)) {
$this->delete($session_id);
return false;
}
return $rs->fields;
}
function setcookies() {
if(defined("AGILE_COOKIE") && AGILE_COOKIE != '') {
/**
* Set or expire cookies
*/
private function setcookies($expire=false) {
if (defined('AGILE_COOKIE') && AGILE_COOKIE != '') {
$domain = AGILE_COOKIE;
} else {
global $_SERVER;
if(isset($_SERVER)) {
@$domain = $_SERVER['HTTP_HOST'];
} else {
$server = getallheaders();
$domain = $server['Host'];
}
$domain = '.'.preg_replace('/^www./', '', $domain);
}
if(COOKIE_EXPIRE == 0 )
$cookie_expire = (time() + 86400*365);
} else {
global $_SERVER;
if (isset($_SERVER['HTTP_HOST'])) {
$domain = $_SERVER['HTTP_HOST'];
} elseif (isset($_SERVER['SERVER_NAME'])) {
$domain = $_SERVER['SERVER_NAME'];
} elseif (function_exists('getallheaders')) {
$server = getallheaders();
$domain = $server['Host'];
} else {
echo '<PRE>';print_r($_SERVER);echo '</PRE>';
echo 'ERROR: Cant work out our domain?';
die();
}
$domain = '.'.preg_replace('/^www./','',$domain);
}
if ($expire)
$cookie_expire = 0;
elseif (COOKIE_EXPIRE == 0)
$cookie_expire = (time()+86400*365);
else
$cookie_expire = (time() + (COOKIE_EXPIRE*60));
if(empty($domain) || preg_match('/localhost/', $domain))
setcookie(COOKIE_NAME,$this->id,$cookie_expire,'/');
$cookie_expire = (time()+(COOKIE_EXPIRE*60));
if (empty($domain) || preg_match('/localhost/',$domain))
setcookie(COOKIE_NAME,$this->id,$cookie_expire,'/');
else
setcookie(COOKIE_NAME,$this->id,$cookie_expire,'/', $domain);
setcookie(COOKIE_NAME,$this->id,$cookie_expire,'/',$domain);
# Affiliate Cookie
if(!empty($this->sess_affiliate_id)) {
$aid_expire = time()+86400*720;
$aid_cookie_name = COOKIE_NAME . 'aid';
if(empty($domain) || eregi('localhost', $domain))
setcookie($aid_cookie_name, $this->sess_affiliate_id, $aid_expire,'/');
if (! empty($this->aid)) {
$aid_cookie_name = COOKIE_NAME.'aid';
if ($expire)
$aid_expire = 0;
else
setcookie($aid_cookie_name, $this->sess_affiliate_id, $aid_expire,'/', $domain);
$aid_expire = time()+86400*720;
if (empty($domain) || preg_match('/localhost/',$domain))
setcookie($aid_cookie_name,$this->aid,$aid_expire,'/');
else
setcookie($aid_cookie_name,$this->aid,$aid_expire,'/',$domain);
}
# Campaign Cookie
if(!empty($this->sess_campaign_id)) {
$cid_expire = time()+86400*720;
$cid_cookie_name = COOKIE_NAME . 'caid';
if(empty($domain) || eregi('localhost', $domain))
setcookie($cid_cookie_name, $this->sess_campaign_id, $cid_expire,'/');
if (! empty($this->caid)) {
$cid_cookie_name = COOKIE_NAME.'caid';
if ($expire)
$cid_expire = 0;
else
setcookie($cid_cookie_name, $this->sess_campaign_id, $cid_expire,'/', $domain);
$cid_expire = time()+86400*720;
if (empty($domain) || preg_match('/localhost/',$domain))
setcookie($cid_cookie_name,$this->caid,$cid_expire,'/');
else
setcookie($cid_cookie_name,$this->caid,$cid_expire,'/',$domain);
}
}
private function get_session_link($id,$type) {
global $VAR;
function get_affiliate($old_aid) {
global $_COOKIE, $VAR;
$aid_cookie_name = COOKIE_NAME.'aid';
if(isset($VAR['aid']))
$aid = $VAR['aid'];
else if(isset($_COOKIE[$aid_cookie_name]))
@$aid = $_COOKIE[$aid_cookie_name];
else if(isset($HTTP_COOKIE_VARS[$aid_cookie_name]))
@$aid = $HTTP_COOKIE_VARS[$aid_cookie_name];
if ($aid == $old_aid) {
return $aid;
} else if (empty($aid)) {
switch($type) {
case 'affiliate' : $var = 'aid'; $table = 'affiliate'; break;
case 'campaign' : $var = 'caid'; $table = 'campaign'; break;
default:
return '';
}
$cookie_name = sprintf('%s%s',COOKIE_NAME,$var);
if (isset($VAR[$var]))
$i = $VAR[$var];
elseif (isset($_COOKIE[$cookie_name]))
$i = $_COOKIE[$cookie_name];
if (empty($i))
return '';
} else {
// validate
elseif ($i == $id)
return $i;
# Validate
else {
$db = &DB();
$q = "SELECT id,account_id FROM " . AGILE_DB_PREFIX . "affiliate
WHERE id = ".$db->qstr($aid)." AND
site_id = ".$db->qstr(DEFAULT_SITE);
@$result = $db->Execute($q);
if(@$result->fields['id'] == $aid)
return $aid;
$rs = $db->Execute(sqlSelect($table,'id',array('where'=>array('id'=>$i))));
if ($rs && $rs->RecordCount())
return $i;
else
return '';
return '';
}
}
function get_campaign($old_cid) {
global $_COOKIE, $VAR;
$cid_cookie_name = COOKIE_NAME.'caid';
if(isset($VAR['caid']))
$cid = $VAR['caid'];
else if(isset($_COOKIE[$cid_cookie_name]))
@$cid = $_COOKIE[$cid_cookie_name];
else if(isset($HTTP_COOKIE_VARS[$cid_cookie_name]))
@$cid = $HTTP_COOKIE_VARS[$cid_cookie_name];
if ($cid == $old_cid) {
return $cid;
} else if (empty($cid)) {
return '';
} else {
// validate
$db = &DB();
$q = "SELECT id FROM " . AGILE_DB_PREFIX . "campaign
WHERE id = ".$db->qstr($cid)." AND
site_id = ".$db->qstr(DEFAULT_SITE);
@$result = $db->Execute($q);
if(@$result->fields['id'] == $cid)
return $cid;
else
return '';
}
}
function get_currency($id) {
$db = &DB();
$sql = 'SELECT * FROM ' . AGILE_DB_PREFIX . 'currency WHERE id = ' . $db->qstr($id) . ' AND site_id = ' . $db->qstr(DEFAULT_SITE);
$result = $db->Execute($sql);
if($result->fields['status'] == 1) return $id;
global $VAR; $VAR['cyid'] = DEFAULT_CURRENCY;
return DEFAULT_CURRENCY;
}
function session() {
global $C_debug;
mt_srand ((double) microtime() * 1000000);
$this->id = md5(uniqid(mt_rand(),1));
private function get_currency($id) {
$db = &DB();
$q = "SELECT id FROM " . AGILE_DB_PREFIX . "session
WHERE id = ".$db->qstr($this->id)." AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
if ($result === false) {
echo "SESSION FAILED: Unable to connect to database";
$rs = $db->Execute(sqlSelect('currency','status',array('where'=>array('id'=>$id))));
if ($rs && $rs->RecordCount() && $rs->fields['status'] == 1)
return $id;
global $VAR;
$VAR['cyid'] = DEFAULT_CURRENCY;
return DEFAULT_CURRENCY;
}
/**
* Create a session
*/
private function session() {
global $C_debug;
$db = &DB();
mt_srand((double)microtime()*1000000);
$this->id = md5(uniqid(mt_rand(),1));
$rs = $db->Execute(sqlSelect('session','id',array('where'=>array('id'=>$this->id))));
if (! $rs) {
echo 'SESSION FAILED: Unable to connect to database';
exit;
} if($result->RecordCount() == 0) {
$expires = time() + (SESSION_EXPIRE*60);
$db = &DB();
$q = "INSERT INTO " . AGILE_DB_PREFIX . "session SET
id = ".$db->qstr($this->id).",
date_orig = ".$db->qstr(time()).",
date_last = ".$db->qstr(time()).",
date_expire = ".$db->qstr($expires).",
logged = ".$db->qstr('0').",
ip = ".$db->qstr(USER_IP).",
site_id = ".$db->qstr(DEFAULT_SITE).",
affiliate_id= ".$db->qstr($this->sess_affiliate_id).",
reseller_id = ".$db->qstr($this->sess_reseller_id).",
country_id = ".$db->qstr($this->sess_country_id).",
language_id = ".$db->qstr($this->sess_language_id).",
currency_id = ".$db->qstr($this->sess_currency_id).",
weight_id = ".$db->qstr($this->sess_weight_id).",
theme_id = ".$db->qstr($this->sess_theme_id).",
campaign_id = ".$db->qstr($this->sess_campaign_id);
$result = $db->Execute($q);
if ($result === false) {
$C_debug->error('session.inc.php','validate', $db->ErrorMsg());
echo 'Unable to start session: Db error<RB><BR>' . $q . '<BR><BR>' . $db->ErrorMsg();
}
if (! $rs->RecordCount()) {
$rs = $db->Execute(
sqlInsert($db,'session',array(
'date_orig'=>time(),
'date_last'=>time(),
'date_expire'=>$this->sess_date_expire,
'affiliate_id'=>$this->aid,
'reseller_id'=>$this->rid,
'country_id'=>$this->cid,
'language_id'=>$this->lid,
'currency_id'=>$this->cyid,
'weight_id'=>$this->wid,
'theme_id'=>$this->tid,
'campaign_id'=>$this->caid,
'logged'=>0,
'ip'=>USER_IP
),$this->id));
if (! $rs) {
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
printf('Unable to start session: Db error<br/><br/>%s<br/><br/>%s',$q,$db->ErrorMsg());
exit;
}
}
}
function logout($sess) {
private function logout($sess) {
$db = &DB();
$q = "UPDATE " . AGILE_DB_PREFIX . "session SET logged = '0' WHERE
id = '$sess' AND
site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
if ($result === false) {
$rs = $db->Execute(sqlUpdate($db,'session',array('logged'=>0),array('id'=>$sess)));
if (! $rs) {
global $C_debug;
$C_debug->error('session.inc.php','logout', $db->ErrorMsg());
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
}
$q = 'DELETE FROM '.AGILE_DB_PREFIX.'session_auth_cache WHERE
session_id = '. $db->qstr($sess) .' AND
site_id = '. $db->qstr(DEFAULT_SITE);
$db->Execute($q);
$db->Execute(sqlDelete($db,'session_auth_cache',array('session_id'=>$sess)));
define('FORCE_SESS_ACCOUNT', 0);
define('FORCE_SESS_LOGGED', FALSE);
define('FORCE_SESS_ACCOUNT',0);
define('FORCE_SESS_LOGGED',false);
if (CACHE_SESSIONS == '1') {
$VAR['_login'] = '1';
$force = true;
$C_auth = new CORE_auth($force);
if(CACHE_SESSIONS == '1') {
$VAR['_login'] = '1';
$force = true;
$C_auth = new CORE_auth($force);
global $C_auth2;
$C_auth2 = $C_auth;
}
$C_auth2 = $C_auth;
}
}
function delete($sess) {
global $C_debug;
/**
* Delete a session
*/
private function delete($sess) {
$db = &DB();
$q = "DELETE FROM " . AGILE_DB_PREFIX . "session WHERE id = '$sess' AND site_id = '" . DEFAULT_SITE . "'";
$result = $db->Execute($q);
if ($result === false) $C_debug->error('session.inc.php','delete', $db->ErrorMsg());
}
function session_constant() {
# Define the constants
define ('SESS_THEME', $this->sess_theme_id);
define ('SESS_COUNTRY', $this->sess_country_id);
define ('SESS_LANGUAGE', $this->sess_language_id);
define ('SESS_CURRENCY', $this->sess_currency_id);
define ('SESS_WEIGHT', $this->sess_weight_id);
define ('SESS_RESELLER', $this->sess_reseller_id);
define ('SESS_AFFILIATE', $this->sess_affiliate_id);
define ('SESS_CAMPAIGN', $this->sess_campaign_id);
}
function session_constant_log() {
global $VAR;
if(isset($VAR['_login']) || isset($VAR['_logout'])) {
$db = &DB();
$q = "SELECT logged,account_id FROM " . AGILE_DB_PREFIX . "session
WHERE id = " . $db->qstr($this->id) . "
AND site_id = " . $db->qstr(DEFAULT_SITE);
$result = $db->Execute($q);
$rs = $db->Execute(sqlDelete($db,'session',array('id'=>$sess)));
if (! $rs === false) {
global $C_debug;
if ($result === false) $C_debug->error('session.inc.php','session_constant', $db->ErrorMsg());
if(!defined("SESS_LOGGED"))
define ('SESS_LOGGED', $result->fields['logged']);
if(!defined("SESS_ACCOUNT"))
define ('SESS_ACCOUNT', $result->fields['account_id']);
} else {
if(!defined("SESS_LOGGED"))
define ('SESS_LOGGED', $this->sess_logged);
if(!defined("SESS_ACCOUNT"))
define ('SESS_ACCOUNT', $this->sess_account_id);
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return false;
}
}
/**
* Define the session constants
*/
public function session_constant() {
# Define the constants
define('SESS_THEME',$this->tid);
define('SESS_LANGUAGE',$this->lid);
define('SESS_COUNTRY',$this->cid);
define('SESS_CURRENCY',$this->cyid);
define('SESS_WEIGHT',$this->wid);
define('SESS_RESELLER',$this->rid);
define('SESS_AFFILIATE',$this->aid);
define('SESS_CAMPAIGN',$this->caid);
}
public function session_constant_log() {
global $VAR;
if (isset($VAR['_login']) || isset($VAR['_logout'])) {
$db = &DB();
$rs = $db->Execute(sqlSelect('session','logged,account_id',array('where'=>array('id'=>$this->id))));
if (! $rs) {
global $C_debug;
$C_debug->error(__FILE__,__METHOD__,$db->ErrorMsg());
return;
}
if (! defined('SESS_LOGGED'))
define('SESS_LOGGED',$rs->fields['logged']);
if (! defined('SESS_ACCOUNT'))
define('SESS_ACCOUNT',$rs->fields['account_id']);
} else {
if (! defined('SESS_LOGGED'))
define('SESS_LOGGED',$this->sess_logged);
if (! defined('SESS_ACCOUNT'))
define('SESS_ACCOUNT',$this->sess_account_id);
}
if(SESS_LOGGED)
define ('SESS_EXPIRES', $this->sess_date_expire);
if (SESS_LOGGED)
define('SESS_EXPIRES',$this->sess_date_expire);
else
define ('SESS_EXPIRES', 0);
}
define('SESS_EXPIRES',0);
}
}
?>

View File

@@ -113,7 +113,7 @@ class CORE_setup {
define('GRACE_PERIOD', $fields['grace_period']);
define('MAX_BILLING_NOTICE', $fields['max_billing_notice']);
error_reporting(ERROR_REPORTING);
eval('error_reporting('.ERROR_REPORTING.');');
}
private function get_setup() {

View File

@@ -329,13 +329,13 @@ class CORE_static_var
{
### BOOLEAN TRUE/FALSE
$C_list = new CORE_list;
$this_html = $C_list->bool_static_var($static_relation, $static_value, $css_menu);
$this_html = $C_list->bool($static_relation, $static_value, $css_menu);
}
elseif($display == 'search')
{
### BOOLEAN TRUE/FALSE
$C_list = new CORE_list;
$this_html = $C_list->bool_static_var($static_relation, 'all', $css_menu);
$this_html = $C_list->bool($static_relation, 'all', $css_menu);
}
else
{
@@ -358,7 +358,7 @@ class CORE_static_var
{
### BOOLEAN TRUE/FALSE
$C_list = new CORE_list;
$this_html = $C_list->bool_static_var($static_relation, 'all', $css_menu);
$this_html = $C_list->bool($static_relation, 'all', $css_menu);
}
else
{
@@ -677,7 +677,7 @@ class CORE_static_var
{
### BOOLEAN TRUE/FALSE
$C_list = new CORE_list;
$this_html = $C_list->bool_static_var($static_relation, $static_value, $css_menu);
$this_html = $C_list->bool($static_relation, $static_value, $css_menu);
}
else
{
@@ -935,7 +935,7 @@ class CORE_static_var
{
### BOOLEAN TRUE/FALSE
$C_list = new CORE_list;
$this_html = $C_list->bool_static_var($static_relation, $static_value, $css_menu);
$this_html = $C_list->bool($static_relation, $static_value, $css_menu);
}
else if ( $static_value != '' )
{

View File

@@ -48,7 +48,7 @@ class CORE_translate {
function get_lang_pack($module, $language) {
# define the language names / ids (must match the language.name & language.id fields in the DB
$this->lang_arr[0] = 'english';
$this->lang_arr[0] = 'en';
# get the Core language pack
if($module=='CORE') {
@@ -132,6 +132,10 @@ class CORE_translate {
$language = DEFAULT_LANGUAGE;
}
#@todo TEMP
if ($language == 'en')
$language = 'english';
if(empty($module)) $module = 'CORE';
if(!empty($resource)) {

View File

@@ -315,7 +315,7 @@ class CORE_validate {
}
public function validate_email($data,$field) {
if (preg_match('/^[a-z0-9\._-]+@+[a-z0-9\._-]+\.+[a-z]{2,4}$/',$data)) {
if (preg_match('/^[a-zA-Z0-9\._-]+@+[a-z0-9\._-]+\.+[a-z]{2,4}$/',$data)) {
return true;
} else {

View File

@@ -52,8 +52,8 @@ class CORE_vars
// mods for hardcoded vars in config/multi-site
global $hardcode;
if(is_array($hardcode)) {
foreach($hardcode as $hc) {
$this->f["{$hc[0]}"] = $hc[1];
foreach($hardcode as $hc => $value) {
$this->f[$hc] = $value;
}
}
}

View File

@@ -0,0 +1,21 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides Country routines
*
* @package OSB
* @subpackage Cart
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Country {
public static function icon($cid) {
// @todo alt character should be country specific
// @todo This doesnt correctly get the right 3 character country code - it should be obtained from a join with country/currency
return HTML::image(sprintf('media/img/country/%s.gif',StaticList_Module::record('country','two_code','id',$cid)),array('alt'=>'$','style'=>'border: 0px;'));
return sprintf('media/img/country/%s.gif',StaticList_Module::record('country','three_code','id',$cid));
}
}
?>

Binary file not shown.

After

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Some files were not shown because too many files have changed in this diff Show More