Пример #1
0
 /**
  * Saves all relations between products and his attributes.
  *
  * @param int $productId The UID of the product
  * @param array $fieldArray Field array
  *
  * @return void
  */
 protected function saveProductRelations($productId, array $fieldArray = null)
 {
     $productId = (int) $productId;
     // first step is to save all relations between this product and all attributes
     // of this product.
     // We don't have to check for any parent categories, because the attributes
     // from them should already be saved for this product.
     $database = $this->getDatabaseConnection();
     // create an article and a new price for a new product
     if (SettingsFactory::getInstance()->getExtConf('simpleMode') && $productId != null) {
         // search for an article of this product
         $res = $database->exec_SELECTquery('*', 'tx_commerce_articles', 'uid_product = ' . $productId, '', '', 1);
         $aRes = array();
         if ($database->sql_num_rows($res)) {
             $aRes = $database->sql_fetch_assoc($res);
             $aUid = $aRes['uid'];
         } else {
             // create a new article if no one exists
             $pRes = $database->exec_SELECTquery('title', 'tx_commerce_products', 'uid = ' . $productId, '', '', 1);
             $productData = $database->sql_fetch_assoc($pRes);
             $database->exec_INSERTquery('tx_commerce_articles', array('pid' => $fieldArray['pid'], 'tstamp' => $GLOBALS['EXEC_TIME'], 'crdate' => $GLOBALS['EXEC_TIME'], 'uid_product' => $productId, 'article_type_uid' => 1, 'title' => $productData['title']));
             $aUid = $database->sql_insert_id();
         }
         // check if the article has already a price
         $row = $database->exec_SELECTgetSingleRow('*', 'tx_commerce_article_prices', 'uid_article = ' . $productId);
         if (empty($row) && $aRes['sys_language_uid'] < 1) {
             // create a new price if no one exists
             $database->exec_INSERTquery('tx_commerce_article_prices', array('pid' => $fieldArray['pid'], 'uid_article' => $aUid, 'tstamp' => $GLOBALS['EXEC_TIME'], 'crdate' => $GLOBALS['EXEC_TIME']));
         }
     }
     $delete = true;
     if (isset($fieldArray['categories'])) {
         $catList = array();
         $res = $database->exec_SELECTquery('uid_foreign', 'tx_commerce_products_categories_mm', 'uid_local = ' . $productId);
         while ($sres = $database->sql_fetch_assoc($res)) {
             $catList[] = $sres['uid_foreign'];
         }
         $paList = $this->belib->getAttributesForCategoryList($catList);
         $uidList = $this->belib->extractFieldArray($paList, 'uid_foreign', true, array('uid_correlationtype'));
         $this->belib->saveRelations($productId, $uidList, 'tx_commerce_products_attributes_mm', false, false);
         $this->belib->updateXML('attributes', 'tx_commerce_products', $productId, 'product', $catList);
         $delete = false;
     }
     $articles = false;
     if (isset($fieldArray['attributes'])) {
         // get all correlation types
         $correlationTypeList = $this->belib->getAllCorrelationTypes();
         $paList = array();
         // extract all attributes from FlexForm
         $ffData = GeneralUtility::xml2array($fieldArray['attributes']);
         if (is_array($ffData)) {
             $this->belib->mergeAttributeListFromFFData($ffData['data']['sDEF']['lDEF'], 'ct_', $correlationTypeList, $productId, $paList);
         }
         // get the list of uid_foreign and save relations for this category
         $uidList = $this->belib->extractFieldArray($paList, 'uid_foreign', true, array('uid_correlationtype'));
         // get all ct4 attributes
         $ct4Attributes = array();
         if (is_array($uidList)) {
             foreach ($uidList as $uidItem) {
                 if ($uidItem['uid_correlationtype'] == 4) {
                     $ct4Attributes[] = $uidItem['uid_foreign'];
                 }
             }
         }
         $this->belib->saveRelations($productId, $uidList, 'tx_commerce_products_attributes_mm', $delete, false);
         /*
          * Rebuild the XML (last param set to true)
          * Fixes that l10n of products had invalid XML attributes
          */
         $this->belib->updateXML('attributes', 'tx_commerce_products', $productId, 'product', $correlationTypeList, true);
         // update the XML for this product, we remove everything that is not
         // set for current attributes
         $pXml = $database->exec_SELECTquery('attributesedit', 'tx_commerce_products', 'uid = ' . $productId);
         $pXml = $database->sql_fetch_assoc($pXml);
         if (!empty($pXml['attributesedit'])) {
             $pXml = GeneralUtility::xml2array($pXml['attributesedit']);
             if (is_array($pXml['data']['sDEF']['lDEF'])) {
                 foreach (array_keys($pXml['data']['sDEF']['lDEF']) as $key) {
                     $data = array();
                     $uid = $this->belib->getUIdFromKey($key, $data);
                     if (!in_array($uid, $ct4Attributes)) {
                         unset($pXml['data']['sDEF']['lDEF'][$key]);
                     }
                 }
             }
             if (is_array($pXml) && is_array($pXml['data']) && is_array($pXml['data']['sDEF'])) {
                 $pXml = GeneralUtility::array2xml($pXml, '', 0, 'T3FlexForms');
                 $fieldArray['attributesedit'] = $pXml;
             }
         }
         // now get all articles that where created from this product
         $articles = $this->belib->getArticlesOfProduct($productId);
         // build relation table
         if (is_array($articles) && !empty($articles)) {
             $uidList = $this->belib->extractFieldArray($paList, 'uid_foreign', true);
             foreach ($articles as $article) {
                 $this->belib->saveRelations($article['uid'], $uidList, 'tx_commerce_articles_article_attributes_mm', true, false);
             }
         }
     }
     $updateArrays = array();
     // update all articles of this product
     if (!empty($fieldArray['attributesedit'])) {
         $ffData = (array) GeneralUtility::xml2array($fieldArray['attributesedit']);
         if (is_array($ffData['data']) && is_array($ffData['data']['sDEF']['lDEF'])) {
             // get articles if they are not already there
             if (!$articles) {
                 $articles = $this->belib->getArticlesOfProduct($productId);
             }
             // update this product
             $articleRelations = array();
             $counter = 0;
             foreach ($ffData['data']['sDEF']['lDEF'] as $ffDataItemKey => $ffDataItem) {
                 ++$counter;
                 $attributeKey = $this->belib->getUidFromKey($ffDataItemKey, $keyData);
                 $attributeData = $this->belib->getAttributeData($attributeKey, 'has_valuelist,multiple');
                 // check if the attribute has more than one value, if that is true,
                 // we have to create a relation for each value
                 if ($attributeData['multiple'] == 1) {
                     // if we have a multiple valuelist we need to handle the attributes a little
                     // bit different first we delete all existing attributes
                     $database->exec_DELETEquery('tx_commerce_products_attributes_mm', 'uid_local = ' . $productId . ' AND uid_foreign = ' . $attributeKey);
                     // now explode the data
                     $attributeValues = GeneralUtility::trimExplode(',', $ffDataItem['vDEF'], true);
                     foreach ($attributeValues as $attributeValue) {
                         // The first time an attribute value is selected, TYPO3 returns them
                         // INCLUDING an empty value! This would cause an unnecessary entry in the
                         // database, so we have to filter this here.
                         if (empty($attributeValue)) {
                             continue;
                         }
                         $updateData = $this->belib->getUpdateData($attributeData, $attributeValue, $productId);
                         $database->exec_INSERTquery('tx_commerce_products_attributes_mm', array_merge(array('uid_local' => $productId, 'uid_foreign' => $attributeKey, 'uid_correlationtype' => 4), $updateData[0]));
                     }
                 } else {
                     // update a simple valuelist and normal attributes as usual
                     $updateArrays = $this->belib->getUpdateData($attributeData, $ffDataItem['vDEF'], $productId);
                     $database->exec_UPDATEquery('tx_commerce_products_attributes_mm', 'uid_local = ' . $productId . ' AND uid_foreign = ' . $attributeKey, $updateArrays[0]);
                 }
                 // update articles
                 if (is_array($articles) && !empty($articles)) {
                     foreach ($articles as $article) {
                         if ($attributeData['multiple'] == 1) {
                             // if we have a multiple valuelist we need to handle the attributes a little
                             // bit different first we delete all existing attributes
                             $database->exec_DELETEquery('tx_commerce_articles_article_attributes_mm', 'uid_local = ' . $article['uid'] . ' AND uid_foreign = ' . $attributeKey);
                             // now explode the data
                             $attributeValues = GeneralUtility::trimExplode(',', $ffDataItem['vDEF'], true);
                             $attributeCount = 0;
                             $attributeValue = '';
                             foreach ($attributeValues as $attributeValue) {
                                 if (empty($attributeValue)) {
                                     continue;
                                 }
                                 ++$attributeCount;
                                 $updateData = $this->belib->getUpdateData($attributeData, $attributeValue, $productId);
                                 $database->exec_INSERTquery('tx_commerce_articles_article_attributes_mm', array_merge(array('uid_local' => $article['uid'], 'uid_foreign' => $attributeKey, 'uid_product' => $productId, 'sorting' => $counter), $updateData[1]));
                             }
                             // create at least an empty relation if no attributes where set
                             if ($attributeCount == 0) {
                                 $updateData = $this->belib->getUpdateData(array(), $attributeValue, $productId);
                                 $database->exec_INSERTquery('tx_commerce_articles_article_attributes_mm', array_merge(array('uid_local' => $article['uid'], 'uid_foreign' => $attributeKey, 'uid_product' => $productId, 'sorting' => $counter), $updateData[1]));
                             }
                         } else {
                             // if the article has already this attribute, we have to insert so try
                             // to select this attribute for this article
                             $res = $database->exec_SELECTquery('uid_local, uid_foreign', 'tx_commerce_articles_article_attributes_mm', 'uid_local = ' . $article['uid'] . ' AND uid_foreign = ' . $attributeKey);
                             if ($database->sql_num_rows($res)) {
                                 $database->exec_UPDATEquery('tx_commerce_articles_article_attributes_mm', 'uid_local = ' . $article['uid'] . ' AND uid_foreign = ' . $attributeKey, array_merge($updateArrays[1], array('sorting' => $counter)));
                             } else {
                                 $database->exec_INSERTquery('tx_commerce_articles_article_attributes_mm', array_merge($updateArrays[1], array('uid_local' => $article['uid'], 'uid_product' => $productId, 'uid_foreign' => $attributeKey, 'sorting' => $counter)));
                             }
                         }
                         $relArray = $updateArrays[0];
                         $relArray['uid_foreign'] = $attributeKey;
                         if (!in_array($relArray, $articleRelations)) {
                             $articleRelations[] = $relArray;
                         }
                         $this->belib->updateArticleHash($article['uid']);
                     }
                 }
             }
             // Finally update the Felxform for this Product
             $this->belib->updateArticleXML($articleRelations, false, null, $productId);
             // And add those datas from the database to the articles
             if (is_array($articles) && !empty($articles)) {
                 foreach ($articles as $article) {
                     $thisArticleRelations = $this->belib->getAttributesForArticle($article['uid']);
                     $this->belib->updateArticleXML($thisArticleRelations, false, $article['uid'], null);
                 }
             }
         }
     }
     // Check if we do have some localized products an call the method recursivly
     $resLocalised = $database->exec_SELECTquery('uid', 'tx_commerce_products', 'deleted = 0 AND l18n_parent = ' . $productId);
     while ($rowLocalised = $database->sql_fetch_assoc($resLocalised)) {
         $this->saveProductRelations($rowLocalised['uid'], $fieldArray);
     }
 }
 /**
  * Creates an article in the database and all needed releations to attributes
  * and values. It also creates a new prices and assignes it to the new article.
  *
  * @param array $parameter Parameter
  * @param string $key The key in the POST var array
  *
  * @return int Returns the new articleUid if success
  */
 protected function createArticle(array $parameter, $key)
 {
     $database = $this->getDatabaseConnection();
     // get the create data
     $data = GeneralUtility::_GP('createData');
     $hash = '';
     if (is_array($data)) {
         $data = $data[$key];
         $hash = md5($data);
         $data = unserialize($data);
     }
     $database->debugOutput = 1;
     $database->store_lastBuiltQuery = true;
     // get the highest sorting
     $sorting = $database->exec_SELECTgetSingleRow('uid, sorting', 'tx_commerce_articles', 'uid_product = ' . $this->uid, '', 'sorting DESC', 1);
     $sorting = is_array($sorting) && isset($sorting['sorting']) ? $sorting['sorting'] + 20 : 0;
     // create article data array
     $articleData = array('pid' => $this->pid, 'crdate' => time(), 'title' => strip_tags($this->createArticleTitleFromAttributes($parameter, (array) $data)), 'uid_product' => (int) $this->uid, 'sorting' => $sorting, 'article_attributes' => count($this->attributes['rest']) + count($data), 'attribute_hash' => $hash, 'article_type_uid' => 1);
     $temp = CoreBackendUtility::getModTSconfig($this->pid, 'mod.commerce.category');
     if ($temp) {
         $moduleConfig = CoreBackendUtility::implodeTSParams($temp['properties']);
         $defaultTax = (int) $moduleConfig['defaultTaxValue'];
         if ($defaultTax > 0) {
             $articleData['tax'] = $defaultTax;
         }
     }
     $hookObject = \CommerceTeam\Commerce\Factory\HookFactory::getHook('Utility/ArticleCreatorUtility', 'createArticle');
     if (method_exists($hookObject, 'preinsert')) {
         $hookObject->preinsert($articleData);
     }
     // create the article
     $database->exec_INSERTquery('tx_commerce_articles', $articleData);
     $articleUid = $database->sql_insert_id();
     // create a new price that is assigned to the new article
     $database->exec_INSERTquery('tx_commerce_article_prices', array('pid' => $this->pid, 'crdate' => time(), 'tstamp' => time(), 'uid_article' => $articleUid));
     // now write all relations between article and attributes into the database
     $relationBaseData = array('uid_local' => $articleUid);
     $createdArticleRelations = array();
     $relationCreateData = $relationBaseData;
     $productsAttributesRes = $database->exec_SELECTquery('sorting, uid_local, uid_foreign', 'tx_commerce_products_attributes_mm', 'uid_local = ' . (int) $this->uid);
     $attributesSorting = array();
     while ($productsAttributes = $database->sql_fetch_assoc($productsAttributesRes)) {
         $attributesSorting[$productsAttributes['uid_foreign']] = $productsAttributes['sorting'];
     }
     if (is_array($data)) {
         foreach ($data as $selectAttributeUid => $selectAttributeValueUid) {
             $relationCreateData['uid_foreign'] = $selectAttributeUid;
             $relationCreateData['uid_valuelist'] = $selectAttributeValueUid;
             $relationCreateData['sorting'] = $attributesSorting[$selectAttributeUid];
             $createdArticleRelations[] = $relationCreateData;
             $database->exec_INSERTquery('tx_commerce_articles_article_attributes_mm', $relationCreateData);
         }
     }
     if (is_array($this->attributes['rest'])) {
         foreach ($this->attributes['rest'] as $attribute) {
             if (empty($attribute['attributeData']['uid'])) {
                 continue;
             }
             $relationCreateData = $relationBaseData;
             $relationCreateData['sorting'] = $attribute['sorting'];
             $relationCreateData['uid_foreign'] = $attribute['attributeData']['uid'];
             if ($attribute['uid_correlationtype'] == 4) {
                 $relationCreateData['uid_product'] = $this->uid;
             }
             $relationCreateData['default_value'] = '';
             $relationCreateData['value_char'] = '';
             $relationCreateData['uid_valuelist'] = $attribute['uid_valuelist'];
             if (!$this->belib->isNumber($attribute['default_value'])) {
                 $relationCreateData['default_value'] = $attribute['default_value'];
             } else {
                 $relationCreateData['value_char'] = $attribute['default_value'];
             }
             $createdArticleRelations[] = $relationCreateData;
             $database->exec_INSERTquery('tx_commerce_articles_article_attributes_mm', $relationCreateData);
         }
     }
     // update the article
     // we have to write the xml datastructure for this article. This is needed
     // to have the correct values inserted on first call of the article.
     $this->belib->updateArticleXML($createdArticleRelations, false, $articleUid);
     // Now check, if the parent Product is already lokalised, so creat Article in
     // the lokalised version Select from Database different localisations
     $resOricArticle = $database->exec_SELECTquery('*', 'tx_commerce_articles', 'uid = ' . (int) $articleUid . ' AND deleted = 0');
     $origArticle = $database->sql_fetch_assoc($resOricArticle);
     $result = $database->exec_SELECTquery('*', 'tx_commerce_products', 'l18n_parent = ' . (int) $this->uid . ' AND deleted = 0');
     if ($database->sql_num_rows($result)) {
         // Only if there are products
         while ($localizedProducts = $database->sql_fetch_assoc($result)) {
             // walk thru and create articles
             $destLanguage = $localizedProducts['sys_language_uid'];
             // get the highest sorting
             $langIsoCode = CoreBackendUtility::getRecord('sys_language', (int) $destLanguage, 'static_lang_isocode');
             $langIdent = CoreBackendUtility::getRecord('static_languages', (int) $langIsoCode['static_lang_isocode'], 'lg_typo3');
             $langIdent = strtoupper($langIdent['lg_typo3']);
             // create article data array
             $articleData = array('pid' => $this->pid, 'crdate' => time(), 'title' => $parameter['title'], 'uid_product' => $localizedProducts['uid'], 'sys_language_uid' => $localizedProducts['sys_language_uid'], 'l18n_parent' => $articleUid, 'sorting' => $sorting['sorting'] + 20, 'article_attributes' => count($this->attributes['rest']) + count($data), 'attribute_hash' => $hash, 'article_type_uid' => 1, 'attributesedit' => $this->belib->buildLocalisedAttributeValues($origArticle['attributesedit'], $langIdent));
             // create the article
             $database->exec_INSERTquery('tx_commerce_articles', $articleData);
             $localizedArticleUid = $database->sql_insert_id();
             // get all relations to attributes from the old article and copy them
             // to new article
             $res = $database->exec_SELECTquery('*', 'tx_commerce_articles_article_attributes_mm', 'uid_local = ' . (int) $origArticle['uid'] . ' AND uid_valuelist = 0');
             while ($origRelation = $database->sql_fetch_assoc($res)) {
                 $origRelation['uid_local'] = $localizedArticleUid;
                 $database->exec_INSERTquery('tx_commerce_articles_article_attributes_mm', $origRelation);
             }
             $this->belib->updateArticleXML($createdArticleRelations, false, $localizedArticleUid);
         }
     }
     return $articleUid;
 }