예제 #1
0
 /**
  * Gets the title.
  *
  * @param string $type Type possible values arte article and product
  *
  * @return string title of article (default) or product
  */
 public function getTitle($type = 'article')
 {
     switch ($type) {
         case 'product':
             return $this->product->getTitle();
         case 'article':
             // fall through
         // fall through
         default:
             return $this->article->getTitle();
     }
 }
예제 #2
0
 /**
  * This method renders a product to a template.
  *
  * @param Product $product Product
  * @param string $template TYPO3 Template
  * @param array $typoscript TypoScript
  * @param array $articleMarker Marker for the article description
  * @param string $articleSubpart Subpart
  *
  * @return string rendered HTML
  */
 public function renderProduct(Product $product, $template, array $typoscript, array $articleMarker, $articleSubpart = '')
 {
     if (!$product instanceof Product) {
         return '';
     }
     if (empty($articleMarker)) {
         return $this->error('renderProduct', __LINE__, 'No ArticleMarker defined in renderProduct ');
     }
     $hooks = HookFactory::getHooks('Controller/BaseController', 'renderProduct');
     $data = $product->returnAssocArray();
     // maybe this is a related product so category may be wrong
     $categoryUid = $this->category->getUid();
     $productCategories = $product->getParentCategories();
     if (!in_array($categoryUid, $productCategories, false)) {
         $categoryUid = $productCategories[0];
     }
     /*
      *  Build TS for Linking the Catergory Images
      */
     $localTs = $typoscript;
     $typoLinkConf = array('useCacheHash' => 1);
     /*
      * Generate TypoLink Configuration and ad to fields by addTypoLinkToTs
      */
     if ($this->conf['singlePid']) {
         $typoLinkConf['parameter'] = $this->conf['singlePid'];
     } elseif ($this->conf['overridePid']) {
         $typoLinkConf['parameter'] = $this->conf['overridePid'];
     } else {
         $typoLinkConf['parameter'] = $this->pid;
     }
     $typoLinkConf['additionalParams'] = $this->argSeparator . $this->prefixId . '[showUid]=' . $product->getUid();
     $typoLinkConf['additionalParams'] .= $this->argSeparator . $this->prefixId . '[catUid]=' . $categoryUid;
     if ($this->basketHashValue) {
         $typoLinkConf['additionalParams'] .= $this->argSeparator . $this->prefixId . '[basketHashValue]=' . $this->basketHashValue;
     }
     $localTs = $this->addTypoLinkToTypoScript($localTs, $typoLinkConf);
     $markerArray = $this->generateMarkerArray($data, $localTs, '', 'tx_commerce_products');
     $markerArrayUp = array();
     foreach ($markerArray as $k => $v) {
         $markerArrayUp[strtoupper($k)] = $v;
     }
     $markerArray = $this->cObj->fillInMarkerArray(array(), $markerArrayUp, implode(',', array_keys($markerArrayUp)), false, 'PRODUCT_');
     $this->can_attributes = $product->getAttributes(array(ATTRIB_CAN));
     $this->selectAttributes = $product->getAttributes(array(ATTRIB_SELECTOR));
     $this->shall_attributes = $product->getAttributes(array(ATTRIB_SHAL));
     $productAttributesSubpartArray = array();
     $productAttributesSubpartArray[] = '###' . strtoupper($this->conf['templateMarker.']['productAttributes']) . '###';
     $productAttributesSubpartArray[] = '###' . strtoupper($this->conf['templateMarker.']['productAttributes2']) . '###';
     $markerArray['###SUBPART_PRODUCT_ATTRIBUTES###'] = $this->cObj->stdWrap($this->renderProductAttributeList($product, $productAttributesSubpartArray, $typoscript['productAttributes.']['fields.']), $typoscript['productAttributes.']);
     $linkArray = array();
     $linkArray['catUid'] = (int) $categoryUid;
     if ($this->basketHashValue) {
         $linkArray['basketHashValue'] = $this->basketHashValue;
     }
     if (is_numeric($this->piVars['manufacturer'])) {
         $linkArray['manufacturer'] = $this->piVars['manufacturer'];
     }
     if (is_numeric($this->piVars['mDepth'])) {
         $linkArray['mDepth'] = $this->piVars['mDepth'];
     }
     foreach ($hooks as $hookObj) {
         if (method_exists($hookObj, 'postProcessLinkArray')) {
             $linkArray = $hookObj->postProcessLinkArray($linkArray, $product, $this);
         }
     }
     $wrapMarkerArray['###PRODUCT_LINK_DETAIL###'] = explode('|', $this->pi_list_linkSingle('|', $product->getUid(), true, $linkArray, false, $this->conf['overridePid']));
     $articleTemplate = $this->cObj->getSubpart($template, '###' . strtoupper($articleSubpart) . '###');
     if ($this->conf['useStockHandling'] == 1) {
         $product = \CommerceTeam\Commerce\Utility\GeneralUtility::removeNoStockArticles($product, $this->conf['articles.']['showWithNoStock']);
     }
     // Set RenderMaxArticles to TS value
     if (isset($localTs['maxArticles']) && (int) $localTs['maxArticles']) {
         $product->setRenderMaxArticles($localTs['maxArticles']);
     }
     $subpartArray = array();
     if ($this->conf['disableArticleViewForProductlist'] == 1 && !$this->piVars['showUid'] || $this->conf['disableArticleView'] == 1) {
         $subpartArray['###' . strtoupper($articleSubpart) . '###'] = '';
     } else {
         $subpartArray['###' . strtoupper($articleSubpart) . '###'] = $this->makeArticleView('list', array(), $product, $articleMarker, $articleTemplate);
     }
     /*
      * Get The Checapest Price
      */
     $cheapestArticleUid = $product->getCheapestArticle();
     /**
      * Cheapest Article.
      *
      * @var Article $cheapestArticle
      */
     $cheapestArticle = GeneralUtility::makeInstance('CommerceTeam\\Commerce\\Domain\\Model\\Article', $cheapestArticleUid);
     $cheapestArticle->loadData();
     $cheapestArticle->loadPrices();
     $markerArray['###PRODUCT_CHEAPEST_PRICE_GROSS###'] = Money::format($cheapestArticle->getPriceGross(), $this->currency);
     $cheapestArticleUid = $product->getCheapestArticle(1);
     /**
      * Cheapest Article.
      *
      * @var Article $cheapestArticle
      */
     $cheapestArticle = GeneralUtility::makeInstance('CommerceTeam\\Commerce\\Domain\\Model\\Article', $cheapestArticleUid);
     $cheapestArticle->loadData();
     $cheapestArticle->loadPrices();
     $markerArray['###PRODUCT_CHEAPEST_PRICE_NET###'] = Money::format($cheapestArticle->getPriceNet(), $this->currency);
     foreach ($hooks as $hookObj) {
         if (method_exists($hookObj, 'additionalMarkerProduct')) {
             $markerArray = $hookObj->additionalMarkerProduct($markerArray, $product, $this);
         }
     }
     foreach ($hooks as $hookObj) {
         if (method_exists($hookObj, 'additionalSubpartsProduct')) {
             $subpartArray = $hookObj->additionalSubpartsProduct($subpartArray, $product, $this);
         }
     }
     $content = $this->substituteMarkerArrayNoCached($template, $markerArray, $subpartArray, $wrapMarkerArray);
     if ($typoscript['editPanel'] == 1) {
         $content = $this->cObj->editPanel($content, $typoscript['editPanel.'], 'tx_commerce_products:' . $product->getUid());
     }
     foreach ($hooks as $hookObj) {
         if (method_exists($hookObj, 'modifyContentProduct')) {
             $content = $hookObj->modifyContentProduct($content, $product, $this);
         }
     }
     return $content;
 }
예제 #3
0
 /**
  * Remove article from product for frontendviewing, if articles
  * with no stock should not shown.
  *
  * @param \CommerceTeam\Commerce\Domain\Model\Product $product Product
  * @param int $dontRemoveArticles Switch to show or not show articles
  *
  * @return \CommerceTeam\Commerce\Domain\Model\Product Cleaned up product object
  */
 public static function removeNoStockArticles(\CommerceTeam\Commerce\Domain\Model\Product $product, $dontRemoveArticles = 1)
 {
     if ($dontRemoveArticles == 1) {
         return $product;
     }
     $articleUids = $product->getArticleUids();
     $articles = $product->getArticleObjects();
     foreach ($articleUids as $arrayKey => $articleUid) {
         /**
          * Article.
          *
          * @var \CommerceTeam\Commerce\Domain\Model\Article $article
          */
         $article = $articles[$articleUid];
         if ($article->getStock() <= 0) {
             $product->removeArticleUid($arrayKey);
             $product->removeArticle($articleUid);
         }
     }
     return $product;
 }
예제 #4
0
 /**
  * Generates payment drop down list for this shop.
  *
  * @param array $basketArray Array of template marker
  *
  * @return array Template marker
  */
 public function makePayment(array $basketArray = array())
 {
     $this->paymentProduct = GeneralUtility::makeInstance('CommerceTeam\\Commerce\\Domain\\Model\\Product', $this->conf['payProdId'], $this->getFrontendController()->sys_language_uid);
     $this->paymentProduct->loadData();
     $this->basketPaymentArticles = $this->basket->getArticlesByArticleTypeUidAsUidlist(PAYMENTARTICLETYPE);
     $select = '<select name="' . $this->prefixId . '[payArt]" onChange="this.form.submit();">';
     $addPleaseSelect = false;
     $addDefaultPaymentToBasket = false;
     // Check if a Payment is selected if not, add standard payment
     if (empty($this->basketPaymentArticles)) {
         // Check if Payment selection is forced
         if ($this->conf['payment.']['forceSelection']) {
             // Add Please Select Option
             $select .= '<option value="-1" selected="selected">' . $this->pi_getLL('lang_payment_force') . '</option>';
             $addPleaseSelect = true;
         } else {
             // No payment article is in the basket, so add the first one
             $addDefaultPaymentToBasket = true;
         }
     }
     $allowedArticles = array();
     if ($this->conf['payment.']['allowedArticles']) {
         $allowedArticles = explode(',', $this->conf['payment.']['allowedArticles']);
     }
     // Check if payment articles are allowed
     $newAllowedArticles = array();
     /**
      * Article.
      *
      * @var Article $article
      */
     foreach ($this->paymentProduct->getArticleObjects() as $articleUid => $article) {
         if (empty($allowedArticles) || in_array($articleUid, $allowedArticles)) {
             $article->loadData();
             $payment = $this->getPaymentObject($article->getClassname());
             if ($payment->isAllowed()) {
                 $newAllowedArticles[] = $articleUid;
             }
         }
     }
     // If default Paymentarticle is, for example, credit card
     // but when we have an article in the basket with the only possible
     // payment method like debit, this ensures that there is still the correct
     // payment article in the basket.
     // @todo: Refactor default handling
     if (count($newAllowedArticles) == 1 && $this->conf['defaultPaymentArticleId'] != $newAllowedArticles[0]) {
         $this->conf['defaultPaymentArticleId'] = $newAllowedArticles[0];
     }
     $allowedArticles = $newAllowedArticles;
     unset($newAllowedArticles);
     // Hook to allow to define/overwrite individually, which payment
     // articles are allowed
     $hooks = HookFactory::getHooks('Controller/BasketController', 'makePayment');
     foreach ($hooks as $hook) {
         if (method_exists($hook, 'paymentAllowedArticles')) {
             $allowedArticles = $hook->paymentAllowedArticles($this, $allowedArticles);
         }
     }
     $first = false;
     $priceNet = '';
     $priceGross = '';
     /**
      * Article.
      *
      * @var Article $article
      */
     foreach ($this->paymentProduct->getArticleObjects() as $articleUid => $article) {
         if (empty($allowedArticles) || in_array($articleUid, $allowedArticles)) {
             $select .= '<option value="' . $articleUid . '"';
             if ($articleUid == $this->basketPaymentArticles[0] || $addDefaultPaymentToBasket && $articleUid == $this->conf['defaultPaymentArticleId'] && !$addPleaseSelect) {
                 $addDefaultPaymentToBasket = false;
                 $first = true;
                 $select .= ' selected="selected"';
                 $this->basket->addArticle($articleUid);
                 $priceNet = Money::format($article->getPriceNet(), $this->currency);
                 $priceGross = Money::format($article->getPriceGross(), $this->currency);
             } elseif (!$first) {
                 $priceNet = Money::format($article->getPriceNet(), $this->currency);
                 $priceGross = Money::format($article->getPriceGross(), $this->currency);
                 $this->basket->deleteArticle($articleUid);
             }
             $select .= '>' . $article->getTitle() . '</option>';
         }
     }
     $select .= '</select>';
     // Set Prices to 0, if "please select " is shown
     if ($addPleaseSelect) {
         $priceGross = Money::format(0, $this->currency);
         $priceNet = Money::format(0, $this->currency);
     }
     $basketArray['###PAYMENT_SELECT_BOX###'] = $select;
     $basketArray['###PAYMENT_PRICE_GROSS###'] = $priceGross;
     $basketArray['###PAYMENT_PRICE_NET###'] = $priceNet;
     $this->basket->storeData();
     return $basketArray;
 }
예제 #5
0
 /**
  * Makes the rendering for all articles for a given product
  * Renders different view, based on viewKind and number of articles.
  *
  * @param string $viewKind Kind of view for choosing the right template
  * @param array $conf TSconfig for handling the articles
  * @param Product $product The parent product
  * @param array|string $templateMarkerArray Current template marker array
  * @param string $template Template text
  *
  * @return string the content for a single product
  */
 public function makeArticleView($viewKind, array $conf, Product $product, $templateMarkerArray = '', $template = '')
 {
     $hooks = HookFactory::getHooks('Controller/CheckoutController', 'makeArticleView');
     $count = is_array($product->getArticleUids()) ? count($product->getArticleUids()) : 0;
     // do nothing if no articles, BE-user-error, should not happen
     if (strlen($template) < 1) {
         $template = $this->templateCode;
     }
     $templateMarker = array();
     $templateMarkerNostock = array();
     $templateMarkerMoreThanMax = array();
     if (is_array($templateMarkerArray)) {
         foreach ($templateMarkerArray as $v) {
             $templateMarker[] = '###' . strtoupper($v) . '###';
             $templateMarkerNostock[] = '###' . strtoupper($v) . '_NOSTOCK###';
             $templateMarkerMoreThanMax[] = '###' . strtoupper($v) . '_MORETHANMAX###';
         }
     } else {
         $templateMarker[] = '###' . strtoupper($this->conf['templateMarker.'][$viewKind . '_productArticleList']) . '###';
         $templateMarker[] = '###' . strtoupper($this->conf['templateMarker.'][$viewKind . '_productArticleList2']) . '###';
         $templateMarkerNostock[] = '###' . strtoupper($this->conf['templateMarker.'][$viewKind . '_productArticleList']) . '_NOSTOCK###';
         $templateMarkerNostock[] = '###' . strtoupper($this->conf['templateMarker.'][$viewKind . '_productArticleList2']) . '_NOSTOCK###';
     }
     $content = '';
     $markerArray = array();
     if ($product->getRenderMaxArticles() > $product->getArticlesCount()) {
         // Only if the number of articles is smaller than defined
         $templateAttrSelectorDropdown = $this->cObj->getSubpart($this->templateCode, '###' . strtoupper($this->conf['templateMarker.']['productAttributesSelectorDropdown']) . '###');
         $templateAttrSelectorDropdownItem = $this->cObj->getSubpart($templateAttrSelectorDropdown, '###' . strtoupper($this->conf['templateMarker.']['productAttributesSelectorDropdown']) . '_ITEM###');
         $templateAttrSelectorRadiobutton = $this->cObj->getSubpart($this->templateCode, '###' . strtoupper($this->conf['templateMarker.']['productAttributesSelectorRadiobutton']) . '###');
         $templateAttrSelectorRadiobuttonItem = $this->cObj->getSubpart($templateAttrSelectorRadiobutton, '###' . strtoupper($this->conf['templateMarker.']['productAttributesSelectorRadiobutton']) . '_ITEM###');
         $templateCount = count($templateMarker);
         $templateAttr = array();
         if (is_array($this->conf['templateMarker.'][$viewKind . '_selectAttributes.'])) {
             foreach ($this->conf['templateMarker.'][$viewKind . '_selectAttributes.'] as $oneMarker) {
                 $templateMarkerAttr = '###' . strtoupper($oneMarker) . '###';
                 $tCode = $this->cObj->getSubpart($this->templateCode, $templateMarkerAttr);
                 if ($tCode) {
                     $templateAttr[] = $tCode;
                 }
             }
         } elseif ($this->conf['templateMarker.'][$viewKind . '_selectAttributes']) {
             $templateMarkerAttr = '###' . strtoupper($this->conf['templateMarker.'][$viewKind . '_selectAttributes']) . '###';
             $templateAttr[] = $this->cObj->getSubpart($this->templateCode, $templateMarkerAttr);
         }
         $countTemplateInterations = count($templateAttr);
         if ($this->conf['showHiddenValues'] == 1) {
             $showHiddenValues = true;
         } else {
             $showHiddenValues = false;
         }
         // Parse piVars for values and names of selected attributes
         // define $arrAttSubmit for finding the right article later
         $arrAttSubmit = array();
         foreach ($this->piVars as $key => $val) {
             if (strstr($key, 'attsel_') && $val) {
                 // set only if it is the selected product - for listing mode
                 if ($this->piVars['changedProductUid'] == $product->getUid() || $this->piVars['showUid'] == $product->getUid()) {
                     $arrAttSubmit[(int) substr($key, 7)] = (int) $val;
                     if ($this->piVars['attList_' . $product->getUid() . '_changed'] == (int) substr($key, 7)) {
                         break;
                     }
                 }
             }
         }
         // @todo wtf need to be reworked how it was ment to be
         if (is_array($arrAttSubmit)) {
             $attributeMatrix = $product->getSelectAttributeValueMatrix($arrAttSubmit);
         } else {
             $attributeMatrix = $product->getSelectAttributeValueMatrix($arrAttSubmit);
         }
         if ($this->conf['allArticles'] || $count == 1) {
             for ($i = 0; $i < $count; ++$i) {
                 $attributeArray = $product->getAttributeMatrix(array($product->getArticleUid($i)), $this->selectAttributes, $showHiddenValues);
                 $attCode = '';
                 if (is_array($attributeArray)) {
                     $ct = 0;
                     foreach ($attributeArray as $attributeUid => $myAttribute) {
                         /**
                          * Attribute.
                          *
                          * @var \CommerceTeam\Commerce\Domain\Model\Attribute $attribute
                          */
                         $attribute = GeneralUtility::makeInstance('CommerceTeam\\Commerce\\Domain\\Model\\Attribute', $attributeUid, $this->getFrontendController()->sys_language_uid);
                         $attribute->loadData();
                         $markerArray['###SELECT_ATTRIBUTES_TITLE###'] = $myAttribute['title'];
                         // @todo check where the attribute values are
                         $attrIcon = '';
                         $attrValue = '';
                         if (!empty($myAttribute['values'])) {
                             $v = current(array_splice(each($myAttribute['values']), 1, 1));
                             if (is_array($v)) {
                                 if (isset($v['value']) && $v['value'] != '') {
                                     $attrValue = $v['value'];
                                 }
                                 if (isset($v['icon']) && $v['icon'] != '') {
                                     $handle = $this->handle . '.';
                                     $attrIcon = $this->renderValue($v['icon'], 'IMAGE', $this->conf[$handle]['products.']['productAttributes.']['fields.']['icon.']);
                                 }
                             }
                         }
                         $markerArray['###SELECT_ATTRIBUTES_ICON###'] = $attrIcon;
                         if (isset($myAttribute['valueformat']) && $myAttribute['valueformat']) {
                             $markerArray['###SELECT_ATTRIBUTES_VALUE###'] = sprintf($myAttribute['valueformat'], $attrValue);
                         } else {
                             $markerArray['###SELECT_ATTRIBUTES_VALUE###'] = $attrValue;
                         }
                         $markerArray['###SELECT_ATTRIBUTES_UNIT###'] = $myAttribute['unit'];
                         $numTemplate = $ct % $countTemplateInterations;
                         $attCode .= $this->cObj->substituteMarkerArray($templateAttr[$numTemplate], $markerArray);
                         ++$ct;
                     }
                 }
                 $markerArray = (array) $this->getArticleMarker($product->getArticle($product->getArticleUid($i)));
                 $markerArray['ARTICLE_SELECT_ATTRIBUTES'] = $this->cObj->stdWrap($attCode, $this->conf['singleView.']['articleAttributesSelectList.']);
                 foreach ($hooks as $hookObj) {
                     if (method_exists($hookObj, 'additionalMarker')) {
                         $markerArray = (array) $hookObj->additionalMarker($markerArray, $this, $product->getArticle($product->getArticleUid($i)));
                     }
                 }
                 $templateAttributes = $this->cObj->getSubpart($template, $templateMarker[$i % $templateCount]);
                 /**
                  * Article.
                  *
                  * @var \CommerceTeam\Commerce\Domain\Model\Article $article
                  */
                 $article = $product->getArticle($product->getArticleUid($i));
                 if ($this->conf['useStockHandling'] == 1 and $article->getStock() <= 0) {
                     $tempTemplate = $this->cObj->getSubpart($template, $templateMarkerNostock[$i % $templateCount]);
                     if ($tempTemplate != '') {
                         $templateAttributes = $tempTemplate;
                     }
                 }
                 if (!empty($markerArray)) {
                     $content .= $this->cObj->substituteMarkerArray($templateAttributes, $markerArray, '###|###', 1);
                 }
             }
         } else {
             $sortedAttributeArray = array();
             $i = 0;
             foreach ($arrAttSubmit as $attrUid => $attrValUid) {
                 $sortedAttributeArray[$i]['AttributeUid'] = $attrUid;
                 $sortedAttributeArray[$i]['AttributeValue'] = $attrValUid;
                 ++$i;
             }
             $artId = array_shift($product->getArticlesByAttributeArray($sortedAttributeArray));
             $attCode = '';
             if (is_array($attributeMatrix)) {
                 $getVarList = array('catUid', 'showUid', 'pointer');
                 $getVars = array();
                 foreach ($getVarList as $getVar) {
                     if (isset($this->piVars[$getVar])) {
                         $getVars[$this->prefixId . '[' . $getVar . ']'] = $this->piVars[$getVar];
                     }
                 }
                 // Makes pi1 a user int so form values are updated as one selects an attribute
                 $getVars['commerce_pi1_user_int'] = 1;
                 $actionUrl = $this->cObj->typoLink_URL(array('parameter' => $GLOBALS['TSFE']->id, 'additionalParams' => GeneralUtility::implodeArrayForUrl('', $getVars), 'useCacheHash' => 1, 'section' => 'attList_' . $product->getUid()));
                 $attCode = '<form name="attList_' . $product->getUid() . '" id="attList_' . $product->getUid() . '" action="' . $actionUrl . '"  method="post">' . '<input type="hidden" name="' . $this->prefixId . '[changedProductUid]" value="' . $product->getUid() . '" />' . '<input type="hidden" name="' . $this->prefixId . '[attList_' . $product->getUid() . '_changed]" id="attList_' . $product->getUid() . '_changed" value="1" />' . '<input type="hidden" name="tx_commerce_pi1[catUid]" value="' . $this->piVars['catUid'] . '" />';
                 $markerArray = array();
                 foreach ($attributeMatrix as $attrUid => $values) {
                     /**
                      * Attribute.
                      *
                      * @var \CommerceTeam\Commerce\Domain\Model\Attribute $attribute
                      */
                     $attribute = GeneralUtility::makeInstance('CommerceTeam\\Commerce\\Domain\\Model\\Attribute', $attrUid, $this->getFrontendController()->sys_language_uid);
                     $attribute->loadData();
                     // disable the icon mode by default
                     $iconMode = false;
                     // if the icon mode is enabled in TS check if the iconMode is also enabled
                     // for this attribute
                     if ($this->conf[$this->handle . '.']['products.']['productAttributes.']['iconMode'] == '1') {
                         $iconMode = $attribute->isIconmode();
                     }
                     if ($iconMode) {
                         $templateAttrSelector = $templateAttrSelectorRadiobutton;
                         $templateAttrSelectorItem = $templateAttrSelectorRadiobuttonItem;
                     } else {
                         $templateAttrSelector = $templateAttrSelectorDropdown;
                         $templateAttrSelectorItem = $templateAttrSelectorDropdownItem;
                     }
                     $markerArray['###SELECT_ATTRIBUTES_TITLE###'] = $attribute->getTitle();
                     $markerArray['###SELECT_ATTRIBUTES_ON_CHANGE###'] = 'document.getElementById(\'attList_' . $product->getUid() . '_changed\').value = ' . $attrUid . ';document.getElementById(\'attList_' . $product->getUid() . '\').submit();';
                     $markerArray['###SELECT_ATTRIBUTES_HTML_ELEMENT_KEY###'] = $this->prefixId . '_' . $attrUid;
                     $markerArray['###SELECT_ATTRIBUTES_HTML_ELEMENT_NAME###'] = $this->prefixId . '[attsel_' . $attrUid . ']';
                     $markerArray['###SELECT_ATTRIBUTES_UNIT###'] = $attribute->getUnit();
                     $itemsContent = '';
                     $i = 1;
                     $attributeValues = $attribute->getAllValues(true, $product);
                     /**
                      * Attribute value.
                      *
                      * @var \CommerceTeam\Commerce\Domain\Model\AttributeValue $val
                      */
                     foreach ($attributeValues as $val) {
                         $markerArrayItem = $markerArray;
                         $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_VALUE###'] = $val->getUid();
                         $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_NAME###'] = $val->getValue();
                         $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_ICON###'] = $this->renderValue($val->getIcon(), 'IMAGE', $this->conf[$this->handle . '.']['products.']['productAttributes.']['fields.']['icon.']);
                         if ($values[$val->getUid()] == 'selected') {
                             $attributeArray[$attrUid] = $val->getUid();
                             if ($iconMode) {
                                 $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_STATUS###'] = 'checked="checked"';
                             } else {
                                 $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_STATUS###'] = 'selected="selected"';
                             }
                             ++$i;
                         } elseif ($values[$val->getUid()] == 'disabled') {
                             $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_STATUS###'] = 'disabled="disabled"';
                         } else {
                             $markerArrayItem['###SELECT_ATTRIBUTES_VALUE_STATUS###'] = '';
                         }
                         foreach ($hooks as $hookObj) {
                             if (method_exists($hookObj, 'additionalAttributeMarker')) {
                                 $markerArrayItem = $hookObj->additionalAttributeMarker($markerArrayItem, $this, $val->getUid());
                             }
                         }
                         $itemsContent .= $this->cObj->substituteMarkerArray($templateAttrSelectorItem, $markerArrayItem);
                         ++$i;
                     }
                     $attributeContent = $this->cObj->substituteMarkerArray($templateAttrSelector, $markerArray);
                     if ($iconMode) {
                         $attCode .= $this->cObj->substituteSubpart($attributeContent, '###' . strtoupper($this->conf['templateMarker.']['productAttributesSelectorRadiobutton']) . '_ITEM###', $itemsContent);
                     } else {
                         $attCode .= $this->cObj->substituteSubpart($attributeContent, '###' . strtoupper($this->conf['templateMarker.']['productAttributesSelectorDropdown']) . '_ITEM###', $itemsContent);
                     }
                 }
                 $attCode .= '</form>';
             }
             $markerArray = (array) $this->getArticleMarker($product->getArticle($artId));
             $markerArray['ARTICLE_SELECT_ATTRIBUTES'] = $attCode;
             foreach ($hooks as $hookObj) {
                 if (method_exists($hookObj, 'additionalMarker')) {
                     $markerArray = (array) $hookObj->additionalMarker($markerArray, $this, $product->getArticle($artId));
                 }
             }
             $templateAttributes = $this->cObj->getSubpart($template, $templateMarker[0]);
             /**
              * Article.
              *
              * @var \CommerceTeam\Commerce\Domain\Model\Article $article
              */
             $article = $product->getArticle($artId);
             if ($this->conf['useStockHandling'] == 1 and $article->getStock() <= 0) {
                 $tempTemplate = $this->cObj->getSubpart($template, $templateMarkerNostock[0]);
                 if ($tempTemplate != '') {
                     $templateAttributes = $tempTemplate;
                 }
             }
             $content .= $this->cObj->substituteMarkerArray($templateAttributes, $markerArray, '###|###', 1);
         }
     } else {
         // Special Marker and rendering when more articles are existing than
         // are allowed to render
         $localContent = $this->cObj->getSubpart($template, reset($templateMarkerMoreThanMax));
         $cat = $this->cat;
         $productCategories = $product->getParentCategories();
         if (!in_array($cat, $productCategories, false)) {
             $cat = $productCategories[0];
         }
         /*
          * Generate TypoLink Configuration and ad to fields by addTypoLinkToTs
          */
         if ($this->conf['overridePid']) {
             $typoLinkConf['parameter'] = $this->conf['overridePid'];
         } else {
             $typoLinkConf['parameter'] = $this->pid;
         }
         $typoLinkConf['useCacheHash'] = 1;
         $typoLinkConf['additionalParams'] = $this->argSeparator . $this->prefixId . '[showUid]=' . $product->getUid();
         $typoLinkConf['additionalParams'] .= $this->argSeparator . $this->prefixId . '[catUid]=' . $cat;
         if ($this->basketHashValue) {
             $typoLinkConf['additionalParams'] .= $this->argSeparator . $this->prefixId . '[basketHashValue]=' . $this->basketHashValue;
         }
         $markerArray['LINKTOPRODUCT'] = $this->cObj->typoLink($this->pi_getLL('lang_toproduct'), $typoLinkConf);
         $content = $this->cObj->substituteMarkerArray($localContent, $markerArray, '###|###', 1);
         $markerArray = array();
         foreach ($hooks as $hookObj) {
             if (method_exists($hookObj, 'additionalMarkerMakeArticleView')) {
                 $markerArray = (array) $hookObj->additionalMarkerMakeArticleView($markerArray, $product, $this);
             }
         }
     }
     $content = $this->cObj->substituteMarkerArray($content, $markerArray);
     return $content;
 }