protected function compile() { $arrProducts = $this->findProducts(); // No products found if (!is_array($arrProducts) || empty($arrProducts)) { // Do not index or cache the page $objPage->noSearch = 1; $objPage->cache = 0; $this->Template->empty = true; $this->Template->type = 'empty'; $this->Template->message = $GLOBALS['TL_LANG']['MSC']['noProducts']; $this->Template->products = array(); return; } $arrBuffer = array(); foreach ($arrProducts as $objProduct) { $arrConfig = array('module' => $this, 'template' => $this->iso_list_layout ?: $objProduct->getRelated('type')->list_template, 'gallery' => $this->iso_gallery ?: $objProduct->getRelated('type')->list_gallery, 'buttons' => deserialize($this->iso_buttons, true), 'useQuantity' => $this->iso_use_quantity, 'jumpTo' => $this->findJumpToPage($objProduct)); if (\Environment::get('isAjaxRequest') && \Input::post('AJAX_MODULE') == $this->id && \Input::post('AJAX_PRODUCT') == $objProduct->getProductId()) { $objResponse = new HtmlResponse($objProduct->generate($arrConfig)); $objResponse->send(); } $arrCSS = deserialize($objProduct->cssID, true); $arrBuffer[] = array('cssID' => $arrCSS[0] != '' ? ' id="' . $arrCSS[0] . '"' : '', 'class' => trim('product ' . ($objProduct->isNew() ? 'new ' : '') . $arrCSS[1]), 'html' => $objProduct->generate($arrConfig), 'product' => $objProduct); } // HOOK: to add any product field or attribute to mod_iso_productlist template if (isset($GLOBALS['ISO_HOOKS']['generateProductList']) && is_array($GLOBALS['ISO_HOOKS']['generateProductList'])) { foreach ($GLOBALS['ISO_HOOKS']['generateProductList'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrBuffer = $objCallback->{$callback}[1]($arrBuffer, $arrProducts, $this->Template, $this); } } RowClass::withKey('class')->addCount('product_')->addEvenOdd('product_')->addFirstLast('product_')->addGridRows($this->iso_cols)->addGridCols($this->iso_cols)->applyTo($arrBuffer); $this->Template->products = $arrBuffer; }
/** * Generate the module */ protected function compile() { $objCart = Isotope::getCart(); $objAddress = $objCart->getShippingAddress(); $this->Template->showResults = false; $this->Template->requiresShipping = false; // There is no address if (!$objAddress->id) { return; } $this->Template->showResults = true; $arrMethods = array(); // Get the shipping methods if ($objAddress->id && $objCart->requiresShipping()) { $this->Template->requiresShipping = true; $objShippingMethods = Shipping::findMultipleByIds($this->arrShippingMethods); /* @var Shipping $objShipping */ foreach ($objShippingMethods as $objShipping) { if ($objShipping->isAvailable()) { $fltPrice = $objShipping->getPrice(); $arrMethods[] = array('label' => $objShipping->getLabel(), 'price' => $fltPrice, 'formatted_price' => Isotope::formatPriceWithCurrency($fltPrice), 'shipping' => $objShipping); } } RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrMethods); } $this->Template->shippingMethods = $arrMethods; }
protected function initializeData($strPeriod, $intStart, $intStop, $privateDate, $publicDate) { $arrData = array('rows' => array()); $arrData['header'] = array(array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['period'], 'header' => true), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['orders#'], 'attributes' => ' style="text-align:right"'), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['products#'], 'attributes' => ' style="text-align:right"'), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['items#'], 'attributes' => ' style="text-align:right"'), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['sales#'], 'attributes' => ' style="text-align:right"')); $arrData['footer'] = array(array('value' => $GLOBALS['TL_LANG']['ISO_REPORT']['sums']), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => array(), 'attributes' => ' style="text-align:right"')); while ($intStart <= $intStop) { $arrData['rows'][date($privateDate, $intStart)] = array('columns' => array(array('value' => $this->parseDate($publicDate, $intStart)), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'))); $intStart = strtotime('+ 1 ' . $strPeriod, $intStart); } RowClass::withKey('class')->addEvenOdd()->applyTo($arrData['rows']); return $arrData; }
/** * Compile the module * @return void */ protected function compile() { $arrConfigs = array(); $objConfigs = Config::findMultipleByIds($this->iso_config_ids); if (null !== $objConfigs) { while ($objConfigs->next()) { $arrConfigs[] = array('config' => $objConfigs->current(), 'label' => $objConfigs->current()->getLabel(), 'active' => Isotope::getConfig()->id == $objConfigs->id ? true : false, 'href' => \Environment::get('request') . (strpos(\Environment::get('request'), '?') === false ? '?' : '&') . 'config=' . $objConfigs->id); } } \Haste\Generator\RowClass::withKey('class')->addFirstLast()->applyTo($arrConfigs); $this->Template->configs = $arrConfigs; }
protected function initializeData(PeriodInterface $period, $intStart, $intStop) { $arrData = array('rows' => array()); $arrData['header'] = array(array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['period'], 'header' => true), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['orders#'], 'attributes' => ' style="text-align:right"'), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['products#'], 'attributes' => ' style="text-align:right"'), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['items#'], 'attributes' => ' style="text-align:right"'), array('value' => &$GLOBALS['TL_LANG']['ISO_REPORT']['sales#'], 'attributes' => ' style="text-align:right"')); $arrData['footer'] = array(array('value' => $GLOBALS['TL_LANG']['ISO_REPORT']['sums']), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => array(), 'attributes' => ' style="text-align:right"')); while ($intStart <= $intStop) { $arrData['rows'][$period->getKey($intStart)] = array('columns' => array(array('value' => $period->format($intStart)), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'), array('value' => 0, 'attributes' => ' style="text-align:right"'))); $intStart = $period->getNext($intStart); } RowClass::withKey('class')->addEvenOdd()->applyTo($arrData['rows']); return $arrData; }
/** * Builds the navigation array items. * * @return array */ private function buildNavigationItems() { $manager = new MPFormsFormManager($this->form); $steps = range(0, $manager->getNumberOfSteps() - 1); $items = []; $firstFailingStep = $manager->validateSteps(); foreach ($steps as $step) { // Check if step can be accessed $cantBeAccessed = true !== $firstFailingStep && $step > $firstFailingStep; // Only active if current step or step cannot be accessed because of // previous steps $isActive = $step === $manager->getCurrentStep() || $cantBeAccessed; $items[] = ['isActive' => $isActive, 'class' => 'step_' . $step . ($cantBeAccessed ? ' forbidden' : ''), 'href' => $manager->getUrlForStep($step), 'title' => $manager->getLabelForStep($step), 'link' => $manager->getLabelForStep($step), 'nofollow' => true]; } \Haste\Generator\RowClass::withKey('class')->addFirstLast()->addEvenOdd()->applyTo($items); return $items; }
/** * Generate the module * @return void */ protected function compile() { $arrOrders = array(); $objOrders = Order::findBy(array('order_status>0', 'member=?', 'config_id IN (?)'), array(\FrontendUser::getInstance()->id, implode("','", $this->iso_config_ids)), array('order' => 'locked DESC')); // No orders found, just display an "empty" message if (null === $objOrders) { $this->Template = new \Isotope\Template('mod_message'); $this->Template->type = 'empty'; $this->Template->message = $GLOBALS['TL_LANG']['ERR']['emptyOrderHistory']; return; } while ($objOrders->next()) { Isotope::setConfig($objOrders->current()->getRelated('config_id')); $arrOrders[] = array('collection' => $objOrders->current(), 'raw' => $objOrders->current()->row(), 'date' => Format::date($objOrders->current()->locked), 'time' => Format::time($objOrders->current()->locked), 'datime' => Format::datim($objOrders->current()->locked), 'grandTotal' => Isotope::formatPriceWithCurrency($objOrders->current()->getTotal()), 'status' => $objOrders->current()->getStatusLabel(), 'link' => $this->jumpTo ? \Haste\Util\Url::addQueryString('uid=' . $objOrders->current()->uniqid, $this->jumpTo) : '', 'class' => $objOrders->current()->getStatusAlias()); } RowClass::withKey('class')->addFirstLast()->addEvenOdd()->applyTo($arrOrders); $this->Template->orders = $arrOrders; }
/** * Generate the current step widgets. * @param bool * @return string|array */ protected function generateFields($blnValidate = false) { $strBuffer = ''; $arrWidgets = $this->getWidgets(); RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrWidgets); foreach ($arrWidgets as $objWidget) { $strBuffer .= $objWidget->parse(); } return $strBuffer; }
/** * Loop over items and add them to template * @param Isotope\Template * @param Callable * @return array */ protected function addItemsToTemplate(\Isotope\Template $objTemplate, $varCallable = null) { $arrItems = array(); foreach ($this->getItems($varCallable) as $objItem) { $arrItems[] = $this->generateItem($objItem); } RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrItems); $objTemplate->items = $arrItems; return $arrItems; }
/** * @param string $attribute * @param string $queryType * @param string $countType * @param bool $showClear * * @return array|null */ protected function generateAttribute($attribute, $queryType, $countType, &$showClear) { $isActive = false; $label = $attribute; // Will be updated by getOptionsForAttribute() $options = $this->getOptionsForAttribute($attribute, $label); // Must have options to apply the filter if (empty($options)) { return null; } $arrItems = $this->generateOptions($attribute, $options, $queryType, $countType, $isActive); // Hide fields with just one option (if enabled) if (empty($arrItems) || $this->iso_filterHideSingle && count($arrItems) < 2) { return null; } $objClass = RowClass::withKey('class')->addFirstLast(); if ($isActive) { $objClass->addCustom('sibling'); $showClear = true; } $objClass->applyTo($arrItems); /** @var Template|object $objTemplate */ $objTemplate = new Template($this->navigationTpl); $objTemplate->level = 'level_2'; $objTemplate->items = $arrItems; $class = $attribute . ' query_' . strtolower($queryType) . ' count_' . $countType; if ($this->isMultiple($attribute)) { $class .= ' multiple'; } if ($isActive) { $class .= ' trail'; } return array('label' => $label, 'subitems' => $objTemplate->parse(), 'isActive' => $isActive, 'class' => $class); }
/** * Include downloads when adding items to template * * @param \Isotope\Template $objTemplate * @param Callable $varCallable * * @return array */ protected function addItemsToTemplate(\Isotope\Template $objTemplate, $varCallable = null) { $taxIds = array(); $arrItems = array(); $arrAllDownloads = array(); foreach ($this->getItems($varCallable) as $objItem) { $arrDownloads = array(); $arrItem = $this->generateItem($objItem); foreach ($objItem->getDownloads() as $objDownload) { $arrDownloads = array_merge($arrDownloads, $objDownload->getForTemplate($this->isPaid())); } $arrItem['downloads'] = $arrDownloads; $arrAllDownloads = array_merge($arrAllDownloads, $arrDownloads); $taxIds[] = $arrItem['tax_id']; $arrItems[] = $arrItem; } RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrItems); $objTemplate->items = $arrItems; $objTemplate->downloads = $arrAllDownloads; $objTemplate->total_tax_ids = count(array_unique($taxIds)); return $arrItems; }
/** * Generate checkout step navigation * * @param array $arrStepKeys * * @return array */ protected function generateStepNavigation(array $arrStepKeys) { $arrItems = array(); $blnPassed = true; foreach ($arrStepKeys as $step) { $blnActive = false; $href = ''; $class = standardize($step); if ($this->strCurrentStep == $step) { $blnPassed = false; $blnActive = true; $class .= ' active'; } elseif ($blnPassed) { $href = static::generateUrlForStep($step); $class .= ' passed'; } $arrItems[] = array('isActive' => $blnActive, 'class' => $class, 'link' => $GLOBALS['TL_LANG']['MSC']['checkout_' . $step] ?: $step, 'href' => $href, 'title' => specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['checkboutStepBack'], $GLOBALS['TL_LANG']['MSC']['checkout_' . $step] ?: $step))); } // Add first/last classes RowClass::withKey('class')->addFirstLast()->applyTo($arrItems); return $arrItems; }
/** * List all addresses for the current frontend user * @return void */ protected function show() { global $objPage; $arrAddresses = array(); $strUrl = \Controller::generateFrontendUrl($objPage->row()) . ($GLOBALS['TL_CONFIG']['disableAlias'] ? '&' : '?'); $objAddresses = Address::findForMember(\FrontendUser::getInstance()->id); if (null !== $objAddresses) { while ($objAddresses->next()) { $objAddress = $objAddresses->current(); $arrAddresses[] = array_merge($objAddress->row(), array('id' => $objAddresses->id, 'class' => ($objAddress->isDefaultBilling ? 'default_billing' : '') . ($objAddress->isDefaultShipping ? ' default_shipping' : ''), 'text' => $objAddress->generateHtml(), 'edit_url' => ampersand($strUrl . 'act=edit&address=' . $objAddress->id), 'delete_url' => ampersand($strUrl . 'act=delete&address=' . $objAddress->id), 'default_billing' => $objAddress->isDefaultBilling ? true : false, 'default_shipping' => $objAddress->isDefaultShipping ? true : false)); } } if (empty($arrAddresses)) { $this->Template->mtype = 'empty'; $this->Template->message = $GLOBALS['TL_LANG']['ERR']['noAddressBookEntries']; } RowClass::withKey('class')->addFirstLast()->addEvenOdd()->applyTo($arrAddresses); $this->Template->addNewAddressLabel = $GLOBALS['TL_LANG']['MSC']['createNewAddressLabel']; $this->Template->editAddressLabel = $GLOBALS['TL_LANG']['MSC']['editAddressLabel']; $this->Template->deleteAddressLabel = $GLOBALS['TL_LANG']['MSC']['deleteAddressLabel']; $this->Template->deleteAddressConfirm = specialchars($GLOBALS['TL_LANG']['MSC']['deleteAddressConfirm']); $this->Template->addresses = $arrAddresses; $this->Template->addNewAddress = ampersand($strUrl . 'act=create'); }
/** * Loop over items and add them to template * * @param \Template $objTemplate * @param Callable $varCallable * * @return array */ protected function addItemsToTemplate(\Template $objTemplate, $varCallable = null) { $taxIds = array(); $arrItems = array(); foreach ($this->getItems($varCallable) as $objItem) { $item = $this->generateItem($objItem); $taxIds[] = $item['tax_id']; $arrItems[] = $item; } RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrItems); $objTemplate->items = $arrItems; $objTemplate->total_tax_ids = count(array_unique($taxIds)); return $arrItems; }
/** * @param array $items * * @return string */ protected function generateNavigationTemplate(array $items) { RowClass::withKey('class')->addFirstLast()->applyTo($items); $objTemplate = new FrontendTemplate($this->navigationTpl ?: 'nav_default'); $objTemplate->setData($this->arrData); $objTemplate->level = 'level_1'; $objTemplate->items = $items; return $objTemplate->parse(); }
/** * Generate a product template * * @param array $arrConfig * * @return string */ public function generate(array $arrConfig) { $this->strFormId = ($arrConfig['module'] instanceof \ContentElement ? 'cte' : 'fmd') . $arrConfig['module']->id . '_product_' . $this->getProductId(); $objProduct = $this->validateVariant(); // A variant has been loaded, generate the variant if ($objProduct->id != $this->id) { return $objProduct->generate($arrConfig); } $arrGalleries = array(); /** @type Template|object $objTemplate */ $objTemplate = new Template($arrConfig['template']); $objTemplate->setData($this->arrData); $objTemplate->product = $this; $objTemplate->config = $arrConfig; $objTemplate->generateAttribute = function ($strAttribute, array $arrOptions = array()) use($objProduct) { $objAttribute = $GLOBALS['TL_DCA']['tl_iso_product']['attributes'][$strAttribute]; if (!$objAttribute instanceof IsotopeAttribute) { throw new \InvalidArgumentException($strAttribute . ' is not a valid attribute'); } return $objAttribute->generate($objProduct, $arrOptions); }; $objTemplate->generatePrice = function () use($objProduct) { $objPrice = $objProduct->getPrice(); /** @type ProductType $objType */ $objType = $objProduct->getRelated('type'); if (null === $objPrice) { return ''; } return $objPrice->generate($objType->showPriceTiers(), 1, $objProduct->getOptions()); }; $objTemplate->getGallery = function ($strAttribute) use($objProduct, $arrConfig, &$arrGalleries) { if (!isset($arrGalleries[$strAttribute])) { $arrGalleries[$strAttribute] = Gallery::createForProductAttribute($objProduct, $strAttribute, $arrConfig); } return $arrGalleries[$strAttribute]; }; $arrVariantOptions = array(); $arrProductOptions = array(); $arrAjaxOptions = array(); foreach (array_unique(array_merge($this->getAttributes(), $this->getVariantAttributes())) as $attribute) { $arrData = $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$attribute]; if ($arrData['attributes']['customer_defined'] || $arrData['attributes']['variant_option']) { $strWidget = $this->generateProductOptionWidget($attribute, $arrVariantOptions, $arrAjaxOptions); if ($strWidget != '') { $arrProductOptions[$attribute] = array_merge($arrData, array('name' => $attribute, 'html' => $strWidget)); } } } $arrButtons = array(); // !HOOK: retrieve buttons if (isset($GLOBALS['ISO_HOOKS']['buttons']) && is_array($GLOBALS['ISO_HOOKS']['buttons'])) { foreach ($GLOBALS['ISO_HOOKS']['buttons'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrButtons = $objCallback->{$callback}[1]($arrButtons); } $arrButtons = array_intersect_key($arrButtons, array_flip($arrConfig['buttons'])); } if (\Input::post('FORM_SUBMIT') == $this->getFormId() && !$this->doNotSubmit) { foreach ($arrButtons as $button => $data) { if (isset($_POST[$button])) { if (isset($data['callback'])) { $objCallback = \System::importStatic($data['callback'][0]); $objCallback->{$data['callback'][1]}($this, $arrConfig); } break; } } } RowClass::withKey('rowClass')->addCustom('product_option')->addFirstLast()->addEvenOdd()->applyTo($arrProductOptions); $objTemplate->buttons = $arrButtons; $objTemplate->useQuantity = $arrConfig['useQuantity']; $objTemplate->minimum_quantity = $this->getMinimumQuantity(); $objTemplate->raw = $this->arrData; $objTemplate->raw_options = $this->getConfiguration(); $objTemplate->configuration = $this->getConfiguration(); $objTemplate->href = $this->generateUrl($arrConfig['jumpTo']); $objTemplate->label_detail = $GLOBALS['TL_LANG']['MSC']['detailLabel']; $objTemplate->options = $arrProductOptions; $objTemplate->hasOptions = !empty($arrProductOptions); $objTemplate->enctype = $this->hasUpload ? 'multipart/form-data' : 'application/x-www-form-urlencoded'; $objTemplate->formId = $this->getFormId(); $objTemplate->action = ampersand(\Environment::get('request'), true); $objTemplate->formSubmit = $this->getFormId(); $objTemplate->product_id = $this->getProductId(); $objTemplate->module_id = $arrConfig['module']->id; $GLOBALS['AJAX_PRODUCTS'][] = array('formId' => $this->getFormId(), 'attributes' => $arrAjaxOptions); // !HOOK: alter product data before output if (isset($GLOBALS['ISO_HOOKS']['generateProduct']) && is_array($GLOBALS['ISO_HOOKS']['generateProduct'])) { foreach ($GLOBALS['ISO_HOOKS']['generateProduct'] as $callback) { $objCallback = \System::importStatic($callback[0]); $objCallback->{$callback}[1]($objTemplate, $this); } } return $objTemplate->parse(); }
public function testGrid() { $arrTest = array(array(), array(), array(), array(), array(), array(), array(), array(), array()); RowClass::withKey('class')->addGridRows(3)->addGridCols(2)->applyTo($arrTest); $this->assertEquals($arrTest, array(array('class' => 'row_0 row_even row_first col_0 col_even col_first'), array('class' => 'row_0 row_even row_first col_1 col_odd col_last'), array('class' => 'row_1 row_odd col_0 col_even col_first'), array('class' => 'row_1 row_odd col_1 col_odd col_last'), array('class' => 'row_2 row_even col_0 col_even col_first'), array('class' => 'row_2 row_even col_1 col_odd col_last'), array('class' => 'row_3 row_odd col_0 col_even col_first'), array('class' => 'row_3 row_odd col_1 col_odd col_last'), array('class' => 'row_4 row_even row_last col_0 col_even col_first'))); $arrTest = array(array(), array(), array(), array(), array(), array(), array(), array(), array()); RowClass::withKey('class')->addGridRows(3)->addGridCols(3)->applyTo($arrTest); $this->assertEquals($arrTest, array(array('class' => 'row_0 row_even row_first col_0 col_even col_first'), array('class' => 'row_0 row_even row_first col_1 col_odd'), array('class' => 'row_0 row_even row_first col_2 col_even col_last'), array('class' => 'row_1 row_odd col_0 col_even col_first'), array('class' => 'row_1 row_odd col_1 col_odd'), array('class' => 'row_1 row_odd col_2 col_even col_last'), array('class' => 'row_2 row_even row_last col_0 col_even col_first'), array('class' => 'row_2 row_even row_last col_1 col_odd'), array('class' => 'row_2 row_even row_last col_2 col_even col_last'))); }
/** * Create the widget instances * * @return $this * @throws \RuntimeException */ public function createWidgets() { // Do nothing if already generated if (!$this->isDirty()) { return $this; } $i = 0; // Reset to initial values $this->arrWidgets = array(); $this->blnHasUploads = false; // Initialize widgets foreach ($this->arrFormFields as $strName => $arrField) { $strClass = $GLOBALS['TL_FFL'][$arrField['type']]; if (!class_exists($strClass)) { throw new \RuntimeException(sprintf('The class "%s" for type "%s" could not be found.', $strClass, $arrField['type'])); } $arrField['tableless'] = $this->blnTableless; // Some widgets render the mandatory asterisk only based on "require" attribute if (!isset($arrField['required'])) { $arrField['required'] = (bool) $arrField['mandatory']; } $objWidget = new $strClass($arrField); if ($objWidget instanceof \uploadable) { $this->blnHasUploads = true; } $this->arrWidgets[$strName] = $objWidget; $i++; } RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd()->applyTo($this->arrWidgets); $this->intState = self::STATE_CLEAN; if ($this->hasUploads()) { if ($this->getMethod() == 'GET') { throw new \RuntimeException('How do you want me to upload your file using GET?'); } $this->strEnctype = 'multipart/form-data'; } else { $this->strEnctype = 'application/x-www-form-urlencoded'; } return $this; }
/** * Compile product list. * * This function is specially designed so you can keep it in your child classes and only override findProducts(). * You will automatically gain product caching (see class property), grid classes, pagination and more. */ protected function compile() { // return message if no filter is set if ($this->iso_emptyFilter && !\Input::get('isorc') && !\Input::get('keywords')) { $this->Template->message = $this->replaceInsertTags($this->iso_noFilter); $this->Template->type = 'noFilter'; $this->Template->products = array(); return; } global $objPage; $intPage = $this->iso_category_scope == 'article' ? $GLOBALS['ISO_CONFIG']['current_article']['pid'] : $objPage->id; $arrProducts = null; $arrCacheIds = null; // Try to load the products from cache if ($this->blnCacheProducts && ($objCache = ProductCache::findForPageAndModule($intPage, $this->id)) !== null) { $arrCacheIds = $objCache->getProductIds(); // Use the cache if keywords match. Otherwise we will use the product IDs as a "limit" for findProducts() if ($objCache->keywords == \Input::get('keywords')) { $arrCacheIds = $this->generatePagination($arrCacheIds); $objProducts = Product::findAvailableByIds($arrCacheIds, array('order' => \Database::getInstance()->findInSet(Product::getTable() . '.id', $arrCacheIds))); $arrProducts = null === $objProducts ? array() : $objProducts->getModels(); // Cache is wrong, drop everything and run findProducts() if (count($arrProducts) != count($arrCacheIds)) { $arrCacheIds = null; $arrProducts = null; } } } if (!is_array($arrProducts)) { // Display "loading products" message and add cache flag if ($this->blnCacheProducts) { $blnCacheMessage = (bool) $this->iso_productcache[$intPage][(int) \Input::get('isorc')]; if ($blnCacheMessage && !\Input::get('buildCache')) { // Do not index or cache the page $objPage->noSearch = 1; $objPage->cache = 0; $this->Template = new \Isotope\Template('mod_iso_productlist_caching'); $this->Template->message = $GLOBALS['TL_LANG']['MSC']['productcacheLoading']; return; } // Start measuring how long it takes to load the products $start = microtime(true); // Load products $arrProducts = $this->findProducts($arrCacheIds); // Decide if we should show the "caching products" message the next time $end = microtime(true) - $start; $this->blnCacheProducts = $end > 1 ? true : false; $arrCacheMessage = $this->iso_productcache; if ($blnCacheMessage != $this->blnCacheProducts) { $arrCacheMessage[$intPage][(int) \Input::get('isorc')] = $this->blnCacheProducts; \Database::getInstance()->prepare("UPDATE tl_module SET iso_productcache=? WHERE id=?")->execute(serialize($arrCacheMessage), $this->id); } // Do not write cache if table is locked. That's the case if another process is already writing cache if (ProductCache::isWritable()) { \Database::getInstance()->lockTables(array(ProductCache::getTable() => 'WRITE', 'tl_iso_product' => 'READ')); $arrIds = array(); foreach ($arrProducts as $objProduct) { $arrIds[] = $objProduct->id; } // Delete existing cache if necessary ProductCache::deleteForPageAndModuleOrExpired($intPage, $this->id); $objCache = ProductCache::createForPageAndModule($intPage, $this->id); $objCache->expires = $this->getProductCacheExpiration(); $objCache->setProductIds($arrIds); $objCache->save(); \Database::getInstance()->unlockTables(); } } else { $arrProducts = $this->findProducts(); } if (!empty($arrProducts)) { $arrProducts = $this->generatePagination($arrProducts); } } // No products found if (!is_array($arrProducts) || empty($arrProducts)) { $this->compileEmptyMessage(); return; } $arrBuffer = array(); $arrDefaultOptions = $this->getDefaultProductOptions(); /** @var \Isotope\Model\Product\Standard $objProduct */ foreach ($arrProducts as $objProduct) { $arrConfig = array('module' => $this, 'template' => $this->iso_list_layout ?: $objProduct->getRelated('type')->list_template, 'gallery' => $this->iso_gallery ?: $objProduct->getRelated('type')->list_gallery, 'buttons' => deserialize($this->iso_buttons, true), 'useQuantity' => $this->iso_use_quantity, 'jumpTo' => $this->findJumpToPage($objProduct)); if (\Environment::get('isAjaxRequest') && \Input::post('AJAX_MODULE') == $this->id && \Input::post('AJAX_PRODUCT') == $objProduct->getProductId()) { $objResponse = new HtmlResponse($objProduct->generate($arrConfig)); $objResponse->send(); } $objProduct->mergeRow($arrDefaultOptions); // Must be done after setting options to generate the variant config into the URL if ($this->iso_jump_first && \Haste\Input\Input::getAutoItem('product', false, true) == '') { \Controller::redirect($objProduct->generateUrl($arrConfig['jumpTo'])); } $arrCSS = deserialize($objProduct->cssID, true); $arrBuffer[] = array('cssID' => $arrCSS[0] != '' ? ' id="' . $arrCSS[0] . '"' : '', 'class' => trim('product ' . ($objProduct->isNew() ? 'new ' : '') . $arrCSS[1]), 'html' => $objProduct->generate($arrConfig), 'product' => $objProduct); } // HOOK: to add any product field or attribute to mod_iso_productlist template if (isset($GLOBALS['ISO_HOOKS']['generateProductList']) && is_array($GLOBALS['ISO_HOOKS']['generateProductList'])) { foreach ($GLOBALS['ISO_HOOKS']['generateProductList'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrBuffer = $objCallback->{$callback}[1]($arrBuffer, $arrProducts, $this->Template, $this); } } RowClass::withKey('class')->addCount('product_')->addEvenOdd('product_')->addFirstLast('product_')->addGridRows($this->iso_cols)->addGridCols($this->iso_cols)->applyTo($arrBuffer); $this->Template->products = $arrBuffer; }
protected function addItemsToTemplate($intProductType, $objOrder, \Template $objTemplate, $varCallable = null) { $taxIds = array(); $arrItems = array(); foreach ($objOrder->getItems($varCallable) as $objItem) { // FIX - check for product type id if ($objItem->getProduct()->type != $intProductType) { continue; } // ENDFIX $item = static::generateItem($objItem); $taxIds[] = $item['tax_id']; $arrItems[] = $item; } RowClass::withKey('rowClass')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrItems); $objTemplate->items = $arrItems; $objTemplate->total_tax_ids = count(array_unique($taxIds)); return $arrItems; }
/** * Compile item list. * * This function is specially designed so you can keep it in your child classes and only override findProperties(). * You will automatically gain item caching (see class property), grid classes, pagination and more. * * @return void */ protected function compile() { //Get products $arrProducts = $this->findProducts(); // No products found if (!is_array($arrProducts) || empty($arrProducts)) { $this->compileEmptyMessage(); return; } $arrBuffer = array(); $arrDefaultOptions = $this->getDefaultProductOptions(); foreach ($arrProducts as $objProduct) { $arrConfig = array('module' => $this, 'template' => $this->iso_list_layout ?: $objProduct->getRelated('type')->list_template, 'gallery' => $this->iso_gallery ?: $objProduct->getRelated('type')->list_gallery, 'buttons' => deserialize($this->iso_buttons, true), 'useQuantity' => $this->iso_use_quantity, 'jumpTo' => $this->findJumpToPage($objProduct)); if (\Environment::get('isAjaxRequest') && \Input::post('AJAX_MODULE') == $this->id && \Input::post('AJAX_PRODUCT') == $objProduct->getProductId()) { $objResponse = new HtmlResponse($objProduct->generate($arrConfig)); $objResponse->send(); } $objProduct->mergeRow($arrDefaultOptions); // Must be done after setting options to generate the variant config into the URL if ($this->iso_jump_first && \Haste\Input\Input::getAutoItem('product') == '') { \Controller::redirect($objProduct->generateUrl($arrConfig['jumpTo'])); } $arrCSS = deserialize($objProduct->cssID, true); $arrBuffer[] = array('cssID' => $arrCSS[0] != '' ? ' id="' . $arrCSS[0] . '"' : '', 'class' => trim('product ' . ($objProduct->isNew() ? 'new ' : '') . $arrCSS[1]), 'html' => $objProduct->generate($arrConfig), 'product' => $objProduct); } // HOOK: to add any product field or attribute to mod_iso_productlist template if (isset($GLOBALS['ISO_HOOKS']['generateProductList']) && is_array($GLOBALS['ISO_HOOKS']['generateProductList'])) { foreach ($GLOBALS['ISO_HOOKS']['generateProductList'] as $callback) { $objCallback = \System::importStatic($callback[0]); $arrBuffer = $objCallback->{$callback}[1]($arrBuffer, $arrProducts, $this->Template, $this); } } RowClass::withKey('class')->addCount('product_')->addEvenOdd('product_')->addFirstLast('product_')->addGridRows($this->iso_cols)->addGridCols($this->iso_cols)->applyTo($arrBuffer); $this->Template->products = $arrBuffer; }
/** * Generates the filter */ protected function generateFilter() { $blnShowClear = false; $arrFilters = array(); foreach ($this->iso_filterFields as $strField) { $blnTrail = false; $arrItems = array(); $arrWidget = \Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strField], $strField); // Use the default routine to initialize options data foreach ($arrWidget['options'] as $option) { $varValue = $option['value']; // skip zero values (includeBlankOption) // @deprecated drop "-" when we only have the database table as options source if ($varValue === '' || $varValue === '-') { continue; } $strFilterKey = $strField . '=' . $varValue; $blnActive = Isotope::getRequestCache()->getFilterForModule($strFilterKey, $this->id) !== null; $blnTrail = $blnActive ? true : $blnTrail; $arrItems[] = array('href' => \Haste\Util\Url::addQueryString('cumulativefilter=' . base64_encode($this->id . ';' . ($blnActive ? 'del' : 'add') . ';' . $strField . ';' . $varValue)), 'class' => $blnActive ? 'active' : '', 'title' => specialchars($option['label']), 'link' => $option['label']); } if (!empty($arrItems) || $this->iso_iso_filterHideSingle && count($arrItems) < 2) { $objClass = RowClass::withKey('class')->addFirstLast(); if ($blnTrail) { $objClass->addCustom('sibling'); } $objClass->applyTo($arrItems); $objTemplate = new \Isotope\Template($this->navigationTpl); $objTemplate->level = 'level_2'; $objTemplate->items = $arrItems; $arrFilters[$strField] = array('label' => $arrWidget['label'], 'subitems' => $objTemplate->parse(), 'isActive' => $blnTrail); $blnShowClear = $blnTrail ? true : $blnShowClear; } } $this->Template->filters = $arrFilters; $this->Template->showClear = $blnShowClear; }
/** * Get formatted column labels * @return array */ protected function getColumnLabels() { $arrLabels = array(); $count = 0; foreach ($this->arrListFields as $strField) { // Use a custom label if (count($this->customLabels) > 0) { $label = $this->customLabels[$count++]; } else { // Get the label from DCA list($strTable, $strColumn) = explode('.', $strField); $label = \Haste\Util\Format::dcaLabel($strTable, $strColumn); } $arrLabels[standardize($strField)]['label'] = $label; } \Haste\Generator\RowClass::withKey('rowClass')->addCustom('row')->addCount('row_')->addFirstLast('row_')->addEvenOdd('row_')->applyTo($arrLabels); return $arrLabels; }