Пример #1
0
 /**
  * Returns true if the product is available
  * ALMOST THE SAME AS THE PARENT, EXCEPT WE DON'T CHECK FOR PRICE
  *
  * @param IsotopeProductCollection|\Isotope\Model\ProductCollection $objCollection
  *
  * @return bool
  */
 public function isAvailableForCollection(IsotopeProductCollection $objCollection)
 {
     if ($objCollection->isLocked()) {
         return true;
     }
     if (BE_USER_LOGGED_IN !== true && !$this->isPublished()) {
         return false;
     }
     // Show to guests only
     if ($this->arrData['guests'] && $objCollection->member > 0 && BE_USER_LOGGED_IN !== true && !$this->arrData['protected']) {
         return false;
     }
     // Protected product
     if (BE_USER_LOGGED_IN !== true && $this->arrData['protected']) {
         if ($objCollection->member == 0) {
             return false;
         }
         $groups = deserialize($this->arrData['groups']);
         $memberGroups = deserialize($objCollection->getRelated('member')->groups);
         if (!is_array($groups) || empty($groups) || !is_array($memberGroups) || empty($memberGroups) || !count(array_intersect($groups, $memberGroups))) {
             return false;
         }
     }
     // Check that the product is in any page of the current site
     if (count(\Isotope\Frontend::getPagesInCurrentRoot($this->getCategories(), $objCollection->getRelated('member'))) == 0) {
         return false;
     }
     // Check if "advanced price" is available
     //if (null === $this->getPrice($objCollection) && (in_array('price', $this->getAttributes()) || $this->hasVariantPrices())) {
     //    return false;
     //}
     return true;
 }
Пример #2
0
 /**
  * Find advanced price for multiple product/variant IDs
  *
  * @param array                                      $arrIds
  * @param IsotopeProductCollection|ProductCollection $objCollection
  *
  * @return \Model\Collection|null
  */
 public static function findAdvancedByProductIdsAndCollection(array $arrIds, IsotopeProductCollection $objCollection)
 {
     $time = \Date::floorToMinute();
     $arrGroups = static::getMemberGroups($objCollection->getRelated('member'));
     $objResult = \Database::getInstance()->query("\n            SELECT *\n            FROM (\n                SELECT\n                    tl_iso_product_price.*,\n                    GROUP_CONCAT(tl_iso_product_pricetier.min) AS tier_keys,\n                    GROUP_CONCAT(tl_iso_product_pricetier.price) AS tier_values\n                FROM tl_iso_product_price\n                LEFT JOIN tl_iso_product_pricetier ON tl_iso_product_pricetier.pid = tl_iso_product_price.id\n                WHERE\n                    config_id IN (" . (int) $objCollection->config_id . ",0) AND\n                    member_group IN(" . implode(',', $arrGroups) . ") AND\n                    (start='' OR start<'{$time}') AND\n                    (stop='' OR stop>'" . ($time + 60) . "') AND\n                    tl_iso_product_price.pid IN (" . implode(',', $arrIds) . ")\n                GROUP BY tl_iso_product_price.id\n                ORDER BY config_id DESC, " . \Database::getInstance()->findInSet('member_group', $arrGroups) . ", start DESC, stop DESC\n            ) AS prices\n            GROUP BY prices.pid\n        ");
     if ($objResult->numRows) {
         return ProductPriceCollection::createFromDbResult($objResult, static::$strTable);
     }
     return null;
 }
Пример #3
0
 /**
  * Create a new address for a product collection
  *
  * @param IsotopeProductCollection $objCollection
  * @param array|null               $arrFill an array of member fields to inherit
  * @param bool                     $blnDefaultBilling
  * @param bool                     $blnDefaultShipping
  *
  * @return static
  */
 public static function createForProductCollection(IsotopeProductCollection $objCollection, $arrFill = null, $blnDefaultBilling = false, $blnDefaultShipping = false)
 {
     $objAddress = new static();
     $arrData = array('pid' => (int) $objCollection->id, 'ptable' => 'tl_iso_product_collection', 'tstamp' => time(), 'store_id' => (int) $objCollection->store_id, 'isDefaultBilling' => $blnDefaultBilling ? '1' : '', 'isDefaultShipping' => $blnDefaultShipping ? '1' : '');
     if ($objCollection->member > 0 && !empty($arrFill) && is_array($arrFill) && ($objMember = \MemberModel::findByPk($objCollection->member)) !== null) {
         // Generate address data from tl_member, limit to fields enabled in the shop configuration
         $arrMember = array_intersect_key(array_merge($objMember->row(), array('street_1' => $objMember->street, 'subdivision' => strtoupper($objMember->country . '-' . $objMember->state))), array_flip($arrFill));
         $arrData = array_merge($arrMember, $arrData);
     }
     if ($arrData['country'] == '' && ($objConfig = $objCollection->getRelated('config_id')) !== null) {
         if ($blnDefaultBilling) {
             $arrData['country'] = $objConfig->billing_country ?: $objConfig->country;
         } elseif ($blnDefaultShipping) {
             $arrData['country'] = $objConfig->shipping_country ?: $objConfig->country;
         }
     }
     $objAddress->setRow($arrData);
     return $objAddress;
 }
Пример #4
0
 /**
  * Initialize a new collection and duplicate everything from the source
  * @param   IsotopeProductCollection
  */
 public static function createFromCollection(IsotopeProductCollection $objSource)
 {
     global $objPage;
     $objCollection = new static();
     $objConfig = $objSource->getRelated('config_id');
     if (null === $objConfig) {
         $objConfig = Isotope::getConfig();
     }
     $objCollection->uniqid = uniqid(Haste::getInstance()->call('replaceInsertTags', array((string) $objConfig->orderPrefix, false)), true);
     $objCollection->source_collection_id = (int) $objSource->id;
     $objCollection->config_id = (int) $objConfig->id;
     $objCollection->store_id = (int) $objSource->store_id;
     $objCollection->member = (int) $objSource->member;
     $objCollection->language = (string) $GLOBALS['TL_LANGUAGE'];
     $objCollection->currency = (string) $objConfig->currency;
     $objCollection->pageId = (int) $objPage->id;
     $objCollection->setShippingMethod($objSource->getShippingMethod());
     $objCollection->setPaymentMethod($objSource->getPaymentMethod());
     $objCollection->setShippingAddress($objSource->getShippingAddress());
     $objCollection->setBillingAddress($objSource->getBillingAddress());
     $arrItemIds = $objCollection->copyItemsFrom($objSource);
     $arrSurchargeIds = $objCollection->copySurchargesFrom($objSource, $arrItemIds);
     $objCollection->updateDatabase();
     // HOOK: order status has been updated
     if (isset($GLOBALS['ISO_HOOKS']['createFromProductCollection']) && is_array($GLOBALS['ISO_HOOKS']['createFromProductCollection'])) {
         foreach ($GLOBALS['ISO_HOOKS']['createFromProductCollection'] as $callback) {
             $objCallback = \System::importStatic($callback[0]);
             $objCallback->{$callback}[1]($objCollection, $objSource, $arrItemIds, $arrSurchargeIds);
         }
     }
     return $objCollection;
 }
Пример #5
0
 /**
  * Initialize a new collection and duplicate everything from the source
  *
  * @param IsotopeProductCollection $objSource
  *
  * @return static
  */
 public static function createFromCollection(IsotopeProductCollection $objSource)
 {
     $objCollection = new static();
     $objConfig = $objSource->getRelated('config_id');
     if (null === $objConfig) {
         $objConfig = Isotope::getConfig();
     }
     $objCollection->source_collection_id = (int) $objSource->id;
     $objCollection->config_id = (int) $objConfig->id;
     $objCollection->store_id = (int) $objSource->store_id;
     $objCollection->member = (int) $objSource->member;
     $objCollection->setShippingMethod($objSource->getShippingMethod());
     $objCollection->setPaymentMethod($objSource->getPaymentMethod());
     $objCollection->setShippingAddress($objSource->getShippingAddress());
     $objCollection->setBillingAddress($objSource->getBillingAddress());
     $arrItemIds = $objCollection->copyItemsFrom($objSource);
     $objCollection->updateDatabase();
     // HOOK: order status has been updated
     if (isset($GLOBALS['ISO_HOOKS']['createFromProductCollection']) && is_array($GLOBALS['ISO_HOOKS']['createFromProductCollection'])) {
         foreach ($GLOBALS['ISO_HOOKS']['createFromProductCollection'] as $callback) {
             $objCallback = \System::importStatic($callback[0]);
             $objCallback->{$callback}[1]($objCollection, $objSource, $arrItemIds);
         }
     }
     return $objCollection;
 }
Пример #6
0
 /**
  * Find advanced price for multiple product/variant IDs
  *
  * @param   array
  * @param   IsotopeProductCollection
  *
  * @return  \Model\Collection|null
  */
 public static function findAdvancedByProductIdsAndCollection(array $arrIds, IsotopeProductCollection $objCollection)
 {
     $time = time();
     $arrGroups = static::getMemberGroups($objCollection->getRelated('member'));
     $objResult = \Database::getInstance()->query("\n            SELECT * FROM (\n                SELECT *\n                FROM " . static::$strTable . "\n                WHERE\n                    config_id IN (" . (int) $objCollection->config_id . ",0) AND\n                    member_group IN(" . implode(',', $arrGroups) . ") AND\n                    (start='' OR start<{$time}) AND\n                    (stop='' OR stop>{$time}) AND\n                    pid IN (" . implode(',', $arrIds) . ")\n                ORDER BY config_id DESC, " . \Database::getInstance()->findInSet('member_group', $arrGroups) . ", start DESC, stop DESC\n            ) AS prices\n            GROUP BY pid\n        ");
     if ($objResult->numRows) {
         return \Isotope\Collection\ProductPrice::createFromDbResult($objResult, static::$strTable);
     }
     return null;
 }
Пример #7
0
 /**
  * Generate and return document template
  *
  * @param IsotopeProductCollection $objCollection
  * @param array                    $arrTokens
  *
  * @return string
  */
 protected function generateTemplate(IsotopeProductCollection $objCollection, array $arrTokens)
 {
     $objPage = \PageModel::findWithDetails($objCollection->page_id);
     $objTemplate = new \Isotope\Template($this->documentTpl);
     $objTemplate->setData($this->arrData);
     $objTemplate->title = \StringUtil::parseSimpleTokens($this->documentTitle, $arrTokens);
     $objTemplate->collection = $objCollection;
     $objTemplate->config = $objCollection->getRelated('config_id');
     $objTemplate->page = $objPage;
     $objTemplate->dateFormat = $objPage->dateFormat ?: $GLOBALS['TL_CONFIG']['dateFormat'];
     $objTemplate->timeFormat = $objPage->timeFormat ?: $GLOBALS['TL_CONFIG']['timeFormat'];
     $objTemplate->datimFormat = $objPage->datimFormat ?: $GLOBALS['TL_CONFIG']['datimFormat'];
     // Render the collection
     $objCollectionTemplate = new \Isotope\Template($this->collectionTpl);
     $objCollection->addToTemplate($objCollectionTemplate, array('gallery' => $this->gallery, 'sorting' => $objCollection->getItemsSortingCallable($this->orderCollectionBy)));
     $objTemplate->products = $objCollectionTemplate->parse();
     // !HOOK: customize the document template
     if (isset($GLOBALS['ISO_HOOKS']['generateDocumentTemplate']) && is_array($GLOBALS['ISO_HOOKS']['generateDocumentTemplate'])) {
         foreach ($GLOBALS['ISO_HOOKS']['generateDocumentTemplate'] as $callback) {
             \System::importStatic($callback[0])->{$callback}[1]($objTemplate, $objCollection, $this);
         }
     }
     // Generate template and fix PDF issues, see Contao's ModuleArticle
     $strBuffer = Haste::getInstance()->call('replaceInsertTags', array($objTemplate->parse(), false));
     $strBuffer = html_entity_decode($strBuffer, ENT_QUOTES, $GLOBALS['TL_CONFIG']['characterSet']);
     $strBuffer = \Controller::convertRelativeUrls($strBuffer, '', true);
     // Remove form elements and JavaScript links
     $arrSearch = array('@<form.*</form>@Us', '@<a [^>]*href="[^"]*javascript:[^>]+>.*</a>@Us');
     $strBuffer = preg_replace($arrSearch, '', $strBuffer);
     // URL decode image paths (see contao/core#6411)
     // Make image paths absolute
     $strBuffer = preg_replace_callback('@(src=")([^"]+)(")@', function ($args) {
         if (preg_match('@^(http://|https://)@', $args[2])) {
             return $args[2];
         }
         return $args[1] . TL_ROOT . '/' . rawurldecode($args[2]) . $args[3];
     }, $strBuffer);
     // Handle line breaks in preformatted text
     $strBuffer = preg_replace_callback('@(<pre.*</pre>)@Us', 'nl2br_callback', $strBuffer);
     // Default PDF export using TCPDF
     $arrSearch = array('@<span style="text-decoration: ?underline;?">(.*)</span>@Us', '@(<img[^>]+>)@', '@(<div[^>]+block[^>]+>)@', '@[\\n\\r\\t]+@', '@<br( /)?><div class="mod_article@', '@href="([^"]+)(pdf=[0-9]*(&|&amp;)?)([^"]*)"@');
     $arrReplace = array('<u>$1</u>', '<br>$1', '<br>$1', ' ', '<div class="mod_article', 'href="$1$4"');
     $strBuffer = preg_replace($arrSearch, $arrReplace, $strBuffer);
     return $strBuffer;
 }
Пример #8
0
 /**
  * Add cart rules to surcharges
  */
 public function findSurcharges(IsotopeProductCollection $objCollection)
 {
     $objCart = $objCollection;
     // The checkout review pages shows an order, but we need the cart
     // Only the cart contains coupons etc.
     if ($objCollection instanceof Order) {
         $objCart = $objCollection->getRelated('source_collection_id');
     }
     // Rules should only be applied to Cart, not any other product collection
     if (!$objCart instanceof Cart) {
         return array();
     }
     $arrSurcharges = array();
     $objRules = Rule::findForCart();
     if (null !== $objRules) {
         while ($objRules->next()) {
             $objSurcharge = RuleSurcharge::createForRuleInCollection($objRules->current(), $objCollection);
             if (null !== $objSurcharge) {
                 $arrSurcharges[] = $objSurcharge;
             }
         }
     }
     $arrCoupons = deserialize($objCart->coupons);
     if (!empty($arrCoupons) && is_array($arrCoupons)) {
         $arrDropped = array();
         foreach ($arrCoupons as $code) {
             $objRule = Rule::findOneByCouponCode($code, $objCollection->getItems());
             if (null === $objRule) {
                 $arrDropped[] = $code;
             } else {
                 // cart rules should total all eligible products for the cart discount and apply the discount to that amount rather than individual products.
                 $objSurcharge = RuleSurcharge::createForRuleInCollection($objRule, $objCollection);
                 if (null !== $objSurcharge) {
                     $arrSurcharges[] = $objSurcharge;
                 }
             }
         }
         if (!empty($arrDropped)) {
             // @todo show dropped coupons
             $arrCoupons = array_diff($arrCoupons, $arrDropped);
             \Database::getInstance()->query("UPDATE tl_iso_product_collection SET coupons='" . serialize($arrCoupons) . "' WHERE id=" . (int) Isotope::getCart()->id);
         }
     }
     return $arrSurcharges;
 }
Пример #9
0
 /**
  * Process post-sale requestion from the PSP payment server.
  * @param   IsotopeProductCollection
  */
 public function processPostsale(IsotopeProductCollection $objOrder)
 {
     if (!$this->validateSHASign()) {
         \System::log('Received invalid postsale data for order ID "' . $objOrder->id . '"', __METHOD__, TL_ERROR);
         return false;
     }
     // Validate payment data
     if ($objOrder->currency != $this->getRequestData('currency') || $objOrder->getTotal() != $this->getRequestData('amount')) {
         \System::log('Postsale checkout manipulation in payment for Order ID ' . $objOrder->id . '!', __METHOD__, TL_ERROR);
         return false;
     }
     // Validate payment status
     switch ($this->getRequestData('STATUS')) {
         case 9:
             // Zahlung beantragt (Authorize & Capture)
             $objOrder->date_paid = time();
             // no break
         // no break
         case 5:
             // Genehmigt (Authorize ohne Capture)
             $intStatus = $this->new_order_status;
             break;
         case 41:
             // Unbekannter Wartezustand
         // Unbekannter Wartezustand
         case 51:
             // Genehmigung im Wartezustand
         // Genehmigung im Wartezustand
         case 91:
             // Zahlung im Wartezustand
         // Zahlung im Wartezustand
         case 52:
             // Genehmigung nicht bekannt
         // Genehmigung nicht bekannt
         case 92:
             // Zahlung unsicher
             if (($objConfig = $objOrder->getRelated('config_id')) === null) {
                 $this->log('Config for Order ID ' . $objOrder->id . ' not found', __METHOD__, TL_ERROR);
                 return false;
             }
             $intStatus = $objConfig->orderstatus_error;
             break;
         case 0:
             // Ungültig / Unvollständig
         // Ungültig / Unvollständig
         case 1:
             // Zahlungsvorgang abgebrochen
         // Zahlungsvorgang abgebrochen
         case 2:
             // Genehmigung verweigert
         // Genehmigung verweigert
         case 4:
             // Gespeichert
         // Gespeichert
         case 93:
             // Bezahlung verweigert
         // Bezahlung verweigert
         default:
             return false;
     }
     if (!$objOrder->checkout()) {
         \System::log('Post-Sale checkout for Order ID "' . $objOrder->id . '" failed', __METHOD__, TL_ERROR);
         return false;
     }
     $objOrder->updateOrderStatus($intStatus);
     $objOrder->save();
     return true;
 }