* @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 * @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;$ivalidate_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; $iiauth_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; $iassoc_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; $iassoc_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='
'; 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('- %s
',$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; } } ?>