Index: in-commerce/constants.php =================================================================== --- in-commerce/constants.php (revision 12146) +++ in-commerce/constants.php (revision 12147) @@ -20,6 +20,12 @@ define('ORDER_STATUS_DENIED', 5); define('ORDER_STATUS_ARCHIVED', 6); + /** + * ID of order, that 100% not in database + * + */ + define('FAKE_ORDER_ID', -1); + define('PRODUCT_TYPE_TANGIBLE', 1); define('PRODUCT_TYPE_SUBSCRIPTION', 2); define('PRODUCT_TYPE_SERVICE', 3); Index: in-commerce/units/orders/orders_event_handler.php =================================================================== --- in-commerce/units/orders/orders_event_handler.php (revision 12146) +++ in-commerce/units/orders/orders_event_handler.php (revision 12147) @@ -1047,77 +1047,113 @@ { $event->setEventParam('raise_warnings', 0); $passed = parent::getPassedID($event); - if( $this->Application->IsAdmin() ) return $passed; + if ( $this->Application->IsAdmin() ) { + // work as usual in admin + return $passed; + } if ($event->Special == 'last') { // return last order id (for using on thank you page) return $this->Application->RecallVar('front_order_id'); } - $ses_id = $this->Application->RecallVar( $event->getPrefixSpecial(true).'_id' ); - if ( $passed && ($passed != $ses_id) ) - { - $query = 'SELECT PortalUserId FROM '.TABLE_PREFIX.'Orders WHERE OrderId = '.$passed; - $user_id = $this->Conn->GetOne($query); - if ($user_id != $this->Application->RecallVar('user_id')) - { + $ses_id = $this->Application->RecallVar( $event->getPrefixSpecial(true) . '_id' ); + if ($passed && ($passed != $ses_id)) { + // order id given in url doesn't match our current order id + $sql = 'SELECT PortalUserId + FROM ' . TABLE_PREFIX . 'Orders + WHERE OrderId = ' . $passed; + $user_id = $this->Conn->GetOne($sql); + + if ($user_id == $this->Application->RecallVar('user_id')) { + // current user is owner of order with given id -> allow him to view order details + return $passed; + } + else { + // current user is not owner of given order -> hacking attempt $this->Application->SetVar($event->getPrefixSpecial().'_id', 0); return 0; } - else - { - return $passed; - } } - else // not passed or equals to ses_id - { - if (!$ses_id) - { - $this->CreateNewCart($event); - return $this->Application->RecallVar($event->getPrefixSpecial(true).'_id'); - } - else - { - return $ses_id; - } + else { + // not passed or equals to ses_id + return $ses_id > 0 ? $ses_id : FAKE_ORDER_ID; // FAKE_ORDER_ID helps to keep parent filter for order items set in "kDBList::linkToParent" } + return $passed; } - function CreateNewCart(&$event) + /** + * Load item if id is available + * + * @param kEvent $event + */ + function LoadItem(&$event) { + $id = $this->getPassedID($event); + if ($id == FAKE_ORDER_ID) { + // if we already know, that there is no such order, + // then don't run database query, that will confirm that + + $object =& $event->getObject(); + /* @var $object kDBItem */ + + $object->Clear($id); + return ; + } + + parent::LoadItem($event); + } + + /** + * Creates new shopping cart + * + * @param kEvent $event + */ + function _createNewCart(&$event) + { $object =& $event->getObject( Array('skip_autoload' => true) ); - $new_number = $this->getNextOrderNumber($event); - $object->SetDBField('Number', $new_number); + /* @var $object kDBItem */ + + $object->SetDBField('Number', $this->getNextOrderNumber($event)); $object->SetDBField('SubNumber', 0); - $object->SetDBField('Type', 0); //incomplete + $object->SetDBField('Type', ORDER_STATUS_INCOMPLETE); $object->SetDBField('VisitId', $this->Application->RecallVar('visit_id') ); + // get user $user_id = $this->Application->RecallVar('user_id'); - if (!$user_id) $user_id = -2; //Guest + if (!$user_id) { + $user_id = -2; // Guest + } $object->SetDBField('PortalUserId', $user_id); + // get affiliate $affiliate_id = $this->isAffiliate($user_id); - if($affiliate_id) - { + if ($affiliate_id) { $object->SetDBField('AffiliateId', $affiliate_id); } - else - { + else { $affiliate_storage_method = $this->Application->ConfigValue('Comm_AffiliateStorageMethod'); $object->SetDBField('AffiliateId', $affiliate_storage_method == 1 ? (int)$this->Application->RecallVar('affiliate_id') : (int)$this->Application->GetVar('affiliate_id') ); } + // get payment type $default_type = $this->Conn->GetOne('SELECT PaymentTypeId FROM '.TABLE_PREFIX.'PaymentTypes WHERE IsPrimary = 1'); - if($default_type) - { + if ($default_type) { $object->SetDBField('PaymentType', $default_type); } - $object->Create(); + $created = $object->Create(); + if ($created) { + $id = $object->GetID(); - $this->Application->SetVar($event->getPrefixSpecial(true).'_id', $object->GetId()); - $this->Application->StoreVar($event->getPrefixSpecial(true).'_id', $object->GetId()); + $this->Application->SetVar($event->getPrefixSpecial(true) . '_id', $id); + $this->Application->StoreVar($event->getPrefixSpecial(true) . '_id', $id); + + return $id; + } + + return 0; } function StoreContinueShoppingLink() @@ -1822,7 +1858,8 @@ function getNextOrderNumber(&$event) { $object =& $event->getObject(); - $sql = 'SELECT MAX(Number) FROM '.$this->Application->GetLiveName($object->TableName); + $sql = 'SELECT MAX(Number) + FROM ' . $this->Application->GetLiveName($object->TableName); return max($this->Conn->GetOne($sql) + 1, $this->Application->ConfigValue('Comm_Next_Order_Number')); } @@ -2588,21 +2625,35 @@ // Loading product to add $product =& $this->Application->recallObject('p.toadd', null, Array('skip_autoload' => true)); + /* @var $product kDBItem */ + $product->Load($item_id); - $object =& $this->Application->recallObject('orditems.-item', null, Array('skip_autoload' => true)); + /* @var $object kDBItem */ $order =& $this->Application->recallObject('ord'); + /* @var $order kDBItem */ + + if (!$order->isLoaded() && !$this->Application->IsAdmin()) { + // no order was created before -> create one now + if ($this->_createNewCart($event)) { + $this->LoadItem($event); + } + } + + if (!$order->isLoaded()) { + // was unable to create new order + return false; + } + $ord_id = $order->GetID(); - if($item_data = $event->getEventParam('ItemData')) - { + if ($item_data = $event->getEventParam('ItemData')) { $item_data = unserialize($item_data); } - else - { - $item_data = Array(); + else { + $item_data = Array (); } $options = getArrayValue($item_data, 'Options'); @@ -2763,7 +2814,10 @@ $order =& $event->getObject(); /* @var $order OrdersItem */ - if ( !$order->isLoaded() ) $this->LoadItem($event); // try to load + if ( !$order->isLoaded() ) { + $this->LoadItem($event); // try to load + } + $ord_id = (int)$order->GetID(); if ( !$order->isLoaded() ) return; //order has not been created yet Index: in-commerce/units/orders/orders_tag_processor.php =================================================================== --- in-commerce/units/orders/orders_tag_processor.php (revision 12146) +++ in-commerce/units/orders/orders_tag_processor.php (revision 12147) @@ -43,21 +43,27 @@ function PrintCompanyLocation($params) { - $fields = Array('City','State','ZIP','Country'); $ret = ''; - foreach($fields as $field) - { + $fields = Array ('City','State','ZIP','Country'); + + foreach ($fields as $field) { $value = $this->Application->ConfigValue('Comm_'.$field); - if($field == 'Country') - { + if ($field == 'Country') { $sql = 'SELECT DestName FROM '.TABLE_PREFIX.'StdDestinations WHERE DestAbbr = '.$this->Conn->qstr($value); $value = $this->Application->Phrase( $this->Conn->GetOne($sql) ); } - if ($field == 'Country' && $value) $ret .= '
'; - if($value) $ret .= $value.', '; + + if ($field == 'Country' && $value) { + $ret .= '
'; + } + + if ($value) { + $ret .= $value.', '; + } } + return rtrim($ret,', '); } @@ -89,18 +95,17 @@ $o = ''; $params['render_as'] = $params['item_render_as']; + $tag_params = array_merge($params, Array ('per_page' => -1)); - $o_items = $this->Application->ProcessParsedTag(rtrim('orditems.'.$this->Special, '.'), 'PrintList', array_merge($params, Array( - 'per_page' => -1 - )) ); - if ($o_items){ + $o_items = $this->Application->ProcessParsedTag(rtrim('orditems.'.$this->Special, '.'), 'PrintList', $tag_params); + if ($o_items) { $cart_params = array('name' => $params['header_render_as']); $o = $this->Application->ParseBlock($cart_params); $o .= $o_items; $cart_params = array('name' => $params['footer_render_as']); $o .= $this->Application->ParseBlock($cart_params); - }else { + } else { $cart_params = array('name' => $params['empty_cart_render_as']); $o = $this->Application->ParseBlock($cart_params); } @@ -121,11 +126,12 @@ return $object->GetDBField('BackOrderFlag'); } - function OrderIcon($params){ + function OrderIcon($params) + { $object =& $this->Application->recallObject('orditems'); - if ($object->GetDBField('BackOrderFlag')==0){ + if ($object->GetDBField('BackOrderFlag') == 0) { return $params['ordericon']; - }else{ + } else { return $params['backordericon']; } } @@ -179,8 +185,8 @@ $order_id = $this->Application->RecallVar('ord_id'); if ($order_id) { $sql = 'SELECT COUNT(*) - FROM '.TABLE_PREFIX.'OrderItems - WHERE OrderId = '.$order_id; + FROM ' . TABLE_PREFIX . 'OrderItems + WHERE OrderId = ' . $order_id; return $this->Conn->GetOne($sql); } @@ -195,7 +201,13 @@ function CartHasBackorders($params) { $object =& $this->getObject($params); - $different_types = $this->Conn->GetCol('SELECT COUNT(*) FROM '.TABLE_PREFIX.'OrderItems WHERE OrderId = '.$object->GetID().' GROUP BY BackOrderFlag'); + + $sql = 'SELECT COUNT(*) + FROM ' . TABLE_PREFIX . 'OrderItems + WHERE OrderId = ' . $object->GetID() . ' + GROUP BY BackOrderFlag'; + $different_types = $this->Conn->GetCol($sql); + return count($different_types) > 1; } @@ -649,7 +661,8 @@ return $o; } - function ShowOrder($params){ + function ShowOrder($params) + { $order_params = $this->prepareTagParams($params); // $order_params['Special'] = 'myorders'; @@ -678,21 +691,19 @@ return crc32($list_unique_key); } - function ListOrders($params){ - + function ListOrders($params) + { $o = ''; - $params['render_as'] = $params['item_render_as']; $o_orders = $this->PrintList2($params); - if ($o_orders){ - + if ($o_orders) { $orders_params = array('name' => $params['header_render_as']); $o = $this->Application->ParseBlock($orders_params); $o .= $o_orders; - }else { + } else { $orders_params = array('name' => $params['empty_myorders_render_as']); $o = $this->Application->ParseBlock($orders_params); } @@ -869,6 +880,9 @@ function OrderHasTangibleItems($params) { $object =& $this->getObject($params); + if ($object->GetID() == FAKE_ORDER_ID) { + return false; + } $sql = 'SELECT COUNT(*) FROM '.TABLE_PREFIX.'OrderItems orditems