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

705 lines
20 KiB
PHP

<?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 Module:Cart
*/
/**
* The main AgileBill Module Cart Class
*
* @package AgileBill
* @subpackage Module:Cart
*/
class cart extends OSB_module {
/**
* Admin View Cart Contents
*/
function admin_view($VAR) {
if(!empty($VAR['account_id'])) {
$this->account_id = $VAR['account_id'];
} else {
return false;
}
$this->admin_view = true;
$this->user_view($VAR,$this);
}
/**
* Admin Add Cart Contents
*/
function admin_add($VAR) {
if(!empty($VAR['account_id'])) {
$this->account_id = $VAR['account_id'];
$db = &DB();
$rs = $db->Execute(sqlSelect($db,"session","id","account_id=$this->account_id"));
if($rs && $rs->RecordCount()) {
$this->session_id = $rs->fields['id'];
} else {
$this->session_id = SESS;
}
} else {
return false;
}
$this->add($VAR,$this);
}
/**
* Admin change cart qty
*/
function admin_changeqty($VAR) {
if(!empty($VAR['account_id'])) {
$this->account_id = $VAR['account_id'];
} else {
return false;
}
$this->admin = true;
$this->changeqty($VAR,$this);
}
/**
* Change the quantity of an item
*/
function changeqty($VAR) {
if(empty($this->account_id)) $this->account_id = SESS_ACCOUNT;
if(empty($this->session_id)) $this->session_id = SESS;
@$id = $VAR['id'];
@$qty = $VAR['qty'];
if ($id <= 0 ) return;
$db = &DB();
if ($qty == '0') {
# Product Plugin Level deletion
$cartid = & $db->Execute($sql=sqlSelect($db,"cart","*","id=::{$id}:: AND session_id = ::{$this->session_id}::"));
if($cartid) $product = & $db->Execute($sql=sqlSelect($db,"product","*","id=::{$cartid->fields['product_id']}::"));
if(!empty($product->fields['prod_plugin']) && !empty($product->fields['prod_plugin_data'])) {
$prodplgfile = PATH_PLUGINS.'product/'. $product->fields['prod_plugin_file'] . '.php';
if(is_file($prodplgfile)) {
include_once(PATH_PLUGINS.'product/'. $product->fields['prod_plugin_file'] . '.php');
eval('$prodplg = new plgn_prov_'. $product->fields['prod_plugin_file'] .';');
if(is_object($prodplg)) {
if(is_callable(array($prodplg,'delete_cart'))) {
$prodplg->delete_cart($VAR,$cartid->fields);
}
}
}
}
# delete main cart items & subitems:
$sql='';
if(empty($this->admin)) $sql = "AND session_id = ::{$this->session_id}::";
$rs = & $db->Execute($sql=sqlDelete($db,"cart","(id=::{$id}:: OR cart_parent_id=::{$id}:: ) $sql"));
global $smarty;
$smarty->assign('js',false);
return false;
}
# update the quantity:
if(!eregi("^[0-9]{1,5}$",$qty)) $qty = 1;
if($qty < 1) $qty = 1;
if(!$this->admin) $sql_extra = " AND session_id=::$this->session_id::"; else $sql_extra='';
if($VAR["type"] == 1) {
$fields=Array('quantity'=>$qty);
$db->Execute($sql=sqlUpdate($db,"cart",$fields,"id=::$id:: $sql_extra"));
} else if ($VAR["type"] == 2) {
$fields=Array('recurr_schedule'=>$VAR["schedule"]);
$db->Execute($sql=sqlUpdate($db,"cart",$fields,"id=::$id:: $sql_extra"));
} else if ($VAR["type"] == 3) {
# change domain term
$fields=Array('domain_term'=>$VAR["term"]);
$db->Execute($sql=sqlUpdate($db,"cart",$fields,"id=::$id:: $sql_extra"));
}
# get the product id:
$result = $db->Execute(sqlSelect($db,"cart","*","id=$id $sql_extra","cart_type,date_orig"));
# get the product details:
$product = $db->Execute(sqlSelect($db,"product","*","id={$result->fields["product_id"]}"));
if($result->fields["cart_type"] == "2") {
# domain name, get pricing
include_once(PATH_MODULES.'host_tld/host_tld.inc.php');
$tldObj=new host_tld;
$tldprice = $tldObj->price_tld_arr($result->fields['domain_tld'],$result->fields['host_type'],false,false,false,$this->account_id);
$qty = $result->fields['domain_term'];
$base_price = $tldprice[$qty];
$setup_price = 0;
} else if($result->fields["cart_type"] == "3") {
# ad-hoc, get price
$base_price = $result->fields["ad_hoc_amount"] * $result->fields["quantity"];
$setup_price = $result->fields["ad_hoc_setup"] * $result->fields["quantity"];
} else {
include_once(PATH_MODULES.'product/product.inc.php');
$productObj=new product;
# get pricing for this product:
$prod_price = $productObj->price_prod($product->fields,$result->fields["recurr_schedule"],$this->account);
$setup_price = $prod_price["setup"] * $result->fields["quantity"];
$base_price = $prod_price["base"] * $result->fields["quantity"];
# get pricing for any attributes:
$attr_price = $productObj->price_attr($product->fields,$result->fields["product_attr"],$result->fields["recurr_schedule"],$this->account);
$setup_price += ($attr_price["setup"] * $result->fields["quantity"]);
$base_price += ($attr_price["base"] * $result->fields["quantity"]);
# get the qty
$qty = $result->fields["quantity"];
}
# set the smarty fields:
global $smarty;
$smarty->assign('qty',$qty);
$smarty->assign('base',$base_price);
$smarty->assign('setup',$setup_price);
$smarty->assign('js',true);
return;
}
/**
* Get cart contents and return adodb rs
*/
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
if (! count($results = $this->sGetContents())) {
$smarty->assign('result','0');
return false;
}
include_once(PATH_MODULES.'invoice/invoice.inc.php');
$invoice = new invoice;
$invoice->setRecordAttr('account_id',SESS_ACCOUNT);
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());
}
/**
* Start add to cart process
*/
public function add($VAR) {
# Set the current account
if (empty($this->account_id))
$this->account_id = SESS_ACCOUNT;
if (empty($this->session_id))
$this->session_id = SESS;
# Determine the type to be added to the domain: (domain or product)
if (! empty($VAR['product_id'])) {
if ($this->validate_product($VAR,$VAR['product_id'],$this->account_id)) {
# Add hosting / domain
if (! empty($VAR['domain_type']))
$this->product_add_host($VAR);
# Standard product (no hosting or domain)
else
$this->product_add($VAR);
return true;
}
} elseif (! empty($VAR['domain_name']) && ! empty($VAR['domain_tld'])) {
# Add Domain only:
# @todo Remove the is_array test, and have 1 set of code
if (is_array($VAR['domain_name'])) {
for ($i=0;$i<count($VAR['domain_name']); $i++) {
if($this->validate_domain($VAR['domain_name'][$i],$VAR['domain_tld'][$i])) {
$this->domain_add($VAR['domain_name'][$i],$VAR['domain_tld'][$i],@$VAR['host_type'][$i],@$VAR['domain_term'][$i]);
}
}
} else {
if($this->validate_domain($VAR['domain_name'],$VAR['domain_tld'])) {
$this->domain_add($VAR['domain_name'],$VAR['domain_tld'],@$VAR['host_type'],@$VAR['domain_term']);
}
}
}
}
/**
* Add a domain name to cart
*
* @param string $domain
* @param string $tld
* @param int $type
* @param int $term
*/
private function domain_add($domain,$tld,$type,$term=false) {
if (empty($type))
return false;
$db = &DB();
if (! $term || empty($term) || ! is_numeric($term)) {
# Get the default term for this domain:
$rs = $db->Execute(sqlSelect($db,'host_tld','default_term_new',array('name'=>$tld)));
if ($rs === false || empty($rs->fields['default_term_new']))
$term = 1;
else
$term = $rs->fields['default_term_new'];
}
# Insert into cart
$fields =array(
'date_orig' => time(),
'session_id' => $this->session_id,
'account_id' => $this->account_id,
'cart_type' => 2,
'host_type' => $type,
'domain_term' => $term,
'domain_name' => $domain,
'domain_tld' => $tld);
$db->Execute(sqlInsert($db,'cart',$fields));
}
/**
* Add an ad-hoc line item to the cart
*/
public function ad_hoc($VAR) {
$db = &DB();
if (! empty($VAR['account_id'])) {
$rs = $db->Execute(sqlSelect($db,'session','id',array('account_id'=>$VAR['account_id'])));
if ($rs && $rs->RecordCount() ==1)
$this->session_id = $rs->fields['id'];
else
$this->session_id = SESS;
} else {
return false;
}
if (empty($VAR['ad_hoc_sku']) || empty($VAR['ad_hoc_name']) || $VAR['ad_hoc_amount'] == '') {
global $C_debug,$C_translate;
$C_debug->alert($C_translate->translate('ad_hoc_err','cart',''));
return false;
}
if (empty($VAR['quantity']))
$qty = 1;
else
$qty = $VAR['quantity'];
if (empty($VAR['ad_hoc_taxable']))
$VAR['ad_hoc_taxable'] = 0;
# Attribs: (ad_hoc_attr_var & ad_hoc_attr_val)
foreach ($VAR['ad_hoc_attr_var'] as $key => $value)
if ($value && $VAR['ad_hoc_attr_val'][$key])
$attr[$value] = $VAR['ad_hoc_attr_val'][$key];
if (count($attr))
$attrib = serialize($attr);
else
$attrib = '';
# Create the record
$fields = array(
'date_orig' => time(),
'session_id' => $this->session_id,
'account_id' => $VAR['account_id'],
'product_attr' => $attrib,
'cart_type' => 3,
'quantity' => $qty,
'ad_hoc_sku' => $VAR['ad_hoc_sku'],
'ad_hoc_name' => $VAR['ad_hoc_name'],
'ad_hoc_amount' => $VAR['ad_hoc_amount'],
'ad_hoc_taxable' => $VAR['ad_hoc_taxable']);
$db->Execute(sqlInsert($db,'cart',$fields));
}
/**
* Add a product to the cart
*/
private function product_add($VAR) {
if (empty($VAR['quantity']))
$qty = 1;
else
$qty = $VAR['quantity'];
if (!empty($VAR['attr']))
@$attr = serialize($VAR['attr']);
else
$attr = '';
# Create the Main DB Record:
$db = &DB();
$fields = array(
'date_orig' => time(),
'session_id' => $this->session_id,
'account_id' => @$VAR['account_id'],
'product_attr' => $attr,
'cart_type' => 0,
'quantity' => $qty,
'product_id' => $VAR['product_id'],
'recurr_schedule' => @$VAR['recurr_schedule'],
'service_id' => @$VAR['service_id']);
$db->Execute(sqlInsert($db,'cart',$fields));
}
/**
* Add an assoc required product
*
* @param int $product_id
* @todo Unused, calling code is commented out.
*/
private function product_req_add($product_id) {
$db = &DB();
$fields = array(
'date_orig' => time(),
'session_id' => $this->session_id,
'account_id' => $this->account_id,
'cart_type' => 0,
'quantity' => 1,
'product_id' => $product_id);
$db->Execute(sqlInsert($db,'cart',$fields));
}
/**
* Add a product to the cart
*/
private function product_add_host($VAR) {
if (! empty($VAR['attr']))
@$attr = serialize($VAR['attr']);
else
$attr = serialize(array(''));
$db = &DB();
$fields = array(
'date_orig' => time(),
'session_id' => $this->session_id,
'account_id' => @$VAR['account_id'],
'product_attr' => $attr,
'cart_type' => 1,
'quantity' => 1,
'product_id' => $VAR['product_id'],
'recurr_schedule' => @$VAR['recurr_schedule'],
'service_id' => @$VAR['service_id'],
'host_type' => $VAR['domain_type'],
'domain_name' => $VAR['domain_name'],
'domain_tld' => $VAR['domain_tld']);
$id = sqlGenID($db,'cart');
$db->Execute(sqlInsert($db,'cart',$fields,$id));
# Get the default domain registration length:
if ($VAR['domain_type'] == 'transfer' || $VAR['domain_type'] == 'register') {
$domain_term = 1;
$result = $db->Execute(sqlSelect($db,'host_tld','default_term_new',array('name'=>$VAR['domain_tld'])));
if ($result && ! empty($result->fields['default_term_new']))
$domain_term = $result->fields['default_term_new'];
# Add child domain if register or transfer
$fields = array(
'date_orig' => time(),
'session_id' => $this->session_id,
'account_id' => @$VAR['account_id'],
'product_attr' => $attr,
'cart_type' => 2,
'quantity' => 1,
'host_type' => $VAR['domain_type'],
'domain_name' => $VAR['domain_name'],
'domain_tld' => $VAR['domain_tld'],
'domain_term' => $domain_term,
'cart_parent_id' => $id);
$db->Execute(sqlInsert($db,'cart',$fields));
}
}
/**
* Validate A Domain
*
* @param string $domain
* @param string $tld
* @return bool
*/
private function validate_domain($domain,$tld) {
# Check that it is not already in the user's cart:
$db = &DB();
$result = $db->Execute(sqlSelect($db,'cart','id',sprintf("(session_id=::%s:: OR account_id=) AND domain_name=:: AND domain_tld=::%s::",
$this->session_id,SESS_ACCOUNT,$tld)));
if ($result && $result->RecordCount()) {
global $C_debug,$C_translate;
$C_debug->alert($C_translate->translate('err_prod_already','cart',''));
return false;
} else {
return true;
}
}
/**
* Validate A Product
*
* @param array $VAR
* @param int $product_id
* @param int $account_id
* @return bool
*/
private function validate_product($VAR,$product_id,$account_id) {
global $C_translate,$C_debug,$C_auth;
$db = &DB();
# Can user add inactive items
if ($C_auth->auth_method_by_name('invoice','add'))
$active = array();
else
$active = array('active'=>1);
# Validate that product exists
$result = $db->Execute(sqlSelect($db,'product','*',array_merge(array('id'=>$product_id),$active)));
if (! $result || $result->RecordCount() == 0) {
$C_debug->alert($C_translate->translate('err_no_prod','cart',''));
return false;
}
# Check that product is not already in cart
if ($result->fields['cart_multiple'] != '1' && empty($VAR['service_id'])) {
$rs = $db->Execute(sqlSelect($db,'cart','id',array('product_id'=>$product_id,'session_id'=>$this->session_id)));
if(! $rs || $rs->RecordCount() > 0) {
$C_debug->alert($C_translate->translate('err_prod_already','cart',''));
return false;
}
}
# Validate groups:
$groups = unserialize($result->fields['group_avail']);
$auth = false;
for ($ii=0; $ii<count($groups); $ii++) {
if ($C_auth->auth_group_by_id($groups[$ii])) {
$auth = true;
break;
}
}
if (! $auth)
return false;
# Validate any required products:
if (! empty($result->fields['assoc_req_prod']))
$reqarr = unserialize($result->fields["assoc_req_prod"]);
else
$reqarr = false;
$reqtype = $result->fields['assoc_req_prod_type'];
$assoc = true;
if (is_array($reqarr) && ! empty($reqarr[0])) {
/*
if($reqtype == 0 && is_array($reqarr)) {
# ALL are required
for($i=0; $i<count($reqarr); $i++)
if(!$this->assoc_prod($reqarr[$i])) {
$assoc = false;
# Add the required product:
$this->product_req_add($reqarr[$i]);
}
} elseif ($reqtype == 1 && is_array($reqarr)) {
# ONE is required
$assoc = false;
for($i=0; $i<count($reqarr); $i++) {
if($this->assoc_prod($reqarr[$i])) {
$assoc = true;
$i = count( $reqarr );
} else {
# add the required product:
$this->product_req_add($reqarr[$i]);
}
}
}*/
if(! SESS_LOGGED) {
$C_debug->alert($C_translate->translate('err_assoc_login','cart',''));
return false;
}
$items='<br/>';
foreach ($reqarr as $prod_id) {
$prodrs = $db->Execute(sqlSelect($db,'product_translate','*',array('product_id'=>$prod_id,'language_id'=>SESS_LANGUAGE)));
if ($prodrs && $prodrs->RecordCount())
$items .= sprintf('- <b><a href="?_page=product:details&id=%s">%s</a></b><br/>',$prod_id,$prodrs->fields['name']);
}
$C_translate->value('cart','items',$items);
$msg = $C_translate->translate('err_assoc_req','cart','');
if ($reqtype == 0)
$C_debug->alert(sprintf('%s %s',$msg,$C_translate->translate('assoc_all','cart','')));
else
$C_debug->alert(sprintf('%s %s',$msg,$C_translate->translate('assoc_one','cart','')));
return false;
}
# Product Plugin Level Validation
$product = $result;
if (! empty($product->fields['prod_plugin']) && !empty($product->fields['prod_plugin_data'])) {
$prodplgfile = sprintf('%sproduct/%s.php',PATH_PLUGINS,$product->fields['prod_plugin_file']);
if (is_file($prodplgfile)) {
include_once($prodplgfile);
eval('$prodplg = new plgn_prov_'.$product->fields['prod_plugin_file'].';');
if (is_object($prodplg)) {
if (is_callable(array($prodplg,'validate_cart'))) {
$result = $prodplg->validate_cart($VAR,$product);
if (! $result) {
$C_debug->alert($result);
return false;
}
}
}
}
}
# Service upgrade
if (! empty($VAR['service_id'])) {
# Validate account logged in
if (SESS_LOGGED == false)
return false;
$dbm = new CORE_database;
# Validate account owns service, service is modifyable, active, not canceled, and exists
$rs = $db->Execute(sqlSelect($db,'service','*',sprintf('recur_modify=1 AND active=1 AND (suspend_billing IS NULL OR suspend_billing=0) AND account_id=%s AND id=%s',
SESS_ACCOUNT,$VAR['service_id'])));
if (! $rs || $rs->RecordCount() == 0)
return false;
# Validate selected product_id is in allowed modify array for selected service
if (empty($rs->fields['product_id']))
return false;
$product_id = $rs->fields['product_id'];
$prod = $db->Execute(sqlSelect($db,'product','*',array('id'=>$product_id)));
if (! $prod || $prod->RecordCount() == 0)
return false;
$arr = unserialize($prod->fields['modify_product_arr']);
if (! is_array($arr) || count($arr) == 0 || empty($arr[0]))
return false;
$do = false;
foreach ($arr as $pid)
if ($pid == $VAR['product_id']) {
$do = true;
break;
}
if (!$do)
return false;
# 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']) ;
$rs = $db->Execute($sql);
# Make sure this service has no outstanding invoices:
$p = AGILE_DB_PREFIX;
$sql = "SELECT DISTINCT {$p}invoice.id, {$p}invoice_item.id
FROM {$p}invoice,{$p}invoice_item
WHERE {$p}invoice.site_id = ".DEFAULT_SITE." AND {$p}invoice_item.site_id = ".DEFAULT_SITE."
AND {$p}invoice_item.service_id = ".$db->qstr($VAR['service_id'])."
AND {$p}invoice_item.invoice_id = {$p}invoice.id AND {$p}invoice.billing_status != 1";
$rs = $db->Execute($sql);
if ($rs && $rs->RecordCount() > 0) {
echo "Invoice(s) in unpaid status for selected service ID {$VAR['service_id']}, cannot upgrade";
return false;
}
}
return true;
}
/**
* Validate Associated Prod Req.
*
* @param int $product_id
* @return bool
* @todo Unused, calling code is commented out.
*/
function assoc_prod($product_id) {
# check if required assoc product is in cart
$db = &DB();
$p = AGILE_DB_PREFIX;
$rs = $db->Execute(sqlSelect($db,"cart","*","product_id=::$product_id:: AND session_id=::".SESS."::"));
if($rs->RecordCount() > 0) {
return true;
} else if (SESS_LOGGED) {
# check if required assoc product has been purchased
$sql ="SELECT {$p}invoice.account_id, {$p}invoice_item.product_id
FROM {$p}invoice_item LEFT JOIN {$p}invoice ON {$p}invoice_item.invoice_id = {$p}invoice.id
WHERE {$p}invoice.account_id = " . $db->qstr(SESS_ACCOUNT) . "
AND {$p}invoice_item.product_id = " . $db->qstr( $product_id ) . "
AND {$p}invoice.process_status = " . $db->qstr( "1" ) . "
AND {$p}invoice.site_id = " . $db->qstr(DEFAULT_SITE) . "
AND {$p}invoice_item.site_id = " . $db->qstr(DEFAULT_SITE);
$rs = $db->Execute($sql);
$rs->RecordCount();
if($rs->RecordCount() > 0) return true;
}
return false;
}
}
?>