/** * Fill the object's arrProducts array * * @param array|null $arrCacheIds * * @return array */ protected function findProducts($arrCacheIds = null) { $t = Product::getTable(); $arrColumns = array(); $arrCategories = $this->findCategories(); $arrProductIds = \Database::getInstance()->query("\n SELECT pid\n FROM tl_iso_product_category\n WHERE page_id IN (" . implode(',', $arrCategories) . ")\n ")->fetchEach('pid'); $arrTypes = \Database::getInstance()->query("SELECT id FROM tl_iso_producttype WHERE variants='1'")->fetchEach('id'); if (empty($arrProductIds)) { return array(); } $queryBuilder = new FilterQueryBuilder(Isotope::getRequestCache()->getFiltersForModules($this->iso_filterModules)); $arrColumns[] = "(\n ({$t}.id IN (" . implode(',', $arrProductIds) . ") AND {$t}.type NOT IN (" . implode(',', $arrTypes) . "))\n OR {$t}.pid IN (" . implode(',', $arrProductIds) . ")\n )"; if (!empty($arrCacheIds) && is_array($arrCacheIds)) { $arrColumns[] = Product::getTable() . ".id IN (" . implode(',', $arrCacheIds) . ")"; } // Apply new/old product filter if ($this->iso_newFilter == 'show_new') { $arrColumns[] = Product::getTable() . ".dateAdded>=" . Isotope::getConfig()->getNewProductLimit(); } elseif ($this->iso_newFilter == 'show_old') { $arrColumns[] = Product::getTable() . ".dateAdded<" . Isotope::getConfig()->getNewProductLimit(); } if ($this->iso_list_where != '') { $arrColumns[] = $this->iso_list_where; } if ($queryBuilder->hasSqlCondition()) { $arrColumns[] = $queryBuilder->getSqlWhere(); } $arrSorting = Isotope::getRequestCache()->getSortingsForModules($this->iso_filterModules); if (empty($arrSorting) && $this->iso_listingSortField != '') { $direction = $this->iso_listingSortDirection == 'DESC' ? Sort::descending() : Sort::ascending(); $arrSorting[$this->iso_listingSortField] = $direction; } $objProducts = Product::findAvailableBy($arrColumns, $queryBuilder->getSqlValues(), array('order' => 'c.sorting', 'filters' => $queryBuilder->getFilters(), 'sorting' => $arrSorting)); return null === $objProducts ? array() : $objProducts->getModels(); }
/** * Find all available property types and return as array * @param array * @return array */ public static function findAllAvailable(&$arrCategories) { $strHash = md5(implode(',', $arrCategories)); if (!\Cache::has(static::$strKey . '-' . $strHash)) { $t = Product::getTable(); $arrAvailable = array(); if (!is_array($arrCategories) || empty($arrCategories)) { $arrCategories = array(0); } //This query is by far the fastest way to get the available attributes $strQuery = "SELECT {$t}." . static::$strKey . " FROM {$t} WHERE " . static::$strKey . " != '' AND {$t}.id IN (" . implode(',', static::getProductsForCategories($arrCategories)) . ")"; if (BE_USER_LOGGED_IN !== true) { $time = time(); $strQuery .= " AND {$t}.published='1' AND ({$t}.start='' OR {$t}.start<{$time}) AND ({$t}.stop='' OR {$t}.stop>{$time})"; } $objResult = \Database::getInstance()->execute($strQuery); if ($objResult->numRows) { while ($objResult->next()) { if (strlen($objResult->{static::$strKey}) && !in_array($objResult->{static::$strKey}, $arrAvailable)) { $arrAvailable[specialchars($objResult->{static::$strKey})] = $objResult->{static::$strKey}; } } } ksort($arrAvailable); \Cache::set(static::$strKey . '-' . $strHash, $arrAvailable); } return \Cache::get(static::$strKey . '-' . $strHash); }
/** * Fill the object's arrProducts array * @param array|null * @return array */ protected function findProducts($arrCacheIds = null) { $t = Product::getTable(); $arrColumns = array(); $arrCategories = $this->findCategories(); $arrProductIds = \Database::getInstance()->query("SELECT pid FROM " . ProductCategory::getTable() . " WHERE page_id IN (" . implode(',', $arrCategories) . ")")->fetchEach('pid'); $arrTypes = \Database::getInstance()->query("SELECT id FROM " . ProductType::getTable() . " WHERE variants='1'")->fetchEach('id'); if (empty($arrProductIds)) { return array(); } list($arrFilters, $arrSorting, $strWhere, $arrValues) = $this->getFiltersAndSorting(); if (!is_array($arrValues)) { $arrValues = array(); } $arrColumns[] = "(\n ({$t}.id IN (" . implode(',', $arrProductIds) . ") AND {$t}.type NOT IN (" . implode(',', $arrTypes) . "))\n OR {$t}.pid IN (" . implode(',', $arrProductIds) . ")\n )"; if (!empty($arrCacheIds) && is_array($arrCacheIds)) { $arrColumns[] = Product::getTable() . ".id IN (" . implode(',', $arrCacheIds) . ")"; } // Apply new/old product filter if ($this->iso_newFilter == 'show_new') { $arrColumns[] = Product::getTable() . ".dateAdded>=" . Isotope::getConfig()->getNewProductLimit(); } elseif ($this->iso_newFilter == 'show_old') { $arrColumns[] = Product::getTable() . ".dateAdded<" . Isotope::getConfig()->getNewProductLimit(); } if ($this->iso_list_where != '') { $arrColumns[] = Haste::getInstance()->call('replaceInsertTags', $this->iso_list_where); } if ($strWhere != '') { $arrColumns[] = $strWhere; } $objProducts = Product::findAvailableBy($arrColumns, $arrValues, array('order' => 'c.sorting', 'filters' => $arrFilters, 'sorting' => $arrSorting)); return null === $objProducts ? array() : $objProducts->getModels(); }
/** * Check if a product can be deleted by the current backend user * Deleting is prohibited if a product has been ordered * @return bool */ public static function getUndeletableIds() { static $arrProducts; if (null === $arrProducts) { $arrProducts = \Database::getInstance()->query("\n SELECT p.type AS type FROM " . Product::getTable() . " p\n INNER JOIN " . ProductCollectionItem::getTable() . " i ON i.product_id=p.id\n INNER JOIN " . ProductCollection::getTable() . " c ON i.pid=c.id\n WHERE p.type>0 AND c.type='order'\n UNION\n SELECT p.type AS type FROM " . Product::getTable() . " p\n INNER JOIN " . Product::getTable() . " p2 ON p2.pid=p.pid\n INNER JOIN " . ProductCollectionItem::getTable() . " i ON i.product_id=p2.id\n INNER JOIN " . ProductCollection::getTable() . " c ON i.pid=c.id\n WHERE c.type='order'\n ")->fetchEach('type'); } return $arrProducts; }
/** * Generate query string for native filters * * @param array $arrFilters * * @return array */ public static function buildSqlFilters(array $arrFilters) { $strWhere = ''; $arrWhere = array(); $arrValues = array(); $arrGroups = array(); // Initiate native SQL filtering /** @var \Isotope\RequestCache\Filter $objFilter */ foreach ($arrFilters as $k => $objFilter) { if ($objFilter->hasGroup() && $arrGroups[$objFilter->getGroup()] !== false) { if ($objFilter->isDynamicAttribute()) { $arrGroups[$objFilter->getGroup()] = false; } else { $arrGroups[$objFilter->getGroup()][] = $k; } } elseif (!$objFilter->hasGroup() && !$objFilter->isDynamicAttribute()) { $arrWhere[] = $objFilter->sqlWhere(); $arrValues[] = $objFilter->sqlValue(); unset($arrFilters[$k]); } } if (!empty($arrGroups)) { foreach ($arrGroups as $arrGroup) { $arrGroupWhere = array(); // Skip dynamic attributes if (false === $arrGroup) { continue; } foreach ($arrGroup as $k) { $objFilter = $arrFilters[$k]; $arrGroupWhere[] = $objFilter->sqlWhere(); $arrValues[] = $objFilter->sqlValue(); unset($arrFilters[$k]); } $arrWhere[] = '(' . implode(' OR ', $arrGroupWhere) . ')'; } } if (!empty($arrWhere)) { $time = time(); $t = Product::getTable(); $strTemp = ""; $arrTemp = $arrWhere; if (in_array("tl_iso_product.shipping_exempt = ?", $arrTemp)) { $strTemp = 'tl_iso_product.shipping_exempt = ? AND '; unset($arrTemp[array_search('tl_iso_product.shipping_exempt = ?', $arrTemp)]); } $strTemp .= "(" . implode(' OR ', $arrTemp) . ")"; $strWhere = "\n (\n (" . $strTemp . ")\n OR {$t}.id IN (SELECT {$t}.pid FROM tl_iso_product AS {$t} WHERE {$t}.language='' AND " . implode(' AND ', $arrWhere) . (BE_USER_LOGGED_IN === true ? '' : " AND {$t}.published='1' AND ({$t}.start='' OR {$t}.start<{$time}) AND ({$t}.stop='' OR {$t}.stop>{$time})") . ")\n OR {$t}.pid IN (SELECT {$t}.id FROM tl_iso_product AS {$t} WHERE {$t}.language='' AND " . implode(' AND ', $arrWhere) . (BE_USER_LOGGED_IN === true ? '' : " AND {$t}.published='1' AND ({$t}.start='' OR {$t}.start<{$time}) AND ({$t}.stop='' OR {$t}.stop>{$time})") . ")\n )\n "; $arrValues = array_merge($arrValues, $arrValues, $arrValues); } return array($arrFilters, $strWhere, $arrValues); }
/** * Restore categories when restoring a product * * @param int $intId * @param string $strTable * @param array $arrData * @param int $intVersion */ public function restoreVersion($intId, $strTable, $arrData, $intVersion) { if ($strTable != Product::getTable()) { return; } $arrData = SubtableVersion::find(ProductCategory::getTable(), $intId, $intVersion); if (null !== $arrData) { \Database::getInstance()->query("DELETE FROM " . ProductCategory::getTable() . " WHERE pid={$intId}"); foreach ($arrData as $arrRow) { \Database::getInstance()->prepare("INSERT INTO " . ProductCategory::getTable() . " %s")->set($arrRow)->execute(); } } }
/** * Return list of default and widget legends * @param Widget * @return array */ public function getLegends($objWidget) { $this->loadDataContainer(\Isotope\Model\Attribute::getTable()); \System::loadLanguageFile(\Isotope\Model\Product::getTable()); $arrLegends = $GLOBALS['TL_DCA'][\Isotope\Model\Attribute::getTable()]['fields']['legend']['options']; $arrLegends = array_intersect_key($GLOBALS['TL_LANG'][\Isotope\Model\Product::getTable()], array_flip($arrLegends)); $varValue = $objWidget->value; if (!empty($varValue) && is_array($varValue)) { foreach ($varValue as $arrField) { if ($arrField['legend'] != '' && !isset($arrLegends[$arrField['legend']])) { $arrLegends[$arrField['legend']] = $arrField['legend']; } } } return $arrLegends; }
/** * Handle the paste button callback for tl_iso_product * @param DataContainer * @param array * @param string * @param bool * @param array * @return string * @link http://www.contao.org/callbacks.html#paste_button_callback */ public function generate(\DataContainer $dc, $row, $table, $cr, $arrClipboard = false) { // Disable all buttons if there is a circular reference if ($arrClipboard !== false && ($arrClipboard['mode'] == 'cut' && ($cr == 1 || $arrClipboard['id'] == $row['id']) || $arrClipboard['mode'] == 'cutAll' && ($cr == 1 || in_array($row['id'], $arrClipboard['id'])))) { return ''; } $objProduct = \Database::getInstance()->prepare("SELECT p.*, t.variants FROM " . \Isotope\Model\Product::getTable() . " p LEFT JOIN " . ProductType::getTable() . " t ON p.type=t.id WHERE p.id=?")->execute($arrClipboard['id']); // Copy or cut a single product or variant if ($arrClipboard['mode'] == 'cut' || $arrClipboard['mode'] == 'copy') { return $this->pasteVariant($objProduct, $table, $row, $arrClipboard); } elseif ($arrClipboard['mode'] == 'cutAll' || $arrClipboard['mode'] == 'copyAll') { return $this->pasteAll($objProduct, $table, $row, $arrClipboard); } $this->Session->set('CLIPBOARD', null); throw new \InvalidArgumentException('Unhandled paste_button_callback mode "' . $arrClipboard['mode'] . '"'); }
/** * Restore pricing information when restoring a product * @param int * @param string * @param array * @param int */ public function restoreVersion($intId, $strTable, $arrData, $intVersion) { if ($strTable != Product::getTable()) { return; } $arrData = SubtableVersion::find(ProductPrice::getTable(), $intId, $intVersion); if (null !== $arrData) { \Database::getInstance()->query("DELETE FROM tl_iso_product_pricetier WHERE pid IN (SELECT id FROM " . ProductPrice::getTable() . " WHERE pid={$intId})"); \Database::getInstance()->query("DELETE FROM " . ProductPrice::getTable() . " WHERE pid={$intId}"); foreach ($arrData['prices'] as $arrRow) { \Database::getInstance()->prepare("INSERT INTO " . ProductPrice::getTable() . " %s")->set($arrRow)->execute(); } foreach ($arrData['tiers'] as $arrRow) { \Database::getInstance()->prepare("INSERT INTO tl_iso_product_pricetier %s")->set($arrRow)->execute(); } } }
/** * Find all products we need to list. * @param array|null * @return array */ protected function findProducts($arrCacheIds = null) { $arrIds = array(0); $objProduct = Product::findAvailableByIdOrAlias(Input::getAutoItem('product')); if (null === $objProduct) { return array(); } $objRelated = RelatedProduct::findByProductAndCategories($objProduct, $this->iso_related_categories); if (null !== $objRelated) { while ($objRelated->next()) { $ids = trimsplit(',', $objRelated->products); if (!empty($ids) && is_array($ids)) { $arrIds = array_unique(array_merge($arrIds, $ids)); } } } $objProducts = Product::findAvailableByIds($arrIds, array('order' => \Database::getInstance()->findInSet(Product::getTable() . '.id', $arrIds))); return null === $objProducts ? array() : $objProducts->getModels(); }
/** * Generate header fields for product or variant * @param array * @param \Contao\DataContainer */ public function headerFields($arrFields, $dc) { $t = Product::getTable(); $arrNew = array(); $objProduct = Product::findByPk($dc->id); if (null === $objProduct) { return $arrFields; } $arrAttributes = array('name', 'alias', 'sku'); if ($objProduct->isVariant()) { $arrAttributes = array_merge($arrAttributes, array_intersect(array_merge($objProduct->getAttributes(), $objProduct->getVariantAttributes()), Attribute::getVariantOptionFields())); } foreach ($arrAttributes as $field) { $v = $objProduct->{$field}; if ($v != '') { $arrNew[Format::dcaLabel($t, $field)] = Format::dcaValue($t, $field, $v); } } // Add fields that have potentially been added through the DCA, but do not allow to override the core fields return array_merge($arrNew, array_diff_key($arrFields, $arrNew)); }
/** * Get the sorting labels (asc/desc) for an attribute * @param string * @return array */ protected static function getSortingLabels($field) { $arrData = $GLOBALS['TL_DCA'][Product::getTable()]['fields'][$field]; switch ($arrData['eval']['rgxp']) { case 'price': case 'digit': return array($GLOBALS['TL_LANG']['MSC']['low_to_high'], $GLOBALS['TL_LANG']['MSC']['high_to_low']); case 'date': case 'time': case 'datim': return array($GLOBALS['TL_LANG']['MSC']['old_to_new'], $GLOBALS['TL_LANG']['MSC']['new_to_old']); } // !HOOK: custom sorting labels if (isset($GLOBALS['ISO_HOOKS']['sortingLabels']) && is_array($GLOBALS['ISO_HOOKS']['sortingLabels'])) { foreach ($GLOBALS['ISO_HOOKS']['sortingLabels'] as $callback) { $objCallback = \System::importStatic($callback[0]); $varReturn = $objCallback->{$callback}[1]($field, $arrData, null); if ($varReturn !== false) { return $varReturn; } } } return array($GLOBALS['TL_LANG']['MSC']['a_to_z'], $GLOBALS['TL_LANG']['MSC']['z_to_a']); }
protected function compile() { $periodFactory = new PeriodFactory(); $arrSession = \Session::getInstance()->get('iso_reports'); $strPeriod = (string) $arrSession[$this->name]['period']; $intColumns = (int) $arrSession[$this->name]['columns']; $blnVariants = (bool) $arrSession[$this->name]['variants']; $intStatus = (int) $arrSession[$this->name]['iso_status']; if ($arrSession[$this->name]['from'] == '') { $intStart = strtotime('-' . ($intColumns - 1) . ' ' . $strPeriod); } else { $intStart = (int) $arrSession[$this->name]['from']; } $period = $periodFactory->create($strPeriod); $intStart = $period->getPeriodStart($intStart); $dateFrom = $period->getKey($intStart); $dateTo = $period->getKey(strtotime('+ ' . ($intColumns - 1) . ' ' . $strPeriod, $intStart)); $arrData = array('rows' => array()); $arrData['header'] = $this->getHeader($period, $intStart, $intColumns); $groupVariants = $blnVariants ? 'p1.id' : 'IF(p1.pid=0, p1.id, p1.pid)'; $objProducts = \Database::getInstance()->query("\n SELECT\n IFNULL({$groupVariants}, i.product_id) AS product_id,\n IFNULL(p1.name, i.name) AS variant_name,\n IFNULL(p2.name, i.name) AS product_name,\n p1.sku AS product_sku,\n p2.sku AS variant_sku,\n IF(p1.pid=0, p1.type, p2.type) AS type,\n i.configuration AS product_configuration,\n SUM(i.quantity) AS quantity,\n SUM(i.tax_free_price * i.quantity) AS total,\n " . $period->getSqlField($this->strDateField) . " AS dateGroup\n FROM " . ProductCollectionItem::getTable() . " i\n LEFT JOIN " . ProductCollection::getTable() . " o ON i.pid=o.id\n LEFT JOIN " . OrderStatus::getTable() . " os ON os.id=o.order_status\n LEFT OUTER JOIN " . Product::getTable() . " p1 ON i.product_id=p1.id\n LEFT OUTER JOIN " . Product::getTable() . " p2 ON p1.pid=p2.id\n WHERE o.type='order' AND o.order_status>0 AND o.locked!=''\n " . ($intStatus > 0 ? " AND o.order_status=" . $intStatus : '') . "\n " . $this->getProductProcedure('p1') . "\n " . $this->getConfigProcedure('o', 'config_id') . "\n GROUP BY dateGroup, product_id\n HAVING dateGroup>={$dateFrom} AND dateGroup<={$dateTo}\n "); // Cache product types so call to findByPk() will trigger the registry ProductType::findMultipleByIds($objProducts->fetchEach('type')); $arrRaw = array(); $objProducts->reset(); // Prepare product data while ($objProducts->next()) { $arrAttributes = array(); $arrVariantAttributes = array(); $blnHasVariants = false; // Can't use it without a type if ($objProducts->type > 0 && ($objType = ProductType::findByPk($objProducts->type)) !== null) { /** @type ProductType $objType */ $arrAttributes = $objType->getAttributes(); $arrVariantAttributes = $objType->getVariantAttributes(); $blnHasVariants = $objType->hasVariants(); $product_type_name = $objType->name; } $arrOptions = array('name' => $objProducts->variant_name); // Use product title if name is not a variant attribute if ($blnHasVariants && !in_array('name', $arrVariantAttributes)) { $arrOptions['name'] = $objProducts->product_name; } $strSku = $blnHasVariants ? $objProducts->variant_sku : $objProducts->product_sku; if (in_array('sku', $arrAttributes) && $strSku != '') { $arrOptions['name'] = sprintf('%s <span style="color:#b3b3b3; padding-left:3px;">[%s]</span>', $arrOptions['name'], $strSku); } if ($blnVariants && $blnHasVariants) { if (in_array('sku', $arrVariantAttributes) && $objProducts->product_sku != '') { $arrOptions['name'] = sprintf('%s <span style="color:#b3b3b3; padding-left:3px;">[%s]</span>', $arrOptions['name'], $objProducts->product_sku); } foreach (deserialize($objProducts->product_configuration, true) as $strName => $strValue) { if (isset($GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strName])) { $strValue = $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strName]['options'][$strValue] ? $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strName]['options'][$strValue] : $strValue; $strName = $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strName]['label'][0] ? $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$strName]['label'][0] : $strName; } $arrOptions[] = '<span class="variant">' . $strName . ': ' . $strValue . '</span>'; } } $arrOptions['name'] = '<span class="product">' . $arrOptions['name'] . '</span>'; $arrRaw[$objProducts->product_id]['name'] = implode('<br>', $arrOptions); $arrRaw[$objProducts->product_id]['product_type_name'] = $product_type_name; $arrRaw[$objProducts->product_id][$objProducts->dateGroup] = (double) $arrRaw[$objProducts->product_id][$objProducts->dateGroup] + (double) $objProducts->total; $arrRaw[$objProducts->product_id][$objProducts->dateGroup . '_quantity'] = (int) $arrRaw[$objProducts->product_id][$objProducts->dateGroup . '_quantity'] + (int) $objProducts->quantity; $arrRaw[$objProducts->product_id]['total'] = (double) $arrRaw[$objProducts->product_id]['total'] + (double) $objProducts->total; $arrRaw[$objProducts->product_id]['quantity'] = (int) $arrRaw[$objProducts->product_id]['quantity'] + (int) $objProducts->quantity; } // Prepare columns $arrColumns = array(); for ($i = 0; $i < $intColumns; $i++) { $arrColumns[] = $period->getKey($intStart); $intStart = $period->getNext($intStart); } $arrFooter = array(); // Sort the data if ($arrSession[$this->name]['tl_sort'] == 'product_name') { usort($arrRaw, function ($a, $b) { return strcasecmp($a['name'], $b['name']); }); } else { usort($arrRaw, function ($a, $b) { return $a['total'] == $b['total'] ? 0 : ($a['total'] < $b['total'] ? 1 : -1); }); } // Generate data foreach ($arrRaw as $arrProduct) { $arrRow = array(array('value' => array($arrProduct['name'], sprintf('<span style="color:#b3b3b3;">[%s]</span>', $arrProduct['product_type_name'])))); $arrFooter[0] = array('value' => $GLOBALS['TL_LANG']['ISO_REPORT']['sums']); foreach ($arrColumns as $i => $column) { $arrRow[$i + 1] = array('value' => Isotope::formatPriceWithCurrency($arrProduct[$column]) . ($arrProduct[$column . '_quantity'] !== null ? '<br><span class="variant">' . Isotope::formatItemsString($arrProduct[$column . '_quantity']) . '</span>' : '')); $arrFooter[$i + 1] = array('total' => $arrFooter[$i + 1]['total'] + $arrProduct[$column], 'quantity' => $arrFooter[$i + 1]['quantity'] + $arrProduct[$column . '_quantity']); } $arrRow[$i + 2] = array('value' => Isotope::formatPriceWithCurrency($arrProduct['total']) . ($arrProduct['quantity'] !== null ? '<br><span class="variant">' . Isotope::formatItemsString($arrProduct['quantity']) . '</span>' : '')); $arrFooter[$i + 2] = array('total' => $arrFooter[$i + 2]['total'] + $arrProduct['total'], 'quantity' => $arrFooter[$i + 2]['quantity'] + $arrProduct['quantity']); $arrData['rows'][] = array('columns' => $arrRow); } for ($i = 1; $i < count($arrFooter); $i++) { $arrFooter[$i]['value'] = Isotope::formatPriceWithCurrency($arrFooter[$i]['total']) . '<br><span class="variant">' . Isotope::formatItemsString($arrFooter[$i]['quantity']) . '</span>'; unset($arrFooter[$i]['total']); } $arrData['footer'] = $arrFooter; $this->Template->data = $arrData; }
private function countProductsForFilter(array $filters) { $arrColumns = array(); $arrCategories = $this->findCategories(); $queryBuilder = new FilterQueryBuilder($filters); $arrColumns[] = "c.page_id IN (" . implode(',', $arrCategories) . ")"; // Apply new/old product filter if ($this->iso_newFilter == self::FILTER_NEW) { $arrColumns[] = Product::getTable() . ".dateAdded>=" . Isotope::getConfig()->getNewProductLimit(); } elseif ($this->iso_newFilter == self::FILTER_OLD) { $arrColumns[] = Product::getTable() . ".dateAdded<" . Isotope::getConfig()->getNewProductLimit(); } if ($this->iso_list_where != '') { $arrColumns[] = $this->iso_list_where; } if ($queryBuilder->hasSqlCondition()) { $arrColumns[] = $queryBuilder->getSqlWhere(); } return Product::countPublishedBy($arrColumns, $queryBuilder->getSqlValues()); }
/** * Disable features that are not used in the current installation */ protected function checkFeatures() { $blnDownloads = false; $blnVariants = false; $blnAdvancedPrices = false; $blnShowSku = false; $blnShowPrice = false; $arrAttributes = array(); /** @var \Isotope\Model\ProductType[] $objProductTypes */ if (($objProductTypes = ProductType::findAllUsed()) !== null) { foreach ($objProductTypes as $objType) { if ($objType->hasDownloads()) { $blnDownloads = true; } if ($objType->hasVariants()) { $blnVariants = true; } if ($objType->hasAdvancedPrices()) { $blnAdvancedPrices = true; } if (in_array('sku', $objType->getAttributes())) { $blnShowSku = true; } if (in_array('price', $objType->getAttributes())) { $blnShowPrice = true; } $arrAttributes = array_merge($arrAttributes, $objType->getAttributes()); } } // If no downloads are enabled in any product type, we do not need the option if (!$blnDownloads) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['operations']['downloads']); } // Disable all variant related operations if (!$blnVariants) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['global_operations']['toggleVariants']); unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['operations']['generate']); } // Disable prices button if not enabled in any product type if (!$blnAdvancedPrices) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['operations']['prices']); } // Hide SKU column if not enabled in any product type if (!$blnShowSku) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['label']['fields'][2]); } // Hide price column if not enabled in any product type if (!$blnShowPrice) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['label']['fields'][3]); } // Disable sort-into-group if no groups are defined if (Group::countAll() == 0) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['operations']['group']); } // Disable related categories if none are defined if (RelatedCategory::countAll() == 0) { unset($GLOBALS['TL_DCA'][Product::getTable()]['list']['operations']['related']); } foreach (array_diff(array_keys($GLOBALS['TL_DCA'][Product::getTable()]['fields']), array_unique($arrAttributes)) as $field) { $GLOBALS['TL_DCA'][Product::getTable()]['fields'][$field]['filter'] = false; $GLOBALS['TL_DCA'][Product::getTable()]['fields'][$field]['sorting'] = false; $GLOBALS['TL_DCA'][Product::getTable()]['fields'][$field]['search'] = false; } }
/** * Add options from attribute to DCA * * @param array $arrData * @param object $objDca * * @return array */ public function addOptionsFromAttribute($arrData, $objDca) { if ($arrData['strTable'] == Product::getTable() && $arrData['optionsSource'] != '' && $arrData['optionsSource'] != 'foreignKey') { /** @var IsotopeAttributeWithOptions|Attribute $objAttribute */ $objAttribute = Attribute::findByFieldName($arrData['strField']); if (null !== $objAttribute && $objAttribute instanceof IsotopeAttributeWithOptions) { $arrOptions = $objDca instanceof IsotopeProduct ? $objAttribute->getOptionsForWidget($objDca) : $objAttribute->getOptionsForWidget(); if (!empty($arrOptions)) { if ($arrData['includeBlankOption']) { array_unshift($arrOptions, array('value' => '', 'label' => $arrData['blankOptionLabel'] ?: '-')); } $arrData['options'] = $arrOptions; if (null !== $arrData['default']) { $arrDefault = array_filter($arrOptions, function (&$option) { return (bool) $option['default']; }); if (!empty($arrDefault)) { array_walk($arrDefault, function (&$value) { $value = $value['value']; }); $arrData['value'] = $objAttribute->multiple ? $arrDefault : $arrDefault[0]; } } } } } return $arrData; }
/** * Find published products by condition * @param mixed * @param mixed * @param array * @return \Contao\Collection */ public static function countPublishedBy($arrColumns, $arrValues, $arrOptions = array()) { $p = Product_Model::getTable(); $arrValues = (array) $arrValues; if (!is_array($arrColumns)) { $arrColumns = array(); } if (BE_USER_LOGGED_IN !== true) { $time = time(); $arrColumns[] = "{$p}.published='1' AND ({$p}.start='' OR {$p}.start<{$time}) AND ({$p}.stop='' OR {$p}.stop>{$time})"; } $arrFind = array_merge(array('table' => $p, 'column' => $arrColumns, 'value' => $arrValues), (array) $arrOptions); $strQuery = QueryBuilder::find($arrFind); $strQuery = static::replaceSectionsOfString($strQuery, "SELECT ", "FROM ", "SELECT {$p}.id FROM ", true, false); $arrIDs = \Database::getInstance()->prepare($strQuery)->execute($arrValues)->fetchEach('id'); // !HOOK: custom actions if (isset($GLOBALS['ISO_HOOKS']['passFoundProducts']) && is_array($GLOBALS['ISO_HOOKS']['passFoundProducts'])) { foreach ($GLOBALS['ISO_HOOKS']['passFoundProducts'] as $callback) { $objCallback = \System::importStatic($callback[0]); $objCallback->{$callback}[1]($arrIDs); } } return (int) count($arrIDs); }
private function verifySystemIntegrity() { // Just make sure no variant or translation has any categories assigned \Database::getInstance()->query("DELETE FROM " . \Isotope\Model\ProductCategory::getTable() . " WHERE pid IN (SELECT id FROM " . \Isotope\Model\Product::getTable() . " WHERE pid>0)"); }
<?php /** * Quick Product Content Element for Isotope eCommerce and Contao Open Source CMS * * Copyright (C) 2014 HB Agency * * @package Isotope_Quickproducts * @link http://www.hbagency.com * @license http://opensource.org/licenses/lgpl-3.0.html */ /** * Palettes */ $GLOBALS['TL_DCA']['tl_content']['palettes']['isotope_quick'] = '{type_legend},type,headline;{include_legend},iso_products;{config_legend},iso_listingSortField,iso_listingSortDirection,iso_cols,iso_use_quantity,iso_buttons;{template_settings},iso_gallery,iso_list_layout;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID,space;{invisible_legend:hide},invisible,start,stop'; /** * Fields */ $GLOBALS['TL_DCA']['tl_content']['fields']['iso_products'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_products'], 'exclude' => true, 'inputType' => 'tableLookup', 'sql' => "blob NULL", 'eval' => array('mandatory' => true, 'doNotSaveEmpty' => true, 'tl_class' => 'clr', 'foreignTable' => 'tl_iso_product', 'fieldType' => 'checkbox', 'listFields' => array('type' => "(SELECT name FROM " . \Isotope\Model\ProductType::getTable() . " WHERE " . \Isotope\Model\Product::getTable() . ".type=" . \Isotope\Model\ProductType::getTable() . ".id)", 'name', 'sku'), 'searchFields' => array('name', 'alias', 'sku', 'description'), 'sqlWhere' => 'pid=0', 'searchLabel' => 'Search products')); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_gallery'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_gallery'], 'exclude' => true, 'inputType' => 'select', 'foreignKey' => \Isotope\Model\Gallery::getTable() . '.name', 'eval' => array('includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_list_layout'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_list_layout'], 'exclude' => true, 'inputType' => 'select', 'options_callback' => function (\DataContainer $dc) { return \Isotope\Backend::getTemplates('iso_list_'); }, 'eval' => array('includeBlankOption' => true, 'tl_class' => 'w50', 'chosen' => true), 'sql' => "varchar(64) NOT NULL default ''"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_use_quantity'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_use_quantity'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_cols'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_cols'], 'exclude' => true, 'default' => 1, 'inputType' => 'text', 'eval' => array('maxlength' => 1, 'rgxp' => 'digit', 'tl_class' => 'w50'), 'sql' => "int(1) unsigned NOT NULL default '1'"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_buttons'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_buttons'], 'exclude' => true, 'inputType' => 'checkboxWizard', 'default' => array('add_to_cart'), 'options_callback' => array('Isotope\\Backend\\Module\\Callback', 'getButtons'), 'eval' => array('multiple' => true, 'tl_class' => 'clr'), 'sql' => "blob NULL"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_listingSortField'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_listingSortField'], 'exclude' => true, 'inputType' => 'select', 'options_callback' => array('Isotope\\Backend\\Module\\Callback', 'getSortingFields'), 'eval' => array('includeBlankOption' => true, 'tl_class' => 'clr w50'), 'sql' => "varchar(255) NOT NULL default ''"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_listingSortDirection'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_listingSortDirection'], 'exclude' => true, 'default' => 'DESC', 'inputType' => 'select', 'options' => array('DESC', 'ASC'), 'reference' => &$GLOBALS['TL_LANG']['tl_content']['sortingDirection'], 'eval' => array('tl_class' => 'w50'), 'sql' => "varchar(8) NOT NULL default ''"); $GLOBALS['TL_DCA']['tl_content']['fields']['iso_cart_jumpTo'] = array('label' => &$GLOBALS['TL_LANG']['tl_content']['iso_cart_jumpTo'], 'exclude' => true, 'inputType' => 'pageTree', 'foreignKey' => 'tl_page.title', 'eval' => array('fieldType' => 'radio', 'tl_class' => 'clr'), 'explanation' => 'jumpTo', 'sql' => "int(10) unsigned NOT NULL default '0'", 'relation' => array('type' => 'hasOne', 'load' => 'lazy'));
<?php /** * Isotope eCommerce for Contao Open Source CMS * * Copyright (C) 2009-2014 terminal42 gmbh & Isotope eCommerce Workgroup * * @package Isotope * @link http://isotopeecommerce.org * @license http://opensource.org/licenses/lgpl-3.0.html */ /** * Table tl_iso_rule */ $GLOBALS['TL_DCA']['tl_iso_rule'] = array('config' => array('dataContainer' => 'Table', 'ctable' => array('tl_iso_rule_restriction'), 'enableVersioning' => false, 'onload_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadAttributeValues')), 'sql' => array('keys' => array('id' => 'primary'))), 'list' => array('sorting' => array('mode' => 1, 'panelLayout' => 'filter;search,limit', 'fields' => array('type', 'name')), 'label' => array('fields' => array('name', 'code'), 'format' => '%s <span style="color:#b3b3b3; padding-left:3px;">[%s]</span>'), 'global_operations' => array('all' => array('label' => &$GLOBALS['TL_LANG']['MSC']['all'], 'href' => 'act=select', 'class' => 'header_edit_all', 'attributes' => 'onclick="Backend.getScrollOffset();" accesskey="e"')), 'operations' => array('edit' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['edit'], 'href' => 'act=edit', 'icon' => 'edit.gif'), 'copy' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['copy'], 'href' => 'act=copy', 'icon' => 'copy.gif'), 'delete' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['delete'], 'href' => 'act=delete', 'icon' => 'delete.gif', 'attributes' => 'onclick="if (!confirm(\'' . $GLOBALS['TL_LANG']['MSC']['deleteConfirm'] . '\')) return false; Backend.getScrollOffset();"'), 'toggle' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['toggle'], 'icon' => 'visible.gif', 'attributes' => 'onclick="Backend.getScrollOffset(); return AjaxRequest.toggleVisibility(this, %s);"', 'button_callback' => array('\\Isotope\\Backend\\Rule\\Callback', 'toggleIcon')), 'show' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['show'], 'href' => 'act=show', 'icon' => 'show.gif'))), 'palettes' => array('__selector__' => array('type', 'applyTo', 'enableCode', 'configRestrictions', 'memberRestrictions', 'productRestrictions'), 'default' => '{basic_legend},type', 'product' => '{basic_legend},type,name,discount;{limit_legend:hide},limitPerMember,limitPerConfig,minItemQuantity,maxItemQuantity,quantityMode;{datim_legend:hide},startDate,endDate,startTime,endTime;{advanced_legend:hide},configRestrictions,memberRestrictions,productRestrictions;{enabled_legend},enabled', 'cart' => '{basic_legend},type,applyTo,name,label,discount;{coupon_legend:hide},enableCode;{limit_legend:hide},limitPerMember,limitPerConfig,minSubtotal,maxSubtotal,minItemQuantity,maxItemQuantity,quantityMode;{datim_legend:hide},startDate,endDate,startTime,endTime;{advanced_legend:hide},configRestrictions,memberRestrictions,productRestrictions;{enabled_legend},enabled', 'cartsubtotal' => '{basic_legend},type,applyTo,name,label,discount,tax_class;{coupon_legend:hide},enableCode;{limit_legend:hide},limitPerMember,limitPerConfig,minSubtotal,maxSubtotal,minItemQuantity,maxItemQuantity,quantityMode;{datim_legend:hide},startDate,endDate,startTime,endTime;{advanced_legend:hide},configRestrictions,memberRestrictions,productRestrictions;{enabled_legend},enabled'), 'subpalettes' => array('enableCode' => 'code', 'configRestrictions' => 'configs,configCondition', 'memberRestrictions_guests' => 'memberCondition', 'memberRestrictions_groups' => 'memberCondition,groups', 'memberRestrictions_members' => 'memberCondition,members', 'productRestrictions_producttypes' => 'productCondition,producttypes', 'productRestrictions_pages' => 'productCondition,pages', 'productRestrictions_products' => 'productCondition,products', 'productRestrictions_variants' => 'productCondition,variants', 'productRestrictions_attribute' => 'attributeName,attributeCondition,attributeValue'), 'fields' => array('id' => array('sql' => "int(10) unsigned NOT NULL auto_increment"), 'tstamp' => array('sql' => "int(10) unsigned NOT NULL default '0'"), 'type' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['type'], 'exclude' => true, 'filter' => true, 'default' => 'product', 'inputType' => 'select', 'options' => array('product', 'cart'), 'reference' => &$GLOBALS['TL_LANG']['tl_iso_rule']['type'], 'eval' => array('mandatory' => true, 'submitOnChange' => true, 'tl_class' => 'w50'), 'sql' => "varchar(32) NOT NULL default ''"), 'name' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['name'], 'exclude' => true, 'search' => true, 'inputType' => 'text', 'eval' => array('mandatory' => true, 'maxlength' => 255, 'tl_class' => 'clr w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'label' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['label'], 'exclude' => true, 'search' => true, 'inputType' => 'text', 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''"), 'discount' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['discount'], 'exclude' => true, 'search' => true, 'inputType' => 'text', 'eval' => array('mandatory' => true, 'maxlength' => 16, 'rgxp' => 'discount', 'tl_class' => 'clr w50'), 'sql' => "varchar(16) NOT NULL default ''"), 'tax_class' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['tax_class'], 'exclude' => true, 'filter' => true, 'inputType' => 'select', 'foreignKey' => \Isotope\Model\TaxClass::getTable() . '.name', 'options_callback' => array('\\Isotope\\Model\\TaxClass', 'getOptionsWithSplit'), 'eval' => array('includeBlankOption' => true, 'tl_class' => 'w50'), 'sql' => "int(10) NOT NULL default '0'", 'relation' => array('type' => 'hasOne', 'load' => 'lazy')), 'applyTo' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['applyTo'], 'exclude' => true, 'default' => 'products', 'inputType' => 'select', 'options' => array('products', 'items', 'subtotal'), 'reference' => &$GLOBALS['TL_LANG']['tl_iso_rule']['applyTo'], 'eval' => array('mandatory' => true, 'submitOnChange' => true, 'tl_class' => 'w50'), 'sql' => "varchar(8) NOT NULL default ''"), 'enableCode' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['enableCode'], 'exclude' => true, 'filter' => true, 'inputType' => 'checkbox', 'eval' => array('submitOnChange' => true), 'sql' => "char(1) NOT NULL default ''"), 'code' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['code'], 'exclude' => true, 'search' => true, 'inputType' => 'text', 'eval' => array('mandatory' => true, 'maxlength' => 255), 'sql' => "varchar(255) NOT NULL default ''"), 'limitPerMember' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['limitPerMember'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('rgxp' => 'digit', 'maxlength' => 10, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"), 'limitPerConfig' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['limitPerConfig'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('rgxp' => 'digit', 'maxlength' => 10, 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"), 'minSubtotal' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['minSubtotal'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('maxlength' => 10, 'rgxp' => 'digit', 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"), 'maxSubtotal' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['maxSubtotal'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('maxlength' => 10, 'rgxp' => 'digit', 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"), 'minItemQuantity' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['minItemQuantity'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('maxlength' => 10, 'rgxp' => 'digit', 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"), 'maxItemQuantity' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['maxItemQuantity'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('maxlength' => 10, 'rgxp' => 'digit', 'tl_class' => 'w50'), 'sql' => "int(10) unsigned NOT NULL default '0'"), 'quantityMode' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['quantityMode'], 'exclude' => true, 'inputType' => 'select', 'default' => 'product_quantity', 'options' => array('product_quantity', 'cart_products', 'cart_items'), 'reference' => &$GLOBALS['TL_LANG']['tl_iso_rule']['quantityMode'], 'eval' => array('tl_class' => 'w50'), 'sql' => "varchar(32) NOT NULL default ''"), 'startDate' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['startDate'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('rgxp' => 'date', 'datepicker' => true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(10) NOT NULL default ''"), 'endDate' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['endDate'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('rgxp' => 'date', 'datepicker' => true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(10) NOT NULL default ''"), 'startTime' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['startTime'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('rgxp' => 'time', 'datepicker' => true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(10) NOT NULL default ''"), 'endTime' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['endTime'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('rgxp' => 'time', 'datepicker' => true, 'tl_class' => 'w50 wizard'), 'sql' => "varchar(10) NOT NULL default ''"), 'configRestrictions' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['configRestrictions'], 'inputType' => 'checkbox', 'exclude' => true, 'filter' => true, 'eval' => array('submitOnChange' => true, 'tl_class' => 'clr'), 'sql' => "char(1) NOT NULL default ''"), 'configCondition' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['configCondition'], 'exclude' => true, 'default' => '1', 'inputType' => 'radio', 'options' => array('1' => $GLOBALS['TL_LANG']['tl_iso_rule']['condition_true'], '0' => $GLOBALS['TL_LANG']['tl_iso_rule']['condition_false']), 'eval' => array('isAssociative' => true, 'tl_class' => 'w50'), 'sql' => "tinyint(1) NOT NULL default '0'"), 'configs' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['configs'], 'exclude' => true, 'inputType' => 'checkbox', 'foreignKey' => \Isotope\Model\Config::getTable() . '.name', 'eval' => array('mandatory' => true, 'multiple' => true, 'doNotSaveEmpty' => true, 'tl_class' => 'clr w50 w50h'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'memberRestrictions' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['memberRestrictions'], 'inputType' => 'radio', 'default' => 'none', 'exclude' => true, 'filter' => true, 'options' => array('none', 'guests', 'groups', 'members'), 'reference' => &$GLOBALS['TL_LANG']['tl_iso_rule']['memberRestrictions'], 'eval' => array('submitOnChange' => true, 'tl_class' => 'clr w50 w50h'), 'sql' => "varchar(32) NOT NULL default ''"), 'memberCondition' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['memberCondition'], 'exclude' => true, 'default' => '1', 'inputType' => 'radio', 'options' => array('1' => $GLOBALS['TL_LANG']['tl_iso_rule']['condition_true'], '0' => $GLOBALS['TL_LANG']['tl_iso_rule']['condition_false']), 'eval' => array('isAssociative' => true, 'tl_class' => 'w50'), 'sql' => "tinyint(1) NOT NULL default '0'"), 'groups' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['groups'], 'exclude' => true, 'inputType' => 'checkbox', 'foreignKey' => 'tl_member_group.name', 'eval' => array('mandatory' => true, 'multiple' => true, 'doNotSaveEmpty' => true, 'tl_class' => 'clr'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'members' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['members'], 'exclude' => true, 'inputType' => 'tableLookup', 'eval' => array('mandatory' => true, 'doNotSaveEmpty' => true, 'tl_class' => 'clr', 'foreignTable' => 'tl_member', 'fieldType' => 'checkbox', 'listFields' => array('firstname', 'lastname', 'username', 'email'), 'searchFields' => array('firstname', 'lastname', 'username', 'email'), 'sqlWhere' => '', 'searchLabel' => 'Search members'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'productRestrictions' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['productRestrictions'], 'inputType' => 'radio', 'default' => 'none', 'exclude' => true, 'filter' => true, 'options' => array('none', 'producttypes', 'pages', 'products', 'variants', 'attribute'), 'reference' => &$GLOBALS['TL_LANG']['tl_iso_rule']['productRestrictions'], 'eval' => array('submitOnChange' => true, 'tl_class' => 'clr w50 w50h'), 'sql' => "varchar(32) NOT NULL default ''"), 'productCondition' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['productCondition'], 'exclude' => true, 'default' => '1', 'inputType' => 'radio', 'options' => array('1' => $GLOBALS['TL_LANG']['tl_iso_rule']['condition_true'], '0' => $GLOBALS['TL_LANG']['tl_iso_rule']['condition_false']), 'eval' => array('isAssociative' => true, 'tl_class' => 'w50'), 'sql' => "tinyint(1) NOT NULL default '0'"), 'producttypes' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['producttypes'], 'exclude' => true, 'inputType' => 'checkbox', 'foreignKey' => \Isotope\Model\ProductType::getTable() . '.name', 'eval' => array('mandatory' => true, 'multiple' => true, 'doNotSaveEmpty' => true, 'tl_class' => 'clr'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'pages' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['pages'], 'exclude' => true, 'inputType' => 'pageTree', 'foreignKey' => 'tl_page.title', 'eval' => array('mandatory' => true, 'multiple' => true, 'fieldType' => 'checkbox', 'doNotSaveEmpty' => true, 'tl_class' => 'clr'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'products' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['products'], 'exclude' => true, 'inputType' => 'tableLookup', 'eval' => array('mandatory' => true, 'doNotSaveEmpty' => true, 'tl_class' => 'clr', 'foreignTable' => 'tl_iso_product', 'fieldType' => 'checkbox', 'listFields' => array('type' => "(SELECT name FROM " . \Isotope\Model\ProductType::getTable() . " WHERE " . \Isotope\Model\Product::getTable() . ".type=" . \Isotope\Model\ProductType::getTable() . ".id)", 'name', 'sku'), 'searchFields' => array('name', 'alias', 'sku', 'description'), 'sqlWhere' => 'pid=0', 'searchLabel' => 'Search products'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'variants' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['variants'], 'exclude' => true, 'inputType' => 'text', 'eval' => array('mandatory' => true, 'doNotSaveEmpty' => true, 'csv' => ',', 'tl_class' => 'clr long'), 'load_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'loadRestrictions')), 'save_callback' => array(array('\\Isotope\\Backend\\Rule\\Callback', 'saveRestrictions'))), 'attributeName' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['attributeName'], 'exclude' => true, 'inputType' => 'select', 'options_callback' => array('\\Isotope\\Backend\\Rule\\Callback', 'getAttributeNames'), 'eval' => array('mandatory' => true, 'includeBlankOption' => true, 'submitOnChange' => true, 'tl_class' => 'clr w50'), 'sql' => "varchar(32) NOT NULL default ''"), 'attributeCondition' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['attributeCondition'], 'exclude' => true, 'inputType' => 'select', 'options' => array('eq', 'neq', 'lt', 'gt', 'elt', 'egt', 'starts', 'ends', 'contains'), 'reference' => &$GLOBALS['TL_LANG']['tl_iso_rule']['attributeCondition'], 'eval' => array('mandatory' => true, 'tl_class' => 'w50'), 'sql' => "varchar(8) NOT NULL default ''"), 'attributeValue' => array('exclude' => true, 'eval' => array('decodeEntities' => true, 'tl_class' => 'clr'), 'sql' => "varchar(255) NOT NULL default ''"), 'enabled' => array('label' => &$GLOBALS['TL_LANG']['tl_iso_rule']['enabled'], 'exclude' => true, 'inputType' => 'checkbox', 'filter' => true, 'sql' => "char(1) NOT NULL default ''")));
/** * Generate ajax */ public function generateAjax() { if (!\Environment::get('isAjaxRequest')) { return; } // todo: Use the current filters too... if ($this->iso_searchAutocomplete && \Input::get('iso_autocomplete') == $this->id) { include_once TL_ROOT . '/system/modules/isotope_direct/config/stopwords.php'; $arrWhere = array("c.page_id IN (" . implode(',', array_map('intval', $this->findCategories())) . ")"); $arrValues = array(); $keywords = explode(' ', \Input::get('query')); for ($i = 0; $i < count($keywords); $i++) { $strTerm = trim($keywords[$i]); if (empty($strTerm) || in_array(strtolower($strTerm), array_map('strtolower', $GLOBALS['KEYWORD_STOP_WORDS'])) || in_array(strtolower($strTerm), array_map('strtolower', $GLOBALS['KEYWORD_STOP_WORDS']))) { continue; } $arrWhere[] = Product_Model::getTable() . "." . $this->iso_searchAutocomplete . " REGEXP ?"; $arrValues[] = $strTerm; } if ($this->iso_list_where != '') { $arrWhere[] = Haste::getInstance()->call('replaceInsertTags', $this->iso_list_where); } $objProducts = Product_Model::findPublishedBy($arrWhere, $arrValues, array('order' => "c.sorting")); if (null === $objProducts) { $objResponse = new JsonResponse(array('suggestions' => array())); $objResponse->send(); } $objResponse = new JsonResponse(array('suggestions' => array_values(array_map('html_entity_decode', $objProducts->fetchEach($this->iso_searchAutocomplete))))); $objResponse->send(); } }
/** * Find all products we need to list. * * @param array|null $arrCacheIds * * @return array */ protected function findProducts($arrCacheIds = null) { $arrColumns = array(); $arrCategories = $this->findCategories(); $queryBuilder = new FilterQueryBuilder(Isotope::getRequestCache()->getFiltersForModules($this->iso_filterModules)); $arrColumns[] = "c.page_id IN (" . implode(',', $arrCategories) . ")"; if (!empty($arrCacheIds) && is_array($arrCacheIds)) { $arrColumns[] = Product::getTable() . ".id IN (" . implode(',', $arrCacheIds) . ")"; } // Apply new/old product filter if ($this->iso_newFilter == 'show_new') { $arrColumns[] = Product::getTable() . ".dateAdded>=" . Isotope::getConfig()->getNewProductLimit(); } elseif ($this->iso_newFilter == 'show_old') { $arrColumns[] = Product::getTable() . ".dateAdded<" . Isotope::getConfig()->getNewProductLimit(); } if ($this->iso_list_where != '') { $arrColumns[] = $this->iso_list_where; } if ($queryBuilder->hasSqlCondition()) { $arrColumns[] = $queryBuilder->getSqlWhere(); } $arrSorting = Isotope::getRequestCache()->getSortingsForModules($this->iso_filterModules); if (empty($arrSorting) && $this->iso_listingSortField != '') { $direction = $this->iso_listingSortDirection == 'DESC' ? Sort::descending() : Sort::ascending(); $arrSorting[$this->iso_listingSortField] = $direction; } $objProducts = Product::findAvailableBy($arrColumns, $queryBuilder->getSqlValues(), array('order' => 'c.sorting', 'filters' => $queryBuilder->getFilters(), 'sorting' => $arrSorting)); return null === $objProducts ? array() : $objProducts->getModels(); }
/** * Get WHERE statement for SQL filter * @return string */ public function sqlWhere() { if ($this->isMultilingualAttribute()) { $strWhere = 'IFNULL(translation.' . $this->arrConfig['attribute'] . ', ' . Product::getTable() . '.' . $this->arrConfig['attribute'] . ')'; } else { $strWhere = Product::getTable() . '.' . $this->arrConfig['attribute']; } $strWhere .= ' ' . $this->getOperatorForSQL() . ' ?'; return $strWhere; }
/** * Find all products we need to list. * @param array|null * @return array */ protected function findProducts($arrCacheIds = null) { $arrColumns = array(); $arrCategories = $this->findCategories(); list($arrFilters, $arrSorting, $strWhere, $arrValues) = $this->getFiltersAndSorting(); if (!is_array($arrValues)) { $arrValues = array(); } $arrColumns[] = "c.page_id IN (" . implode(',', $arrCategories) . ")"; if (!empty($arrCacheIds) && is_array($arrCacheIds)) { $arrColumns[] = Product::getTable() . ".id IN (" . implode(',', $arrCacheIds) . ")"; } // Apply new/old product filter if ($this->iso_newFilter == 'show_new') { $arrColumns[] = Product::getTable() . ".dateAdded>=" . Isotope::getConfig()->getNewProductLimit(); } elseif ($this->iso_newFilter == 'show_old') { $arrColumns[] = Product::getTable() . ".dateAdded<" . Isotope::getConfig()->getNewProductLimit(); } if ($this->iso_list_where != '') { $arrColumns[] = Haste::getInstance()->call('replaceInsertTags', $this->iso_list_where); } if ($strWhere != '') { $arrColumns[] = $strWhere; } $objProducts = Product::findAvailableBy($arrColumns, $arrValues, array('order' => 'c.sorting', 'filters' => $arrFilters, 'sorting' => $arrSorting)); return null === $objProducts ? array() : $objProducts->getModels(); }
/** * Generate query string for native filters * * @param array $arrFilters */ private function buildSqlFilters(array $arrFilters) { $strWhere = ''; $arrWhere = array(); $arrValues = array(); $arrGroups = array(); // Initiate native SQL filtering /** @var \Isotope\RequestCache\Filter $objFilter */ foreach ($arrFilters as $k => $objFilter) { if ($objFilter->hasGroup() && $arrGroups[$objFilter->getGroup()] !== false) { if ($objFilter->isDynamicAttribute()) { $arrGroups[$objFilter->getGroup()] = false; } else { $arrGroups[$objFilter->getGroup()][] = $k; } } elseif (!$objFilter->hasGroup() && !$objFilter->isDynamicAttribute()) { $arrWhere[] = $objFilter->sqlWhere(); $arrValues[] = $objFilter->sqlValue(); unset($arrFilters[$k]); } } if (!empty($arrGroups)) { foreach ($arrGroups as $arrGroup) { $arrGroupWhere = array(); // Skip dynamic attributes if (false === $arrGroup) { continue; } foreach ($arrGroup as $k) { $objFilter = $arrFilters[$k]; $arrGroupWhere[] = $objFilter->sqlWhere(); $arrValues[] = $objFilter->sqlValue(); unset($arrFilters[$k]); } $arrWhere[] = '(' . implode(' OR ', $arrGroupWhere) . ')'; } } if (!empty($arrWhere)) { $strWhere = implode(' AND ', $arrWhere); if (ProductType::countByVariants() > 0) { $time = \Date::floorToMinute(); $t = Product::getTable(); $protected = ''; if (BE_USER_LOGGED_IN === true) { $protected = "\n AND {$t}.published='1'\n AND ({$t}.start='' OR {$t}.start<'{$time}')\n AND ({$t}.stop='' OR {$t}.stop>'" . ($time + 60) . "')"; } $strWhere = "\n (\n ({$strWhere})\n OR {$t}.id IN (\n SELECT {$t}.pid\n FROM tl_iso_product AS {$t}\n WHERE {$t}.language='' AND " . implode(' AND ', $arrWhere) . "\n {$protected}\n )\n OR {$t}.pid IN (\n SELECT {$t}.id\n FROM tl_iso_product AS {$t}\n WHERE {$t}.language='' AND " . implode(' AND ', $arrWhere) . "\n {$protected}\n )\n )\n "; $arrValues = array_merge($arrValues, $arrValues, $arrValues); } } $this->filters = $arrFilters; $this->sqlWhere = $strWhere; $this->sqlValues = $arrValues; }
$GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['isotope']['iso_order_status_change']['email_recipient_bcc'] =& $GLOBALS['NOTIFICATION_CENTER']['NOTIFICATION_TYPE']['isotope']['iso_order_status_change']['recipients']; /** * Models */ $GLOBALS['TL_MODELS'][\Isotope\Model\Address::getTable()] = 'Isotope\\Model\\Address'; $GLOBALS['TL_MODELS'][\Isotope\Model\Attribute::getTable()] = 'Isotope\\Model\\Attribute'; $GLOBALS['TL_MODELS'][\Isotope\Model\BasePrice::getTable()] = 'Isotope\\Model\\BasePrice'; $GLOBALS['TL_MODELS'][\Isotope\Model\Config::getTable()] = 'Isotope\\Model\\Config'; $GLOBALS['TL_MODELS'][\Isotope\Model\Document::getTable()] = 'Isotope\\Model\\Document'; $GLOBALS['TL_MODELS'][\Isotope\Model\Download::getTable()] = 'Isotope\\Model\\Download'; $GLOBALS['TL_MODELS'][\Isotope\Model\Gallery::getTable()] = 'Isotope\\Model\\Gallery'; $GLOBALS['TL_MODELS'][\Isotope\Model\Group::getTable()] = 'Isotope\\Model\\Group'; $GLOBALS['TL_MODELS'][\Isotope\Model\Label::getTable()] = 'Isotope\\Model\\Label'; $GLOBALS['TL_MODELS'][\Isotope\Model\OrderStatus::getTable()] = 'Isotope\\Model\\OrderStatus'; $GLOBALS['TL_MODELS'][\Isotope\Model\Payment::getTable()] = 'Isotope\\Model\\Payment'; $GLOBALS['TL_MODELS'][\Isotope\Model\Product::getTable()] = 'Isotope\\Model\\Product'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductCategory::getTable()] = 'Isotope\\Model\\ProductCategory'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductCollection::getTable()] = 'Isotope\\Model\\ProductCollection'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductCollectionDownload::getTable()] = 'Isotope\\Model\\ProductCollectionDownload'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductCollectionItem::getTable()] = 'Isotope\\Model\\ProductCollectionItem'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductCollectionSurcharge::getTable()] = 'Isotope\\Model\\ProductCollectionSurcharge'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductPrice::getTable()] = 'Isotope\\Model\\ProductPrice'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductCache::getTable()] = 'Isotope\\Model\\ProductCache'; $GLOBALS['TL_MODELS'][\Isotope\Model\ProductType::getTable()] = 'Isotope\\Model\\ProductType'; $GLOBALS['TL_MODELS'][\Isotope\Model\RelatedCategory::getTable()] = 'Isotope\\Model\\RelatedCategory'; $GLOBALS['TL_MODELS'][\Isotope\Model\RelatedProduct::getTable()] = 'Isotope\\Model\\RelatedProduct'; $GLOBALS['TL_MODELS'][\Isotope\Model\RequestCache::getTable()] = 'Isotope\\Model\\RequestCache'; $GLOBALS['TL_MODELS'][\Isotope\Model\Shipping::getTable()] = 'Isotope\\Model\\Shipping'; $GLOBALS['TL_MODELS'][\Isotope\Model\TaxClass::getTable()] = 'Isotope\\Model\\TaxClass'; $GLOBALS['TL_MODELS'][\Isotope\Model\TaxRate::getTable()] = 'Isotope\\Model\\TaxRate'; /**
/** * Generate all combination of product attributes * @param object * @return string */ public function generate($dc) { $table = Product::getTable(); $objProduct = Product::findByPk($dc->id); $doNotSubmit = false; $strBuffer = ''; $arrOptions = array(); foreach ($objProduct->getRelated('type')->getVariantAttributes() as $attribute) { if ($GLOBALS['TL_DCA'][$table]['fields'][$attribute]['attributes']['variant_option']) { $GLOBALS['TL_DCA'][$table]['fields'][$attribute]['eval']['mandatory'] = true; $GLOBALS['TL_DCA'][$table]['fields'][$attribute]['eval']['multiple'] = true; $arrField = \CheckBox::getAttributesFromDca($GLOBALS['TL_DCA'][$table]['fields'][$attribute], $attribute); foreach ($arrField['options'] as $k => $option) { if ($option['value'] == '') { unset($arrField['options'][$k]); } } $objWidget = new \CheckBox($arrField); if (\Input::post('FORM_SUBMIT') == $table . '_generate') { $objWidget->validate(); if ($objWidget->hasErrors()) { $doNotSubmit = true; } else { $arrOptions[$attribute] = $objWidget->value; } } $strBuffer .= $objWidget->parse(); } } if (\Input::post('FORM_SUBMIT') == $table . '_generate' && !$doNotSubmit) { $time = time(); $arrCombinations = array(); foreach ($arrOptions as $name => $options) { $arrTemp = $arrCombinations; $arrCombinations = array(); foreach ($options as $option) { if (empty($arrTemp)) { $arrCombinations[][$name] = $option; continue; } foreach ($arrTemp as $temp) { $temp[$name] = $option; $arrCombinations[] = $temp; } } } foreach ($arrCombinations as $combination) { $objVariant = \Database::getInstance()->prepare("\n SELECT * FROM {$table} WHERE pid=? AND " . implode('=? AND ', array_keys($combination)) . "=?")->execute(array_merge(array($objProduct->id), $combination)); if (!$objVariant->numRows) { $arrInherit = array_diff($objProduct->getRelated('type')->getVariantAttributes(), Attribute::getVariantOptionFields(), Attribute::getCustomerDefinedFields(), Attribute::getSystemColumnsFields()); $arrSet = array_merge($combination, array('tstamp' => $time, 'pid' => $objProduct->id, 'inherit' => $arrInherit ?: null)); \Database::getInstance()->prepare("INSERT INTO {$table} %s")->set($arrSet)->execute(); } } \Controller::redirect(str_replace('&key=generate', '', \Environment::get('request'))); } // Return form return ' <div id="tl_buttons"> <a href="' . ampersand(str_replace('&key=generate', '', \Environment::get('request'))) . '" class="header_back" title="' . specialchars($GLOBALS['TL_LANG']['MSC']['backBT']) . '">' . $GLOBALS['TL_LANG']['MSC']['backBT'] . '</a> </div> <h2 class="sub_headline">' . sprintf($GLOBALS['TL_LANG'][$table]['generate'][1], $dc->id) . '</h2>' . \Message::generate() . ' <form action="' . ampersand(\Environment::get('request'), true) . '" id="' . $table . '_generate" class="tl_form" method="post"> <div class="tl_formbody_edit"> <input type="hidden" name="FORM_SUBMIT" value="' . $table . '_generate"> <input type="hidden" name="REQUEST_TOKEN" value="' . REQUEST_TOKEN . '"> <div class="tl_tbox block"> ' . $strBuffer . ' </div> </div> <div class="tl_formbody_submit"> <div class="tl_submit_container"> <input type="submit" name="save" id="save" class="tl_submit" accesskey="s" value="' . specialchars($GLOBALS['TL_LANG']['tl_iso_product']['generate'][0]) . '"> </div> </div> </form>'; }
/** * Return a widget object based on a product attribute's properties * @param string * @param boolean * @return string */ protected function generateProductOptionWidget($strField, &$arrVariantOptions, &$arrAjaxOptions) { \Controller::loadDataContainer(ProductModel::getTable()); $GLOBALS['TL_DCA'][ProductModel::getTable()]['fields']['gift_amount']['default'] = $GLOBALS['TL_DCA'][ProductModel::getTable()]['fields']['gift_amount']['default'] ?: Isotope::formatPrice($this->getPrice()->getAmount()); return parent::generateProductOptionWidget($strField, $arrVariantOptions, $arrAjaxOptions); }
/** * Returns the compiled name of the SQL field (depending on multilingual attributes). * * @return string */ protected function getFieldForSQL() { if ($this->isMultilingualAttribute() && Product::countTranslatedProducts()) { $field = sprintf('IFNULL(translation.%s, %s.%s)', $this->arrConfig['attribute'], Product::getTable(), $this->arrConfig['attribute']); } else { $field = Product::getTable() . '.' . $this->arrConfig['attribute']; } return $field; }