protected function processForm() { // get a product collection (aka cart) global $objPage; $objCart = new Cart(); // Can't call the individual rows here, it would trigger markModified and a save() $objCart->setRow(array_merge($objCart->row(), array('tstamp' => time(), 'member' => 0, 'uniqid' => null, 'config_id' => $this->iso_config_id, 'store_id' => (int) \PageModel::findByPk($objPage->rootId)->iso_store_id))); $objSubmission = $this->getSubmission(false); // add products to cart foreach ($this->arrProducts as $arrProduct) { $strProduct = 'product_' . $arrProduct['product']->id; $strQuantity = 'quantity_' . $arrProduct['product']->id; if (($this->getProductCount() > 1 || $this->getTypeCount() > 1) && !$objSubmission->{$strProduct}) { continue; } if (!$objCart->addProduct($arrProduct['product'], $arrProduct['useQuantity'] ? $objSubmission->{$strQuantity} : 1)) { $this->transformIsotopeErrorMessages(); return; } } $objCart->save(); $objOrder = $objCart->getDraftOrder(); // temporarily override the cart for generating the reviews... $objCartTmp = Isotope::getCart(); Isotope::setCart($objCart); // create steps $arrSteps = array(); $arrCheckoutInfo = array(); // billing address $objBillingAddress = new Address(); foreach ($this->arrBillingAddressFields as $strName) { $objBillingAddress->{$strName} = $objSubmission->{$strName}; } $objBillingAddress->save(); $objOrder->setBillingAddress($objBillingAddress); $objBillingAddressStep = new BillingAddress($this->objCheckoutModule); $arrSteps[] = $objBillingAddressStep; $arrCheckoutInfo['billing_address'] = $objBillingAddressStep->review()['billing_address']; // shipping address $objShippingAddress = new Address(); // standard isotope handling for distinguishing between the address types: // -> if only a billing address is available, it's also the shipping address foreach ($objSubmission->shippingaddress ? $this->arrShippingAddressFields : $this->arrBillingAddressFields as $strName) { $objShippingAddress->{str_replace('shippingaddress_', '', $strName)} = $objSubmission->{$objSubmission->shippingaddress ? $strName : str_replace('shippingaddress_', 'billingaddress_', $strName)}; } $objShippingAddress->save(); // $objOrder->setShippingAddress($objShippingAddress); // $objShippingAddressStep = new ShippingAddress($this->objCheckoutModule); // $arrSteps[] = $objShippingAddressStep; // $arrCheckoutInfo['shipping_address'] = $objShippingAddressStep->review()['shipping_address']; // add shipping method $objIsotopeShipping = Flat::findByPk($this->iso_shipping_modules); $objOrder->setShippingMethod($objIsotopeShipping); $objShippingMethodStep = new ShippingMethod($this->objCheckoutModule); $arrSteps[] = $objShippingMethodStep; $arrCheckoutInfo['shipping_method'] = $objShippingMethodStep->review()['shipping_method']; // add all the checkout info to the order $objOrder->checkout_info = $arrCheckoutInfo; $objOrder->notes = $objSubmission->notes; //... restore the former cart again Isotope::setCart($objCartTmp); $objOrder->nc_notification = $this->nc_notification; $objOrder->email_data = $this->getNotificationTokensFromSteps($arrSteps, $objOrder); // !HOOK: pre-process checkout if (isset($GLOBALS['ISO_HOOKS']['preCheckout']) && is_array($GLOBALS['ISO_HOOKS']['preCheckout'])) { foreach ($GLOBALS['ISO_HOOKS']['preCheckout'] as $callback) { $objCallback = \System::importStatic($callback[0]); if ($objCallback->{$callback}[1]($objOrder, $this->objCheckoutModule) === false) { \System::log('Callback ' . $callback[0] . '::' . $callback[1] . '() cancelled checkout for Order ID ' . $this->id, __METHOD__, TL_ERROR); $this->objCheckoutModule->redirectToStep('failed'); } } } $objOrder->lock(); $objOrder->checkout(); $objOrder->complete(); if (is_array($this->dca['config']['onsubmit_callback'])) { foreach ($this->dca['config']['onsubmit_callback'] as $key => $callback) { if ($callback[0] == 'Isotope\\Backend\\ProductCollection\\Callback' && $callback[1] == 'executeSaveHook') { unset($this->dca['config']['onsubmit_callback'][$key]); break; } } } $this->transformIsotopeErrorMessages(); parent::processForm(); }
/** * Remove carts that have not been accessed for a given number of days */ public function deleteOldCarts() { $t = Cart::getTable(); $objCarts = Cart::findBy(array("({$t}.member=0 AND {$t}.tstamp<?) OR {$t}.member NOT IN (SELECT id FROM tl_member)"), array(time() - $GLOBALS['TL_CONFIG']['iso_cartTimeout'])); if (($intPurged = $this->deleteOldCollections($objCarts)) > 0) { \System::log('Deleted ' . $intPurged . ' old guest carts', __METHOD__, TL_CRON); } }
/** * Delete the cart when a member is deleted * * @param object $dc */ public function deleteMemberCart($dc) { $carts = Cart::findBy('member', $dc->id); if (null !== $carts) { foreach ($carts as $cart) { $cart->delete(); } } }
/** * Get the currently active Isotope cart * * @return Cart|null */ public static function getCart() { if (null === static::$objCart && TL_MODE == 'FE') { static::initialize(); if ((static::$objCart = Cart::findForCurrentStore()) !== null) { static::$objCart->mergeGuestCart(); } } return static::$objCart; }
/** * Callback for checkout Hook. Transfer active rules to usage table. */ public function writeRuleUsages($objOrder) { $objCart = Cart::findByPk($objOrder->source_collection_id); $objRules = Rule::findActiveWitoutCoupons(); $arrRules = null === $objRules ? array() : $objRules->fetchEach('id'); $arrCoupons = deserialize($objCart->coupons); if (is_array($arrCoupons) && !empty($arrCoupons)) { $blnError = false; foreach ($arrCoupons as $k => $code) { $objRule = Rule::findOneByCouponCode($code, $objCart->getItems()); if (null === $objRule) { Message::addError(sprintf($GLOBALS['TL_LANG']['ERR']['couponCodeDropped'], $code)); unset($arrCoupons[$k]); $blnError = true; } else { $arrRules[] = $objRule->id; } } if ($blnError) { $objCart->coupons = $arrCoupons; return false; } } if (!empty($arrRules)) { $time = time(); \Database::getInstance()->query("INSERT INTO tl_iso_rule_usage (pid,tstamp,order_id,config_id,member_id) VALUES (" . implode(", {$time}, {$objOrder->id}, " . (int) Isotope::getConfig()->id . ", {$objOrder->member}), (", $arrRules) . ", {$time}, {$objOrder->id}, " . (int) Isotope::getConfig()->id . ", {$objOrder->member})"); } return true; }
/** * Process the order checkout * * @return bool */ public function checkout() { if ($this->isCheckoutComplete()) { return true; } // Finish and lock the order // (do this now, because otherwise surcharges etc. will not be loaded form the database) $this->checkout_complete = true; $this->generateDocumentNumber($this->getRelated('config_id')->orderPrefix, (int) $this->getRelated('config_id')->orderDigits); if (!$this->isLocked()) { $this->lock(); } \System::log('New order ID ' . $this->id . ' has been placed', __METHOD__, TL_ACCESS); // Delete cart after migrating to order if (($objCart = Cart::findByPk($this->source_collection_id)) !== null) { $objCart->delete(); } // Delete all other orders that relate to the current cart if (($objOrders = static::findSiblingsBy('source_collection_id', $this)) !== null) { /** @var static $objOrder */ foreach ($objOrders as $objOrder) { if (!$objOrder->isCheckoutComplete()) { $objOrder->delete(true); } } } // Generate tokens $arrTokens = $this->getNotificationTokens($this->nc_notification); // Send notification if ($this->nc_notification) { $blnNotificationError = true; /** @type Notification $objNotification */ if (($objNotification = Notification::findByPk($this->nc_notification)) !== null) { $arrResult = $objNotification->send($arrTokens, $this->language); if (!empty($arrResult) && !in_array(false, $arrResult)) { $blnNotificationError = false; } } if ($blnNotificationError === true) { \System::log('Error sending new order notification for order ID ' . $this->id, __METHOD__, TL_ERROR); } } else { \System::log('No notification for order ID ' . $this->id, __METHOD__, TL_ERROR); } // Set order status only if a payment module has not already set it if ($this->order_status == 0) { $this->updateOrderStatus($this->getRelated('config_id')->orderstatus_new); } // !HOOK: post-process checkout if (isset($GLOBALS['ISO_HOOKS']['postCheckout']) && is_array($GLOBALS['ISO_HOOKS']['postCheckout'])) { foreach ($GLOBALS['ISO_HOOKS']['postCheckout'] as $callback) { $objCallback = \System::importStatic($callback[0]); $objCallback->{$callback}[1]($this, $arrTokens); } } return true; }