public function testClearSpecific() { $cache = Controller_Frontend_Factory::setCache(true); $context = TestHelper::getContext(); $basket1 = Controller_Frontend_Factory::createController($context, 'basket'); $catalog1 = Controller_Frontend_Factory::createController($context, 'catalog'); Controller_Frontend_Factory::clear((string) $context, 'basket'); $basket2 = Controller_Frontend_Factory::createController($context, 'basket'); $catalog2 = Controller_Frontend_Factory::createController($context, 'catalog'); Controller_Frontend_Factory::setCache($cache); $this->assertNotSame($basket1, $basket2); $this->assertSame($catalog1, $catalog2); }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $context = $this->_getContext(); try { $params = $this->getView()->param(); $orderid = $context->getSession()->get('arcavias/orderid'); $serviceManager = MShop_Factory::createManager($context, 'service'); $search = $serviceManager->createSearch(); $search->setConditions($search->compare('==', 'service.type.code', 'payment')); $search->setSortations(array($search->sort('+', 'service.position'))); $start = 0; do { $serviceItems = $serviceManager->searchItems($search); foreach ($serviceItems as $serviceItem) { try { $provider = $serviceManager->getProvider($serviceItem); if (($orderItem = $provider->updateSync($params)) !== null) { if ($orderItem->getPaymentStatus() === MShop_Order_Item_Abstract::PAY_UNFINISHED && $provider->isImplemented(MShop_Service_Provider_Payment_Abstract::FEAT_QUERY)) { $provider->query($orderItem); } break 2; } } catch (Exception $e) { $msg = 'Updating order ID "%1$s" failed: %2$s'; $context->getLogger()->log(sprintf($msg, $orderid, $e->getMessage())); } } $count = count($serviceItems); $start += $count; $search->setSlice($start); } while ($count >= $search->getSliceSize()); parent::process(); $orderManager = MShop_Factory::createManager($context, 'order'); $orderItem = $orderManager->getItem($orderid); // Clear basket and cache if ($orderItem->getPaymentStatus() > MShop_Order_Item_Abstract::PAY_REFUSED) { $session = $context->getSession(); foreach ($session->get('arcavias/basket/cache', array()) as $key => $value) { $session->set($key, null); } $orderBaseManager = MShop_Factory::createManager($context, 'order/base'); $orderBaseManager->setSession($orderBaseManager->createItem()); } // Update stock, coupons, etc. Controller_Frontend_Factory::createController($context, 'order')->update($orderItem); } catch (Client_Html_Exception $e) { $view = $this->getView(); $error = array($context->getI18n()->dt('client/html', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (Controller_Frontend_Exception $e) { $view = $this->getView(); $error = array($context->getI18n()->dt('controller/frontend', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (MShop_Exception $e) { $view = $this->getView(); $error = array($context->getI18n()->dt('mshop', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (Exception $e) { $context->getLogger()->log($e->getMessage() . PHP_EOL . $e->getTraceAsString()); $view = $this->getView(); $error = array($context->getI18n()->dt('client/html', 'A non-recoverable error occured')); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { if ($view->detailProductItem->getType() === 'select') { $context = $this->_getContext(); $products = $view->detailProductItem->getRefItems('product', 'default', 'default'); /** @todo Make referenced domains configurable */ $domains = array('text', 'price', 'media', 'attribute'); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $subproducts = $controller->getProductItems(array_keys($products), $domains); $attrIds = $prodDeps = $attrDeps = $attrTypeDeps = array(); foreach ($subproducts as $subProdId => $subProduct) { foreach ($subProduct->getRefItems('attribute', null, 'variant') as $attrId => $attrItem) { $attrTypeDeps[$attrItem->getType()][$attrId] = $attrItem->getPosition(); $attrDeps[$attrId][] = $subProdId; $prodDeps[$subProdId][] = $attrId; $attrIds[] = $attrId; } } ksort($attrTypeDeps); $this->_addMetaItem($subproducts, 'product', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($subproducts), 'product', $this->_expire); $attrManager = $controller->createManager('attribute'); $search = $attrManager->createSearch(true); $expr = array($search->compare('==', 'attribute.id', $attrIds), $search->getConditions()); $search->setConditions($search->combine('&&', $expr)); /** @todo Make referenced domains configurable */ $attributes = $attrManager->searchItems($search, array('text', 'media')); $this->_addMetaItem($attributes, 'attribute', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($attributes), 'attribute', $this->_expire); $view->selectionProducts = $subproducts; $view->selectionProductDependencies = $prodDeps; $view->selectionAttributeDependencies = $attrDeps; $view->selectionAttributeTypeDependencies = $attrTypeDeps; $view->selectionAttributeItems = $attributes; } $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); $context = $this->_getContext(); $session = $context->getSession(); try { $orderid = $session->get('arcavias/orderid'); $provider = $this->_getServiceProvider($view->param('code')); $config = array('absoluteUri' => true, 'namespace' => false); $params = array('code' => $view->param('code'), 'orderid' => $orderid); $urls = array('payment.url-success' => $this->_getUrlConfirm($view, $params, $config), 'payment.url-update' => $this->_getUrlUpdate($view, $params, $config), 'client.ipaddress' => $view->request()->getClientAddress()); $urls['payment.url-self'] = $urls['payment.url-success']; $provider->injectGlobalConfigBE($urls); $reqParams = $view->param(); $reqParams['orderid'] = $orderid; if (($orderItem = $provider->updateSync($reqParams, $view->request()->getBody())) !== null) { if ($orderItem->getPaymentStatus() === MShop_Order_Item_Abstract::PAY_UNFINISHED && $provider->isImplemented(MShop_Service_Provider_Payment_Abstract::FEAT_QUERY)) { $provider->query($orderItem); } $view->confirmOrderItem = $orderItem; } else { return; } parent::process(); if ($orderItem->getPaymentStatus() > MShop_Order_Item_Abstract::PAY_REFUSED) { foreach ($session->get('arcavias/basket/cache', array()) as $key => $value) { $session->set($key, null); } Controller_Frontend_Factory::createController($context, 'basket')->clear(); } // Update stock, coupons, etc. Controller_Frontend_Factory::createController($context, 'order')->update($orderItem); } catch (Client_Html_Exception $e) { $error = array($context->getI18n()->dt('client/html', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (Controller_Frontend_Exception $e) { $error = array($context->getI18n()->dt('controller/frontend', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (MShop_Exception $e) { $error = array($context->getI18n()->dt('mshop', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (Exception $e) { $context->getLogger()->log($e->getMessage() . PHP_EOL . $e->getTraceAsString()); $error = array($context->getI18n()->dt('client/html', 'A non-recoverable error occured')); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_view)) { if (($pos = $view->param('l-pos')) !== null && ($pid = $view->param('d-product-id')) !== null) { if ($pos < 1) { $start = 0; $size = 2; } else { $start = $pos - 1; $size = 3; } $filter = $this->_getProductListFilterByParam($view->get('stageParams', array())); $filter->setSlice($start, $size); $total = null; $controller = Controller_Frontend_Factory::createController($this->_getContext(), 'catalog'); $products = $controller->getProductList($filter, $total, array('text')); if (($count = count($products)) > 1) { $listPos = array_search($pid, array_keys($products)); $target = $view->config('client/html/catalog/detail/url/target'); $controller = $view->config('client/html/catalog/detail/url/controller', 'catalog'); $action = $view->config('client/html/catalog/detail/url/action', 'detail'); $config = $view->config('client/html/catalog/detail/url/config', array()); if ($listPos > 0 && ($product = reset($products)) !== false) { $param = array('a-name' => $product->getName(), 'd-product-id' => $product->getId(), 'l-pos' => $listPos - 1); $view->navigationPrev = $view->url($target, $controller, $action, $param, array(), $config); } if ($listPos < $count - 1 && ($product = end($products)) !== false) { $param = array('a-name' => $product->getName(), 'd-product-id' => $product->getId(), 'l-pos' => $listPos + 1); $view->navigationNext = $view->url($target, $controller, $action, $param, array(), $config); } } } $this->_view = $view; } return $this->_view; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $input = $view->param('f_search'); $controller = Controller_Frontend_Factory::createController($this->_getContext(), 'catalog'); $filter = $controller->createTextFilter($input); $items = $controller->getTextList($filter); $suggestTextItems = array(); foreach ($items as $id => $name) { $suggestTextItems[] = array("id" => $id, "name" => $name); } $view->suggestTextItems = $suggestTextItems; $this->_cache = $view; } return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $attrMap = array(); $controller = Controller_Frontend_Factory::createController($this->_getContext(), 'catalog'); /** client/html/catalog/filter/attribute/types * List of attribute types that should be displayed in this order in the catalog filter * * The attribute section in the catalog filter component can display * all attributes a visitor can use to reduce the listed products * to those that contains one or more attributes. By default, all * available attributes will be displayed and ordered by their * attribute type. * * With this setting, you can limit the attribute types to only thoses * whose names are part of the setting value. Furthermore, a particular * order for the attribute types can be enforced that is different * from the standard order. * * @param array List of attribute type codes * @since 2015.05 * @category User * @category Developer * @see client/html/catalog/filter/attribute/domains */ $attrTypes = $view->config('client/html/catalog/filter/attribute/types', array()); $manager = $controller->createManager('attribute'); $search = $manager->createSearch(true); $expr = array(); if (!empty($attrTypes)) { $expr[] = $search->compare('==', 'attribute.type.code', $attrTypes); } $expr[] = $search->compare('==', 'attribute.domain', 'product'); $expr[] = $search->getConditions(); $sort = array($search->sort('+', 'attribute.position')); $search->setConditions($search->combine('&&', $expr)); $search->setSortations($sort); /** client/html/catalog/filter/attribute/domains * List of domain names whose items should be fetched with the filter attributes * * The templates rendering the attributes in the catalog filter usually * add the images and texts associated to each item. If you want to * display additional content, you can configure your own list of * domains (attribute, media, price, product, text, etc. are domains) * whose items are fetched from the storage. Please keep in mind that * the more domains you add to the configuration, the more time is * required for fetching the content! * * @param array List of domain item names * @since 2015.05 * @category Developer * @see client/html/catalog/filter/attribute/types */ $domains = $view->config('client/html/catalog/filter/attribute/domains', array('text', 'media')); $attributes = $manager->searchItems($search, $domains); foreach ($attributes as $id => $item) { $attrMap[$item->getType()][$id] = $item; } if (!empty($attrTypes)) { $sortedMap = array(); foreach ($attrTypes as $type) { if (isset($attrMap[$type])) { $sortedMap[$type] = $attrMap[$type]; } } $attrMap = $sortedMap; } else { ksort($attrMap); } $this->_addMetaItem($attributes, 'attribute', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($attributes), 'attribute', $this->_expire); // Delete cache when attributes are added or deleted even in "tag-all" mode $this->_tags[] = 'attribute'; $view->attributeMap = $attrMap; $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); $context = $this->_getContext(); try { $provider = $this->_getServiceProvider($view->param('code')); $config = array('absoluteUri' => true, 'namespace' => false); $params = array('code' => $view->param('code'), 'orderid' => $view->param('orderid')); $urls = array('payment.url-success' => $this->_getUrlConfirm($view, $params, $config), 'payment.url-update' => $this->_getUrlUpdate($view, $params, $config)); $urls['payment.url-self'] = $urls['payment.url-update']; $provider->injectGlobalConfigBE($urls); $response = null; $headers = array(); try { $body = $view->request()->getBody(); if (($orderItem = $provider->updateSync($view->param(), $body, $response, $headers)) !== null) { Controller_Frontend_Factory::createController($context, 'order')->update($orderItem); // stock, coupons } $view->updateMessage = $response; } catch (MShop_Service_Exception $e) { $view->updateMessage = $e->getMessage(); } if (!empty($headers)) { $view->updateHttpHeaders = $headers; } parent::process(); } catch (Exception $e) { /** client/html/checkout/standard/update/http-error * HTTP header sent for failed attempts to update the order status * * This HTTP header is returned to the remote system if the status * update failed due to an error in the application. This header is * not sent if e.g. a payment was refused by the payment gateway! * It should be one of the 5xx HTTP headers. * * @param array List of valid HTTP headers * @since 2015.07 * @category Developer * @see client/html/checkout/standard/update/http-success */ $default = array('HTTP/1.1 500 Error updating order status'); $headerList = $context->getConfig()->get('client/html/checkout/standard/update/http-error', $default); $view->updateHttpHeaders = $headerList; $view->updateMessage = $e->getMessage(); $body = $view->request()->getBody(); $params = print_r($view->param(), true); $msg = "Updating order status failed: %1\$s\n%2\$s\n%3\$s"; $context->getLogger()->log(sprintf($msg, $e->getMessage(), $params, $body)); } }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); $context = $this->_getContext(); switch ($view->param('b_action')) { case 'coupon-delete': if (($coupon = $view->param('b_coupon')) != '') { $this->_clearCached(); $cntl = Controller_Frontend_Factory::createController($context, 'basket'); $cntl->deleteCoupon($coupon); } break; default: if (($coupon = $view->param('b_coupon')) != '') { $this->_clearCached(); $cntl = Controller_Frontend_Factory::createController($context, 'basket'); /** client/html/basket/standard/coupon/allowed * Number of coupon codes a customer is allowed to enter * * This configuration option enables shop owners to limit the number of coupon * codes that can be added by a customer to his current basket. By default, only * one coupon code is allowed per order. * * Coupon codes are valid until a payed order is placed by the customer. The * "count" of the codes is decreased afterwards. If codes are not personalized * the codes can be reused in the next order until their "count" reaches zero. * * @param integer Positive number of coupon codes including zero * @since 2014.05 * @category User * @category Developer */ $allowed = $context->getConfig()->get('client/html/basket/standard/coupon/allowed', 1); if ($allowed <= count($cntl->get()->getCoupons())) { throw new Client_Html_Exception(sprintf('Number of coupon codes exceeds the limit')); } $cntl->addCoupon($coupon); } break; } parent::process(); }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $config = $context->getConfig(); /** client/html/catalog/count/tree/aggregate * Enables or disables generating product counts for the category catalog filter * * This configuration option allows shop owners to enable or disable product counts * for the tree section of the catalog filter HTML client. * * @param boolean Disabled if "0", enabled if "1" * @since 2014.03 * @see client/html/catalog/count/limit */ if ($config->get('client/html/catalog/count/tree/aggregate', true) == true) { /** client/html/catalog/count/limit * @see client/html/catalog/count/tree/aggregate */ $filter = $this->_getProductListFilter($view, false); $filter->setSlice(0, $config->get('client/html/catalog/count/limit', 10000)); $filter->setSortations(array()); // it's not necessary and slows down the query $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $view->treeCountList = $controller->aggregateIndex($filter, 'catalog.index.catalog.id'); } $this->_cache = $view; } return $this->_cache; }
/** * Processes the input, e.g. store given order. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); try { // only start if there's something to do if (($option = $view->param('cs-order', null)) === null || $view->get('standardStepActive') !== null) { return; } $context = $this->_getContext(); $orderBaseManager = MShop_Factory::createManager($context, 'order/base'); $basket = $orderBaseManager->getSession(); $basket->setCustomerId($context->getUserId()); $basket->finish(); $cntl = Controller_Frontend_Factory::createController($context, 'order'); $orderItem = $cntl->store($basket); $cntl->block($orderItem); $context->getSession()->set('arcavias/orderid', $orderItem->getId()); $view->orderItem = $orderItem; $view->orderBasket = $basket; parent::process(); // save again after sub-clients modified it's state MShop_Factory::createManager($context, 'order')->saveItem($orderItem); } catch (Exception $e) { $view->standardStepActive = 'order'; throw $e; } }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $total = 0; $productIds = array(); $context = $this->_getContext(); $typeItem = $this->_getTypeItem('customer/list/type', 'product', 'favorite'); $size = $this->_getProductListSize($view); $current = $this->_getProductListPage($view); $last = $total != 0 ? ceil($total / $size) : 1; $manager = MShop_Factory::createManager($context, 'customer/list'); $search = $manager->createSearch(); $expr = array($search->compare('==', 'customer.list.parentid', $context->getUserId()), $search->compare('==', 'customer.list.typeid', $typeItem->getId()), $search->compare('==', 'customer.list.domain', 'product')); $search->setConditions($search->combine('&&', $expr)); $search->setSortations(array($search->sort('-', 'customer.list.position'))); $search->setSlice(($current - 1) * $size, $size); $view->favoriteListItems = $manager->searchItems($search, array(), $total); /** client/html/account/favorite/domains * A list of domain names whose items should be available in the account favorite view template * * The templates rendering product details usually add the images, * prices and texts associated to the product item. If you want to * display additional or less content, you can configure your own * list of domains (attribute, media, price, product, text, etc. are * domains) whose items are fetched from the storage. Please keep * in mind that the more domains you add to the configuration, the * more time is required for fetching the content! * * @param array List of domain names * @since 2014.09 * @category Developer * @see client/html/catalog/domains */ $default = array('text', 'price', 'media'); $domains = $context->getConfig()->get('client/html/account/favorite/domains', $default); foreach ($view->favoriteListItems as $listItem) { $productIds[] = $listItem->getRefId(); } $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $view->favoriteProductItems = $controller->getProductItems($productIds, $domains); $view->favoritePageFirst = 1; $view->favoritePagePrev = $current > 1 ? $current - 1 : 1; $view->favoritePageNext = $current < $last ? $current + 1 : $last; $view->favoritePageLast = $last; $view->favoritePageCurr = $current; $this->_cache = $view; } return $this->_cache; }
/** * Returns the product item for the given ID including the domain items * * @param string $prodid Unique product ID * @param array List of domain items that should be fetched too * @throws Client_Html_Exception If no product item was found * @return MShop_Product_Item_Interface Product item object */ protected function _getProductItem($prodid, array $domains) { $context = $this->_getContext(); $config = $context->getConfig(); /** client/html/catalog/domains * A list of domain names whose items should be available in the catalog view templates * * @see client/html/catalog/detail/domains */ $domains = $config->get('client/html/catalog/domains', $domains); /** client/html/catalog/detail/domains * A list of domain names whose items should be available in the product detail view template * * The templates rendering product details usually add the images, * prices, texts, attributes, products, etc. associated to the product * item. If you want to display additional or less content, you can * configure your own list of domains (attribute, media, price, product, * text, etc. are domains) whose items are fetched from the storage. * Please keep in mind that the more domains you add to the configuration, * the more time is required for fetching the content! * * Since version 2014.05 this configuration option overwrites the * "client/html/catalog/domains" option that allows to configure the * domain names of the items fetched for all catalog related data. * * @param array List of domain names * @since 2014.03 * @category Developer * @see client/html/catalog/domains * @see client/html/catalog/list/domains */ $domains = $config->get('client/html/catalog/detail/domains', $domains); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $items = $controller->getProductItems(array($prodid), $domains); if (($item = reset($items)) === false) { throw new Client_Html_Exception(sprintf('No product with ID "%1$s" found', $prodid)); } $this->_addMetaItem($item, 'product', $this->_expire, $this->_tags); $this->_addMetaList($prodid, 'product', $this->_expire); return $item; }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); $context = $this->_getContext(); $session = $context->getSession(); $orderid = $session->get('arcavias/orderid'); try { if (($orderItem = $this->_updatePayment($view, $orderid)) === null) { $orderManager = MShop_Factory::createManager($context, 'order'); $orderItem = $orderManager->getItem($orderid); } $view->confirmOrderItem = $orderItem; parent::process(); if ($orderItem->getPaymentStatus() > MShop_Order_Item_Abstract::PAY_REFUSED) { foreach ($session->get('arcavias/basket/cache', array()) as $key => $value) { $session->set($key, null); } Controller_Frontend_Factory::createController($context, 'basket')->clear(); } if ($orderItem->getPaymentStatus() == MShop_Order_Item_Abstract::PAY_RECEIVED) { $orderBaseManager = MShop_Factory::createManager($context, 'order/base'); $orderBase = $orderBaseManager->load($orderItem->getBaseId()); $attributeManager = MShop_Factory::createManager($context, 'attribute'); $downloadManager = MShop_Factory::createManager($context, 'download'); foreach ($orderBase->getProducts() as $product) { $dfProdAttr = $product->getAttributeItem('digital-file', 'hidden'); $dfAttr = $attributeManager->getItem($dfProdAttr->getAttributeId(), array('media')); $listItems = $dfAttr->getRefItems('media'); $media = reset($listItems); $download = $downloadManager->createItem(); $download->setUserId($context->getUserId()); $download->setFileId($this->_generateId()); $download->setProductId($product->getId()); $download->setOrderBaseId($orderBase->getId()); $download->setUrl($media->getUrl()); $download->setDownloads(0); $downloadManager->saveItem($download); } } // Update stock, coupons, etc. Controller_Frontend_Factory::createController($context, 'order')->update($orderItem); } catch (Client_Html_Exception $e) { $error = array($context->getI18n()->dt('client/html', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (Controller_Frontend_Exception $e) { $error = array($context->getI18n()->dt('controller/frontend', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (MShop_Exception $e) { $error = array($context->getI18n()->dt('mshop', $e->getMessage())); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } catch (Exception $e) { $context->getLogger()->log($e->getMessage() . PHP_EOL . $e->getTraceAsString()); $error = array($context->getI18n()->dt('client/html', 'A non-recoverable error occured')); $view->confirmErrorList = $view->get('confirmErrorList', array()) + $error; } }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $controller = Controller_Frontend_Factory::createController($this->_getContext(), 'basket'); $view->miniBasket = $controller->get(); $this->_cache = $view; } return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $currentid = (string) $view->param('f_catid', ''); $currentid = $currentid != '' ? $currentid : null; /** client/html/catalog/filter/tree/startid * The ID of the category node that should be the root of the displayed category tree * * If you want to display only a part of your category tree, you can * configure the ID of the category node from which rendering the * remaining sub-tree should start. * * In most cases you can set this value via the administration interface * of the shop application. In that case you often can configure the * start ID individually for each catalog filter. * * @param string Category ID * @since 2014.03 * @category User * @category Developer * @see client/html/catalog/filter/tree/levels-always * @see client/html/catalog/filter/tree/levels-only * @see client/html/catalog/filter/tree/domains */ $startid = $view->config('client/html/catalog/filter/tree/startid', ''); $startid = $startid != '' ? $startid : null; /** client/html/catalog/filter/tree/domains * List of domain names whose items should be fetched with the filter categories * * The templates rendering the categories in the catalog filter usually * add the images and texts associated to each item. If you want to * display additional content, you can configure your own list of * domains (attribute, media, price, product, text, etc. are domains) * whose items are fetched from the storage. Please keep in mind that * the more domains you add to the configuration, the more time is * required for fetching the content! * * @param array List of domain item names * @since 2014.03 * @category Developer * @see client/html/catalog/filter/tree/startid * @see client/html/catalog/filter/tree/levels-always * @see client/html/catalog/filter/tree/levels-only */ $ref = $view->config('client/html/catalog/filter/tree/domains', array('text', 'media')); if ($currentid) { $catItems = $controller->getCatalogPath($currentid); if ($startid) { foreach ($catItems as $key => $item) { if ($key == $startid) { break; } unset($catItems[$key]); } } if (($node = reset($catItems)) === false) { $msg = sprintf('Category with ID "%1$s" not below ID "%2$s"', $currentid, $startid); throw new Client_Html_Exception($msg); } } else { $node = $controller->getCatalogTree($startid, array(), MW_Tree_Manager_Abstract::LEVEL_ONE); $catItems = array($node->getId() => $node); } $search = $controller->createCatalogFilter(); $expr = $search->compare('==', 'catalog.parentid', array_keys($catItems)); $expr = $search->combine('||', array($expr, $search->compare('==', 'catalog.id', $node->getId()))); /** client/html/catalog/filter/tree/levels-always * The number of levels in the category tree that should be always displayed * * Usually, only the root node and the first level of the category * tree is shown in the frontend. Only if the user clicks on a * node in the first level, the page reloads and the sub-nodes of * the chosen category are rendered as well. * * Using this configuration option you can enforce the given number * of levels to be always displayed. The root node uses level 0, the * categories below level 1 and so on. * * In most cases you can set this value via the administration interface * of the shop application. In that case you often can configure the * levels individually for each catalog filter. * * @param integer Number of tree levels * @since 2014.03 * @category User * @category Developer * @see client/html/catalog/filter/tree/startid * @see client/html/catalog/filter/tree/levels-only * @see client/html/catalog/filter/tree/domains */ if (($levels = $view->config('client/html/catalog/filter/tree/levels-always')) != null) { $expr = $search->combine('||', array($expr, $search->compare('<=', 'catalog.level', $levels))); } /** client/html/catalog/filter/tree/levels-only * No more than this number of levels in the category tree should be displayed * * If the user clicks on a category node, the page reloads and the * sub-nodes of the chosen category are rendered as well. * Using this configuration option you can enforce that no more than * the given number of levels will be displayed at all. The root * node uses level 0, the categories below level 1 and so on. * * In most cases you can set this value via the administration interface * of the shop application. In that case you often can configure the * levels individually for each catalog filter. * * @param integer Number of tree levels * @since 2014.03 * @category User * @category Developer * @see client/html/catalog/filter/tree/startid * @see client/html/catalog/filter/tree/levels-always * @see client/html/catalog/filter/tree/domains */ if (($levels = $view->config('client/html/catalog/filter/tree/levels-only')) != null) { $expr = $search->combine('&&', array($expr, $search->compare('<=', 'catalog.level', $levels))); } $search->setConditions($expr); $level = MW_Tree_Manager_Abstract::LEVEL_TREE; $view->treeCatalogPath = $catItems; $view->treeCatalogTree = $controller->getCatalogTree($startid, $ref, $level, $search); $view->treeCatalogIds = $this->_getCatalogIds($view->treeCatalogTree, $catItems, $currentid); $view->treeFilterParams = $this->_getClientParams($view->param(), array('f')); $this->_addMetaItemCatalog($view->treeCatalogTree, $this->_expire, $this->_tags); $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); try { parent::process(); $basketCntl = Controller_Frontend_Factory::createController($this->_getContext(), 'basket'); // Test if addresses are available $addresses = $basketCntl->get()->getAddresses(); if (!isset($view->standardStepActive) && count($addresses) === 0) { $view->standardStepActive = 'address'; return false; } } catch (Exception $e) { $this->getView()->standardStepActive = 'address'; throw $e; } }
/** * Edits the products specified by the view parameters to the basket. * * @param MW_View_Interface $view View object * @param array $options List of options for editProducts() in basket controller */ protected function _editProducts(MW_View_Interface $view, array $options) { $this->_clearCached(); $products = (array) $view->param('b-prod', array()); $controller = Controller_Frontend_Factory::createController($this->_getContext(), 'basket'); if (($positon = $view->param('b-position', null)) !== null) { $products[] = array('position' => $positon, 'quantity' => $view->param('b-quantity', 1), 'attrconf-code' => array_filter((array) $view->param('b-attrconf-code', array()))); } foreach ($products as $values) { $controller->editProduct(isset($values['position']) ? $values['position'] : null, isset($values['quantity']) ? $values['quantity'] : 1, $options, isset($values['attrconf-code']) ? array_filter((array) $values['attrconf-code']) : array()); } }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $products = array(); $context = $this->_getContext(); $config = $context->getConfig(); if (isset($view->listCurrentCatItem)) { /** client/html/catalog/list/promo/size * The maximum number of products that should be shown in the promotion section * * Each product list can render a list of promoted products on * top if there are any products associated to that category whose * list type is "promotion". This option limits the maximum number * of products that are displayed. It takes only effect if more * promotional products are added to this category than the set * value. * * @param integer Number of promotion products * @since 2014.03 * @category User * @category Developer */ $size = $config->get('client/html/catalog/list/promo/size', 6); $domains = $config->get('client/html/catalog/list/domains', array('media', 'price', 'text')); $total = null; $catId = $view->listCurrentCatItem->getId(); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $filter = $controller->createIndexFilterCategory($catId, 'relevance', '+', 0, $size, 'promotion'); $products = $controller->getIndexItems($filter, $domains, $total); } if (!empty($products) && $config->get('client/html/catalog/list/stock/enable', true) === true) { $stockTarget = $config->get('client/html/catalog/stock/url/target'); $stockController = $config->get('client/html/catalog/stock/url/controller', 'catalog'); $stockAction = $config->get('client/html/catalog/stock/url/action', 'stock'); $stockConfig = $config->get('client/html/catalog/stock/url/config', array()); $productIds = array_keys($products); sort($productIds); $params = array('s_prodid' => implode(' ', $productIds)); $view->promoStockUrl = $view->url($stockTarget, $stockController, $stockAction, $params, array(), $stockConfig); } $this->_addMetaItem($products, 'product', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($products), 'product', $this->_expire); $view->promoItems = $products; $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Searches for the products based on the current paramters. * * The found products and the total number of available products can be * retrieved using the getProductList() and getProductTotal() methods. * * @param MW_View_Interface $view View instance with helper for retrieving the required parameters */ protected function _searchProducts(MW_View_Interface $view) { $context = $this->_getContext(); $config = $context->getConfig(); /** client/html/catalog/domains * A list of domain names whose items should be available in the catalog view templates * * The templates rendering catalog related data usually add the images and * texts associated to each item. If you want to display additional * content like the attributes, you can configure your own list of * domains (attribute, media, price, product, text, etc. are domains) * whose items are fetched from the storage. Please keep in mind that * the more domains you add to the configuration, the more time is required * for fetching the content! * * This configuration option can be overwritten by the "client/html/catalog/list/domains" * configuration option that allows to configure the domain names of the * items fetched specifically for all types of product listings. * * @param array List of domain names * @since 2014.03 * @category Developer * @see client/html/catalog/list/domains * @see client/html/catalog/list/catid-default * @see client/html/catalog/list/size */ $domains = $config->get('client/html/catalog/domains', array('media', 'price', 'text')); /** client/html/catalog/list/domains * A list of domain names whose items should be available in the product list view template * * The templates rendering product lists usually add the images, prices * and texts associated to each product item. If you want to display additional * content like the product attributes, you can configure your own list of * domains (attribute, media, price, product, text, etc. are domains) * whose items are fetched from the storage. Please keep in mind that * the more domains you add to the configuration, the more time is required * for fetching the content! * * This configuration option overwrites the "client/html/catalog/domains" * option that allows to configure the domain names of the items fetched * for all catalog related data. * * @param array List of domain names * @since 2014.03 * @category Developer * @see client/html/catalog/domains * @see client/html/catalog/detail/domains * @see client/html/catalog/stage/domains * @see client/html/catalog/list/catid-default * @see client/html/catalog/list/size */ $domains = $config->get('client/html/catalog/list/domains', $domains); $productFilter = $this->_getProductListFilter($view); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $this->_productList = $controller->getProductList($productFilter, $this->_productTotal, $domains); }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $basketCntl = Controller_Frontend_Factory::createController($context, 'basket'); try { $langid = $basketCntl->get()->getAddress('payment')->getLanguageId(); } catch (Exception $e) { $langid = $view->param('ca_billing/order.base.address.languageid', $context->getLocale()->getLanguageId()); } $view->billingLanguage = $langid; /** client/html/checkout/standard/address/billing/hidden * List of billing address input fields that are optional and should be hidden * * You can configure the list of billing address fields that * are hidden when a customer enters his new billing address. * Available field keys are: * * order.base.address.company * * order.base.address.vatid * * order.base.address.salutation * * order.base.address.firstname * * order.base.address.lastname * * order.base.address.address1 * * order.base.address.address2 * * order.base.address.address3 * * order.base.address.postal * * order.base.address.city * * order.base.address.state * * order.base.address.languageid * * order.base.address.countryid * * order.base.address.telephone * * order.base.address.telefax * * order.base.address.email * * order.base.address.website * * Caution: Only hide fields that don't require any input * * Until 2015-02, the configuration option was available as * "client/html/common/address/billing/hidden" starting from 2014-03. * * @param array List of field keys * @since 2015.02 * @category User * @category Developer * @see client/html/checkout/standard/address/billing/disable-new * @see client/html/checkout/standard/address/billing/salutations * @see client/html/checkout/standard/address/billing/mandatory * @see client/html/checkout/standard/address/billing/optional * @see client/html/checkout/standard/address/countries */ $hidden = $view->config('client/html/checkout/standard/address/billing/hidden', array()); if (count($view->get('addressLanguages', array())) === 1) { $hidden[] = 'order.base.address.languageid'; } $salutations = array('company', 'mr', 'mrs'); /** client/html/checkout/standard/address/billing/salutations * List of salutions the customer can select from for the billing address * * The following salutations are available: * * empty string for "unknown" * * company * * mr * * mrs * * miss * * You can modify the list of salutation codes and remove the ones * which shouldn't be used. Adding new salutations is a little bit * more difficult because you have to adapt a few areas in the source * code. * * Until 2015-02, the configuration option was available as * "client/html/common/address/billing/salutations" starting from 2014-03. * * @param array List of available salutation codes * @since 2015.02 * @category User * @category Developer * @see client/html/checkout/standard/address/billing/disable-new * @see client/html/checkout/standard/address/billing/mandatory * @see client/html/checkout/standard/address/billing/optional * @see client/html/checkout/standard/address/billing/hidden * @see client/html/checkout/standard/address/countries */ $view->billingSalutations = $view->config('client/html/checkout/standard/address/billing/salutations', $salutations); $view->billingMandatory = $view->config('client/html/checkout/standard/address/billing/mandatory', $this->_mandatory); $view->billingOptional = $view->config('client/html/checkout/standard/address/billing/optional', $this->_optional); $view->billingHidden = $hidden; $this->_cache = $view; } return $this->_cache; }
/** * Returns the product items for the given IDs. * * @param string[] $ids List of product IDs * @return MShop_Product_Item_Interface[] List of product items */ protected function _getProductItems(array $ids) { $context = $this->_getContext(); $config = $context->getConfig(); /** client/html/basket/related/bought/default/domains * The list of domain names whose items should be available in the template for the products * * The templates rendering product details usually add the images, * prices and texts, etc. associated to the product * item. If you want to display additional or less content, you can * configure your own list of domains (attribute, media, price, product, * text, etc. are domains) whose items are fetched from the storage. * Please keep in mind that the more domains you add to the configuration, * the more time is required for fetching the content! * * @param array List of domain names * @since 2014.09 * @category Developer */ $domains = array('text', 'price', 'media'); $domains = $config->get('client/html/basket/related/bought/default/domains', $domains); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); return $controller->getProductItems($ids, $domains); }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $basketCntl = Controller_Frontend_Factory::createController($context, 'basket'); $serviceCntl = Controller_Frontend_Factory::createController($context, 'service'); $basket = $basketCntl->get(); $services = $serviceCntl->getServices('payment', $basket); $serviceAttributes = $servicePrices = array(); foreach ($services as $id => $service) { $serviceAttributes[$id] = $serviceCntl->getServiceAttributes('payment', $id, $basket); $servicePrices[$id] = $serviceCntl->getServicePrice('payment', $id, $basket); } $view->paymentServices = $services; $view->paymentServiceAttributes = $serviceAttributes; $view->paymentServicePrices = $servicePrices; $this->_cache = $view; } return $this->_cache; }
/** * Processes the input, e.g. store given values. * A view must be available and this method doesn't generate any output * besides setting view variables. */ public function process() { $view = $this->getView(); if ($view->param('cs-order', null) === null) { return; } try { $controller = Controller_Frontend_Factory::createController($this->_getContext(), 'basket'); $controller->get()->check(MShop_Order_Item_Base_Abstract::PARTS_ALL); parent::process(); } catch (Exception $e) { $view->standardStepActive = 'summary'; throw $e; } }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $basketCntl = Controller_Frontend_Factory::createController($context, 'basket'); $view->standardBasket = $basketCntl->get(); $basketTarget = $view->config('client/html/basket/standard/url/target'); $basketController = $view->config('client/html/basket/standard/url/controller', 'basket'); $basketAction = $view->config('client/html/basket/standard/url/action', 'index'); $basketConfig = $view->config('client/html/basket/standard/url/config', array()); /** client/html/checkout/standard/url/target * Destination of the URL where the controller specified in the URL is known * * The destination can be a page ID like in a content management system or the * module of a software development framework. This "target" must contain or know * the controller that should be called by the generated URL. * * @param string Destination of the URL * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/controller * @see client/html/checkout/standard/url/action * @see client/html/checkout/standard/url/config */ $checkoutTarget = $view->config('client/html/checkout/standard/url/target'); /** client/html/checkout/standard/url/controller * Name of the controller whose action should be called * * In Model-View-Controller (MVC) applications, the controller contains the methods * that create parts of the output displayed in the generated HTML page. Controller * names are usually alpha-numeric. * * @param string Name of the controller * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/target * @see client/html/checkout/standard/url/action * @see client/html/checkout/standard/url/config */ $checkoutController = $view->config('client/html/checkout/standard/url/controller', 'checkout'); /** client/html/checkout/standard/url/action * Name of the action that should create the output * * In Model-View-Controller (MVC) applications, actions are the methods of a * controller that create parts of the output displayed in the generated HTML page. * Action names are usually alpha-numeric. * * @param string Name of the action * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/target * @see client/html/checkout/standard/url/controller * @see client/html/checkout/standard/url/config */ $checkoutAction = $view->config('client/html/checkout/standard/url/action', 'index'); /** client/html/checkout/standard/url/config * Associative list of configuration options used for generating the URL * * You can specify additional options as key/value pairs used when generating * the URLs, like * * client/html/<clientname>/url/config = array( 'absoluteUri' => true ) * * The available key/value pairs depend on the application that embeds the e-commerce * framework. This is because the infrastructure of the application is used for * generating the URLs. The full list of available config options is referenced * in the "see also" section of this page. * * @param string Associative list of configuration options * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/target * @see client/html/checkout/standard/url/controller * @see client/html/checkout/standard/url/action * @see client/html/url/config */ $checkoutConfig = $view->config('client/html/checkout/standard/url/config', array()); /** client/html/checkout/standard/url/step-active * Name of the checkout process step to jump to if no previous step requires attention * * The checkout process consists of several steps which are usually * displayed one by another to the customer. If the data of a step * is already available, then that step is skipped. The active step * is the one that is displayed if all other steps are skipped. * * If one of the previous steps misses some data the customer has * to enter, then this step is displayed first. After providing * the missing data, the whole series of steps are tested again * and if no other step requests attention, the configured active * step will be displayed. * * The order of the steps is determined by the order of sub-parts * that are configured for the checkout client. * * @param string Name of the confirm standard HTML client * @since 2014.07 * @category Developer * @category User * @see client/html/checkout/standard/default/subparts */ $default = $view->config('client/html/checkout/standard/url/step-active', 'summary'); $steps = (array) $context->getConfig()->get($this->_subPartPath, $this->_subPartNames); $default = !in_array($default, $steps) ? reset($steps) : $default; $activeStep = $this->_getStepActive($view, $steps, $default); $step = null; do { $lastStep = $step; } while (($step = array_shift($steps)) !== null && $step !== $activeStep); if ($lastStep !== null) { $view->standardUrlBack = $view->url($checkoutTarget, $checkoutController, $checkoutAction, array('c-step' => $lastStep), array(), $checkoutConfig); } else { $view->standardUrlBack = $view->url($basketTarget, $basketController, $basketAction, array(), array(), $basketConfig); } if (($nextStep = array_shift($steps)) !== null) { $param = $activeStep === $default ? array('c-step' => $nextStep) : array(); $view->standardUrlNext = $view->url($checkoutTarget, $checkoutController, $checkoutAction, $param, array(), $checkoutConfig); } else { $view->standardUrlNext = ''; } $view->standardStepActive = $activeStep; $view->standardSteps = $steps; $this->_cache = $view; } return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $config = $context->getConfig(); $products = $this->_getProductList($view); $text = (string) $view->param('f_search'); $catid = (string) $view->param('f_catid'); if ($catid == '') { $catid = $config->get('client/html/catalog/list/catid-default', ''); } if ($text === '' && $catid !== '') { $domains = $config->get('client/html/catalog/domains', array('media', 'text')); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $view->listCatPath = $controller->getCatalogPath($catid, $domains); $listCatPath = $view->get('listCatPath', array()); if (($categoryItem = end($listCatPath)) !== false) { $view->listCurrentCatItem = $categoryItem; } $this->_addMetaItem($listCatPath, 'catalog', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($listCatPath), 'catalog', $this->_expire); } /** client/html/catalog/list/stock/enable * Enables or disables displaying product stock levels in product list views * * This configuration option allows shop owners to display product * stock levels for each product in list views or to disable * fetching product stock information. * * The stock information is fetched via AJAX and inserted via Javascript. * This allows to cache product items by leaving out such highly * dynamic content like stock levels which changes with each order. * * @param boolean Value of "1" to display stock levels, "0" to disable displaying them * @since 2014.03 * @category User * @category Developer * @see client/html/catalog/detail/stock/enable * @see client/html/catalog/stock/url/target * @see client/html/catalog/stock/url/controller * @see client/html/catalog/stock/url/action * @see client/html/catalog/stock/url/config */ if (!empty($products) && $config->get('client/html/catalog/list/stock/enable', true) === true) { /** client/html/catalog/stock/url/target * Destination of the URL where the controller specified in the URL is known * * The destination can be a page ID like in a content management system or the * module of a software development framework. This "target" must contain or know * the controller that should be called by the generated URL. * * @param string Destination of the URL * @since 2014.03 * @category Developer * @see client/html/catalog/stock/url/controller * @see client/html/catalog/stock/url/action * @see client/html/catalog/stock/url/config */ $stockTarget = $config->get('client/html/catalog/stock/url/target'); /** client/html/catalog/stock/url/controller * Name of the controller whose action should be called * * In Model-View-Controller (MVC) applications, the controller contains the methods * that create parts of the output displayed in the generated HTML page. Controller * names are usually alpha-numeric. * * @param string Name of the controller * @since 2014.03 * @category Developer * @see client/html/catalog/stock/url/target * @see client/html/catalog/stock/url/action * @see client/html/catalog/stock/url/config */ $stockController = $config->get('client/html/catalog/stock/url/controller', 'catalog'); /** client/html/catalog/stock/url/action * Name of the action that should create the output * * In Model-View-Controller (MVC) applications, actions are the methods of a * controller that create parts of the output displayed in the generated HTML page. * Action names are usually alpha-numeric. * * @param string Name of the action * @since 2014.03 * @category Developer * @see client/html/catalog/stock/url/target * @see client/html/catalog/stock/url/controller * @see client/html/catalog/stock/url/config */ $stockAction = $config->get('client/html/catalog/stock/url/action', 'stock'); /** client/html/catalog/stock/url/config * Associative list of configuration options used for generating the URL * * You can specify additional options as key/value pairs used when generating * the URLs, like * * client/html/<clientname>/url/config = array( 'absoluteUri' => true ) * * The available key/value pairs depend on the application that embeds the e-commerce * framework. This is because the infrastructure of the application is used for * generating the URLs. The full list of available config options is referenced * in the "see also" section of this page. * * @param string Associative list of configuration options * @since 2014.03 * @category Developer * @see client/html/catalog/stock/url/target * @see client/html/catalog/stock/url/controller * @see client/html/catalog/stock/url/action * @see client/html/url/config */ $stockConfig = $config->get('client/html/catalog/stock/url/config', array()); $productIds = array_keys($products); sort($productIds); $params = array('s_prodid' => implode(' ', $productIds)); $view->listStockUrl = $view->url($stockTarget, $stockController, $stockAction, $params, array(), $stockConfig); } $this->_addMetaItem($products, 'product', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($products), 'product', $this->_expire); // Delete cache when products are added or deleted even when in "tag-all" mode $this->_tags[] = 'product'; $view->listParams = $this->_getClientParams($view->param()); $view->listPageCurr = $this->_getProductListPage($view); $view->listPageSize = $this->_getProductListSize($view); $view->listProductTotal = $this->_getProductListTotal($view); $view->listProductSort = $view->param('f_sort', 'relevance'); $view->listProductItems = $products; $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { if (isset($view->detailProductItem)) { $context = $this->_getContext(); $products = $view->detailProductItem->getRefItems('product', null, 'bought-together'); /** @todo Make referenced domains configurable */ $domains = array('text', 'price', 'media'); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $view->boughtItems = $controller->getProductItems(array_keys($products), $domains); $view->boughtPosItems = $products; $this->_addMetaItem($view->boughtItems, 'product', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($view->boughtItems), 'product', $this->_expire); } $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $params = $this->_getParamStage($view); if (isset($params['f_catid']) && $params['f_catid'] != '') { $context = $this->_getContext(); $config = $context->getConfig(); $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $default = array('attribute', 'media', 'text'); /** client/html/catalog/domains * A list of domain names whose items should be available in the catalog view templates * * @see client/html/catalog/stage/domains */ $domains = $config->get('client/html/catalog/domains', $default); /** client/html/catalog/stage/default/domains * A list of domain names whose items should be available in the catalog stage view template * * The templates rendering the catalog stage section use the texts and * maybe images and attributes associated to the categories. You can * configure your own list of domains (attribute, media, price, product, * text, etc. are domains) whose items are fetched from the storage. * Please keep in mind that the more domains you add to the configuration, * the more time is required for fetching the content! * * This configuration option overwrites the "client/html/catalog/domains" * option that allows to configure the domain names of the items fetched * for all catalog related data. * * @param array List of domain names * @since 2014.03 * @category Developer * @see client/html/catalog/domains * @see client/html/catalog/detail/domains * @see client/html/catalog/list/domains */ $domains = $config->get('client/html/catalog/stage/default/domains', $domains); $stageCatPath = $controller->getCatalogPath($params['f_catid'], $domains); if (($categoryItem = end($stageCatPath)) !== false) { $view->stageCurrentCatItem = $categoryItem; } $this->_addMetaItem($stageCatPath, 'catalog', $this->_expire, $this->_tags); $this->_addMetaList(array_keys($stageCatPath), 'catalog', $this->_expire); $view->stageCatPath = $stageCatPath; } $view->stageParams = $params; $this->_cache = $view; } $expire = $this->_expires($this->_expire, $expire); $tags = array_merge($tags, $this->_tags); return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $config = $context->getConfig(); /** client/html/catalog/count/attribute/aggregate * Enables or disables generating product counts for the attribute catalog filter * * This configuration option allows shop owners to enable or disable product counts * for the attribute section of the catalog filter HTML client. * * @param boolean Disabled if "0", enabled if "1" * @since 2014.03 * @see client/html/catalog/count/limit * @category Developer * @category User */ if ($config->get('client/html/catalog/count/attribute/aggregate', true) == true) { /** client/html/catalog/count/limit * Limits the number of records that are used for product counts in the catalog filter * * The product counts in the catalog filter are generated by searching for all * products that match the criteria and then counting the number of products * that are available for each attribute or category. * * As counting huge amount of records (several 10 000 records) takes a long time, * the limit can cut down response times so the counts are available more quickly * in the front-end and the server load is reduced. * * Using a low limit can lead to incorrect numbers if the amount of found products * is very high. Approximate product counts are normally not a problem but it can * lead to the situation that visitors see that no products are available for * an attribute or in a category despite the fact that there would be at least * one. * * @param integer Number of records * @since 2014.03 * @see client/html/catalog/count/attribute/aggregate * @category Developer * @category User */ $filter = $this->_getProductListFilter($view); $filter->setSlice(0, $config->get('client/html/catalog/count/limit', 10000)); $filter->setSortations(array()); // it's not necessary and slows down the query $controller = Controller_Frontend_Factory::createController($context, 'catalog'); $view->attributeCountList = $controller->aggregate($filter, 'catalog.index.attribute.id'); } $this->_cache = $view; } return $this->_cache; }
/** * Sets the necessary parameter values in the view. * * @param MW_View_Interface $view The view object which generates the HTML output * @param array &$tags Result array for the list of tags that are associated to the output * @param string|null &$expire Result variable for the expiration date of the output (null for no expiry) * @return MW_View_Interface Modified view object */ protected function _setViewParams(MW_View_Interface $view, array &$tags = array(), &$expire = null) { if (!isset($this->_cache)) { $context = $this->_getContext(); $basketCntl = Controller_Frontend_Factory::createController($context, 'basket'); $view->standardBasket = $basketCntl->get(); $bTarget = $view->config('client/html/basket/standard/url/target'); $bCntl = $view->config('client/html/basket/standard/url/controller', 'basket'); $bAction = $view->config('client/html/basket/standard/url/action', 'index'); $bConfig = $view->config('client/html/basket/standard/url/config', array()); /** client/html/checkout/standard/url/target * Destination of the URL where the controller specified in the URL is known * * The destination can be a page ID like in a content management system or the * module of a software development framework. This "target" must contain or know * the controller that should be called by the generated URL. * * @param string Destination of the URL * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/controller * @see client/html/checkout/standard/url/action * @see client/html/checkout/standard/url/config */ $cTarget = $view->config('client/html/checkout/standard/url/target'); /** client/html/checkout/standard/url/controller * Name of the controller whose action should be called * * In Model-View-Controller (MVC) applications, the controller contains the methods * that create parts of the output displayed in the generated HTML page. Controller * names are usually alpha-numeric. * * @param string Name of the controller * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/target * @see client/html/checkout/standard/url/action * @see client/html/checkout/standard/url/config */ $cCntl = $view->config('client/html/checkout/standard/url/controller', 'checkout'); /** client/html/checkout/standard/url/action * Name of the action that should create the output * * In Model-View-Controller (MVC) applications, actions are the methods of a * controller that create parts of the output displayed in the generated HTML page. * Action names are usually alpha-numeric. * * @param string Name of the action * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/target * @see client/html/checkout/standard/url/controller * @see client/html/checkout/standard/url/config */ $cAction = $view->config('client/html/checkout/standard/url/action', 'index'); /** client/html/checkout/standard/url/config * Associative list of configuration options used for generating the URL * * You can specify additional options as key/value pairs used when generating * the URLs, like * * client/html/<clientname>/url/config = array( 'absoluteUri' => true ) * * The available key/value pairs depend on the application that embeds the e-commerce * framework. This is because the infrastructure of the application is used for * generating the URLs. The full list of available config options is referenced * in the "see also" section of this page. * * @param string Associative list of configuration options * @since 2014.03 * @category Developer * @see client/html/checkout/standard/url/target * @see client/html/checkout/standard/url/controller * @see client/html/checkout/standard/url/action * @see client/html/url/config */ $cConfig = $view->config('client/html/checkout/standard/url/config', array()); /** client/html/checkout/standard/url/step-active * Name of the checkout process step to jump to if no previous step requires attention * * The checkout process consists of several steps which are usually * displayed one by another to the customer. If the data of a step * is already available, then that step is skipped. The active step * is the one that is displayed if all other steps are skipped. * * If one of the previous steps misses some data the customer has * to enter, then this step is displayed first. After providing * the missing data, the whole series of steps are tested again * and if no other step requests attention, the configured active * step will be displayed. * * The order of the steps is determined by the order of sub-parts * that are configured for the checkout client. * * @param string Name of the confirm standard HTML client * @since 2014.07 * @category Developer * @category User * @see client/html/checkout/standard/default/subparts */ $default = $view->config('client/html/checkout/standard/url/step-active', 'summary'); /** client/html/checkout/standard/onepage * Shows all named checkout subparts at once for a one page checkout * * Normally, the checkout process is divided into several steps for entering * addresses, select delivery and payment options as well as showing the * summary page. This enables dependencies between two steps like showing * delivery options based on the address entered by the customer. Furthermore, * this is good way to limit the amount of information displayed which is * preferred by mobile users. * * Contrary to that, a one page checkout displays all information on only * one page and customers get an immediate overview of which information * they have to enter and what options they can select from. This is an * advantage if only a very limited amount of information must be entered * or if there are almost no options to choose from and no dependencies * between exist. * * Using this config options, shop developers are able to define which * checkout subparts are combined to a one page view. Simply add the names * of all checkout subparts to the list. Available checkout subparts for * a one page checkout are: * * address * * delivery * * payment * * summary * * @param array List of checkout subparts name * @since 2015.05 * @category Developer */ $onepage = $view->config('client/html/checkout/standard/onepage', array()); $onestep = array_shift($onepage); // keep the first one page step $steps = (array) $context->getConfig()->get($this->_subPartPath, $this->_subPartNames); $steps = array_diff($steps, $onepage); // remove all remaining steps in $onepage // use first step if default step isn't available $default = !in_array($default, $steps) ? reset($steps) : $default; $current = $view->param('c_step', $default); // use $onestep if current step isn't available due to one page layout $current = !in_array($current, $steps) ? $onestep : $current; $cpos = $cpos = array_search($current, $steps); if (!isset($view->standardStepActive) || ($apos = array_search($view->standardStepActive, $steps)) !== false && $cpos !== false && $cpos < $apos) { $view->standardStepActive = $current; } $activeStep = $view->standardStepActive; $view->standardSteps = $steps; $step = null; do { $lastStep = $step; } while (($step = array_shift($steps)) !== null && $step !== $activeStep); if ($lastStep !== null) { $param = array('c_step' => $lastStep); $view->standardUrlBack = $view->url($cTarget, $cCntl, $cAction, $param, array(), $cConfig); } else { $view->standardUrlBack = $view->url($bTarget, $bCntl, $bAction, array(), array(), $bConfig); } if (!isset($view->standardUrlNext) && ($nextStep = array_shift($steps)) !== null) { $param = array('c_step' => $nextStep); $view->standardUrlNext = $view->url($cTarget, $cCntl, $cAction, $param, array(), $cConfig); } // don't overwrite $view->standardUrlNext so order step URL is used $this->_cache = $view; } return $this->_cache; }