Exemplo n.º 1
0
 /**
  * Copy or paste a single variant
  * @return string
  */
 protected function pasteVariant($objProduct, $table, $row, $arrClipboard)
 {
     // Can't copy variant into it's current product
     if ($table == 'tl_iso_product' && $objProduct->pid == $row['id'] && $arrClipboard['mode'] == 'copy') {
         return $this->getPasteButton(false);
     } elseif ($table == 'tl_iso_product' && $row['id'] > 0) {
         $objType = ProductType::findByPk($row['type']);
         if (null === $objType || !$objType->hasVariants()) {
             return $this->getPasteButton(false);
         }
     }
     return $this->getPasteButton(true, $this->addToUrl('act=' . $arrClipboard['mode'] . '&mode=2&pid=' . $row['id']), $table, $row['id']);
 }
Exemplo n.º 2
0
 /**
  * Generate a product label and return it as HTML string
  * @param array
  * @param string
  * @param object
  * @param array
  * @return string
  */
 public function generate($row, $label, $dc, $args)
 {
     $objProduct = Product::findByPk($row['id']);
     foreach ($GLOBALS['TL_DCA'][$dc->table]['list']['label']['fields'] as $i => $field) {
         switch ($field) {
             // Add an image
             case 'images':
                 $arrImages = deserialize($objProduct->images);
                 $args[$i] = ' ';
                 if (is_array($arrImages) && !empty($arrImages)) {
                     foreach ($arrImages as $image) {
                         $strImage = 'isotope/' . strtolower(substr($image['src'], 0, 1)) . '/' . $image['src'];
                         if (!is_file(TL_ROOT . '/' . $strImage)) {
                             continue;
                         }
                         $size = @getimagesize(TL_ROOT . '/' . $strImage);
                         $args[$i] = sprintf('<a href="%s" onclick="Backend.openModalImage({\'width\':%s,\'title\':\'%s\',\'url\':\'%s\'});return false"><img src="%s" alt="%s" align="left"></a>', $strImage, $size[0], str_replace("'", "\\'", $objProduct->name), $strImage, \Image::get($strImage, 50, 50, 'proportional'), $image['alt']);
                         break;
                     }
                 }
                 break;
             case 'name':
                 $args[$i] = $objProduct->name;
                 /** @var \Isotope\Model\ProductType $objProductType */
                 if ($row['pid'] == 0 && ($objProductType = ProductType::findByPk($row['type'])) !== null && $objProductType->hasVariants()) {
                     // Add a variants link
                     $args[$i] = sprintf('<a href="%s" title="%s">%s</a>', ampersand(\Environment::get('request')) . '&amp;id=' . $row['id'], specialchars($GLOBALS['TL_LANG'][$dc->table]['showVariants']), $args[$i]);
                 }
                 break;
             case 'price':
                 $objPrice = ProductPrice::findPrimaryByProductId($row['id']);
                 if (null !== $objPrice) {
                     /** @var \Isotope\Model\TaxClass $objTax */
                     $objTax = $objPrice->getRelated('tax_class');
                     $strTax = null === $objTax ? '' : ' (' . $objTax->getName() . ')';
                     $args[$i] = $objPrice->getValueForTier(1) . $strTax;
                 }
                 break;
             case 'variantFields':
                 $attributes = array();
                 foreach ($GLOBALS['TL_DCA'][$dc->table]['list']['label']['variantFields'] as $variantField) {
                     $attributes[] = '<strong>' . Format::dcaLabel($dc->table, $variantField) . ':</strong>&nbsp;' . Format::dcaValue($dc->table, $variantField, $objProduct->{$variantField});
                 }
                 $args[$i] = ($args[$i] ? $args[$i] . '<br>' : '') . implode(', ', $attributes);
                 break;
         }
     }
     return $args;
 }
Exemplo n.º 3
0
 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;
 }
Exemplo n.º 4
0
 /**
  * Build palette for the current product type/variant
  */
 public function buildPaletteString()
 {
     $this->loadDataContainer(Attribute::getTable());
     if (\Input::get('act') == '' && \Input::get('key') == '' || \Input::get('act') == 'select') {
         return;
     }
     $arrTypes = array();
     $arrFields =& $GLOBALS['TL_DCA']['tl_iso_product']['fields'];
     /** @var IsotopeAttribute[] $arrAttributes */
     $arrAttributes =& $GLOBALS['TL_DCA']['tl_iso_product']['attributes'];
     $blnVariants = false;
     $act = \Input::get('act');
     $blnSingleRecord = $act === 'edit' || $act === 'show';
     if (\Input::get('id') > 0) {
         /** @type object $objProduct */
         $objProduct = \Database::getInstance()->prepare("SELECT p1.pid, p1.type, p2.type AS parent_type FROM tl_iso_product p1 LEFT JOIN tl_iso_product p2 ON p1.pid=p2.id WHERE p1.id=?")->execute(\Input::get('id'));
         if ($objProduct->numRows) {
             $objType = ProductType::findByPk($objProduct->pid > 0 ? $objProduct->parent_type : $objProduct->type);
             $arrTypes = null === $objType ? array() : array($objType);
             if ($objProduct->pid > 0 || $act != 'edit' && $act != 'copyFallback' && $act != 'show') {
                 $blnVariants = true;
             }
         }
     } else {
         $arrTypes = ProductType::findAllUsed() ?: array();
     }
     /** @var \Isotope\Model\ProductType $objType */
     foreach ($arrTypes as $objType) {
         // Enable advanced prices
         if ($blnSingleRecord && $objType->hasAdvancedPrices()) {
             $arrFields['prices']['exclude'] = $arrFields['price']['exclude'];
             $arrFields['prices']['attributes'] = $arrFields['price']['attributes'];
             $arrFields['price'] = $arrFields['prices'];
         } else {
             $GLOBALS['TL_DCA']['tl_iso_product']['config']['onversion_callback'][] = array('Isotope\\Backend\\Product\\Price', 'createVersion');
             $GLOBALS['TL_DCA']['tl_iso_product']['config']['onrestore_callback'][] = array('Isotope\\Backend\\Product\\Price', 'restoreVersion');
         }
         $arrInherit = array();
         $arrPalette = array();
         $arrLegends = array();
         $arrLegendOrder = array();
         $arrCanInherit = array();
         if ($blnVariants) {
             $arrConfig = $objType->variant_attributes;
             $arrEnabled = $objType->getVariantAttributes();
             $arrCanInherit = $objType->getAttributes();
         } else {
             $arrConfig = $objType->attributes;
             $arrEnabled = $objType->getAttributes();
         }
         // Go through each enabled field and build palette
         foreach ($arrFields as $name => $arrField) {
             if (in_array($name, $arrEnabled)) {
                 if ($arrField['inputType'] == '') {
                     continue;
                 }
                 // Variant fields can only be edited in variant mode
                 if (null !== $arrAttributes[$name] && !$blnVariants && $arrAttributes[$name]->isVariantOption()) {
                     continue;
                 }
                 // Field cannot be edited in variant
                 if ($blnVariants && $arrAttributes[$name]->inherit) {
                     continue;
                 }
                 $arrLegendOrder[$arrConfig[$name]['position']] = $arrConfig[$name]['legend'];
                 $arrPalette[$arrConfig[$name]['legend']][$arrConfig[$name]['position']] = $name;
                 // Apply product type attribute config
                 if ($arrConfig[$name]['tl_class'] != '') {
                     $arrFields[$name]['eval']['tl_class'] = $arrConfig[$name]['tl_class'];
                 }
                 if ($arrConfig[$name]['mandatory'] > 0) {
                     $arrFields[$name]['eval']['mandatory'] = $arrConfig[$name]['mandatory'] == 1 ? false : true;
                 }
                 if ($blnVariants && in_array($name, $arrCanInherit) && null !== $arrAttributes[$name] && !$arrAttributes[$name]->isVariantOption() && !in_array($name, array('price', 'published', 'start', 'stop'))) {
                     $arrInherit[$name] = Format::dcaLabel('tl_iso_product', $name);
                 }
             } else {
                 // Hide field from "show" option
                 if (!isset($arrField['attributes']) || $arrField['inputType'] != '' && $name != 'inherit') {
                     $arrFields[$name]['eval']['doNotShow'] = true;
                 }
             }
         }
         ksort($arrLegendOrder);
         $arrLegendOrder = array_unique($arrLegendOrder);
         // Build
         foreach ($arrLegendOrder as $legend) {
             $fields = $arrPalette[$legend];
             ksort($fields);
             $arrLegends[] = '{' . $legend . '},' . implode(',', $fields);
         }
         // Set inherit options
         $arrFields['inherit']['options'] = $arrInherit;
         // Add palettes
         $GLOBALS['TL_DCA']['tl_iso_product']['palettes'][$blnVariants ? 'default' : $objType->id] = ($blnVariants ? 'inherit,' : '') . implode(';', $arrLegends);
     }
     // Remove non-active fields from multi-selection
     if ($blnVariants && !$blnSingleRecord) {
         $arrInclude = empty($arrPalette) ? array() : call_user_func_array('array_merge', $arrPalette);
         foreach ($arrFields as $name => $config) {
             if ($arrFields[$name]['attributes']['legend'] != '' && !in_array($name, $arrInclude)) {
                 $arrFields[$name]['exclude'] = true;
             }
         }
     }
 }
Exemplo n.º 5
0
 /**
  * Validate data and remove non-available attributes
  *
  * @param array $arrData
  *
  * @return $this
  */
 public function setRow(array $arrData)
 {
     if ($arrData['pid'] > 0) {
         // Do not use the model, it would trigger setRow and generate too much
         // @deprecated use static::buildFindQuery once we drop BC support for buildQueryString
         /** @type object $objParent */
         $objParent = \Database::getInstance()->prepare(static::buildQueryString(array('table' => static::$strTable, 'column' => 'id')))->execute($arrData['pid']);
         if (null === $objParent) {
             throw new \UnderflowException('Parent record of product variant ID ' . $arrData['id'] . ' not found');
         }
         $this->setRow($objParent->row());
         // Must be set before call to getInheritedFields()
         $this->arrData['id'] = $arrData['id'];
         $this->arrData['pid'] = $arrData['pid'];
         $this->arrData['inherit'] = $arrData['inherit'];
         // Set all variant attributes, except if they are inherited
         $arrFallbackFields = Attribute::getFetchFallbackFields();
         $arrVariantFields = array_diff($this->getVariantAttributes(), $this->getInheritedFields());
         foreach ($arrData as $attribute => $value) {
             if (in_array($attribute, $arrVariantFields) || $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$attribute]['attributes']['legend'] == '' && !in_array(str_replace('_fallback', '', $attribute), $arrFallbackFields)) {
                 $this->arrData[$attribute] = $arrData[$attribute];
                 if (in_array($attribute, $arrFallbackFields)) {
                     $this->arrData[$attribute . '_fallback'] = $arrData[$attribute . '_fallback'];
                 }
             }
         }
         // Make sure publishing settings match product and variant (see #1120)
         $this->arrData['published'] = $objParent->published ? $arrData['published'] : '';
         $this->arrData['start'] = $objParent->start != '' && ($arrData['start'] == '' || $objParent->start > $arrData['start']) ? $objParent->start : $arrData['start'];
         $this->arrData['stop'] = $objParent->stop != '' && ($arrData['stop'] == '' || $objParent->stop < $arrData['stop']) ? $objParent->stop : $arrData['stop'];
         return $this;
     }
     // Empty cache
     $this->objPrice = false;
     $this->arrAttributes = null;
     $this->arrVariantAttributes = null;
     $this->arrVariantIds = null;
     $this->arrCategories = null;
     $this->arrRelated = array();
     // Must initialize product type to have attributes etc.
     if (($this->arrRelated['type'] = ProductType::findByPk($arrData['type'])) === null) {
         throw new \UnderflowException('Product type for product ID ' . $arrData['id'] . ' not found');
     }
     $this->strFormId = 'iso_product_' . $arrData['id'];
     // Remove attributes not in this product type
     foreach ($arrData as $attribute => $value) {
         if (!in_array($attribute, $this->getAttributes()) && !in_array($attribute, $this->getVariantAttributes()) && isset($GLOBALS['TL_DCA']['tl_iso_product']['fields'][$attribute]['attributes']['legend']) && $GLOBALS['TL_DCA']['tl_iso_product']['fields'][$attribute]['attributes']['legend'] != '' || in_array($attribute, Attribute::getVariantOptionFields())) {
             unset($arrData[$attribute]);
         }
     }
     return parent::setRow($arrData);
 }
 public static function getOverridableStockProperty($strProperty, $objProduct)
 {
     // at first check for product and product type
     if ($objProduct->overrideStockShopConfig) {
         return $objProduct->{$strProperty};
     } else {
         if (($objProductType = ProductType::findByPk($objProduct->type)) !== null && $objProductType->overrideStockShopConfig) {
             return $objProductType->{$strProperty};
         }
     }
     // nothing returned?
     $objConfig = Isotope::getConfig();
     //		global $objPage;
     //
     //		if ($objPage->iso_config)
     //		{
     //			$objConfig = Config::findByPk($objPage->iso_config);
     //		}
     // defaultly return the value defined in the global config
     return $objConfig->{$strProperty};
 }
 public static function getProducts()
 {
     $objProducts = \Isotope\Model\Product::findPublished();
     $arrProductTypeLabels = array();
     $arrProducts = array();
     while ($objProducts->next()) {
         // check for label cache
         if (isset($arrProductTypeLabels[$objProducts->type])) {
             $strProductTypeLabel = $arrProductTypeLabels[$objProducts->type];
         } else {
             if (($objProductType = \Isotope\Model\ProductType::findByPk($objProducts->type)) !== null) {
                 $strProductTypeLabel = $objProductType->name;
                 $arrProductTypeLabels[$objProductType->id] = $objProductType->name;
             }
         }
         $arrProducts[$objProducts->id] = $strProductTypeLabel . ' - ' . $objProducts->name;
     }
     asort($arrProducts);
     return $arrProducts;
 }